diff options
791 files changed, 64489 insertions, 9922 deletions
diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 84dab2dc819..4eb39d5426c 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,6 +1,6 @@ [MYSQL] -tree_location = lp:maria +tree_location = lp:maria/5.2 post_commit_to = commits@mariadb.org -post_commit_url = lp:maria -tree_name = maria -project_name = "MariaDB 5.1, with Maria 1.5" +post_commit_url = lp:maria/5.2 +tree_name = maria/5.2 +project_name = "Mariadb 5.2, with Maria 2.0" diff --git a/.bzrignore b/.bzrignore index 84ebe547912..be6b6d47d31 100644 --- a/.bzrignore +++ b/.bzrignore @@ -699,7 +699,6 @@ ma_test_recovery.output man/*.1 maria-win.patch maria_log.00000* -maria_log_control merge/*.ds? merge/*.vcproj missing @@ -1488,15 +1487,15 @@ storage/maria/ma_test1 storage/maria/ma_test2 storage/maria/ma_test3 storage/maria/ma_test_all -storage/maria/maria.log -storage/maria/maria_chk -storage/maria/maria_control -storage/maria/maria_dump_log -storage/maria/maria_ftdump -storage/maria/maria_log -storage/maria/maria_log.* -storage/maria/maria_pack -storage/maria/maria_read_log +storage/maria/aria.log +storage/maria/aria_chk +storage/maria/aria_control +storage/maria/aria_dump_log +storage/maria/aria_ftdump +storage/maria/aria_log +storage/maria/aria_log.* +storage/maria/aria_pack +storage/maria/aria_read_log storage/maria/tmp storage/maria/tmp/* storage/maria/unittest/ma_pagecache_consist_1k-t-big @@ -1946,12 +1945,21 @@ libmysqld/opt_table_elimination.cc libmysqld/ha_federatedx.cc tmp libmysqld/debug_sync.cc +client/rpl_filter.cc +client/rpl_filter.h +client/sql_list.cc +client/sql_list.h +libmysqld/client_plugin.c +sql/client_plugin.c +*.dgcov +libmysqld/create_options.cc storage/pbxt/bin/xtstat mysql-test/mtr_command scripts/convert-debug-for-diff client/strings_def.h libmysql/strings_def.h libmysql_r/strings_def.h +storage/maria/aria_log_control CPackConfig.cmake CPackSourceConfig.cmake win/nmake_cache.txt diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 34e6cea05df..c254304a5a8 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -178,7 +178,7 @@ base_configs="--prefix=$prefix --enable-assembler " base_configs="$base_configs --with-extra-charsets=complex " base_configs="$base_configs --enable-thread-safe-client " base_configs="$base_configs --with-big-tables" -base_configs="$base_configs --with-plugin-maria --with-maria-tmp-tables --without-plugin-innodb_plugin" +base_configs="$base_configs --with-plugin-aria --with-aria-tmp-tables --without-plugin-innodb_plugin" # Compile our client programs with static libraries to allow them to be moved base_configs="$base_configs --with-mysqld-ldflags=-static --with-client-ldflags=-static" @@ -194,7 +194,7 @@ max_no_embedded_configs="$SSL_LIBRARY --with-plugins=max" max_no_qc_configs="$SSL_LIBRARY --with-plugins=max --without-query-cache" max_no_ndb_configs="$SSL_LIBRARY --with-plugins=max-no-ndb --with-embedded-server --with-libevent" max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-libevent" -all_configs="$SSL_LIBRARY --with-plugins=max --with-plugin-ndbcluster --with-embedded-server --with-libevent" +all_configs="$SSL_LIBRARY --with-plugins=max --with-plugin-ndbcluster --with-embedded-server --with-innodb_plugin --with-libevent" # # CPU and platform specific compilation flags. @@ -219,7 +219,7 @@ if test -z "$CC" ; then fi if test -z "$CXX" ; then - CXX=gcc + CXX=g++ fi diff --git a/BUILD/compile-bintar b/BUILD/compile-bintar index 8777cfb2670..2b039e439c0 100755 --- a/BUILD/compile-bintar +++ b/BUILD/compile-bintar @@ -32,8 +32,7 @@ # .so files at runtime (either system stuff like NSS, or server # plugins). # -# We link libgcc statically (and avoid linking libstdc++ at all by -# CXX=gcc), to avoid reduce nasty library version dependencies. +# We link libgcc statically to avoid reduce nasty library version dependencies. test -f Makefile && make distclean @@ -52,13 +51,12 @@ get_cpuopt get_make_parallel_flag # Use gcc rather than g++ to avoid linking libstdc++.so (which we don't need). -COMP="gcc -static-libgcc" FLAGS="-O2 -fno-omit-frame-pointer -g -pipe -Wall $CPUOPT" # Don't press on in case of error. set -e -CC="$COMP" CXX="$COMP" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \ +CC="gcc -static-libgcc" CXX="g++ -static-libgcc" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \ ./configure \ --prefix=/usr/local/mysql \ --exec-prefix=/usr/local/mysql \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 1da115b57c3..13ef58a072a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,133 +18,77 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR) IF(COMMAND cmake_policy) cmake_policy(SET CMP0005 NEW) ENDIF(COMMAND cmake_policy) +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/win/cmake) PROJECT(MySql) +include(package_name) +include(mysql_version) +include(mysql_add_executable) +include(install_macros) +include(install_layout) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/include) + +# Hardcode WITH_XXX_STORAGE_ENGINE to ON for storage engines that go into the +# distributable package, this is temporary solution to get rid of configure.js stuff, +# 5.5 will handle it more nicely. + +SET(WITH_ARCHIVE_STORAGE_ENGINE 1 CACHE BOOL "Include archive storage engine") +SET(WITH_BLACKHOLE_STORAGE_ENGINE 1 CACHE BOOL "Include blockhole storage engine") +SET(WITH_FEDERATEDX_STORAGE_ENGINE 1 CACHE BOOL "Include federatedx storage engine") +SET(WITH_PARTITION_STORAGE_ENGINE 1 CACHE BOOL "Include partition storage engine") +SET(WITH_ARIA_STORAGE_ENGINE 1 CACHE BOOL "Include aria storage engine") +SET(WITH_PBXT_STORAGE_ENGINE 1 CACHE BOOL "Include pbxt storage engine") +SET(WITH_XTRADB_STORAGE_ENGINE 1 CACHE BOOL "Include xtradb storage engine") +SET(WITH_FEEDBACK_STORAGE_ENGINE 1 CACHE FORCE BOOL "Include feedback plugin") -# This reads user configuration, generated by configure.js. -INCLUDE(win/configure.data OPTIONAL) - -MACRO(MYSQL_GET_CONFIG_VALUE keyword var) - IF(NOT ${var}) - IF (EXISTS ${CMAKE_SOURCE_DIR}/configure.in) - FILE (STRINGS ${CMAKE_SOURCE_DIR}/configure.in str REGEX "^[ ]*${keyword}=") - IF(str) - STRING(REPLACE "${keyword}=" "" str ${str}) - STRING(REGEX REPLACE "[ ].*" "" str ${str}) - SET(${var} ${str} CACHE INTERNAL "Config variable") - ENDIF() - ENDIF() - ENDIF() -ENDMACRO() - - -# Read mysql version for configure script - -MACRO(GET_MYSQL_VERSION) - IF(NOT VERSION_STRING) - IF(EXISTS ${CMAKE_SOURCE_DIR}/configure.in) - FILE(STRINGS ${CMAKE_SOURCE_DIR}/configure.in str REGEX "AM_INIT_AUTOMAKE") - STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+[-][^ \\)]+" VERSION_STRING "${str}") - IF(NOT VERSION_STRING) - STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION_STRING "${str}") - IF(NOT VERSION_STRING) - FILE(STRINGS configure.in str REGEX "AC_INIT\\(") - STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+[-][a-zA-Z0-9]+" VERSION_STRING "${str}") - IF(NOT VERSION_STRING) - STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION_STRING "${str}") - ENDIF() - ENDIF() - ENDIF() - ENDIF() - ENDIF() - - IF(NOT VERSION_STRING) - MESSAGE(FATAL_ERROR - "VERSION_STRING cannot be parsed, please specify -DVERSION_STRING=major.minor.patch-extra" - "when calling cmake") - ENDIF() - - SET(VERSION ${VERSION_STRING}) - STRING(REPLACE "-" "_" MYSQL_U_SCORE_VERSION "${VERSION_STRING}") - - # Remove trailing (non-numeric) part of the version string - STRING(REGEX REPLACE "[^\\.0-9].*" "" VERSION_STRING ${VERSION_STRING}) - - STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" MAJOR_VERSION "${VERSION_STRING}") - STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" MINOR_VERSION "${VERSION_STRING}") - STRING(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" PATCH "${VERSION_STRING}") - SET(MYSQL_BASE_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}" CACHE INTERNAL "MySQL Base version") - SET(MYSQL_NO_DASH_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH}") - MATH(EXPR MYSQL_VERSION_ID "10000*${MAJOR_VERSION} + 100*${MINOR_VERSION} + ${PATCH}") - MARK_AS_ADVANCED(VERSION MYSQL_VERSION_ID MYSQL_BASE_VERSION) - SET(CPACK_PACKAGE_VERSION_MAJOR ${MAJOR_VERSION}) - SET(CPACK_PACKAGE_VERSION_MINOR ${MINOR_VERSION}) - SET(CPACK_PACKAGE_VERSION_PATCH ${PATCH}) -ENDMACRO() - -# Get mysql version and other interesting variables -GET_MYSQL_VERSION() - -MYSQL_GET_CONFIG_VALUE("PROTOCOL_VERSION" PROTOCOL_VERSION) -MYSQL_GET_CONFIG_VALUE("DOT_FRM_VERSION" DOT_FRM_VERSION) -MYSQL_GET_CONFIG_VALUE("MYSQL_TCP_PORT_DEFAULT" MYSQL_TCP_PORT_DEFAULT) -MYSQL_GET_CONFIG_VALUE("MYSQL_UNIX_ADDR_DEFAULT" MYSQL_UNIX_ADDR_DEFAULT) -MYSQL_GET_CONFIG_VALUE("SHARED_LIB_MAJOR_VERSION" SHARED_LIB_MAJOR_VERSION) -IF(NOT MYSQL_TCP_PORT_DEFAULT) - SET(MYSQL_TCP_PORT_DEFAULT "3306") +IF(WIN32) + LINK_LIBRARIES(ws2_32) + # This reads user configuration, generated by configure.js. + INCLUDE(win/configure.data OPTIONAL) ENDIF() -IF(NOT MYSQL_TCP_PORT) - SET(MYSQL_TCP_PORT ${MYSQL_TCP_PORT_DEFAULT}) - SET(MYSQL_TCP_PORT_DEFAULT "0") -ELSEIF(MYSQL_TCP_PORT EQUAL MYSQL_TCP_PORT_DEFAULT) - SET(MYSQL_TCP_PORT_DEFAULT "0") +IF(BUILD_RELEASE) + MESSAGE("Building release package") ENDIF() -IF(NOT MYSQL_UNIX_ADDR) - SET(MYSQL_UNIX_ADDR "/tmp/mysql.sock") -ENDIF() -IF(NOT COMPILATION_COMMENT) - SET(COMPILATION_COMMENT "Source distribution") -ENDIF() - -SET(WITH_EXAMPLE_STORAGE_ENGINE TRUE) -SET(WITH_FEDERATEDX_STORAGE_ENGINE TRUE) -SET(WITH_PARTITION_STORAGE_ENGINE TRUE) -SET(WITH_MARIA_STORAGE_ENGINE TRUE) -SET(WITH_PBXT_STORAGE_ENGINE TRUE) -SET(WITH_XTRADB_STORAGE_ENGINE TRUE) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/mysql_version.h.in + ${CMAKE_BINARY_DIR}/include/mysql_version.h @ONLY) -# Hardcode support for CSV storage engine -SET(WITH_CSV_STORAGE_ENGINE TRUE) +# Speed up multiprocessor build +IF (MSVC_VERSION GREATER 1400) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") +ENDIF() -CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/mysql_version.h.in - ${CMAKE_SOURCE_DIR}/include/mysql_version.h @ONLY) +SET(CMAKE_INSTALL_PREFIX "C:/MariaDB${MYSQL_BASE_VERSION}") +SET(INSTALL_ROOT "${CMAKE_INSTALL_PREFIX}") # Set standard options ADD_DEFINITIONS(-DHAVE_YASSL) ADD_DEFINITIONS(-DCMAKE_CONFIGD) -ADD_DEFINITIONS(-DDEFAULT_MYSQL_HOME="c:/Program Files/MySQL/MySQL Server ${MYSQL_BASE_VERSION}/") -ADD_DEFINITIONS(-DDEFAULT_BASEDIR="c:/Program Files/MySQL/") -ADD_DEFINITIONS(-DMYSQL_DATADIR="c:/Program Files/MySQL/MySQL Server ${MYSQL_BASE_VERSION}/data") -ADD_DEFINITIONS(-DDEFAULT_CHARSET_HOME="c:/Program Files/MySQL/MySQL Server ${MYSQL_BASE_VERSION}/") +ADD_DEFINITIONS(-DDEFAULT_MYSQL_HOME="${INSTALL_ROOT}") +ADD_DEFINITIONS(-DDEFAULT_BASEDIR="${INSTALL_ROOT}") +ADD_DEFINITIONS(-DMYSQL_DATADIR="data") +ADD_DEFINITIONS(-DDEFAULT_CHARSET_HOME="${INSTALL_ROOT}") ADD_DEFINITIONS(-DPACKAGE=mysql) ADD_DEFINITIONS(-DSHAREDIR="share") +ADD_DEFINITIONS(-DPLUGINDIR="lib/plugin") # Set debug options SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFORCE_INIT_OF_VARS") SET(localstatedir "C:\\\\mysql\\\\data\\\\") CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-huge.cnf.sh - ${CMAKE_SOURCE_DIR}/support-files/my-huge.ini @ONLY) + ${CMAKE_BINARY_DIR}/support-files/my-huge.ini @ONLY) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-innodb-heavy-4G.cnf.sh - ${CMAKE_SOURCE_DIR}/support-files/my-innodb-heavy-4G.ini @ONLY) + ${CMAKE_BINARY_DIR}/support-files/my-innodb-heavy-4G.ini @ONLY) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-large.cnf.sh - ${CMAKE_SOURCE_DIR}/support-files/my-large.ini @ONLY) + ${CMAKE_BINARY_DIR}/support-files/my-large.ini @ONLY) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-medium.cnf.sh - ${CMAKE_SOURCE_DIR}/support-files/my-medium.ini @ONLY) + ${CMAKE_BINARY_DIR}/support-files/my-medium.ini @ONLY) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-small.cnf.sh - ${CMAKE_SOURCE_DIR}/support-files/my-small.ini @ONLY) + ${CMAKE_BINARY_DIR}/support-files/my-small.ini @ONLY) ADD_DEFINITIONS(-D__NT__) @@ -230,15 +174,7 @@ IF(MSVC) IF(CMAKE_SIZEOF_VOID_P MATCHES 4) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") ENDIF(CMAKE_SIZEOF_VOID_P MATCHES 4) - - # Disable automatic manifest generation. - STRING(REPLACE "/MANIFEST" "/MANIFEST:NO" CMAKE_EXE_LINKER_FLAGS - ${CMAKE_EXE_LINKER_FLAGS}) - # Explicitly disable it since it is the default for newer versions of VS - STRING(REGEX MATCH "MANIFEST:NO" tmp_manifest ${CMAKE_EXE_LINKER_FLAGS}) - IF(NOT tmp_manifest) - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") - ENDIF(NOT tmp_manifest) + SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /INCREMENTAL:NO") ENDIF(MSVC) IF(WIN32) @@ -361,7 +297,7 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS}) ENDIF(WITH_${ENGINE}_STORAGE_ENGINE AND MYSQL_PLUGIN_STATIC) IF (ENGINE_BUILD_TYPE STREQUAL "STATIC") - SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_${ENGINE_LOWER}_plugin") + SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${ENGINE_LOWER}_plugin") SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${MYSQL_PLUGIN_STATIC}) SET (MYSQLD_STATIC_ENGINES ${MYSQLD_STATIC_ENGINES} ${ENGINE}) SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE") @@ -382,22 +318,24 @@ ENDFOREACH(SUBDIR ${STORAGE_SUBDIRS}) # Special handling for partition(not really pluggable) IF(NOT WITHOUT_PARTITION_STORAGE_ENGINE) SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_PARTITION_STORAGE_ENGINE") - SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_partition_plugin") + SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_partition_plugin") ENDIF(NOT WITHOUT_PARTITION_STORAGE_ENGINE) -# Special handling for tmp tables with the maria engine -IF(WITH_MARIA_STORAGE_ENGINE) - ADD_DEFINITIONS(-DWITH_MARIA_STORAGE_ENGINE) - IF(WITH_MARIA_TMP_TABLES) +# Special handling for tmp tables with the Aria engine +IF(WITH_ARIA_STORAGE_ENGINE) + ADD_DEFINITIONS(-DWITH_ARIA_STORAGE_ENGINE) + SET(WITH_ARIA_TMP_TABLES 1 CACHE BOOL "Use Aria for temporary tables") + IF(WITH_ARIA_TMP_TABLES) + MESSAGE(STATUS "Using Aria for temporary tables") ADD_DEFINITIONS(-DUSE_MARIA_FOR_TMP_TABLES) - ENDIF(WITH_MARIA_TMP_TABLES) -ENDIF(WITH_MARIA_STORAGE_ENGINE) + ENDIF() +ENDIF() ADD_DEFINITIONS(${STORAGE_ENGINE_DEFS}) # Now write out our mysql_plugin_defs struct CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc.in - ${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc @ONLY) + ${CMAKE_BINARY_DIR}/sql/sql_builtin.cc @ONLY) # Add subdirectories for storage engines SET (ENGINE_BUILD_TYPE "STATIC") @@ -424,11 +362,13 @@ ADD_SUBDIRECTORY(extra/yassl) ADD_SUBDIRECTORY(extra/yassl/taocrypt) ADD_SUBDIRECTORY(extra/libevent) ADD_SUBDIRECTORY(extra) -ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(sql) -ADD_SUBDIRECTORY(server-tools/instance-manager) +ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(libmysql) +ADD_SUBDIRECTORY(libservices) ADD_SUBDIRECTORY(tests) +ADD_SUBDIRECTORY(mysql-test) +ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(unittest/mytap) ADD_SUBDIRECTORY(unittest/mysys) IF(WITH_EMBEDDED_SERVER) @@ -436,126 +376,31 @@ IF(WITH_EMBEDDED_SERVER) ADD_SUBDIRECTORY(libmysqld/examples) ENDIF(WITH_EMBEDDED_SERVER) ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess) +IF(WIN32) + ADD_SUBDIRECTORY(win/upgrade_wizard) + ADD_SUBDIRECTORY(win/packaging) +ENDIF() -# Set up the installer -SET(CPACK_PACKAGE_NAME "MariaDB") -STRING(REPLACE "-MariaDB" "" CPACK_PACKAGE_VERSION ${VERSION}) -SET(CPACK_PACKAGE_VENDOR "Monty Program AB http://www.montyprogram.com") -SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MariaDB") -SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/COPYING) -SET(CPACK_GENERATOR NSIS) - -# Use our own NSIS template -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/win/cmake" ${CMAKE_MODULE_PATH}) - -# Installer components and grouping -SET(CPACK_COMPONENT_GROUP_SERVER_DESCRIPTION "The files necessary for running the MariaDB server.") -SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION "Files used in development on the MariaDB server.") -SET(CPACK_ALL_INSTALL_TYPES Normal Development) -SET(CPACK_COMPONENT_RUNTIME_DISPLAY_NAME "MariaDB server") -SET(CPACK_COMPONENT_RUNTIME_DESCRIPTION "The server itself. You want to install this one.") -SET(CPACK_COMPONENT_RUNTIME_GROUP "Server") -SET(CPACK_COMPONENT_RUNTIME_INSTALL_TYPES Normal Development) -SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "Development headers") -SET(CPACK_COMPONENT_HEADERS_DESCRIPTION "Header files for development on MariaDB.") -SET(CPACK_COMPONENT_HEADERS_DEPENDS runtime) -SET(CPACK_COMPONENT_HEADERS_GROUP "Development") -SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Development) -SET(CPACK_COMPONENT_EMBEDDED_DISPLAY_NAME "Embedded") -SET(CPACK_COMPONENT_EMBEDDED_DESCRIPTION "Files for embedding MariaDB in other projects.") -SET(CPACK_COMPONENT_EMBEDDED_DEPENDS headers) -SET(CPACK_COMPONENT_EMBEDDED_GROUP "Development") -SET(CPACK_COMPONENT_EMBEDDED_INSTALL_TYPES Development) -SET(CPACK_COMPONENT_SCRIPTS_DISPLAY_NAME "Server scripts") -SET(CPACK_COMPONENT_SCRIPTS_DESCRIPTION "SQL and Perl scripts to control and modify the server. You need a perl installation for some of these to work.") -SET(CPACK_COMPONENT_SCRIPTS_DEPENDS runtime) -SET(CPACK_COMPONENT_SCRIPTS_GROUP "Server") -SET(CPACK_COMPONENT_SCRIPTS_INSTALL_TYPES Normal Development) -SET(CPACK_COMPONENT_MYSQLTEST_DISPLAY_NAME "MariaDB test suite") -SET(CPACK_COMPONENT_MYSQLTEST_DESCRIPTION "The MariaDB regression test suite.") -SET(CPACK_COMPONENT_MYSQLTEST_DEPENDS runtime) -SET(CPACK_COMPONENT_MYSQLTEST_GROUP "Testing") -SET(CPACK_COMPONENT_MYSQLTEST_INSTALL_TYPES Normal Development) -SET(CPACK_COMPONENT_SQLBENCH_DISPLAY_NAME "SQL Bench") -SET(CPACK_COMPONENT_SQLBENCH_DESCRIPTION "The MariaDB benchmark suite.") -SET(CPACK_COMPONENT_SQLBENCH_DEPENDS runtime) -SET(CPACK_COMPONENT_SQLBENCH_GROUP "Testing") -SET(CPACK_COMPONENT_SQLBENCH_INSTALL_TYPES Normal Development) - -# Add files to the installer -INSTALL(FILES COPYING EXCEPTIONS-CLIENT DESTINATION .) -INSTALL(FILES support-files/my-huge.ini support-files/my-innodb-heavy-4G.ini DESTINATION .) -INSTALL(FILES support-files/my-large.ini support-files/my-medium.ini DESTINATION .) -INSTALL(FILES support-files/my-small.ini DESTINATION .) -INSTALL(FILES Docs/INSTALL-BINARY DESTINATION Docs) -INSTALL(FILES COPYING DESTINATION Docs) -FILE(GLOB headerfiles "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h") -INSTALL(FILES ${headerfiles} DESTINATION include COMPONENT headers) -INSTALL(FILES include/mysql/plugin.h DESTINATION include/mysql COMPONENT headers) -INSTALL(FILES libmysql/libmysql.def DESTINATION include COMPONENT headers) - -# Handle the database files -FILE(GLOB datafiles "${CMAKE_CURRENT_SOURCE_DIR}/win/data/mysql/*") -INSTALL(FILES ${datafiles} DESTINATION data/clean/mysql) -INSTALL(FILES win/data/maria_log.00000001 win/data/maria_log_control DESTINATION data/clean) -INSTALL(DIRECTORY win/data/test DESTINATION data/clean) -SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS} - IfFileExists '$INSTDIR\\\\data\\\\mysql\\\\db.frm' 0 CopyDatabaseFiles - MessageBox MB_OK 'There are already database files present in the data directory. Clean database files are not written to the directory' - GoTo EndCopyDatabaseFiles - CopyDatabaseFiles: - CopyFiles '$INSTDIR\\\\data\\\\clean\\\\*' '$INSTDIR\\\\data' - EndCopyDatabaseFiles:") -SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} - MessageBox MB_OK 'This will not delete the database files in $INSTDIR\\\\data'") - -# Files in the share dir -INSTALL(FILES sql/share/errmsg.txt DESTINATION share COMPONENT runtime) -FILE(GLOB charsets sql/share/charsets/*) -INSTALL(FILES ${charsets} DESTINATION share/charsets COMPONENT runtime) -FILE(GLOB share_dirs sql/share/*/errmsg.sys) -FOREACH(ERRMSGFILE ${share_dirs}) - STRING(REPLACE "//" "/" ERRMSGFILE ${ERRMSGFILE}) # Work around a cmake bug - FILE(RELATIVE_PATH DIRNAME ${PROJECT_SOURCE_DIR}/sql/share ${ERRMSGFILE}) - STRING(REPLACE "/errmsg.sys" "" DIRNAME ${DIRNAME}) - INSTALL(FILES ${ERRMSGFILE} DESTINATION share/${DIRNAME} COMPONENT runtime) -ENDFOREACH(ERRMSGFILE ${share_dirs}) - -# MTR files -FILE(GLOB_RECURSE testfiles mysql-test/*) -FOREACH(testfile ${testfiles}) - FILE(RELATIVE_PATH dirname ${PROJECT_SOURCE_DIR} ${testfile}) - GET_FILENAME_COMPONENT(dirname ${dirname} PATH) - GET_FILENAME_COMPONENT(filename ${testfile} NAME) - GET_FILENAME_COMPONENT(ext ${testfile} EXT) - SET(ok "yes") - IF (NOT "x_${ext}" STREQUAL "x_") - # Test if this is one of the extensions we don't want to install - STRING(TOLOWER ${ext} ext) - IF(${ext} STREQUAL ".dir" OR ${ext} STREQUAL ".vcproj" OR ${ext} STREQUAL ".user" OR ${ext} STREQUAL ".ilk" - OR ${ext} STREQUAL ".idb" OR ${ext} STREQUAL ".map" OR ${ext} STREQUAL ".gcov" - OR ${ext} STREQUAL ".supp" OR ${ext} STREQUAL ".am" OR ${ext} STREQUAL ".stress") - SET(ok "no") - ENDIF() - ENDIF(NOT "x_${ext}" STREQUAL "x_") - IF (${ok} STREQUAL "yes") - # Message("Dir: ${dirname}. File: ${filename}. Ext: ${ext}") - INSTALL(FILES ${testfile} DESTINATION ${dirname} COMPONENT mysqltest) - ENDIF(${ok} STREQUAL "yes") -ENDFOREACH(testfile ${testfiles}) - -# SQL Bench -FILE(GLOB_RECURSE benchfiles sql-bench/*) -FOREACH(testfile ${testfiles}) - FILE(RELATIVE_PATH dirname ${PROJECT_SOURCE_DIR} ${testfile}) - GET_FILENAME_COMPONENT(dirname ${dirname} PATH) - GET_FILENAME_COMPONENT(filename ${testfile} NAME) - IF(NOT ${dirname} STREQUAL "sql-bench" OR ${filename} STREQUAL "README") - INSTALL(FILES ${testfile} DESTINATION ${dirname} COMPONENT sqlbench) - ENDIF() -ENDFOREACH(testfile ${testfiles}) - -INCLUDE(InstallRequiredSystemLibraries) - +IF(WIN32) + SET(CPACK_GENERATOR "ZIP") +ENDIF() +INSTALL(FILES + ${CMAKE_BINARY_DIR}/support-files/my-huge.ini + ${CMAKE_BINARY_DIR}/support-files/my-large.ini + ${CMAKE_BINARY_DIR}/support-files/my-medium.ini + ${CMAKE_BINARY_DIR}/support-files/my-small.ini + DESTINATION . + COMPONENT IniFiles +) +INSTALL(FILES + COPYING + EXCEPTIONS-CLIENT + DESTINATION . + COMPONENT Readme +) +IF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" STREQUAL "2.8.3") + # CMake bug#11452, only in 2.8.3 + SET(CPACK_MONOLITHIC_INSTALL 1 CACHE INTERNAL "") +ENDIF() # This must always be the last line INCLUDE(CPack) diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt index ac17a375926..9795dd72252 100644 --- a/Docs/sp-imp-spec.txt +++ b/Docs/sp-imp-spec.txt @@ -1075,7 +1075,7 @@ 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', - 'NOT_USED', + 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', @@ -1097,4 +1097,4 @@ ) comment='Stored Procedures'; -- -
\ No newline at end of file + diff --git a/Makefile.am b/Makefile.am index 1371f06c743..cc1156fce5a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,8 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \ config/ac-macros/libevent_configure.m4 SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ @readline_topdir@ sql-common scripts \ - @sql_union_dirs@ unittest \ + libservices \ + @sql_union_dirs@ storage \ @sql_server@ @man_dirs@ tests \ netware @libmysqld_dirs@ \ mysql-test support-files sql-bench @tools_dirs@ \ @@ -33,6 +34,7 @@ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ DIST_SUBDIRS = . include Docs zlib \ cmd-line-utils sql-common scripts \ + libservices \ strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \ vio sql man tests \ netware libmysqld \ @@ -138,14 +140,14 @@ smoke: test-full: test test-nr test-ps test-force: - $(MAKE) force=--force test + $(MAKE) -k force=--force test test-force-full: - $(MAKE) force=--force test-full + $(MAKE) -k force=--force test-full #used by autopush.pl to run memory based tests test-force-mem: - $(MAKE) force=--force mem=--mem test + $(MAKE) -k force=--force mem=--mem test test-bt: -cd mysql-test ; MTR_BUILD_THREAD=auto \ @@ -259,7 +261,7 @@ test-fast-prepare: $(MAKE) subset=--ps-protocol test-fast test-full-qa: - $(MAKE) force=--force test-pr \ + $(MAKE) -k force=--force test-pr \ test-binlog-statement test-ext test-fast-view \ test-fast-cursor test-unit @@ -269,12 +271,13 @@ test-full-qa: # after which TEST_PREPROCESSOR_HEADER will be used. # -API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \ - $(top_srcdir)/include/mysql.h +API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql.h \ + $(top_srcdir)/include/mysql/client_plugin.h \ + $(top_srcdir)/include/mysql/plugin_auth.h -TEST_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \ - $(top_srcdir)/sql/mysql_priv.h \ - $(top_srcdir)/include/mysql.h +TEST_PREPROCESSOR_HEADER = $(API_PREPROCESSOR_HEADER) \ + $(top_srcdir)/sql/mysql_priv.h + # # Rules for checking that the abi/api has not changed. diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c04b4fc4b59..5780da71bef 100755 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -15,7 +15,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") -# We use the "mysqlclient_notls" library here just as safety, in case +# We use the "mysqlclient" library here just as safety, in case # any of the clients here would go beyond the client API and access the # Thread Local Storage directly. @@ -26,61 +26,48 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/libmysql ${CMAKE_SOURCE_DIR}/regex ${CMAKE_SOURCE_DIR}/sql - ${CMAKE_SOURCE_DIR}/strings) + ${CMAKE_SOURCE_DIR}/strings + ${CMAKE_CURRENT_BINARY_DIR}) -ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c) -TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysql mysqlclient wsock32) -ADD_EXECUTABLE(mysqltest mysqltest.cc) +MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc DESTINATION bin) SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS") TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex wsock32 dbug) -ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) -TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqlcheck mysqlcheck.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient wsock32) -ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c ../mysys/mf_getdate.c) -TARGET_LINK_LIBRARIES(mysqldump mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c ../mysys/mf_getdate.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqldump mysqlclient wsock32) -ADD_EXECUTABLE(mysqlimport mysqlimport.c) -TARGET_LINK_LIBRARIES(mysqlimport mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqlimport mysqlimport.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqlimport mysqlclient wsock32) -ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c) -TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient wsock32) ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs) -ADD_EXECUTABLE(mysqlshow mysqlshow.c) -TARGET_LINK_LIBRARIES(mysqlshow mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqlshow mysqlshow.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqlshow mysqlclient wsock32) -ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc +MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/mf_tempdir.c ../mysys/my_new.cc ../mysys/my_bit.c ../mysys/my_bitmap.c ../mysys/my_vle.c - ../mysys/base64.c) -TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient_notls wsock32) + ../mysys/base64.c + DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient wsock32) -ADD_EXECUTABLE(mysqladmin mysqladmin.cc) -TARGET_LINK_LIBRARIES(mysqladmin mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqladmin mysqlclient wsock32) -ADD_EXECUTABLE(mysqlslap mysqlslap.c) +MYSQL_ADD_EXECUTABLE(mysqlslap mysqlslap.c DESTINATION bin) SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS") TARGET_LINK_LIBRARIES(mysqlslap mysqlclient mysys zlib wsock32 dbug) -ADD_EXECUTABLE(echo echo.c) -IF(EMBED_MANIFESTS) - MYSQL_EMBED_MANIFEST("mysql" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqltest" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqlcheck" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqldump" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqlimport" "asInvoker") - MYSQL_EMBED_MANIFEST("mysql_upgrade" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqlshow" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqlbinlog" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqladmin" "asInvoker") - MYSQL_EMBED_MANIFEST("echo" "asInvoker") -ENDIF(EMBED_MANIFESTS) - -INSTALL(TARGETS mysql mysqltest mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow - mysqlbinlog mysqladmin mysqlslap echo DESTINATION bin COMPONENT runtime) +MYSQL_ADD_EXECUTABLE(echo echo.c COMPONENT Test) diff --git a/client/Makefile.am b/client/Makefile.am index 9fdbf0bfceb..4e7fe46d9fc 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -98,14 +98,15 @@ mysql_upgrade_SOURCES= mysql_upgrade.c \ # Fix for mit-threads DEFS = -DMYSQL_CLIENT_NO_THREADS \ - -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \ - -DMYSQL_DATADIR="\"$(localstatedir)\"" + -DDEFAULT_MYSQL_HOME='"$(prefix)"' \ + -DMYSQL_DATADIR='"$(localstatedir)"' sql_src=log_event.h mysql_priv.h rpl_constants.h \ rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \ log_event.cc my_decimal.h my_decimal.cc \ log_event_old.h log_event_old.cc \ - rpl_record_old.h rpl_record_old.cc + rpl_record_old.h rpl_record_old.cc \ + sql_list.h rpl_filter.h sql_list.cc rpl_filter.cc strings_src=decimal.c strings_def.h link_sources: diff --git a/client/client_priv.h b/client/client_priv.h index 773d65c5d1e..9ad627f0832 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -62,6 +62,7 @@ enum options_client OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG, OPT_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME, OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT, + OPT_FLUSH_TABLES, #ifdef HAVE_NDBCLUSTER_DB OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, #endif @@ -95,5 +96,8 @@ enum options_client OPT_ABORT_SOURCE_ON_ERROR, OPT_FIRST_SLAVE, OPT_ALL, - OPT_MAX_CLIENT_OPTION + OPT_REWRITE_DB, + OPT_PLUGIN_DIR, + OPT_DEFAULT_PLUGIN, + OPT_MAX_CLIENT_OPTION /* should be always the last */ }; diff --git a/client/mysql.cc b/client/mysql.cc index 4d761945068..82ffaa22032 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -151,7 +151,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, default_charset_used= 0, opt_secure_auth= 0, default_pager_set= 0, opt_sigint_ignore= 0, - show_warnings= 0, executing_query= 0, interrupted_query= 0, + show_warnings= 0, executing_query= 0, ignore_spaces= 0; static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error; static my_bool column_types_flag; @@ -162,6 +162,7 @@ static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static uint my_end_arg; static char * opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; +static int interrupted_query= 0; static char *current_host,*current_db,*current_user=0,*opt_password=0, *current_prompt=0, *delimiter_str= 0, *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; @@ -174,6 +175,7 @@ static int wait_time = 5; static STATUS status; static ulong select_limit,max_join_size,opt_connect_timeout=0; static char mysql_charsets_dir[FN_REFLEN+1]; +static char *opt_plugin_dir= 0, *opt_default_auth; static const char *xmlmeta[] = { "&", "&", "<", "<", @@ -1028,7 +1030,8 @@ static COMMANDS commands[] = { { (char *)NULL, 0, 0, 0, ""} }; -static const char *load_default_groups[]= { "mysql","client",0 }; +static const char *load_default_groups[]= +{ "mysql", "client", "client-server", "client-mariadb", 0 }; static int embedded_server_arg_count= 0; static char *embedded_server_args[MAX_SERVER_ARGS]; @@ -1576,6 +1579,13 @@ static struct my_option my_long_options[] = {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.", &show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default_auth", OPT_PLUGIN_DIR, + "Default authentication client-side plugin to use.", + (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -3622,7 +3632,7 @@ static void print_warnings() mysql_store_result_for_lazy(&result); /* Bail out when no warnings */ - if (!(num_rows= mysql_num_rows(result))) + if (!result || !(num_rows= mysql_num_rows(result))) goto end; cur= mysql_fetch_row(result); @@ -3987,7 +3997,7 @@ static int com_connect(String *buffer, char *line) { char *tmp, buff[256]; - bool save_rehash= opt_rehash; + my_bool save_rehash= opt_rehash; int error; bzero(buff, sizeof(buff)); @@ -4286,6 +4296,57 @@ char *get_arg(char *line, my_bool get_next_arg) } +/** + An example of mysql_authentication_dialog_ask callback. + + The C function with the name "mysql_authentication_dialog_ask", if exists, + will be used by the "dialog" client authentication plugin when user + input is needed. This function should be of mysql_authentication_dialog_ask_t + type. If the function does not exists, a built-in implementation will be + used. + + @param mysql mysql + @param type type of the input + 1 - normal string input + 2 - password string + @param prompt prompt + @param buf a buffer to store the use input + @param buf_len the length of the buffer + + @retval a pointer to the user input string. + It may be equal to 'buf' or to 'mysql->password'. + In all other cases it is assumed to be an allocated + string, and the "dialog" plugin will free() it. +*/ + +extern "C" char *mysql_authentication_dialog_ask(MYSQL *mysql, int type, + const char *prompt, + char *buf, int buf_len) +{ + char *s=buf; + + fputs("[mariadb] ", stdout); + fputs(prompt, stdout); + fputs(" ", stdout); + + if (type == 2) /* password */ + { + s= get_tty_password(""); + strnmov(buf, s, buf_len); + buf[buf_len-1]= 0; + my_free(s, MYF(0)); + } + else + { + if (!fgets(buf, buf_len-1, stdin)) + buf[0]= 0; + else if (buf[0] && (s= strend(buf))[-1] == '\n') + s[-1]= 0; + } + + return buf; +} + static int sql_real_connect(char *host,char *database,char *user,char *password, uint silent) @@ -4331,6 +4392,13 @@ sql_real_connect(char *host,char *database,char *user,char *password, } if (default_charset_used) mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); + + if (opt_plugin_dir && *opt_plugin_dir) + mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir); + + if (opt_default_auth && *opt_default_auth) + mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); + if (!mysql_real_connect(&mysql, host, user, password, database, opt_mysql_port, opt_mysql_unix_port, connect_flag | CLIENT_MULTI_STATEMENTS)) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 90a5ed6dad0..c6e54cba67b 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -819,8 +819,10 @@ static int run_sql_fix_privilege_tables(void) static const char *load_default_groups[]= { - "client", /* Read settings how to connect to server */ - "mysql_upgrade", /* Read special settings for mysql_upgrade*/ + "client", /* Read settings how to connect to server */ + "mysql_upgrade", /* Read special settings for mysql_upgrade */ + "client-server", /* Reads settings common between client & server */ + "client-mariadb", /* Read mariadb unique client settings */ 0 }; diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 22a58e31f2c..0716e391ab4 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -26,7 +26,7 @@ #include <mysql.h> #include <sql_common.h> -#define ADMIN_VERSION "8.42" +#define ADMIN_VERSION "9.0" #define MAX_MYSQL_VAR 512 #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ #define MAX_TRUNC_LENGTH 3 @@ -99,7 +99,10 @@ enum commands { ADMIN_FLUSH_HOSTS, ADMIN_FLUSH_TABLES, ADMIN_PASSWORD, ADMIN_PING, ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS, ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE, ADMIN_STOP_SLAVE, - ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD + ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD, ADMIN_FLUSH_SLOW_LOG, + ADMIN_FLUSH_TABLE_STATISTICS, ADMIN_FLUSH_INDEX_STATISTICS, + ADMIN_FLUSH_USER_STATISTICS, ADMIN_FLUSH_CLIENT_STATISTICS, + ADMIN_FLUSH_ALL_STATUS, ADMIN_FLUSH_ALL_STATISTICS }; static const char *command_names[]= { "create", "drop", "shutdown", @@ -109,7 +112,10 @@ static const char *command_names[]= { "flush-hosts", "flush-tables", "password", "ping", "extended-status", "flush-status", "flush-privileges", "start-slave", "stop-slave", - "flush-threads","old-password", + "flush-threads", "old-password", "flush-slow-log", + "flush-table-statistics", "flush-index-statistics", + "flush-user-statistics", "flush-client-statistics", + "flush-all-status", "flush-all-statistics", NullS }; @@ -219,7 +225,8 @@ static struct my_option my_long_options[] = }; -static const char *load_default_groups[]= { "mysqladmin","client",0 }; +static const char *load_default_groups[]= +{ "mysqladmin", "client", "client-server", "client-mariadb", 0 }; my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), @@ -597,7 +604,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) for (; argc > 0 ; argv++,argc--) { - switch (find_type(argv[0],&command_typelib,2)) { + int command; + switch ((command= find_type(argv[0],&command_typelib,2))) { case ADMIN_CREATE: { char buff[FN_REFLEN+20]; @@ -674,7 +682,11 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (mysql_refresh(mysql, (uint) ~(REFRESH_GRANT | REFRESH_STATUS | REFRESH_READ_LOCK | REFRESH_SLAVE | - REFRESH_MASTER))) + REFRESH_MASTER | REFRESH_TABLE_STATS | + REFRESH_INDEX_STATS | + REFRESH_USER_STATS | + REFRESH_SLOW_QUERY_LOG | + REFRESH_CLIENT_STATS))) { my_printf_error(0, "refresh failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -692,7 +704,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_VER: new_line=1; print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); + puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc,\n" + "2009 Monty Program Ab"); puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); printf("Server version\t\t%s\n", mysql_get_server_info(mysql)); printf("Protocol version\t%d\n", mysql_get_proto_info(mysql)); @@ -868,9 +881,19 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_LOGS: { - if (mysql_refresh(mysql,REFRESH_LOG)) + if (mysql_query(mysql,"flush logs")) { - my_printf_error(0, "refresh failed; error: '%s'", error_flags, + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_SLOW_LOG: + { + if (mysql_query(mysql,"flush slow query logs")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -880,7 +903,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_query(mysql,"flush hosts")) { - my_printf_error(0, "refresh failed; error: '%s'", error_flags, + my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -890,7 +913,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_query(mysql,"flush tables")) { - my_printf_error(0, "refresh failed; error: '%s'", error_flags, + my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -900,7 +923,71 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_query(mysql,"flush status")) { - my_printf_error(0, "refresh failed; error: '%s'", error_flags, + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_TABLE_STATISTICS: + { + if (mysql_query(mysql,"flush table_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_INDEX_STATISTICS: + { + if (mysql_query(mysql,"flush index_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_USER_STATISTICS: + { + if (mysql_query(mysql,"flush user_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_CLIENT_STATISTICS: + { + if (mysql_query(mysql,"flush client_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_ALL_STATISTICS: + { + if (mysql_query(mysql, + "flush table_statistics,index_statistics," + "user_statistics,client_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_ALL_STATUS: + { + if (mysql_query(mysql, + "flush status,table_statistics,index_statistics," + "user_statistics,client_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -1072,7 +1159,8 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); + puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc,\n" + "2009 Monty Program Ab"); puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); puts("Administration program for the mysqld daemon."); printf("Usage: %s [OPTIONS] command command....\n", my_progname); @@ -1080,16 +1168,23 @@ static void usage(void) my_print_variables(my_long_options); print_defaults("my",load_default_groups); puts("\nWhere command is a one or more of: (Commands may be shortened)\n\ - create databasename Create a new database\n\ - debug Instruct server to write debug information to log\n\ - drop databasename Delete a database and all its tables\n\ - extended-status Gives an extended status message from the server\n\ - flush-hosts Flush all cached hosts\n\ - flush-logs Flush all logs\n\ - flush-status Clear status variables\n\ - flush-tables Flush all tables\n\ - flush-threads Flush the thread cache\n\ - flush-privileges Reload grant tables (same as reload)\n\ + create databasename Create a new database\n\ + debug Instruct server to write debug information to log\n\ + drop databasename Delete a database and all its tables\n\ + extended-status Gives an extended status message from the server\n\ + flush-all-statistics Flush all statistics tables\n\ + flush-all-status Flush status and statistics\n\ + flush-client-statistics Flush client statistics\n\ + flush-hosts Flush all cached hosts\n\ + flush-index-statistics Flush index statistics\n\ + flush-logs Flush all logs\n\ + flush-privileges Reload grant tables (same as reload)\n\ + flush-slow-log Flush slow query log\n\ + flush-status Clear status variables\n\ + flush-table-statistics Clear table statistics\n\ + flush-tables Flush all tables\n\ + flush-threads Flush the thread cache\n\ + flush-user-statistics Flush user statistics\n\ kill id,id,... Kill mysql threads"); #if MYSQL_VERSION_ID >= 32200 puts("\ @@ -1380,7 +1475,7 @@ static my_bool wait_pidfile(char *pidfile, time_t last_modified, struct stat *pidfile_status) { char buff[FN_REFLEN]; - int error= 1; + my_bool error= 1; uint count= 0; DBUG_ENTER("wait_pidfile"); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 2a77578401a..c1473b18486 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -37,6 +37,15 @@ #include "log_event.h" #include "sql_common.h" +/* Needed for Rpl_filter */ +CHARSET_INFO* system_charset_info= &my_charset_utf8_general_ci; + +#include "sql_string.h" // needed for Rpl_filter +#include "sql_list.h" // needed for Rpl_filter +#include "rpl_filter.h" + +Rpl_filter *binlog_filter; + #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) @@ -58,7 +67,8 @@ static FILE *result_file; #ifndef DBUG_OFF static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; #endif -static const char *load_default_groups[]= { "mysqlbinlog","client",0 }; +static const char *load_default_groups[]= +{ "mysqlbinlog", "client", "client-server", "client-mariadb", 0 }; static void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); static void warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); @@ -622,6 +632,47 @@ static bool shall_skip_database(const char *log_dbname) /** + Print "use <db>" statement when current db is to be changed. + + We have to control emiting USE statements according to rewrite-db options. + We have to do it here (see process_event() below) and to suppress + producing USE statements by corresponding log event print-functions. +*/ + +static void +print_use_stmt(PRINT_EVENT_INFO* pinfo, const Query_log_event *ev) +{ + const char* db= ev->db; + const size_t db_len= ev->db_len; + + // pinfo->db is the current db. + // If current db is the same as required db, do nothing. + if ((ev->flags & LOG_EVENT_SUPPRESS_USE_F) || !db || + !memcmp(pinfo->db, db, db_len + 1)) + return; + + // Current db and required db are different. + // Check for rewrite rule for required db. (Note that in a rewrite rule + // neither db_from nor db_to part can be empty). + size_t len_to= 0; + const char *db_to= binlog_filter->get_rewrite_db(db, &len_to); + + // If there is no rewrite rule for db (in this case len_to is left = 0), + // printing of the corresponding USE statement is left for log event + // print-function. + if (!len_to) + return; + + // In case of rewrite rule print USE statement for db_to + fprintf(result_file, "use %s%s\n", db_to, pinfo->delimiter); + + // Copy the *original* db to pinfo to suppress emiting + // of USE stmts by log_event print-functions. + memcpy(pinfo->db, db, db_len + 1); +} + + +/** Prints the given event in base64 format. The header is printed to the head cache and the body is printed to @@ -740,9 +791,11 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, switch (ev_type) { case QUERY_EVENT: - if (!((Query_log_event*)ev)->is_trans_keyword() && - shall_skip_database(((Query_log_event*)ev)->db)) + { + Query_log_event *qe= (Query_log_event*)ev; + if (!qe->is_trans_keyword() && shall_skip_database(qe->db)) goto end; + print_use_stmt(print_event_info, qe); if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) { if ((retval= write_event_header_and_base64(ev, result_file, @@ -753,6 +806,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, else ev->print(result_file, print_event_info); break; + } case CREATE_FILE_EVENT: { @@ -874,6 +928,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, if (!shall_skip_database(exlq->db)) { + print_use_stmt(print_event_info, exlq); if (fname) { convert_path_to_forward_slashes(fname); @@ -897,6 +952,13 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, destroy_evt= FALSE; goto end; } + size_t len_to= 0; + const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to); + if (len_to && map->rewrite_db(db_to, len_to, glob_description_event)) + { + error("Could not rewrite database name"); + goto err; + } } case WRITE_ROWS_EVENT: case DELETE_ROWS_EVENT: @@ -982,14 +1044,16 @@ err: retval= ERROR_STOP; end: rec_count++; + /* - Destroy the log_event object. If reading from a remote host, - set the temp_buf to NULL so that memory isn't freed twice. + Destroy the log_event object. + MariaDB MWL#36: mainline does this: + If reading from a remote host, + set the temp_buf to NULL so that memory isn't freed twice. + We no longer do that, we use Rpl_filter::event_owns_temp_buf instead. */ if (ev) { - if (remote_opt) - ev->temp_buf= 0; if (destroy_evt) /* destroy it later if not set (ignored table map) */ delete ev; } @@ -1155,6 +1219,10 @@ that may lead to an endless loop.", "Used to reserve file descriptors for use by this program.", &open_files_limit, &open_files_limit, 0, GET_ULONG, REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, + {"rewrite-db", OPT_REWRITE_DB, + "Updates to a database with a different name than the original. \ +Example: rewrite-db='from->to'.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1349,6 +1417,53 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); } break; + case OPT_REWRITE_DB: // db_from->db_to + { + /* See also handling of OPT_REPLICATE_REWRITE_DB in sql/mysqld.cc */ + char* ptr; + char* key= argument; // db-from + char* val; // db-to + + // Where key begins + while (*key && my_isspace(&my_charset_latin1, *key)) + key++; + + // Where val begins + if (!(ptr= strstr(argument, "->"))) + { + sql_print_error("Bad syntax in rewrite-db: missing '->'!\n"); + return 1; + } + val= ptr + 2; + while (*val && my_isspace(&my_charset_latin1, *val)) + val++; + + // Write \0 and skip blanks at the end of key + *ptr-- = 0; + while (my_isspace(&my_charset_latin1, *ptr) && ptr > argument) + *ptr-- = 0; + + if (!*key) + { + sql_print_error("Bad syntax in rewrite-db: empty db-from!\n"); + return 1; + } + + // Skip blanks at the end of val + ptr= val; + while (*ptr && !my_isspace(&my_charset_latin1, *ptr)) + ptr++; + *ptr= 0; + + if (!*val) + { + sql_print_error("Bad syntax in rewrite-db: empty db-to!\n"); + return 1; + } + + binlog_filter->add_db_rewrite(key, val); + break; + } case 'v': if (argument == disabled_my_option) verbose= 0; @@ -1393,7 +1508,7 @@ static int parse_args(int *argc, char*** argv) */ static Exit_status safe_connect() { - /* Close and old connections to MySQL */ + /* Close any old connections to MySQL */ if (mysql) mysql_close(mysql); @@ -1622,7 +1737,7 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, If reading from a remote host, ensure the temp_buf for the Log_event class is pointing to the incoming stream. */ - ev->register_temp_buf((char *) net->read_pos + 1); + ev->register_temp_buf((char *) net->read_pos + 1, FALSE); Log_event_type type= ev->get_type_code(); if (glob_description_event->binlog_version >= 3 || @@ -2022,6 +2137,8 @@ end: return retval; } +/* Used in sql_alloc(). Inited and freed in main() */ +MEM_ROOT s_mem_root; int main(int argc, char** argv) { @@ -2034,8 +2151,16 @@ int main(int argc, char** argv) my_init_time(); // for time functions + init_alloc_root(&s_mem_root, 16384, 0); + if (!(binlog_filter= new Rpl_filter)) + { + error("Failed to create Rpl_filter"); + exit(1); + } + if (load_defaults("my", load_default_groups, &argc, &argv)) exit(1); + defaults_argv= argv; parse_args(&argc, (char***)&argv); @@ -2122,6 +2247,8 @@ int main(int argc, char** argv) if (result_file != stdout) my_fclose(result_file, MYF(0)); cleanup(); + delete binlog_filter; + free_root(&s_mem_root, MYF(0)); free_defaults(defaults_argv); my_free_open_file_info(); load_processor.destroy(); @@ -2133,6 +2260,12 @@ int main(int argc, char** argv) DBUG_RETURN(retval == ERROR_STOP ? 1 : 0); } + +void *sql_alloc(size_t size) +{ + return alloc_root(&s_mem_root, size); +} + /* We must include this here as it's compiled with different options for the server @@ -2143,4 +2276,7 @@ int main(int argc, char** argv) #include "my_decimal.cc" #include "log_event.cc" #include "log_event_old.cc" +#include "sql_string.cc" +#include "sql_list.cc" +#include "rpl_filter.cc" diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index d45dccf328d..8bf6cbe8d83 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -16,7 +16,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#define CHECK_VERSION "2.6.0" +#define CHECK_VERSION "2.7.0" #include "client_priv.h" #include <m_ctype.h> @@ -35,8 +35,8 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0, opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0, tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0, - opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0, - opt_write_binlog= 1; + opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0; +static my_bool opt_write_binlog= 1, opt_flush_tables= 0; static uint verbose = 0, opt_mysql_port=0; static int my_end_arg; static char * opt_mysql_unix_port = 0; @@ -121,6 +121,9 @@ static struct my_option my_long_options[] = "If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will force using old slow repair with keycache method, instead of much faster repair by sorting.", &opt_extended, &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"flush", OPT_FLUSH_TABLES, "Flush each table after check. This is useful if you don't want to have the checked tables take up space in the caches after the check", + &opt_flush_tables, &opt_flush_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0 }, {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host",'h', "Connect to host.", ¤t_host, @@ -187,7 +190,8 @@ static struct my_option my_long_options[] = {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -static const char *load_default_groups[] = { "mysqlcheck", "client", 0 }; +static const char *load_default_groups[]= +{ "mysqlcheck", "client", "client-server", "client-mariadb", 0 }; static void print_version(void); @@ -684,6 +688,7 @@ static int disable_binlog() static int handle_request_for_tables(char *tables, uint length) { char *query, *end, options[100], message[100]; + char table_name_buff[NAME_CHAR_LEN*2*2+1], *table_name; uint query_length= 0; const char *op = 0; @@ -722,13 +727,17 @@ static int handle_request_for_tables(char *tables, uint length) /* No backticks here as we added them before */ query_length= my_sprintf(query, (query, "%s TABLE %s %s", op, tables, options)); + table_name= tables; } else { - char *ptr; + char *ptr, *org; - ptr= strmov(strmov(query, op), " TABLE "); + org= ptr= strmov(strmov(query, op), " TABLE "); ptr= fix_table_name(ptr, tables); + strmake(table_name_buff, org, min((int) sizeof(table_name_buff)-1, + (int) (ptr - org))); + table_name= table_name_buff; ptr= strxmov(ptr, " ", options, NullS); query_length= (uint) (ptr - query); } @@ -736,9 +745,21 @@ static int handle_request_for_tables(char *tables, uint length) { sprintf(message, "when executing '%s TABLE ... %s'", op, options); DBerror(sock, message); + my_free(query, MYF(0)); return 1; } print_result(); + if (opt_flush_tables) + { + query_length= my_sprintf(query, + (query, "FLUSH TABLES %s", table_name)); + if (mysql_real_query(sock, query, query_length)) + { + DBerror(sock, query); + my_free(query, MYF(0)); + return 1; + } + } my_free(query, MYF(0)); return 0; } diff --git a/client/mysqldump.c b/client/mysqldump.c index bd43da936a3..ee376e36e1a 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -38,7 +38,7 @@ ** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov */ -#define DUMP_VERSION "10.13" +#define DUMP_VERSION "10.14" #include <my_global.h> #include <my_sys.h> @@ -482,7 +482,8 @@ static struct my_option my_long_options[] = {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -static const char *load_default_groups[]= { "mysqldump","client",0 }; +static const char *load_default_groups[]= +{ "mysqldump", "client", "client-server", "client-mariadb", 0 }; static void maybe_exit(int error); static void die(int error, const char* reason, ...); @@ -633,8 +634,13 @@ static void write_header(FILE *sql_file, char *db_name) if (!path) { + if (!opt_no_create_info) + { + /* We don't need unique checks as the table is created just before */ + fprintf(md_result_file,"\ +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n"); + } fprintf(md_result_file,"\ -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n\ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n\ "); } @@ -664,8 +670,12 @@ static void write_footer(FILE *sql_file) if (!path) { fprintf(md_result_file,"\ -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n\ +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n"); + if (!opt_no_create_info) + { + fprintf(md_result_file,"\ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n"); + } } if (opt_set_charset) fprintf(sql_file, diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 8a71a07e471..654f19f6f57 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -185,7 +185,8 @@ static struct my_option my_long_options[] = }; -static const char *load_default_groups[]= { "mysqlimport","client",0 }; +static const char *load_default_groups[]= +{ "mysqlimport","client", "client-server", "client-mariadb", 0 }; #include <help_start.h> diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 955cfe4442a..e1cbfcb9404 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -55,7 +55,8 @@ static void print_res_header(MYSQL_RES *result); static void print_res_top(MYSQL_RES *result); static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur); -static const char *load_default_groups[]= { "mysqlshow","client",0 }; +static const char *load_default_groups[]= +{ "mysqlshow","client", "client-server", "client-mariadb", 0 }; static char * opt_mysql_unix_port=0; int main(int argc, char **argv) diff --git a/client/mysqlslap.c b/client/mysqlslap.c index cbd244d802b..196cdc6f394 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -179,7 +179,8 @@ static uint opt_protocol= 0; static int get_options(int *argc,char ***argv); static uint opt_mysql_port= 0; -static const char *load_default_groups[]= { "mysqlslap","client",0 }; +static const char *load_default_groups[]= +{ "mysqlslap", "client", "client-server", "client-mariadb", 0 }; typedef struct statement statement; diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 668d9ba45ba..84cbd314b4a 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -39,6 +39,7 @@ #include "client_priv.h" #include <mysql_version.h> #include <mysqld_error.h> +#include <sql_common.h> #include <m_ctype.h> #include <my_dir.h> #include <hash.h> @@ -120,7 +121,8 @@ static my_bool abort_on_error= 1; static my_bool server_initialized= 0; static my_bool is_windows= 0; static char **default_argv; -static const char *load_default_groups[]= { "mysqltest", "client", 0 }; +static const char *load_default_groups[]= +{ "mysqltest", "client", "client-server", "client-mariadb", 0 }; static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer; static uint start_lineno= 0; /* Start line of current command */ @@ -602,6 +604,10 @@ public: DBUG_VOID_RETURN; DBUG_ASSERT(ds->str); +#ifdef EXTRA_DEBUG + DBUG_PRINT("QQ", ("str: %*s", (int) ds->length, ds->str)); +#endif + if (fwrite(ds->str, 1, ds->length, m_file) != ds->length) die("Failed to write %lu bytes to '%s', errno: %d", (unsigned long)ds->length, m_file_name, errno); @@ -1294,6 +1300,7 @@ void die(const char *fmt, ...) DBUG_ENTER("die"); DBUG_PRINT("enter", ("start_lineno: %d", start_lineno)); + fflush(stdout); /* Print the error message */ fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) @@ -1380,6 +1387,7 @@ void verbose_msg(const char *fmt, ...) if (!verbose) DBUG_VOID_RETURN; + fflush(stdout); va_start(args, fmt); fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) @@ -1390,6 +1398,7 @@ void verbose_msg(const char *fmt, ...) vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); va_end(args); + fflush(stderr); DBUG_VOID_RETURN; } @@ -1474,6 +1483,8 @@ static int run_command(char* cmd, char buf[512]= {0}; FILE *res_file; int error; + DBUG_ENTER("run_command"); + DBUG_PRINT("enter", ("cmd: %s", cmd)); if (!(res_file= popen(cmd, "r"))) die("popen(\"%s\", \"r\") failed", cmd); @@ -1494,7 +1505,7 @@ static int run_command(char* cmd, } error= pclose(res_file); - return WEXITSTATUS(error); + DBUG_RETURN(WEXITSTATUS(error)); } @@ -3843,13 +3854,15 @@ void do_change_user(struct st_command *command) } if (!ds_user.length) + { dynstr_set(&ds_user, mysql->user); - if (!ds_passwd.length) - dynstr_set(&ds_passwd, mysql->passwd); + if (!ds_passwd.length) + dynstr_set(&ds_passwd, mysql->passwd); - if (!ds_db.length) - dynstr_set(&ds_db, mysql->db); + if (!ds_db.length) + dynstr_set(&ds_db, mysql->db); + } DBUG_PRINT("info",("connection: '%s' user: '%s' password: '%s' database: '%s'", cur_con->name, ds_user.str, ds_passwd.str, ds_db.str)); @@ -4872,11 +4885,11 @@ char *get_string(char **to_ptr, char **from_ptr, } -void set_reconnect(MYSQL* mysql, int val) +void set_reconnect(MYSQL* mysql, my_bool val) { my_bool reconnect= val; DBUG_ENTER("set_reconnect"); - DBUG_PRINT("info", ("val: %d", val)); + DBUG_PRINT("info", ("val: %d", (int) val)); #if MYSQL_VERSION_ID < 50000 mysql->reconnect= reconnect; #else @@ -7566,6 +7579,15 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_append_mem(ds, "\n", 1); } + /* + Write the command to the result file before we execute the query + This is needed to be able to analyse the log if something goes + wrong + */ + log_file.write(&ds_res); + log_file.flush(); + dynstr_set(&ds_res, 0); + if (view_protocol_enabled && complete_query && match_re(&view_re, query)) @@ -7904,7 +7926,7 @@ void mark_progress(struct st_command* command __attribute__((unused)), die("Out of memory"); /* Milliseconds since start */ - end= longlong2str(timer, buf, 10); + end= longlong10_to_str(timer, buf, 10); dynstr_append_mem(&ds_progress, buf, (int)(end-buf)); dynstr_append_mem(&ds_progress, "\t", 1); @@ -8722,7 +8744,7 @@ void timer_output(void) { char buf[32], *end; ulonglong timer= timer_now() - timer_start; - end= longlong2str(timer, buf, 10); + end= longlong10_to_str(timer, buf, 10); str_to_file(timer_file,buf, (int) (end-buf)); /* Timer has been written to the file, don't use it anymore */ timer_file= 0; @@ -8884,15 +8906,15 @@ void free_replace() typedef struct st_replace { - my_bool found; + int found; struct st_replace *next[256]; } REPLACE; typedef struct st_replace_found { - my_bool found; - char *replace_string; + int found; uint to_offset; int from_offset; + char *replace_string; } REPLACE_STRING; @@ -8924,7 +8946,7 @@ void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds, } /* Found a string that needs to be replaced */ - DBUG_PRINT("info", ("found: %d, to_offset: %d, from_offset: %d, string: %s", + DBUG_PRINT("info", ("found: %d, to_offset: %u, from_offset: %d, string: %s", rep_str->found, rep_str->to_offset, rep_str->from_offset, rep_str->replace_string)); diff --git a/client/sql_string.cc b/client/sql_string.cc index ccb633c6d8e..3afc69b3ea6 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -28,15 +28,6 @@ #ifdef HAVE_FCONVERT #include <floatingpoint.h> #endif - -/* - The following extern declarations are ok as these are interface functions - required by the string function -*/ - -extern void sql_alloc(size_t size); -extern void sql_element_free(void *ptr); - #include "sql_string.h" /***************************************************************************** diff --git a/client/sql_string.h b/client/sql_string.h index e72bf42a5ba..6d8269a4b31 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -17,6 +17,9 @@ /* This file is originally from the mysql distribution. Coded by monty */ +#ifndef CLIENT_SQL_STRING_H +#define CLIENT_SQL_STRING_H + #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ #endif @@ -359,3 +362,5 @@ public: return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length); } }; + +#endif diff --git a/config/ac-macros/plugins.m4 b/config/ac-macros/plugins.m4 index 8af9cacbb6d..aba68dbe04c 100644 --- a/config/ac-macros/plugins.m4 +++ b/config/ac-macros/plugins.m4 @@ -38,6 +38,7 @@ AC_DEFUN([_MYSQL_PLUGIN],[ _MYSQL_PLUGAPPEND([__mysql_plugin_list__],[$1]) m4_define([MYSQL_PLUGIN_NAME_]AS_TR_CPP([$1]), [$3]) m4_define([MYSQL_PLUGIN_DESC_]AS_TR_CPP([$1]), [$4]) + m4_ifdef([_AC_ENABLE_IF], [_AC_ENABLE_IF([with],[plugin-$1])]) _MYSQL_PLUGAPPEND_META([$1], $5) ifelse(m4_bregexp(__mysql_include__,[/plug\.in$]),-1,[],[ MYSQL_PLUGIN_DIRECTORY([$1], @@ -216,6 +217,30 @@ AC_DEFUN([_MYSQL_PLUGIN_DISABLED],[ dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN_WITHOUT +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_WITHOUT([name]) +dnl +dnl DESCRIPTION +dnl Exclude the plugin from being built, as if --without-plugin-name +dnl was specified. +dnl If the plugin was selected manually by --with-plugin-name, +dnl excluding it here will abort the configure script with an error, +dnl otherwise plugin will be silently disabled. +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN_WITHOUT],[ + MYSQL_REQUIRE_PLUGIN([$1]) + if test "X[$with_plugin_]$1" = Xyes; then + AC_MSG_ERROR([Plugin $1 cannot be built]) + else + [mysql_plugin_]$1=no + fi +]) + +dnl --------------------------------------------------------------------------- dnl Macro: MYSQL_PLUGIN_DEPENDS dnl dnl SYNOPSIS @@ -348,7 +373,7 @@ dnl 11 - static target for libmysqld (if different from $7) dnl 12 - actions AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ m4_ifdef([$5],[ - AH_TEMPLATE($5, [Include ]$4[ into mysqld]) + AH_TEMPLATE($5, [Include ]$3[ into mysqld]) ]) AC_MSG_CHECKING([whether to use ]$3) mysql_use_plugin_dir="" @@ -356,12 +381,16 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ if test "X[$mysql_plugin_]$2" = Xyes -a \ "X[$with_plugin_]$2" != Xno -o \ "X[$with_plugin_]$2" = Xyes; then - AC_MSG_RESULT([error]) + __MYSQL_EMIT_CHECK_RESULT($3,[error]) AC_MSG_ERROR([disabled]) fi - AC_MSG_RESULT([no]) + __MYSQL_EMIT_CHECK_RESULT($3,[no]) ],[ + if test "X[$mysql_plugin_]$2" = Xno; then + [with_plugin_]$2=no + fi + # Plugin is not disabled, determine if it should be built, # or only distributed @@ -370,7 +399,7 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ # Plugin directory was removed after autoconf was run; treat # this as a disabled plugin if test "X[$with_plugin_]$2" = Xyes; then - AC_MSG_RESULT([error]) + __MYSQL_EMIT_CHECK_RESULT($3,[error]) AC_MSG_ERROR([disabled]) fi @@ -381,7 +410,7 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ m4_ifdef([$9],[ if test "X[$with_plugin_]$2" = Xno; then - AC_MSG_RESULT([error]) + __MYSQL_EMIT_CHECK_RESULT($3,[error]) AC_MSG_ERROR([cannot disable mandatory plugin]) fi [mysql_plugin_]$2=yes @@ -408,7 +437,7 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ if test "X[$with_plugin_]$2" = Xno; then - AC_MSG_RESULT([no]) + __MYSQL_EMIT_CHECK_RESULT($3,[no]) else m4_ifdef([$8],m4_ifdef([$7],[],[[with_plugin_]$2=''])) if test "X[$mysql_plugin_]$2" != Xyes -a \ @@ -422,16 +451,16 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ AC_SUBST([plugin_]$2[_static_target], [""]) AC_SUBST([plugin_]$2[_embedded_static_target], [""]) [with_plugin_]$2=yes - AC_MSG_RESULT([plugin]) + __MYSQL_EMIT_CHECK_RESULT($3,[plugin]) m4_ifdef([$6],[ else - [mysql_plugin_]$2=no - AC_MSG_RESULT([no]) + [with_plugin_]$2=no + __MYSQL_EMIT_CHECK_RESULT($3,[no]) fi ]) ],[ [with_plugin_]$2=no - AC_MSG_RESULT([no]) + __MYSQL_EMIT_CHECK_RESULT($3,[no]) ]) else m4_ifdef([$7],[ @@ -479,7 +508,7 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ AC_SUBST([plugin_]$2[_shared_target], [""]) ],[ m4_ifdef([$6],[ - AC_MSG_RESULT([error]) + __MYSQL_EMIT_CHECK_RESULT($3,[error]) AC_MSG_ERROR([Plugin $1 does not support static linking]) ],[ m4_ifdef([$5],[ @@ -489,9 +518,9 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ ]) ]) ]) - mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]" + maria_plugin_defs="$maria_plugin_defs, [builtin_maria_]$2[_plugin]" [with_plugin_]$2=yes - AC_MSG_RESULT([yes]) + __MYSQL_EMIT_CHECK_RESULT($3,[yes]) fi fi @@ -539,6 +568,12 @@ dnl ]) ]) +AC_DEFUN([__MYSQL_EMIT_CHECK_RESULT],[ + AC_MSG_RESULT($2) + plugin_report="[$plugin_report] +m4_format([ * %-32s $2],$1:)" +]) + AC_DEFUN([_MYSQL_EMIT_PLUGIN_ACTIONS],[ ifelse($#, 0, [], $#, 1, [ _MYSQL_EMIT_PLUGIN_ACTION([$1]) @@ -752,6 +787,10 @@ AC_DEFUN([_MYSQL_EMIT_PLUGINS],[ ]) AC_DEFUN([_MYSQL_EMIT_PLUGIN_ENABLE],[ + if test "X[$mysql_plugin_]$2" = Xno -a \ + "X[$with_plugin_]$2" != Xno; then + AC_MSG_ERROR([Plugin $1 cannot be built]) + fi m4_ifdef([$5],m4_ifdef([$4],[ [mysql_plugin_]$2=yes ],[ diff --git a/configure.in b/configure.in index e8a2979de68..2b7c2f715eb 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,8 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MariaDB Server], [5.1.60-MariaDB], [], [mysql]) + +AC_INIT([MariaDB Server], [5.2.9-MariaDB], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM @@ -869,7 +870,7 @@ AC_CHECK_HEADERS(fcntl.h fenv.h float.h floatingpoint.h fpu_control.h \ sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \ unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \ sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h \ - sys/prctl.h sys/resource.h sys/param.h port.h ieeefp.h \ + sys/prctl.h sys/resource.h sys/param.h port.h ieeefp.h linux/unistd.h \ execinfo.h) AC_CHECK_HEADERS([xfs/xfs.h]) @@ -1624,9 +1625,8 @@ case "$with_mysqld_ldflags " in ;; *) - # Check for dlopen, needed for user definable functions + # Check for dlopen, needed for user definable functions and plugins # This must be checked after threads on AIX - # We only need this for mysqld, not for the clients. my_save_LIBS="$LIBS" LIBS="" @@ -2146,7 +2146,18 @@ case "$target" in # We also disable for SCO for the time being, the headers for the # thread library we use conflicts with other headers. ;; - *) AC_CHECK_FUNCS(clock_gettime) +*) + # most systems require the program be linked with librt library to use + # the function clock_gettime + my_save_LIBS="$LIBS" + LIBS="" + AC_CHECK_LIB(rt,clock_gettime) + LIBRT=$LIBS + LIBS="$my_save_LIBS" + AC_SUBST(LIBRT) + + LIBS="$LIBS $LIBRT" + AC_CHECK_FUNCS(clock_gettime) ;; esac @@ -2835,7 +2846,7 @@ then fi sql_client_dirs="$sql_client_dirs client" -CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS" +CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT" AC_SUBST(CLIENT_LIBS) AC_SUBST(CLIENT_THREAD_LIBS) @@ -2885,7 +2896,7 @@ AC_SUBST(server_scripts) AC_SUBST(mysql_plugin_dirs) AC_SUBST(mysql_plugin_libs) AC_SUBST(mysql_embedded_plugin_libs) -AC_SUBST(mysql_plugin_defs) +AC_SUBST(maria_plugin_defs) # Now that sql_client_dirs and sql_server_dirs are stable, determine the union. @@ -2937,7 +2948,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl man/Makefile BUILD/Makefile vio/Makefile dnl libmysql/Makefile libmysql_r/Makefile client/Makefile dnl sql/Makefile sql/share/Makefile dnl - sql/sql_builtin.cc sql-common/Makefile dnl + sql/sql_builtin.cc sql-common/Makefile libservices/Makefile dnl dbug/Makefile scripts/Makefile include/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl support-files/MacOSX/Makefile support-files/RHEL4-SElinux/Makefile dnl @@ -2956,27 +2967,26 @@ AC_CONFIG_COMMANDS_POST(ac_configure_args="$ac_configure_args CFLAGS='$CFLAGS' C AC_OUTPUT -echo -echo "You can find information about MariaDB at" -echo http://askmonty.org/wiki/index.php/MariaDB -echo -echo "Remember to check the platform specific part of the reference manual for" -echo "hints about installing MariaDB on your platform. Also have a look at the" -echo "files in the Docs directory." -echo - echo "---" echo "Configuration summary for $PACKAGE_NAME version $VERSION" +echo "$plugin_report" | sort echo "" -echo " * Installation prefix: $prefix" -echo " * System type: $SYSTEM_TYPE" -echo " * Host CPU: $host_cpu" -echo " * C Compiler: $CC_VERSION" -echo " * C++ Compiler: $CXX_VERSION" -echo " * Debug enabled: $with_debug" -echo " * Community Features: $ENABLE_COMMUNITY_FEATURES" +echo " * Installation prefix: $prefix" +echo " * System type: $SYSTEM_TYPE" +echo " * Host CPU: $host_cpu" +echo " * C Compiler: $CC_VERSION" +echo " * C++ Compiler: $CXX_VERSION" +echo " * Debug enabled: $with_debug" +echo " * Community Features: $ENABLE_COMMUNITY_FEATURES" echo "" echo "---" +echo "" +echo "You can find information about MariaDB at" +echo "http://kb.askmonty.org/" +echo "" +echo "Remember to check the platform specific part of the reference manual for" +echo "hints about installing MariaDB on your platform. Also have a look at the" +echo "files in the Docs directory." # Add warning if user configures with --with-ndbcluster if test X"$with_plugin_ndbcluster" = Xyes ; then @@ -2989,6 +2999,6 @@ fi # The first line "Thank you ..." is checked in ./Do-compile to verify that configure # ended sucessfully - don't remove it. -echo +echo "" echo "Thank you for choosing MariaDB!" -echo +echo "" diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt index 6cc69d3251e..adb357cf790 100755 --- a/extra/CMakeLists.txt +++ b/extra/CMakeLists.txt @@ -22,34 +22,36 @@ TARGET_LINK_LIBRARIES(comp_err debug dbug mysys strings zlib wsock32) GET_TARGET_PROPERTY(COMP_ERR_EXE comp_err LOCATION) -ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/include/mysqld_error.h - COMMAND ${COMP_ERR_EXE} - --charset=${PROJECT_SOURCE_DIR}/sql/share/charsets - --out-dir=${PROJECT_SOURCE_DIR}/sql/share/ - --header_file=${PROJECT_SOURCE_DIR}/include/mysqld_error.h - --name_file=${PROJECT_SOURCE_DIR}/include/mysqld_ername.h - --state_file=${PROJECT_SOURCE_DIR}/include/sql_state.h - --in_file=${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt - DEPENDS comp_err ${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt) +# Generate mysqld_error.h +# Try not to change its timestamp if not necessary(as touching +# mysqld_error.h results in rebuild of the almost whole server) +# To preserve timestamp, first generate a temp header file, then copy it +# to mysqld_error.h using cmake -E copy_if_different +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp + COMMAND ${COMP_ERR_EXE} + --charset=${PROJECT_SOURCE_DIR}/sql/share/charsets + --out-dir=${CMAKE_BINARY_DIR}/sql/share/ + --header_file=${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp + --name_file=${CMAKE_BINARY_DIR}/include/mysqld_ername.h.tmp + --state_file=${CMAKE_BINARY_DIR}/include/sql_state.h.tmp + --in_file=${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp ${CMAKE_BINARY_DIR}/include/mysqld_error.h + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/include/mysqld_ername.h.tmp ${CMAKE_BINARY_DIR}/include/mysqld_ername.h + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/include/sql_state.h.tmp ${CMAKE_BINARY_DIR}/include/sql_state.h + DEPENDS comp_err ${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt) ADD_CUSTOM_TARGET(GenError ALL - DEPENDS ${PROJECT_SOURCE_DIR}/include/mysqld_error.h) + DEPENDS ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp) -ADD_EXECUTABLE(my_print_defaults my_print_defaults.c) +MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c) TARGET_LINK_LIBRARIES(my_print_defaults strings mysys debug dbug taocrypt wsock32) -ADD_EXECUTABLE(perror perror.c) +MYSQL_ADD_EXECUTABLE(perror perror.c) TARGET_LINK_LIBRARIES(perror strings mysys debug dbug wsock32) -ADD_EXECUTABLE(resolveip resolveip.c) +MYSQL_ADD_EXECUTABLE(resolveip resolveip.c) TARGET_LINK_LIBRARIES(resolveip strings mysys debug dbug wsock32) -ADD_EXECUTABLE(replace replace.c) +MYSQL_ADD_EXECUTABLE(replace replace.c COMPONENT Server) TARGET_LINK_LIBRARIES(replace strings mysys debug dbug wsock32) - -IF(EMBED_MANIFESTS) - MYSQL_EMBED_MANIFEST("myTest" "asInvoker") -ENDIF(EMBED_MANIFESTS) - -INSTALL(TARGETS comp_err my_print_defaults perror resolveip replace DESTINATION bin COMPONENT runtime) diff --git a/extra/libevent/CMakeLists.txt b/extra/libevent/CMakeLists.txt index 66961502357..6be15641d3e 100644 --- a/extra/libevent/CMakeLists.txt +++ b/extra/libevent/CMakeLists.txt @@ -1,7 +1,10 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/extra/libevent ${CMAKE_SOURCE_DIR}/extra/libevent/compat - ${CMAKE_SOURCE_DIR}/extra/libevent/WIN32-Code) + ${CMAKE_SOURCE_DIR}/extra/libevent/WIN32-Code + ${CMAKE_BINARY_DIR}/extra/libevent + ${CMAKE_SOURCE_DIR}/include +) IF(MSVC) ADD_DEFINITIONS("-DWIN32 -DHAVE_CONFIG_H") @@ -27,8 +30,14 @@ SET(LIBEVENT_SOURCES min_heap.h strlcpy-internal.h ) +IF(WIN32) + # Workaround source distribution bug, remove preconfigured event-config + IF(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + FILE(REMOVE ${CMAKE_SOURCE_DIR}/extra/libevent/event-config.h) + ENDIF() + CONFIGURE_FILE(WIN32-Code/config.h ${CMAKE_BINARY_DIR}/extra/libevent/event-config.h COPYONLY) +ENDIF() -CONFIGURE_FILE(WIN32-Code/config.h ${CMAKE_SOURCE_DIR}/extra/libevent/event-config.h COPYONLY) IF(NOT SOURCE_SUBLIBS) ADD_LIBRARY(libevent ${LIBEVENT_SOURCES}) ENDIF(NOT SOURCE_SUBLIBS) diff --git a/extra/libevent/event.h b/extra/libevent/event.h index 451ca895e2b..078c940770e 100644 --- a/extra/libevent/event.h +++ b/extra/libevent/event.h @@ -159,6 +159,8 @@ extern "C" { #endif +#include <my_attribute.h> + #include <event-config.h> #ifdef _EVENT_HAVE_SYS_TYPES_H #include <sys/types.h> diff --git a/extra/libevent/evutil.h b/extra/libevent/evutil.h index 46e4079715d..2cfcacb2e0e 100644 --- a/extra/libevent/evutil.h +++ b/extra/libevent/evutil.h @@ -171,21 +171,4 @@ ev_int64_t evutil_strtoll(const char *s, char **endptr, int base); } #endif -/* Define __attribute__ for platforms that doesn't suppor it */ - -#ifndef __attribute__ -# if !defined(__GNUC__) -# define __attribute__(A) -# else -# ifndef GCC_VERSION -# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) -# endif -# if GCC_VERSION < 2008 -# define __attribute__(A) -# elif defined(__cplusplus) && GCC_VERSION < 3004 -# define __attribute__(A) -# endif -# endif -#endif - #endif /* _EVUTIL_H_ */ diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c index e6b3d6dffc8..9f856b816ed 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -106,7 +106,7 @@ static void usage(my_bool version) my_print_help(my_long_options); my_print_default_files(config_file); my_print_variables(my_long_options); - printf("\nExample usage:\n%s --defaults-file=example.cnf client mysql\n", my_progname); + printf("\nExample usage:\n%s --defaults-file=example.cnf client client-server mysql\n", my_progname); } #include <help_end.h> diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 00000000000..9bafbd43793 --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,66 @@ +# Copyright (c) 2006, 2010, 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 + +SET(HEADERS_GEN_CONFIGURE +${CMAKE_CURRENT_BINARY_DIR}/mysql_version.h +#${CMAKE_CURRENT_BINARY_DIR}/my_config.h +${CMAKE_CURRENT_BINARY_DIR}/mysqld_ername.h +${CMAKE_CURRENT_BINARY_DIR}/mysqld_error.h +${CMAKE_CURRENT_BINARY_DIR}/sql_state.h +) +SET(HEADERS_ABI + mysql.h + mysql_com.h + mysql_time.h + my_list.h + my_alloc.h + typelib.h + mysql/plugin.h + mysql/plugin_auth.h + mysql/client_plugin.h +) + +SET(HEADERS + ${HEADERS_ABI} + config-win.h + my_dbug.h + m_string.h + my_sys.h + my_xml.h + mysql_embed.h + my_pthread.h + my_no_pthread.h + decimal.h + errmsg.h + my_global.h + my_net.h + my_getopt.h + sslopt-longopts.h + my_dir.h + sslopt-vars.h + sslopt-case.h + sql_common.h + keycache.h + m_ctype.h + my_attribute.h + my_compiler.h + ${HEADERS_GEN_CONFIGURE} +) + +INSTALL(FILES ${HEADERS} DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT Development) +INSTALL(DIRECTORY mysql/ DESTINATION ${INSTALL_INCLUDEDIR}/mysql COMPONENT Development FILES_MATCHING PATTERN "*.h" ) + + + diff --git a/include/Makefile.am b/include/Makefile.am index 3f60ffaf74b..67ffef3e714 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -21,8 +21,11 @@ HEADERS_GEN_MAKE = my_config.h HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \ my_list.h my_alloc.h typelib.h mysql/plugin.h pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \ - my_xml.h mysql_embed.h \ + my_xml.h mysql_embed.h mysql/services.h \ + mysql/service_my_snprintf.h mysql/service_thd_alloc.h \ my_pthread.h my_no_pthread.h \ + mysql/plugin_auth.h mysql/client_plugin.h \ + mysql/plugin_auth_common.h \ decimal.h errmsg.h my_global.h my_valgrind.h my_net.h \ my_getopt.h sslopt-longopts.h my_dir.h \ sslopt-vars.h sslopt-case.h sql_common.h keycache.h \ @@ -37,15 +40,16 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ + service_versions.h \ my_compare.h my_handler.h my_time.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \ atomic/rwlock.h atomic/x86-gcc.h \ - atomic/generic-msvc.h atomic/gcc_builtins.h \ - my_libwrap.h my_stacktrace.h \ + atomic/generic-msvc.h \ + atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \ wqueue.h waiting_threads.h \ welcome_copyright_notice.h -EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp +EXTRA_DIST = mysql.h.pp mysql/plugin_auth.h.pp mysql/client_plugin.h.pp CMakeLists.txt # Remove built files and the symlinked directories CLEANFILES = $(BUILT_SOURCES) readline openssl diff --git a/include/errmsg.h b/include/errmsg.h index a6d8c770de8..94209f35a61 100644 --- a/include/errmsg.h +++ b/include/errmsg.h @@ -97,6 +97,7 @@ extern const char *client_errors[]; /* Error messages */ #define CR_SERVER_LOST_EXTENDED 2055 #define CR_STMT_CLOSED 2056 #define CR_NEW_STMT_METADATA 2057 -#define CR_ERROR_LAST /*Copy last error nr:*/ 2057 +#define CR_AUTH_PLUGIN_CANNOT_LOAD 2058 +#define CR_ERROR_LAST /*Copy last error nr:*/ 2058 /* Add error numbers before CR_ERROR_LAST and change it accordingly. */ diff --git a/include/keycache.h b/include/keycache.h index 1dc30c5567e..12338037ea1 100644 --- a/include/keycache.h +++ b/include/keycache.h @@ -22,96 +22,146 @@ #define _keycache_h C_MODE_START -/* declare structures that is used by st_key_cache */ -struct st_block_link; -typedef struct st_block_link BLOCK_LINK; -struct st_keycache_page; -typedef struct st_keycache_page KEYCACHE_PAGE; -struct st_hash_link; -typedef struct st_hash_link HASH_LINK; -/* info about requests in a waiting queue */ -typedef struct st_keycache_wqueue -{ - struct st_my_thread_var *last_thread; /* circular list of waiting threads */ -} KEYCACHE_WQUEUE; +/* + Currently the default key cache is created as non-partitioned at + the start of the server unless the server is started with the parameter + --key-cache-partitions that is greater than 0 +*/ -#define CHANGED_BLOCKS_HASH 128 /* must be power of 2 */ +#define DEFAULT_KEY_CACHE_PARTITIONS 0 + +/* + MAX_KEY_CACHE_PARTITIONS cannot be greater than + sizeof(MYISAM_SHARE::dirty_part_map) + Currently sizeof(MYISAM_SHARE::dirty_part_map)=sizeof(ulonglong) +*/ + +#define MAX_KEY_CACHE_PARTITIONS 64 + +/* The structure to get statistical data about a key cache */ + +typedef struct st_key_cache_statistics +{ + ulonglong mem_size; /* memory for cache buffers/auxiliary structures */ + ulonglong block_size; /* size of the each buffers in the key cache */ + ulonglong blocks_used; /* maximum number of used blocks/buffers */ + ulonglong blocks_unused; /* number of currently unused blocks */ + ulonglong blocks_changed; /* number of currently dirty blocks */ + ulonglong blocks_warm; /* number of blocks in warm sub-chain */ + ulonglong read_requests; /* number of read requests (read hits) */ + ulonglong reads; /* number of actual reads from files into buffers */ + ulonglong write_requests; /* number of write requests (write hits) */ + ulonglong writes; /* number of actual writes from buffers into files */ +} KEY_CACHE_STATISTICS; + +#define NUM_LONG_KEY_CACHE_STAT_VARIABLES 3 + +/* The type of a key cache object */ +typedef enum key_cache_type +{ + SIMPLE_KEY_CACHE, + PARTITIONED_KEY_CACHE +} KEY_CACHE_TYPE; + + +typedef + int (*INIT_KEY_CACHE) + (void *, uint key_cache_block_size, + size_t use_mem, uint division_limit, uint age_threshold); +typedef + int (*RESIZE_KEY_CACHE) + (void *, uint key_cache_block_size, + size_t use_mem, uint division_limit, uint age_threshold); +typedef + void (*CHANGE_KEY_CACHE_PARAM) + (void *keycache_cb, + uint division_limit, uint age_threshold); +typedef + uchar* (*KEY_CACHE_READ) + (void *keycache_cb, + File file, my_off_t filepos, int level, + uchar *buff, uint length, + uint block_length, int return_buffer); +typedef + int (*KEY_CACHE_INSERT) + (void *keycache_cb, + File file, my_off_t filepos, int level, + uchar *buff, uint length); +typedef + int (*KEY_CACHE_WRITE) + (void *keycache_cb, + File file, void *file_extra, + my_off_t filepos, int level, + uchar *buff, uint length, + uint block_length, int force_write); +typedef + int (*FLUSH_KEY_BLOCKS) + (void *keycache_cb, + int file, void *file_extra, + enum flush_type type); +typedef + int (*RESET_KEY_CACHE_COUNTERS) + (const char *name, void *keycache_cb); +typedef + void (*END_KEY_CACHE) + (void *keycache_cb, my_bool cleanup); +typedef + void (*GET_KEY_CACHE_STATISTICS) + (void *keycache_cb, uint partition_no, + KEY_CACHE_STATISTICS *key_cache_stats); /* - The key cache structure - It also contains read-only statistics parameters. + An object of the type KEY_CACHE_FUNCS contains pointers to all functions + from the key cache interface. + Currently a key cache can be of two types: simple and partitioned. + For each of them its own static structure of the type KEY_CACHE_FUNCS is + defined . The structures contain the pointers to the implementations of + the interface functions used by simple key caches and partitioned key + caches respectively. Pointers to these structures are assigned to key cache + objects at the time of their creation. */ +typedef struct st_key_cache_funcs +{ + INIT_KEY_CACHE init; + RESIZE_KEY_CACHE resize; + CHANGE_KEY_CACHE_PARAM change_param; + KEY_CACHE_READ read; + KEY_CACHE_INSERT insert; + KEY_CACHE_WRITE write; + FLUSH_KEY_BLOCKS flush; + RESET_KEY_CACHE_COUNTERS reset_counters; + END_KEY_CACHE end; + GET_KEY_CACHE_STATISTICS get_stats; +} KEY_CACHE_FUNCS; + + typedef struct st_key_cache { - my_bool key_cache_inited; - my_bool in_resize; /* true during resize operation */ - my_bool resize_in_flush; /* true during flush of resize operation */ + KEY_CACHE_TYPE key_cache_type; /* type of the key cache used for debugging */ + void *keycache_cb; /* control block of the used key cache */ + KEY_CACHE_FUNCS *interface_funcs; /* interface functions of the key cache */ + ulonglong param_buff_size; /* size the memory allocated for the cache */ + ulong param_block_size; /* size of the blocks in the key cache */ + ulong param_division_limit; /* min. percentage of warm blocks */ + ulong param_age_threshold; /* determines when hot block is downgraded */ + ulong param_partitions; /* number of the key cache partitions */ + my_bool key_cache_inited; /* <=> key cache has been created */ my_bool can_be_used; /* usage of cache for read/write is allowed */ - size_t key_cache_mem_size; /* specified size of the cache memory */ - uint key_cache_block_size; /* size of the page buffer of a cache block */ - ulong min_warm_blocks; /* min number of warm blocks; */ - ulong age_threshold; /* age threshold for hot blocks */ - ulonglong keycache_time; /* total number of block link operations */ - uint hash_entries; /* max number of entries in the hash table */ - int hash_links; /* max number of hash links */ - int hash_links_used; /* number of hash links currently used */ - int disk_blocks; /* max number of blocks in the cache */ - ulong blocks_used; /* maximum number of concurrently used blocks */ - ulong blocks_unused; /* number of currently unused blocks */ - ulong blocks_changed; /* number of currently dirty blocks */ - ulong warm_blocks; /* number of blocks in warm sub-chain */ - ulong cnt_for_resize_op; /* counter to block resize operation */ - long blocks_available; /* number of blocks available in the LRU chain */ - HASH_LINK **hash_root; /* arr. of entries into hash table buckets */ - HASH_LINK *hash_link_root; /* memory for hash table links */ - HASH_LINK *free_hash_list; /* list of free hash links */ - BLOCK_LINK *free_block_list; /* list of free blocks */ - BLOCK_LINK *block_root; /* memory for block links */ - uchar HUGE_PTR *block_mem; /* memory for block buffers */ - BLOCK_LINK *used_last; /* ptr to the last block of the LRU chain */ - BLOCK_LINK *used_ins; /* ptr to the insertion block in LRU chain */ - pthread_mutex_t cache_lock; /* to lock access to the cache structure */ - KEYCACHE_WQUEUE resize_queue; /* threads waiting during resize operation */ - /* - Waiting for a zero resize count. Using a queue for symmetry though - only one thread can wait here. - */ - KEYCACHE_WQUEUE waiting_for_resize_cnt; - KEYCACHE_WQUEUE waiting_for_hash_link; /* waiting for a free hash link */ - KEYCACHE_WQUEUE waiting_for_block; /* requests waiting for a free block */ - BLOCK_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; /* hash for dirty file bl.*/ - BLOCK_LINK *file_blocks[CHANGED_BLOCKS_HASH]; /* hash for other file bl.*/ - - /* - The following variables are and variables used to hold parameters for - initializing the key cache. - */ - - ulonglong param_buff_size; /* size the memory allocated for the cache */ - ulong param_block_size; /* size of the blocks in the key cache */ - ulong param_division_limit; /* min. percentage of warm blocks */ - ulong param_age_threshold; /* determines when hot block is downgraded */ - - /* Statistics variables. These are reset in reset_key_cache_counters(). */ - ulong global_blocks_changed; /* number of currently dirty blocks */ - ulonglong global_cache_w_requests;/* number of write requests (write hits) */ - ulonglong global_cache_write; /* number of writes from cache to files */ - ulonglong global_cache_r_requests;/* number of read requests (read hits) */ - ulonglong global_cache_read; /* number of reads from files to cache */ - - int blocks; /* max number of blocks in the cache */ - my_bool in_init; /* Set to 1 in MySQL during init/resize */ + my_bool in_init; /* Set to 1 in MySQL during init/resize */ + uint partitions; /* actual number of partitions */ + size_t key_cache_mem_size; /* specified size of the cache memory */ } KEY_CACHE; + /* The default key cache */ extern KEY_CACHE dflt_key_cache_var, *dflt_key_cache; extern int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, size_t use_mem, uint division_limit, - uint age_threshold); + uint age_threshold, uint partitions); extern int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, size_t use_mem, uint division_limit, uint age_threshold); @@ -125,12 +175,17 @@ extern int key_cache_insert(KEY_CACHE *keycache, File file, my_off_t filepos, int level, uchar *buff, uint length); extern int key_cache_write(KEY_CACHE *keycache, - File file, my_off_t filepos, int level, + File file, void *file_extra, + my_off_t filepos, int level, uchar *buff, uint length, - uint block_length,int force_write); + uint block_length, int force_write); extern int flush_key_blocks(KEY_CACHE *keycache, - int file, enum flush_type type); + int file, void *file_extra, + enum flush_type type); extern void end_key_cache(KEY_CACHE *keycache, my_bool cleanup); +extern void get_key_cache_statistics(KEY_CACHE *keycache, + uint partition_no, + KEY_CACHE_STATISTICS *key_cache_stats); /* Functions to handle multiple key caches */ extern my_bool multi_keycache_init(void); @@ -143,5 +198,11 @@ extern void multi_key_cache_change(KEY_CACHE *old_data, KEY_CACHE *new_data); extern int reset_key_cache_counters(const char *name, KEY_CACHE *key_cache); +extern int repartition_key_cache(KEY_CACHE *keycache, + uint key_cache_block_size, + size_t use_mem, + uint division_limit, + uint age_threshold, + uint partitions); C_MODE_END #endif /* _keycache_h */ diff --git a/include/m_ctype.h b/include/m_ctype.h index 216e03bfcac..a8fe21c625d 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -40,16 +40,23 @@ extern "C" { #define my_wc_t ulong -typedef struct unicase_info_st +typedef const struct charset_info_st CHARSET_INFO; +typedef const struct my_charset_handler_st MY_CHARSET_HANDLER; +typedef const struct my_collation_handler_st MY_COLLATION_HANDLER; + +typedef const struct unicase_info_st MY_UNICASE_INFO; +typedef const struct uni_ctype_st MY_UNI_CTYPE; +typedef const struct my_uni_idx_st MY_UNI_IDX; + +struct unicase_info_st { uint16 toupper; uint16 tolower; uint16 sort; -} MY_UNICASE_INFO; - +}; -extern MY_UNICASE_INFO *my_unicase_default[256]; -extern MY_UNICASE_INFO *my_unicase_turkish[256]; +extern MY_UNICASE_INFO *const my_unicase_default[256]; +extern MY_UNICASE_INFO *const my_unicase_turkish[256]; #define MY_UCA_MAX_CONTRACTION 4 #define MY_UCA_MAX_WEIGHT_SIZE 8 @@ -69,11 +76,11 @@ typedef struct my_contraction_list_t } MY_CONTRACTIONS; -typedef struct uni_ctype_st +struct uni_ctype_st { uchar pctype; - uchar *ctype; -} MY_UNI_CTYPE; + const uchar *ctype; +}; extern MY_UNI_CTYPE my_uni_ctype[256]; @@ -116,12 +123,12 @@ extern MY_UNI_CTYPE my_uni_ctype[256]; #define MY_REPERTOIRE_UNICODE30 3 /* ASCII | EXTENDED: U+0000..U+FFFF */ -typedef struct my_uni_idx_st +struct my_uni_idx_st { uint16 from; uint16 to; - uchar *tab; -} MY_UNI_IDX; + const uchar *tab; +}; typedef struct { @@ -150,41 +157,41 @@ struct charset_info_st; /* See strings/CHARSET_INFO.txt for information about this structure */ -typedef struct my_collation_handler_st +struct my_collation_handler_st { my_bool (*init)(struct charset_info_st *, void *(*alloc)(size_t)); /* Collation routines */ - int (*strnncoll)(struct charset_info_st *, + int (*strnncoll)(CHARSET_INFO *, const uchar *, size_t, const uchar *, size_t, my_bool); - int (*strnncollsp)(struct charset_info_st *, + int (*strnncollsp)(CHARSET_INFO *, const uchar *, size_t, const uchar *, size_t, my_bool diff_if_only_endspace_difference); - size_t (*strnxfrm)(struct charset_info_st *, + size_t (*strnxfrm)(CHARSET_INFO *, uchar *, size_t, const uchar *, size_t); - size_t (*strnxfrmlen)(struct charset_info_st *, size_t); - my_bool (*like_range)(struct charset_info_st *, + size_t (*strnxfrmlen)(CHARSET_INFO *, size_t); + my_bool (*like_range)(CHARSET_INFO *, const char *s, size_t s_length, pchar w_prefix, pchar w_one, pchar w_many, size_t res_length, char *min_str, char *max_str, size_t *min_len, size_t *max_len); - int (*wildcmp)(struct charset_info_st *, + int (*wildcmp)(CHARSET_INFO *, const char *str,const char *str_end, const char *wildstr,const char *wildend, int escape,int w_one, int w_many); - int (*strcasecmp)(struct charset_info_st *, const char *, const char *); + int (*strcasecmp)(CHARSET_INFO *, const char *, const char *); - uint (*instr)(struct charset_info_st *, + uint (*instr)(CHARSET_INFO *, const char *b, size_t b_length, const char *s, size_t s_length, my_match_t *match, uint nmatch); /* Hash calculation */ - void (*hash_sort)(struct charset_info_st *cs, const uchar *key, size_t len, + void (*hash_sort)(CHARSET_INFO *cs, const uchar *key, size_t len, ulong *nr1, ulong *nr2); - my_bool (*propagate)(struct charset_info_st *cs, const uchar *str, size_t len); -} MY_COLLATION_HANDLER; + my_bool (*propagate)(CHARSET_INFO *cs, const uchar *str, size_t len); +}; extern MY_COLLATION_HANDLER my_collation_mb_bin_handler; extern MY_COLLATION_HANDLER my_collation_8bit_bin_handler; @@ -192,83 +199,83 @@ extern MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler; extern MY_COLLATION_HANDLER my_collation_ucs2_uca_handler; /* Some typedef to make it easy for C++ to make function pointers */ -typedef int (*my_charset_conv_mb_wc)(struct charset_info_st *, my_wc_t *, +typedef int (*my_charset_conv_mb_wc)(CHARSET_INFO *, my_wc_t *, const uchar *, const uchar *); -typedef int (*my_charset_conv_wc_mb)(struct charset_info_st *, my_wc_t, +typedef int (*my_charset_conv_wc_mb)(CHARSET_INFO *, my_wc_t, uchar *, uchar *); -typedef size_t (*my_charset_conv_case)(struct charset_info_st *, +typedef size_t (*my_charset_conv_case)(CHARSET_INFO *, char *, size_t, char *, size_t); /* See strings/CHARSET_INFO.txt about information on this structure */ -typedef struct my_charset_handler_st +struct my_charset_handler_st { my_bool (*init)(struct charset_info_st *, void *(*alloc)(size_t)); /* Multibyte routines */ - uint (*ismbchar)(struct charset_info_st *, const char *, const char *); - uint (*mbcharlen)(struct charset_info_st *, uint c); - size_t (*numchars)(struct charset_info_st *, const char *b, const char *e); - size_t (*charpos)(struct charset_info_st *, const char *b, const char *e, + uint (*ismbchar)(CHARSET_INFO *, const char *, const char *); + uint (*mbcharlen)(CHARSET_INFO *, uint c); + size_t (*numchars)(CHARSET_INFO *, const char *b, const char *e); + size_t (*charpos)(CHARSET_INFO *, const char *b, const char *e, size_t pos); - size_t (*well_formed_len)(struct charset_info_st *, + size_t (*well_formed_len)(CHARSET_INFO *, const char *b,const char *e, size_t nchars, int *error); - size_t (*lengthsp)(struct charset_info_st *, const char *ptr, size_t length); - size_t (*numcells)(struct charset_info_st *, const char *b, const char *e); + size_t (*lengthsp)(CHARSET_INFO *, const char *ptr, size_t length); + size_t (*numcells)(CHARSET_INFO *, const char *b, const char *e); /* Unicode conversion */ my_charset_conv_mb_wc mb_wc; my_charset_conv_wc_mb wc_mb; /* CTYPE scanner */ - int (*ctype)(struct charset_info_st *cs, int *ctype, + int (*ctype)(CHARSET_INFO *cs, int *ctype, const uchar *s, const uchar *e); /* Functions for case and sort conversion */ - size_t (*caseup_str)(struct charset_info_st *, char *); - size_t (*casedn_str)(struct charset_info_st *, char *); + size_t (*caseup_str)(CHARSET_INFO *, char *); + size_t (*casedn_str)(CHARSET_INFO *, char *); my_charset_conv_case caseup; my_charset_conv_case casedn; /* Charset dependant snprintf() */ - size_t (*snprintf)(struct charset_info_st *, char *to, size_t n, + size_t (*snprintf)(CHARSET_INFO *, char *to, size_t n, const char *fmt, ...) ATTRIBUTE_FORMAT_FPTR(printf, 4, 5); - size_t (*long10_to_str)(struct charset_info_st *, char *to, size_t n, + size_t (*long10_to_str)(CHARSET_INFO *, char *to, size_t n, int radix, long int val); - size_t (*longlong10_to_str)(struct charset_info_st *, char *to, size_t n, + size_t (*longlong10_to_str)(CHARSET_INFO *, char *to, size_t n, int radix, longlong val); - void (*fill)(struct charset_info_st *, char *to, size_t len, int fill); + void (*fill)(CHARSET_INFO *, char *to, size_t len, int fill); /* String-to-number conversion routines */ - long (*strntol)(struct charset_info_st *, const char *s, size_t l, + long (*strntol)(CHARSET_INFO *, const char *s, size_t l, int base, char **e, int *err); - ulong (*strntoul)(struct charset_info_st *, const char *s, size_t l, + ulong (*strntoul)(CHARSET_INFO *, const char *s, size_t l, int base, char **e, int *err); - longlong (*strntoll)(struct charset_info_st *, const char *s, size_t l, + longlong (*strntoll)(CHARSET_INFO *, const char *s, size_t l, int base, char **e, int *err); - ulonglong (*strntoull)(struct charset_info_st *, const char *s, size_t l, + ulonglong (*strntoull)(CHARSET_INFO *, const char *s, size_t l, int base, char **e, int *err); - double (*strntod)(struct charset_info_st *, char *s, size_t l, char **e, + double (*strntod)(CHARSET_INFO *, char *s, size_t l, char **e, int *err); - longlong (*strtoll10)(struct charset_info_st *cs, + longlong (*strtoll10)(CHARSET_INFO *cs, const char *nptr, char **endptr, int *error); - ulonglong (*strntoull10rnd)(struct charset_info_st *cs, + ulonglong (*strntoull10rnd)(CHARSET_INFO *cs, const char *str, size_t length, int unsigned_fl, char **endptr, int *error); - size_t (*scan)(struct charset_info_st *, const char *b, const char *e, + size_t (*scan)(CHARSET_INFO *, const char *b, const char *e, int sq); -} MY_CHARSET_HANDLER; +}; extern MY_CHARSET_HANDLER my_charset_8bit_handler; extern MY_CHARSET_HANDLER my_charset_ucs2_handler; /* See strings/CHARSET_INFO.txt about information on this structure */ -typedef struct charset_info_st +struct charset_info_st { uint number; uint primary_number; @@ -278,17 +285,17 @@ typedef struct charset_info_st const char *name; const char *comment; const char *tailoring; - uchar *ctype; - uchar *to_lower; - uchar *to_upper; - uchar *sort_order; - MY_CONTRACTIONS *contractions; - uint16 **sort_order_big; - uint16 *tab_to_uni; - MY_UNI_IDX *tab_from_uni; - MY_UNICASE_INFO **caseinfo; - uchar *state_map; - uchar *ident_map; + const uchar *ctype; + const uchar *to_lower; + const uchar *to_upper; + const uchar *sort_order; + const MY_CONTRACTIONS *contractions; + const uint16 *const *sort_order_big; + const uint16 *tab_to_uni; + MY_UNI_IDX *tab_from_uni; + MY_UNICASE_INFO *const *caseinfo; + const uchar *state_map; + const uchar *ident_map; uint strxfrm_multiply; uchar caseup_multiply; uchar casedn_multiply; @@ -302,41 +309,41 @@ typedef struct charset_info_st MY_CHARSET_HANDLER *cset; MY_COLLATION_HANDLER *coll; -} CHARSET_INFO; +}; #define ILLEGAL_CHARSET_INFO_NUMBER (~0U) - -extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_bin; -extern CHARSET_INFO my_charset_big5_chinese_ci; -extern CHARSET_INFO my_charset_big5_bin; -extern CHARSET_INFO my_charset_cp932_japanese_ci; -extern CHARSET_INFO my_charset_cp932_bin; -extern CHARSET_INFO my_charset_eucjpms_japanese_ci; -extern CHARSET_INFO my_charset_eucjpms_bin; -extern CHARSET_INFO my_charset_euckr_korean_ci; -extern CHARSET_INFO my_charset_euckr_bin; -extern CHARSET_INFO my_charset_gb2312_chinese_ci; -extern CHARSET_INFO my_charset_gb2312_bin; -extern CHARSET_INFO my_charset_gbk_chinese_ci; -extern CHARSET_INFO my_charset_gbk_bin; -extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_latin1; -extern CHARSET_INFO my_charset_latin1_german2_ci; -extern CHARSET_INFO my_charset_latin1_bin; -extern CHARSET_INFO my_charset_latin2_czech_ci; -extern CHARSET_INFO my_charset_sjis_japanese_ci; -extern CHARSET_INFO my_charset_sjis_bin; -extern CHARSET_INFO my_charset_tis620_thai_ci; -extern CHARSET_INFO my_charset_tis620_bin; -extern CHARSET_INFO my_charset_ucs2_general_ci; -extern CHARSET_INFO my_charset_ucs2_bin; -extern CHARSET_INFO my_charset_ucs2_unicode_ci; -extern CHARSET_INFO my_charset_ujis_japanese_ci; -extern CHARSET_INFO my_charset_ujis_bin; -extern CHARSET_INFO my_charset_utf8_general_ci; -extern CHARSET_INFO my_charset_utf8_unicode_ci; -extern CHARSET_INFO my_charset_utf8_bin; -extern CHARSET_INFO my_charset_cp1250_czech_ci; -extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename; +extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_bin; +extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_latin1; +extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_filename; + +extern struct charset_info_st my_charset_big5_chinese_ci; +extern struct charset_info_st my_charset_big5_bin; +extern struct charset_info_st my_charset_cp932_japanese_ci; +extern struct charset_info_st my_charset_cp932_bin; +extern struct charset_info_st my_charset_eucjpms_japanese_ci; +extern struct charset_info_st my_charset_eucjpms_bin; +extern struct charset_info_st my_charset_euckr_korean_ci; +extern struct charset_info_st my_charset_euckr_bin; +extern struct charset_info_st my_charset_gb2312_chinese_ci; +extern struct charset_info_st my_charset_gb2312_bin; +extern struct charset_info_st my_charset_gbk_chinese_ci; +extern struct charset_info_st my_charset_gbk_bin; +extern struct charset_info_st my_charset_latin1_german2_ci; +extern struct charset_info_st my_charset_latin1_bin; +extern struct charset_info_st my_charset_latin2_czech_ci; +extern struct charset_info_st my_charset_sjis_japanese_ci; +extern struct charset_info_st my_charset_sjis_bin; +extern struct charset_info_st my_charset_tis620_thai_ci; +extern struct charset_info_st my_charset_tis620_bin; +extern struct charset_info_st my_charset_ucs2_general_ci; +extern struct charset_info_st my_charset_ucs2_bin; +extern struct charset_info_st my_charset_ucs2_unicode_ci; +extern struct charset_info_st my_charset_ujis_japanese_ci; +extern struct charset_info_st my_charset_ujis_bin; +extern struct charset_info_st my_charset_utf8_general_ci; +extern struct charset_info_st my_charset_utf8_unicode_ci; +extern struct charset_info_st my_charset_utf8_bin; +extern struct charset_info_st my_charset_cp1250_czech_ci; /* declarations for simple charsets */ extern size_t my_strnxfrm_simple(CHARSET_INFO *, uchar *, size_t, @@ -355,7 +362,7 @@ extern void my_hash_sort_simple(CHARSET_INFO *cs, extern size_t my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, size_t length); -extern uint my_instr_simple(struct charset_info_st *, +extern uint my_instr_simple(CHARSET_INFO *, const char *b, size_t b_length, const char *s, size_t s_length, my_match_t *match, uint nmatch); @@ -379,7 +386,7 @@ int my_mb_ctype_mb(CHARSET_INFO *,int *, const uchar *,const uchar *); size_t my_scan_8bit(CHARSET_INFO *cs, const char *b, const char *e, int sq); -size_t my_snprintf_8bit(struct charset_info_st *, char *to, size_t n, +size_t my_snprintf_8bit(CHARSET_INFO *, char *to, size_t n, const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 4, 5); @@ -470,7 +477,7 @@ size_t my_numcells_mb(CHARSET_INFO *, const char *b, const char *e); size_t my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, size_t pos); size_t my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e, size_t pos, int *error); -uint my_instr_mb(struct charset_info_st *, +uint my_instr_mb(CHARSET_INFO *, const char *b, size_t b_length, const char *s, size_t s_length, my_match_t *match, uint nmatch); @@ -479,10 +486,10 @@ int my_wildcmp_unicode(CHARSET_INFO *cs, const char *str, const char *str_end, const char *wildstr, const char *wildend, int escape, int w_one, int w_many, - MY_UNICASE_INFO **weights); + MY_UNICASE_INFO *const *weights); extern my_bool my_parse_charset_xml(const char *bug, size_t len, - int (*add)(CHARSET_INFO *cs)); + int (*add)(struct charset_info_st *cs)); extern char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end, pchar c); extern size_t my_strcspn(CHARSET_INFO *cs, const char *str, const char *end, @@ -500,9 +507,8 @@ uint my_charset_repertoire(CHARSET_INFO *cs); my_bool my_uca_have_contractions(CHARSET_INFO *cs); my_bool my_uca_can_be_contraction_head(CHARSET_INFO *cs, my_wc_t wc); my_bool my_uca_can_be_contraction_tail(CHARSET_INFO *cs, my_wc_t wc); -uint16 *my_uca_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2); - - +const uint16 *my_uca_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, + my_wc_t wc2); #define _MY_U 01 /* Upper case */ diff --git a/include/m_string.h b/include/m_string.h index c9c1d4e6800..33043955cef 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -91,8 +91,8 @@ extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */ #endif /* Declared in int2str() */ -extern char NEAR _dig_vec_upper[]; -extern char NEAR _dig_vec_lower[]; +extern const char NEAR _dig_vec_upper[]; +extern const char NEAR _dig_vec_lower[]; /* Defined in strtod.c */ extern const double log_10[309]; @@ -221,7 +221,7 @@ extern char *str2int(const char *src,int radix,long lower,long upper, long *val); longlong my_strtoll10(const char *nptr, char **endptr, int *error); #if SIZEOF_LONG == SIZEOF_LONG_LONG -#define longlong2str(A,B,C) int2str((A),(B),(C),1) +#define longlong2str(A,B,C,D) int2str((A),(B),(C),(D)) #define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C)) #undef strtoll #define strtoll(A,B,C) strtol((A),(B),(C)) @@ -234,7 +234,7 @@ longlong my_strtoll10(const char *nptr, char **endptr, int *error); #endif #else #ifdef HAVE_LONG_LONG -extern char *longlong2str(longlong val,char *dst,int radix); + extern char *longlong2str(longlong val,char *dst,int radix, int upcase); extern char *longlong10_to_str(longlong val,char *dst,int radix); #if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO)) extern longlong strtoll(const char *str, char **ptr, int base); @@ -256,16 +256,10 @@ extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...) /* LEX_STRING -- a pair of a C-string and its length. + (it's part of the plugin API as a MYSQL_LEX_STRING) */ -#ifndef _my_plugin_h -/* This definition must match the one given in mysql/plugin.h */ -struct st_mysql_lex_string -{ - char *str; - size_t length; -}; -#endif +#include <mysql/plugin.h> typedef struct st_mysql_lex_string LEX_STRING; #define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1)) diff --git a/include/maria.h b/include/maria.h index 1f054bce58d..470f76669f3 100644 --- a/include/maria.h +++ b/include/maria.h @@ -21,12 +21,9 @@ #ifdef __cplusplus extern "C" { #endif -#ifndef _my_base_h #include <my_base.h> -#endif -#ifndef _m_ctype_h +#include <my_sys.h> #include <m_ctype.h> -#endif #include "../storage/maria/ma_pagecache.h" #include "my_handler.h" #include "my_compare.h" @@ -287,6 +284,7 @@ extern int (*maria_test_invalid_symlink)(const char *filename); extern int maria_init(void); extern void maria_end(void); +extern my_bool maria_upgrade(void); extern int maria_close(MARIA_HA *file); extern int maria_delete(MARIA_HA *file, const uchar *buff); extern MARIA_HA *maria_open(const char *name, int mode, @@ -335,6 +333,12 @@ extern int maria_begin(MARIA_HA *info); extern void maria_disable_logging(MARIA_HA *info); extern void maria_enable_logging(MARIA_HA *info); +#define HA_RECOVER_NONE 0 /* No automatic recover */ +#define HA_RECOVER_DEFAULT 1 /* Automatic recover active */ +#define HA_RECOVER_BACKUP 2 /* Make a backupfile on recover */ +#define HA_RECOVER_FORCE 4 /* Recover even if we loose rows */ +#define HA_RECOVER_QUICK 8 /* Don't check rows in data file */ + /* this is used to pass to mysql_mariachk_table */ #define MARIA_CHK_REPAIR 1 /* equivalent to mariachk -r */ diff --git a/include/my_attribute.h b/include/my_attribute.h index 8309d85f20a..ce14a5298ec 100644 --- a/include/my_attribute.h +++ b/include/my_attribute.h @@ -30,10 +30,15 @@ #ifndef __attribute__ # if !defined(__GNUC__) # define __attribute__(A) -# elif GCC_VERSION < 2008 -# define __attribute__(A) -# elif defined(__cplusplus) && GCC_VERSION < 3004 -# define __attribute__(A) +# else +# ifndef GCC_VERSION +# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) +# endif +# if GCC_VERSION < 2008 +# define __attribute__(A) +# elif defined(__cplusplus) && GCC_VERSION < 3004 +# define __attribute__(A) +# endif # endif #endif diff --git a/include/my_base.h b/include/my_base.h index 8bc484eea0a..81b20200e6b 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -277,17 +277,6 @@ enum ha_base_keytype { #define HA_USES_PARSER 16384 /* Fulltext index uses [pre]parser */ #define HA_USES_BLOCK_SIZE ((uint) 32768) #define HA_SORT_ALLOWS_SAME 512 /* Intern bit when sorting records */ -#if MYSQL_VERSION_ID < 50200 -/* - Key has a part that can have end space. If this is an unique key - we have to handle it differently from other unique keys as we can find - many matching rows for one key (because end space are not compared) -*/ -#define HA_END_SPACE_KEY 0 /* was: 4096 */ -#else -#error HA_END_SPACE_KEY is obsolete, please remove it -#endif - /* These flags can be added to key-seg-flag */ @@ -305,6 +294,7 @@ enum ha_base_keytype { */ #define HA_END_SPACE_ARE_EQUAL 512 #define HA_BIT_PART 1024 +#define HA_CAN_MEMCMP 2048 /* internal, never stored in frm */ /* optionbits for database */ #define HA_OPTION_PACK_RECORD 1 @@ -319,6 +309,8 @@ enum ha_base_keytype { #define HA_OPTION_RELIES_ON_SQL_LAYER 512 #define HA_OPTION_NULL_FIELDS 1024 #define HA_OPTION_PAGE_CHECKSUM 2048 +/* .frm has extra create options in linked-list format */ +#define HA_OPTION_TEXT_CREATE_OPTIONS (1L << 14) #define HA_OPTION_TEMP_COMPRESS_RECORD (1L << 15) /* set by isamchk */ #define HA_OPTION_READ_ONLY_DATA (1L << 16) /* Set by isamchk */ #define HA_OPTION_NO_CHECKSUM (1L << 17) diff --git a/include/my_global.h b/include/my_global.h index 5dca5710055..92aa2352621 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -582,6 +582,14 @@ int __void__; #define LINT_INIT(var) #endif +#ifdef _WIN32 +#define SO_EXT ".dll" +#elif defined(__APPLE__) +#define SO_EXT ".dylib" +#else +#define SO_EXT ".so" +#endif + /* Suppress uninitialized variable warning without generating code. @@ -1520,6 +1528,9 @@ do { doubleget_union _tmp; \ #elif defined(HAVE_DLFCN_H) #include <dlfcn.h> #endif +#ifndef HAVE_DLERROR +#define dlerror() "" +#endif #endif /* FreeBSD 2.2.2 does not define RTLD_NOW) */ @@ -1527,11 +1538,13 @@ do { doubleget_union _tmp; \ #define RTLD_NOW 1 #endif -#ifndef HAVE_DLERROR -#define dlerror() "" +#ifndef HAVE_DLOPEN +#define dlerror() "No support for dynamic loading (static build?)" +#define dlopen(A,B) 0 +#define dlsym(A,B) 0 +#define dlclose(A) 0 #endif - #ifndef __NETWARE__ /* * Include standard definitions of operator new and delete. diff --git a/include/my_no_pthread.h b/include/my_no_pthread.h index 1d08f51bb36..3e4335d8122 100644 --- a/include/my_no_pthread.h +++ b/include/my_no_pthread.h @@ -49,6 +49,7 @@ #define rw_wrlock(A) #define rw_unlock(A) #define rwlock_destroy(A) +#define safe_mutex_assert_owner(mp) typedef int my_pthread_once_t; #define MY_PTHREAD_ONCE_INIT 0 diff --git a/include/my_pthread.h b/include/my_pthread.h index 1f5be847da6..fffb883912a 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -127,6 +127,7 @@ struct tm *localtime_r(const time_t *timep,struct tm *tmp); struct tm *gmtime_r(const time_t *timep,struct tm *tmp); void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/ + #ifndef ETIMEDOUT #define ETIMEDOUT 145 /* Win32 might not have this */ #endif diff --git a/include/my_sys.h b/include/my_sys.h index 93f413092e0..30b7e0262da 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -49,7 +49,6 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_WME 16 /* Write message on error */ #define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */ #define MY_IGNORE_BADFD 32 /* my_sync: ignore 'bad descriptor' errors */ -#define MY_SYNC_DIR 1024 /* my_create/delete/rename: sync directory */ #define MY_RAID 64 /* Support for RAID */ #define MY_FULL_IO 512 /* For my_read - loop intil I/O is complete */ #define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */ @@ -70,6 +69,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_DONT_OVERWRITE_FILE 2048 /* my_copy: Don't overwrite file */ #define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */ #define MY_SYNC 4096 /* my_copy(): sync dst file */ +#define MY_SYNC_DIR 32768 /* my_create/delete/rename: sync directory */ #define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */ #define MY_GIVE_INFO 2 /* Give time info about process*/ @@ -197,7 +197,7 @@ extern void my_large_free(uchar * ptr, myf my_flags); #define my_large_free(A,B) my_free_lock((A),(B)) #endif /* HAVE_LARGE_PAGES */ -#ifdef HAVE_ALLOCA +#if defined(HAVE_ALLOCA) && !defined(HAVE_valgrind) #if defined(_AIX) && !defined(__GNUC__) && !defined(_AIX43) #pragma alloca #endif /* _AIX */ @@ -209,10 +209,14 @@ extern void my_large_free(uchar * ptr, myf my_flags); #define alloca __builtin_alloca #endif /* GNUC */ #define my_alloca(SZ) alloca((size_t) (SZ)) -#define my_afree(PTR) {} +#define my_afree(PTR) ((void)0) +#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(MY_FAE))) +#define my_safe_afree(ptr, size, min_length) ((size <= min_length) ? (void)0 : my_free(ptr,MYF(MY_WME))) #else -#define my_alloca(SZ) my_malloc(SZ,MYF(0)) +#define my_alloca(SZ) my_malloc(SZ,MYF(MY_FAE)) #define my_afree(PTR) my_free(PTR,MYF(MY_WME)) +#define my_safe_alloca(size, min_length) my_alloca(size) +#define my_safe_afree(ptr, size, min_length) my_afree(ptr) #endif /* HAVE_ALLOCA */ #ifndef errno /* did we already get it? */ @@ -243,7 +247,7 @@ extern uint my_large_page_size; /* charsets */ extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *default_charset_info; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *all_charsets[256]; -extern CHARSET_INFO compiled_charsets[]; +extern struct charset_info_st compiled_charsets[]; /* statistics */ extern ulong my_file_opened,my_stream_opened, my_tmp_file_created; @@ -251,7 +255,8 @@ extern ulong my_file_total_opened; extern ulong my_sync_count; extern uint mysys_usage_id; extern my_bool my_init_done; - +extern my_bool my_assert_on_error; +extern myf my_global_flags; /* Set to MY_WME for more error messages */ /* Point to current my_message() */ extern void (*my_sigtstp_cleanup)(void), /* Executed before jump to shell */ @@ -876,6 +881,10 @@ extern void set_prealloc_root(MEM_ROOT *root, char *ptr); extern void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, size_t prealloc_size); extern char *strdup_root(MEM_ROOT *root,const char *str); +static inline char *safe_strdup_root(MEM_ROOT *root, const char *str) +{ + return str ? strdup_root(root, str) : 0; +} extern char *strmake_root(MEM_ROOT *root,const char *str,size_t len); extern void *memdup_root(MEM_ROOT *root,const void *str, size_t len); extern int get_defaults_options(int argc, char **argv, @@ -921,6 +930,7 @@ void my_free_open_file_info(void); extern time_t my_time(myf flags); extern ulonglong my_getsystime(void); +extern ulonglong my_getcputime(void); extern ulonglong my_micro_time(); extern ulonglong my_micro_time_and_time(time_t *time_arg); time_t my_time_possible_from_micro(ulonglong microtime); @@ -1008,7 +1018,7 @@ extern void free_charsets(void); extern char *get_charsets_dir(char *buf); extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2); extern my_bool init_compiled_charsets(myf flags); -extern void add_compiled_collation(CHARSET_INFO *cs); +extern void add_compiled_collation(struct charset_info_st *cs); extern size_t escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, size_t to_length, const char *from, size_t length); diff --git a/include/myisamchk.h b/include/myisamchk.h index 7d7100bdd71..e8f1ce576bf 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -144,7 +144,7 @@ typedef struct st_handler_check_param time_t backup_time; /* To sign backup files */ ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY]; double new_rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY]; - uint out_flag, warning_printed, error_printed, verbose; + uint out_flag, warning_printed, error_printed, note_printed, verbose; uint opt_sort_key, total_files, max_level; uint key_cache_block_size, pagecache_block_size; int tmpfile_createflag, err_count; diff --git a/include/mysql.h b/include/mysql.h index 48b4b019485..8a94a4d3a09 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -171,9 +171,15 @@ enum mysql_option MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, - MYSQL_OPT_SSL_VERIFY_SERVER_CERT + MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH }; +/** + @todo remove the "extension", move st_mysql_options completely + out of mysql.h +*/ +struct st_mysql_options_extention; + struct st_mysql_options { unsigned int connect_timeout, read_timeout, write_timeout; unsigned int port, protocol; @@ -221,7 +227,7 @@ struct st_mysql_options { void (*local_infile_end)(void *); int (*local_infile_error)(void *, char *, unsigned int); void *local_infile_userdata; - void *extension; + struct st_mysql_options_extention *extension; }; enum mysql_status @@ -266,7 +272,7 @@ typedef struct st_mysql unsigned char *connector_fd; /* ConnectorFd for SSL */ char *host,*user,*passwd,*unix_socket,*server_version,*host_info; char *info, *db; - struct charset_info_st *charset; + const struct charset_info_st *charset; MYSQL_FIELD *fields; MEM_ROOT field_alloc; my_ulonglong affected_rows; @@ -757,38 +763,6 @@ enum enum_stmt_attr_type }; -typedef struct st_mysql_methods -{ - my_bool (*read_query_result)(MYSQL *mysql); - my_bool (*advanced_command)(MYSQL *mysql, - enum enum_server_command command, - const unsigned char *header, - unsigned long header_length, - const unsigned char *arg, - unsigned long arg_length, - my_bool skip_check, - MYSQL_STMT *stmt); - MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields, - unsigned int fields); - MYSQL_RES * (*use_result)(MYSQL *mysql); - void (*fetch_lengths)(unsigned long *to, - MYSQL_ROW column, unsigned int field_count); - void (*flush_use_result)(MYSQL *mysql); -#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) - MYSQL_FIELD * (*list_fields)(MYSQL *mysql); - my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); - int (*stmt_execute)(MYSQL_STMT *stmt); - int (*read_binary_rows)(MYSQL_STMT *stmt); - int (*unbuffered_fetch)(MYSQL *mysql, char **row); - void (*free_embedded_thd)(MYSQL *mysql); - const char *(*read_statistics)(MYSQL *mysql); - my_bool (*next_result)(MYSQL *mysql); - int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd); - int (*read_rows_from_cursor)(MYSQL_STMT *stmt); -#endif -} MYSQL_METHODS; - - MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql); int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length); @@ -851,18 +825,6 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); #endif #define HAVE_MYSQL_REAL_CONNECT -/* - The following functions are mainly exported because of mysqlbinlog; - They are not for general usage -*/ - -#define simple_command(mysql, command, arg, length, skip_check) \ - (*(mysql)->methods->advanced_command)(mysql, command, 0, \ - 0, arg, length, skip_check, NULL) -#define stmt_command(mysql, command, arg, length, stmt) \ - (*(mysql)->methods->advanced_command)(mysql, command, 0, \ - 0, arg, length, 1, stmt) - #ifdef __NETWARE__ #pragma pack(pop) /* restore alignment */ #endif diff --git a/include/mysql.h.pp b/include/mysql.h.pp index a3bce0e5506..6e71f886eba 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -127,13 +127,13 @@ void create_random_string(char *to, unsigned int length, void hash_password(unsigned long *to, const char *password, unsigned int password_len); void make_scrambled_password_323(char *to, const char *password); void scramble_323(char *to, const char *message, const char *password); -my_bool check_scramble_323(const char *, const char *message, +my_bool check_scramble_323(const unsigned char *reply, const char *message, unsigned long *salt); void get_salt_from_password_323(unsigned long *res, const char *password); void make_password_from_salt_323(char *to, const unsigned long *salt); void make_scrambled_password(char *to, const char *password); void scramble(char *to, const char *message, const char *password); -my_bool check_scramble(const char *reply, const char *message, +my_bool check_scramble(const unsigned char *reply, const char *message, const unsigned char *hash_stage2); void get_salt_from_password(unsigned char *res, const char *password); void make_password_from_salt(char *to, const unsigned char *hash_stage2); @@ -257,8 +257,9 @@ enum mysql_option MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, - MYSQL_OPT_SSL_VERIFY_SERVER_CERT + MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH }; +struct st_mysql_options_extention; struct st_mysql_options { unsigned int connect_timeout, read_timeout, write_timeout; unsigned int port, protocol; @@ -288,7 +289,7 @@ struct st_mysql_options { void (*local_infile_end)(void *); int (*local_infile_error)(void *, char *, unsigned int); void *local_infile_userdata; - void *extension; + struct st_mysql_options_extention *extension; }; enum mysql_status { @@ -323,7 +324,7 @@ typedef struct st_mysql unsigned char *connector_fd; char *host,*user,*passwd,*unix_socket,*server_version,*host_info; char *info, *db; - struct charset_info_st *charset; + const struct charset_info_st *charset; MYSQL_FIELD *fields; MEM_ROOT field_alloc; my_ulonglong affected_rows; @@ -601,34 +602,6 @@ enum enum_stmt_attr_type STMT_ATTR_CURSOR_TYPE, STMT_ATTR_PREFETCH_ROWS }; -typedef struct st_mysql_methods -{ - my_bool (*read_query_result)(MYSQL *mysql); - my_bool (*advanced_command)(MYSQL *mysql, - enum enum_server_command command, - const unsigned char *header, - unsigned long header_length, - const unsigned char *arg, - unsigned long arg_length, - my_bool skip_check, - MYSQL_STMT *stmt); - MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields, - unsigned int fields); - MYSQL_RES * (*use_result)(MYSQL *mysql); - void (*fetch_lengths)(unsigned long *to, - MYSQL_ROW column, unsigned int field_count); - void (*flush_use_result)(MYSQL *mysql); - MYSQL_FIELD * (*list_fields)(MYSQL *mysql); - my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); - int (*stmt_execute)(MYSQL_STMT *stmt); - int (*read_binary_rows)(MYSQL_STMT *stmt); - int (*unbuffered_fetch)(MYSQL *mysql, char **row); - void (*free_embedded_thd)(MYSQL *mysql); - const char *(*read_statistics)(MYSQL *mysql); - my_bool (*next_result)(MYSQL *mysql); - int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd); - int (*read_rows_from_cursor)(MYSQL_STMT *stmt); -} MYSQL_METHODS; MYSQL_STMT * mysql_stmt_init(MYSQL *mysql); int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length); diff --git a/include/mysql/client_plugin.h b/include/mysql/client_plugin.h new file mode 100644 index 00000000000..9c7b1aee9f9 --- /dev/null +++ b/include/mysql/client_plugin.h @@ -0,0 +1,166 @@ +#ifndef MYSQL_CLIENT_PLUGIN_INCLUDED +/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + + MySQL Client Plugin API + + This file defines the API for plugins that work on the client side +*/ +#define MYSQL_CLIENT_PLUGIN_INCLUDED + +#ifndef MYSQL_ABI_CHECK +#include <stdarg.h> +#include <stdlib.h> +#endif + +/* known plugin types */ +#define MYSQL_CLIENT_reserved1 0 +#define MYSQL_CLIENT_reserved2 1 +#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2 + +#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100 + +#define MYSQL_CLIENT_MAX_PLUGINS 3 + +#define mysql_declare_client_plugin(X) \ + struct st_mysql_client_plugin_ ## X \ + _mysql_client_plugin_declaration_ = { \ + MYSQL_CLIENT_ ## X ## _PLUGIN, \ + MYSQL_CLIENT_ ## X ## _PLUGIN_INTERFACE_VERSION, +#define mysql_end_client_plugin } + +/* generic plugin header structure */ +#define MYSQL_CLIENT_PLUGIN_HEADER \ + int type; \ + unsigned int interface_version; \ + const char *name; \ + const char *author; \ + const char *desc; \ + unsigned int version[3]; \ + int (*init)(char *, size_t, int, va_list); \ + int (*deinit)(); + +struct st_mysql_client_plugin +{ + MYSQL_CLIENT_PLUGIN_HEADER +}; + +struct st_mysql; + +/******** authentication plugin specific declarations *********/ +#include <mysql/plugin_auth_common.h> + +struct st_mysql_client_plugin_AUTHENTICATION +{ + MYSQL_CLIENT_PLUGIN_HEADER + int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql); +}; + +/** + type of the mysql_authentication_dialog_ask function + + @param mysql mysql + @param type type of the input + 1 - ordinary string input + 2 - password string + @param prompt prompt + @param buf a buffer to store the use input + @param buf_len the length of the buffer + + @retval a pointer to the user input string. + It may be equal to 'buf' or to 'mysql->password'. + In all other cases it is assumed to be an allocated + string, and the "dialog" plugin will free() it. +*/ +typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql, + int type, const char *prompt, char *buf, int buf_len); +/******** using plugins ************/ + +/** + loads a plugin and initializes it + + @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used, + and last_errno/last_error, for error reporting + @param name a name of the plugin to load + @param type type of plugin that should be loaded, -1 to disable type check + @param argc number of arguments to pass to the plugin initialization + function + @param ... arguments for the plugin initialization function + + @retval + a pointer to the loaded plugin, or NULL in case of a failure +*/ +struct st_mysql_client_plugin * +mysql_load_plugin(struct st_mysql *mysql, const char *name, int type, + int argc, ...); + +/** + loads a plugin and initializes it, taking va_list as an argument + + This is the same as mysql_load_plugin, but take va_list instead of + a list of arguments. + + @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used, + and last_errno/last_error, for error reporting + @param name a name of the plugin to load + @param type type of plugin that should be loaded, -1 to disable type check + @param argc number of arguments to pass to the plugin initialization + function + @param args arguments for the plugin initialization function + + @retval + a pointer to the loaded plugin, or NULL in case of a failure +*/ +struct st_mysql_client_plugin * +mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type, + int argc, va_list args); + +/** + finds an already loaded plugin by name, or loads it, if necessary + + @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used, + and last_errno/last_error, for error reporting + @param name a name of the plugin to load + @param type type of plugin that should be loaded + + @retval + a pointer to the plugin, or NULL in case of a failure +*/ +struct st_mysql_client_plugin * +mysql_client_find_plugin(struct st_mysql *mysql, const char *name, int type); + +/** + adds a plugin structure to the list of loaded plugins + + This is useful if an application has the necessary functionality + (for example, a special load data handler) statically linked into + the application binary. It can use this function to register the plugin + directly, avoiding the need to factor it out into a shared object. + + @param mysql MYSQL structure. It is only used for error reporting + @param plugin an st_mysql_client_plugin structure to register + + @retval + a pointer to the plugin, or NULL in case of a failure +*/ +struct st_mysql_client_plugin * +mysql_client_register_plugin(struct st_mysql *mysql, + struct st_mysql_client_plugin *plugin); + +#endif + diff --git a/include/mysql/client_plugin.h.pp b/include/mysql/client_plugin.h.pp new file mode 100644 index 00000000000..ca477d83bb2 --- /dev/null +++ b/include/mysql/client_plugin.h.pp @@ -0,0 +1,39 @@ +struct st_mysql_client_plugin +{ + int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; int (*init)(char *, size_t, int, va_list); int (*deinit)(); +}; +struct st_mysql; +#include <mysql/plugin_auth_common.h> +typedef struct st_plugin_vio_info +{ + enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET, + MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol; + int socket; +} MYSQL_PLUGIN_VIO_INFO; +typedef struct st_plugin_vio +{ + int (*read_packet)(struct st_plugin_vio *vio, + unsigned char **buf); + int (*write_packet)(struct st_plugin_vio *vio, + const unsigned char *packet, + int packet_len); + void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info); +} MYSQL_PLUGIN_VIO; +struct st_mysql_client_plugin_AUTHENTICATION +{ + int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; int (*init)(char *, size_t, int, va_list); int (*deinit)(); + int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql); +}; +typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql, + int type, const char *prompt, char *buf, int buf_len); +struct st_mysql_client_plugin * +mysql_load_plugin(struct st_mysql *mysql, const char *name, int type, + int argc, ...); +struct st_mysql_client_plugin * +mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type, + int argc, va_list args); +struct st_mysql_client_plugin * +mysql_client_find_plugin(struct st_mysql *mysql, const char *name, int type); +struct st_mysql_client_plugin * +mysql_client_register_plugin(struct st_mysql *mysql, + struct st_mysql_client_plugin *plugin); diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 7a684614bf4..bacc4bd7bd8 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -50,15 +50,7 @@ class Item; #define MYSQL_THD void* #endif -#ifndef _m_string_h -/* This definition must match the one given in m_string.h */ -struct st_mysql_lex_string -{ - char *str; - unsigned int length; -}; -#endif /* _m_string_h */ -typedef struct st_mysql_lex_string MYSQL_LEX_STRING; +#include <mysql/services.h> #define MYSQL_XIDDATASIZE 128 /** @@ -81,7 +73,10 @@ typedef struct st_mysql_xid MYSQL_XID; Plugin API. Common for all plugin types. */ -#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0100 +/* MySQL plugin interface version */ +#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101 +/* MariaDB plugin interface version */ +#define MARIA_PLUGIN_INTERFACE_VERSION 0x0100 /* The allowable types of plugins @@ -91,7 +86,10 @@ typedef struct st_mysql_xid MYSQL_XID; #define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */ #define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */ #define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */ -#define MYSQL_MAX_PLUGIN_TYPE_NUM 5 /* The number of plugin types */ +#define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */ +#define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */ +#define MYSQL_AUTHENTICATION_PLUGIN 7 /* The authentication plugin type */ +#define MYSQL_MAX_PLUGIN_TYPE_NUM 8 /* The number of plugin types */ /* We use the following strings to define licenses for plugins */ #define PLUGIN_LICENSE_PROPRIETARY 0 @@ -102,6 +100,14 @@ typedef struct st_mysql_xid MYSQL_XID; #define PLUGIN_LICENSE_GPL_STRING "GPL" #define PLUGIN_LICENSE_BSD_STRING "BSD" +/* definitions of code maturity for plugins */ +#define MariaDB_PLUGIN_MATURITY_UNKNOWN 0 +#define MariaDB_PLUGIN_MATURITY_EXPERIMENTAL 1 +#define MariaDB_PLUGIN_MATURITY_ALPHA 2 +#define MariaDB_PLUGIN_MATURITY_BETA 3 +#define MariaDB_PLUGIN_MATURITY_GAMMA 4 +#define MariaDB_PLUGIN_MATURITY_STABLE 5 + /* Macros for beginning and ending plugin declarations. Between mysql_declare_plugin and mysql_declare_plugin_end there should @@ -114,11 +120,24 @@ typedef struct st_mysql_xid MYSQL_XID; int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \ int PSIZE= sizeof(struct st_mysql_plugin); \ struct st_mysql_plugin DECLS[]= { + +#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \ +int VERSION= MARIA_PLUGIN_INTERFACE_VERSION; \ +int PSIZE= sizeof(struct st_maria_plugin); \ +struct st_maria_plugin DECLS[]= { + #else + #define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \ MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \ MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \ MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= { + +#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \ +MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \ +MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \ +MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]= { + #endif #define mysql_declare_plugin(NAME) \ @@ -127,7 +146,14 @@ __MYSQL_DECLARE_PLUGIN(NAME, \ builtin_ ## NAME ## _sizeof_struct_st_plugin, \ builtin_ ## NAME ## _plugin) +#define maria_declare_plugin(NAME) \ +MARIA_DECLARE_PLUGIN__(NAME, \ + builtin_maria_ ## NAME ## _plugin_interface_version, \ + builtin_maria_ ## NAME ## _sizeof_struct_st_plugin, \ + builtin_maria_ ## NAME ## _plugin) + #define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0}} +#define maria_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}} /* declarations for SHOW STATUS support in plugins @@ -136,7 +162,8 @@ enum enum_mysql_show_type { SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, - SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE + SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, + SHOW_always_last }; struct st_mysql_show_var { @@ -246,7 +273,7 @@ typedef void (*mysql_var_update_func)(MYSQL_THD thd, #define DECLARE_MYSQL_SYSVAR_BASIC(name, type) struct { \ MYSQL_PLUGIN_VAR_HEADER; \ type *value; \ - const type def_val; \ + const type def_val; \ } MYSQL_SYSVAR_NAME(name) #define DECLARE_MYSQL_SYSVAR_SIMPLE(name, type) struct { \ @@ -283,7 +310,7 @@ typedef void (*mysql_var_update_func)(MYSQL_THD thd, #define DECLARE_MYSQL_THDVAR_TYPELIB(name, type) struct { \ MYSQL_PLUGIN_VAR_HEADER; \ int offset; \ - type def_val; \ + const type def_val; \ DECLARE_THDVAR_FUNC(type); \ TYPELIB *typelib; \ } MYSQL_SYSVAR_NAME(name) @@ -423,6 +450,30 @@ struct st_mysql_plugin void * __reserved1; /* reserved for dependency checking */ }; +/* + MariaDB extension for plugins declaration structure. + + It also copy current MySQL plugin fields to have more independency + in plugins extension +*/ + +struct st_maria_plugin +{ + int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + void *info; /* pointer to type-specific plugin descriptor */ + const char *name; /* plugin name */ + const char *author; /* plugin author (for SHOW PLUGINS) */ + const char *descr; /* general descriptive text (for SHOW PLUGINS ) */ + int license; /* the plugin license (PLUGIN_LICENSE_XXX) */ + int (*init)(void *); /* the function to invoke when plugin is loaded */ + int (*deinit)(void *);/* the function to invoke when plugin is unloaded */ + unsigned int version; /* plugin version (for SHOW PLUGINS) */ + struct st_mysql_show_var *status_vars; + struct st_mysql_sys_var **system_vars; + const char *version_info; /* plugin version string */ + unsigned int maturity; /* MariaDB_PLUGIN_MATURITY_XXX */ +}; + /************************************************************************* API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN) */ @@ -592,7 +643,7 @@ typedef struct st_mysql_ftparser_param MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info); void *ftparser_state; void *mysql_ftparam; - struct charset_info_st *cs; + const struct charset_info_st *cs; const unsigned char *doc; mysql_ft_size_t length; unsigned int flags; @@ -755,54 +806,6 @@ int thd_killed(const MYSQL_THD thd); */ unsigned long thd_get_thread_id(const MYSQL_THD thd); - -/** - Allocate memory in the connection's local memory pool - - @details - When properly used in place of @c my_malloc(), this can significantly - improve concurrency. Don't use this or related functions to allocate - large chunks of memory. Use for temporary storage only. The memory - will be freed automatically at the end of the statement; no explicit - code is required to prevent memory leaks. - - @see alloc_root() -*/ -void *thd_alloc(MYSQL_THD thd, unsigned int size); -/** - @see thd_alloc() -*/ -void *thd_calloc(MYSQL_THD thd, unsigned int size); -/** - @see thd_alloc() -*/ -char *thd_strdup(MYSQL_THD thd, const char *str); -/** - @see thd_alloc() -*/ -char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size); -/** - @see thd_alloc() -*/ -void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size); - -/** - Create a LEX_STRING in this connection's local memory pool - - @param thd user thread connection handle - @param lex_str pointer to LEX_STRING object to be initialized - @param str initializer to be copied into lex_str - @param size length of str, in bytes - @param allocate_lex_string flag: if TRUE, allocate new LEX_STRING object, - instead of using lex_str value - @return NULL on failure, or pointer to the LEX_STRING object - - @see thd_alloc() -*/ -MYSQL_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str, - const char *str, unsigned int size, - int allocate_lex_string); - /** Get the XID for this connection's transaction diff --git a/include/mysql/plugin_auth.h b/include/mysql/plugin_auth.h new file mode 100644 index 00000000000..2b84a6c73af --- /dev/null +++ b/include/mysql/plugin_auth.h @@ -0,0 +1,83 @@ +#ifndef MYSQL_PLUGIN_AUTH_INCLUDED +/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + + Authentication Plugin API. + + This file defines the API for server authentication plugins. +*/ + +#define MYSQL_PLUGIN_AUTH_INCLUDED + +#include <mysql/plugin.h> + +#define MYSQL_AUTHENTICATION_INTERFACE_VERSION 0x0100 + +#include <mysql/plugin_auth_common.h> + +/** + Provides server plugin access to authentication information +*/ +typedef struct st_mysql_server_auth_info +{ + /** + User name as sent by the client and shown in USER(). + NULL if the client packet with the user name was not received yet. + */ + const char *user_name; + /** + A corresponding column value from the mysql.user table for the + matching account name + */ + const char *auth_string; + + /** + Matching account name as found in the mysql.user table. + A plugin can override it with another name that will be + used by MySQL for authorization, and shown in CURRENT_USER() + */ + char authenticated_as[MYSQL_USERNAME_LENGTH+1]; + /** + This only affects the "Authentication failed. Password used: %s" + error message. If set, %s will be YES, otherwise - NO. + Set it as appropriate or ignore at will. + */ + int password_used; +} MYSQL_SERVER_AUTH_INFO; + +/** + Server authentication plugin descriptor +*/ +struct st_mysql_auth +{ + int interface_version; /**< version plugin uses */ + /** + A plugin that a client must use for authentication with this server + plugin. Can be NULL to mean "any plugin". + */ + const char *client_auth_plugin; + /** + Function provided by the plugin which should perform authentication (using + the vio functions if necessary) and return 0 if successful. The plugin can + also fill the info.authenticated_as field if a different username should be + used for authorization. + */ + int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info); +}; +#endif + diff --git a/include/mysql/plugin.h.pp b/include/mysql/plugin_auth.h.pp index ac86f687723..b0d5daf4c64 100644 --- a/include/mysql/plugin.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -1,9 +1,36 @@ +#include <mysql/plugin.h> +#include <mysql/services.h> +#include <mysql/service_my_snprintf.h> +extern struct my_snprintf_service_st { + size_t (*my_snprintf_type)(char*, size_t, const char*, ...); + size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list); +} *my_snprintf_service; +size_t my_snprintf(char* to, size_t n, const char* fmt, ...); +size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap); +#include <mysql/service_thd_alloc.h> struct st_mysql_lex_string { char *str; - unsigned int length; + size_t length; }; typedef struct st_mysql_lex_string MYSQL_LEX_STRING; +extern struct thd_alloc_service_st { + void *(*thd_alloc_func)(void*, unsigned int); + void *(*thd_calloc_func)(void*, unsigned int); + char *(*thd_strdup_func)(void*, const char *); + char *(*thd_strmake_func)(void*, const char *, unsigned int); + void *(*thd_memdup_func)(void*, const void*, unsigned int); + MYSQL_LEX_STRING *(*thd_make_lex_string_func)(void*, MYSQL_LEX_STRING *, + const char *, unsigned int, int); +} *thd_alloc_service; +void *thd_alloc(void* thd, unsigned int size); +void *thd_calloc(void* thd, unsigned int size); +char *thd_strdup(void* thd, const char *str); +char *thd_strmake(void* thd, const char *str, unsigned int size); +void *thd_memdup(void* thd, const void* str, unsigned int size); +MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, + const char *str, unsigned int size, + int allocate_lex_string); struct st_mysql_xid { long formatID; long gtrid_length; @@ -15,7 +42,8 @@ enum enum_mysql_show_type { SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, - SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE + SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, + SHOW_always_last }; struct st_mysql_show_var { const char *name; @@ -46,6 +74,22 @@ struct st_mysql_plugin struct st_mysql_sys_var **system_vars; void * __reserved1; }; +struct st_maria_plugin +{ + int type; + void *info; + const char *name; + const char *author; + const char *descr; + int license; + int (*init)(void *); + int (*deinit)(void *); + unsigned int version; + struct st_mysql_show_var *status_vars; + struct st_mysql_sys_var **system_vars; + const char *version_info; + unsigned int maturity; +}; enum enum_ftparser_mode { MYSQL_FTPARSER_SIMPLE_MODE= 0, @@ -80,7 +124,7 @@ typedef struct st_mysql_ftparser_param MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info); void *ftparser_state; void *mysql_ftparam; - struct charset_info_st *cs; + const struct charset_info_st *cs; const unsigned char *doc; mysql_ft_size_t length; unsigned int flags; @@ -127,14 +171,6 @@ const char *set_thd_proc_info(void*, const char * info, const char *func, int mysql_tmpfile(const char *prefix); int thd_killed(const void* thd); unsigned long thd_get_thread_id(const void* thd); -void *thd_alloc(void* thd, unsigned int size); -void *thd_calloc(void* thd, unsigned int size); -char *thd_strdup(void* thd, const char *str); -char *thd_strmake(void* thd, const char *str, unsigned int size); -void *thd_memdup(void* thd, const void* str, unsigned int size); -MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, - const char *str, unsigned int size, - int allocate_lex_string); void thd_get_xid(const void* thd, MYSQL_XID *xid); void mysql_query_cache_invalidate4(void* thd, const char *key, unsigned int key_length, @@ -142,3 +178,32 @@ void mysql_query_cache_invalidate4(void* thd, void *thd_get_ha_data(const void* thd, const struct handlerton *hton); void thd_set_ha_data(void* thd, const struct handlerton *hton, const void *ha_data); +#include <mysql/plugin_auth_common.h> +typedef struct st_plugin_vio_info +{ + enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET, + MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol; + int socket; +} MYSQL_PLUGIN_VIO_INFO; +typedef struct st_plugin_vio +{ + int (*read_packet)(struct st_plugin_vio *vio, + unsigned char **buf); + int (*write_packet)(struct st_plugin_vio *vio, + const unsigned char *packet, + int packet_len); + void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info); +} MYSQL_PLUGIN_VIO; +typedef struct st_mysql_server_auth_info +{ + const char *user_name; + const char *auth_string; + char authenticated_as[48 +1]; + int password_used; +} MYSQL_SERVER_AUTH_INFO; +struct st_mysql_auth +{ + int interface_version; + const char *client_auth_plugin; + int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info); +}; diff --git a/include/mysql/plugin_auth_common.h b/include/mysql/plugin_auth_common.h new file mode 100644 index 00000000000..b71591d6eb6 --- /dev/null +++ b/include/mysql/plugin_auth_common.h @@ -0,0 +1,105 @@ +#ifndef MYSQL_PLUGIN_AUTH_COMMON_INCLUDED +/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + + This file defines constants and data structures that are the same for + both client- and server-side authentication plugins. +*/ +#define MYSQL_PLUGIN_AUTH_COMMON_INCLUDED + +/** the max allowed length for a user name */ +#define MYSQL_USERNAME_LENGTH 48 + +/** + return values of the plugin authenticate_user() method. +*/ + +/** + Authentication failed. Additionally, all other CR_xxx values + (libmysql error code) can be used too. + + The client plugin may set the error code and the error message directly + in the MYSQL structure and return CR_ERROR. If a CR_xxx specific error + code was returned, an error message in the MYSQL structure will be + overwritten. If CR_ERROR is returned without setting the error in MYSQL, + CR_UNKNOWN_ERROR will be user. +*/ +#define CR_ERROR 0 +/** + Authentication (client part) was successful. It does not mean that the + authentication as a whole was successful, usually it only means + that the client was able to send the user name and the password to the + server. If CR_OK is returned, the libmysql reads the next packet expecting + it to be one of OK, ERROR, or CHANGE_PLUGIN packets. +*/ +#define CR_OK -1 +/** + Authentication was successful. + It means that the client has done its part successfully and also that + a plugin has read the last packet (one of OK, ERROR, CHANGE_PLUGIN). + In this case, libmysql will not read a packet from the server, + but it will use the data at mysql->net.read_pos. + + A plugin may return this value if the number of roundtrips in the + authentication protocol is not known in advance, and the client plugin + needs to read one packet more to determine if the authentication is finished + or not. +*/ +#define CR_OK_HANDSHAKE_COMPLETE -2 + +typedef struct st_plugin_vio_info +{ + enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET, + MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol; + int socket; /**< it's set, if the protocol is SOCKET or TCP */ +#ifdef _WIN32 + HANDLE handle; /**< it's set, if the protocol is PIPE or MEMORY */ +#endif +} MYSQL_PLUGIN_VIO_INFO; + +/** + Provides plugin access to communication channel +*/ +typedef struct st_plugin_vio +{ + /** + Plugin provides a pointer reference and this function sets it to the + contents of any incoming packet. Returns the packet length, or -1 if + the plugin should terminate. + */ + int (*read_packet)(struct st_plugin_vio *vio, + unsigned char **buf); + + /** + Plugin provides a buffer with data and the length and this + function sends it as a packet. Returns 0 on success, 1 on failure. + */ + int (*write_packet)(struct st_plugin_vio *vio, + const unsigned char *packet, + int packet_len); + + /** + Fills in a st_plugin_vio_info structure, providing the information + about the connection. + */ + void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info); + +} MYSQL_PLUGIN_VIO; + +#endif + diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h new file mode 100644 index 00000000000..30e95e20a5a --- /dev/null +++ b/include/mysql/service_my_snprintf.h @@ -0,0 +1,100 @@ +#ifndef MYSQL_SERVICE_MY_SNPRINTF_INCLUDED +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + my_snprintf service + + Portable and limited vsnprintf() implementation. + + This is a portable, limited vsnprintf() implementation, with some + extra features. "Portable" means that it'll produce identical result + on all platforms (for example, on Windows and Linux system printf %e + formats the exponent differently, on different systems %p either + prints leading 0x or not, %s may accept null pointer or crash on + it). "Limited" means that it does not support all the C89 features. + But it supports few extensions, not in any standard. + + my_vsnprintf(to, n, fmt, ap) + + @param[out] to A buffer to store the result in + @param[in] n Store up to n-1 characters, followed by an end 0 + @param[in] fmt printf-like format string + @param[in] ap Arguments + + @return a number of bytes written to a buffer *excluding* terminating '\0' + + @post + The syntax of a format string is generally the same: + % <flag> <width> <precision> <length modifier> <format> + where everithing but the format is optional. + + Three one-character flags are recognized: + '0' has the standard zero-padding semantics; + '-' is parsed, but silently ignored; + '`' (backtick) is only supported for strings (%s) and means that the + string will be quoted according to MySQL identifier quoting rules. + + Both <width> and <precision> can be specified as numbers or '*'. + + <length modifier> can be 'l', 'll', or 'z'. + + Supported formats are 's' (null pointer is accepted, printed as + "(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x', + 'X', 'p' (works as 0x%x). + + Standard syntax for positional arguments $n is supported. + + Extensions: + + Flag '`' (backtick): see above. + + Format 'b': binary buffer, prints exactly <precision> bytes from the + argument, without stopping at '\0'. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MYSQL_ABI_CHECK +#include <stdarg.h> +#include <stdlib.h> +#endif +extern struct my_snprintf_service_st { + size_t (*my_snprintf_type)(char*, size_t, const char*, ...); + size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list); +} *my_snprintf_service; + +#ifdef MYSQL_DYNAMIC_PLUGIN + +#define my_vsnprintf my_snprintf_service->my_vsnprintf_type +#define my_snprintf my_snprintf_service->my_snprintf_type + +#else + +size_t my_snprintf(char* to, size_t n, const char* fmt, ...); +size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap); + +#endif + +#ifdef __cplusplus +} +#endif + +#define MYSQL_SERVICE_MY_SNPRINTF_INCLUDED +#endif + diff --git a/include/mysql/service_thd_alloc.h b/include/mysql/service_thd_alloc.h new file mode 100644 index 00000000000..7061c2bd4d5 --- /dev/null +++ b/include/mysql/service_thd_alloc.h @@ -0,0 +1,130 @@ +#ifndef MYSQL_SERVICE_THD_ALLOC_INCLUDED +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + This service provdes functions to allocate memory in a connection local + memory pool. The memory allocated there will be automatically freed at the + end of the statement, don't use it for allocations that should live longer + than that. For short living allocations this is more efficient than + using my_malloc and friends, and automatic "garbage collection" allows not + to think about memory leaks. + + The pool is best for small to medium objects, don't use it for large + allocations - they are better served with my_malloc. +*/ + +#ifndef MYSQL_ABI_CHECK +#include <stdlib.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct st_mysql_lex_string +{ + char *str; + size_t length; +}; +typedef struct st_mysql_lex_string MYSQL_LEX_STRING; + +extern struct thd_alloc_service_st { + void *(*thd_alloc_func)(MYSQL_THD, unsigned int); + void *(*thd_calloc_func)(MYSQL_THD, unsigned int); + char *(*thd_strdup_func)(MYSQL_THD, const char *); + char *(*thd_strmake_func)(MYSQL_THD, const char *, unsigned int); + void *(*thd_memdup_func)(MYSQL_THD, const void*, unsigned int); + MYSQL_LEX_STRING *(*thd_make_lex_string_func)(MYSQL_THD, MYSQL_LEX_STRING *, + const char *, unsigned int, int); +} *thd_alloc_service; + +#ifdef MYSQL_DYNAMIC_PLUGIN + +#define thd_alloc(thd,size) (thd_alloc_service->thd_alloc_func((thd), (size))) + +#define thd_calloc(thd,size) (thd_alloc_service->thd_calloc_func((thd), (size))) + +#define thd_strdup(thd,str) (thd_alloc_service->thd_strdup_func((thd), (str))) + +#define thd_strmake(thd,str,size) \ + (thd_alloc_service->thd_strmake_func((thd), (str), (size))) + +#define thd_memdup(thd,str,size) \ + (thd_alloc_service->thd_memdup_func((thd), (str), (size))) + +#define thd_make_lex_string(thd, lex_str, str, size, allocate_lex_string) \ + (thd_alloc_service->thd_make_lex_string_func((thd), (lex_str), (str), \ + (size), (allocate_lex_string))) + +#else + +/** + Allocate memory in the connection's local memory pool + + @details + When properly used in place of @c my_malloc(), this can significantly + improve concurrency. Don't use this or related functions to allocate + large chunks of memory. Use for temporary storage only. The memory + will be freed automatically at the end of the statement; no explicit + code is required to prevent memory leaks. + + @see alloc_root() +*/ +void *thd_alloc(MYSQL_THD thd, unsigned int size); +/** + @see thd_alloc() +*/ +void *thd_calloc(MYSQL_THD thd, unsigned int size); +/** + @see thd_alloc() +*/ +char *thd_strdup(MYSQL_THD thd, const char *str); +/** + @see thd_alloc() +*/ +char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size); +/** + @see thd_alloc() +*/ +void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size); + +/** + Create a LEX_STRING in this connection's local memory pool + + @param thd user thread connection handle + @param lex_str pointer to LEX_STRING object to be initialized + @param str initializer to be copied into lex_str + @param size length of str, in bytes + @param allocate_lex_string flag: if TRUE, allocate new LEX_STRING object, + instead of using lex_str value + @return NULL on failure, or pointer to the LEX_STRING object + + @see thd_alloc() +*/ +MYSQL_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str, + const char *str, unsigned int size, + int allocate_lex_string); + +#endif + +#ifdef __cplusplus +} +#endif + +#define MYSQL_SERVICE_THD_ALLOC_INCLUDED +#endif + diff --git a/include/mysql/services.h b/include/mysql/services.h new file mode 100644 index 00000000000..19003e66b96 --- /dev/null +++ b/include/mysql/services.h @@ -0,0 +1,30 @@ +#ifndef MYSQL_SERVICES_INCLUDED +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <mysql/service_my_snprintf.h> +#include <mysql/service_thd_alloc.h> + +#ifdef __cplusplus +} +#endif + +#define MYSQL_SERVICES_INCLUDED +#endif + diff --git a/include/mysql_com.h b/include/mysql_com.h index 96eb8f21d3f..affd24a4636 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -27,8 +27,13 @@ #define NAME_LEN (NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN) #define USERNAME_LENGTH (USERNAME_CHAR_LENGTH*SYSTEM_CHARSET_MBMAXLEN) +#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" +#define MYSQL50_TABLE_NAME_PREFIX_LENGTH (sizeof(MYSQL50_TABLE_NAME_PREFIX)-1) +#define SAFE_NAME_LEN (NAME_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH) + #define SERVER_VERSION_LENGTH 60 #define SQLSTATE_LENGTH 5 +#define LIST_PROCESS_HOST_LEN 64 /* USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain @@ -67,7 +72,8 @@ enum enum_server_command COM_END }; - +/* sql type stored in .frm files for virtual fields */ +#define MYSQL_TYPE_VIRTUAL 245 /* Length of random string sent by server on handshake; this is also length of obfuscated password, recieved from client @@ -115,6 +121,11 @@ enum enum_server_command thread */ #define REFRESH_MASTER 128 /* Remove all bin logs in the index and truncate the index */ +#define REFRESH_TABLE_STATS 256 /* Refresh table stats hash table */ +#define REFRESH_INDEX_STATS 512 /* Refresh index stats hash table */ +#define REFRESH_USER_STATS 1024 /* Refresh user stats hash table */ +#define REFRESH_SLOW_QUERY_LOG 4096 /* Flush slow query log and rotate*/ +#define REFRESH_CLIENT_STATS 8192 /* Refresh client stats hash table */ /* The following can't be set with mysql_refresh() */ #define REFRESH_READ_LOCK 16384 /* Lock tables for read */ @@ -145,9 +156,17 @@ enum enum_server_command #define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ #define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ +#define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */ + #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) #define CLIENT_REMEMBER_OPTIONS (1UL << 31) +#ifdef HAVE_COMPRESS +#define CAN_CLIENT_COMPRESS CLIENT_COMPRESS +#else +#define CAN_CLIENT_COMPRESS 0 +#endif + /* Gather all possible capabilites (flags) supported by the server */ #define CLIENT_ALL_FLAGS (CLIENT_LONG_PASSWORD | \ CLIENT_FOUND_ROWS | \ @@ -168,7 +187,8 @@ enum enum_server_command CLIENT_MULTI_STATEMENTS | \ CLIENT_MULTI_RESULTS | \ CLIENT_SSL_VERIFY_SERVER_CERT | \ - CLIENT_REMEMBER_OPTIONS) + CLIENT_REMEMBER_OPTIONS | \ + CLIENT_PLUGIN_AUTH) /* Switch off the flags that are optional and depending on build flags @@ -481,14 +501,14 @@ void create_random_string(char *to, unsigned int length, void hash_password(unsigned long *to, const char *password, unsigned int password_len); void make_scrambled_password_323(char *to, const char *password); void scramble_323(char *to, const char *message, const char *password); -my_bool check_scramble_323(const char *, const char *message, +my_bool check_scramble_323(const unsigned char *reply, const char *message, unsigned long *salt); void get_salt_from_password_323(unsigned long *res, const char *password); void make_password_from_salt_323(char *to, const unsigned long *salt); void make_scrambled_password(char *to, const char *password); void scramble(char *to, const char *message, const char *password); -my_bool check_scramble(const char *reply, const char *message, +my_bool check_scramble(const unsigned char *reply, const char *message, const unsigned char *hash_stage2); void get_salt_from_password(unsigned char *res, const char *password); void make_password_from_salt(char *to, const unsigned char *hash_stage2); diff --git a/include/service_versions.h b/include/service_versions.h new file mode 100644 index 00000000000..114957cdd86 --- /dev/null +++ b/include/service_versions.h @@ -0,0 +1,24 @@ +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef _WIN32 +#define SERVICE_VERSION __declspec(dllexport) void * +#else +#define SERVICE_VERSION void * +#endif + +#define VERSION_my_snprintf 0x0100 +#define VERSION_thd_alloc 0x0100 + diff --git a/include/sql_common.h b/include/sql_common.h index 9e43d076ba9..6b66ae2fd81 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -1,3 +1,4 @@ +#ifndef SQL_COMMON_INCLUDED /* Copyright (C) 2003-2004, 2006 MySQL AB This program is free software; you can redistribute it and/or modify @@ -13,14 +14,60 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define SQL_COMMON_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include <mysql.h> extern const char *unknown_sqlstate; extern const char *cant_connect_sqlstate; extern const char *not_error_sqlstate; -#ifdef __cplusplus -extern "C" { +struct st_mysql_options_extention { + char *plugin_dir; + char *default_auth; +}; + +typedef struct st_mysql_methods +{ + my_bool (*read_query_result)(MYSQL *mysql); + my_bool (*advanced_command)(MYSQL *mysql, + enum enum_server_command command, + const unsigned char *header, + unsigned long header_length, + const unsigned char *arg, + unsigned long arg_length, + my_bool skip_check, + MYSQL_STMT *stmt); + MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields, + unsigned int fields); + MYSQL_RES * (*use_result)(MYSQL *mysql); + void (*fetch_lengths)(unsigned long *to, + MYSQL_ROW column, unsigned int field_count); + void (*flush_use_result)(MYSQL *mysql); + int (*read_change_user_result)(MYSQL *mysql); +#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) + MYSQL_FIELD * (*list_fields)(MYSQL *mysql); + my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); + int (*stmt_execute)(MYSQL_STMT *stmt); + int (*read_binary_rows)(MYSQL_STMT *stmt); + int (*unbuffered_fetch)(MYSQL *mysql, char **row); + void (*free_embedded_thd)(MYSQL *mysql); + const char *(*read_statistics)(MYSQL *mysql); + my_bool (*next_result)(MYSQL *mysql); + int (*read_rows_from_cursor)(MYSQL_STMT *stmt); #endif +} MYSQL_METHODS; + +#define simple_command(mysql, command, arg, length, skip_check) \ + (*(mysql)->methods->advanced_command)(mysql, command, 0, \ + 0, arg, length, skip_check, NULL) +#define stmt_command(mysql, command, arg, length, stmt) \ + (*(mysql)->methods->advanced_command)(mysql, command, 0, \ + 0, arg, length, 1, stmt) extern CHARSET_INFO *default_client_charset_info; MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, @@ -42,9 +89,23 @@ void set_stmt_errmsg(MYSQL_STMT *stmt, NET *net); void set_stmt_error(MYSQL_STMT *stmt, int errcode, const char *sqlstate, const char *err); void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate); +void set_mysql_extended_error(MYSQL *mysql, int errcode, const char *sqlstate, + const char *format, ...); + +/* client side of the pluggable authentication */ +struct st_plugin_vio_info; +void mpvio_info(Vio *vio, struct st_plugin_vio_info *info); +int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, + const char *data_plugin, const char *db); +int mysql_client_plugin_init(); +void mysql_client_plugin_deinit(); +struct st_mysql_client_plugin; +extern struct st_mysql_client_plugin *mysql_client_builtins[]; + #ifdef __cplusplus } #endif #define protocol_41(A) ((A)->server_capabilities & CLIENT_PROTOCOL_41) +#endif diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 96ebaa0dc30..2e99b2a001d 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -95,7 +95,7 @@ SET(CLIENT_SOURCES ../mysys/array.c ../strings/bchange.c ../strings/bmove.c ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c ../mysys/mf_qsort.c - ../mysys/my_getsystime.c ../mysys/my_sync.c ${LIB_SOURCES}) + ../mysys/my_getsystime.c ../mysys/my_sync.c ../sql-common/client_plugin.c ${LIB_SOURCES}) # Need to set USE_TLS for building the DLL, since __declspec(thread) # approach to thread local storage does not work properly in DLLs. @@ -110,27 +110,17 @@ SET(CLIENT_SOURCES ../mysys/array.c ../strings/bchange.c ../strings/bmove.c ADD_LIBRARY(mysqlclient STATIC ${CLIENT_SOURCES}) ADD_DEPENDENCIES(mysqlclient GenError) -TARGET_LINK_LIBRARIES(mysqlclient) -ADD_LIBRARY(mysqlclient_notls STATIC ${CLIENT_SOURCES}) -ADD_DEPENDENCIES(mysqlclient_notls GenError) -TARGET_LINK_LIBRARIES(mysqlclient_notls) +SET(SHARED_SOURCES dll.c libmysql.def) +ADD_VERSION_INFO(libmysql SHARED SHARED_SOURCES) +ADD_LIBRARY(libmysql SHARED ${SHARED_SOURCES}) -ADD_LIBRARY(libmysql SHARED ${CLIENT_SOURCES} dll.c libmysql.def) IF(WIN32) SET_TARGET_PROPERTIES(libmysql mysqlclient PROPERTIES COMPILE_FLAGS "-DUSE_TLS") ENDIF(WIN32) ADD_DEPENDENCIES(libmysql GenError) -TARGET_LINK_LIBRARIES(libmysql wsock32) +TARGET_LINK_LIBRARIES(libmysql mysqlclient ws2_32) +ADD_DEFINITIONS(-DHAVE_DLOPEN) -IF(EMBED_MANIFESTS) - MYSQL_EMBED_MANIFEST("myTest" "asInvoker") -ENDIF(EMBED_MANIFESTS) - -# TODO: Install mysqlclient_notls? -# TODO: Which component should these be part of, development? -INSTALL(TARGETS mysqlclient DESTINATION lib/opt COMPONENT runtime) -INSTALL(TARGETS libmysql DESTINATION lib/opt COMPONENT runtime) - -# Also install libmysql.dll to the bin dir -INSTALL(TARGETS libmysql DESTINATION bin COMPONENT runtime) +MYSQL_INSTALL_TARGETS(mysqlclient DESTINATION lib COMPONENT Development) +MYSQL_INSTALL_TARGETS(libmysql DESTINATION lib COMPONENT SharedLibraries) diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index d443cb12363..089cade996a 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -23,6 +23,7 @@ MYSQLDATAdir = $(localstatedir) MYSQLSHAREdir = $(pkgdatadir) MYSQLBASEdir= $(prefix) +pkgplugindir = $(pkglibdir)/plugin ## We'll use CLIENT_EXTRA_LDFLAGS for threaded and non-threaded ## until someone complains that they need separate options. LDADD = @CLIENT_EXTRA_LDFLAGS@ $(target) @@ -72,26 +73,27 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ my_getopt.lo my_port.lo \ my_rename.lo my_chsize.lo my_sync.lo my_getsystime.lo sqlobjects = net.lo -sql_cmn_objects = pack.lo client.lo my_time.lo +sql_cmn_objects = pack.lo client.lo my_time.lo client_plugin.lo # Not needed in the minimum library mysysobjects2 = my_lib.lo mf_qsort.lo mysysobjects = $(mysysobjects1) $(mysysobjects2) target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \ $(sql_cmn_objects) $(vio_objects) $(sqlobjects) -target_ldflags = -version-info @SHARED_LIB_VERSION@ @LD_VERSION_SCRIPT@ +target_ldflags = -version-info @SHARED_LIB_VERSION@ @LD_VERSION_SCRIPT@ @LIBDL@ vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo BUILT_SOURCES = link_sources CLEANFILES = $(target_libadd) $(SHLIBOBJS) \ $(target) $(BUILT_SOURCES) -DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \ - -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ +DEFS = -DDEFAULT_CHARSET_HOME='"$(MYSQLBASEdir)"' \ + -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \ -DDEFAULT_HOME_ENV=MYSQL_HOME \ + -DPLUGINDIR='"$(pkgplugindir)"' \ -DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \ - -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \ - -DSHAREDIR="\"$(MYSQLSHAREdir)\"" $(target_defs) + -DDEFAULT_SYSCONFDIR='"$(sysconfdir)"' \ + -DSHAREDIR='"$(MYSQLSHAREdir)"' $(target_defs) if HAVE_YASSL yassl_las = $(top_builddir)/extra/yassl/src/libyassl.la \ diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h index f87e625771f..b486c101327 100644 --- a/libmysql/client_settings.h +++ b/libmysql/client_settings.h @@ -18,7 +18,8 @@ extern char * mysql_unix_port; #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \ CLIENT_TRANSACTIONS | \ - CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION) + CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | \ + CLIENT_PLUGIN_AUTH) sig_handler my_pipe_sig_handler(int sig); void read_user_name(char *name); @@ -57,7 +58,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt); int cli_read_binary_rows(MYSQL_STMT *stmt); int cli_unbuffered_fetch(MYSQL *mysql, char **row); const char * cli_read_statistics(MYSQL *mysql); -int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd); +int cli_read_change_user_result(MYSQL *mysql); #ifdef EMBEDDED_LIBRARY int init_embedded_server(int argc, char **argv, char **groups); diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c index 95ee6862aa8..fc77db151aa 100644 --- a/libmysql/errmsg.c +++ b/libmysql/errmsg.c @@ -85,6 +85,7 @@ const char *client_errors[]= "Lost connection to MySQL server at '%s', system error: %d", "Statement closed indirectly because of a preceeding %s() call", "The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again", + "Authentication plugin '%s' cannot be loaded: %s", "" }; @@ -151,6 +152,7 @@ const char *client_errors[]= "Lost connection to MySQL server at '%s', system error: %d", "Statement closed indirectly because of a preceeding %s() call", "The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again", + "Authentication plugin '%s' cannot be loaded: %s", "" }; @@ -215,6 +217,7 @@ const char *client_errors[]= "Lost connection to MySQL server at '%s', system error: %d", "Statement closed indirectly because of a preceeding %s() call", "The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again", + "Authentication plugin '%s' cannot be loaded: %s", "" }; #endif diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 6c2f34e55a3..6fc380b4a20 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -126,6 +126,8 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)), if (my_init()) /* Will init threads */ return 1; init_client_errs(); + if (mysql_client_plugin_init()) + return 1; if (!mysql_port) { mysql_port = MYSQL_PORT; @@ -144,11 +146,9 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)), */ #if MYSQL_PORT_DEFAULT == 0 - { - struct servent *serv_ptr; - if ((serv_ptr = getservbyname("mysql", "tcp"))) - mysql_port = (uint) ntohs((ushort) serv_ptr->s_port); - } + struct servent *serv_ptr; + if ((serv_ptr = getservbyname("mysql", "tcp"))) + mysql_port = (uint) ntohs((ushort) serv_ptr->s_port); #endif if ((env = getenv("MYSQL_TCP_PORT"))) mysql_port =(uint) atoi(env); @@ -200,6 +200,8 @@ void STDCALL mysql_server_end() if (!mysql_client_init) return; + mysql_client_plugin_deinit(); + #ifdef EMBEDDED_LIBRARY end_embedded_server(); #endif @@ -673,44 +675,14 @@ mysql_connect(MYSQL *mysql,const char *host, Change user and database **************************************************************************/ -int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd) -{ - NET *net= &mysql->net; - ulong pkt_length; - - pkt_length= cli_safe_read(mysql); - - if (pkt_length == packet_error) - return 1; - - if (pkt_length == 1 && net->read_pos[0] == 254 && - mysql->server_capabilities & CLIENT_SECURE_CONNECTION) - { - /* - By sending this very specific reply server asks us to send scrambled - password in old format. The reply contains scramble_323. - */ - scramble_323(buff, mysql->scramble, passwd); - if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) || - net_flush(net)) - { - set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate); - return 1; - } - /* Read what server thinks about out new auth message report */ - if (cli_safe_read(mysql) == packet_error) - return 1; - } - return 0; -} - my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, const char *passwd, const char *db) { - char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2]; - char *end= buff; int rc; CHARSET_INFO *saved_cs= mysql->charset; + char *saved_user= mysql->user; + char *saved_passwd= mysql->passwd; + char *saved_db= mysql->db; DBUG_ENTER("mysql_change_user"); @@ -724,49 +696,11 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, /* Use an empty string instead of NULL. */ - if (!user) - user=""; - if (!passwd) - passwd=""; - - /* - Store user into the buffer. - Advance position as strmake returns a pointer to the closing NUL. - */ - end= strmake(end, user, USERNAME_LENGTH) + 1; - - /* write scrambled password according to server capabilities */ - if (passwd[0]) - { - if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION) - { - *end++= SCRAMBLE_LENGTH; - scramble(end, mysql->scramble, passwd); - end+= SCRAMBLE_LENGTH; - } - else - { - scramble_323(end, mysql->scramble, passwd); - end+= SCRAMBLE_LENGTH_323 + 1; - } - } - else - *end++= '\0'; /* empty password */ - /* Add database if needed */ - end= strmake(end, db ? db : "", NAME_LEN) + 1; - - /* Add character set number. */ - - if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION) - { - int2store(end, (ushort) mysql->charset->number); - end+= 2; - } - - /* Write authentication package */ - simple_command(mysql,COM_CHANGE_USER, (uchar*) buff, (ulong) (end-buff), 1); + mysql->user= (char*)(user ? user : ""); + mysql->passwd= (char*)(passwd ? passwd : ""); + mysql->db= 0; - rc= (*mysql->methods->read_change_user_result)(mysql, buff, passwd); + rc= run_plugin_auth(mysql, 0, 0, 0, db); /* The server will close all statements no matter was the attempt @@ -776,18 +710,21 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, if (rc == 0) { /* Free old connect information */ - my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); + my_free(saved_user, MYF(MY_ALLOW_ZERO_PTR)); + my_free(saved_passwd, MYF(MY_ALLOW_ZERO_PTR)); + my_free(saved_db, MYF(MY_ALLOW_ZERO_PTR)); /* alloc new connect information */ - mysql->user= my_strdup(user,MYF(MY_WME)); - mysql->passwd=my_strdup(passwd,MYF(MY_WME)); - mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0; + mysql->user= my_strdup(mysql->user, MYF(MY_WME)); + mysql->passwd= my_strdup(mysql->passwd, MYF(MY_WME)); + mysql->db= db ? my_strdup(db, MYF(MY_WME)) : 0; } else { mysql->charset= saved_cs; + mysql->user= saved_user; + mysql->passwd= saved_passwd; + mysql->db= saved_db; } DBUG_RETURN(rc); diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index b74a38cc8a6..d964def7505 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -29,14 +29,15 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/regex ${CMAKE_SOURCE_DIR}/extra/yassl/include - ${CMAKE_SOURCE_DIR}/zlib) + ${CMAKE_SOURCE_DIR}/zlib + ${CMAKE_BINARY_DIR}/sql) -SET(GEN_SOURCES ${CMAKE_SOURCE_DIR}/sql/sql_yacc.cc - ${CMAKE_SOURCE_DIR}/sql/sql_yacc.h +SET(GEN_SOURCES ${CMAKE_BINARY_DIR}/sql/sql_yacc.cc + ${CMAKE_BINARY_DIR}/sql/sql_yacc.h ${CMAKE_SOURCE_DIR}/sql/message.h ${CMAKE_SOURCE_DIR}/sql/message.rc - ${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc - ${CMAKE_SOURCE_DIR}/sql/lex_hash.h) + ${CMAKE_BINARY_DIR}/sql/sql_builtin.cc + ${CMAKE_BINARY_DIR}/sql/lex_hash.h) SET_SOURCE_FILES_PROPERTIES(${GEN_SOURCES} PROPERTIES GENERATED 1) @@ -96,12 +97,12 @@ ENDFOREACH(ENGINE) SET(SOURCE_SUBLIBS FALSE) -SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc +SET(LIBMYSQLD_SOURCES libmysqld.c emb_qcache.cc lib_sql.cc ../libmysql/libmysql.c ../libmysql/errmsg.c ../client/get_password.c ../sql-common/client.c ../sql-common/my_time.c ../sql-common/my_user.c ../sql-common/pack.c ../sql/password.c ../sql/discover.cc ../sql/derror.cc - ../sql/field.cc ../sql/field_conv.cc + ../sql/field.cc ../sql/field_conv.cc ../sql-common/client_plugin.c ../sql/filesort.cc ../sql/gstream.cc ../sql/ha_partition.cc ../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc ../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc @@ -136,7 +137,8 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc ../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc ../sql/partition_info.cc ../sql/sql_connect.cc - ../sql/scheduler.cc ../sql/event_parse_data.cc + ../sql/scheduler.cc ../sql/event_parse_data.cc + ../sql/create_options.cc ${GEN_SOURCES} ${LIB_SOURCES}) @@ -169,6 +171,4 @@ ADD_LIBRARY(libmysqld SHARED cmake_dummy.c libmysqld.def) ADD_DEPENDENCIES(libmysqld mysqlserver) TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32 iphlpapi) -INSTALL(TARGETS mysqlserver DESTINATION Embedded/static COMPONENT embedded) - -INSTALL(TARGETS libmysqld DESTINATION Embedded/DLL COMPONENT embedded) +MYSQL_INSTALL_TARGETS(mysqlserver libmysqld DESTINATION lib COMPONENT Embedded) diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 7a2c92ed030..7605c33021f 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -26,10 +26,10 @@ pkgplugindir = $(pkglibdir)/plugin EXTRA_DIST = libmysqld.def CMakeLists.txt DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ - -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ - -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ - -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ - -DPLUGINDIR="\"$(pkgplugindir)\"" + -DDEFAULT_MYSQL_HOME='"$(MYSQLBASEdir)"' \ + -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \ + -DSHAREDIR='"$(MYSQLSHAREdir)"' \ + -DPLUGINDIR='"$(pkgplugindir)"' INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/sql -I$(top_srcdir)/sql \ -I$(top_srcdir)/sql/examples \ @@ -42,7 +42,7 @@ pkglib_LTLIBRARIES = libmysqld.la SUBDIRS = . examples libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \ - my_time.c + my_time.c client_plugin.c noinst_HEADERS = embedded_priv.h emb_qcache.h @@ -76,7 +76,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \ debug_sync.cc \ - sql_tablespace.cc \ + sql_tablespace.cc create_options.cc \ rpl_injector.cc my_user.c partition_info.cc \ sql_servers.cc event_parse_data.cc opt_table_elimination.cc diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h index 369b344d4bd..c246693594b 100644 --- a/libmysqld/embedded_priv.h +++ b/libmysqld/embedded_priv.h @@ -15,6 +15,8 @@ /* Prototypes for the embedded version of MySQL */ +#include <sql_common.h> + C_MODE_START void lib_connection_phase(NET *net, int phase); void init_embedded_mysql(MYSQL *mysql, int client_flag); diff --git a/libmysqld/examples/CMakeLists.txt b/libmysqld/examples/CMakeLists.txt index 2b900a1fa8f..e5f6388496b 100644 --- a/libmysqld/examples/CMakeLists.txt +++ b/libmysqld/examples/CMakeLists.txt @@ -27,16 +27,17 @@ ENDIF(WIN32) ADD_DEFINITIONS(-DEMBEDDED_LIBRARY) -ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc + +MYSQL_ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc ../../client/mysql.cc ../../client/readline.cc - ../../client/sql_string.cc) + COMPONENT Test) TARGET_LINK_LIBRARIES(mysql_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32) -TARGET_LINK_LIBRARIES(mysql_embedded libmysqld) +TARGET_LINK_LIBRARIES(mysql_embedded mysqlserver) -ADD_EXECUTABLE(mysqltest_embedded ../../client/mysqltest.cc) +MYSQL_ADD_EXECUTABLE(mysqltest_embedded ../../client/mysqltest.cc COMPONENT Test) TARGET_LINK_LIBRARIES(mysqltest_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32) -TARGET_LINK_LIBRARIES(mysqltest_embedded libmysqld) +TARGET_LINK_LIBRARIES(mysqltest_embedded mysqlserver) -ADD_EXECUTABLE(mysql_client_test_embedded ../../tests/mysql_client_test.c) +MYSQL_ADD_EXECUTABLE(mysql_client_test_embedded ../../tests/mysql_client_test.c COMPONENT Test) TARGET_LINK_LIBRARIES(mysql_client_test_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32) -TARGET_LINK_LIBRARIES(mysql_client_test_embedded libmysqld) +TARGET_LINK_LIBRARIES(mysql_client_test_embedded mysqlserver) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 83a984763e5..226d49b5154 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -35,7 +35,6 @@ C_MODE_START #include <mysql.h> #undef ER #include "errmsg.h" -#include <sql_common.h> #include "embedded_priv.h" extern unsigned int mysql_server_last_errno; @@ -435,11 +434,10 @@ static MYSQL_RES * emb_store_result(MYSQL *mysql) return mysql_store_result(mysql); } -int emb_read_change_user_result(MYSQL *mysql, - char *buff __attribute__((unused)), - const char *passwd __attribute__((unused))) +int emb_read_change_user_result(MYSQL *mysql) { - return mysql_errno(mysql); + mysql->net.read_pos= (uchar*)""; // fake an OK packet + return mysql_errno(mysql) ? packet_error : 1 /* length of the OK packet */; } MYSQL_METHODS embedded_methods= @@ -450,6 +448,7 @@ MYSQL_METHODS embedded_methods= emb_store_result, emb_fetch_lengths, emb_flush_use_result, + emb_read_change_user_result, emb_list_fields, emb_read_prepare_result, emb_stmt_execute, @@ -458,7 +457,6 @@ MYSQL_METHODS embedded_methods= emb_free_embedded_thd, emb_read_statistics, emb_read_query_result, - emb_read_change_user_result, emb_read_rows_from_cursor }; @@ -610,6 +608,8 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag) THD *thd = (THD *)mysql->thd; thd->mysql= mysql; mysql->server_version= server_version; + mysql->client_flag= client_flag; + mysql->server_capabilities= client_flag; init_alloc_root(&mysql->field_alloc, 8192, 0); } @@ -674,14 +674,19 @@ err: int check_embedded_connection(MYSQL *mysql, const char *db) { int result; + LEX_STRING db_str = { (char*)db, db ? strlen(db) : 0 }; THD *thd= (THD*)mysql->thd; thd_init_client_charset(thd, mysql->charset->number); thd->update_charset(); Security_context *sctx= thd->security_ctx; sctx->host_or_ip= sctx->host= (char*) my_localhost; strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1); - sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0)); - result= check_user(thd, COM_CONNECT, NULL, 0, db, true); + strmake(sctx->priv_user, mysql->user, USERNAME_LENGTH-1); + sctx->user= my_strdup(mysql->user, MYF(0)); + sctx->master_access= GLOBAL_ACLS; // Full rights + /* Change database if necessary */ + if (!(result= (db && db[0] && mysql_change_db(thd, &db_str, FALSE)))) + my_ok(thd); net_end_statement(thd); emb_read_query_result(mysql); return result; @@ -690,14 +695,15 @@ int check_embedded_connection(MYSQL *mysql, const char *db) #else int check_embedded_connection(MYSQL *mysql, const char *db) { + /* + we emulate a COM_CHANGE_USER user here, + it's easier than to emulate the complete 3-way handshake + */ + char buf[USERNAME_LENGTH + SCRAMBLE_LENGTH + 1 + 2*NAME_LEN + 2], *end; + NET *net= &mysql->net; THD *thd= (THD*)mysql->thd; Security_context *sctx= thd->security_ctx; - int result; - char scramble_buff[SCRAMBLE_LENGTH]; - int passwd_len; - thd_init_client_charset(thd, mysql->charset->number); - thd->update_charset(); if (mysql->options.client_ip) { sctx->host= my_strdup(mysql->options.client_ip, MYF(0)); @@ -708,36 +714,45 @@ int check_embedded_connection(MYSQL *mysql, const char *db) sctx->host_or_ip= sctx->host; if (acl_check_host(sctx->host, sctx->ip)) - { - result= ER_HOST_NOT_PRIVILEGED; goto err; - } - sctx->user= my_strdup(mysql->user, MYF(0)); + /* construct a COM_CHANGE_USER packet */ + end= strmake(buf, mysql->user, USERNAME_LENGTH) + 1; + + memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble + thd->scramble[SCRAMBLE_LENGTH]= 0; + strcpy(mysql->scramble, thd->scramble); + if (mysql->passwd && mysql->passwd[0]) { - memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble - thd->scramble[SCRAMBLE_LENGTH]= 0; - scramble(scramble_buff, thd->scramble, mysql->passwd); - passwd_len= SCRAMBLE_LENGTH; + *end++= SCRAMBLE_LENGTH; + scramble(end, thd->scramble, mysql->passwd); + end+= SCRAMBLE_LENGTH; } else - passwd_len= 0; + *end++= 0; - if((result= check_user(thd, COM_CONNECT, - scramble_buff, passwd_len, db, true))) - goto err; + end= strmake(end, db ? db : "", NAME_LEN) + 1; - return 0; -err: + int2store(end, (ushort) mysql->charset->number); + end+= 2; + + /* acl_authenticate() takes the data from thd->net->read_pos */ + thd->net.read_pos= (uchar*)buf; + + if (acl_authenticate(thd, 0, end - buf)) { - NET *net= &mysql->net; - strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1); - memcpy(net->sqlstate, - mysql_errno_to_sqlstate(thd->main_da.sql_errno()), - sizeof(net->sqlstate)-1); + x_free(thd->security_ctx->user); + goto err; } - return result; + return 0; + +err: + strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1); + memcpy(net->sqlstate, + mysql_errno_to_sqlstate(thd->main_da.sql_errno()), + sizeof(net->sqlstate)-1); + return 1; } #endif diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 508916e79ba..901decf9dc6 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -21,7 +21,6 @@ #include <mysql_embed.h> #include <mysqld_error.h> #include <my_pthread.h> -#include "embedded_priv.h" #include <my_sys.h> #include <mysys_err.h> #include <m_string.h> @@ -31,6 +30,7 @@ #include <sys/stat.h> #include <signal.h> #include <time.h> +#include "embedded_priv.h" #include "client_settings.h" #ifdef HAVE_PWD_H #include <pwd.h> @@ -84,9 +84,9 @@ static my_bool is_NT(void) ** Shut down connection **************************************************************************/ -static void end_server(MYSQL *mysql) +void embedded_end_server(MYSQL *mysql) { - DBUG_ENTER("end_server"); + DBUG_ENTER("embedded_end_server"); free_old_query(mysql); DBUG_VOID_RETURN; } @@ -172,7 +172,11 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, client_flag|=CLIENT_CAPABILITIES; if (client_flag & CLIENT_MULTI_STATEMENTS) client_flag|= CLIENT_MULTI_RESULTS; - client_flag&= ~CLIENT_COMPRESS; + /* + no compression in embedded as we don't send any data, + and no pluggable auth, as we cannot do a client-server dialog + */ + client_flag&= ~(CLIENT_COMPRESS | CLIENT_PLUGIN_AUTH); if (db) client_flag|=CLIENT_CONNECT_WITH_DB; @@ -219,7 +223,7 @@ error: { /* Free alloced memory */ my_bool free_me=mysql->free_me; - end_server(mysql); + embedded_end_server(mysql); mysql->free_me=0; mysql_close(mysql); mysql->free_me=free_me; diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index 754aa6b3c29..08325cc6180 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -1,5 +1,4 @@ LIBRARY LIBMYSQLD -DESCRIPTION 'MySQL 5.1 Embedded Server Library' VERSION 5.1 EXPORTS mysql_thread_end diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt new file mode 100644 index 00000000000..ddfa2495ade --- /dev/null +++ b/libservices/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (C) 2006 MySQL AB +# +# 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 + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c) + +ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES}) diff --git a/libservices/HOWTO b/libservices/HOWTO new file mode 100644 index 00000000000..3e5597105ab --- /dev/null +++ b/libservices/HOWTO @@ -0,0 +1,100 @@ +How to create a new service +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A "service" is a set of C functions in a structure that a +service dynamic linker uses when a dynamic plugin is loaded. + +If you want to export C++ class you need to provide an +extern "C" function that will create a new instance of your class, +and put it in a service. + +Data structures are not part of the service structure, but they are part +of the API you create and usually need to be declared in the same +service_*.h file. + +To turn a set of functions (foo_func1, foo_func2) +into a service "foo" you need to + +1. create a new file include/mysql/service_foo.h + +2. the template is +================================================================== + #ifndef MYSQL_SERVICE_FOO_INCLUDED + /* standard GPL header */ + + /** + @file + *exhaustive* description of the interface you provide. + This file is the main user documentation of the new service + */ + #ifdef __cplusplus + extern "C" { + #endif + + extern struct foo_service_st { + int (*foo_func1_type)(...); /* fix the prototype as appropriate */ + void (*foo_func2_type)(...); /* fix the prototype as appropriate */ + } *foo_service; + + #ifdef MYSQL_DYNAMIC_PLUGIN + + #define foo_func1(...) foo_service->foo_func1_type(...) + #define foo_func2(...) foo_service->foo_func2_type(...) + + #else + + int foo_func1(...); /* fix the prototype as appropriate */ + void foo_func2(...); /* fix the prototype as appropriate */ + + #endif + + #ifdef __cplusplus + } + #endif + + #define MYSQL_SERVICE_FOO_INCLUDED + #endif +================================================================== + +the service_foo.h file should be self-contained, if it needs system headers - +include them in it, e.g. if you use size_t - #include <stdlib.h> + +it should also declare all the accompanying data structures, as necessary +(e.g. thd_alloc_service declares MYSQL_LEX_STRING). + +3. add the new file to include/Makefile.am (pkginclude_HEADERS) +4. add the new file to include/mysql/services.h +5. increase the minor plugin ABI version in include/mysql/plugin.h + (MYSQL_PLUGIN_INTERFACE_VERSION = MYSQL_PLUGIN_INTERFACE_VERSION+1) +6. add the version of your service to include/service_versions.h: +================================================================== + #define VERSION_foo 0x0100 +================================================================== + +7. create a new file libservices/foo_service.c using the following template: +================================================================== + /* GPL header */ + #include <service_versions.h> + SERVICE_VERSION *foo_service= (void*)VERSION_foo; +================================================================== + +8. add the new file to libservices/CMakeLists.txt (MYSQLSERVICES_SOURCES) +9. add the new file to libservices/Makefile.am (libmysqlservices_a_SOURCES) +10. and finally, register your service for dynamic linking in + sql/sql_plugin_services.h +10.1 fill in the service structure: +================================================================== + static struct foo_service_st foo_handler = { + foo_func1, + foo_func2 + } +================================================================== + +10.2 and add it to the list of services + +================================================================== + { "foo_service", VERSION_foo, &foo_handler } +================================================================== + +that's all. + diff --git a/libservices/Makefile.am b/libservices/Makefile.am new file mode 100644 index 00000000000..642081859c1 --- /dev/null +++ b/libservices/Makefile.am @@ -0,0 +1,19 @@ +# Copyright 2009 Sun Microsystems, Inc. +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +AM_CPPFLAGS = -I$(top_srcdir)/include +pkglib_LIBRARIES = libmysqlservices.a +libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c +EXTRA_DIST = CMakeLists.txt diff --git a/libservices/my_snprintf_service.c b/libservices/my_snprintf_service.c new file mode 100644 index 00000000000..40d778e4b8d --- /dev/null +++ b/libservices/my_snprintf_service.c @@ -0,0 +1,17 @@ +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <service_versions.h> +SERVICE_VERSION my_snprintf_service= (void*)VERSION_my_snprintf; diff --git a/libservices/thd_alloc_service.c b/libservices/thd_alloc_service.c new file mode 100644 index 00000000000..5d4d496774c --- /dev/null +++ b/libservices/thd_alloc_service.c @@ -0,0 +1,17 @@ +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <service_versions.h> +SERVICE_VERSION *thd_alloc_service= (void*)VERSION_thd_alloc; diff --git a/mysql-test/CMakeLists.txt b/mysql-test/CMakeLists.txt new file mode 100644 index 00000000000..38b934c476c --- /dev/null +++ b/mysql-test/CMakeLists.txt @@ -0,0 +1,137 @@ +# Copyright (c) 2006, 2010, 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 + +IF(INSTALL_MYSQLTESTDIR) +INSTALL( + DIRECTORY . + DESTINATION ${INSTALL_MYSQLTESTDIR} + USE_SOURCE_PERMISSIONS + COMPONENT Test + PATTERN "var/" EXCLUDE + PATTERN "lib/My/SafeProcess" EXCLUDE + PATTERN "lib/t*" EXCLUDE + PATTERN "CPack" EXCLUDE + PATTERN "CMake*" EXCLUDE + PATTERN "mtr.out*" EXCLUDE + PATTERN ".cvsignore" EXCLUDE + PATTERN "*.am" EXCLUDE + PATTERN "*.in" EXCLUDE + PATTERN "*.vcproj" EXCLUDE + PATTERN "*.vcxproj" EXCLUDE + PATTERN "*.vcxproj.*" EXCLUDE +) +ENDIF() + + + +IF(NOT ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) + # Enable running mtr from build directory + CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/mtr.out-of-source + ${CMAKE_CURRENT_BINARY_DIR}/mysql-test-run.pl + @ONLY + ) +ENDIF() +IF(UNIX) + EXECUTE_PROCESS( + COMMAND chmod +x mysql-test-run.pl + COMMAND ${CMAKE_COMMAND} -E create_symlink + ./mysql-test-run.pl mtr + COMMAND ${CMAKE_COMMAND} -E create_symlink + ./mysql-test-run.pl mysql-test-run + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + IF(INSTALL_MYSQLTESTDIR) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mtr + ${CMAKE_CURRENT_BINARY_DIR}/mysql-test-run + DESTINATION ${INSTALL_MYSQLTESTDIR} + COMPONENT Test) + ENDIF() +ENDIF() + +IF(CMAKE_GENERATOR MATCHES "Visual Studio") + SET(SETCONFIG_COMMAND set MTR_VS_CONFIG=${CMAKE_CFG_INTDIR}) +ELSEIF(CMAKE_GENERATOR MATCHES "Xcode") + SET(SETCONFIG_COMMAND export MTR_VS_CONFIG=${CMAKE_CFG_INTDIR}) +ELSE() + SET(SETCONFIG_COMMAND echo Running tests) +ENDIF() +IF(CYGWIN) + # On cygwin, pretend to be "Unix" system + SET(SETOS_COMMAND export MTR_CYGWIN_IS_UNIX=1) +ELSE() + SET(SETOS_COMMAND echo OS=${CMAKE_SYSTEM_NAME}) +ENDIF() + + + +SET(EXP --experimental=collections/default.experimental) +IF(WIN32) + SET(SET_ENV set) +ELSE() + SET(SET_ENV export) +ENDIF() + + +SET(MTR_FORCE perl ./mysql-test-run.pl --force) +IF(EXISTS ${CMAKE_SOURCE_DIR}/mysql-test/suite/nist) + SET(TEST_NIST ${MTR_FORCE} --comment=nist suite=nist ${EXP} && + ${MTR_FORCE} --comment=nist --force --suite=nist+ps ${EXP}) +ELSE() + SET(TEST_NIST echo "NIST tests not found") +ENDIF() + +IF(WITH_EMBEDDED_SERVER) + SET(TEST_EMBEDDED ${MTR_FORCE} --comment=embedded --timer --embedded-server + --skip-rpl --skip-ndbcluster $(EXP)) +ELSE() + SET(TEST_EMBEDDED echo "Can not test embedded, not compiled in") +ENDIF() + +SET(TEST_BT_START + COMMAND ${SETCONFIG_COMMAND} + COMMAND ${SETOS_COMMAND} + COMMAND ${SET_ENV} MTR_BUILD_THREAD=auto +) + +ADD_CUSTOM_TARGET(test-force + ${TEST_BT_START} + COMMAND ${MTR_FORCE} +) + +ADD_CUSTOM_TARGET(test-bt + ${TEST_BT_START} + COMMAND ${MTR_FORCE} --comment=normal --timer --skip-ndbcluster --report-features ${EXP} + COMMAND ${MTR_FORCE} --comment=ps --timer --skip-ndbcluster --ps-protocol ${EXP} + COMMAND ${MTR_FORCE} --comment=funcs1+ps --ps-protocol --reorder --suite=funcs_1 ${EXP} + COMMAND ${MTR_FORCE} --comment=funcs2 --suite=funcs_2 ${EXP} + COMMAND ${MTR_FORCE} --comment=partitions --suite=parts ${EXP} + COMMAND ${MTR_FORCE} --comment=stress --suite=stress ${EXP} + COMMAND ${MTR_FORCE} --force --comment=jp --suite=jp ${EXP} + COMMAND ${TEST_NIST} + COMMAND ${TEST_EMBEDDED} +) + +ADD_CUSTOM_TARGET(test-bt-fast + ${TEST_BT_START} + COMMAND ${MTR_FORCE} --comment=ps --timer --skip-ndbcluster --ps-protocol --report-features ${EXP} + COMMAND ${MTR_FORCE} --comment=stress --suite=stress ${EXP} +) + +ADD_CUSTOM_TARGET(test-bt-debug + ${TEST_BT_START} + COMMAND ${MTR_FORCE} --comment=debug --timer --skip-ndbcluster --skip-rpl --report-features ${EXP} +) + diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index d99da446fb9..ddf8d0457f3 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -72,7 +72,9 @@ SUBDIRS = lib/My/SafeProcess EXTRA_DIST = README README.suites \ $(test_SCRIPTS) \ - $(nobase_test_DATA) + $(nobase_test_DATA) \ + CMakeLists.txt \ + mtr.out-of-source # List of directories containing test + result files and the # related test data files that should be copied @@ -83,6 +85,10 @@ TEST_DIRS = t r include std_data std_data/parts collections \ extra/binlog_tests/ extra/rpl_tests \ suite/binlog suite/binlog/t suite/binlog/r suite/binlog/std_data \ suite/federated \ + suite/pbxt/t suite/pbxt/r suite/pbxt \ + suite/vcol suite/vcol/t suite/vcol/r suite/vcol/inc \ + suite/oqgraph suite/oqgraph/t suite/oqgraph/r \ + suite/percona suite/sphinx \ suite/funcs_1 suite/funcs_1/bitdata \ suite/funcs_1/include suite/funcs_1/lib suite/funcs_1/r \ suite/funcs_1/t suite/funcs_1/views suite/funcs_1/cursors \ @@ -101,7 +107,6 @@ TEST_DIRS = t r include std_data std_data/parts collections \ suite/ndb suite/ndb/t suite/ndb/r \ suite/rpl_ndb suite/rpl_ndb/t suite/rpl_ndb/r \ suite/parts suite/parts/t suite/parts/r suite/parts/inc \ - suite/pbxt/t suite/pbxt/r suite/pbxt \ suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \ suite/innodb_plugin suite/innodb_plugin/t suite/innodb_plugin/r \ suite/innodb_plugin/include \ diff --git a/mysql-test/extra/rpl_tests/rpl_row_func003.test b/mysql-test/extra/rpl_tests/rpl_row_func003.test index b77465de39e..6369d36e7e3 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_func003.test +++ b/mysql-test/extra/rpl_tests/rpl_row_func003.test @@ -47,17 +47,9 @@ delimiter ;| --disable_warnings INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1()); -sleep 6; INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1()); -sleep 6; --enable_warnings -#Select in this test are used for debugging -#select * from test.t1; -#connection slave; -#select * from test.t1; - -connection master; SET AUTOCOMMIT=0; START TRANSACTION; --disable_warnings @@ -65,18 +57,14 @@ INSERT INTO test.t1 VALUES (null,test.f1()); --enable_warnings ROLLBACK; SET AUTOCOMMIT=1; -#select * from test.t1; -#sleep 6; - -#connection slave; -#select * from test.t1; - -#connection master; -#used for debugging -#show binlog events; +# Sync master and slave for all engines except NDB +if (`SELECT UPPER(LEFT('$engine_type', 3)) != 'NDB'`) { + sync_slave_with_master; + connection master; +} -# time to dump the databases and so we can see if they match +# Time to dump the databases and so we can see if they match --exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/func003_master.sql --exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/func003_slave.sql @@ -93,5 +81,8 @@ DROP TABLE test.t1; diff_files $MYSQLTEST_VARDIR/tmp/func003_master.sql $MYSQLTEST_VARDIR/tmp/func003_slave.sql; +# Clean up +remove_file $MYSQLTEST_VARDIR/tmp/func003_master.sql; +remove_file $MYSQLTEST_VARDIR/tmp/func003_slave.sql; # End of 5.0 test case diff --git a/mysql-test/include/have_maria.inc b/mysql-test/include/have_maria.inc index 474e9db12b9..82725beb1e0 100644 --- a/mysql-test/include/have_maria.inc +++ b/mysql-test/include/have_maria.inc @@ -1,4 +1,5 @@ -disable_query_log; ---require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'maria'; -enable_query_log; +if (!`SELECT count(*) FROM information_schema.engines WHERE + (support = 'YES' OR support = 'DEFAULT') AND + engine = 'aria'`){ + skip Need Aria engine; +} diff --git a/mysql-test/include/have_xtradb.inc b/mysql-test/include/have_xtradb.inc index 6c2fc5155a9..3f3893e5642 100644 --- a/mysql-test/include/have_xtradb.inc +++ b/mysql-test/include/have_xtradb.inc @@ -1,4 +1,5 @@ -disable_query_log; ---require r/true.require -SELECT (plugin_description LIKE '%xtradb%') AS `TRUE` FROM information_schema.plugins WHERE LOWER(plugin_name) = 'innodb' AND LOWER(plugin_status) = 'active'; -enable_query_log; +if (!`SELECT count(*) FROM information_schema.plugins WHERE + plugin_name = 'innodb' AND plugin_status = 'active' AND + plugin_description LIKE '%xtradb%'`){ + skip Need XtraDB engine; +} diff --git a/mysql-test/include/have_xtradb.opt b/mysql-test/include/have_xtradb.opt new file mode 100644 index 00000000000..4fb96229a7b --- /dev/null +++ b/mysql-test/include/have_xtradb.opt @@ -0,0 +1,2 @@ +--loose-innodb +--plugin-load=$HA_XTRADB_SO diff --git a/mysql-test/include/maria_empty_logs.inc b/mysql-test/include/maria_empty_logs.inc index e8b6a423953..78a08228caa 100644 --- a/mysql-test/include/maria_empty_logs.inc +++ b/mysql-test/include/maria_empty_logs.inc @@ -28,52 +28,52 @@ EOF if (!$mel_keep_control_file) { --error 0,1 - remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log_control; + remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log_control; } -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000001; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000001; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000002; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000002; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000003; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000003; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000004; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000004; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000005; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000005; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000006; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000006; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000007; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000007; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000008; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000008; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000009; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000009; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000010; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000010; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000011; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000011; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000012; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000012; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000013; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000013; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000014; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000014; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000015; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000015; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000016; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000016; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000017; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000017; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000018; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000018; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000019; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000019; -- error 0,1 -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000020; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000020; # hope there are not more than these logs... -- error 0,1 -remove_file $MYSQLD_DATADIR/maria_recovery.trace; +remove_file $MYSQLD_DATADIR/aria_recovery.trace; --enable_warnings append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; diff --git a/mysql-test/include/maria_make_snapshot_for_feeding_recovery.inc b/mysql-test/include/maria_make_snapshot_for_feeding_recovery.inc index 8a2a99c28eb..fded4cb83b4 100644 --- a/mysql-test/include/maria_make_snapshot_for_feeding_recovery.inc +++ b/mysql-test/include/maria_make_snapshot_for_feeding_recovery.inc @@ -34,8 +34,8 @@ let $mms_copy=0; let $MYSQLD_DATADIR= `SELECT @@datadir`; --disable_warnings -- error 0,1 -remove_file $MYSQLTEST_VARDIR/tmp/mms_for_$mms_purpose.maria_log_control; +remove_file $MYSQLTEST_VARDIR/tmp/mms_for_$mms_purpose.aria_log_control; --enable_warnings -copy_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log_control $MYSQLTEST_VARDIR/tmp/mms_for_$mms_purpose.maria_log_control; +copy_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log_control $MYSQLTEST_VARDIR/tmp/mms_for_$mms_purpose.aria_log_control; connection default; diff --git a/mysql-test/include/maria_verify_recovery.inc b/mysql-test/include/maria_verify_recovery.inc index e8354c43837..71292947c80 100644 --- a/mysql-test/include/maria_verify_recovery.inc +++ b/mysql-test/include/maria_verify_recovery.inc @@ -56,8 +56,8 @@ if ($mvr_restore_old_snapshot) # also copy back control file, to force recovery to start from an early # point, ignoring further checkpoints. -- error 0,1 - remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log_control; - copy_file $MYSQLTEST_VARDIR/tmp/mms_for_$mms_purpose.maria_log_control $MYSQLD_DATADIR/$MARIA_LOG/maria_log_control; + remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log_control; + copy_file $MYSQLTEST_VARDIR/tmp/mms_for_$mms_purpose.aria_log_control $MYSQLD_DATADIR/$MARIA_LOG/aria_log_control; } --echo * recovery happens diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm index 94ed75648b5..90c0ee4ecfb 100644 --- a/mysql-test/lib/My/ConfigFactory.pm +++ b/mysql-test/lib/My/ConfigFactory.pm @@ -53,6 +53,15 @@ sub get_testdir { return $testdir; } +# Retrive build directory (which is different from basedir in out-of-source build) +sub get_bindir { + if (defined $ENV{MTR_BINDIR}) + { + return $ENV{MTR_BINDIR}; + } + my ($self, $group)= @_; + return $self->get_basedir($group); +} sub fix_charset_dir { my ($self, $config, $group_name, $group)= @_; @@ -62,7 +71,7 @@ sub fix_charset_dir { sub fix_language { my ($self, $config, $group_name, $group)= @_; - return my_find_dir($self->get_basedir($group), + return my_find_dir($self->get_bindir($group), \@share_locations, "english"); } @@ -220,6 +229,7 @@ my @mysqld_rules= ( { 'basedir' => sub { return shift->{ARGS}->{basedir}; } }, { 'tmpdir' => \&fix_tmpdir }, + { 'log-basename' => sub { return "mysqld" } }, { 'character-sets-dir' => \&fix_charset_dir }, { 'language' => \&fix_language }, { 'datadir' => \&fix_datadir }, @@ -228,6 +238,7 @@ my @mysqld_rules= { 'port' => \&fix_port }, { '#extra-port' => \&fix_port }, { 'socket' => \&fix_socket }, + { 'log-error' => \&fix_log_error }, { '#log-error' => \&fix_log_error }, { 'general-log' => sub { return 1; } }, { 'general-log-file' => \&fix_log }, @@ -236,6 +247,7 @@ my @mysqld_rules= { '#user' => sub { return shift->{ARGS}->{user} || ""; } }, { '#password' => sub { return shift->{ARGS}->{password} || ""; } }, { 'server-id' => \&fix_server_id, }, + { 'sync-sys' => sub { return 1; } }, # By default, prevent the started mysqld to access files outside of vardir { 'secure-file-priv' => sub { return shift->{ARGS}->{vardir}; } }, { 'ssl-ca' => \&fix_ssl_ca }, @@ -358,6 +370,7 @@ my @mysql_upgrade_rules= sub post_check_client_group { my ($self, $config, $client_group_name, $mysqld_group_name)= @_; + # Settings needed for client, copied from its "mysqld" my %client_needs= ( @@ -367,7 +380,6 @@ sub post_check_client_group { user => '#user', password => '#password', ); - my $group_to_copy_from= $config->group($mysqld_group_name); while (my ($name_to, $name_from)= each( %client_needs )) { my $option= $group_to_copy_from->option($name_from); diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index 0f0b5b8c175..baeb452fde0 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -86,23 +86,34 @@ sub is_child { my @safe_process_cmd; my $safe_kill; +my $bindir; +if(defined $ENV{MTR_BINDIR}) +{ + # This is an out-of-source build. Build directory + # is given in MTR_BINDIR env.variable + $bindir = $ENV{MTR_BINDIR}."/mysql-test"; +} +else +{ + $bindir = "."; +} # Find the safe process binary or script sub find_bin { if (IS_WIN32PERL or IS_CYGWIN) { # Use my_safe_process.exe - my $exe= my_find_bin(".", ["lib/My/SafeProcess", "My/SafeProcess"], + my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"], "my_safe_process"); push(@safe_process_cmd, $exe); # Use my_safe_kill.exe - $safe_kill= my_find_bin(".", "lib/My/SafeProcess", "my_safe_kill"); + $safe_kill= my_find_bin($bindir, "lib/My/SafeProcess", "my_safe_kill"); } else { # Use my_safe_process - my $exe= my_find_bin(".", ["lib/My/SafeProcess", "My/SafeProcess"], + my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"], "my_safe_process"); push(@safe_process_cmd, $exe); } diff --git a/mysql-test/lib/My/SafeProcess/CMakeLists.txt b/mysql-test/lib/My/SafeProcess/CMakeLists.txt index 5150fcaafff..6edf9d45683 100644 --- a/mysql-test/lib/My/SafeProcess/CMakeLists.txt +++ b/mysql-test/lib/My/SafeProcess/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright (C) 2008 MySQL AB +# Copyright (c) 2006, 2010, 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 @@ -11,7 +12,18 @@ # # 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 -ADD_EXECUTABLE(my_safe_process safe_process_win.cc) -ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc) +SET(INSTALL_ARGS + DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" + COMPONENT Test +) + +IF (WIN32) + MYSQL_ADD_EXECUTABLE(my_safe_process safe_process_win.cc ${INSTALL_ARGS}) + MYSQL_ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc ${INSTALL_ARGS}) +ELSE() + MYSQL_ADD_EXECUTABLE(my_safe_process safe_process.cc ${INSTALL_ARGS}) +ENDIF() + +INSTALL(FILES safe_process.pl Base.pm DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" COMPONENT Test) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index e311a9bc3ba..f453cb387b7 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -91,15 +91,16 @@ sub init_pattern { sub testcase_sort_order { my ($a, $b, $sort_criteria)= @_; - my $a_sort_criteria= $sort_criteria->{$a->fullname()}; - my $b_sort_criteria= $sort_criteria->{$b->fullname()}; - my $res= $a_sort_criteria cmp $b_sort_criteria; - return $res if $res; # Run slow tests first, trying to avoid getting stuck at the end # with a slow test in one worker and the other workers idle. return -1 if $a->{'long_test'} && !$b->{'long_test'}; return 1 if !$a->{'long_test'} && $b->{'long_test'}; + my $a_sort_criteria= $sort_criteria->{$a->fullname()}; + my $b_sort_criteria= $sort_criteria->{$b->fullname()}; + my $res= $a_sort_criteria cmp $b_sort_criteria; + return $res if $res; + return $a->fullname() cmp $b->fullname(); } @@ -939,6 +940,11 @@ sub collect_one_test_case { $tinfo->{'comment'}= "Test needs --big-test"; return $tinfo } + if ( $tinfo->{'big_test'} ) + { + # All 'big_test' takes a long time to run + $tinfo->{'long_test'}= 1; + } if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries ) { @@ -1057,6 +1063,16 @@ sub collect_one_test_case { } } + if ( $tinfo->{'oqgraph_test'} ) + { + if ( !$ENV{'GRAPH_ENGINE_SO'} ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Test requires the OQGraph storage engine"; + return $tinfo; + } + } + if (not ref $::suites{$tinfo->{suite}}) { $tinfo->{'skip'}= 1; diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl index 0e47ec885bd..ef4de686bab 100755 --- a/mysql-test/lib/v1/mysql-test-run.pl +++ b/mysql-test/lib/v1/mysql-test-run.pl @@ -2243,20 +2243,20 @@ sub environment_setup () { "$glob_basedir/myisam/myisampack")); # ---------------------------------------------------- - # Setup env so childs can execute maria_pack and maria_chk + # Setup env so childs can execute aria_pack and aria_chk # ---------------------------------------------------- - $ENV{'MARIA_CHK'}= mtr_native_path(mtr_exe_maybe_exists( - vs_config_dirs('storage/maria', 'maria_chk'), - vs_config_dirs('maria', 'maria_chk'), - "$path_client_bindir/maria_chk", - "$glob_basedir/storage/maria/maria_chk", - "$glob_basedir/maria/maria_chk")); - $ENV{'MARIA_PACK'}= mtr_native_path(mtr_exe_maybe_exists( - vs_config_dirs('storage/maria', 'maria_pack'), - vs_config_dirs('maria', 'maria_pack'), - "$path_client_bindir/maria_pack", - "$glob_basedir/storage/maria/maria_pack", - "$glob_basedir/maria/maria_pack")); + $ENV{'ARIA_CHK'}= mtr_native_path(mtr_exe_maybe_exists( + vs_config_dirs('storage/maria', 'aria_chk'), + vs_config_dirs('maria', 'aria_chk'), + "$path_client_bindir/aria_chk", + "$glob_basedir/storage/maria/aria_chk", + "$glob_basedir/maria/aria_chk")); + $ENV{'ARIA_PACK'}= mtr_native_path(mtr_exe_maybe_exists( + vs_config_dirs('storage/maria', 'aria_pack'), + vs_config_dirs('maria', 'aria_pack'), + "$path_client_bindir/aria_pack", + "$glob_basedir/storage/maria/aria_pack", + "$glob_basedir/maria/aria_pack")); # ---------------------------------------------------- # We are nice and report a bit about our settings @@ -3207,7 +3207,7 @@ sub install_db ($$) { mtr_add_arg($args, "--datadir=%s", $data_dir); mtr_add_arg($args, "--loose-skip-innodb"); mtr_add_arg($args, "--loose-skip-ndbcluster"); - mtr_add_arg($args, "--loose-skip-maria"); + mtr_add_arg($args, "--loose-skip-aria"); mtr_add_arg($args, "--disable-sync-frm"); mtr_add_arg($args, "--loose-disable-debug"); mtr_add_arg($args, "--tmpdir=."); @@ -3217,7 +3217,7 @@ sub install_db ($$) { # Setup args for bootstrap.test # mtr_init_args(\$cmd_args); - mtr_add_arg($cmd_args, "--loose-skip-maria"); + mtr_add_arg($cmd_args, "--loose-skip-aria"); if ( $opt_debug ) { @@ -5300,7 +5300,6 @@ sub valgrind_arguments { else { mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option - mtr_add_arg($args, "--alignment=8"); mtr_add_arg($args, "--leak-check=yes"); mtr_add_arg($args, "--num-callers=16"); mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir) diff --git a/mysql-test/mtr.out-of-source b/mysql-test/mtr.out-of-source new file mode 100644 index 00000000000..c2809ede136 --- /dev/null +++ b/mysql-test/mtr.out-of-source @@ -0,0 +1,5 @@ +#!/usr/bin/perl +# Call mtr in out-of-source build +$ENV{MTR_BINDIR} = "@CMAKE_BINARY_DIR@"; +chdir("@CMAKE_SOURCE_DIR@/mysql-test"); +exit(system($^X, "@CMAKE_SOURCE_DIR@/mysql-test/mysql-test-run.pl", @ARGV) >> 8);
\ No newline at end of file diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1c9d3b5159f..417b60d8d46 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -112,6 +112,7 @@ $SIG{INT}= sub { mtr_error("Got ^C signal"); }; our $mysql_version_id; our $glob_mysql_test_dir; our $basedir; +our $bindir; our $path_charsetsdir; our $path_client_bindir; @@ -159,7 +160,7 @@ my $path_config_file; # The generated config file, var/my.cnf # executables will be used by the test suite. our $opt_vs_config = $ENV{'MTR_VS_CONFIG'}; -my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,handler,parts,innodb,innodb_plugin,percona,ndb"; +my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,handler,parts,innodb,innodb_plugin,percona,ndb,vcol,oqgraph,sphinx"; my $opt_suites; our $opt_verbose= 0; # Verbose output, enable with --verbose @@ -531,7 +532,7 @@ sub run_test_server ($$$) { my $completed= []; my %running; my $result; - my $exe_mysqld= find_mysqld($basedir) || ""; # Used as hint to CoreDump + my $exe_mysqld= find_mysqld($bindir) || ""; # Used as hint to CoreDump my $suite_timeout= start_timer(suite_timeout()); @@ -907,7 +908,7 @@ sub run_worker ($) { $valgrind_reports= valgrind_exit_reports(); } if ( $opt_gprof ) { - gprof_collect (find_mysqld($basedir), keys %gprof_dirs); + gprof_collect (find_mysqld($bindir), keys %gprof_dirs); } exit($valgrind_reports); } @@ -1147,6 +1148,10 @@ sub command_line_setup { $basedir= dirname($basedir); } + # Respect MTR_BINDIR variable, which is typically set in to the + # build directory in out-of-source builds. + $bindir=$ENV{MTR_BINDIR}||$basedir; + fix_vs_config_dir(); # Look for the client binaries directory @@ -1157,21 +1162,25 @@ sub command_line_setup { } else { - $path_client_bindir= mtr_path_exists("$basedir/client_release", - "$basedir/client_debug", - "$basedir/client$opt_vs_config", - "$basedir/client", - "$basedir/bin"); + $path_client_bindir= mtr_path_exists("$bindir/client_release", + "$bindir/client_debug", + "$bindir/client$opt_vs_config", + "$bindir/client", + "$bindir/bin"); } - # Look for language files and charsetsdir, use same share - $path_language= mtr_path_exists("$basedir/share/mariadb/english", - "$basedir/share/mysql/english", - "$basedir/sql/share/english", - "$basedir/share/english"); + + $path_language= mtr_path_exists("$bindir/share/mariadb/english", + "$bindir/share/mysql/english", + "$bindir/sql/share/english", + "$bindir/share/english"); my $path_share= dirname($path_language); - $path_charsetsdir= mtr_path_exists("$path_share/charsets"); + + $path_charsetsdir= mtr_path_exists("$basedir/share/charsets", + "$basedir/share/mysql/charsets", + "$basedir/sql/share/charsets", + "$basedir/share/charsets"); # --debug implies we run debug server $opt_debug_server= 1 if $opt_debug; @@ -1337,7 +1346,15 @@ sub command_line_setup { # -------------------------------------------------------------------------- # Set the "var/" directory, the base for everything else # -------------------------------------------------------------------------- - $default_vardir= "$glob_mysql_test_dir/var"; + if(defined $ENV{MTR_BINDIR}) + { + $default_vardir= "$ENV{MTR_BINDIR}/mysql-test/var"; + } + else + { + $default_vardir= "$glob_mysql_test_dir/var"; + } + if ( ! $opt_vardir ) { $opt_vardir= $default_vardir; @@ -1408,25 +1425,15 @@ sub command_line_setup { # -------------------------------------------------------------------------- if ( $opt_embedded_server ) { - if ( IS_WINDOWS ) - { - # Add the location for libmysqld.dll to the path. - my $separator= ";"; - my $lib_mysqld= - mtr_path_exists("$basedir/libmysqld$opt_vs_config"); - if ( IS_CYGWIN ) - { - $lib_mysqld= posix_path($lib_mysqld); - $separator= ":"; - } - $ENV{'PATH'}= "$ENV{'PATH'}".$separator.$lib_mysqld; - } $opt_skip_ndbcluster= 1; # Turn off use of NDB cluster $opt_skip_ssl= 1; # Turn off use of SSL # Turn off use of bin log push(@opt_extra_mysqld_opt, "--skip-log-bin"); + # Write errors to stderr, not to mysqld.1.err + push(@opt_extra_mysqld_opt, "--disable-log-error"); + if ( using_extern() ) { mtr_error("Can't use --extern with --embedded-server"); @@ -1435,21 +1442,18 @@ sub command_line_setup { if ($opt_gdb) { - mtr_warning("Silently converting --gdb to --client-gdb in embedded mode"); $opt_client_gdb= $opt_gdb; $opt_gdb= undef; } if ($opt_ddd) { - mtr_warning("Silently converting --ddd to --client-ddd in embedded mode"); $opt_client_ddd= $opt_ddd; $opt_ddd= undef; } if ($opt_debugger) { - mtr_warning("Silently converting --debugger to --client-debugger in embedded mode"); $opt_client_debugger= $opt_debugger; $opt_debugger= undef; } @@ -1717,7 +1721,7 @@ sub collect_mysqld_features { mtr_add_arg($args, "--user=root"); } - my $exe_mysqld= find_mysqld($basedir); + my $exe_mysqld= find_mysqld($bindir); my $cmd= join(" ", $exe_mysqld, @$args); my $list= `$cmd`; @@ -1842,7 +1846,7 @@ sub find_mysqld { unshift(@mysqld_names, "mysqld-debug"); } - return my_find_bin($mysqld_basedir, + return my_find_bin($bindir, ["sql", "libexec", "sbin", "bin"], [@mysqld_names]); } @@ -1892,7 +1896,7 @@ sub executable_setup () { if ( $opt_embedded_server ) { $exe_mysqltest= - mtr_exe_exists("$basedir/libmysqld/examples$opt_vs_config/mysqltest_embedded", + mtr_exe_exists("$bindir/libmysqld/examples$opt_vs_config/mysqltest_embedded", "$path_client_bindir/mysqltest_embedded"); } else @@ -2005,11 +2009,11 @@ sub mysql_client_test_arguments(){ # mysql_client_test executable may _not_ exist if ( $opt_embedded_server ) { $exe= mtr_exe_maybe_exists( - "$basedir/libmysqld/examples$opt_vs_config/mysql_client_test_embedded", - "$basedir/bin/mysql_client_test_embedded"); + "$bindir/libmysqld/examples$opt_vs_config/mysql_client_test_embedded", + "$bindir/bin/mysql_client_test_embedded"); } else { - $exe= mtr_exe_maybe_exists("$basedir/tests$opt_vs_config/mysql_client_test", - "$basedir/bin/mysql_client_test"); + $exe= mtr_exe_maybe_exists("$bindir/tests$opt_vs_config/mysql_client_test", + "$bindir/bin/mysql_client_test"); } my $args; @@ -2021,13 +2025,13 @@ sub mysql_client_test_arguments(){ mtr_add_arg($args, "--testcase"); mtr_add_arg($args, "--vardir=$opt_vardir"); client_debug_arg($args,"mysql_client_test"); - - return mtr_args2str($exe, @$args); + my $ret=mtr_args2str($exe, @$args); + return $ret; } sub tool_arguments ($$) { my($sedir, $tool_name) = @_; - my $exe= my_find_bin($basedir, + my $exe= my_find_bin($bindir, [$sedir, "bin"], $tool_name); @@ -2041,7 +2045,7 @@ sub tool_arguments ($$) { # scripts to run the mysqld binary to test invalid server startup options. sub mysqld_client_arguments () { my $default_mysqld= default_mysqld(); - my $exe = find_mysqld($basedir); + my $exe = find_mysqld($bindir); my $args; mtr_init_args(\$args); mtr_add_arg($args, "--no-defaults"); @@ -2053,7 +2057,7 @@ sub mysqld_client_arguments () { sub have_maria_support () { - my $maria_var= $mysqld_variables{'maria'}; + my $maria_var= $mysqld_variables{'aria'}; return defined $maria_var and $maria_var eq 'TRUE'; } @@ -2311,24 +2315,24 @@ sub environment_setup { # some versions, test using it should be skipped # ---------------------------------------------------- my $exe_bug25714= - mtr_exe_maybe_exists("$basedir/tests$opt_vs_config/bug25714"); + mtr_exe_maybe_exists("$bindir/tests$opt_vs_config/bug25714"); $ENV{'MYSQL_BUG25714'}= native_path($exe_bug25714); # ---------------------------------------------------- # mysql_fix_privilege_tables.sql # ---------------------------------------------------- my $file_mysql_fix_privilege_tables= - mtr_file_exists("$basedir/scripts/mysql_fix_privilege_tables.sql", - "$basedir/share/mysql_fix_privilege_tables.sql", - "$basedir/share/mariadb/mysql_fix_privilege_tables.sql", - "$basedir/share/mysql/mysql_fix_privilege_tables.sql"); + mtr_file_exists("$bindir/scripts/mysql_fix_privilege_tables.sql", + "$bindir/share/mysql_fix_privilege_tables.sql", + "$bindir/share/mariadb/mysql_fix_privilege_tables.sql", + "$bindir/share/mysql/mysql_fix_privilege_tables.sql"); $ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}= $file_mysql_fix_privilege_tables; # ---------------------------------------------------- # my_print_defaults # ---------------------------------------------------- my $exe_my_print_defaults= - mtr_exe_exists("$basedir/extra$opt_vs_config/my_print_defaults", + mtr_exe_exists("$bindir/extra$opt_vs_config/my_print_defaults", "$path_client_bindir/my_print_defaults"); $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= native_path($exe_my_print_defaults); @@ -2341,12 +2345,12 @@ sub environment_setup { $ENV{'MYISAM_FTDUMP'}= tool_arguments("storage/myisam", "myisam_ftdump"); # ---------------------------------------------------- - # maria tools + # aria tools # ---------------------------------------------------- if (have_maria_support()) { - $ENV{'MARIA_CHK'}= tool_arguments("storage/maria", "maria_chk"); - $ENV{'MARIA_PACK'}= tool_arguments("storage/maria", "maria_pack"); + $ENV{'MARIA_CHK'}= tool_arguments("storage/maria", "aria_chk"); + $ENV{'MARIA_PACK'}= tool_arguments("storage/maria", "aria_pack"); } # ---------------------------------------------------- @@ -2363,7 +2367,7 @@ sub environment_setup { # ---------------------------------------------------- # perror # ---------------------------------------------------- - my $exe_perror= mtr_exe_exists("$basedir/extra$opt_vs_config/perror", + my $exe_perror= mtr_exe_exists("$bindir/extra$opt_vs_config/perror", "$path_client_bindir/perror"); $ENV{'MY_PERROR'}= native_path($exe_perror); @@ -2420,9 +2424,11 @@ sub remove_stale_vardir () { mtr_report(" - WARNING: Using the 'mysql-test/var' symlink"); # Make sure the directory where it points exist - mtr_error("The destination for symlink $opt_vardir does not exist") - if ! -d readlink($opt_vardir); - + if (! -d readlink($opt_vardir)) + { + mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory"); + unlink($opt_vardir); + } foreach my $bin ( glob("$opt_vardir/*") ) { mtr_verbose("Removing bin $bin"); @@ -2489,8 +2495,11 @@ sub setup_vardir() { # it's a symlink # Make sure the directory where it points exist - mtr_error("The destination for symlink $opt_vardir does not exist") - if ! -d readlink($opt_vardir); + if (! -d readlink($opt_vardir)) + { + mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory"); + unlink($opt_vardir); + } } elsif ( $opt_mem ) { @@ -2544,9 +2553,9 @@ sub setup_vardir() { mkpath($plugindir); if (IS_WINDOWS && !$opt_embedded_server) { - for (<../storage/*$opt_vs_config/*.dll>, - <../plugin/*$opt_vs_config/*.dll>, - <../sql$opt_vs_config/*.dll>) + for (<$bindir/storage/*$opt_vs_config/*.dll>, + <$bindir/plugin/*$opt_vs_config/*.dll>, + <$bindir/sql$opt_vs_config/*.dll>) { my $pname=basename($_); copy rel2abs($_), "$plugindir/$pname"; @@ -2555,7 +2564,7 @@ sub setup_vardir() { } else { - for (<../storage/*/.libs/*.so>,<../plugin/*/.libs/*.so>,<../sql/.libs/*.so>) + for (<$bindir/storage/*/.libs/*.so>,<$bindir/plugin/*/.libs/*.so>,<$bindir/sql/.libs/*.so>) { my $pname=basename($_); symlink rel2abs($_), "$plugindir/$pname"; @@ -2566,8 +2575,8 @@ sub setup_vardir() { else { # hm, what paths work for debs and for rpms ? - for (<$basedir/lib/mysql/plugin/*.so>, - <$basedir/lib/plugin/*.dll>) + for (<$bindir/lib/mysql/plugin/*.so>, + <$bindir/lib/plugin/*.dll>) { my $pname=basename($_); set_plugin_var($pname); @@ -2682,7 +2691,7 @@ sub fix_vs_config_dir () { $opt_vs_config=""; - for (<$basedir/sql/*/mysqld.exe>) { + for (<$bindir/sql/*/mysqld.exe>) { if (-M $_ < $modified) { $modified = -M _; @@ -3272,7 +3281,7 @@ sub mysql_install_db { mtr_add_arg($args, "--loose-skip-innodb"); mtr_add_arg($args, "--loose-skip-pbxt"); mtr_add_arg($args, "--loose-skip-ndbcluster"); - mtr_add_arg($args, "--loose-skip-maria"); + mtr_add_arg($args, "--loose-skip-aria"); mtr_add_arg($args, "--disable-sync-frm"); mtr_add_arg($args, "--loose-disable-debug"); mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/"); @@ -3299,7 +3308,7 @@ sub mysql_install_db { # Setup args for bootstrap.test # #mtr_init_args(\$cmd_args); - #mtr_add_arg($cmd_args, "--loose-skip-maria") + #mtr_add_arg($cmd_args, "--loose-skip-aria") # ---------------------------------------------------------------------- # export MYSQLD_BOOTSTRAP_CMD variable containing <path>/mysqld <args> @@ -4464,7 +4473,7 @@ sub extract_warning_lines ($) { my @patterns = ( - qr/^Warning:|mysqld: Warning|\[Warning\]/, + qr/^Warning|mysqld: Warning|\[Warning\]/, qr/^Error:|\[ERROR\]/, qr/^==\d+==\s+\S/, # valgrind errors qr/InnoDB: Warning|InnoDB: Error/, @@ -4520,6 +4529,8 @@ sub extract_warning_lines ($) { qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|, qr|mysqld: Table '\./mtr/test_suppressions' is marked as crashed and should be repaired|, qr|InnoDB: Error: table 'test/bug39438'|, + qr|Access denied for user|, + qr|Aborted connection|, qr|table.*is full|, ); @@ -5024,14 +5035,13 @@ sub mysqld_arguments ($$$) { if ( $opt_valgrind_mysqld ) { - mtr_add_arg($args, "--skip-safemalloc"); - if ( $mysql_version_id < 50100 ) { mtr_add_arg($args, "--skip-bdb"); } } + mtr_add_arg($args, "--loose-skip-safemalloc"); mtr_add_arg($args, "%s--disable-sync-frm"); if (!using_extern() and $mysql_version_id >= 50106 && !$opt_user_args) @@ -5694,9 +5704,7 @@ sub gdb_arguments { if ( $type eq "client" ) { # write init file for client - mtr_tofile($gdb_init_file, - "set args $str\n" . - "break main\n"); + mtr_tofile($gdb_init_file, "set args $str\n"); } else { @@ -5752,9 +5760,7 @@ sub ddd_arguments { if ( $type eq "client" ) { # write init file for client - mtr_tofile($gdb_init_file, - "set args $str\n" . - "break main\n"); + mtr_tofile($gdb_init_file, "set args $str\n"); } else { diff --git a/mysql-test/r/change_user.result b/mysql-test/r/change_user.result index d43688f8e2c..18c53a5e22b 100644 --- a/mysql-test/r/change_user.result +++ b/mysql-test/r/change_user.result @@ -1,3 +1,36 @@ +grant select on test.* to test_nopw; +grant select on test.* to test_oldpw identified by password "09301740536db389"; +grant select on test.* to test_newpw identified by "newpw"; +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +concat('<', user(), '>') concat('<', current_user(), '>') database() +<root@localhost> <root@localhost> test +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +concat('<', user(), '>') concat('<', current_user(), '>') database() +<test_nopw@localhost> <test_nopw@%> NULL +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +concat('<', user(), '>') concat('<', current_user(), '>') database() +<test_oldpw@localhost> <test_oldpw@%> NULL +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +concat('<', user(), '>') concat('<', current_user(), '>') database() +<test_newpw@localhost> <test_newpw@%> NULL +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +concat('<', user(), '>') concat('<', current_user(), '>') database() +<root@localhost> <root@localhost> NULL +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +concat('<', user(), '>') concat('<', current_user(), '>') database() +<test_nopw@localhost> <test_nopw@%> test +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +concat('<', user(), '>') concat('<', current_user(), '>') database() +<test_oldpw@localhost> <test_oldpw@%> test +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +concat('<', user(), '>') concat('<', current_user(), '>') database() +<test_newpw@localhost> <test_newpw@%> test +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +concat('<', user(), '>') concat('<', current_user(), '>') database() +<root@localhost> <root@localhost> test +drop user test_nopw; +drop user test_oldpw; +drop user test_newpw; Bug#20023 SELECT @@session.sql_big_selects; @@session.sql_big_selects diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index c27ecc5fc8d..7a972f4814a 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -236,3 +236,21 @@ FLUSH PRIVILEGES; # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ +CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB'; +CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389'; +connect(localhost,mysqltest_up1,foo,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'mysqltest_up1'@'localhost' (using password: YES) +select user(), current_user(); +user() current_user() +mysqltest_up1@localhost mysqltest_up1@% +connect(localhost,mysqltest_up2,newpw,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'mysqltest_up2'@'localhost' (using password: YES) +select user(), current_user(); +user() current_user() +mysqltest_up2@localhost mysqltest_up2@% +connect(localhost,mysqltest_nouser,newpw,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'mysqltest_nouser'@'localhost' (using password: YES) +connect(localhost,mysqltest_nouser,,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'mysqltest_nouser'@'localhost' (using password: NO) +DROP USER mysqltest_up1@'%'; +DROP USER mysqltest_up2@'%'; diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index 8a34a1366b9..c0350cfe202 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -730,9 +730,8 @@ set @@sql_mode= pow(2,32)-1; create event e1 on schedule every 1 day do select 1; select @@sql_mode; @@sql_mode -REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH +REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH set @@sql_mode= @old_mode; -select replace(@full_mode, '?', 'NOT_USED') into @full_mode; select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; select name from mysql.event where name = 'p' and sql_mode = @full_mode; name diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index 92e5bcfce6f..d9acadb78fb 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -171,7 +171,7 @@ DROP TABLE t1; # Bug#48295: # explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode # -CREATE TABLE t1 (f1 INT); +CREATE TABLE t1 (f1 INT not null); SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; EXPLAIN EXTENDED SELECT 1 FROM t1 diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index b90eb2a4c0f..2ff1cd2ec4a 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1758,3 +1758,13 @@ MAX(f1) DROP TABLE t1; # End of 5.1 tests +# LP BUG#813418 - incorrect optimisation of max/min by index for +# negated BETWEEN +CREATE TABLE t1 (a int, KEY (a)); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +SELECT MAX(a) FROM t1 WHERE a NOT BETWEEN 3 AND 9; +MAX(a) +10 +drop table t1; +# +End of 5.1 tests diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 2df77cca7b2..0d9b99721cb 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -13,8 +13,8 @@ GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3 GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' grant delete on mysqltest.* to mysqltest_1@localhost; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' @@ -44,15 +44,15 @@ delete from mysql.user where user='mysqltest_1'; flush privileges; grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30 @@ -164,6 +164,7 @@ Warnings: Warning 1364 Field 'ssl_cipher' doesn't have a default value Warning 1364 Field 'x509_issuer' doesn't have a default value Warning 1364 Field 'x509_subject' doesn't have a default value +Warning 1364 Field 'auth_string' doesn't have a default value insert into mysql.db (host, db, user, select_priv) values ('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); alter table mysql.db order by db asc; diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 12269f0cb1c..ee3fe1540b9 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -287,6 +287,7 @@ Warnings: Warning 1364 Field 'ssl_cipher' doesn't have a default value Warning 1364 Field 'x509_issuer' doesn't have a default value Warning 1364 Field 'x509_subject' doesn't have a default value +Warning 1364 Field 'auth_string' doesn't have a default value create user mysqltest_A@'%'; rename user mysqltest_B@'%' to mysqltest_C@'%'; drop user mysqltest_C@'%'; @@ -354,6 +355,7 @@ Warnings: Warning 1364 Field 'ssl_cipher' doesn't have a default value Warning 1364 Field 'x509_issuer' doesn't have a default value Warning 1364 Field 'x509_subject' doesn't have a default value +Warning 1364 Field 'auth_string' doesn't have a default value INSERT INTO mysql.db (host, db, user, select_priv) VALUES ('%','TESTDB','mysqltest_1','Y'); FLUSH PRIVILEGES; diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 537b30520bd..8a2b258e356 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -45,6 +45,7 @@ NOT (table_schema = 'INFORMATION_SCHEMA' AND table_name LIKE 'PBXT_%'); select * from v1 ORDER BY c COLLATE utf8_bin; c CHARACTER_SETS +CLIENT_STATISTICS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY COLUMNS @@ -54,6 +55,7 @@ EVENTS FILES GLOBAL_STATUS GLOBAL_VARIABLES +INDEX_STATISTICS INNODB_BUFFER_POOL_PAGES INNODB_BUFFER_POOL_PAGES_BLOB INNODB_BUFFER_POOL_PAGES_INDEX @@ -70,6 +72,7 @@ INNODB_SYS_STATS INNODB_SYS_TABLES INNODB_TABLE_STATS INNODB_TRX +KEY_CACHES KEY_COLUMN_USAGE PARTITIONS PLUGINS @@ -85,8 +88,10 @@ STATISTICS TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS USER_PRIVILEGES +USER_STATISTICS VIEWS XTRADB_ADMIN_COMMAND XTRADB_ENHANCEMENTS @@ -125,6 +130,7 @@ c table_name TABLES TABLES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES +TABLE_STATISTICS TABLE_STATISTICS TRIGGERS TRIGGERS tables_priv tables_priv time_zone time_zone @@ -144,6 +150,7 @@ c table_name TABLES TABLES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES +TABLE_STATISTICS TABLE_STATISTICS TRIGGERS TRIGGERS tables_priv tables_priv time_zone time_zone @@ -163,6 +170,7 @@ c table_name TABLES TABLES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES +TABLE_STATISTICS TABLE_STATISTICS TRIGGERS TRIGGERS tables_priv tables_priv time_zone time_zone @@ -611,7 +619,7 @@ proc body longblob proc definer char(77) proc created timestamp proc modified timestamp -proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') +proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') proc comment char(64) proc character_set_client char(32) proc collation_connection char(32) @@ -644,12 +652,13 @@ from information_schema.tables where table_schema='information_schema' limit 2; TABLE_NAME TABLE_TYPE ENGINE CHARACTER_SETS SYSTEM VIEW MEMORY -COLLATIONS SYSTEM VIEW MEMORY +CLIENT_STATISTICS SYSTEM VIEW MEMORY show tables from information_schema like "T%"; Tables_in_information_schema (T%) TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS create database information_schema; ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' @@ -659,6 +668,7 @@ Tables_in_information_schema (T%) Table_type TABLES SYSTEM VIEW TABLE_CONSTRAINTS SYSTEM VIEW TABLE_PRIVILEGES SYSTEM VIEW +TABLE_STATISTICS SYSTEM VIEW TRIGGERS SYSTEM VIEW create table t1(a int); ERROR 42S02: Unknown table 't1' in information_schema @@ -671,6 +681,7 @@ Tables_in_information_schema (T%) TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS select table_name from tables where table_name='user'; table_name @@ -860,6 +871,7 @@ TABLE_NAME COLUMN_NAME PRIVILEGES COLUMNS TABLE_NAME select COLUMN_PRIVILEGES TABLE_NAME select FILES TABLE_NAME select +INDEX_STATISTICS TABLE_NAME select INNODB_INDEX_STATS table_name select INNODB_TABLE_STATS table_name select KEY_COLUMN_USAGE TABLE_NAME select @@ -869,6 +881,7 @@ STATISTICS TABLE_NAME select TABLES TABLE_NAME select TABLE_CONSTRAINTS TABLE_NAME select TABLE_PRIVILEGES TABLE_NAME select +TABLE_STATISTICS TABLE_NAME select VIEWS TABLE_NAME select delete from mysql.user where user='mysqltest_4'; delete from mysql.db where user='mysqltest_4'; diff --git a/mysql-test/r/information_schema_all_engines.result b/mysql-test/r/information_schema_all_engines.result index a2209f84a45..7a2c548a329 100644 --- a/mysql-test/r/information_schema_all_engines.result +++ b/mysql-test/r/information_schema_all_engines.result @@ -2,6 +2,7 @@ use INFORMATION_SCHEMA; show tables; Tables_in_information_schema CHARACTER_SETS +CLIENT_STATISTICS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY COLUMNS @@ -11,6 +12,8 @@ EVENTS FILES GLOBAL_STATUS GLOBAL_VARIABLES +INDEX_STATISTICS +KEY_CACHES KEY_COLUMN_USAGE PARTITIONS PLUGINS @@ -26,8 +29,10 @@ STATISTICS TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS USER_PRIVILEGES +USER_STATISTICS VIEWS INNODB_BUFFER_POOL_PAGES PBXT_STATISTICS @@ -64,6 +69,7 @@ c2.column_name LIKE '%SCHEMA%' ); table_name column_name CHARACTER_SETS CHARACTER_SET_NAME +CLIENT_STATISTICS CLIENT COLLATIONS COLLATION_NAME COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME COLUMNS TABLE_SCHEMA @@ -73,6 +79,8 @@ EVENTS EVENT_SCHEMA FILES TABLE_SCHEMA GLOBAL_STATUS VARIABLE_NAME GLOBAL_VARIABLES VARIABLE_NAME +INDEX_STATISTICS TABLE_SCHEMA +KEY_CACHES KEY_CACHE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME @@ -88,8 +96,10 @@ STATISTICS TABLE_SCHEMA TABLES TABLE_SCHEMA TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA +TABLE_STATISTICS TABLE_SCHEMA TRIGGERS TRIGGER_SCHEMA USER_PRIVILEGES GRANTEE +USER_STATISTICS USER VIEWS TABLE_SCHEMA INNODB_BUFFER_POOL_PAGES page_type PBXT_STATISTICS ID @@ -126,6 +136,7 @@ c2.column_name LIKE '%SCHEMA%' ); table_name column_name CHARACTER_SETS CHARACTER_SET_NAME +CLIENT_STATISTICS CLIENT COLLATIONS COLLATION_NAME COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME COLUMNS TABLE_SCHEMA @@ -135,6 +146,8 @@ EVENTS EVENT_SCHEMA FILES TABLE_SCHEMA GLOBAL_STATUS VARIABLE_NAME GLOBAL_VARIABLES VARIABLE_NAME +INDEX_STATISTICS TABLE_SCHEMA +KEY_CACHES KEY_CACHE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME @@ -150,8 +163,10 @@ STATISTICS TABLE_SCHEMA TABLES TABLE_SCHEMA TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA +TABLE_STATISTICS TABLE_SCHEMA TRIGGERS TRIGGER_SCHEMA USER_PRIVILEGES GRANTEE +USER_STATISTICS USER VIEWS TABLE_SCHEMA INNODB_BUFFER_POOL_PAGES page_type PBXT_STATISTICS ID @@ -194,6 +209,7 @@ group by c2.column_type order by num limit 1) group by t.table_name order by num1, t.table_name; table_name group_concat(t.table_schema, '.', t.table_name) num1 CHARACTER_SETS information_schema.CHARACTER_SETS 1 +CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1 COLLATIONS information_schema.COLLATIONS 1 COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1 COLUMNS information_schema.COLUMNS 1 @@ -203,6 +219,7 @@ EVENTS information_schema.EVENTS 1 FILES information_schema.FILES 1 GLOBAL_STATUS information_schema.GLOBAL_STATUS 1 GLOBAL_VARIABLES information_schema.GLOBAL_VARIABLES 1 +INDEX_STATISTICS information_schema.INDEX_STATISTICS 1 INNODB_BUFFER_POOL_PAGES information_schema.INNODB_BUFFER_POOL_PAGES 1 INNODB_BUFFER_POOL_PAGES_BLOB information_schema.INNODB_BUFFER_POOL_PAGES_BLOB 1 INNODB_BUFFER_POOL_PAGES_INDEX information_schema.INNODB_BUFFER_POOL_PAGES_INDEX 1 @@ -219,6 +236,7 @@ INNODB_SYS_STATS information_schema.INNODB_SYS_STATS 1 INNODB_SYS_TABLES information_schema.INNODB_SYS_TABLES 1 INNODB_TABLE_STATS information_schema.INNODB_TABLE_STATS 1 INNODB_TRX information_schema.INNODB_TRX 1 +KEY_CACHES information_schema.KEY_CACHES 1 KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1 PARTITIONS information_schema.PARTITIONS 1 PBXT_STATISTICS information_schema.PBXT_STATISTICS 1 @@ -235,8 +253,10 @@ STATISTICS information_schema.STATISTICS 1 TABLES information_schema.TABLES 1 TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1 TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1 +TABLE_STATISTICS information_schema.TABLE_STATISTICS 1 TRIGGERS information_schema.TRIGGERS 1 USER_PRIVILEGES information_schema.USER_PRIVILEGES 1 +USER_STATISTICS information_schema.USER_STATISTICS 1 VIEWS information_schema.VIEWS 1 XTRADB_ENHANCEMENTS information_schema.XTRADB_ENHANCEMENTS 1 Database: information_schema @@ -244,6 +264,7 @@ Database: information_schema | Tables | +---------------------------------------+ | CHARACTER_SETS | +| CLIENT_STATISTICS | | COLLATIONS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLUMNS | @@ -253,6 +274,8 @@ Database: information_schema | FILES | | GLOBAL_STATUS | | GLOBAL_VARIABLES | +| INDEX_STATISTICS | +| KEY_CACHES | | KEY_COLUMN_USAGE | | PARTITIONS | | PLUGINS | @@ -268,8 +291,10 @@ Database: information_schema | TABLES | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | +| TABLE_STATISTICS | | TRIGGERS | | USER_PRIVILEGES | +| USER_STATISTICS | | VIEWS | | INNODB_BUFFER_POOL_PAGES | | PBXT_STATISTICS | @@ -296,6 +321,7 @@ Database: INFORMATION_SCHEMA | Tables | +---------------------------------------+ | CHARACTER_SETS | +| CLIENT_STATISTICS | | COLLATIONS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLUMNS | @@ -305,6 +331,8 @@ Database: INFORMATION_SCHEMA | FILES | | GLOBAL_STATUS | | GLOBAL_VARIABLES | +| INDEX_STATISTICS | +| KEY_CACHES | | KEY_COLUMN_USAGE | | PARTITIONS | | PLUGINS | @@ -320,8 +348,10 @@ Database: INFORMATION_SCHEMA | TABLES | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | +| TABLE_STATISTICS | | TRIGGERS | | USER_PRIVILEGES | +| USER_STATISTICS | | VIEWS | | INNODB_BUFFER_POOL_PAGES | | PBXT_STATISTICS | @@ -351,5 +381,5 @@ Wildcard: inf_rmation_schema +--------------------+ SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 47 +information_schema 52 mysql 22 diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index a6f81d7688b..b5be0137520 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -7,6 +7,7 @@ Tables_in_information_schema (T%) TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS create database `inf%`; create database mbase; diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index f80fea0fc76..fe579431420 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -1,5 +1,7 @@ drop table if exists t1, t2, t3; -SET @save_key_buffer=@@key_buffer_size; +SET @save_key_buffer_size=@@key_buffer_size; +SET @save_key_cache_block_size=@@key_cache_block_size; +SET @save_key_cache_segments=@@key_cache_segments; SELECT @@key_buffer_size, @@small.key_buffer_size; @@key_buffer_size @@small.key_buffer_size 2097152 131072 @@ -37,7 +39,7 @@ SELECT @@small.key_buffer_size; SELECT @@medium.key_buffer_size; @@medium.key_buffer_size 0 -SET @@global.key_buffer_size=@save_key_buffer; +SET @@global.key_buffer_size=@save_key_buffer_size; SELECT @@default.key_buffer_size; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default.key_buffer_size' at line 1 SELECT @@skr.storage_engine="test"; @@ -365,3 +367,435 @@ Variable_name Value key_cache_block_size 1536 SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; DROP TABLE t1; +set global key_buffer_size=@save_key_buffer_size; +set global key_cache_block_size=@save_key_cache_block_size; +select @@key_buffer_size; +@@key_buffer_size +2097152 +select @@key_cache_block_size; +@@key_cache_block_size +1024 +select @@key_cache_segments; +@@key_cache_segments +0 +create table t1 ( +p int not null auto_increment primary key, +a char(10)); +create table t2 ( +p int not null auto_increment primary key, +i int, a char(10), key k1(i), key k2(a)); +select @@key_cache_segments; +@@key_cache_segments +0 +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default NULL NULL 2097152 1024 0 # 0 0 0 0 0 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +insert into t1 values (1, 'qqqq'), (2, 'yyyy'); +insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), +(3, 1, 'yyyy'), (4, 3, 'zzzz'); +select * from t1; +p a +1 qqqq +2 yyyy +select * from t2; +p i a +1 1 qqqq +2 1 pppp +3 1 yyyy +4 3 zzzz +update t1 set p=3 where p=1; +update t2 set i=2 where i=1; +show status like 'key_%'; +Variable_name Value +Key_blocks_not_flushed 0 +Key_blocks_unused KEY_BLOCKS_UNUSED +Key_blocks_used 4 +Key_blocks_warm 0 +Key_read_requests 22 +Key_reads 0 +Key_write_requests 26 +Key_writes 6 +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default NULL NULL 2097152 1024 4 # 0 22 0 26 6 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +delete from t2 where a='zzzz'; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default NULL NULL 2097152 1024 4 # 0 29 0 32 9 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +delete from t1; +delete from t2; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default NULL NULL 2097152 1024 4 # 0 29 0 32 9 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +set global key_cache_segments=2; +select @@key_cache_segments; +@@key_cache_segments +2 +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 2097152 1024 0 # 0 0 0 0 0 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +insert into t1 values (1, 'qqqq'), (2, 'yyyy'); +insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), +(3, 1, 'yyyy'), (4, 3, 'zzzz'); +select * from t1; +p a +1 qqqq +2 yyyy +select * from t2; +p i a +1 1 qqqq +2 1 pppp +3 1 yyyy +4 3 zzzz +update t1 set p=3 where p=1; +update t2 set i=2 where i=1; +show status like 'key_%'; +Variable_name Value +Key_blocks_not_flushed 0 +Key_blocks_unused KEY_BLOCKS_UNUSED +Key_blocks_used 4 +Key_blocks_warm 0 +Key_read_requests 22 +Key_reads 0 +Key_write_requests 26 +Key_writes 6 +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 2097152 1024 4 # 0 22 0 26 6 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +delete from t1; +delete from t2; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 2097152 1024 4 # 0 22 0 26 6 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +set global key_cache_segments=1; +select @@key_cache_segments; +@@key_cache_segments +1 +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 1 NULL 2097152 1024 0 # 0 0 0 0 0 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +insert into t1 values (1, 'qqqq'), (2, 'yyyy'); +insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), +(3, 1, 'yyyy'), (4, 3, 'zzzz'); +select * from t1; +p a +1 qqqq +2 yyyy +select * from t2; +p i a +1 1 qqqq +2 1 pppp +3 1 yyyy +4 3 zzzz +update t1 set p=3 where p=1; +update t2 set i=2 where i=1; +show status like 'key_%'; +Variable_name Value +Key_blocks_not_flushed 0 +Key_blocks_unused KEY_BLOCKS_UNUSED +Key_blocks_used 4 +Key_blocks_warm 0 +Key_read_requests 22 +Key_reads 0 +Key_write_requests 26 +Key_writes 6 +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 1 NULL 2097152 1024 4 # 0 22 0 26 6 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +delete from t1; +delete from t2; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 1 NULL 2097152 1024 4 # 0 22 0 26 6 +small NULL NULL 1048576 1024 1 # 0 1 0 2 1 +flush tables; +flush status; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 1 NULL 2097152 1024 4 # 0 0 0 0 0 +small NULL NULL 1048576 1024 1 # 0 0 0 0 0 +set global key_buffer_size=32*1024; +select @@key_buffer_size; +@@key_buffer_size +32768 +set global key_cache_segments=2; +select @@key_cache_segments; +@@key_cache_segments +2 +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 0 # 0 0 0 0 0 +small NULL NULL 1048576 1024 1 # 0 0 0 0 0 +insert into t1 values (1, 'qqqq'), (2, 'yyyy'); +insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), +(3, 1, 'yyyy'), (4, 3, 'zzzz'); +select * from t1; +p a +1 qqqq +2 yyyy +select * from t2; +p i a +1 1 qqqq +2 1 pppp +3 1 yyyy +4 3 zzzz +update t1 set p=3 where p=1; +update t2 set i=2 where i=1; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 4 # 0 22 0 26 6 +small NULL NULL 1048576 1024 1 # 0 0 0 0 0 +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 6733 # 3684 103 +small NULL NULL 1048576 1024 # # 0 0 # 0 0 +select * from t1 where p between 1010 and 1020 ; +p a +select * from t2 where p between 1010 and 1020 ; +p i a +1010 2 pppp +1011 2 yyyy +1012 3 zzzz +1013 2 qqqq +1014 2 pppp +1015 2 yyyy +1016 3 zzzz +1017 2 qqqq +1018 2 pppp +1019 2 yyyy +1020 3 zzzz +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 6750 # 3684 103 +small NULL NULL 1048576 1024 # # 0 0 # 0 0 +flush tables; +flush status; +update t1 set a='zzzz' where a='qqqq'; +update t2 set i=1 where i=2; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3076 18 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +set global keycache1.key_buffer_size=256*1024; +select @@keycache1.key_buffer_size; +@@keycache1.key_buffer_size +262144 +set global keycache1.key_cache_segments=7; +select @@keycache1.key_cache_segments; +@@keycache1.key_cache_segments +7 +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3076 18 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache1 7 NULL 262143 2048 # # 0 0 0 0 0 +select * from information_schema.key_caches where key_cache_name like "key%" + and segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +keycache1 7 NULL 262143 2048 0 # 0 0 0 0 0 +cache index t1 key (`primary`) in keycache1; +Table Op Msg_type Msg_text +test.t1 assign_to_keycache status OK +explain select p from t1 where p between 1010 and 1020; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using index +select p from t1 where p between 1010 and 1020; +p +explain select i from t2 where p between 1010 and 1020; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 28 Using where +select i from t2 where p between 1010 and 1020; +i +1 +1 +3 +1 +1 +1 +3 +1 +1 +1 +3 +explain select count(*) from t1, t2 where t1.p = t2.i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index k1 k1 5 NULL 1024 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.i 1 Using index +select count(*) from t1, t2 where t1.p = t2.i; +count(*) +256 +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache1 7 NULL 262143 2048 # # 0 14 3 0 0 +select * from information_schema.key_caches where key_cache_name like "key%" + and segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +keycache1 7 NULL 262143 2048 3 # 0 14 3 0 0 +cache index t2 in keycache1; +Table Op Msg_type Msg_text +test.t2 assign_to_keycache status OK +update t2 set p=p+3000, i=2 where a='qqqq'; +select * from information_schema.key_caches where key_cache_name like "key%" + and segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19 +set global keycache2.key_buffer_size=1024*1024; +cache index t2 in keycache2; +Table Op Msg_type Msg_text +test.t2 assign_to_keycache status OK +insert into t2 values (2000, 3, 'yyyy'); +select * from information_schema.key_caches where key_cache_name like "keycache2" + and segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3 +select * from information_schema.key_caches where key_cache_name like "key%" +and segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19 +keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3 +cache index t2 in keycache1; +Table Op Msg_type Msg_text +test.t2 assign_to_keycache status OK +update t2 set p=p+5000 where a='zzzz'; +select * from t2 where p between 1010 and 1020; +p i a +1010 1 pppp +1011 1 yyyy +1014 1 pppp +1015 1 yyyy +1018 1 pppp +1019 1 yyyy +explain select p from t2 where p between 1010 and 1020; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 7 Using where; Using index +select p from t2 where p between 1010 and 1020; +p +1010 +1011 +1014 +1015 +1018 +1019 +explain select i from t2 where a='yyyy' and i=3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref k1,k2 k1 5 const 188 Using where +select i from t2 where a='yyyy' and i=3; +i +3 +explain select a from t2 where a='yyyy' and i=3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref k1,k2 k1 5 const 188 Using where +select a from t2 where a='yyyy' and i=3 ; +a +yyyy +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache1 7 NULL 262143 2048 # # 0 3201 43 1594 30 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_cache_block_size=2*1024; +insert into t2 values (7000, 3, 'yyyy'); +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache1 7 NULL 262143 2048 # # 0 6 6 3 3 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_cache_block_size=8*1024; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache1 3 NULL 262143 8192 # # 0 0 0 0 0 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +insert into t2 values (8000, 3, 'yyyy'); +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache1 3 NULL 262143 8192 # # 0 6 5 3 3 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_buffer_size=64*1024; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_cache_block_size=2*1024; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache1 3 NULL 65535 2048 # # 0 0 0 0 0 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_cache_block_size=8*1024; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_buffer_size=0; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_cache_block_size=8*1024; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_buffer_size=0; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_buffer_size=128*1024; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache1 1 NULL 131072 8192 # # 0 0 0 0 0 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +set global keycache1.key_cache_block_size=1024; +select * from information_schema.key_caches where segment_number is null; +KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES +default 2 NULL 32768 1024 # # 0 3172 24 1552 18 +small NULL NULL 1048576 1024 # # 0 0 0 0 0 +keycache1 7 NULL 131068 1024 # # 0 0 0 0 0 +keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3 +drop table t1,t2; +set global keycache1.key_buffer_size=0; +set global keycache2.key_buffer_size=0; +set global key_buffer_size=@save_key_buffer_size; +set global key_cache_segments=@save_key_cache_segments; diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result index 7ec07fb5273..1828a5f11e0 100644 --- a/mysql-test/r/lock.result +++ b/mysql-test/r/lock.result @@ -194,3 +194,13 @@ ERROR HY000: Table 't2' was locked with a READ lock and can't be updated UNLOCK TABLES; DROP TABLE t1,t2; End of 5.1 tests. +create table t1 (a int) engine=myisam; +lock tables t1 write concurrent, t1 as t2 read; +lock tables t1 read local; +unlock tables; +unlock tables; +lock tables t1 read local; +lock tables t1 write concurrent, t1 as t2 read; +unlock tables; +unlock tables; +drop table t1; diff --git a/mysql-test/r/log_slow.result b/mysql-test/r/log_slow.result index 57d12a64f5a..b6341109556 100644 --- a/mysql-test/r/log_slow.result +++ b/mysql-test/r/log_slow.result @@ -56,5 +56,6 @@ last_insert_id int(11) NO NULL insert_id int(11) NO NULL server_id int(10) unsigned NO NULL sql_text mediumtext NO NULL +flush slow query logs; set @@log_slow_filter=default; set @@log_slow_verbosity=default; diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result index fcde09db7c5..c6eaf9b6625 100644 --- a/mysql-test/r/log_tables.result +++ b/mysql-test/r/log_tables.result @@ -248,13 +248,13 @@ set global slow_query_log='OFF'; set @save_storage_engine= @@session.storage_engine; set storage_engine= MEMORY; alter table mysql.slow_log engine=ndb; -ERROR HY000: This storage engine cannot be used for log tables" +ERROR HY000: This storage engine cannot be used for log tables alter table mysql.slow_log engine=innodb; -ERROR HY000: This storage engine cannot be used for log tables" +ERROR HY000: This storage engine cannot be used for log tables alter table mysql.slow_log engine=archive; -ERROR HY000: This storage engine cannot be used for log tables" +ERROR HY000: This storage engine cannot be used for log tables alter table mysql.slow_log engine=blackhole; -ERROR HY000: This storage engine cannot be used for log tables" +ERROR HY000: This storage engine cannot be used for log tables set storage_engine= @save_storage_engine; drop table mysql.slow_log; drop table mysql.general_log; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 4135038c6e8..f546b78abaa 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2469,3 +2469,9 @@ test.t1 check status OK DROP TABLE t1; SET GLOBAL myisam_use_mmap=default; End of 5.1 tests +show variables like 'myisam_block_size'; +Variable_name Value +myisam_block_size 1024 +select @@global.myisam_block_size; +@@global.myisam_block_size +1024 diff --git a/mysql-test/r/mysqlbinlog-innodb.result b/mysql-test/r/mysqlbinlog-innodb.result new file mode 100644 index 00000000000..d9f83fb89f0 --- /dev/null +++ b/mysql-test/r/mysqlbinlog-innodb.result @@ -0,0 +1,85 @@ +SET TIMESTAMP=1000000000; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb; +CREATE DATABASE test2; +RESET MASTER; +USE test2; +BEGIN; +USE test; +INSERT INTO t1 VALUES (1); +USE test2; +COMMIT; +BEGIN; +USE test; +INSERT INTO t1 VALUES (2); +USE test2; +COMMIT; +USE test; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +FLUSH LOGS; +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +ROLLBACK/*!*/; +SET TIMESTAMP=1000000000/*!*/; +SET @@session.pseudo_thread_id=999999999/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.sql_mode=0/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +BEGIN +/*!*/; +use test/*!*/; +SET TIMESTAMP=1000000000/*!*/; +INSERT INTO t1 VALUES (1) +/*!*/; +COMMIT/*!*/; +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +SET TIMESTAMP=1000000000/*!*/; +INSERT INTO t1 VALUES (2) +/*!*/; +COMMIT/*!*/; +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +ROLLBACK/*!*/; +SET TIMESTAMP=1000000000/*!*/; +SET @@session.pseudo_thread_id=999999999/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.sql_mode=0/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +BEGIN +/*!*/; +use foo/*!*/; +SET TIMESTAMP=1000000000/*!*/; +INSERT INTO t1 VALUES (1) +/*!*/; +COMMIT/*!*/; +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +SET TIMESTAMP=1000000000/*!*/; +INSERT INTO t1 VALUES (2) +/*!*/; +COMMIT/*!*/; +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +DROP DATABASE test2; +DROP TABLE t1; diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 812fd12e197..8aa121f9854 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -138,6 +138,7 @@ Tables_in_test DROP TABLE `@`; CREATE TABLE `Ñ` (a INT); SET NAMES DEFAULT; +call mtr.add_suppression("@003f.frm' \\(errno: 22\\)"); mysqlcheck --default-character-set="latin1" --databases test test.? Error : Table doesn't exist diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 9723c40721c..86754f1b458 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1722,6 +1722,90 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir </table_data> </database> </mysqldump> + +/*!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_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 */; + +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES (NULL),(10),(20); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; + +LOCK TABLES `t2` WRITE; +/*!40000 ALTER TABLE `t2` DISABLE KEYS */; +INSERT INTO `t2` VALUES (1,NULL,NULL,NULL,NULL,NULL),(2,10,NULL,NULL,NULL,NULL),(3,NULL,'twenty',NULL,NULL,NULL),(4,30,'thirty',NULL,NULL,NULL); +/*!40000 ALTER TABLE `t2` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_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 */; + + +/*!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 */; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `a` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES (NULL),(10),(20); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +DROP TABLE IF EXISTS `t2`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t2` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `a` int(10) DEFAULT NULL, + `b` varchar(30) DEFAULT NULL, + `c` datetime DEFAULT NULL, + `d` blob, + `e` text, + PRIMARY KEY (`pk`) +) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +LOCK TABLES `t2` WRITE; +/*!40000 ALTER TABLE `t2` DISABLE KEYS */; +INSERT INTO `t2` VALUES (1,NULL,NULL,NULL,NULL,NULL),(2,10,NULL,NULL,NULL,NULL),(3,NULL,'twenty',NULL,NULL,NULL),(4,30,'thirty',NULL,NULL,NULL); +/*!40000 ALTER TABLE `t2` ENABLE KEYS */; +UNLOCK TABLES; +/*!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 table t1, t2; # # Bug#12123 mysqldump --tab results in text file which can't be imported diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index fdb0ba46abd..312dd7d0312 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -8,16 +8,19 @@ otto select otto from (select 1 as otto) as t1; otto 1 +select friedrich from (select 1 as otto) as t1; mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed: 1054: Unknown column 'friedrich' in 'field list' select friedrich from (select 1 as otto) as t1; ERROR 42S22: Unknown column 'friedrich' in 'field list' select otto from (select 1 as otto) as t1; otto 1 +select otto from (select 1 as otto) as t1; mysqltest: At line 1: query 'select otto from (select 1 as otto) as t1' succeeded - should have failed with sqlstate 42S22... mysqltest: At line 1: expecting a SQL-state (00000) from query 'remove_file MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp' which cannot produce one... select friedrich from (select 1 as otto) as t1; ERROR 42S22: Unknown column 'friedrich' in 'field list' +select friedrich from (select 1 as otto) as t1; mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22: 'Unknown column 'friedrich' in 'field list'', instead of 00000... select otto from (select 1 as otto) as t1; otto @@ -135,6 +138,7 @@ ERROR 42S02: Table 'test.t1' doesn't exist select 1146 as "after_!errno_masked_error" ; after_!errno_masked_error 1146 +select 3 from t1; mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1000... ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1 is empty @@ -147,6 +151,7 @@ after_--enable_abort_on_error 1064 select 3 from t1 ; ERROR 42S02: Table 'test.t1' doesn't exist +select 3 from t1; mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1064... is empty is empty @@ -343,6 +348,7 @@ included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1: included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1: included from <stdin> at line 1: At line 1: Source directives are nesting too deep +garbage ; mysqltest: In included file "MYSQLTEST_VARDIR/tmp/error.sql": included from <stdin> at line 1: At line 1: query 'garbage ' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1 @@ -447,6 +453,7 @@ mysqltest: At line 1: missing ')' in while mysqltest: At line 1: Missing '{' after while. Found "dec $i" mysqltest: At line 1: Stray '}' - end of block before beginning mysqltest: At line 1: Stray 'end' command - end of block before beginning +{; mysqltest: At line 1: query '{' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{' at line 1 mysqltest: At line 1: Missing '{' after while. Found "echo hej" mysqltest: At line 3: Missing end of block @@ -540,6 +547,10 @@ this will be executed this will be executed mysqltest: The test didn't produce any output Failing multi statement query +create table t1 (a int primary key); +insert into t1 values (1); +select 'select-me'; +insertz 'error query'|||| mysqltest: At line 3: query 'create table t1 (a int primary key); insert into t1 values (1); select 'select-me'; @@ -610,8 +621,8 @@ Abcd select * from t1;; f1 Abcd -mysqltest: At line 2: Cannot run query on connection between send and reap select * from t1;; +mysqltest: At line 2: Cannot run query on connection between send and reap drop table t1; mysqltest: At line 1: Missing required argument 'filename' to command 'remove_file' mysqltest: At line 1: Missing required argument 'directory' to command 'remove_files_wildcard' diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index 269b6875430..a14b1280eb7 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -657,15 +657,16 @@ CREATE TABLE t1 (a INT) PARTITION BY HASH (a); FLUSH TABLES; CHECK TABLE t1; Table Op Msg_type Msg_text +test.t1 check Error File './test/t1.par' not found (Errcode: 2) test.t1 check Error Failed to read from the .par file test.t1 check Error Incorrect information in file: './test/t1.frm' test.t1 check error Corrupt SELECT * FROM t1; -ERROR HY000: Failed to read from the .par file +ERROR HY000: File './test/t1.par' not found (Errcode: 2) # Note that it is currently impossible to drop a partitioned table # without the .par file DROP TABLE t1; -ERROR 42S02: Unknown table 't1' +ERROR HY000: File './test/t1.par' not found (Errcode: 2) # # Bug#49477: Assertion `0' failed in ha_partition.cc:5530 # with temporary table and partitions diff --git a/mysql-test/r/partition_example.result b/mysql-test/r/partition_example.result new file mode 100644 index 00000000000..2129eea0818 --- /dev/null +++ b/mysql-test/r/partition_example.result @@ -0,0 +1,31 @@ +install plugin example soname 'ha_example.so'; +create table t1 (a int not null) +engine=example +partition by list (a) +(partition p0 values in (1), partition p1 values in (2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (1) ENGINE = EXAMPLE, + PARTITION p1 VALUES IN (2) ENGINE = EXAMPLE) */ +drop table t1; +create table t1 (a int not null) +engine=example ull=12340 +partition by list (a) +(partition p0 values in (1), partition p1 values in (2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (1) ENGINE = EXAMPLE, + PARTITION p1 VALUES IN (2) ENGINE = EXAMPLE) */ +drop table t1; +select 1; +1 +1 +uninstall plugin example; diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index 782d2a5a9a4..98be0326ef0 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -12,6 +12,15 @@ CREATE TABLE t1(a int) ENGINE=EXAMPLE; SELECT * FROM t1; a DROP TABLE t1; +set global example_ulong_var=500; +set global example_enum_var= e1; +show status like 'example%'; +Variable_name Value +example_func_example enum_var is 0, ulong_var is 500, really +show variables like 'example%'; +Variable_name Value +example_enum_var e1 +example_ulong_var 500 UNINSTALL PLUGIN example; UNINSTALL PLUGIN EXAMPLE; ERROR 42000: PLUGIN EXAMPLE does not exist @@ -53,4 +62,67 @@ select @@global.example_ulong_var; set session sql_mode=@old_sql_mode; set session old=bla; ERROR HY000: Variable 'old' is a read only variable +#legal values +CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example ULL=10000 STR='dskj' one_or_two='one' YESNO=0; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `complex`='c,f,f,f' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0 +drop table t1; +SET @OLD_SQL_MODE=@@SQL_MODE; +SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; +#illegal value fixed +CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS; +Warnings: +Warning 1653 Incorrect value '10000000000000000000' for option 'ULL' +Warning 1653 Incorrect value 'ttt' for option 'one_or_two' +Warning 1653 Incorrect value 'SSS' for option 'YESNO' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS +#alter table +alter table t1 ULL=10000000; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000 +alter table t1 change a a int complex='c,c,c'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `complex`='c,c,c' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000 +drop table t1; +#illegal value error +SET SQL_MODE=''; +CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS; +ERROR HY000: Incorrect value '10000000000000000000' for option 'ULL' +CREATE TABLE t1 (a int) ENGINE=example ULL=10.00; +ERROR 42000: Only integers allowed as number here near '10.00' at line 1 +CREATE TABLE t1 (a int) ENGINE=example ULL=1e2; +ERROR 42000: Only integers allowed as number here near '1e2' at line 1 +CREATE TABLE t1 (a int) ENGINE=example ULL=0x1234; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=4660 +select create_options from information_schema.tables where table_schema='test' and table_name='t1'; +create_options +`ULL`=4660 +ALTER TABLE t1 ULL=DEFAULT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 +DROP TABLE t1; +SET @@SQL_MODE=@OLD_SQL_MODE; +select 1; +1 +1 UNINSTALL PLUGIN example; diff --git a/mysql-test/r/plugin_maturity.result b/mysql-test/r/plugin_maturity.result new file mode 100644 index 00000000000..97147459f6f --- /dev/null +++ b/mysql-test/r/plugin_maturity.result @@ -0,0 +1,2 @@ +INSTALL PLUGIN example SONAME 'ha_example.so'; +ERROR HY000: Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugins is prohibited by --plugin-maturity=stable) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 84c64a3905a..b3f4ad017d3 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1194,13 +1194,13 @@ SET @aux= "SELECT COUNT(*) prepare my_stmt from @aux; execute my_stmt; COUNT(*) -39 +41 execute my_stmt; COUNT(*) -39 +41 execute my_stmt; COUNT(*) -39 +41 deallocate prepare my_stmt; drop procedure if exists p1| drop table if exists t1| diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result new file mode 100644 index 00000000000..f8df72c6709 --- /dev/null +++ b/mysql-test/r/select_pkeycache.result @@ -0,0 +1,4878 @@ +drop table if exists t1,t2,t3,t4,t11; +drop table if exists t1_1,t1_2,t9_1,t9_2,t1aa,t2aa; +drop view if exists v1; +CREATE TABLE t1 ( +Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, +Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL +); +INSERT INTO t1 VALUES (9410,9412); +select period from t1; +period +9410 +select * from t1; +Period Varor_period +9410 9412 +select t1.* from t1; +Period Varor_period +9410 9412 +CREATE TABLE t2 ( +auto int not null auto_increment, +fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL, +companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL, +fld3 char(30) DEFAULT '' NOT NULL, +fld4 char(35) DEFAULT '' NOT NULL, +fld5 char(35) DEFAULT '' NOT NULL, +fld6 char(4) DEFAULT '' NOT NULL, +UNIQUE fld1 (fld1), +KEY fld3 (fld3), +PRIMARY KEY (auto) +); +select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%"; +fld3 +imaginable +select fld3 from t2 where fld3 like "%cultivation" ; +fld3 +cultivation +select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3; +fld3 companynr +concoct 58 +druggists 58 +engrossing 58 +Eurydice 58 +exclaimers 58 +ferociousness 58 +hopelessness 58 +Huey 58 +imaginable 58 +judges 58 +merging 58 +ostrich 58 +peering 58 +Phelps 58 +presumes 58 +Ruth 58 +sentences 58 +Shylock 58 +straggled 58 +synergy 58 +thanking 58 +tying 58 +unlocks 58 +select fld3,companynr from t2 where companynr = 58 order by fld3; +fld3 companynr +concoct 58 +druggists 58 +engrossing 58 +Eurydice 58 +exclaimers 58 +ferociousness 58 +hopelessness 58 +Huey 58 +imaginable 58 +judges 58 +merging 58 +ostrich 58 +peering 58 +Phelps 58 +presumes 58 +Ruth 58 +sentences 58 +Shylock 58 +straggled 58 +synergy 58 +thanking 58 +tying 58 +unlocks 58 +select fld3 from t2 order by fld3 desc limit 10; +fld3 +youthfulness +yelped +Wotan +workers +Witt +witchcraft +Winsett +Willy +willed +wildcats +select fld3 from t2 order by fld3 desc limit 5; +fld3 +youthfulness +yelped +Wotan +workers +Witt +select fld3 from t2 order by fld3 desc limit 5,5; +fld3 +witchcraft +Winsett +Willy +willed +wildcats +select t2.fld3 from t2 where fld3 = 'honeysuckle'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'h%le'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_'; +fld3 +select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%'; +fld3 +explain select t2.fld3 from t2 where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index +explain select fld3 from t2 ignore index (fld3) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select fld3 from t2 use index (fld1) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select fld3 from t2 use index (fld3) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index +explain select fld3 from t2 use index (fld1,fld3) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index +explain select fld3 from t2 ignore index (fld3,not_used); +ERROR 42000: Key 'not_used' doesn't exist in table 't2' +explain select fld3 from t2 use index (not_used); +ERROR 42000: Key 'not_used' doesn't exist in table 't2' +select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; +fld3 +honeysuckle +honoring +explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range fld3 fld3 30 NULL 2 Using where; Using index +select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; +fld1 fld3 +148504 Colombo +068305 Colombo +000000 nondecreasing +select fld1,fld3 from t2 where companynr = 37 and fld3 = 'appendixes'; +fld1 fld3 +232605 appendixes +1232605 appendixes +1232606 appendixes +1232607 appendixes +1232608 appendixes +1232609 appendixes +select fld1 from t2 where fld1=250501 or fld1="250502"; +fld1 +250501 +250502 +explain select fld1 from t2 where fld1=250501 or fld1="250502"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range fld1 fld1 4 NULL 2 Using where; Using index +select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502; +fld1 +250501 +250502 +250505 +250601 +explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index +select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%'; +fld1 fld3 +218401 faithful +018007 fanatic +228311 fated +018017 featherweight +218022 feed +088303 feminine +058004 Fenton +038017 fetched +018054 fetters +208101 fiftieth +238007 filial +013606 fingerings +218008 finishers +038205 firearm +188505 fitting +202301 Fitzpatrick +238008 fixedly +012001 flanking +018103 flint +018104 flopping +188007 flurried +013602 foldout +226205 foothill +232102 forgivably +228306 forthcoming +186002 freakish +208113 freest +231315 freezes +036002 funereal +226209 furnishings +198006 furthermore +select fld3 from t2 where fld3 like "L%" and fld3 = "ok"; +fld3 +select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly"); +fld3 +Chantilly +select fld1,fld3 from t2 where fld1 like "25050%"; +fld1 fld3 +250501 poisoning +250502 Iraqis +250503 heaving +250504 population +250505 bomb +select fld1,fld3 from t2 where fld1 like "25050_"; +fld1 fld3 +250501 poisoning +250502 Iraqis +250503 heaving +250504 population +250505 bomb +select distinct companynr from t2; +companynr +00 +37 +36 +50 +58 +29 +40 +53 +65 +41 +34 +68 +select distinct companynr from t2 order by companynr; +companynr +00 +29 +34 +36 +37 +40 +41 +50 +53 +58 +65 +68 +select distinct companynr from t2 order by companynr desc; +companynr +68 +65 +58 +53 +50 +41 +40 +37 +36 +34 +29 +00 +select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%"; +fld3 period +obliterates 9410 +offload 9410 +opaquely 9410 +organizer 9410 +overestimating 9410 +overlay 9410 +select distinct fld3 from t2 where companynr = 34 order by fld3; +fld3 +absentee +accessed +ahead +alphabetic +Asiaticizations +attitude +aye +bankruptcies +belays +Blythe +bomb +boulevard +bulldozes +cannot +caressing +charcoal +checksumming +chess +clubroom +colorful +cosy +creator +crying +Darius +diffusing +duality +Eiffel +Epiphany +Ernestine +explorers +exterminated +famine +forked +Gershwins +heaving +Hodges +Iraqis +Italianization +Lagos +landslide +libretto +Majorca +mastering +narrowed +occurred +offerers +Palestine +Peruvianizes +pharmaceutic +poisoning +population +Pygmalion +rats +realest +recording +regimented +retransmitting +reviver +rouses +scars +sicker +sleepwalk +stopped +sugars +translatable +uncles +unexpected +uprisings +versatility +vest +select distinct fld3 from t2 limit 10; +fld3 +abates +abiding +Abraham +abrogating +absentee +abut +accessed +accruing +accumulating +accuracies +select distinct fld3 from t2 having fld3 like "A%" limit 10; +fld3 +abates +abiding +Abraham +abrogating +absentee +abut +accessed +accruing +accumulating +accuracies +select distinct substring(fld3,1,3) from t2 where fld3 like "A%"; +substring(fld3,1,3) +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +Adl +adm +Ado +ads +adv +aer +aff +afi +afl +afo +agi +ahe +aim +air +Ald +alg +ali +all +alp +alr +ama +ame +amm +ana +and +ane +Ang +ani +Ann +Ant +api +app +aqu +Ara +arc +Arm +arr +Art +Asi +ask +asp +ass +ast +att +aud +Aug +aut +ave +avo +awe +aye +Azt +select distinct substring(fld3,1,3) as a from t2 having a like "A%" order by a limit 10; +a +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +select distinct substring(fld3,1,3) from t2 where fld3 like "A%" limit 10; +substring(fld3,1,3) +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +select distinct substring(fld3,1,3) as a from t2 having a like "A%" limit 10; +a +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +create table t3 ( +period int not null, +name char(32) not null, +companynr int not null, +price double(11,0), +price2 double(11,0), +key (period), +key (name) +); +create temporary table tmp engine = myisam select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +alter table t3 add t2nr int not null auto_increment primary key first; +drop table tmp; +SET SQL_BIG_TABLES=1; +select distinct concat(fld3," ",fld3) as namn from t2,t3 where t2.fld1=t3.t2nr order by namn limit 10; +namn +Abraham Abraham +abrogating abrogating +admonishing admonishing +Adolph Adolph +afield afield +aging aging +ammonium ammonium +analyzable analyzable +animals animals +animized animized +SET SQL_BIG_TABLES=0; +select distinct concat(fld3," ",fld3) from t2,t3 where t2.fld1=t3.t2nr order by fld3 limit 10; +concat(fld3," ",fld3) +Abraham Abraham +abrogating abrogating +admonishing admonishing +Adolph Adolph +afield afield +aging aging +ammonium ammonium +analyzable analyzable +animals animals +animized animized +select distinct fld5 from t2 limit 10; +fld5 +neat +Steinberg +jarring +tinily +balled +persist +attainments +fanatic +measures +rightfulness +select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10; +fld3 count(*) +affixed 1 +and 1 +annoyers 1 +Anthony 1 +assayed 1 +assurers 1 +attendants 1 +bedlam 1 +bedpost 1 +boasted 1 +SET SQL_BIG_TABLES=1; +select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10; +fld3 count(*) +affixed 1 +and 1 +annoyers 1 +Anthony 1 +assayed 1 +assurers 1 +attendants 1 +bedlam 1 +bedpost 1 +boasted 1 +SET SQL_BIG_TABLES=0; +select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10; +fld3 repeat("a",length(fld3)) count(*) +circus aaaaaa 1 +cited aaaaa 1 +Colombo aaaaaaa 1 +congresswoman aaaaaaaaaaaaa 1 +contrition aaaaaaaaaa 1 +corny aaaaa 1 +cultivation aaaaaaaaaaa 1 +definiteness aaaaaaaaaaaa 1 +demultiplex aaaaaaaaaaa 1 +disappointing aaaaaaaaaaaaa 1 +select distinct companynr,rtrim(space(512+companynr)) from t3 order by 1,2; +companynr rtrim(space(512+companynr)) +37 +78 +101 +154 +311 +447 +512 +select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by fld3; +fld3 +explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort +1 SIMPLE t3 ref period period 4 test.t1.period 4181 +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 index period period 4 NULL 1 +1 SIMPLE t1 ref period period 4 test.t3.period 4181 +explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index period period 4 NULL 1 +1 SIMPLE t3 ref period period 4 test.t1.period 4181 +select period from t1; +period +9410 +select period from t1 where period=1900; +period +select fld3,period from t1,t2 where fld1 = 011401 order by period; +fld3 period +breaking 9410 +select fld3,period from t2,t3 where t2.fld1 = 011401 and t2.fld1=t3.t2nr and t3.period=1001; +fld3 period +breaking 1001 +explain select fld3,period from t2,t3 where t2.fld1 = 011401 and t3.t2nr=t2.fld1 and 1001 = t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 const fld1 fld1 4 const 1 +1 SIMPLE t3 const PRIMARY,period PRIMARY 4 const 1 +select fld3,period from t2,t1 where companynr*10 = 37*10; +fld3 period +breaking 9410 +Romans 9410 +intercepted 9410 +bewilderingly 9410 +astound 9410 +admonishing 9410 +sumac 9410 +flanking 9410 +combed 9410 +subjective 9410 +scatterbrain 9410 +Eulerian 9410 +Kane 9410 +overlay 9410 +perturb 9410 +goblins 9410 +annihilates 9410 +Wotan 9410 +snatching 9410 +concludes 9410 +laterally 9410 +yelped 9410 +grazing 9410 +Baird 9410 +celery 9410 +misunderstander 9410 +handgun 9410 +foldout 9410 +mystic 9410 +succumbed 9410 +Nabisco 9410 +fingerings 9410 +aging 9410 +afield 9410 +ammonium 9410 +boat 9410 +intelligibility 9410 +Augustine 9410 +teethe 9410 +dreaded 9410 +scholastics 9410 +audiology 9410 +wallet 9410 +parters 9410 +eschew 9410 +quitter 9410 +neat 9410 +Steinberg 9410 +jarring 9410 +tinily 9410 +balled 9410 +persist 9410 +attainments 9410 +fanatic 9410 +measures 9410 +rightfulness 9410 +capably 9410 +impulsive 9410 +starlet 9410 +terminators 9410 +untying 9410 +announces 9410 +featherweight 9410 +pessimist 9410 +daughter 9410 +decliner 9410 +lawgiver 9410 +stated 9410 +readable 9410 +attrition 9410 +cascade 9410 +motors 9410 +interrogate 9410 +pests 9410 +stairway 9410 +dopers 9410 +testicle 9410 +Parsifal 9410 +leavings 9410 +postulation 9410 +squeaking 9410 +contrasted 9410 +leftover 9410 +whiteners 9410 +erases 9410 +Punjab 9410 +Merritt 9410 +Quixotism 9410 +sweetish 9410 +dogging 9410 +scornfully 9410 +bellow 9410 +bills 9410 +cupboard 9410 +sureties 9410 +puddings 9410 +fetters 9410 +bivalves 9410 +incurring 9410 +Adolph 9410 +pithed 9410 +Miles 9410 +trimmings 9410 +tragedies 9410 +skulking 9410 +flint 9410 +flopping 9410 +relaxing 9410 +offload 9410 +suites 9410 +lists 9410 +animized 9410 +multilayer 9410 +standardizes 9410 +Judas 9410 +vacuuming 9410 +dentally 9410 +humanness 9410 +inch 9410 +Weissmuller 9410 +irresponsibly 9410 +luckily 9410 +culled 9410 +medical 9410 +bloodbath 9410 +subschema 9410 +animals 9410 +Micronesia 9410 +repetitions 9410 +Antares 9410 +ventilate 9410 +pityingly 9410 +interdependent 9410 +Graves 9410 +neonatal 9410 +chafe 9410 +honoring 9410 +realtor 9410 +elite 9410 +funereal 9410 +abrogating 9410 +sorters 9410 +Conley 9410 +lectured 9410 +Abraham 9410 +Hawaii 9410 +cage 9410 +hushes 9410 +Simla 9410 +reporters 9410 +Dutchman 9410 +descendants 9410 +groupings 9410 +dissociate 9410 +coexist 9410 +Beebe 9410 +Taoism 9410 +Connally 9410 +fetched 9410 +checkpoints 9410 +rusting 9410 +galling 9410 +obliterates 9410 +traitor 9410 +resumes 9410 +analyzable 9410 +terminator 9410 +gritty 9410 +firearm 9410 +minima 9410 +Selfridge 9410 +disable 9410 +witchcraft 9410 +betroth 9410 +Manhattanize 9410 +imprint 9410 +peeked 9410 +swelling 9410 +interrelationships 9410 +riser 9410 +Gandhian 9410 +peacock 9410 +bee 9410 +kanji 9410 +dental 9410 +scarf 9410 +chasm 9410 +insolence 9410 +syndicate 9410 +alike 9410 +imperial 9410 +convulsion 9410 +railway 9410 +validate 9410 +normalizes 9410 +comprehensive 9410 +chewing 9410 +denizen 9410 +schemer 9410 +chronicle 9410 +Kline 9410 +Anatole 9410 +partridges 9410 +brunch 9410 +recruited 9410 +dimensions 9410 +Chicana 9410 +announced 9410 +praised 9410 +employing 9410 +linear 9410 +quagmire 9410 +western 9410 +relishing 9410 +serving 9410 +scheduling 9410 +lore 9410 +eventful 9410 +arteriole 9410 +disentangle 9410 +cured 9410 +Fenton 9410 +avoidable 9410 +drains 9410 +detectably 9410 +husky 9410 +impelling 9410 +undoes 9410 +evened 9410 +squeezes 9410 +destroyer 9410 +rudeness 9410 +beaner 9410 +boorish 9410 +Everhart 9410 +encompass 9410 +mushrooms 9410 +Alison 9410 +externally 9410 +pellagra 9410 +cult 9410 +creek 9410 +Huffman 9410 +Majorca 9410 +governing 9410 +gadfly 9410 +reassigned 9410 +intentness 9410 +craziness 9410 +psychic 9410 +squabbled 9410 +burlesque 9410 +capped 9410 +extracted 9410 +DiMaggio 9410 +exclamation 9410 +subdirectory 9410 +Gothicism 9410 +feminine 9410 +metaphysically 9410 +sanding 9410 +Miltonism 9410 +freakish 9410 +index 9410 +straight 9410 +flurried 9410 +denotative 9410 +coming 9410 +commencements 9410 +gentleman 9410 +gifted 9410 +Shanghais 9410 +sportswriting 9410 +sloping 9410 +navies 9410 +leaflet 9410 +shooter 9410 +Joplin 9410 +babies 9410 +assails 9410 +admiring 9410 +swaying 9410 +Goldstine 9410 +fitting 9410 +Norwalk 9410 +analogy 9410 +deludes 9410 +cokes 9410 +Clayton 9410 +exhausts 9410 +causality 9410 +sating 9410 +icon 9410 +throttles 9410 +communicants 9410 +dehydrate 9410 +priceless 9410 +publicly 9410 +incidentals 9410 +commonplace 9410 +mumbles 9410 +furthermore 9410 +cautioned 9410 +parametrized 9410 +registration 9410 +sadly 9410 +positioning 9410 +babysitting 9410 +eternal 9410 +hoarder 9410 +congregates 9410 +rains 9410 +workers 9410 +sags 9410 +unplug 9410 +garage 9410 +boulder 9410 +specifics 9410 +Teresa 9410 +Winsett 9410 +convenient 9410 +buckboards 9410 +amenities 9410 +resplendent 9410 +sews 9410 +participated 9410 +Simon 9410 +certificates 9410 +Fitzpatrick 9410 +Evanston 9410 +misted 9410 +textures 9410 +save 9410 +count 9410 +rightful 9410 +chaperone 9410 +Lizzy 9410 +clenched 9410 +effortlessly 9410 +accessed 9410 +beaters 9410 +Hornblower 9410 +vests 9410 +indulgences 9410 +infallibly 9410 +unwilling 9410 +excrete 9410 +spools 9410 +crunches 9410 +overestimating 9410 +ineffective 9410 +humiliation 9410 +sophomore 9410 +star 9410 +rifles 9410 +dialysis 9410 +arriving 9410 +indulge 9410 +clockers 9410 +languages 9410 +Antarctica 9410 +percentage 9410 +ceiling 9410 +specification 9410 +regimented 9410 +ciphers 9410 +pictures 9410 +serpents 9410 +allot 9410 +realized 9410 +mayoral 9410 +opaquely 9410 +hostess 9410 +fiftieth 9410 +incorrectly 9410 +decomposition 9410 +stranglings 9410 +mixture 9410 +electroencephalography 9410 +similarities 9410 +charges 9410 +freest 9410 +Greenberg 9410 +tinting 9410 +expelled 9410 +warm 9410 +smoothed 9410 +deductions 9410 +Romano 9410 +bitterroot 9410 +corset 9410 +securing 9410 +environing 9410 +cute 9410 +Crays 9410 +heiress 9410 +inform 9410 +avenge 9410 +universals 9410 +Kinsey 9410 +ravines 9410 +bestseller 9410 +equilibrium 9410 +extents 9410 +relatively 9410 +pressure 9410 +critiques 9410 +befouled 9410 +rightfully 9410 +mechanizing 9410 +Latinizes 9410 +timesharing 9410 +Aden 9410 +embassies 9410 +males 9410 +shapelessly 9410 +mastering 9410 +Newtonian 9410 +finishers 9410 +abates 9410 +teem 9410 +kiting 9410 +stodgy 9410 +feed 9410 +guitars 9410 +airships 9410 +store 9410 +denounces 9410 +Pyle 9410 +Saxony 9410 +serializations 9410 +Peruvian 9410 +taxonomically 9410 +kingdom 9410 +stint 9410 +Sault 9410 +faithful 9410 +Ganymede 9410 +tidiness 9410 +gainful 9410 +contrary 9410 +Tipperary 9410 +tropics 9410 +theorizers 9410 +renew 9410 +already 9410 +terminal 9410 +Hegelian 9410 +hypothesizer 9410 +warningly 9410 +journalizing 9410 +nested 9410 +Lars 9410 +saplings 9410 +foothill 9410 +labeled 9410 +imperiously 9410 +reporters 9410 +furnishings 9410 +precipitable 9410 +discounts 9410 +excises 9410 +Stalin 9410 +despot 9410 +ripeness 9410 +Arabia 9410 +unruly 9410 +mournfulness 9410 +boom 9410 +slaughter 9410 +Sabine 9410 +handy 9410 +rural 9410 +organizer 9410 +shipyard 9410 +civics 9410 +inaccuracy 9410 +rules 9410 +juveniles 9410 +comprised 9410 +investigations 9410 +stabilizes 9410 +seminaries 9410 +Hunter 9410 +sporty 9410 +test 9410 +weasels 9410 +CERN 9410 +tempering 9410 +afore 9410 +Galatean 9410 +techniques 9410 +error 9410 +veranda 9410 +severely 9410 +Cassites 9410 +forthcoming 9410 +guides 9410 +vanish 9410 +lied 9410 +sawtooth 9410 +fated 9410 +gradually 9410 +widens 9410 +preclude 9410 +evenhandedly 9410 +percentage 9410 +disobedience 9410 +humility 9410 +gleaning 9410 +petted 9410 +bloater 9410 +minion 9410 +marginal 9410 +apiary 9410 +measures 9410 +precaution 9410 +repelled 9410 +primary 9410 +coverings 9410 +Artemia 9410 +navigate 9410 +spatial 9410 +Gurkha 9410 +meanwhile 9410 +Melinda 9410 +Butterfield 9410 +Aldrich 9410 +previewing 9410 +glut 9410 +unaffected 9410 +inmate 9410 +mineral 9410 +impending 9410 +meditation 9410 +ideas 9410 +miniaturizes 9410 +lewdly 9410 +title 9410 +youthfulness 9410 +creak 9410 +Chippewa 9410 +clamored 9410 +freezes 9410 +forgivably 9410 +reduce 9410 +McGovern 9410 +Nazis 9410 +epistle 9410 +socializes 9410 +conceptions 9410 +Kevin 9410 +uncovering 9410 +chews 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +raining 9410 +infest 9410 +compartment 9410 +minting 9410 +ducks 9410 +roped 9410 +waltz 9410 +Lillian 9410 +repressions 9410 +chillingly 9410 +noncritical 9410 +lithograph 9410 +spongers 9410 +parenthood 9410 +posed 9410 +instruments 9410 +filial 9410 +fixedly 9410 +relives 9410 +Pandora 9410 +watering 9410 +ungrateful 9410 +secures 9410 +poison 9410 +dusted 9410 +encompasses 9410 +presentation 9410 +Kantian 9410 +select fld3,period,price,price2 from t2,t3 where t2.fld1=t3.t2nr and period >= 1001 and period <= 1002 and t2.companynr = 37 order by fld3,period, price; +fld3 period price price2 +admonishing 1002 28357832 8723648 +analyzable 1002 28357832 8723648 +annihilates 1001 5987435 234724 +Antares 1002 28357832 8723648 +astound 1001 5987435 234724 +audiology 1001 5987435 234724 +Augustine 1002 28357832 8723648 +Baird 1002 28357832 8723648 +bewilderingly 1001 5987435 234724 +breaking 1001 5987435 234724 +Conley 1001 5987435 234724 +dentally 1002 28357832 8723648 +dissociate 1002 28357832 8723648 +elite 1001 5987435 234724 +eschew 1001 5987435 234724 +Eulerian 1001 5987435 234724 +flanking 1001 5987435 234724 +foldout 1002 28357832 8723648 +funereal 1002 28357832 8723648 +galling 1002 28357832 8723648 +Graves 1001 5987435 234724 +grazing 1001 5987435 234724 +groupings 1001 5987435 234724 +handgun 1001 5987435 234724 +humility 1002 28357832 8723648 +impulsive 1002 28357832 8723648 +inch 1001 5987435 234724 +intelligibility 1001 5987435 234724 +jarring 1001 5987435 234724 +lawgiver 1001 5987435 234724 +lectured 1002 28357832 8723648 +Merritt 1002 28357832 8723648 +neonatal 1001 5987435 234724 +offload 1002 28357832 8723648 +parters 1002 28357832 8723648 +pityingly 1002 28357832 8723648 +puddings 1002 28357832 8723648 +Punjab 1001 5987435 234724 +quitter 1002 28357832 8723648 +realtor 1001 5987435 234724 +relaxing 1001 5987435 234724 +repetitions 1001 5987435 234724 +resumes 1001 5987435 234724 +Romans 1002 28357832 8723648 +rusting 1001 5987435 234724 +scholastics 1001 5987435 234724 +skulking 1002 28357832 8723648 +stated 1002 28357832 8723648 +suites 1002 28357832 8723648 +sureties 1001 5987435 234724 +testicle 1002 28357832 8723648 +tinily 1002 28357832 8723648 +tragedies 1001 5987435 234724 +trimmings 1001 5987435 234724 +vacuuming 1001 5987435 234724 +ventilate 1001 5987435 234724 +wallet 1001 5987435 234724 +Weissmuller 1002 28357832 8723648 +Wotan 1002 28357832 8723648 +select t2.fld1,fld3,period,price,price2 from t2,t3 where t2.fld1>= 18201 and t2.fld1 <= 18811 and t2.fld1=t3.t2nr and period = 1001 and t2.companynr = 37; +fld1 fld3 period price price2 +018201 relaxing 1001 5987435 234724 +018601 vacuuming 1001 5987435 234724 +018801 inch 1001 5987435 234724 +018811 repetitions 1001 5987435 234724 +create table t4 ( +companynr tinyint(2) unsigned zerofill NOT NULL default '00', +companyname char(30) NOT NULL default '', +PRIMARY KEY (companynr), +UNIQUE KEY companyname(companyname) +) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; +select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; +companynr companyname +00 Unknown +29 company 1 +34 company 2 +36 company 3 +37 company 4 +40 company 5 +41 company 6 +50 company 11 +53 company 7 +58 company 8 +65 company 9 +68 company 10 +select SQL_SMALL_RESULT t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; +companynr companyname +00 Unknown +29 company 1 +34 company 2 +36 company 3 +37 company 4 +40 company 5 +41 company 6 +50 company 11 +53 company 7 +58 company 8 +65 company 9 +68 company 10 +select * from t1,t1 t12; +Period Varor_period Period Varor_period +9410 9412 9410 9412 +select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 250505 and t22.fld1 >= 250501 and t22.fld1 <= 250505; +fld1 fld1 +250501 250501 +250502 250501 +250503 250501 +250504 250501 +250505 250501 +250501 250502 +250502 250502 +250503 250502 +250504 250502 +250505 250502 +250501 250503 +250502 250503 +250503 250503 +250504 250503 +250505 250503 +250501 250504 +250502 250504 +250503 250504 +250504 250504 +250505 250504 +250501 250505 +250502 250505 +250503 250505 +250504 250505 +250505 250505 +insert into t2 (fld1, companynr) values (999999,99); +select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; +companynr companyname +99 NULL +select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null; +count(*) +1199 +explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists +select companynr,companyname from t2 left join t4 using (companynr) where companynr is null; +companynr companyname +select count(*) from t2 left join t4 using (companynr) where companynr is not null; +count(*) +1200 +explain select companynr,companyname from t2 left join t4 using (companynr) where companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +delete from t2 where fld1=999999; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; +companynr companynr +37 36 +41 40 +explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer +select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008; +fld1 companynr fld3 period +038008 37 reporters 1008 +038208 37 Selfridge 1008 +select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t2.fld1 = 38208 or t2.fld1 = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009; +fld1 companynr fld3 period +038008 37 reporters 1008 +038208 37 Selfridge 1008 +select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t3.t2nr = 38208 or t3.t2nr = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009; +fld1 companynr fld3 period +038008 37 reporters 1008 +038208 37 Selfridge 1008 +select period from t1 where (((period > 0) or period < 10000 or (period = 1900)) and (period=1900 and period <= 1901) or (period=1903 and (period=1903)) and period>=1902) or ((period=1904 or period=1905) or (period=1906 or period>1907)) or (period=1908 and period = 1909); +period +9410 +select period from t1 where ((period > 0 and period < 1) or (((period > 0 and period < 100) and (period > 10)) or (period > 10)) or (period > 0 and (period > 5 or period > 6))); +period +9410 +select a.fld1 from t2 as a,t2 b where ((a.fld1 = 250501 and a.fld1=b.fld1) or a.fld1=250502 or a.fld1=250503 or (a.fld1=250505 and a.fld1<=b.fld1 and b.fld1>=a.fld1)) and a.fld1=b.fld1; +fld1 +250501 +250502 +250503 +250505 +select fld1 from t2 where fld1 in (250502,98005,98006,250503,250605,250606) and fld1 >=250502 and fld1 not in (250605,250606); +fld1 +250502 +250503 +select fld1 from t2 where fld1 between 250502 and 250504; +fld1 +250502 +250503 +250504 +select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld3 like "L%" or fld3 like "G%")) and fld3 like "L%" ; +fld3 +label +labeled +labeled +landslide +laterally +leaflet +lewdly +Lillian +luckily +select count(*) from t1; +count(*) +1 +select companynr,count(*),sum(fld1) from t2 group by companynr; +companynr count(*) sum(fld1) +00 82 10355753 +29 95 14473298 +34 70 17788966 +36 215 22786296 +37 588 83602098 +40 37 6618386 +41 52 12816335 +50 11 1595438 +53 4 793210 +58 23 2254293 +65 10 2284055 +68 12 3097288 +select companynr,count(*) from t2 group by companynr order by companynr desc limit 5; +companynr count(*) +68 12 +65 10 +58 23 +53 4 +50 11 +select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>""; +count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1) +70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069 +explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>""; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where +Warnings: +Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> '')) +select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3; +companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1) +00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087 +29 95 abut wetness 14473298 152350.5053 8368.5480 70032594.9026 +34 70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069 +select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10; +companynr t2nr count(price) sum(price) min(price) max(price) avg(price) +37 1 1 5987435 5987435 5987435 5987435.0000 +37 2 1 28357832 28357832 28357832 28357832.0000 +37 3 1 39654943 39654943 39654943 39654943.0000 +37 11 1 5987435 5987435 5987435 5987435.0000 +37 12 1 28357832 28357832 28357832 28357832.0000 +37 13 1 39654943 39654943 39654943 39654943.0000 +37 21 1 5987435 5987435 5987435 5987435.0000 +37 22 1 28357832 28357832 28357832 28357832.0000 +37 23 1 39654943 39654943 39654943 39654943.0000 +37 31 1 5987435 5987435 5987435 5987435.0000 +select /*! SQL_SMALL_RESULT */ companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10; +companynr t2nr count(price) sum(price) min(price) max(price) avg(price) +37 1 1 5987435 5987435 5987435 5987435.0000 +37 2 1 28357832 28357832 28357832 28357832.0000 +37 3 1 39654943 39654943 39654943 39654943.0000 +37 11 1 5987435 5987435 5987435 5987435.0000 +37 12 1 28357832 28357832 28357832 28357832.0000 +37 13 1 39654943 39654943 39654943 39654943.0000 +37 21 1 5987435 5987435 5987435 5987435.0000 +37 22 1 28357832 28357832 28357832 28357832.0000 +37 23 1 39654943 39654943 39654943 39654943.0000 +37 31 1 5987435 5987435 5987435 5987435.0000 +select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ; +companynr count(price) sum(price) min(price) max(price) avg(price) +37 12543 309394878010 5987435 39654943 24666736.6667 +78 8362 414611089292 726498 98439034 49582766.0000 +101 4181 3489454238 834598 834598 834598.0000 +154 4181 4112197254950 983543950 983543950 983543950.0000 +311 4181 979599938 234298 234298 234298.0000 +447 4181 9929180954 2374834 2374834 2374834.0000 +512 4181 3288532102 786542 786542 786542.0000 +select distinct mod(companynr,10) from t4 group by companynr; +mod(companynr,10) +0 +9 +4 +6 +7 +1 +3 +8 +5 +select distinct 1 from t4 group by companynr; +1 +1 +select count(distinct fld1) from t2; +count(distinct fld1) +1199 +select companynr,count(distinct fld1) from t2 group by companynr; +companynr count(distinct fld1) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(*) from t2 group by companynr; +companynr count(*) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(distinct concat(fld1,repeat(65,1000))) from t2 group by companynr; +companynr count(distinct concat(fld1,repeat(65,1000))) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(distinct concat(fld1,repeat(65,200))) from t2 group by companynr; +companynr count(distinct concat(fld1,repeat(65,200))) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(distinct floor(fld1/100)) from t2 group by companynr; +companynr count(distinct floor(fld1/100)) +00 47 +29 35 +34 14 +36 69 +37 108 +40 16 +41 11 +50 9 +53 1 +58 1 +65 1 +68 1 +select companynr,count(distinct concat(repeat(65,1000),floor(fld1/100))) from t2 group by companynr; +companynr count(distinct concat(repeat(65,1000),floor(fld1/100))) +00 47 +29 35 +34 14 +36 69 +37 108 +40 16 +41 11 +50 9 +53 1 +58 1 +65 1 +68 1 +select sum(fld1),fld3 from t2 where fld3="Romans" group by fld1 limit 10; +sum(fld1) fld3 +11402 Romans +select name,count(*) from t3 where name='cloakroom' group by name; +name count(*) +cloakroom 4181 +select name,count(*) from t3 where name='cloakroom' and price>10 group by name; +name count(*) +cloakroom 4181 +select count(*) from t3 where name='cloakroom' and price2=823742; +count(*) +4181 +select name,count(*) from t3 where name='cloakroom' and price2=823742 group by name; +name count(*) +cloakroom 4181 +select name,count(*) from t3 where name >= "extramarital" and price <= 39654943 group by name; +name count(*) +extramarital 4181 +gazer 4181 +gems 4181 +Iranizes 4181 +spates 4181 +tucked 4181 +violinist 4181 +select t2.fld3,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name; +fld3 count(*) +spates 4181 +select companynr|0,companyname from t4 group by 1; +companynr|0 companyname +0 Unknown +29 company 1 +34 company 2 +36 company 3 +37 company 4 +40 company 5 +41 company 6 +50 company 11 +53 company 7 +58 company 8 +65 company 9 +68 company 10 +select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by t2.companynr order by companyname; +companynr companyname count(*) +29 company 1 95 +68 company 10 12 +50 company 11 11 +34 company 2 70 +36 company 3 215 +37 company 4 588 +40 company 5 37 +41 company 6 52 +53 company 7 4 +58 company 8 23 +65 company 9 10 +00 Unknown 82 +select t2.fld1,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name; +fld1 count(*) +158402 4181 +select sum(Period)/count(*) from t1; +sum(Period)/count(*) +9410.0000 +select companynr,count(price) as "count",sum(price) as "sum" ,abs(sum(price)/count(price)-avg(price)) as "diff",(0+count(price))*companynr as func from t3 group by companynr; +companynr count sum diff func +37 12543 309394878010 0.0000 464091 +78 8362 414611089292 0.0000 652236 +101 4181 3489454238 0.0000 422281 +154 4181 4112197254950 0.0000 643874 +311 4181 979599938 0.0000 1300291 +447 4181 9929180954 0.0000 1868907 +512 4181 3288532102 0.0000 2140672 +select companynr,sum(price)/count(price) as avg from t3 group by companynr having avg > 70000000 order by avg; +companynr avg +154 983543950.0000 +select companynr,count(*) from t2 group by companynr order by 2 desc; +companynr count(*) +37 588 +36 215 +29 95 +00 82 +34 70 +41 52 +40 37 +58 23 +68 12 +50 11 +65 10 +53 4 +select companynr,count(*) from t2 where companynr > 40 group by companynr order by 2 desc; +companynr count(*) +41 52 +58 23 +68 12 +50 11 +65 10 +53 4 +select t2.fld4,t2.fld1,count(price),sum(price),min(price),max(price),avg(price) from t3,t2 where t3.companynr = 37 and t2.fld1 = t3.t2nr group by fld1,t2.fld4; +fld4 fld1 count(price) sum(price) min(price) max(price) avg(price) +teethe 000001 1 5987435 5987435 5987435 5987435.0000 +dreaded 011401 1 5987435 5987435 5987435 5987435.0000 +scholastics 011402 1 28357832 28357832 28357832 28357832.0000 +audiology 011403 1 39654943 39654943 39654943 39654943.0000 +wallet 011501 1 5987435 5987435 5987435 5987435.0000 +parters 011701 1 5987435 5987435 5987435 5987435.0000 +eschew 011702 1 28357832 28357832 28357832 28357832.0000 +quitter 011703 1 39654943 39654943 39654943 39654943.0000 +neat 012001 1 5987435 5987435 5987435 5987435.0000 +Steinberg 012003 1 39654943 39654943 39654943 39654943.0000 +balled 012301 1 5987435 5987435 5987435 5987435.0000 +persist 012302 1 28357832 28357832 28357832 28357832.0000 +attainments 012303 1 39654943 39654943 39654943 39654943.0000 +capably 012501 1 5987435 5987435 5987435 5987435.0000 +impulsive 012602 1 28357832 28357832 28357832 28357832.0000 +starlet 012603 1 39654943 39654943 39654943 39654943.0000 +featherweight 012701 1 5987435 5987435 5987435 5987435.0000 +pessimist 012702 1 28357832 28357832 28357832 28357832.0000 +daughter 012703 1 39654943 39654943 39654943 39654943.0000 +lawgiver 013601 1 5987435 5987435 5987435 5987435.0000 +stated 013602 1 28357832 28357832 28357832 28357832.0000 +readable 013603 1 39654943 39654943 39654943 39654943.0000 +testicle 013801 1 5987435 5987435 5987435 5987435.0000 +Parsifal 013802 1 28357832 28357832 28357832 28357832.0000 +leavings 013803 1 39654943 39654943 39654943 39654943.0000 +squeaking 013901 1 5987435 5987435 5987435 5987435.0000 +contrasted 016001 1 5987435 5987435 5987435 5987435.0000 +leftover 016201 1 5987435 5987435 5987435 5987435.0000 +whiteners 016202 1 28357832 28357832 28357832 28357832.0000 +erases 016301 1 5987435 5987435 5987435 5987435.0000 +Punjab 016302 1 28357832 28357832 28357832 28357832.0000 +Merritt 016303 1 39654943 39654943 39654943 39654943.0000 +sweetish 018001 1 5987435 5987435 5987435 5987435.0000 +dogging 018002 1 28357832 28357832 28357832 28357832.0000 +scornfully 018003 1 39654943 39654943 39654943 39654943.0000 +fetters 018012 1 28357832 28357832 28357832 28357832.0000 +bivalves 018013 1 39654943 39654943 39654943 39654943.0000 +skulking 018021 1 5987435 5987435 5987435 5987435.0000 +flint 018022 1 28357832 28357832 28357832 28357832.0000 +flopping 018023 1 39654943 39654943 39654943 39654943.0000 +Judas 018032 1 28357832 28357832 28357832 28357832.0000 +vacuuming 018033 1 39654943 39654943 39654943 39654943.0000 +medical 018041 1 5987435 5987435 5987435 5987435.0000 +bloodbath 018042 1 28357832 28357832 28357832 28357832.0000 +subschema 018043 1 39654943 39654943 39654943 39654943.0000 +interdependent 018051 1 5987435 5987435 5987435 5987435.0000 +Graves 018052 1 28357832 28357832 28357832 28357832.0000 +neonatal 018053 1 39654943 39654943 39654943 39654943.0000 +sorters 018061 1 5987435 5987435 5987435 5987435.0000 +epistle 018062 1 28357832 28357832 28357832 28357832.0000 +Conley 018101 1 5987435 5987435 5987435 5987435.0000 +lectured 018102 1 28357832 28357832 28357832 28357832.0000 +Abraham 018103 1 39654943 39654943 39654943 39654943.0000 +cage 018201 1 5987435 5987435 5987435 5987435.0000 +hushes 018202 1 28357832 28357832 28357832 28357832.0000 +Simla 018402 1 28357832 28357832 28357832 28357832.0000 +reporters 018403 1 39654943 39654943 39654943 39654943.0000 +coexist 018601 1 5987435 5987435 5987435 5987435.0000 +Beebe 018602 1 28357832 28357832 28357832 28357832.0000 +Taoism 018603 1 39654943 39654943 39654943 39654943.0000 +Connally 018801 1 5987435 5987435 5987435 5987435.0000 +fetched 018802 1 28357832 28357832 28357832 28357832.0000 +checkpoints 018803 1 39654943 39654943 39654943 39654943.0000 +gritty 018811 1 5987435 5987435 5987435 5987435.0000 +firearm 018812 1 28357832 28357832 28357832 28357832.0000 +minima 019101 1 5987435 5987435 5987435 5987435.0000 +Selfridge 019102 1 28357832 28357832 28357832 28357832.0000 +disable 019103 1 39654943 39654943 39654943 39654943.0000 +witchcraft 019201 1 5987435 5987435 5987435 5987435.0000 +betroth 030501 1 5987435 5987435 5987435 5987435.0000 +Manhattanize 030502 1 28357832 28357832 28357832 28357832.0000 +imprint 030503 1 39654943 39654943 39654943 39654943.0000 +swelling 031901 1 5987435 5987435 5987435 5987435.0000 +interrelationships 036001 1 5987435 5987435 5987435 5987435.0000 +riser 036002 1 28357832 28357832 28357832 28357832.0000 +bee 038001 1 5987435 5987435 5987435 5987435.0000 +kanji 038002 1 28357832 28357832 28357832 28357832.0000 +dental 038003 1 39654943 39654943 39654943 39654943.0000 +railway 038011 1 5987435 5987435 5987435 5987435.0000 +validate 038012 1 28357832 28357832 28357832 28357832.0000 +normalizes 038013 1 39654943 39654943 39654943 39654943.0000 +Kline 038101 1 5987435 5987435 5987435 5987435.0000 +Anatole 038102 1 28357832 28357832 28357832 28357832.0000 +partridges 038103 1 39654943 39654943 39654943 39654943.0000 +recruited 038201 1 5987435 5987435 5987435 5987435.0000 +dimensions 038202 1 28357832 28357832 28357832 28357832.0000 +Chicana 038203 1 39654943 39654943 39654943 39654943.0000 +select t3.companynr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 group by companynr,fld3; +companynr fld3 sum(price) +512 boat 786542 +512 capably 786542 +512 cupboard 786542 +512 decliner 786542 +512 descendants 786542 +512 dopers 786542 +512 erases 786542 +512 Micronesia 786542 +512 Miles 786542 +512 skies 786542 +select t2.companynr,count(*),min(fld3),max(fld3),sum(price),avg(price) from t2,t3 where t3.companynr >= 30 and t3.companynr <= 58 and t3.t2nr = t2.fld1 and 1+1=2 group by t2.companynr; +companynr count(*) min(fld3) max(fld3) sum(price) avg(price) +00 1 Omaha Omaha 5987435 5987435.0000 +36 1 dubbed dubbed 28357832 28357832.0000 +37 83 Abraham Wotan 1908978016 22999735.1325 +50 2 scribbled tapestry 68012775 34006387.5000 +select t3.companynr+0,t3.t2nr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 37 group by 1,t3.t2nr,fld3,fld3,fld3,fld3,fld3 order by fld1; +t3.companynr+0 t2nr fld3 sum(price) +37 1 Omaha 5987435 +37 11401 breaking 5987435 +37 11402 Romans 28357832 +37 11403 intercepted 39654943 +37 11501 bewilderingly 5987435 +37 11701 astound 5987435 +37 11702 admonishing 28357832 +37 11703 sumac 39654943 +37 12001 flanking 5987435 +37 12003 combed 39654943 +37 12301 Eulerian 5987435 +37 12302 dubbed 28357832 +37 12303 Kane 39654943 +37 12501 annihilates 5987435 +37 12602 Wotan 28357832 +37 12603 snatching 39654943 +37 12701 grazing 5987435 +37 12702 Baird 28357832 +37 12703 celery 39654943 +37 13601 handgun 5987435 +37 13602 foldout 28357832 +37 13603 mystic 39654943 +37 13801 intelligibility 5987435 +37 13802 Augustine 28357832 +37 13803 teethe 39654943 +37 13901 scholastics 5987435 +37 16001 audiology 5987435 +37 16201 wallet 5987435 +37 16202 parters 28357832 +37 16301 eschew 5987435 +37 16302 quitter 28357832 +37 16303 neat 39654943 +37 18001 jarring 5987435 +37 18002 tinily 28357832 +37 18003 balled 39654943 +37 18012 impulsive 28357832 +37 18013 starlet 39654943 +37 18021 lawgiver 5987435 +37 18022 stated 28357832 +37 18023 readable 39654943 +37 18032 testicle 28357832 +37 18033 Parsifal 39654943 +37 18041 Punjab 5987435 +37 18042 Merritt 28357832 +37 18043 Quixotism 39654943 +37 18051 sureties 5987435 +37 18052 puddings 28357832 +37 18053 tapestry 39654943 +37 18061 trimmings 5987435 +37 18062 humility 28357832 +37 18101 tragedies 5987435 +37 18102 skulking 28357832 +37 18103 flint 39654943 +37 18201 relaxing 5987435 +37 18202 offload 28357832 +37 18402 suites 28357832 +37 18403 lists 39654943 +37 18601 vacuuming 5987435 +37 18602 dentally 28357832 +37 18603 humanness 39654943 +37 18801 inch 5987435 +37 18802 Weissmuller 28357832 +37 18803 irresponsibly 39654943 +37 18811 repetitions 5987435 +37 18812 Antares 28357832 +37 19101 ventilate 5987435 +37 19102 pityingly 28357832 +37 19103 interdependent 39654943 +37 19201 Graves 5987435 +37 30501 neonatal 5987435 +37 30502 scribbled 28357832 +37 30503 chafe 39654943 +37 31901 realtor 5987435 +37 36001 elite 5987435 +37 36002 funereal 28357832 +37 38001 Conley 5987435 +37 38002 lectured 28357832 +37 38003 Abraham 39654943 +37 38011 groupings 5987435 +37 38012 dissociate 28357832 +37 38013 coexist 39654943 +37 38101 rusting 5987435 +37 38102 galling 28357832 +37 38103 obliterates 39654943 +37 38201 resumes 5987435 +37 38202 analyzable 28357832 +37 38203 terminator 39654943 +select sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1= t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008; +sum(price) +234298 +select t2.fld1,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1 = t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008 or t3.t2nr = t2.fld1 and t2.fld1 = 38008 group by t2.fld1; +fld1 sum(price) +038008 234298 +explain select fld3 from t2 where 1>2 or 2>3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +explain select fld3 from t2 where fld1=fld1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502; +companynr fld1 +34 250501 +34 250502 +select companynr,fld1 from t2 WHERE fld1>=250501 HAVING fld1<=250502; +companynr fld1 +34 250501 +34 250502 +select companynr,count(*) as count,sum(fld1) as sum from t2 group by companynr having count > 40 and sum/count >= 120000; +companynr count sum +00 82 10355753 +29 95 14473298 +34 70 17788966 +37 588 83602098 +41 52 12816335 +select companynr from t2 group by companynr having count(*) > 40 and sum(fld1)/count(*) >= 120000 ; +companynr +00 +29 +34 +37 +41 +select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by companyname having t2.companynr >= 40; +companynr companyname count(*) +68 company 10 12 +50 company 11 11 +40 company 5 37 +41 company 6 52 +53 company 7 4 +58 company 8 23 +65 company 9 10 +select count(*) from t2; +count(*) +1199 +select count(*) from t2 where fld1 < 098024; +count(*) +387 +select min(fld1) from t2 where fld1>= 098024; +min(fld1) +98024 +select max(fld1) from t2 where fld1>= 098024; +max(fld1) +1232609 +select count(*) from t3 where price2=76234234; +count(*) +4181 +select count(*) from t3 where companynr=512 and price2=76234234; +count(*) +4181 +explain select min(fld1),max(fld1),count(*) from t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +select min(fld1),max(fld1),count(*) from t2; +min(fld1) max(fld1) count(*) +0 1232609 1199 +select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742; +min(t2nr) max(t2nr) +2115 2115 +select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78; +count(*) min(t2nr) max(t2nr) +4181 4 41804 +select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20; +t2nr count(*) +9 1 +19 1 +29 1 +39 1 +49 1 +59 1 +69 1 +79 1 +89 1 +99 1 +109 1 +119 1 +129 1 +139 1 +149 1 +159 1 +169 1 +179 1 +189 1 +199 1 +select max(t2nr) from t3 where price=983543950; +max(t2nr) +41807 +select t1.period from t3 = t1 limit 1; +period +1001 +select t1.period from t1 as t1 limit 1; +period +9410 +select t1.period as "Nuvarande period" from t1 as t1 limit 1; +Nuvarande period +9410 +select period as ok_period from t1 limit 1; +ok_period +9410 +select period as ok_period from t1 group by ok_period limit 1; +ok_period +9410 +select 1+1 as summa from t1 group by summa limit 1; +summa +2 +select period as "Nuvarande period" from t1 group by "Nuvarande period" limit 1; +Nuvarande period +9410 +show tables; +Tables_in_test +t1 +t2 +t3 +t4 +show tables from test like "s%"; +Tables_in_test (s%) +show tables from test like "t?"; +Tables_in_test (t?) +show full columns from t2; +Field Type Collation Null Key Default Extra Privileges Comment +auto int(11) NULL NO PRI NULL auto_increment # +fld1 int(6) unsigned zerofill NULL NO UNI 000000 # +companynr tinyint(2) unsigned zerofill NULL NO 00 # +fld3 char(30) latin1_swedish_ci NO MUL # +fld4 char(35) latin1_swedish_ci NO # +fld5 char(35) latin1_swedish_ci NO # +fld6 char(4) latin1_swedish_ci NO # +show full columns from t2 from test like 'f%'; +Field Type Collation Null Key Default Extra Privileges Comment +fld1 int(6) unsigned zerofill NULL NO UNI 000000 # +fld3 char(30) latin1_swedish_ci NO MUL # +fld4 char(35) latin1_swedish_ci NO # +fld5 char(35) latin1_swedish_ci NO # +fld6 char(4) latin1_swedish_ci NO # +show full columns from t2 from test like 's%'; +Field Type Collation Null Key Default Extra Privileges Comment +show keys from t2; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE +t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE +t2 1 fld3 1 fld3 A NULL NULL NULL BTREE +drop table t4, t3, t2, t1; +DO 1; +DO benchmark(100,1+1),1,1; +do default; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +do foobar; +ERROR 42S22: Unknown column 'foobar' in 'field list' +CREATE TABLE t1 ( +id mediumint(8) unsigned NOT NULL auto_increment, +pseudo varchar(35) NOT NULL default '', +PRIMARY KEY (id), +UNIQUE KEY pseudo (pseudo) +); +INSERT INTO t1 (pseudo) VALUES ('test'); +INSERT INTO t1 (pseudo) VALUES ('test1'); +SELECT 1 as rnd1 from t1 where rand() > 2; +rnd1 +DROP TABLE t1; +CREATE TABLE t1 (gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL); +CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35); +SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'wrong-date-value' AND b.sampletime < 'wrong-date-value' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid; +gvid the_success the_fail the_size the_time +Warnings: +Warning 1292 Incorrect datetime value: 'wrong-date-value' for column 'sampletime' at row 1 +Warning 1292 Incorrect datetime value: 'wrong-date-value' for column 'sampletime' at row 1 +SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= NULL AND b.sampletime < NULL AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid; +gvid the_success the_fail the_size the_time +DROP TABLE t1,t2; +create table t1 ( A_Id bigint(20) NOT NULL default '0', A_UpdateBy char(10) NOT NULL default '', A_UpdateDate bigint(20) NOT NULL default '0', A_UpdateSerial int(11) NOT NULL default '0', other_types bigint(20) NOT NULL default '0', wss_type bigint(20) NOT NULL default '0'); +INSERT INTO t1 VALUES (102935998719055004,'brade',1029359987,2,102935229116544068,102935229216544093); +select wss_type from t1 where wss_type ='102935229216544106'; +wss_type +select wss_type from t1 where wss_type ='102935229216544105'; +wss_type +select wss_type from t1 where wss_type ='102935229216544104'; +wss_type +select wss_type from t1 where wss_type ='102935229216544093'; +wss_type +102935229216544093 +select wss_type from t1 where wss_type =102935229216544093; +wss_type +102935229216544093 +drop table t1; +select 1+2,"aaaa",3.13*2.0 into @a,@b,@c; +select @a; +@a +3 +select @b; +@b +aaaa +select @c; +@c +6.260 +create table t1 (a int not null auto_increment primary key); +insert into t1 values (); +insert into t1 values (); +insert into t1 values (); +select * from (t1 as t2 left join t1 as t3 using (a)), t1; +a a +1 1 +2 1 +3 1 +1 2 +2 2 +3 2 +1 3 +2 3 +3 3 +select * from t1, (t1 as t2 left join t1 as t3 using (a)); +a a +1 1 +2 1 +3 1 +1 2 +2 2 +3 2 +1 3 +2 3 +3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) straight_join t1; +a a +1 1 +2 1 +3 1 +1 2 +2 2 +3 2 +1 3 +2 3 +3 3 +select * from t1 straight_join (t1 as t2 left join t1 as t3 using (a)); +a a +1 1 +2 1 +3 1 +1 2 +2 2 +3 2 +1 3 +2 3 +3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1; +a a +1 2 +2 2 +3 2 +1 3 +2 3 +3 3 +select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a +2 1 +3 1 +2 2 +3 2 +2 3 +3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 using ( a ); +a +1 +2 +3 +select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +a +1 +2 +3 +select * from (t1 as t2 left join t1 as t3 using (a)) left outer join t1 on t1.a>1; +a a +1 2 +1 3 +2 2 +2 3 +3 2 +3 3 +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a +1 NULL +2 1 +2 2 +2 3 +3 1 +3 2 +3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) left join t1 using ( a ); +a +1 +2 +3 +select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +a +1 +2 +3 +select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; +a +1 +2 +3 +select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a)); +a +1 +2 +3 +select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1; +a a +NULL 1 +1 2 +2 2 +3 2 +1 3 +2 3 +3 3 +select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a +2 1 +3 1 +2 2 +3 2 +2 3 +3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a ); +a +1 +2 +3 +select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +a +1 +2 +3 +select * from (t1 as t2 left join t1 as t3 using (a)) natural right join t1; +a +1 +2 +3 +select * from t1 natural right join (t1 as t2 left join t1 as t3 using (a)); +a +1 +2 +3 +select * from t1 natural join (t1 as t2 left join t1 as t3 using (a)); +a +1 +2 +3 +select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1; +a +1 +2 +3 +drop table t1; +CREATE TABLE t1 ( aa char(2), id int(11) NOT NULL auto_increment, t2_id int(11) NOT NULL default '0', PRIMARY KEY (id), KEY replace_id (t2_id)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ("1",8264,2506),("2",8299,2517),("3",8301,2518),("4",8302,2519),("5",8303,2520),("6",8304,2521),("7",8305,2522); +CREATE TABLE t2 ( id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (2517), (2518), (2519), (2520), (2521), (2522); +select * from t1, t2 WHERE t1.t2_id = t2.id and t1.t2_id > 0 order by t1.id LIMIT 0, 5; +aa id t2_id id +2 8299 2517 2517 +3 8301 2518 2518 +4 8302 2519 2519 +5 8303 2520 2520 +6 8304 2521 2521 +drop table t1,t2; +create table t1 (id1 int NOT NULL); +create table t2 (id2 int NOT NULL); +create table t3 (id3 int NOT NULL); +create table t4 (id4 int NOT NULL, id44 int NOT NULL, KEY (id4)); +insert into t1 values (1); +insert into t1 values (2); +insert into t2 values (1); +insert into t4 values (1,1); +explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 +left join t4 on id3 = id4 where id2 = 1 or id4 = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found +1 SIMPLE t4 const id4 NULL NULL NULL 1 +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where +select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 +left join t4 on id3 = id4 where id2 = 1 or id4 = 1; +id1 id2 id3 id4 id44 +1 1 NULL NULL NULL +drop table t1,t2,t3,t4; +create table t1(s varchar(10) not null); +create table t2(s varchar(10) not null primary key); +create table t3(s varchar(10) not null primary key); +insert into t1 values ('one\t'), ('two\t'); +insert into t2 values ('one\r'), ('two\t'); +insert into t3 values ('one '), ('two\t'); +select * from t1 where s = 'one'; +s +select * from t2 where s = 'one'; +s +select * from t3 where s = 'one'; +s +one +select * from t1,t2 where t1.s = t2.s; +s s +two two +select * from t2,t3 where t2.s = t3.s; +s s +two two +drop table t1, t2, t3; +create table t1 (a integer, b integer, index(a), index(b)); +create table t2 (c integer, d integer, index(c), index(d)); +insert into t1 values (1,2), (2,2), (3,2), (4,2); +insert into t2 values (1,3), (2,3), (3,4), (4,4); +explain select * from t1 left join t2 on a=c where d in (4); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer +select * from t1 left join t2 on a=c where d in (4); +a b c d +3 2 3 4 +4 2 4 4 +explain select * from t1 left join t2 on a=c where d = 4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer +select * from t1 left join t2 on a=c where d = 4; +a b c d +3 2 3 4 +4 2 4 4 +drop table t1, t2; +CREATE TABLE t1 ( +i int(11) NOT NULL default '0', +c char(10) NOT NULL default '', +PRIMARY KEY (i), +UNIQUE KEY c (c) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,'a'); +INSERT INTO t1 VALUES (2,'b'); +INSERT INTO t1 VALUES (3,'c'); +EXPLAIN SELECT i FROM t1 WHERE i=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index +DROP TABLE t1; +CREATE TABLE t1 ( a BLOB, INDEX (a(20)) ); +CREATE TABLE t2 ( a BLOB, INDEX (a(20)) ); +INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five'); +INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five'); +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ref a a 23 test.t1.a 2 +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ref a a 23 test.t1.a 2 +DROP TABLE t1, t2; +CREATE TABLE t1 ( city char(30) ); +INSERT INTO t1 VALUES ('London'); +INSERT INTO t1 VALUES ('Paris'); +SELECT * FROM t1 WHERE city='London'; +city +London +SELECT * FROM t1 WHERE city='london'; +city +London +EXPLAIN SELECT * FROM t1 WHERE city='London' AND city='london'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 WHERE city='London' AND city='london'; +city +London +EXPLAIN SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London'; +city +London +DROP TABLE t1; +create table t1 (a int(11) unsigned, b int(11) unsigned); +insert into t1 values (1,0), (1,1), (1,2); +select a-b from t1 order by 1; +a-b +0 +1 +18446744073709551615 +select a-b , (a-b < 0) from t1 order by 1; +a-b (a-b < 0) +0 0 +1 0 +18446744073709551615 0 +select a-b as d, (a-b >= 0), b from t1 group by b having d >= 0; +d (a-b >= 0) b +1 1 0 +0 1 1 +18446744073709551615 1 2 +select cast((a - b) as unsigned) from t1 order by 1; +cast((a - b) as unsigned) +0 +1 +18446744073709551615 +drop table t1; +create table t1 (a int(11)); +select all all * from t1; +a +select distinct distinct * from t1; +a +select all distinct * from t1; +ERROR HY000: Incorrect usage of ALL and DISTINCT +select distinct all * from t1; +ERROR HY000: Incorrect usage of ALL and DISTINCT +drop table t1; +CREATE TABLE t1 ( +kunde_intern_id int(10) unsigned NOT NULL default '0', +kunde_id int(10) unsigned NOT NULL default '0', +FK_firma_id int(10) unsigned NOT NULL default '0', +aktuell enum('Ja','Nein') NOT NULL default 'Ja', +vorname varchar(128) NOT NULL default '', +nachname varchar(128) NOT NULL default '', +geloescht enum('Ja','Nein') NOT NULL default 'Nein', +firma varchar(128) NOT NULL default '' +); +INSERT INTO t1 VALUES +(3964,3051,1,'Ja','Vorname1','1Nachname','Nein','Print Schau XXXX'), +(3965,3051111,1,'Ja','Vorname1111','1111Nachname','Nein','Print Schau XXXX'); +SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname, geloescht FROM t1 +WHERE +( +( +( '' != '' AND firma LIKE CONCAT('%', '', '%')) +OR +(vorname LIKE CONCAT('%', 'Vorname1', '%') AND +nachname LIKE CONCAT('%', '1Nachname', '%') AND +'Vorname1' != '' AND 'xxxx' != '') +) +AND +( +aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2 +) +) +; +kunde_id FK_firma_id aktuell vorname nachname geloescht +SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname, +geloescht FROM t1 +WHERE +( +( +aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2 +) +AND +( +( '' != '' AND firma LIKE CONCAT('%', '', '%') ) +OR +( vorname LIKE CONCAT('%', 'Vorname1', '%') AND +nachname LIKE CONCAT('%', '1Nachname', '%') AND 'Vorname1' != '' AND +'xxxx' != '') +) +) +; +kunde_id FK_firma_id aktuell vorname nachname geloescht +SELECT COUNT(*) FROM t1 WHERE +( 0 OR (vorname LIKE '%Vorname1%' AND nachname LIKE '%1Nachname%' AND 1)) +AND FK_firma_id = 2; +COUNT(*) +0 +drop table t1; +CREATE TABLE t1 (b BIGINT(20) UNSIGNED NOT NULL, PRIMARY KEY (b)); +INSERT INTO t1 VALUES (0x8000000000000000); +SELECT b FROM t1 WHERE b=0x8000000000000000; +b +9223372036854775808 +DROP TABLE t1; +CREATE TABLE `t1` ( `gid` int(11) default NULL, `uid` int(11) default NULL); +CREATE TABLE `t2` ( `ident` int(11) default NULL, `level` char(16) default NULL); +INSERT INTO `t2` VALUES (0,'READ'); +CREATE TABLE `t3` ( `id` int(11) default NULL, `name` char(16) default NULL); +INSERT INTO `t3` VALUES (1,'fs'); +select * from t3 left join t1 on t3.id = t1.uid, t2 where t2.ident in (0, t1.gid, t3.id, 0); +id name gid uid ident level +1 fs NULL NULL 0 READ +drop table t1,t2,t3; +CREATE TABLE t1 ( +acct_id int(11) NOT NULL default '0', +profile_id smallint(6) default NULL, +UNIQUE KEY t1$acct_id (acct_id), +KEY t1$profile_id (profile_id) +); +INSERT INTO t1 VALUES (132,17),(133,18); +CREATE TABLE t2 ( +profile_id smallint(6) default NULL, +queue_id int(11) default NULL, +seq int(11) default NULL, +KEY t2$queue_id (queue_id) +); +INSERT INTO t2 VALUES (17,31,4),(17,30,3),(17,36,2),(17,37,1); +CREATE TABLE t3 ( +id int(11) NOT NULL default '0', +qtype int(11) default NULL, +seq int(11) default NULL, +warn_lvl int(11) default NULL, +crit_lvl int(11) default NULL, +rr1 tinyint(4) NOT NULL default '0', +rr2 int(11) default NULL, +default_queue tinyint(4) NOT NULL default '0', +KEY t3$qtype (qtype), +KEY t3$id (id) +); +INSERT INTO t3 VALUES (30,1,29,NULL,NULL,0,NULL,0),(31,1,28,NULL,NULL,0,NULL,0), +(36,1,34,NULL,NULL,0,NULL,0),(37,1,35,NULL,NULL,0,121,0); +SELECT COUNT(*) FROM t1 a STRAIGHT_JOIN t2 pq STRAIGHT_JOIN t3 q +WHERE +(pq.profile_id = a.profile_id) AND (a.acct_id = 132) AND +(pq.queue_id = q.id) AND (q.rr1 <> 1); +COUNT(*) +4 +drop table t1,t2,t3; +create table t1 (f1 int); +insert into t1 values (1),(NULL); +create table t2 (f2 int, f3 int, f4 int); +create index idx1 on t2 (f4); +insert into t2 values (1,2,3),(2,4,6); +select A.f2 from t1 left join t2 A on A.f2 = f1 where A.f3=(select min(f3) +from t2 C where A.f4 = C.f4) or A.f3 IS NULL; +f2 +1 +NULL +drop table t1,t2; +create table t2 (a tinyint unsigned); +create index t2i on t2(a); +insert into t2 values (0), (254), (255); +explain select * from t2 where a > -1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index t2i t2i 2 NULL 3 Using where; Using index +select * from t2 where a > -1; +a +0 +254 +255 +drop table t2; +CREATE TABLE t1 (a int, b int, c int); +INSERT INTO t1 +SELECT 50, 3, 3 FROM DUAL +WHERE NOT EXISTS +(SELECT * FROM t1 WHERE a = 50 AND b = 3); +SELECT * FROM t1; +a b c +50 3 3 +INSERT INTO t1 +SELECT 50, 3, 3 FROM DUAL +WHERE NOT EXISTS +(SELECT * FROM t1 WHERE a = 50 AND b = 3); +select found_rows(); +found_rows() +0 +SELECT * FROM t1; +a b c +50 3 3 +select count(*) from t1; +count(*) +1 +select found_rows(); +found_rows() +1 +select count(*) from t1 limit 2,3; +count(*) +select found_rows(); +found_rows() +0 +select SQL_CALC_FOUND_ROWS count(*) from t1 limit 2,3; +count(*) +select found_rows(); +found_rows() +1 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT); +(SELECT a, b AS c FROM t1) ORDER BY c+1; +a c +(SELECT a, b AS c FROM t1) ORDER BY b+1; +a c +SELECT a, b AS c FROM t1 ORDER BY c+1; +a c +SELECT a, b AS c FROM t1 ORDER BY b+1; +a c +drop table t1; +create table t1(f1 int, f2 int); +create table t2(f3 int); +select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,1)); +f1 +select f1 from t1,t2 where f1=f2 and (f1,NULL) = ((1,1)); +f1 +select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,NULL)); +f1 +insert into t1 values(1,1),(2,null); +insert into t2 values(2); +select * from t1,t2 where f1=f3 and (f1,f2) = (2,null); +f1 f2 f3 +select * from t1,t2 where f1=f3 and (f1,f2) <=> (2,null); +f1 f2 f3 +2 NULL 2 +drop table t1,t2; +create table t1 (f1 int not null auto_increment primary key, f2 varchar(10)); +create table t11 like t1; +insert into t1 values(1,""),(2,""); +show table status like 't1%'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +t1 MyISAM 10 Dynamic 2 20 X X X X X X X X latin1_swedish_ci NULL +t11 MyISAM 10 Dynamic 0 0 X X X X X X X X latin1_swedish_ci NULL +select 123 as a from t1 where f1 is null; +a +drop table t1,t11; +CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL, UNIQUE idx (a,b) ); +INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4); +CREATE TABLE t2 ( a INT NOT NULL, b INT NOT NULL, e INT ); +INSERT INTO t2 VALUES ( 1,10,1), (1,10,2), (1,11,1), (1,11,2), (1,2,1), (1,2,2),(1,2,3); +SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2 LEFT JOIN +t1 ON t2.a = t1.a AND t2.b = t1.b GROUP BY a, b, c; +a b c d +1 2 1 1 +1 2 2 1 +1 2 3 1 +1 10 2 +1 11 2 +SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2 LEFT JOIN +t1 ON t2.a = t1.a AND t2.b = t1.b GROUP BY t1.a, t1.b, c; +a b c d +1 10 4 +1 2 1 1 +1 2 2 1 +1 2 3 1 +SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2 LEFT JOIN +t1 ON t2.a = t1.a AND t2.b = t1.b GROUP BY t2.a, t2.b, c; +a b c d +1 2 1 1 +1 2 2 1 +1 2 3 1 +1 10 2 +1 11 2 +SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2,t1 +WHERE t2.a = t1.a AND t2.b = t1.b GROUP BY a, b, c; +a b c d +1 2 1 1 +1 2 2 1 +1 2 3 1 +DROP TABLE IF EXISTS t1, t2; +create table t1 (f1 int primary key, f2 int); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t1 values (1,1); +insert into t2 values (1,1),(1,2); +select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; +count(f2) >0 +1 +drop table t1,t2; +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +f1 f2 +1 1 +drop table t1,t2; +CREATE TABLE t1(a int, b int, c int, KEY b(b), KEY c(c)); +insert into t1 values (1,0,0),(2,0,0); +CREATE TABLE t2 (a int, b varchar(2), c varchar(2), PRIMARY KEY(a)); +insert into t2 values (1,'',''), (2,'',''); +CREATE TABLE t3 (a int, b int, PRIMARY KEY (a,b), KEY a (a), KEY b (b)); +insert into t3 values (1,1),(1,2); +explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2 +where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and +t2.b like '%%' order by t2.b limit 0,1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b,c b 5 const 1 Using where; Using temporary; Using filesort +1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1) +DROP TABLE t1,t2,t3; +CREATE TABLE t1 (a int, INDEX idx(a)); +INSERT INTO t1 VALUES (2), (3), (1); +EXPLAIN SELECT * FROM t1 IGNORE INDEX (idx); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +EXPLAIN SELECT * FROM t1 IGNORE INDEX (a); +ERROR 42000: Key 'a' doesn't exist in table 't1' +EXPLAIN SELECT * FROM t1 FORCE INDEX (a); +ERROR 42000: Key 'a' doesn't exist in table 't1' +DROP TABLE t1; +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1,1), (2,1), (4,10); +CREATE TABLE t2 (a int PRIMARY KEY, b int, KEY b (b)); +INSERT INTO t2 VALUES (1,NULL), (2,10); +ALTER TABLE t1 ENABLE KEYS; +EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index b b 5 NULL 2 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer +SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +a b a b +1 NULL 1 1 +1 NULL 2 1 +1 NULL 4 10 +2 10 4 10 +EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index b b 5 NULL 2 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer +SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +a b a b +1 NULL 1 1 +1 NULL 2 1 +1 NULL 4 10 +2 10 4 10 +DROP TABLE IF EXISTS t1,t2; +CREATE TABLE t1 (key1 float default NULL, UNIQUE KEY key1 (key1)); +CREATE TABLE t2 (key2 float default NULL, UNIQUE KEY key2 (key2)); +INSERT INTO t1 VALUES (0.3762),(0.3845),(0.6158),(0.7941); +INSERT INTO t2 VALUES (1.3762),(1.3845),(1.6158),(1.7941); +explain select max(key1) from t1 where key1 <= 0.6158; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select max(key2) from t2 where key2 <= 1.6158; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select min(key1) from t1 where key1 >= 0.3762; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select min(key2) from t2 where key2 >= 1.3762; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select max(key1), min(key2) from t1, t2 +where key1 <= 0.6158 and key2 >= 1.3762; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +select max(key1) from t1 where key1 <= 0.6158; +max(key1) +0.615800023078918 +select max(key2) from t2 where key2 <= 1.6158; +max(key2) +1.61580002307892 +select min(key1) from t1 where key1 >= 0.3762; +min(key1) +0.376199990510941 +select min(key2) from t2 where key2 >= 1.3762; +min(key2) +1.37619996070862 +select max(key1), min(key2) from t1, t2 +where key1 <= 0.6158 and key2 >= 1.3762; +max(key1) min(key2) +0.615800023078918 1.37619996070862 +select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; +max(key1) +0.615800023078918 +select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; +min(key1) +0.376199990510941 +DROP TABLE t1,t2; +CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); +INSERT INTO t1 VALUES (10); +SELECT i='1e+01',i=1e+01, i in (1e+01,1e+01), i in ('1e+01','1e+01') FROM t1; +i='1e+01' i=1e+01 i in (1e+01,1e+01) i in ('1e+01','1e+01') +1 1 1 1 +DROP TABLE t1; +create table t1(a bigint unsigned, b bigint); +insert into t1 values (0xfffffffffffffffff, 0xfffffffffffffffff), +(0x10000000000000000, 0x10000000000000000), +(0x8fffffffffffffff, 0x8fffffffffffffff); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +Warning 1264 Out of range value for column 'b' at row 1 +Warning 1264 Out of range value for column 'a' at row 2 +Warning 1264 Out of range value for column 'b' at row 2 +Warning 1264 Out of range value for column 'b' at row 3 +select hex(a), hex(b) from t1; +hex(a) hex(b) +FFFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF +8FFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF +drop table t1; +CREATE TABLE t1 (c0 int); +CREATE TABLE t2 (c0 int); +INSERT INTO t1 VALUES(@@connect_timeout); +INSERT INTO t2 VALUES(@@connect_timeout); +SELECT * FROM t1 JOIN t2 ON t1.c0 = t2.c0 WHERE (t1.c0 <=> @@connect_timeout); +c0 c0 +X X +DROP TABLE t1, t2; +End of 4.1 tests +CREATE TABLE t1 ( +K2C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '', +K4N4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '0000', +F2I4 int(11) NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES +('W%RT', '0100', 1), +('W-RT', '0100', 1), +('WART', '0100', 1), +('WART', '0200', 1), +('WERT', '0100', 2), +('WORT','0200', 2), +('WT', '0100', 2), +('W_RT', '0100', 2), +('WaRT', '0100', 3), +('WART', '0300', 3), +('WRT' , '0400', 3), +('WURM', '0500', 3), +('W%T', '0600', 4), +('WA%T', '0700', 4), +('WA_T', '0800', 4); +SELECT K2C4, K4N4, F2I4 FROM t1 +WHERE K2C4 = 'WART' AND +(F2I4 = 2 AND K2C4 = 'WART' OR (F2I4 = 2 OR K4N4 = '0200')); +K2C4 K4N4 F2I4 +WART 0200 1 +SELECT K2C4, K4N4, F2I4 FROM t1 +WHERE K2C4 = 'WART' AND (K2C4 = 'WART' OR K4N4 = '0200'); +K2C4 K4N4 F2I4 +WART 0100 1 +WART 0200 1 +WART 0300 3 +DROP TABLE t1; +create table t1 (a int, b int); +create table t2 like t1; +select t1.a from (t1 inner join t2 on t1.a=t2.a) where t2.a=1; +a +select t1.a from ((t1 inner join t2 on t1.a=t2.a)) where t2.a=1; +a +select x.a, y.a, z.a from ( (t1 x inner join t2 y on x.a=y.a) inner join t2 z on y.a=z.a) WHERE x.a=1; +a a a +drop table t1,t2; +create table t1 (s1 varchar(5)); +insert into t1 values ('Wall'); +select min(s1) from t1 group by s1 with rollup; +min(s1) +Wall +Wall +drop table t1; +create table t1 (s1 int) engine=myisam; +insert into t1 values (0); +select avg(distinct s1) from t1 group by s1 with rollup; +avg(distinct s1) +0.0000 +0.0000 +drop table t1; +create table t1 (s1 int); +insert into t1 values (null),(1); +select distinct avg(s1) as x from t1 group by s1 with rollup; +x +NULL +1.0000 +drop table t1; +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +INSERT INTO t2 VALUES (2), (4), (6); +SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a; +a +2 +4 +EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer +EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer +DROP TABLE t1,t2; +select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0; +x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0 +16 16 2 2 +create table t1 (f1 varchar(6) default NULL, f2 int(6) primary key not null); +create table t2 (f3 varchar(5) not null, f4 varchar(5) not null, UNIQUE KEY UKEY (f3,f4)); +insert into t1 values (" 2", 2); +insert into t2 values (" 2", " one "),(" 2", " two "); +select * from t1 left join t2 on f1 = f3; +f1 f2 f3 f4 + 2 2 2 one + 2 2 2 two +drop table t1,t2; +create table t1 (empnum smallint, grp int); +create table t2 (empnum int, name char(5)); +insert into t1 values(1,1); +insert into t2 values(1,'bob'); +create view v1 as select * from t2 inner join t1 using (empnum); +select * from v1; +empnum name grp +1 bob 1 +drop table t1,t2; +drop view v1; +create table t1 (pk int primary key, b int); +create table t2 (pk int primary key, c int); +select pk from t1 inner join t2 using (pk); +pk +drop table t1,t2; +create table t1 (s1 int, s2 char(5), s3 decimal(10)); +create view v1 as select s1, s2, 'x' as s3 from t1; +select * from t1 natural join v1; +s1 s2 s3 +insert into t1 values (1,'x',5); +select * from t1 natural join v1; +s1 s2 s3 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +drop table t1; +drop view v1; +create table t1(a1 int); +create table t2(a2 int); +insert into t1 values(1),(2); +insert into t2 values(1),(2); +create view v2 (c) as select a1 from t1; +select * from t1 natural left join t2; +a1 a2 +1 1 +1 2 +2 1 +2 2 +select * from t1 natural right join t2; +a2 a1 +1 1 +1 2 +2 1 +2 2 +select * from v2 natural left join t2; +c a2 +1 1 +1 2 +2 1 +2 2 +select * from v2 natural right join t2; +a2 c +1 1 +1 2 +2 1 +2 2 +drop table t1, t2; +drop view v2; +create table t1 (a int(10), t1_val int(10)); +create table t2 (b int(10), t2_val int(10)); +create table t3 (a int(10), b int(10)); +insert into t1 values (1,1),(2,2); +insert into t2 values (1,1),(2,2),(3,3); +insert into t3 values (1,1),(2,1),(3,1),(4,1); +select * from t1 natural join t2 natural join t3; +a b t1_val t2_val +1 1 1 1 +2 1 2 1 +select * from t1 natural join t3 natural join t2; +b a t1_val t2_val +1 1 1 1 +1 2 2 1 +drop table t1, t2, t3; +DO IFNULL(NULL, NULL); +SELECT CAST(IFNULL(NULL, NULL) AS DECIMAL); +CAST(IFNULL(NULL, NULL) AS DECIMAL) +NULL +SELECT ABS(IFNULL(NULL, NULL)); +ABS(IFNULL(NULL, NULL)) +NULL +SELECT IFNULL(NULL, NULL); +IFNULL(NULL, NULL) +NULL +SET @OLD_SQL_MODE12595=@@SQL_MODE, @@SQL_MODE=''; +SHOW LOCAL VARIABLES LIKE 'SQL_MODE'; +Variable_name Value +sql_mode +CREATE TABLE BUG_12595(a varchar(100)); +INSERT INTO BUG_12595 VALUES ('hakan%'), ('hakank'), ("ha%an"); +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%'; +a +hakan% +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan*%' ESCAPE '*'; +a +hakan% +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan**%' ESCAPE '**'; +ERROR HY000: Incorrect arguments to ESCAPE +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan%' ESCAPE ''; +a +hakan% +hakank +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%' ESCAPE ''; +a +SELECT * FROM BUG_12595 WHERE a LIKE 'ha\%an' ESCAPE 0x5c; +a +ha%an +SELECT * FROM BUG_12595 WHERE a LIKE 'ha%%an' ESCAPE '%'; +a +ha%an +SELECT * FROM BUG_12595 WHERE a LIKE 'ha\%an' ESCAPE '\\'; +a +ha%an +SELECT * FROM BUG_12595 WHERE a LIKE 'ha|%an' ESCAPE '|'; +a +ha%an +SET @@SQL_MODE='NO_BACKSLASH_ESCAPES'; +SHOW LOCAL VARIABLES LIKE 'SQL_MODE'; +Variable_name Value +sql_mode NO_BACKSLASH_ESCAPES +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%'; +a +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan*%' ESCAPE '*'; +a +hakan% +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan**%' ESCAPE '**'; +ERROR HY000: Incorrect arguments to ESCAPE +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%' ESCAPE '\\'; +ERROR HY000: Incorrect arguments to ESCAPE +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan%' ESCAPE ''; +ERROR HY000: Incorrect arguments to ESCAPE +SELECT * FROM BUG_12595 WHERE a LIKE 'ha\%an' ESCAPE 0x5c; +a +ha%an +SELECT * FROM BUG_12595 WHERE a LIKE 'ha|%an' ESCAPE '|'; +a +ha%an +SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\n%' ESCAPE '\n'; +ERROR HY000: Incorrect arguments to ESCAPE +SET @@SQL_MODE=@OLD_SQL_MODE12595; +DROP TABLE BUG_12595; +create table t1 (a char(1)); +create table t2 (a char(1)); +insert into t1 values ('a'),('b'),('c'); +insert into t2 values ('b'),('c'),('d'); +select a from t1 natural join t2; +a +b +c +select * from t1 natural join t2 where a = 'b'; +a +b +drop table t1, t2; +CREATE TABLE t1 (`id` TINYINT); +CREATE TABLE t2 (`id` TINYINT); +CREATE TABLE t3 (`id` TINYINT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2); +INSERT INTO t3 VALUES (3); +SELECT t1.id,t3.id FROM t1 JOIN t2 ON (t2.id=t1.id) LEFT JOIN t3 USING (id); +ERROR 23000: Column 'id' in from clause is ambiguous +SELECT t1.id,t3.id FROM t1 JOIN t2 ON (t2.notacolumn=t1.id) LEFT JOIN t3 USING (id); +ERROR 23000: Column 'id' in from clause is ambiguous +SELECT id,t3.id FROM t1 JOIN t2 ON (t2.id=t1.id) LEFT JOIN t3 USING (id); +ERROR 23000: Column 'id' in from clause is ambiguous +SELECT id,t3.id FROM (t1 JOIN t2 ON (t2.id=t1.id)) LEFT JOIN t3 USING (id); +ERROR 23000: Column 'id' in from clause is ambiguous +drop table t1, t2, t3; +create table t1 (a int(10),b int(10)); +create table t2 (a int(10),b int(10)); +insert into t1 values (1,10),(2,20),(3,30); +insert into t2 values (1,10); +select * from t1 inner join t2 using (A); +a b b +1 10 10 +select * from t1 inner join t2 using (a); +a b b +1 10 10 +drop table t1, t2; +create table t1 (a int, c int); +create table t2 (b int); +create table t3 (b int, a int); +create table t4 (c int); +insert into t1 values (1,1); +insert into t2 values (1); +insert into t3 values (1,1); +insert into t4 values (1); +select * from t1 join t2 join t3 on (t2.b = t3.b and t1.a = t3.a); +a c b b a +1 1 1 1 1 +select * from t1, t2 join t3 on (t2.b = t3.b and t1.a = t3.a); +ERROR 42S22: Unknown column 't1.a' in 'on clause' +select * from t1 join t2 join t3 join t4 on (t1.a = t4.c and t2.b = t4.c); +a c b b a c +1 1 1 1 1 1 +select * from t1 join t2 join t4 using (c); +c a b +1 1 1 +drop table t1, t2, t3, t4; +create table t1(x int, y int); +create table t2(x int, y int); +create table t3(x int, primary key(x)); +insert into t1 values (1, 1), (2, 1), (3, 1), (4, 3), (5, 6), (6, 6); +insert into t2 values (1, 1), (2, 1), (3, 3), (4, 6), (5, 6); +insert into t3 values (1), (2), (3), (4), (5); +select t1.x, t3.x from t1, t2, t3 where t1.x = t2.x and t3.x >= t1.y and t3.x <= t2.y; +x x +1 1 +2 1 +3 1 +3 2 +3 3 +4 3 +4 4 +4 5 +drop table t1,t2,t3; +create table t1 (id char(16) not null default '', primary key (id)); +insert into t1 values ('100'),('101'),('102'); +create table t2 (id char(16) default null); +insert into t2 values (1); +create view v1 as select t1.id from t1; +create view v2 as select t2.id from t2; +create view v3 as select (t1.id+2) as id from t1 natural left join t2; +select t1.id from t1 left join v2 using (id); +id +100 +101 +102 +select t1.id from v2 right join t1 using (id); +id +100 +101 +102 +select t1.id from t1 left join v3 using (id); +id +100 +101 +102 +select * from t1 left join v2 using (id); +id +100 +101 +102 +select * from v2 right join t1 using (id); +id +100 +101 +102 +select * from t1 left join v3 using (id); +id +100 +101 +102 +select v1.id from v1 left join v2 using (id); +id +100 +101 +102 +select v1.id from v2 right join v1 using (id); +id +100 +101 +102 +select v1.id from v1 left join v3 using (id); +id +100 +101 +102 +select * from v1 left join v2 using (id); +id +100 +101 +102 +select * from v2 right join v1 using (id); +id +100 +101 +102 +select * from v1 left join v3 using (id); +id +100 +101 +102 +drop table t1, t2; +drop view v1, v2, v3; +create table t1 (id int(11) not null default '0'); +insert into t1 values (123),(191),(192); +create table t2 (id char(16) character set utf8 not null); +insert into t2 values ('58013'),('58014'),('58015'),('58016'); +create table t3 (a_id int(11) not null, b_id char(16) character set utf8); +insert into t3 values (123,null),(123,null),(123,null),(123,null),(123,null),(123,'58013'); +select count(*) +from t1 inner join (t3 left join t2 on t2.id = t3.b_id) on t1.id = t3.a_id; +count(*) +6 +select count(*) +from t1 inner join (t2 right join t3 on t2.id = t3.b_id) on t1.id = t3.a_id; +count(*) +6 +drop table t1,t2,t3; +create table t1 (a int); +create table t2 (b int); +create table t3 (c int); +select * from t1 join t2 join t3 on (t1.a=t3.c); +a b c +select * from t1 join t2 left join t3 on (t1.a=t3.c); +a b c +select * from t1 join t2 right join t3 on (t1.a=t3.c); +a b c +select * from t1 join t2 straight_join t3 on (t1.a=t3.c); +a b c +drop table t1, t2 ,t3; +create table t1(f1 int, f2 date); +insert into t1 values(1,'2005-01-01'),(2,'2005-09-01'),(3,'2005-09-30'), +(4,'2005-10-01'),(5,'2005-12-30'); +select * from t1 where f2 >= 0 order by f2; +f1 f2 +1 2005-01-01 +2 2005-09-01 +3 2005-09-30 +4 2005-10-01 +5 2005-12-30 +select * from t1 where f2 >= '0000-00-00' order by f2; +f1 f2 +1 2005-01-01 +2 2005-09-01 +3 2005-09-30 +4 2005-10-01 +5 2005-12-30 +select * from t1 where f2 >= '2005-09-31' order by f2; +f1 f2 +4 2005-10-01 +5 2005-12-30 +select * from t1 where f2 >= '2005-09-3a' order by f2; +f1 f2 +3 2005-09-30 +4 2005-10-01 +5 2005-12-30 +Warnings: +Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1 +select * from t1 where f2 <= '2005-09-31' order by f2; +f1 f2 +1 2005-01-01 +2 2005-09-01 +3 2005-09-30 +select * from t1 where f2 <= '2005-09-3a' order by f2; +f1 f2 +1 2005-01-01 +2 2005-09-01 +Warnings: +Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1 +drop table t1; +create table t1 (f1 int, f2 int); +insert into t1 values (1, 30), (2, 20), (3, 10); +create algorithm=merge view v1 as select f1, f2 from t1; +create algorithm=merge view v2 (f2, f1) as select f1, f2 from t1; +create algorithm=merge view v3 as select t1.f1 as f2, t1.f2 as f1 from t1; +select t1.f1 as x1, f1 from t1 order by t1.f1; +x1 f1 +1 1 +2 2 +3 3 +select v1.f1 as x1, f1 from v1 order by v1.f1; +x1 f1 +1 1 +2 2 +3 3 +select v2.f1 as x1, f1 from v2 order by v2.f1; +x1 f1 +10 10 +20 20 +30 30 +select v3.f1 as x1, f1 from v3 order by v3.f1; +x1 f1 +10 10 +20 20 +30 30 +select f1, f2, v1.f1 as x1 from v1 order by v1.f1; +f1 f2 x1 +1 30 1 +2 20 2 +3 10 3 +select f1, f2, v2.f1 as x1 from v2 order by v2.f1; +f1 f2 x1 +10 3 10 +20 2 20 +30 1 30 +select f1, f2, v3.f1 as x1 from v3 order by v3.f1; +f1 f2 x1 +10 3 10 +20 2 20 +30 1 30 +drop table t1; +drop view v1, v2, v3; +CREATE TABLE t1(key_a int4 NOT NULL, optimus varchar(32), PRIMARY KEY(key_a)); +CREATE TABLE t2(key_a int4 NOT NULL, prime varchar(32), PRIMARY KEY(key_a)); +CREATE table t3(key_a int4 NOT NULL, key_b int4 NOT NULL, foo varchar(32), +PRIMARY KEY(key_a,key_b)); +INSERT INTO t1 VALUES (0,''); +INSERT INTO t1 VALUES (1,'i'); +INSERT INTO t1 VALUES (2,'j'); +INSERT INTO t1 VALUES (3,'k'); +INSERT INTO t2 VALUES (1,'r'); +INSERT INTO t2 VALUES (2,'s'); +INSERT INTO t2 VALUES (3,'t'); +INSERT INTO t3 VALUES (1,5,'x'); +INSERT INTO t3 VALUES (1,6,'y'); +INSERT INTO t3 VALUES (2,5,'xx'); +INSERT INTO t3 VALUES (2,6,'yy'); +INSERT INTO t3 VALUES (2,7,'zz'); +INSERT INTO t3 VALUES (3,5,'xxx'); +SELECT t2.key_a,foo +FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a +INNER JOIN t3 ON t1.key_a = t3.key_a +WHERE t2.key_a=2 and key_b=5; +key_a foo +2 xx +EXPLAIN SELECT t2.key_a,foo +FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a +INNER JOIN t3 ON t1.key_a = t3.key_a +WHERE t2.key_a=2 and key_b=5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1 +SELECT t2.key_a,foo +FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a +INNER JOIN t3 ON t1.key_a = t3.key_a +WHERE t2.key_a=2 and key_b=5; +key_a foo +2 xx +EXPLAIN SELECT t2.key_a,foo +FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a +INNER JOIN t3 ON t1.key_a = t3.key_a +WHERE t2.key_a=2 and key_b=5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1 +DROP TABLE t1,t2,t3; +create table t1 (f1 int); +insert into t1 values(1),(2); +create table t2 (f2 int, f3 int, key(f2)); +insert into t2 values(1,1),(2,2); +create table t3 (f4 int not null); +insert into t3 values (2),(2),(2); +select f1,(select count(*) from t2,t3 where f2=f1 and f3=f4) as count from t1; +f1 count +1 0 +2 3 +drop table t1,t2,t3; +create table t1 (f1 int unique); +create table t2 (f2 int unique); +create table t3 (f3 int unique); +insert into t1 values(1),(2); +insert into t2 values(1),(2); +insert into t3 values(1),(NULL); +select * from t3 where f3 is null; +f3 +NULL +select t2.f2 from t1 left join t2 on f1=f2 join t3 on f1=f3 where f1=1; +f2 +1 +drop table t1,t2,t3; +create table t1(f1 char, f2 char not null); +insert into t1 values(null,'a'); +create table t2 (f2 char not null); +insert into t2 values('b'); +select * from t1 left join t2 on f1=t2.f2 where t1.f2='a'; +f1 f2 f2 +NULL a NULL +drop table t1,t2; +select * from (select * left join t on f1=f2) tt; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'on f1=f2) tt' at line 1 +CREATE TABLE t1 (sku int PRIMARY KEY, pr int); +CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255)); +INSERT INTO t1 VALUES +(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10); +INSERT INTO t2 VALUES +(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'), +(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh'); +SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr +FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku); +sku sppr name sku pr +20 10 bbb 10 10 +20 10 bbb 20 10 +EXPLAIN +SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr +FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where +DROP TABLE t1,t2; +CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL); +INSERT t1 SET i = 0; +UPDATE t1 SET i = -1; +Warnings: +Warning 1264 Out of range value for column 'i' at row 1 +SELECT * FROM t1; +i +0 +UPDATE t1 SET i = CAST(i - 1 AS SIGNED); +Warnings: +Warning 1264 Out of range value for column 'i' at row 1 +SELECT * FROM t1; +i +0 +UPDATE t1 SET i = i - 1; +Warnings: +Warning 1264 Out of range value for column 'i' at row 1 +SELECT * FROM t1; +i +255 +DROP TABLE t1; +create table t1 (a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, b int, c int, e int, primary key(a,b,c)); +insert into t2 select A.a, B.a, C.a, C.a from t1 A, t1 B, t1 C; +analyze table t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK +select 'In next EXPLAIN, B.rows must be exactly 10:' Z; +Z +In next EXPLAIN, B.rows must be exactly 10: +explain select * from t2 A, t2 B where A.a=5 and A.b=5 and A.C<5 +and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using where +1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10 +drop table t1, t2; +CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b)); +INSERT INTO t1 VALUES (1, 3), (9,4), (7,5), (4,5), (6,2), +(3,1), (5,1), (8,9), (2,2), (0,9); +CREATE TABLE t2 (c int, d int, f int, INDEX(c,f)); +INSERT INTO t2 VALUES +(1,0,0), (1,0,1), (2,0,0), (2,0,1), (3,0,0), (4,0,1), +(5,0,0), (5,0,1), (6,0,0), (0,0,1), (7,0,0), (7,0,1), +(0,0,0), (0,0,1), (8,0,0), (8,0,1), (9,0,0), (9,0,1); +EXPLAIN +SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where +1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where +EXPLAIN +SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where +1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where +DROP TABLE t1, t2; +create table t1 ( +a int unsigned not null auto_increment primary key, +b bit not null, +c bit not null +); +create table t2 ( +a int unsigned not null auto_increment primary key, +b bit not null, +c int unsigned not null, +d varchar(50) +); +insert into t1 (b,c) values (0,1), (0,1); +insert into t2 (b,c) values (0,1); +select t1.a, t1.b + 0, t1.c + 0, t2.a, t2.b + 0, t2.c, t2.d +from t1 left outer join t2 on t1.a = t2.c and t2.b <> 1 +where t1.b <> 1 order by t1.a; +a t1.b + 0 t1.c + 0 a t2.b + 0 c d +1 0 1 1 0 1 NULL +2 0 1 NULL NULL NULL NULL +drop table t1,t2; +SELECT 0.9888889889 * 1.011111411911; +0.9888889889 * 1.011111411911 +0.9998769417899202067879 +prepare stmt from 'select 1 as " a "'; +Warnings: +Warning 1466 Leading spaces are removed from name ' a ' +execute stmt; +a +1 +CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int NOT NULL); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4); +CREATE TABLE t2 (c int NOT NULL, INDEX idx(c)); +INSERT INTO t2 VALUES +(1), (1), (1), (1), (1), (1), (1), (1), +(2), (2), (2), (2), +(3), (3), +(4); +EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 ref idx idx 4 const 7 Using index +EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 ref idx idx 4 const 1 Using index +DROP TABLE t1, t2; +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int); +INSERT INTO t1 VALUES (1,2), (2,NULL), (3,2); +CREATE TABLE t2 (b int, c INT, INDEX idx1(b)); +INSERT INTO t2 VALUES (2,1), (3,2); +CREATE TABLE t3 (d int, e int, INDEX idx1(d)); +INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50); +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id +WHERE t1.id=2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 const idx1 NULL NULL NULL 1 +1 SIMPLE t3 ref idx1 idx1 5 const 3 Using where +SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id +WHERE t1.id=2; +id a b c d e +2 NULL NULL NULL 2 10 +2 NULL NULL NULL 2 20 +2 NULL NULL NULL 2 40 +2 NULL NULL NULL 2 50 +DROP TABLE t1,t2,t3; +create table t1 (c1 varchar(1), c2 int, c3 int, c4 int, c5 int, c6 int, +c7 int, c8 int, c9 int, fulltext key (`c1`)); +select distinct match (`c1`) against ('z') , c2, c3, c4,c5, c6,c7, c8 +from t1 where c9=1 order by c2, c2; +match (`c1`) against ('z') c2 c3 c4 c5 c6 c7 c8 +drop table t1; +CREATE TABLE t1 (pk varchar(10) PRIMARY KEY, fk varchar(16)); +CREATE TABLE t2 (pk varchar(16) PRIMARY KEY, fk varchar(10)); +INSERT INTO t1 VALUES +('d','dddd'), ('i','iii'), ('a','aa'), ('b','bb'), ('g','gg'), +('e','eee'), ('c','cccc'), ('h','hhh'), ('j','jjj'), ('f','fff'); +INSERT INTO t2 VALUES +('jjj', 'j'), ('cc','c'), ('ccc','c'), ('aaa', 'a'), ('jjjj','j'), +('hhh','h'), ('gg','g'), ('fff','f'), ('ee','e'), ('ffff','f'), +('bbb','b'), ('ff','f'), ('cccc','c'), ('dddd','d'), ('jj','j'), +('aaaa','a'), ('bb','b'), ('eeee','e'), ('aa','a'), ('hh','h'); +EXPLAIN SELECT t2.* +FROM t1 JOIN t2 ON t2.fk=t1.pk +WHERE t2.fk < 'c' AND t2.pk=t1.fk; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where +EXPLAIN SELECT t2.* +FROM t1 JOIN t2 ON t2.fk=t1.pk +WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where +EXPLAIN SELECT t2.* +FROM t1 JOIN t2 ON t2.fk=t1.pk +WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where +DROP TABLE t1,t2; +CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a)); +CREATE TABLE t2 (a int, b varchar(20) NOT NULL, +PRIMARY KEY (a), UNIQUE KEY (b)); +INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c'); +INSERT INTO t2 VALUES (1,'a'),(2,'b'),(3,'c'); +EXPLAIN SELECT t1.a FROM t1 LEFT JOIN t2 ON t2.b=t1.b WHERE t1.a=3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +DROP TABLE t1,t2; +CREATE TABLE t1(id int PRIMARY KEY, b int, e int); +CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a)); +CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c)); +INSERT INTO t1 VALUES +(1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79), +(6,63,67), (5,55,58), (3,38,39), (8,81,89); +INSERT INTO t2 VALUES +(21,210), (41,410), (82,820), (83,830), (84,840), +(65,650), (51,510), (37,370), (94,940), (76,760), +(22,220), (33,330), (40,400), (95,950), (38,380), +(67,670), (88,880), (57,570), (96,960), (97,970); +INSERT INTO t3 VALUES +(210,'bb'), (950,'ii'), (400,'ab'), (500,'ee'), (220,'gg'), +(440,'gg'), (310,'eg'), (380,'ee'), (840,'bb'), (830,'ff'), +(230,'aa'), (960,'ii'), (410,'aa'), (510,'ee'), (290,'bb'), +(450,'gg'), (320,'dd'), (390,'hh'), (850,'jj'), (860,'ff'); +EXPLAIN +SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 +WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND +t3.a=t2.a AND t3.c IN ('bb','ee'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 range si si 5 NULL 4 Using where +1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +EXPLAIN +SELECT t3.a FROM t1,t2,t3 +WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND +t3.a=t2.a AND t3.c IN ('bb','ee') ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 range si,ai si 5 NULL 4 Using where +1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +EXPLAIN +SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 +WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND +t3.c IN ('bb','ee'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 range si si 5 NULL 2 Using where +1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +EXPLAIN +SELECT t3.a FROM t1,t2,t3 +WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND +t3.c IN ('bb','ee'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 range si,ai si 5 NULL 2 Using where +1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +DROP TABLE t1,t2,t3; +CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int); +CREATE TABLE t2 ( f11 int PRIMARY KEY ); +INSERT INTO t1 VALUES (1,1,1,0,0,0,0),(2,1,1,3,8,1,0),(3,1,1,4,12,1,0); +INSERT INTO t2 VALUES (62); +SELECT * FROM t1 LEFT JOIN t2 ON f11 = t1.checked_out GROUP BY f1 ORDER BY f2, f3, f4, f5 LIMIT 0, 1; +f1 f2 f3 f4 f5 f6 checked_out f11 +1 1 1 0 0 0 0 NULL +DROP TABLE t1, t2; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a int); +INSERT into t1 values (1), (2), (3); +SELECT * FROM t1 LIMIT 2, -1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1' at line 1 +DROP TABLE t1; +CREATE TABLE t1 ( +ID_with_null int NULL, +ID_better int NOT NULL, +INDEX idx1 (ID_with_null), +INDEX idx2 (ID_better) +); +INSERT INTO t1 VALUES (1,1), (2,1), (null,3), (null,3), (null,3), (null,3); +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +SELECT COUNT(*) FROM t1 WHERE ID_with_null IS NULL; +COUNT(*) +128 +SELECT COUNT(*) FROM t1 WHERE ID_better=1; +COUNT(*) +2 +EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +DROP INDEX idx1 ON t1; +CREATE UNIQUE INDEX idx1 ON t1(ID_with_null); +EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +DROP TABLE t1; +CREATE TABLE t1 ( +ID1_with_null int NULL, +ID2_with_null int NULL, +ID_better int NOT NULL, +INDEX idx1 (ID1_with_null, ID2_with_null), +INDEX idx2 (ID_better) +); +INSERT INTO t1 VALUES (1,1,1), (2,2,1), (3,null,3), (null,3,3), (null,null,3), +(3,null,3), (null,3,3), (null,null,3), (3,null,3), (null,3,3), (null,null,3); +INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3; +COUNT(*) +24 +SELECT COUNT(*) FROM t1 WHERE ID1_with_null=3 AND ID2_with_null IS NULL; +COUNT(*) +24 +SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null IS NULL; +COUNT(*) +192 +SELECT COUNT(*) FROM t1 WHERE ID_better=1; +COUNT(*) +2 +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +DROP INDEX idx1 ON t1; +CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null); +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND +(ID2_with_null=1 OR ID2_with_null=2); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +DROP TABLE t1; +CREATE TABLE t1 (a INT, ts TIMESTAMP, KEY ts(ts)); +INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00"); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +CREATE TABLE t2 (a INT, dt1 DATETIME, dt2 DATETIME, PRIMARY KEY (a)); +INSERT INTO t2 VALUES (30, "2006-01-01 00:00:00", "2999-12-31 00:00:00"); +INSERT INTO t2 SELECT a+1,dt1,dt2 FROM t2; +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30 +AND t1.ts BETWEEN t2.dt1 AND t2.dt2 +AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t1 range ts ts 4 NULL 1 Using where +Warnings: +Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1 +SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30 +AND t1.ts BETWEEN t2.dt1 AND t2.dt2 +AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; +a ts a dt1 dt2 +30 2006-01-03 23:00:00 30 2006-01-01 00:00:00 2999-12-31 00:00:00 +Warnings: +Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1 +DROP TABLE t1,t2; +create table t1 (a bigint unsigned); +insert into t1 values +(if(1, 9223372036854775808, 1)), +(case when 1 then 9223372036854775808 else 1 end), +(coalesce(9223372036854775808, 1)); +select * from t1; +a +9223372036854775808 +9223372036854775808 +9223372036854775808 +drop table t1; +create table t1 select +if(1, 9223372036854775808, 1) i, +case when 1 then 9223372036854775808 else 1 end c, +coalesce(9223372036854775808, 1) co; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` decimal(19,0) NOT NULL DEFAULT '0', + `c` decimal(19,0) NOT NULL DEFAULT '0', + `co` decimal(19,0) NOT NULL DEFAULT '0' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +select +if(1, cast(1111111111111111111 as unsigned), 1) i, +case when 1 then cast(1111111111111111111 as unsigned) else 1 end c, +coalesce(cast(1111111111111111111 as unsigned), 1) co; +i c co +1111111111111111111 1111111111111111111 1111111111111111111 +CREATE TABLE t1 (name varchar(255)); +CREATE TABLE t2 (name varchar(255), n int, KEY (name(3))); +INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); +INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); +INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); +INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +SELECT * FROM t2; +name n +bb 1 +aa 2 +cc 3 +cc 4 +cc 5 +bb 6 +cc 7 +SELECT * FROM t2 ORDER BY name; +name n +aa 2 +bb 1 +bb 6 +cc 4 +cc 3 +cc 5 +cc 7 +SELECT name, LENGTH(name), n FROM t2 ORDER BY name; +name LENGTH(name) n +aa 2 2 +bb 2 1 +bb 3 6 +cc 4 4 +cc 5 3 +cc 2 5 +cc 3 7 +EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref name name 6 const 3 Using where +SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; +name LENGTH(name) n +cc 5 3 +cc 2 5 +cc 3 7 +EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range name name 6 NULL 3 Using where +SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; +name LENGTH(name) n +cc 5 3 +cc 4 4 +cc 2 5 +cc 3 7 +EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort +SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; +name LENGTH(name) n +cc 4 4 +cc 5 3 +cc 2 5 +cc 3 7 +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ref name name 6 test.t1.name 2 +SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; +name name n +ccc NULL NULL +bb bb 1 +bb bb 6 +cc cc 3 +cc cc 5 +cc cc 7 +aa aa 2 +aa aa 2 +DROP TABLE t1,t2; +CREATE TABLE t1 (name text); +CREATE TABLE t2 (name text, n int, KEY (name(3))); +INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa'); +INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3); +INSERT INTO t2 VALUES (concat('cc ', 0x06), 4); +INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7); +SELECT * FROM t2; +name n +bb 1 +aa 2 +cc 3 +cc 4 +cc 5 +bb 6 +cc 7 +SELECT * FROM t2 ORDER BY name; +name n +aa 2 +bb 1 +bb 6 +cc 4 +cc 3 +cc 5 +cc 7 +SELECT name, LENGTH(name), n FROM t2 ORDER BY name; +name LENGTH(name) n +aa 2 2 +bb 2 1 +bb 3 6 +cc 4 4 +cc 5 3 +cc 2 5 +cc 3 7 +EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref name name 6 const 3 Using where +SELECT name, LENGTH(name), n FROM t2 WHERE name='cc '; +name LENGTH(name) n +cc 5 3 +cc 2 5 +cc 3 7 +EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range name name 6 NULL 3 Using where +SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%'; +name LENGTH(name) n +cc 5 3 +cc 4 4 +cc 2 5 +cc 3 7 +EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort +SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name; +name LENGTH(name) n +cc 4 4 +cc 5 3 +cc 2 5 +cc 3 7 +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ref name name 6 test.t1.name 2 +SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; +name name n +ccc NULL NULL +bb bb 1 +bb bb 6 +cc cc 3 +cc cc 5 +cc cc 7 +aa aa 2 +aa aa 2 +DROP TABLE t1,t2; +CREATE TABLE t1 ( +access_id int NOT NULL default '0', +name varchar(20) default NULL, +rank int NOT NULL default '0', +KEY idx (access_id) +); +CREATE TABLE t2 ( +faq_group_id int NOT NULL default '0', +faq_id int NOT NULL default '0', +access_id int default NULL, +UNIQUE KEY idx1 (faq_id), +KEY idx2 (faq_group_id,faq_id) +); +INSERT INTO t1 VALUES +(1,'Everyone',2),(2,'Help',3),(3,'Technical Support',1),(4,'Chat User',4); +INSERT INTO t2 VALUES +(261,265,1),(490,494,1); +SELECT t2.faq_id +FROM t1 INNER JOIN t2 IGNORE INDEX (idx1) +ON (t1.access_id = t2.access_id) +LEFT JOIN t2 t +ON (t.faq_group_id = t2.faq_group_id AND +find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4')) +WHERE +t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265); +faq_id +265 +SELECT t2.faq_id +FROM t1 INNER JOIN t2 +ON (t1.access_id = t2.access_id) +LEFT JOIN t2 t +ON (t.faq_group_id = t2.faq_group_id AND +find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4')) +WHERE +t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265); +faq_id +265 +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT, b INT, KEY inx (b,a)); +INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1, 6), (1,7); +EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2 +ON ( f1.b=f2.b AND f1.a<f2.a ) +WHERE 1 AND f1.b NOT IN (100,2232,3343,51111); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE f1 index inx inx 10 NULL 7 Using where; Using index +1 SIMPLE f2 ref inx inx 5 test.f1.b 1 Using where; Using index +DROP TABLE t1; +CREATE TABLE t1 (c1 INT, c2 INT); +INSERT INTO t1 VALUES (1,11), (2,22), (2,22); +EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2)))))))))))))))))))))))))))))))) > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where +31 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +32 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) > 0; +ERROR HY000: Too high level of nesting for select +DROP TABLE t1; +CREATE TABLE t1 ( +c1 int(11) NOT NULL AUTO_INCREMENT, +c2 varchar(1000) DEFAULT NULL, +c3 bigint(20) DEFAULT NULL, +c4 bigint(20) DEFAULT NULL, +PRIMARY KEY (c1) +); +EXPLAIN EXTENDED +SELECT join_2.c1 +FROM +t1 AS join_0, +t1 AS join_1, +t1 AS join_2, +t1 AS join_3, +t1 AS join_4, +t1 AS join_5, +t1 AS join_6, +t1 AS join_7 +WHERE +join_0.c1=join_1.c1 AND +join_1.c1=join_2.c1 AND +join_2.c1=join_3.c1 AND +join_3.c1=join_4.c1 AND +join_4.c1=join_5.c1 AND +join_5.c1=join_6.c1 AND +join_6.c1=join_7.c1 +OR +join_0.c2 < '?' AND +join_1.c2 < '?' AND +join_2.c2 > '?' AND +join_2.c2 < '!' AND +join_3.c2 > '?' AND +join_4.c2 = '?' AND +join_5.c2 <> '?' AND +join_6.c2 <> '?' AND +join_7.c2 >= '?' AND +join_0.c1=join_1.c1 AND +join_1.c1=join_2.c1 AND +join_2.c1=join_3.c1 AND +join_3.c1=join_4.c1 AND +join_4.c1=join_5.c1 AND +join_5.c1=join_6.c1 AND +join_6.c1=join_7.c1 +GROUP BY +join_3.c1, +join_2.c1, +join_7.c1, +join_1.c1, +join_0.c1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select NULL AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by NULL,NULL,NULL,NULL,NULL +SHOW WARNINGS; +Level Code Message +Note 1003 select NULL AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by NULL,NULL,NULL,NULL,NULL +DROP TABLE t1; +SELECT 1 AS ` `; + +1 +Warnings: +Warning 1474 Name ' ' has become '' +SELECT 1 AS ` `; + +1 +Warnings: +Warning 1474 Name ' ' has become '' +SELECT 1 AS ` x`; +x +1 +Warnings: +Warning 1466 Leading spaces are removed from name ' x' +CREATE VIEW v1 AS SELECT 1 AS ``; +ERROR 42000: Incorrect column name '' +CREATE VIEW v1 AS SELECT 1 AS ` `; +ERROR 42000: Incorrect column name ' ' +CREATE VIEW v1 AS SELECT 1 AS ` `; +ERROR 42000: Incorrect column name ' ' +CREATE VIEW v1 AS SELECT (SELECT 1 AS ` `); +ERROR 42000: Incorrect column name ' ' +CREATE VIEW v1 AS SELECT 1 AS ` x`; +Warnings: +Warning 1466 Leading spaces are removed from name ' x' +SELECT `x` FROM v1; +x +1 +ALTER VIEW v1 AS SELECT 1 AS ` `; +ERROR 42000: Incorrect column name ' ' +DROP VIEW v1; +select str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' + and '2007/10/20 00:00:00 GMT'; +str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' + and '2007/10/20 00:00:00 GMT' +1 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT' +Warning 1292 Truncated incorrect datetime value: '2007/10/20 00:00:00 GMT' +select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6'; +str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6' +1 +Warnings: +Warning 1292 Truncated incorrect date value: '2007/10/01 00:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6'; +str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6' +1 +Warnings: +Warning 1292 Truncated incorrect date value: '2007/10/2000:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6'; +str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6' +1 +Warnings: +Warning 1292 Truncated incorrect date value: '2007-10-1 00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6'; +str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6' +1 +Warnings: +Warning 1292 Truncated incorrect date value: '2007-10-01 x00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6'; +str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6' +1 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6'; +str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6' +1 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:x00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6'; +str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6' +1 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007-10-01 x12:34:56 GMT-6' +select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; +str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' +1 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6' +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; +str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' +0 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6' +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56'; +str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56' +1 +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00'; +str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00' +0 +select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00'; +str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00' +1 +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00'; +str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00' +1 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34' +select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34'; +str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34' +1 +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; +str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +1 +select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' + and '2007/10/20 00:00:00'; +str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' + and '2007/10/20 00:00:00' +1 +set SQL_MODE=TRADITIONAL; +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; +str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +0 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34' +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; +str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +0 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34'; +str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34' +0 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34:00' +select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' + and '2007/10/20'; +str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' + and '2007/10/20' +0 +Warnings: +Warning 1292 Incorrect datetime value: '2007-10-00' for column '2007/09/01' at row 1 +Warning 1292 Incorrect datetime value: '2007-10-00' for column '2007/10/20' at row 1 +set SQL_MODE=DEFAULT; +select str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20'; +str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20' +1 +Warnings: +Warning 1292 Truncated incorrect datetime value: '' +select str_to_date('','%Y-%m-%d') between '2007/10/01' and '2007/10/20'; +str_to_date('','%Y-%m-%d') between '2007/10/01' and '2007/10/20' +0 +select str_to_date('','%Y-%m-%d %H:%i') = '2007-10-01 12:34'; +str_to_date('','%Y-%m-%d %H:%i') = '2007-10-01 12:34' +0 +select str_to_date(NULL,'%Y-%m-%d %H:%i') = '2007-10-01 12:34'; +str_to_date(NULL,'%Y-%m-%d %H:%i') = '2007-10-01 12:34' +NULL +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = ''; +str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '' +0 +Warnings: +Warning 1292 Truncated incorrect datetime value: '' +select str_to_date('1','%Y-%m-%d') = '1'; +str_to_date('1','%Y-%m-%d') = '1' +0 +Warnings: +Warning 1292 Truncated incorrect date value: '1' +select str_to_date('1','%Y-%m-%d') = '1'; +str_to_date('1','%Y-%m-%d') = '1' +0 +Warnings: +Warning 1292 Truncated incorrect date value: '1' +select str_to_date('','%Y-%m-%d') = ''; +str_to_date('','%Y-%m-%d') = '' +0 +Warnings: +Warning 1292 Truncated incorrect date value: '' +select str_to_date('1000-01-01','%Y-%m-%d') between '0000-00-00' and NULL; +str_to_date('1000-01-01','%Y-%m-%d') between '0000-00-00' and NULL +0 +select str_to_date('1000-01-01','%Y-%m-%d') between NULL and '2000-00-00'; +str_to_date('1000-01-01','%Y-%m-%d') between NULL and '2000-00-00' +0 +select str_to_date('1000-01-01','%Y-%m-%d') between NULL and NULL; +str_to_date('1000-01-01','%Y-%m-%d') between NULL and NULL +0 +CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY); +CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL, +c22 INT DEFAULT NULL, +KEY(c21, c22)); +CREATE TABLE t3 (c31 INT UNSIGNED NOT NULL DEFAULT 0, +c32 INT DEFAULT NULL, +c33 INT NOT NULL, +c34 INT UNSIGNED DEFAULT 0, +KEY (c33, c34, c32)); +INSERT INTO t1 values (),(),(),(),(); +INSERT INTO t2 SELECT a.c11, b.c11 FROM t1 a, t1 b; +INSERT INTO t3 VALUES (1, 1, 1, 0), +(2, 2, 0, 0), +(3, 3, 1, 0), +(4, 4, 0, 0), +(5, 5, 1, 0); +SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND +t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND +t3.c33 = 1 AND t2.c22 in (1, 3) +ORDER BY c32; +c32 +1 +1 +3 +3 +5 +5 +SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND +t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND +t3.c33 = 1 AND t2.c22 in (1, 3) +ORDER BY c32 DESC; +c32 +5 +5 +3 +3 +1 +1 +DROP TABLE t1, t2, t3; + +# +# Bug#30736: Row Size Too Large Error Creating a Table and +# Inserting Data. +# +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; + +CREATE TABLE t1( +c1 DECIMAL(10, 2), +c2 FLOAT); + +INSERT INTO t1 VALUES (0, 1), (2, 3), (4, 5); + +CREATE TABLE t2( +c3 DECIMAL(10, 2)) +SELECT +c1 * c2 AS c3 +FROM t1; + +SELECT * FROM t1; +c1 c2 +0.00 1 +2.00 3 +4.00 5 + +SELECT * FROM t2; +c3 +0.00 +6.00 +20.00 + +DROP TABLE t1; +DROP TABLE t2; + +CREATE TABLE t1 (c1 BIGINT NOT NULL); +INSERT INTO t1 (c1) VALUES (1); +SELECT * FROM t1 WHERE c1 > NULL + 1; +c1 +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(10) NOT NULL PRIMARY KEY); +INSERT INTO t1 (a) VALUES ('foo0'), ('bar0'), ('baz0'); +SELECT * FROM t1 WHERE a IN (CONCAT('foo', 0), 'bar'); +a +foo0 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT, c INT, KEY(a)); +INSERT INTO t1 VALUES (1, 1), (2, 2); +INSERT INTO t2 VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), +(2, 1), (2, 2), (2, 3), (2, 4), (2, 5), +(3, 1), (3, 2), (3, 3), (3, 4), (3, 5), +(4, 1), (4, 2), (4, 3), (4, 4), (4, 5); +FLUSH STATUS; +SELECT DISTINCT b FROM t1 LEFT JOIN t2 USING(a) WHERE c <= 3; +b +1 +2 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 2 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 6 +DROP TABLE t1, t2; +CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0', +f2 int(11) NOT NULL default '0', +f3 bigint(20) NOT NULL default '0', +f4 varchar(255) NOT NULL default '', +PRIMARY KEY (f1), +KEY key1 (f4), +KEY key2 (f2)); +CREATE TABLE t2 (f1 int(11) NOT NULL default '0', +f2 enum('A1','A2','A3') NOT NULL default 'A1', +f3 int(11) NOT NULL default '0', +PRIMARY KEY (f1), +KEY key1 (f3)); +CREATE TABLE t3 (f1 bigint(20) NOT NULL default '0', +f2 datetime NOT NULL default '1980-01-01 00:00:00', +PRIMARY KEY (f1)); +insert into t1 values (1, 1, 1, 'abc'); +insert into t1 values (2, 1, 2, 'def'); +insert into t1 values (3, 1, 2, 'def'); +insert into t2 values (1, 'A1', 1); +insert into t3 values (1, '1980-01-01'); +SELECT a.f3, cr.f4, count(*) count +FROM t2 a +STRAIGHT_JOIN t1 cr ON cr.f2 = a.f1 +LEFT JOIN +(t1 cr2 +JOIN t3 ae2 ON cr2.f3 = ae2.f1 +) ON a.f1 = cr2.f2 AND ae2.f2 < now() - INTERVAL 7 DAY AND +cr.f4 = cr2.f4 +GROUP BY a.f3, cr.f4; +f3 f4 count +1 abc 1 +1 def 2 +drop table t1, t2, t3; +CREATE TABLE t1 (a INT KEY, b INT); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4); +EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2 +EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2 +DROP TABLE t1; +# +# Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when +# forcing a spatial index +# +CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a)); +INSERT INTO t1 VALUES +(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')), +(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')); +EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL a NULL NULL NULL 2 +SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2; +1 +1 +1 +1 +1 +EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL a NULL NULL NULL 2 +SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a); +1 +1 +1 +1 +1 +DROP TABLE t1; +# +# Bug #48291 : crash with row() operator,select into @var, and +# subquery returning multiple rows +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (2),(3); +# Should not crash +SELECT 1 FROM t1 WHERE a <> 1 AND NOT +ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1)) +INTO @var0; +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1; +# +# Bug #48458: simple query tries to allocate enormous amount of +# memory +# +CREATE TABLE t1(a INT NOT NULL, b YEAR); +INSERT INTO t1 VALUES (); +Warnings: +Warning 1364 Field 'a' doesn't have a default value +CREATE TABLE t2(c INT); +# Should not err out because of out-of-memory +SELECT 1 FROM t2 JOIN t1 ON 1=1 +WHERE a != '1' AND NOT a >= b OR NOT ROW(b,a )<> ROW(a,a); +1 +DROP TABLE t1,t2; +# +# Bug #49199: Optimizer handles incorrectly: +# field='const1' AND field='const2' in some cases + +CREATE TABLE t1(a DATETIME NOT NULL); +INSERT INTO t1 VALUES('2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a DATE NOT NULL); +INSERT INTO t1 VALUES('2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +a +2001-01-01 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select '2001-01-01' AS `a` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a TIMESTAMP NOT NULL); +INSERT INTO t1 VALUES('2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL); +INSERT INTO t1 VALUES('2001-01-01', '2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +a b +2001-01-01 00:00:00 2001-01-01 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a DATETIME NOT NULL, b VARCHAR(20) NOT NULL); +INSERT INTO t1 VALUES('2001-01-01', '2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +a b +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 0 +SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01'; +a b +2001-01-01 00:00:00 2001-01-01 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL); +INSERT INTO t1 VALUES('2001-01-01', '2001-01-01'); +SELECT x.a, y.a, z.a FROM t1 x +JOIN t1 y ON x.a=y.a +JOIN t1 z ON y.a=z.a +WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00'; +a a a +2001-01-01 00:00:00 2001-01-01 00:00:00 2001-01-01 00:00:00 +EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x +JOIN t1 y ON x.a=y.a +JOIN t1 z ON y.a=z.a +WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE x system NULL NULL NULL NULL 1 100.00 +1 SIMPLE y system NULL NULL NULL NULL 1 100.00 +1 SIMPLE z system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a` from `test`.`t1` `x` join `test`.`t1` `y` join `test`.`t1` `z` where 1 +DROP TABLE t1; +# +# Bug #49897: crash in ptr_compare when char(0) NOT NULL +# column is used for ORDER BY +# +SET @old_sort_buffer_size= @@session.sort_buffer_size; +SET @@sort_buffer_size= 40000; +CREATE TABLE t1(a CHAR(0) NOT NULL); +INSERT INTO t1 VALUES (0), (0), (0); +INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12; +EXPLAIN SELECT a FROM t1 ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 +SELECT a FROM t1 ORDER BY a; +DROP TABLE t1; +CREATE TABLE t1(a CHAR(0) NOT NULL, b CHAR(0) NOT NULL, c int); +INSERT INTO t1 VALUES (0, 0, 0), (0, 0, 2), (0, 0, 1); +INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12; +EXPLAIN SELECT a FROM t1 ORDER BY a LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 +SELECT a FROM t1 ORDER BY a LIMIT 5; +a + + + + + +EXPLAIN SELECT * FROM t1 ORDER BY a, b LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 +SELECT * FROM t1 ORDER BY a, b LIMIT 5; +a b c + 0 + 2 + 1 + 0 + 2 +EXPLAIN SELECT * FROM t1 ORDER BY a, b, c LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort +SELECT * FROM t1 ORDER BY a, b, c LIMIT 5; +a b c + 0 + 0 + 0 + 0 + 0 +EXPLAIN SELECT * FROM t1 ORDER BY c, a LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort +SELECT * FROM t1 ORDER BY c, a LIMIT 5; +a b c + 0 + 0 + 0 + 0 + 0 +SET @@sort_buffer_size= @old_sort_buffer_size; +DROP TABLE t1; +End of 5.0 tests +create table t1(a INT, KEY (a)); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +SELECT a FROM t1 ORDER BY a LIMIT 2; +a +1 +2 +SELECT a FROM t1 ORDER BY a LIMIT 2,4294967296; +a +3 +4 +5 +SELECT a FROM t1 ORDER BY a LIMIT 2,4294967297; +a +3 +4 +5 +DROP TABLE t1; +CREATE TABLE A (date_key date); +CREATE TABLE C ( +pk int, +int_nokey int, +int_key int, +date_key date NOT NULL, +date_nokey date, +varchar_key varchar(1) +); +INSERT INTO C VALUES +(1,1,1,'0000-00-00',NULL,NULL), +(1,1,1,'0000-00-00',NULL,NULL); +SELECT 1 FROM C WHERE pk > ANY (SELECT 1 FROM C); +1 +SELECT COUNT(DISTINCT 1) FROM C +WHERE date_key = (SELECT 1 FROM A WHERE C.date_key IS NULL) GROUP BY pk; +COUNT(DISTINCT 1) +SELECT date_nokey FROM C +WHERE int_key IN (SELECT 1 FROM A) +HAVING date_nokey = '10:41:7' +ORDER BY date_key; +date_nokey +Warnings: +Warning 1292 Incorrect date value: '10:41:7' for column 'date_nokey' at row 1 +DROP TABLE A,C; +CREATE TABLE t1 (a INT NOT NULL, b INT); +INSERT INTO t1 VALUES (1, 1); +EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a) OR b > 2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select '1' AS `a`,'1' AS `b` from `test`.`t1` where 1 +SELECT * FROM t1 WHERE (a=a AND a=a) OR b > 2; +a b +1 1 +DROP TABLE t1; +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL); +EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND c=c) OR b > 20; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found +Warnings: +Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a AND b=b) OR b > 20; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found +Warnings: +Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND a=a) OR b > 20; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found +Warnings: +Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1 +DROP TABLE t1; +# +# Bug#45266: Uninitialized variable lead to an empty result. +# +drop table if exists A,AA,B,BB; +CREATE TABLE `A` ( +`pk` int(11) NOT NULL AUTO_INCREMENT, +`date_key` date NOT NULL, +`date_nokey` date NOT NULL, +`datetime_key` datetime NOT NULL, +`int_nokey` int(11) NOT NULL, +`time_key` time NOT NULL, +`time_nokey` time NOT NULL, +PRIMARY KEY (`pk`), +KEY `date_key` (`date_key`), +KEY `time_key` (`time_key`), +KEY `datetime_key` (`datetime_key`) +); +CREATE TABLE `AA` ( +`pk` int(11) NOT NULL AUTO_INCREMENT, +`int_nokey` int(11) NOT NULL, +`time_key` time NOT NULL, +KEY `time_key` (`time_key`), +PRIMARY KEY (`pk`) +); +CREATE TABLE `B` ( +`date_nokey` date NOT NULL, +`date_key` date NOT NULL, +`time_key` time NOT NULL, +`datetime_nokey` datetime NOT NULL, +`varchar_key` varchar(1) NOT NULL, +KEY `date_key` (`date_key`), +KEY `time_key` (`time_key`), +KEY `varchar_key` (`varchar_key`) +); +INSERT INTO `B` VALUES ('2003-07-28','2003-07-28','15:13:38','0000-00-00 00:00:00','f'),('0000-00-00','0000-00-00','00:05:48','2004-07-02 14:34:13','x'); +CREATE TABLE `BB` ( +`pk` int(11) NOT NULL AUTO_INCREMENT, +`int_nokey` int(11) NOT NULL, +`date_key` date NOT NULL, +`varchar_nokey` varchar(1) NOT NULL, +`date_nokey` date NOT NULL, +PRIMARY KEY (`pk`), +KEY `date_key` (`date_key`) +); +INSERT INTO `BB` VALUES (10,8,'0000-00-00','i','0000-00-00'),(11,0,'2005-08-18','','2005-08-18'); +SELECT table1 . `pk` AS field1 +FROM +(BB AS table1 INNER JOIN +(AA AS table2 STRAIGHT_JOIN A AS table3 +ON ( table3 . `date_key` = table2 . `pk` )) +ON ( table3 . `datetime_key` = table2 . `int_nokey` )) +WHERE ( table3 . `date_key` <= 4 AND table2 . `pk` = table1 . `varchar_nokey`) +GROUP BY field1 ; +field1 +SELECT table3 .`date_key` field1 +FROM +B table1 LEFT JOIN B table3 JOIN +(BB table6 JOIN A table7 ON table6 .`varchar_nokey`) +ON table6 .`int_nokey` ON table6 .`date_key` + WHERE NOT ( table1 .`varchar_key` AND table7 .`pk`) GROUP BY field1; +field1 +NULL +SELECT table4 . `time_nokey` AS field1 FROM +(AA AS table1 CROSS JOIN +(AA AS table2 STRAIGHT_JOIN +(B AS table3 STRAIGHT_JOIN A AS table4 +ON ( table4 . `date_key` = table3 . `time_key` )) +ON ( table4 . `pk` = table3 . `date_nokey` )) +ON ( table4 . `time_key` = table3 . `datetime_nokey` )) +WHERE ( table4 . `time_key` < table1 . `time_key` AND +table1 . `int_nokey` != 'f') +GROUP BY field1 ORDER BY field1 , field1; +field1 +SELECT table1 .`time_key` field2 FROM B table1 LEFT JOIN BB JOIN A table5 ON table5 .`date_nokey` ON table5 .`int_nokey` GROUP BY field2; +field2 +00:05:48 +15:13:38 +drop table A,AA,B,BB; +#end of test for bug#45266 +# +# BUG#48052: Valgrind warning - uninitialized value in init_read_record() +# +CREATE TABLE t1 ( +pk int(11) NOT NULL, +i int(11) DEFAULT NULL, +v varchar(1) DEFAULT NULL, +PRIMARY KEY (pk) +); +INSERT INTO t1 VALUES (2,7,'m'); +INSERT INTO t1 VALUES (3,9,'m'); +SELECT v +FROM t1 +WHERE NOT pk > 0 +HAVING v <= 't' +ORDER BY pk; +v +DROP TABLE t1; +# +# Bug#49489 Uninitialized cache led to a wrong result. +# +CREATE TABLE t1(c1 DOUBLE(5,4)); +INSERT INTO t1 VALUES (9.1234); +SELECT * FROM t1 WHERE c1 < 9.12345; +c1 +9.1234 +DROP TABLE t1; +# End of test for bug#49489. +# +# Bug #49517: Inconsistent behavior while using +# NULLable BIGINT and INT columns in comparison +# +CREATE TABLE t1(a BIGINT UNSIGNED NOT NULL, b BIGINT NULL, c INT NULL); +INSERT INTO t1 VALUES(105, NULL, NULL); +SELECT * FROM t1 WHERE b < 102; +a b c +SELECT * FROM t1 WHERE c < 102; +a b c +SELECT * FROM t1 WHERE 102 < b; +a b c +SELECT * FROM t1 WHERE 102 < c; +a b c +DROP TABLE t1; +# +# Bug #54459: Assertion failed: param.sort_length, +# file .\filesort.cc, line 149 (part II) +# +CREATE TABLE t1(a ENUM('') NOT NULL); +INSERT INTO t1 VALUES (), (), (); +EXPLAIN SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; +1 +1 +1 +1 +DROP TABLE t1; +# +# Bug #702310: usage of 2 join buffers after ref access to an empty table +# +CREATE TABLE t1 (f1 int) ; +INSERT INTO t1 VALUES (9); +CREATE TABLE t2 (f1 int); +INSERT INTO t2 VALUES (3),(7),(18); +INSERT INTO t2 VALUES (3),(7),(18); +INSERT INTO t2 VALUES (3),(7),(18); +INSERT INTO t2 VALUES (3),(7),(18); +CREATE TABLE t3 (f1 int); +INSERT INTO t3 VALUES (17); +CREATE TABLE t4 (f1 int PRIMARY KEY, f2 varchar(1024)) ; +CREATE TABLE t5 (f1 int) ; +INSERT INTO t5 VALUES (20),(5); +CREATE TABLE t6(f1 int); +INSERT INTO t6 VALUES (9),(7); +SET SESSION join_buffer_size = 9000; +EXPLAIN +SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +1 SIMPLE t2 ALL NULL NULL NULL NULL 12 +1 SIMPLE t3 ALL NULL NULL NULL NULL 1 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 const 1 +1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer +1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer +SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; +f1 f1 f1 f1 f2 f1 f1 +3 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 20 9 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 20 9 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 20 9 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 20 9 +18 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +SET SESSION join_buffer_size = DEFAULT; +DROP TABLE t1,t2,t3,t4,t5,t6; +End of 5.1 tests diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index f5ed4fbd901..97af1ef7244 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6940,9 +6940,8 @@ create procedure p() begin end; call p(); select @@sql_mode; @@sql_mode -REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH +REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH set @@sql_mode= @old_mode; -select replace(@full_mode, '?', 'NOT_USED') into @full_mode; select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; select name from mysql.proc where name = 'p' and sql_mode = @full_mode; name diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result index b21395d9623..880531f4b47 100644 --- a/mysql-test/r/sp_notembedded.result +++ b/mysql-test/r/sp_notembedded.result @@ -191,6 +191,8 @@ max_updates, max_connections, max_user_connections) VALUES('%', 'mysqltest_1', password(''), 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', 'N', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', 'Y', 'Y', 'N', '', '', '', '', '0', '0', '0', '0'); +Warnings: +Warning 1364 Field 'auth_string' doesn't have a default value FLUSH PRIVILEGES; CREATE PROCEDURE p1(i INT) BEGIN END; DROP PROCEDURE p1; diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result new file mode 100644 index 00000000000..636eeabfffc --- /dev/null +++ b/mysql-test/r/status_user.result @@ -0,0 +1,186 @@ +DROP TABLE IF EXISTS t1; +select variable_value from information_schema.global_status where variable_name="handler_read_key" into @global_read_key; +show columns from information_schema.client_statistics; +Field Type Null Key Default Extra +CLIENT varchar(64) NO +TOTAL_CONNECTIONS bigint(21) NO 0 +CONCURRENT_CONNECTIONS bigint(21) NO 0 +CONNECTED_TIME bigint(21) NO 0 +BUSY_TIME double NO 0 +CPU_TIME double NO 0 +BYTES_RECEIVED bigint(21) NO 0 +BYTES_SENT bigint(21) NO 0 +BINLOG_BYTES_WRITTEN bigint(21) NO 0 +ROWS_READ bigint(21) NO 0 +ROWS_SENT bigint(21) NO 0 +ROWS_DELETED bigint(21) NO 0 +ROWS_INSERTED bigint(21) NO 0 +ROWS_UPDATED bigint(21) NO 0 +SELECT_COMMANDS bigint(21) NO 0 +UPDATE_COMMANDS bigint(21) NO 0 +OTHER_COMMANDS bigint(21) NO 0 +COMMIT_TRANSACTIONS bigint(21) NO 0 +ROLLBACK_TRANSACTIONS bigint(21) NO 0 +DENIED_CONNECTIONS bigint(21) NO 0 +LOST_CONNECTIONS bigint(21) NO 0 +ACCESS_DENIED bigint(21) NO 0 +EMPTY_QUERIES bigint(21) NO 0 +show columns from information_schema.user_statistics; +Field Type Null Key Default Extra +USER varchar(48) NO +TOTAL_CONNECTIONS int(11) NO 0 +CONCURRENT_CONNECTIONS int(11) NO 0 +CONNECTED_TIME int(11) NO 0 +BUSY_TIME double NO 0 +CPU_TIME double NO 0 +BYTES_RECEIVED bigint(21) NO 0 +BYTES_SENT bigint(21) NO 0 +BINLOG_BYTES_WRITTEN bigint(21) NO 0 +ROWS_READ bigint(21) NO 0 +ROWS_SENT bigint(21) NO 0 +ROWS_DELETED bigint(21) NO 0 +ROWS_INSERTED bigint(21) NO 0 +ROWS_UPDATED bigint(21) NO 0 +SELECT_COMMANDS bigint(21) NO 0 +UPDATE_COMMANDS bigint(21) NO 0 +OTHER_COMMANDS bigint(21) NO 0 +COMMIT_TRANSACTIONS bigint(21) NO 0 +ROLLBACK_TRANSACTIONS bigint(21) NO 0 +DENIED_CONNECTIONS bigint(21) NO 0 +LOST_CONNECTIONS bigint(21) NO 0 +ACCESS_DENIED bigint(21) NO 0 +EMPTY_QUERIES bigint(21) NO 0 +show columns from information_schema.index_statistics; +Field Type Null Key Default Extra +TABLE_SCHEMA varchar(192) NO +TABLE_NAME varchar(192) NO +INDEX_NAME varchar(192) NO +ROWS_READ bigint(21) NO 0 +show columns from information_schema.table_statistics; +Field Type Null Key Default Extra +TABLE_SCHEMA varchar(192) NO +TABLE_NAME varchar(192) NO +ROWS_READ bigint(21) NO 0 +ROWS_CHANGED bigint(21) NO 0 +ROWS_CHANGED_X_INDEXES bigint(21) NO 0 +set @save_general_log=@@global.general_log; +set @@global.general_log=0; +set @@global.userstat=1; +flush status; +create table t1 (a int, primary key (a), b int default 0) engine=innodb; +insert into t1 (a) values (1),(2),(3),(4); +update t1 set b=1; +update t1 set b=5 where a=2; +delete from t1 where a=3; +/* Empty query */ +select * from t1 where a=999; +a b +drop table t1; +create table t1 (a int, primary key (a), b int default 0) engine=innodb; +begin; +insert into t1 values(1,1); +commit; +begin; +insert into t1 values(2,2); +commit; +begin; +insert into t1 values(3,3); +rollback; +drop table t1; +select sleep(1); +sleep(1) +0 +show status like "rows%"; +Variable_name Value +Rows_read 6 +Rows_sent 1 +show status like "ha%"; +Variable_name Value +Handler_commit 19 +Handler_delete 1 +Handler_discover 0 +Handler_prepare 18 +Handler_read_first 0 +Handler_read_key 3 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 5 +Handler_rollback 2 +Handler_savepoint 0 +Handler_savepoint_rollback 0 +Handler_update 5 +Handler_write 7 +select variable_value - @global_read_key as "handler_read_key" from information_schema.global_status where variable_name="handler_read_key"; +handler_read_key +3 +set @@global.userstat=0; +select * from information_schema.index_statistics; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +test t1 PRIMARY 2 +select * from information_schema.table_statistics; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +test t1 6 13 13 +show table_statistics; +Table_schema Table_name Rows_read Rows_changed Rows_changed_x_#indexes +test t1 6 13 13 +show index_statistics; +Table_schema Table_name Index_name Rows_read +test t1 PRIMARY 2 +select TOTAL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, OTHER_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.client_statistics;; +TOTAL_CONNECTIONS 1 +CONCURRENT_CONNECTIONS 0 +ROWS_READ 6 +ROWS_SENT 2 +ROWS_DELETED 1 +ROWS_INSERTED 8 +ROWS_UPDATED 5 +SELECT_COMMANDS 3 +UPDATE_COMMANDS 11 +OTHER_COMMANDS 7 +COMMIT_TRANSACTIONS 19 +ROLLBACK_TRANSACTIONS 2 +DENIED_CONNECTIONS 0 +LOST_CONNECTIONS 0 +ACCESS_DENIED 0 +EMPTY_QUERIES 1 +select TOTAL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, OTHER_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.user_statistics;; +TOTAL_CONNECTIONS 1 +CONCURRENT_CONNECTIONS 0 +ROWS_READ 6 +ROWS_SENT 2 +ROWS_DELETED 1 +ROWS_INSERTED 8 +ROWS_UPDATED 5 +SELECT_COMMANDS 3 +UPDATE_COMMANDS 11 +OTHER_COMMANDS 7 +COMMIT_TRANSACTIONS 19 +ROLLBACK_TRANSACTIONS 2 +DENIED_CONNECTIONS 0 +LOST_CONNECTIONS 0 +ACCESS_DENIED 0 +EMPTY_QUERIES 1 +flush table_statistics; +flush index_statistics; +select * from information_schema.index_statistics; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +select * from information_schema.table_statistics; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +show status like "%statistics%"; +Variable_name Value +Com_show_client_statistics 0 +Com_show_index_statistics 1 +Com_show_table_statistics 1 +Com_show_user_statistics 0 +select connected_time <> 0, busy_time <> 0, bytes_received <> 0, +bytes_sent <> 0, binlog_bytes_written <> 0 +from information_schema.user_statistics; +connected_time <> 0 busy_time <> 0 bytes_received <> 0 bytes_sent <> 0 binlog_bytes_written <> 0 +1 1 1 1 1 +select connected_time <> 0, busy_time <> 0, bytes_received <> 0, +bytes_sent <> 0, binlog_bytes_written <> 0 +from information_schema.client_statistics; +connected_time <> 0 busy_time <> 0 bytes_received <> 0 bytes_sent <> 0 binlog_bytes_written <> 0 +1 1 1 1 1 +set @@global.general_log=@save_general_log; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 909af13b6c6..1a56940a560 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -270,7 +270,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)) select * from t3 where a >= all (select b from t2); a 7 @@ -908,6 +908,131 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1` drop table t1,t2,t3; +# check correct NULL Processing for normal IN/ALL/ANY +# and 2 ways of max/min optimization +create table t1 (a int); +insert into t1 values (1), (100), (NULL), (1000); +create table t2 (a int not null); +# subselect returns empty set (for NULL and non-NULL left part) +select a, a in (select * from t2) from t1; +a a in (select * from t2) +1 0 +100 0 +NULL 0 +1000 0 +select a, a > any (select * from t2) from t1; +a a > any (select * from t2) +1 0 +100 0 +NULL 0 +1000 0 +select a, a > all (select * from t2) from t1; +a a > all (select * from t2) +1 1 +100 1 +NULL 1 +1000 1 +select a from t1 where a in (select * from t2); +a +select a from t1 where a > any (select * from t2); +a +select a from t1 where a > all (select * from t2); +a +1 +100 +NULL +1000 +select a from t1 where a in (select * from t2 group by a); +a +select a from t1 where a > any (select * from t2 group by a); +a +select a from t1 where a > all (select * from t2 group by a); +a +1 +100 +NULL +1000 +insert into t2 values (1),(200); +# sebselect returns non-empty set without NULLs +select a, a in (select * from t2) from t1; +a a in (select * from t2) +1 1 +100 0 +NULL NULL +1000 0 +select a, a > any (select * from t2) from t1; +a a > any (select * from t2) +1 0 +100 1 +NULL NULL +1000 1 +select a, a > all (select * from t2) from t1; +a a > all (select * from t2) +1 0 +100 0 +NULL NULL +1000 1 +select a from t1 where a in (select * from t2); +a +1 +select a from t1 where a > any (select * from t2); +a +100 +1000 +select a from t1 where a > all (select * from t2); +a +1000 +select a from t1 where a in (select * from t2 group by a); +a +1 +select a from t1 where a > any (select * from t2 group by a); +a +100 +1000 +select a from t1 where a > all (select * from t2 group by a); +a +1000 +drop table t2; +create table t2 (a int); +insert into t2 values (1),(NULL),(200); +# sebselect returns non-empty set with NULLs +select a, a in (select * from t2) from t1; +a a in (select * from t2) +1 1 +100 NULL +NULL NULL +1000 NULL +select a, a > any (select * from t2) from t1; +a a > any (select * from t2) +1 NULL +100 1 +NULL NULL +1000 1 +select a, a > all (select * from t2) from t1; +a a > all (select * from t2) +1 0 +100 0 +NULL NULL +1000 NULL +select a from t1 where a in (select * from t2); +a +1 +select a from t1 where a > any (select * from t2); +a +100 +1000 +select a from t1 where a > all (select * from t2); +a +select a from t1 where a in (select * from t2 group by a); +a +1 +select a from t1 where a > any (select * from t2 group by a); +a +100 +1000 +select a from t1 where a > all (select * from t2 group by a); +a +drop table t1, t2; create table t1 (a float); select 10.5 IN (SELECT * from t1 LIMIT 1); ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' @@ -1407,7 +1532,7 @@ INSERT INTO t1 VALUES ('z','?'); select * from t1 where s1 > (select max(s2) from t1); ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>' select * from t1 where s1 > any (select max(s2) from t1); -ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>' +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<' drop table t1; create table t1(toid int,rd int); create table t2(userid int,pmnew int,pmtotal int); @@ -1483,7 +1608,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1` drop table t1,t2; -create table t2 (a int, b int); +create table t2 (a int, b int not null); create table t3 (a int); insert into t3 values (6),(7),(3); select * from t3 where a >= all (select b from t2); @@ -1496,7 +1621,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(((select max(NULL) from `test`.`t2`) > `test`.`t3`.`a`)) select * from t3 where a >= some (select b from t2); a explain extended select * from t3 where a >= some (select b from t2); @@ -1504,7 +1629,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(((select min(NULL) from `test`.`t2`) <= `test`.`t3`.`a`)) select * from t3 where a >= all (select b from t2 group by 1); a 6 @@ -1515,7 +1640,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((<max>(select NULL from `test`.`t2` group by 1) > `test`.`t3`.`a`)) select * from t3 where a >= some (select b from t2 group by 1); a explain extended select * from t3 where a >= some (select b from t2 group by 1); @@ -1523,13 +1648,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((<min>(select NULL from `test`.`t2` group by 1) <= `test`.`t3`.`a`)) select * from t3 where NULL >= any (select b from t2); a explain extended select * from t3 where NULL >= any (select b from t2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table Warnings: Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0 select * from t3 where NULL >= any (select b from t2 group by 1); @@ -1537,7 +1662,7 @@ a explain extended select * from t3 where NULL >= any (select b from t2 group by 1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table Warnings: Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0 select * from t3 where NULL >= some (select b from t2); @@ -1545,7 +1670,7 @@ a explain extended select * from t3 where NULL >= some (select b from t2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table Warnings: Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0 select * from t3 where NULL >= some (select b from t2 group by 1); @@ -1553,7 +1678,7 @@ a explain extended select * from t3 where NULL >= some (select b from t2 group by 1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table Warnings: Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0 insert into t2 values (2,2), (2,1), (3,3), (3,1); @@ -1566,7 +1691,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary; Using filesort Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`a`)) drop table t2, t3; CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ; INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now()); @@ -4805,3 +4930,164 @@ SELECT 1 as foo FROM t1 WHERE a < SOME ); foo DROP TABLE t1; +CREATE TABLE t1 (a int(11), b varchar(1)); +INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g'); +SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 ); +a +5 +SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b ); +a +7 +SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 ); +a +7 +SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +7 +SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 ); +a +5 +7 +SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +7 +SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 ); +a +5 +7 +SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 ); +a +5 +7 +SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +7 +SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 ); +a +5 +7 +SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +7 +SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b ); +a +delete from t1; +INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g'); +SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 ); +a +5 +SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b ); +a +7 +SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 ); +a +7 +SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +7 +SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 ); +a +5 +7 +SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +7 +SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 ); +a +5 +7 +SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 ); +a +5 +7 +SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +7 +SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 ); +a +5 +7 +SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b ); +a +5 +7 +SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b ); +a +SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 ); +a +SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b ); +a +drop table t1; +# +# Fix of LP BUG#780386 (NULL left part with empty ALL subquery). +# +CREATE TABLE t1 ( f11 int) ; +INSERT IGNORE INTO t1 VALUES (0),(0); +CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ; +INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0); +DROP TABLE IF EXISTS t3; +Warnings: +Note 1051 Unknown table 't3' +CREATE TABLE t3 ( f3 int) ; +INSERT INTO t3 VALUES (0),(0); +SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ; +r +NULL +5 +NULL +5 +DROP TABLE t1, t2, t3; +End of 5.2 tests diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index 17fd95ab1c8..aa407b25401 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -118,6 +118,8 @@ user CREATE TABLE `user` ( `max_updates` int(11) unsigned NOT NULL DEFAULT '0', `max_connections` int(11) unsigned NOT NULL DEFAULT '0', `max_user_connections` int(11) unsigned NOT NULL DEFAULT '0', + `plugin` char(60) CHARACTER SET latin1 NOT NULL DEFAULT '', + `auth_string` text COLLATE utf8_bin NOT NULL, PRIMARY KEY (`Host`,`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges' show create table func; @@ -200,7 +202,7 @@ proc CREATE TABLE `proc` ( `definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', - `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '', + `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '', `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, @@ -225,7 +227,7 @@ event CREATE TABLE `event` ( `ends` datetime DEFAULT NULL, `status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED', `on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP', - `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '', + `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '', `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `originator` int(10) unsigned NOT NULL, `time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', diff --git a/mysql-test/r/table_options.result b/mysql-test/r/table_options.result new file mode 100644 index 00000000000..ddb7bd13c03 --- /dev/null +++ b/mysql-test/r/table_options.result @@ -0,0 +1,182 @@ +drop table if exists t1; +SET @OLD_SQL_MODE=@@SQL_MODE; +SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; +create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1='1v1'; +Warnings: +Warning 1652 Unknown option 'fkey' +Warning 1652 Unknown option 'dff' +Warning 1652 Unknown option 'tkey1' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey`=vvv, + KEY `akey` (`a`) `dff`=vvv +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v1' +drop table t1; +#reassiginig options in the same line +create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1; +Warnings: +Warning 1652 Unknown option 'fkey' +Warning 1652 Unknown option 'dff' +Warning 1652 Unknown option 'tkey1' +Warning 1652 Unknown option 'tkey2' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey`=vvv, + KEY `akey` (`a`) `dff`=vvv +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=1v2 `tkey2`=2v1 +#add option +alter table t1 tkey4=4v1; +Warnings: +Warning 1652 Unknown option 'tkey4' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey`=vvv, + KEY `akey` (`a`) `dff`=vvv +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=1v2 `tkey2`=2v1 `tkey4`=4v1 +#remove options +alter table t1 tkey3=DEFAULT tkey4=DEFAULT; +Warnings: +Warning 1652 Unknown option 'tkey3' +Warning 1652 Unknown option 'tkey4' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey`=vvv, + KEY `akey` (`a`) `dff`=vvv +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=1v2 `tkey2`=2v1 +drop table t1; +create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1; +Warnings: +Warning 1652 Unknown option 'fkey1' +Warning 1652 Unknown option 'kkey1' +Warning 1652 Unknown option 'TKEY1' +Warning 1652 Unknown option 'tkey2' +Warning 1652 Unknown option 'tkey3' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey1`=v1, + KEY `akey` (`a`) `kkey1`=v1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +#change field with option with the same value +alter table t1 change a a int `FKEY1`='v1'; +Warnings: +Warning 1652 Unknown option 'FKEY1' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `FKEY1`='v1', + KEY `akey` (`a`) `kkey1`=v1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +#change field with option with a different value +alter table t1 change a a int fkey1=v2; +Warnings: +Warning 1652 Unknown option 'fkey1' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey1`=v2, + KEY `akey` (`a`) `kkey1`=v1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +#new column no options +alter table t1 add column b int; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey1`=v2, + `b` int(11) DEFAULT NULL, + KEY `akey` (`a`) `kkey1`=v1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +#new key with options +alter table t1 add key bkey (b) kkey2=v1; +Warnings: +Warning 1652 Unknown option 'kkey2' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey1`=v2, + `b` int(11) DEFAULT NULL, + KEY `akey` (`a`) `kkey1`=v1, + KEY `bkey` (`b`) `kkey2`=v1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +#new column with options +alter table t1 add column c int fkey1=v1 fkey2=v2; +Warnings: +Warning 1652 Unknown option 'fkey1' +Warning 1652 Unknown option 'fkey2' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey1`=v2, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2, + KEY `akey` (`a`) `kkey1`=v1, + KEY `bkey` (`b`) `kkey2`=v1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +#new key no options +alter table t1 add key ckey (c); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey1`=v2, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2, + KEY `akey` (`a`) `kkey1`=v1, + KEY `bkey` (`b`) `kkey2`=v1, + KEY `ckey` (`c`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +#drop column +alter table t1 drop b; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey1`=v2, + `c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2, + KEY `akey` (`a`) `kkey1`=v1, + KEY `ckey` (`c`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +#add column with options after delete +alter table t1 add column b int fkey2=v1; +Warnings: +Warning 1652 Unknown option 'fkey2' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey1`=v2, + `c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2, + `b` int(11) DEFAULT NULL `fkey2`=v1, + KEY `akey` (`a`) `kkey1`=v1, + KEY `ckey` (`c`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +#add key +alter table t1 add key bkey (b) kkey2=v2; +Warnings: +Warning 1652 Unknown option 'kkey2' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL `fkey1`=v2, + `c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2, + `b` int(11) DEFAULT NULL `fkey2`=v1, + KEY `akey` (`a`) `kkey1`=v1, + KEY `ckey` (`c`), + KEY `bkey` (`b`) `kkey2`=v2 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1 +drop table t1; +create table t1 (a int) tkey1=100; +Warnings: +Warning 1652 Unknown option 'tkey1' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=100 +drop table t1; +#error on unknown option +SET SQL_MODE=''; +create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1; +ERROR HY000: Unknown option 'fkey' +SET @@SQL_MODE=@OLD_SQL_MODE; diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index f5763057bb7..479778deca3 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -2115,3 +2115,22 @@ b DROP DATABASE db1; USE test; End of 5.1 tests. +create table t1 (i int); +create table t2 (i int); +flush tables; +flush status; +CREATE DEFINER=`root`@`localhost` TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW BEGIN DELETE FROM t2 WHERE t2.i = OLD.i; END // +insert into t1 values (1),(2); +insert into t2 values (1),(2); +delete from t1 where i=1; +show status like 'Opened_tables'; +Variable_name Value +Opened_tables 3 +select * from t1; +i +2 +select * from t2; +i +2 +drop table t1,t2; +End of 5.2 tests. diff --git a/mysql-test/r/variables-notembedded.result b/mysql-test/r/variables-notembedded.result index 8056af49090..6089d39780b 100644 --- a/mysql-test/r/variables-notembedded.result +++ b/mysql-test/r/variables-notembedded.result @@ -33,12 +33,12 @@ ERROR HY000: Variable 'log_slave_updates' is a read only variable # SHOW VARIABLES like 'relay_log'; Variable_name Value -relay_log +relay_log mysqld-relay-bin SELECT @@session.relay_log; ERROR HY000: Variable 'relay_log' is a GLOBAL variable SELECT @@global.relay_log; @@global.relay_log -NULL +mysqld-relay-bin SET @@session.relay_log= 'x'; ERROR HY000: Variable 'relay_log' is a read only variable SET @@global.relay_log= 'x'; @@ -46,12 +46,12 @@ ERROR HY000: Variable 'relay_log' is a read only variable # SHOW VARIABLES like 'relay_log_index'; Variable_name Value -relay_log_index +relay_log_index mysqld-relay-bin.index SELECT @@session.relay_log_index; ERROR HY000: Variable 'relay_log_index' is a GLOBAL variable SELECT @@global.relay_log_index; @@global.relay_log_index -NULL +mysqld-relay-bin.index SET @@session.relay_log_index= 'x'; ERROR HY000: Variable 'relay_log_index' is a read only variable SET @@global.relay_log_index= 'x'; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index b62fc7e0a8c..eaecde5613e 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -27,6 +27,7 @@ set @my_thread_cache_size =@@global.thread_cache_size; set @my_max_allowed_packet =@@global.max_allowed_packet; set @my_delay_key_write =@@global.delay_key_write; set @my_join_buffer_size =@@global.join_buffer_size; +set @my_log_warnings =@@global.log_warnings; set @`test`=1; select @test, @`test`, @TEST, @`TEST`, @"teSt"; @test @`test` @TEST @`TEST` @"teSt" @@ -1064,6 +1065,7 @@ set global thread_cache_size =@my_thread_cache_size; set global max_allowed_packet = default; set global delay_key_write =@my_delay_key_write; set global join_buffer_size =@my_join_buffer_size; +set global log_warnings =@my_log_warnings; show global variables where Variable_name='table_definition_cache' or Variable_name='table_lock_wait_timeout'; Variable_name Value diff --git a/mysql-test/std_data/loaddata7.dat b/mysql-test/std_data/loaddata7.dat new file mode 100644 index 00000000000..e86d1621bd4 --- /dev/null +++ b/mysql-test/std_data/loaddata7.dat @@ -0,0 +1,5 @@ +2,2
+3,3
+4,4
+5,5
+6,6
\ No newline at end of file diff --git a/mysql-test/suite/binlog/r/binlog_index.result b/mysql-test/suite/binlog/r/binlog_index.result index 8ada910c974..21a290bfc3b 100644 --- a/mysql-test/suite/binlog/r/binlog_index.result +++ b/mysql-test/suite/binlog/r/binlog_index.result @@ -15,6 +15,7 @@ master-bin.000001 # master-bin.000002 # master-bin.000003 # master-bin.000004 # +flush tables; purge binary logs TO 'master-bin.000004'; Warnings: Warning 1612 Being purged log master-bin.000001 was not found diff --git a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result new file mode 100644 index 00000000000..5e48f13932d --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result @@ -0,0 +1,414 @@ +DROP DATABASE IF EXISTS test1; +DROP DATABASE IF EXISTS test2; +DROP DATABASE IF EXISTS test3; +CREATE DATABASE test1; +CREATE DATABASE test2; +CREATE DATABASE test3; +SET timestamp=1000000000; +RESET MASTER; +USE test1; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1),(2,2); +USE test2; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1),(2); +DELETE FROM test1.t1 WHERE a=1; +USE test3; +CREATE TABLE t3 (a INT); +INSERT INTO t3 VALUES (1),(2); +INSERT INTO test1.t1 VALUES (3,3); +USE test1; +LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE t1 +FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n'; +DELETE FROM test3.t3 WHERE a=1; +flush logs; +# +# mysqlbinlog output +# --base64-output = decode-rows +# --rewrite-db = test1->new_test1 +# --rewrite-db = test3->new_test3 +# +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup +ROLLBACK/*!*/; +# at # +use new_test1/*!*/; +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +SET @@session.pseudo_thread_id=#/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.sql_mode=0/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +CREATE TABLE t1 (a INT, b INT) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO new_test1.t1 +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### @2=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### @2=2 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +use test2/*!*/; +SET TIMESTAMP=1000000000/*!*/; +CREATE TABLE t2 (a INT) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO test2.t2 +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO test2.t2 +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +### DELETE FROM new_test1.t1 +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### @2=1 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +use new_test3/*!*/; +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE TABLE t3 (a INT) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test3`.`t3` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO new_test3.t3 +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test3.t3 +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO new_test1.t1 +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +### @2=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO new_test1.t1 +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### @2=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +### @2=3 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=4 /* INT meta=0 nullable=1 is_null=0 */ +### @2=4 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=5 /* INT meta=0 nullable=1 is_null=0 */ +### @2=5 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=6 /* INT meta=0 nullable=1 is_null=0 */ +### @2=6 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test3`.`t3` mapped to number # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +### DELETE FROM new_test3.t3 +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +# +# mysqlbinlog output +# --base64-output = decode-rows +# --rewrite-db = test1->new_test1 +# --rewrite-db = test3->new_test3 +# --read-from-remote-server +# +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup +ROLLBACK/*!*/; +# at # +use new_test1/*!*/; +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +SET @@session.pseudo_thread_id=#/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.sql_mode=0/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +CREATE TABLE t1 (a INT, b INT) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO new_test1.t1 +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### @2=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### @2=2 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +use test2/*!*/; +SET TIMESTAMP=1000000000/*!*/; +CREATE TABLE t2 (a INT) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO test2.t2 +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO test2.t2 +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +### DELETE FROM new_test1.t1 +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### @2=1 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +use new_test3/*!*/; +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE TABLE t3 (a INT) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test3`.`t3` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO new_test3.t3 +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test3.t3 +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO new_test1.t1 +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +### @2=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO new_test1.t1 +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### @2=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +### @2=3 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=4 /* INT meta=0 nullable=1 is_null=0 */ +### @2=4 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=5 /* INT meta=0 nullable=1 is_null=0 */ +### @2=5 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO new_test1.t1 +### SET +### @1=6 /* INT meta=0 nullable=1 is_null=0 */ +### @2=6 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `new_test3`.`t3` mapped to number # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +### DELETE FROM new_test3.t3 +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +DROP DATABASE test1; +DROP DATABASE test2; +DROP DATABASE test3; diff --git a/mysql-test/suite/binlog/t/binlog_delete_and_flush_index-master.opt b/mysql-test/suite/binlog/t/binlog_delete_and_flush_index-master.opt new file mode 100644 index 00000000000..434bd66d696 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_delete_and_flush_index-master.opt @@ -0,0 +1 @@ +--log-bin=master-bin --log-bin-index=master-bin diff --git a/mysql-test/suite/binlog/t/binlog_index-master.opt b/mysql-test/suite/binlog/t/binlog_index-master.opt index ff2ad57a9e9..35b2dc04cd1 100644 --- a/mysql-test/suite/binlog/t/binlog_index-master.opt +++ b/mysql-test/suite/binlog/t/binlog_index-master.opt @@ -1 +1 @@ ---force-restart --skip-stack-trace --test-expect-abort --log-warnings=0 +--force-restart --skip-stack-trace --test-expect-abort --log-warnings=0 --log-bin=master-bin --log-bin-index=master-bin diff --git a/mysql-test/suite/binlog/t/binlog_index.test b/mysql-test/suite/binlog/t/binlog_index.test index f38b9b0258c..86c314e9236 100644 --- a/mysql-test/suite/binlog/t/binlog_index.test +++ b/mysql-test/suite/binlog/t/binlog_index.test @@ -33,6 +33,7 @@ flush logs; source include/show_binary_logs.inc; remove_file $MYSQLD_DATADIR/master-bin.000001; +flush tables; # there must be a warning with file names replace_regex /\.[\\\/]master/master/; diff --git a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_options-master.opt b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_options-master.opt new file mode 100644 index 00000000000..4d69f3359db --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_options-master.opt @@ -0,0 +1 @@ +--timezone=GMT-3 diff --git a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_options.test b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_options.test new file mode 100644 index 00000000000..c1756b22eab --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_options.test @@ -0,0 +1,78 @@ +--source include/have_log_bin.inc +--source include/have_binlog_format_row.inc + +# +# MWL36: Add a mysqlbinlog option to change the used database +# (Adding --rewrite-db option) +# +--disable_warnings +DROP DATABASE IF EXISTS test1; +DROP DATABASE IF EXISTS test2; +DROP DATABASE IF EXISTS test3; +--enable_warnings + +# For SBR --rewrite-db affects only default database and doesn't affect +# a query (specifically CREATE DATABASE) itself. Hence (for testing +# purpose) we start binary logging after all databases have been created. + +CREATE DATABASE test1; +CREATE DATABASE test2; +CREATE DATABASE test3; + +# Fix timestamp to avoid varying results. +SET timestamp=1000000000; + +# Delete all existing binary logs. +RESET MASTER; + +# Whe'll call mysqlbinlog with two rewrite rules: +# --rewrite-db="test1->new_test1" +# --rewrite-db="test3->new_test3" + +USE test1; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1),(2,2); + +USE test2; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1),(2); + +DELETE FROM test1.t1 WHERE a=1; + +USE test3; +CREATE TABLE t3 (a INT); +INSERT INTO t3 VALUES (1),(2); +INSERT INTO test1.t1 VALUES (3,3); + +USE test1; +LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE t1
+ FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
+DELETE FROM test3.t3 WHERE a=1; + +flush logs; + +--echo # +--echo # mysqlbinlog output +--echo # --base64-output = decode-rows +--echo # --rewrite-db = test1->new_test1 +--echo # --rewrite-db = test3->new_test3 +--echo # + +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ +--exec $MYSQL_BINLOG --base64-output=decode-rows --rewrite-db="test1->new_test1" --rewrite-db="test3->new_test3" -v -v $MYSQLD_DATADIR/master-bin.000001 + +--echo # +--echo # mysqlbinlog output +--echo # --base64-output = decode-rows +--echo # --rewrite-db = test1->new_test1 +--echo # --rewrite-db = test3->new_test3 +--echo # --read-from-remote-server +--echo # + +--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ +--exec $MYSQL_BINLOG --base64-output=decode-rows --rewrite-db="test1->new_test1" --rewrite-db="test3->new_test3" -v -v --read-from-remote-server --user=root --host=localhost --port=$MASTER_MYPORT master-bin.000001 + +DROP DATABASE test1; +DROP DATABASE test2; +DROP DATABASE test3; diff --git a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning-master.opt b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning-master.opt index 91466bcdea3..2dda40e61c3 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning-master.opt +++ b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning-master.opt @@ -1 +1 @@ ---binlog-ignore-db=b42851 --log-error +--binlog-ignore-db=b42851 --log-error --log-bin=master-bin --log-bin-index=master-bin diff --git a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test index d09f4e433ac..809b03691c7 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test +++ b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test @@ -101,6 +101,7 @@ if(!`select LENGTH('$log_error_')`) # does not know the location of its .err log, use default location let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err; } + # Assign env variable LOG_ERROR let LOG_ERROR=$log_error_; @@ -109,8 +110,9 @@ let LOG_ERROR=$log_error_; perl; use strict; + use Cwd; my $log_error= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set"; - open(FILE, "$log_error") or die("Unable to open $log_error: $!\n"); + open(FILE, "$log_error") or die("Unable to open '$log_error' from directory " . cwd() . "\n"); my $count = () = grep(/Bug#46265/g,<FILE>); print "Occurrences: $count\n"; close(FILE); diff --git a/mysql-test/suite/federated/federated_server.result b/mysql-test/suite/federated/federated_server.result index 05782c6ef81..2c1dd96d612 100644 --- a/mysql-test/suite/federated/federated_server.result +++ b/mysql-test/suite/federated/federated_server.result @@ -54,7 +54,7 @@ PASSWORD '', PORT SLAVE_PORT, SOCKET '', OWNER 'root'); -select * from mysql.servers; +select * from mysql.servers order by db; Server_name Host Db Username Password Port Socket Wrapper Owner server_one 127.0.0.1 first_db root SLAVE_PORT mysql root server_two 127.0.0.1 second_db root SLAVE_PORT mysql root @@ -154,7 +154,7 @@ id name drop table federated.t1; drop server 'server_one'; drop server 'server_two'; -select * from mysql.servers; +select * from mysql.servers order by db; Server_name Host Db Username Password Port Socket Wrapper Owner drop table first_db.t1; drop table second_db.t1; diff --git a/mysql-test/suite/federated/federated_server.test b/mysql-test/suite/federated/federated_server.test index d03c2d26014..ba1df04b62f 100644 --- a/mysql-test/suite/federated/federated_server.test +++ b/mysql-test/suite/federated/federated_server.test @@ -66,7 +66,7 @@ eval create server 'server_two' foreign data wrapper 'mysql' options OWNER 'root'); --replace_result $SLAVE_MYPORT SLAVE_PORT -eval select * from mysql.servers; +eval select * from mysql.servers order by db; DROP TABLE IF EXISTS federated.old; --replace_result $SLAVE_MYPORT SLAVE_PORT @@ -151,7 +151,7 @@ drop table federated.t1; drop server 'server_one'; drop server 'server_two'; -select * from mysql.servers; +select * from mysql.servers order by db; connection slave; drop table first_db.t1; diff --git a/mysql-test/suite/funcs_1/datadict/is_routines.inc b/mysql-test/suite/funcs_1/datadict/is_routines.inc index e6405c8d455..cc0cbdf62fe 100644 --- a/mysql-test/suite/funcs_1/datadict/is_routines.inc +++ b/mysql-test/suite/funcs_1/datadict/is_routines.inc @@ -75,7 +75,7 @@ eval SHOW TABLES FROM information_schema LIKE '$is_table'; --source suite/funcs_1/datadict/datadict_bug_12777.inc eval DESCRIBE information_schema.$is_table; --source suite/funcs_1/datadict/datadict_bug_12777.inc ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" eval SHOW CREATE TABLE information_schema.$is_table; --source suite/funcs_1/datadict/datadict_bug_12777.inc eval SHOW COLUMNS FROM information_schema.$is_table; diff --git a/mysql-test/suite/funcs_1/datadict/is_triggers.inc b/mysql-test/suite/funcs_1/datadict/is_triggers.inc index df3e6e7d2b6..5597bc816fc 100644 --- a/mysql-test/suite/funcs_1/datadict/is_triggers.inc +++ b/mysql-test/suite/funcs_1/datadict/is_triggers.inc @@ -70,7 +70,7 @@ eval SHOW TABLES FROM information_schema LIKE '$is_table'; --source suite/funcs_1/datadict/datadict_bug_12777.inc eval DESCRIBE information_schema.$is_table; --source suite/funcs_1/datadict/datadict_bug_12777.inc ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" eval SHOW CREATE TABLE information_schema.$is_table; --source suite/funcs_1/datadict/datadict_bug_12777.inc eval SHOW COLUMNS FROM information_schema.$is_table; diff --git a/mysql-test/suite/funcs_1/datadict/is_views.inc b/mysql-test/suite/funcs_1/datadict/is_views.inc index b04904c2eba..0ba1aaff3f2 100644 --- a/mysql-test/suite/funcs_1/datadict/is_views.inc +++ b/mysql-test/suite/funcs_1/datadict/is_views.inc @@ -57,7 +57,7 @@ eval SHOW TABLES FROM information_schema LIKE '$is_table'; --source suite/funcs_1/datadict/datadict_bug_12777.inc eval DESCRIBE information_schema.$is_table; --source suite/funcs_1/datadict/datadict_bug_12777.inc ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" eval SHOW CREATE TABLE information_schema.$is_table; --source suite/funcs_1/datadict/datadict_bug_12777.inc eval SHOW COLUMNS FROM information_schema.$is_table; diff --git a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc index 1fffdf014e6..544560ec526 100644 --- a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc +++ b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc @@ -155,7 +155,7 @@ let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE DB = 'information_schema' AND COMMAND = 'Sleep' AND USER = 'ddicttestuser1'; --source include/wait_condition.inc ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" eval SHOW CREATE TABLE $table; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS eval SHOW $table; @@ -175,7 +175,7 @@ connection con100; # No need for poll routine here. # The current state of the default session might depend on load of testing box # but "ddicttestuser1" must not see anything of the root session. ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" eval SHOW CREATE TABLE $table; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS eval SHOW $table; diff --git a/mysql-test/suite/funcs_1/datadict/processlist_val.inc b/mysql-test/suite/funcs_1/datadict/processlist_val.inc index a2ab02c963f..b1c1130cbdf 100644 --- a/mysql-test/suite/funcs_1/datadict/processlist_val.inc +++ b/mysql-test/suite/funcs_1/datadict/processlist_val.inc @@ -72,7 +72,7 @@ echo # Show the definition of the PROCESSLIST table #-------------------------------------------------------------------------- ; ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" SHOW CREATE TABLE INFORMATION_SCHEMA.PROCESSLIST; echo diff --git a/mysql-test/suite/funcs_1/datadict/tables2.inc b/mysql-test/suite/funcs_1/datadict/tables2.inc index f9bb296eeaa..0d110dd22d9 100644 --- a/mysql-test/suite/funcs_1/datadict/tables2.inc +++ b/mysql-test/suite/funcs_1/datadict/tables2.inc @@ -31,7 +31,7 @@ let $ndb_pattern = 'number_of_replicas'; --vertical_results # We do not unify the engine name here, because the rowformat is # specific to the engine. ---replace_result Dynamic DYNAMIC_OR_PAGE Page DYNAMIC_OR_PAGE MyISAM MYISAM_OR_MARIA MARIA MYISAM_OR_MARIA +--replace_result Dynamic DYNAMIC_OR_PAGE Page DYNAMIC_OR_PAGE MyISAM MYISAM_OR_MARIA Aria MYISAM_OR_MARIA --replace_column 8 "#TBLR#" 9 "#ARL#" 10 "#DL#" 11 "#MDL#" 12 "#IL#" 13 "#DF#" 15 "#CRT#" 16 "#UT#" 17 "#CT#" 20 "#CO#" 21 "#TC#" eval SELECT *, diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index e647d4af174..4b9577109b3 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -7,6 +7,29 @@ NULL information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NU NULL information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select NULL information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL utf8 utf8_general_ci varchar(60) select NULL information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(3) select +NULL information_schema CLIENT_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL double select +NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS CLIENT 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select +NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS CONNECTED_TIME 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL double select +NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS 2 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select NULL information_schema COLLATIONS CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select NULL information_schema COLLATIONS COLLATION_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select NULL information_schema COLLATIONS ID 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(11) select @@ -113,6 +136,10 @@ NULL information_schema GLOBAL_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NU NULL information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select NULL information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select +NULL information_schema INDEX_STATISTICS INDEX_NAME 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select +NULL information_schema INDEX_STATISTICS ROWS_READ 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema INDEX_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select +NULL information_schema INDEX_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select NULL information_schema INNODB_BUFFER_POOL_PAGES fix_count 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema INNODB_BUFFER_POOL_PAGES flush_type 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema INNODB_BUFFER_POOL_PAGES lru_position 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select @@ -223,6 +250,18 @@ NULL information_schema INNODB_TRX trx_started 3 0000-00-00 00:00:00 NO datetime NULL information_schema INNODB_TRX trx_state 2 NO varchar 13 39 NULL NULL utf8 utf8_general_ci varchar(13) select NULL information_schema INNODB_TRX trx_wait_started 5 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select NULL information_schema INNODB_TRX trx_weight 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema KEY_CACHES BLOCK_SIZE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema KEY_CACHES DIRTY_BLOCKS 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema KEY_CACHES FULL_SIZE 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema KEY_CACHES KEY_CACHE_NAME 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select +NULL information_schema KEY_CACHES READS 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema KEY_CACHES READ_REQUESTS 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema KEY_CACHES SEGMENTS 2 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned select +NULL information_schema KEY_CACHES SEGMENT_NUMBER 3 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned select +NULL information_schema KEY_CACHES UNUSED_BLOCKS 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema KEY_CACHES USED_BLOCKS 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema KEY_CACHES WRITES 12 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema KEY_CACHES WRITE_REQUESTS 11 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema KEY_COLUMN_USAGE COLUMN_NAME 7 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select @@ -264,10 +303,12 @@ NULL information_schema PBXT_STATISTICS ID 1 0 NO int NULL NULL 10 0 NULL NULL i NULL information_schema PBXT_STATISTICS Name 2 NO varchar 40 120 NULL NULL utf8 utf8_general_ci varchar(40) select NULL information_schema PBXT_STATISTICS Value 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(8) select NULL information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select +NULL information_schema PLUGINS PLUGIN_AUTH_VERSION 12 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select NULL information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select NULL information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select NULL information_schema PLUGINS PLUGIN_LICENSE 10 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select +NULL information_schema PLUGINS PLUGIN_MATURITY 11 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select NULL information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select NULL information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select @@ -378,6 +419,11 @@ NULL information_schema TABLE_PRIVILEGES PRIVILEGE_TYPE 5 NO varchar 64 192 NUL NULL information_schema TABLE_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select NULL information_schema TABLE_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema TABLE_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select +NULL information_schema TABLE_STATISTICS ROWS_CHANGED 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema TABLE_STATISTICS ROWS_READ 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema TABLE_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select +NULL information_schema TABLE_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select NULL information_schema TRIGGERS ACTION_CONDITION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select NULL information_schema TRIGGERS ACTION_ORDER 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) select NULL information_schema TRIGGERS ACTION_ORIENTATION 11 NO varchar 9 27 NULL NULL utf8 utf8_general_ci varchar(9) select @@ -404,6 +450,29 @@ NULL information_schema USER_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL u NULL information_schema USER_PRIVILEGES IS_GRANTABLE 4 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select NULL information_schema USER_PRIVILEGES PRIVILEGE_TYPE 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema USER_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select +NULL information_schema USER_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL double select +NULL information_schema USER_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO int NULL NULL 10 0 NULL NULL int(11) select +NULL information_schema USER_STATISTICS CONNECTED_TIME 4 0 NO int NULL NULL 10 0 NULL NULL int(11) select +NULL information_schema USER_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL double select +NULL information_schema USER_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS 2 0 NO int NULL NULL 10 0 NULL NULL int(11) select +NULL information_schema USER_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select +NULL information_schema USER_STATISTICS USER 1 NO varchar 48 144 NULL NULL utf8 utf8_general_ci varchar(48) select NULL information_schema VIEWS CHARACTER_SET_CLIENT 9 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select NULL information_schema VIEWS CHECK_OPTION 5 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8) select NULL information_schema VIEWS COLLATION_CONNECTION 10 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select @@ -460,6 +529,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME NULL bigint NULL NULL NULL datetime NULL NULL NULL decimal NULL NULL +NULL double NULL NULL NULL int NULL NULL --> CHAR(0) is allowed (see manual), and here both CHARACHTER_* values --> are 0, which is intended behavior, and the result of 0 / 0 IS NULL @@ -482,6 +552,29 @@ COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH C 3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 60 180 utf8 utf8_general_ci varchar(60) NULL information_schema CHARACTER_SETS MAXLEN bigint NULL NULL NULL NULL bigint(3) +3.0000 information_schema CLIENT_STATISTICS CLIENT varchar 64 192 utf8 utf8_general_ci varchar(64) +NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS CONNECTED_TIME bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS BUSY_TIME double NULL NULL NULL NULL double +NULL information_schema CLIENT_STATISTICS CPU_TIME double NULL NULL NULL NULL double +NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS BYTES_SENT bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS ROWS_READ bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS ROWS_SENT bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS ROWS_DELETED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS ROWS_INSERTED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS ROWS_UPDATED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS ACCESS_DENIED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES bigint NULL NULL NULL NULL bigint(21) 3.0000 information_schema COLLATIONS COLLATION_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema COLLATIONS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) NULL information_schema COLLATIONS ID bigint NULL NULL NULL NULL bigint(11) @@ -588,6 +681,10 @@ NULL information_schema FILES CHECKSUM bigint NULL NULL NULL NULL bigint(21) uns 3.0000 information_schema GLOBAL_STATUS VARIABLE_VALUE varchar 1024 3072 utf8 utf8_general_ci varchar(1024) 3.0000 information_schema GLOBAL_VARIABLES VARIABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema GLOBAL_VARIABLES VARIABLE_VALUE varchar 1024 3072 utf8 utf8_general_ci varchar(1024) +3.0000 information_schema INDEX_STATISTICS TABLE_SCHEMA varchar 192 576 utf8 utf8_general_ci varchar(192) +3.0000 information_schema INDEX_STATISTICS TABLE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192) +3.0000 information_schema INDEX_STATISTICS INDEX_NAME varchar 192 576 utf8 utf8_general_ci varchar(192) +NULL information_schema INDEX_STATISTICS ROWS_READ bigint NULL NULL NULL NULL bigint(21) 3.0000 information_schema INNODB_BUFFER_POOL_PAGES page_type varchar 64 192 utf8 utf8_general_ci varchar(64) NULL information_schema INNODB_BUFFER_POOL_PAGES space_id bigint NULL NULL NULL NULL bigint(21) unsigned NULL information_schema INNODB_BUFFER_POOL_PAGES page_no bigint NULL NULL NULL NULL bigint(21) unsigned @@ -698,6 +795,18 @@ NULL information_schema INNODB_TRX trx_wait_started datetime NULL NULL NULL NULL NULL information_schema INNODB_TRX trx_weight bigint NULL NULL NULL NULL bigint(21) unsigned NULL information_schema INNODB_TRX trx_mysql_thread_id bigint NULL NULL NULL NULL bigint(21) unsigned 3.0000 information_schema INNODB_TRX trx_query varchar 1024 3072 utf8 utf8_general_ci varchar(1024) +3.0000 information_schema KEY_CACHES KEY_CACHE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192) +NULL information_schema KEY_CACHES SEGMENTS int NULL NULL NULL NULL int(3) unsigned +NULL information_schema KEY_CACHES SEGMENT_NUMBER int NULL NULL NULL NULL int(3) unsigned +NULL information_schema KEY_CACHES FULL_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema KEY_CACHES BLOCK_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema KEY_CACHES USED_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema KEY_CACHES UNUSED_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema KEY_CACHES DIRTY_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema KEY_CACHES READ_REQUESTS bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema KEY_CACHES READS bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema KEY_CACHES WRITE_REQUESTS bigint NULL NULL NULL NULL bigint(21) unsigned +NULL information_schema KEY_CACHES WRITES bigint NULL NULL NULL NULL bigint(21) unsigned 3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) @@ -748,6 +857,8 @@ NULL information_schema PBXT_STATISTICS Value bigint NULL NULL NULL NULL bigint( 3.0000 information_schema PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64) 1.0000 information_schema PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext 3.0000 information_schema PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema PLUGINS PLUGIN_MATURITY varchar 12 36 utf8 utf8_general_ci varchar(12) +3.0000 information_schema PLUGINS PLUGIN_AUTH_VERSION varchar 80 240 utf8 utf8_general_ci varchar(80) NULL information_schema PROCESSLIST ID bigint NULL NULL NULL NULL bigint(4) 3.0000 information_schema PROCESSLIST USER varchar 16 48 utf8 utf8_general_ci varchar(16) 3.0000 information_schema PROCESSLIST HOST varchar 64 192 utf8 utf8_general_ci varchar(64) @@ -853,6 +964,11 @@ NULL information_schema TABLES CHECKSUM bigint NULL NULL NULL NULL bigint(21) un 3.0000 information_schema TABLE_PRIVILEGES TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TABLE_PRIVILEGES PRIVILEGE_TYPE varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TABLE_PRIVILEGES IS_GRANTABLE varchar 3 9 utf8 utf8_general_ci varchar(3) +3.0000 information_schema TABLE_STATISTICS TABLE_SCHEMA varchar 192 576 utf8 utf8_general_ci varchar(192) +3.0000 information_schema TABLE_STATISTICS TABLE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192) +NULL information_schema TABLE_STATISTICS ROWS_READ bigint NULL NULL NULL NULL bigint(21) +NULL information_schema TABLE_STATISTICS ROWS_CHANGED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES bigint NULL NULL NULL NULL bigint(21) 3.0000 information_schema TRIGGERS TRIGGER_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema TRIGGERS TRIGGER_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TRIGGERS TRIGGER_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) @@ -879,6 +995,29 @@ NULL information_schema TRIGGERS CREATED datetime NULL NULL NULL NULL datetime 3.0000 information_schema USER_PRIVILEGES TABLE_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema USER_PRIVILEGES PRIVILEGE_TYPE varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema USER_PRIVILEGES IS_GRANTABLE varchar 3 9 utf8 utf8_general_ci varchar(3) +3.0000 information_schema USER_STATISTICS USER varchar 48 144 utf8 utf8_general_ci varchar(48) +NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS int NULL NULL NULL NULL int(11) +NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS int NULL NULL NULL NULL int(11) +NULL information_schema USER_STATISTICS CONNECTED_TIME int NULL NULL NULL NULL int(11) +NULL information_schema USER_STATISTICS BUSY_TIME double NULL NULL NULL NULL double +NULL information_schema USER_STATISTICS CPU_TIME double NULL NULL NULL NULL double +NULL information_schema USER_STATISTICS BYTES_RECEIVED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS BYTES_SENT bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS ROWS_READ bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS ROWS_SENT bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS ROWS_DELETED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS ROWS_INSERTED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS ROWS_UPDATED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS SELECT_COMMANDS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS UPDATE_COMMANDS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS OTHER_COMMANDS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS DENIED_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS LOST_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS ACCESS_DENIED bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS EMPTY_QUERIES bigint NULL NULL NULL NULL bigint(21) 3.0000 information_schema VIEWS TABLE_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema VIEWS TABLE_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema VIEWS TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result index 5cf23ab5c36..9fd9fc3130d 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result @@ -7,6 +7,29 @@ NULL information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NU NULL information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) NULL information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL utf8 utf8_general_ci varchar(60) NULL information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(3) +NULL information_schema CLIENT_STATISTICS ACCESS_DENIED 22 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL double +NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED 7 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS BYTES_SENT 8 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS CLIENT 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) +NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS 18 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS CONNECTED_TIME 4 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL double +NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS 20 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES 23 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS 21 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS 17 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_DELETED 12 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_INSERTED 13 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_READ 10 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_SENT 11 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_UPDATED 14 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS 15 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS 2 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS 16 0 NO int NULL NULL 10 0 NULL NULL int(21) NULL information_schema COLLATIONS CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) NULL information_schema COLLATIONS COLLATION_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) NULL information_schema COLLATIONS ID 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(11) @@ -113,6 +136,10 @@ NULL information_schema GLOBAL_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NU NULL information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) NULL information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) NULL information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) +NULL information_schema INDEX_STATISTICS INDEX_NAME 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) +NULL information_schema INDEX_STATISTICS ROWS_READ 4 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema INDEX_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) +NULL information_schema INDEX_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) NULL information_schema INNODB_BUFFER_POOL_PAGES fix_count 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned NULL information_schema INNODB_BUFFER_POOL_PAGES flush_type 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned NULL information_schema INNODB_BUFFER_POOL_PAGES lru_position 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned @@ -355,6 +382,11 @@ NULL information_schema TABLE_PRIVILEGES PRIVILEGE_TYPE 5 NO varchar 64 192 NUL NULL information_schema TABLE_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) NULL information_schema TABLE_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) NULL information_schema TABLE_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) +NULL information_schema TABLE_STATISTICS ROWS_CHANGED 4 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES 5 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema TABLE_STATISTICS ROWS_READ 3 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema TABLE_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) +NULL information_schema TABLE_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) NULL information_schema TRIGGERS ACTION_CONDITION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext NULL information_schema TRIGGERS ACTION_ORDER 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) NULL information_schema TRIGGERS ACTION_ORIENTATION 11 NO varchar 9 27 NULL NULL utf8 utf8_general_ci varchar(9) @@ -381,6 +413,29 @@ NULL information_schema USER_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL u NULL information_schema USER_PRIVILEGES IS_GRANTABLE 4 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) NULL information_schema USER_PRIVILEGES PRIVILEGE_TYPE 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) NULL information_schema USER_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) +NULL information_schema USER_STATISTICS ACCESS_DENIED 22 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL double +NULL information_schema USER_STATISTICS BYTES_RECEIVED 7 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS BYTES_SENT 8 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS 18 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS CONNECTED_TIME 4 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL double +NULL information_schema USER_STATISTICS DENIED_CONNECTIONS 20 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS EMPTY_QUERIES 23 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS LOST_CONNECTIONS 21 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS OTHER_COMMANDS 17 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_DELETED 12 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_INSERTED 13 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_READ 10 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_SENT 11 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_UPDATED 14 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS SELECT_COMMANDS 15 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS 2 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS UPDATE_COMMANDS 16 0 NO int NULL NULL 10 0 NULL NULL int(21) +NULL information_schema USER_STATISTICS USER 1 NO varchar 48 144 NULL NULL utf8 utf8_general_ci varchar(48) NULL information_schema VIEWS CHARACTER_SET_CLIENT 9 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) NULL information_schema VIEWS CHECK_OPTION 5 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8) NULL information_schema VIEWS COLLATION_CONNECTION 10 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) @@ -436,6 +491,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME NULL bigint NULL NULL NULL datetime NULL NULL NULL decimal NULL NULL +NULL double NULL NULL NULL int NULL NULL --> CHAR(0) is allowed (see manual), and here both CHARACHTER_* values --> are 0, which is intended behavior, and the result of 0 / 0 IS NULL @@ -458,6 +514,29 @@ COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH C 3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 60 180 utf8 utf8_general_ci varchar(60) NULL information_schema CHARACTER_SETS MAXLEN bigint NULL NULL NULL NULL bigint(3) +3.0000 information_schema CLIENT_STATISTICS CLIENT varchar 64 192 utf8 utf8_general_ci varchar(64) +NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS CONNECTED_TIME int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS BUSY_TIME double NULL NULL NULL NULL double +NULL information_schema CLIENT_STATISTICS CPU_TIME double NULL NULL NULL NULL double +NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS BYTES_SENT int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_READ int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_SENT int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_DELETED int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_INSERTED int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROWS_UPDATED int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS ACCESS_DENIED int NULL NULL NULL NULL int(21) +NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES int NULL NULL NULL NULL int(21) 3.0000 information_schema COLLATIONS COLLATION_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema COLLATIONS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) NULL information_schema COLLATIONS ID bigint NULL NULL NULL NULL bigint(11) @@ -564,6 +643,10 @@ NULL information_schema FILES CHECKSUM bigint NULL NULL NULL NULL bigint(21) uns 3.0000 information_schema GLOBAL_STATUS VARIABLE_VALUE varchar 1024 3072 utf8 utf8_general_ci varchar(1024) 3.0000 information_schema GLOBAL_VARIABLES VARIABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema GLOBAL_VARIABLES VARIABLE_VALUE varchar 1024 3072 utf8 utf8_general_ci varchar(1024) +3.0000 information_schema INDEX_STATISTICS TABLE_SCHEMA varchar 192 576 utf8 utf8_general_ci varchar(192) +3.0000 information_schema INDEX_STATISTICS TABLE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192) +3.0000 information_schema INDEX_STATISTICS INDEX_NAME varchar 192 576 utf8 utf8_general_ci varchar(192) +NULL information_schema INDEX_STATISTICS ROWS_READ int NULL NULL NULL NULL int(21) 3.0000 information_schema INNODB_BUFFER_POOL_PAGES page_type varchar 64 192 utf8 utf8_general_ci varchar(64) NULL information_schema INNODB_BUFFER_POOL_PAGES space_id bigint NULL NULL NULL NULL bigint(21) unsigned NULL information_schema INNODB_BUFFER_POOL_PAGES page_no bigint NULL NULL NULL NULL bigint(21) unsigned @@ -806,6 +889,11 @@ NULL information_schema TABLES CHECKSUM bigint NULL NULL NULL NULL bigint(21) un 3.0000 information_schema TABLE_PRIVILEGES TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TABLE_PRIVILEGES PRIVILEGE_TYPE varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TABLE_PRIVILEGES IS_GRANTABLE varchar 3 9 utf8 utf8_general_ci varchar(3) +3.0000 information_schema TABLE_STATISTICS TABLE_SCHEMA varchar 192 576 utf8 utf8_general_ci varchar(192) +3.0000 information_schema TABLE_STATISTICS TABLE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192) +NULL information_schema TABLE_STATISTICS ROWS_READ int NULL NULL NULL NULL int(21) +NULL information_schema TABLE_STATISTICS ROWS_CHANGED int NULL NULL NULL NULL int(21) +NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES int NULL NULL NULL NULL int(21) 3.0000 information_schema TRIGGERS TRIGGER_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema TRIGGERS TRIGGER_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TRIGGERS TRIGGER_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) @@ -832,6 +920,29 @@ NULL information_schema TRIGGERS CREATED datetime NULL NULL NULL NULL datetime 3.0000 information_schema USER_PRIVILEGES TABLE_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema USER_PRIVILEGES PRIVILEGE_TYPE varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema USER_PRIVILEGES IS_GRANTABLE varchar 3 9 utf8 utf8_general_ci varchar(3) +3.0000 information_schema USER_STATISTICS USER varchar 48 144 utf8 utf8_general_ci varchar(48) +NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS CONNECTED_TIME int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS BUSY_TIME double NULL NULL NULL NULL double +NULL information_schema USER_STATISTICS CPU_TIME double NULL NULL NULL NULL double +NULL information_schema USER_STATISTICS BYTES_RECEIVED int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS BYTES_SENT int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_READ int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_SENT int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_DELETED int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_INSERTED int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS ROWS_UPDATED int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS SELECT_COMMANDS int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS UPDATE_COMMANDS int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS OTHER_COMMANDS int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS DENIED_CONNECTIONS int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS LOST_CONNECTIONS int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS ACCESS_DENIED int NULL NULL NULL NULL int(21) +NULL information_schema USER_STATISTICS EMPTY_QUERIES int NULL NULL NULL NULL int(21) 3.0000 information_schema VIEWS TABLE_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema VIEWS TABLE_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema VIEWS TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index 2b285d7cc56..30a3d047bde 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -49,7 +49,7 @@ NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references -NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references +NULL mysql event sql_mode 15 NO set 494 1482 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references @@ -124,7 +124,7 @@ NULL mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references -NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references +NULL mysql proc sql_mode 15 NO set 494 1482 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI select,insert,update,references NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references @@ -178,6 +178,7 @@ NULL mysql time_zone_transition_type Time_zone_id 1 NULL NO int NULL NULL 10 0 N NULL mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references NULL mysql user Alter_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NULL mysql user Alter_routine_priv 28 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references +NULL mysql user auth_string 41 NULL NO text 65535 65535 NULL NULL utf8 utf8_bin text select,insert,update,references NULL mysql user Create_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NULL mysql user Create_routine_priv 27 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NULL mysql user Create_tmp_table_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references @@ -198,6 +199,7 @@ NULL mysql user max_questions 36 0 NO int NULL NULL 10 0 NULL NULL int(11) unsig NULL mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references NULL mysql user Password 3 NO char 41 41 NULL NULL latin1 latin1_bin char(41) select,insert,update,references +NULL mysql user plugin 40 NO char 60 60 NULL NULL latin1 latin1_swedish_ci char(60) select,insert,update,references NULL mysql user Process_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NULL mysql user References_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NULL mysql user Reload_priv 10 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references @@ -233,6 +235,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME 1.0000 char latin1 latin1_bin 1.0000 char latin1 latin1_swedish_ci 1.0000 varchar latin1 latin1_swedish_ci +1.0000 text utf8 utf8_bin 1.0000 mediumtext utf8 utf8_general_ci 1.0000 text utf8 utf8_general_ci SELECT DISTINCT @@ -327,7 +330,7 @@ NULL mysql event starts datetime NULL NULL NULL NULL datetime NULL mysql event ends datetime NULL NULL NULL NULL datetime 3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') 3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE') -3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') +3.0000 mysql event sql_mode set 494 1482 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') 3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64) NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned 1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64) @@ -402,7 +405,7 @@ NULL mysql ndb_binlog_index schemaops bigint NULL NULL NULL NULL bigint(20) unsi 3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77) NULL mysql proc created timestamp NULL NULL NULL NULL timestamp NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp -3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') +3.0000 mysql proc sql_mode set 494 1482 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') 3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64) 3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32) 3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32) @@ -497,3 +500,5 @@ NULL mysql user max_questions int NULL NULL NULL NULL int(11) unsigned NULL mysql user max_updates int NULL NULL NULL NULL int(11) unsigned NULL mysql user max_connections int NULL NULL NULL NULL int(11) unsigned NULL mysql user max_user_connections int NULL NULL NULL NULL int(11) unsigned +1.0000 mysql user plugin char 60 60 latin1 latin1_swedish_ci char(60) +1.0000 mysql user auth_string text 65535 65535 utf8 utf8_bin text diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result index 983f9dd833e..926c2219bb0 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result @@ -49,7 +49,7 @@ NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned -NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') +NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64) @@ -124,7 +124,7 @@ NULL mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') -NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') +NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL @@ -327,7 +327,7 @@ NULL mysql event starts datetime NULL NULL NULL NULL datetime NULL mysql event ends datetime NULL NULL NULL NULL datetime 3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') 3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE') -3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') +3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') 3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64) NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned 1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64) @@ -402,7 +402,7 @@ NULL mysql ndb_binlog_index schemaops bigint NULL NULL NULL NULL bigint(20) unsi 3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77) NULL mysql proc created timestamp NULL NULL NULL NULL timestamp NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp -3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') +3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') 3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64) 3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32) 3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32) diff --git a/mysql-test/suite/funcs_1/r/is_engines_innodb.result b/mysql-test/suite/funcs_1/r/is_engines_innodb.result index 6de31d3ad31..5713b417cd1 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_innodb.result +++ b/mysql-test/suite/funcs_1/r/is_engines_innodb.result @@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'InnoDB'; ENGINE InnoDB SUPPORT YES -COMMENT Percona-XtraDB, Supports transactions, row-level locking, and foreign keys +COMMENT Supports transactions, row-level locking, and foreign keys TRANSACTIONS YES XA YES SAVEPOINTS YES diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result index 4b2b3bff752..f4fe0a880e7 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is.result @@ -38,6 +38,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME CLIENT_STATISTICS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME COLLATIONS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -245,6 +268,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME INDEX_STATISTICS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME INNODB_BUFFER_POOL_PAGES TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -613,6 +659,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME KEY_CACHES +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME KEY_COLUMN_USAGE TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -958,6 +1027,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME TABLE_STATISTICS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME TRIGGERS TABLE_TYPE SYSTEM VIEW ENGINE MYISAM_OR_MARIA @@ -1004,6 +1096,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME USER_STATISTICS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME VIEWS TABLE_TYPE SYSTEM VIEW ENGINE MYISAM_OR_MARIA @@ -1113,6 +1228,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME CLIENT_STATISTICS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME COLLATIONS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -1320,6 +1458,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME INDEX_STATISTICS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME INNODB_BUFFER_POOL_PAGES TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -1688,6 +1849,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME KEY_CACHES +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME KEY_COLUMN_USAGE TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -2033,6 +2217,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME TABLE_STATISTICS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME TRIGGERS TABLE_TYPE SYSTEM VIEW ENGINE MYISAM_OR_MARIA @@ -2079,6 +2286,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG NULL TABLE_SCHEMA information_schema +TABLE_NAME USER_STATISTICS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG NULL +TABLE_SCHEMA information_schema TABLE_NAME VIEWS TABLE_TYPE SYSTEM VIEW ENGINE MYISAM_OR_MARIA diff --git a/mysql-test/suite/funcs_1/r/is_user_privileges.result b/mysql-test/suite/funcs_1/r/is_user_privileges.result index 03865f59c2c..b9a19f98d65 100644 --- a/mysql-test/suite/funcs_1/r/is_user_privileges.result +++ b/mysql-test/suite/funcs_1/r/is_user_privileges.result @@ -76,10 +76,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 # # Add GRANT OPTION db_datadict.* to testuser1; GRANT UPDATE ON db_datadict.* TO 'testuser1'@'localhost' WITH GRANT OPTION; @@ -93,10 +93,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 # Establish connection testuser1 (user=testuser1) SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' @@ -105,10 +105,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser1'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 SHOW GRANTS; Grants for testuser1@localhost GRANT USAGE ON *.* TO 'testuser1'@'localhost' @@ -130,10 +130,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION; # # Here <SELECT YES> is shown correctly for testuser1; @@ -147,10 +147,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 # Switch to connection testuser1 SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' @@ -159,10 +159,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser1'@'localhost' NULL SELECT YES SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 SHOW GRANTS; Grants for testuser1@localhost GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION @@ -207,10 +207,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 # Switch to connection testuser1 SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' @@ -253,10 +253,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 # Switch to connection testuser1 SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' @@ -265,10 +265,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser1'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 SHOW GRANTS; Grants for testuser1@localhost GRANT USAGE ON *.* TO 'testuser1'@'localhost' @@ -284,10 +284,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser1'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 SHOW GRANTS; Grants for testuser1@localhost GRANT USAGE ON *.* TO 'testuser1'@'localhost' @@ -309,10 +309,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' NULL USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 # Switch to connection testuser1 SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' diff --git a/mysql-test/suite/funcs_1/t/is_columns.test b/mysql-test/suite/funcs_1/t/is_columns.test index 5e754c56532..fca21034e37 100644 --- a/mysql-test/suite/funcs_1/t/is_columns.test +++ b/mysql-test/suite/funcs_1/t/is_columns.test @@ -78,7 +78,7 @@ eval SHOW TABLES FROM information_schema LIKE '$is_table'; --source suite/funcs_1/datadict/datadict_bug_12777.inc eval DESCRIBE information_schema.$is_table; --source suite/funcs_1/datadict/datadict_bug_12777.inc ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" eval SHOW CREATE TABLE information_schema.$is_table; --source suite/funcs_1/datadict/datadict_bug_12777.inc eval SHOW COLUMNS FROM information_schema.$is_table; diff --git a/mysql-test/suite/funcs_1/t/is_events.test b/mysql-test/suite/funcs_1/t/is_events.test index 22565840728..400094966b1 100644 --- a/mysql-test/suite/funcs_1/t/is_events.test +++ b/mysql-test/suite/funcs_1/t/is_events.test @@ -89,7 +89,7 @@ eval SHOW TABLES FROM information_schema LIKE '$is_table'; # is associated. # eval DESCRIBE information_schema.$is_table; ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" eval SHOW CREATE TABLE information_schema.$is_table; eval SHOW COLUMNS FROM information_schema.$is_table; diff --git a/mysql-test/suite/funcs_1/t/is_tables_is.test b/mysql-test/suite/funcs_1/t/is_tables_is.test index 3db2f7fbdcb..6401f2d451a 100644 --- a/mysql-test/suite/funcs_1/t/is_tables_is.test +++ b/mysql-test/suite/funcs_1/t/is_tables_is.test @@ -17,4 +17,3 @@ let $my_where = WHERE table_schema = 'information_schema' AND table_name <> 'profiling'; --source suite/funcs_1/datadict/tables1.inc - diff --git a/mysql-test/suite/maria/r/compat_aliases.result b/mysql-test/suite/maria/r/compat_aliases.result new file mode 100644 index 00000000000..f0cd5f1d719 --- /dev/null +++ b/mysql-test/suite/maria/r/compat_aliases.result @@ -0,0 +1,59 @@ +select * from information_schema.plugins where plugin_name like '%aria'; +PLUGIN_NAME PLUGIN_VERSION PLUGIN_STATUS PLUGIN_TYPE PLUGIN_TYPE_VERSION PLUGIN_LIBRARY PLUGIN_LIBRARY_VERSION PLUGIN_AUTHOR PLUGIN_DESCRIPTION PLUGIN_LICENSE PLUGIN_MATURITY PLUGIN_AUTH_VERSION +Maria 1.5 ACTIVE DAEMON # NULL NULL Monty Program Ab Compatibility aliases for the Aria engine GPL Gamma 1.5 +Aria 1.5 ACTIVE STORAGE ENGINE # NULL NULL Monty Program Ab Crash-safe tables with MyISAM heritage GPL Gamma 1.5 +select maria_vars.variable_name, aria_vars.variable_name from +information_schema.session_variables as maria_vars left join +information_schema.session_variables as aria_vars +on (maria_vars.variable_name = concat('m', aria_vars.variable_name)) +where maria_vars.variable_name like 'maria_%' + and not (maria_vars.variable_value <=> aria_vars.variable_value); +variable_name variable_name +select maria_vars.variable_name, aria_vars.variable_name from +information_schema.session_status as maria_vars left join +information_schema.session_status as aria_vars +on (maria_vars.variable_name = concat('m', aria_vars.variable_name)) +where maria_vars.variable_name like 'maria_%' + and not (maria_vars.variable_value <=> aria_vars.variable_value); +variable_name variable_name +select maria_vars.variable_name, aria_vars.variable_name from +information_schema.session_variables as aria_vars left join +information_schema.session_variables as maria_vars +on (maria_vars.variable_name = concat('m', aria_vars.variable_name)) +where aria_vars.variable_name like 'aria_%' + and not (maria_vars.variable_value <=> aria_vars.variable_value); +variable_name variable_name +NULL ARIA_CHECKPOINT_LOG_ACTIVITY +select maria_vars.variable_name, aria_vars.variable_name from +information_schema.session_status as aria_vars left join +information_schema.session_status as maria_vars +on (maria_vars.variable_name = concat('m', aria_vars.variable_name)) +where aria_vars.variable_name like 'aria_%' + and not (maria_vars.variable_value <=> aria_vars.variable_value); +variable_name variable_name +set @old_checkpoint_interval=@@global.aria_checkpoint_interval; +set global maria_checkpoint_interval=10; +select @@global.aria_checkpoint_interval; +@@global.aria_checkpoint_interval +10 +set global maria_checkpoint_interval=@old_checkpoint_interval; +set @old_sort_buffer_size=@@global.maria_sort_buffer_size; +set global aria_sort_buffer_size=1024; +select @@global.maria_sort_buffer_size; +@@global.maria_sort_buffer_size +1024 +set global aria_sort_buffer_size=@old_sort_buffer_size; +set @old_sort_buffer_size=@@session.maria_sort_buffer_size; +set session aria_sort_buffer_size=2048; +select @@session.maria_sort_buffer_size; +@@session.maria_sort_buffer_size +2048 +set session aria_sort_buffer_size=@old_sort_buffer_size; +set @old_max_sort_file_size=@@global.maria_max_sort_file_size, +@old_repair_threads=@@global.aria_repair_threads; +set @@global.maria_max_sort_file_size=default, @@global.aria_repair_threads=default; +select @@global.maria_max_sort_file_size, @@global.aria_repair_threads; +@@global.maria_max_sort_file_size @@global.aria_repair_threads +9223372036853727232 1 +set @@global.aria_max_sort_file_size=@old_max_sort_file_size, +@@global.maria_repair_threads=@old_repair_threads; diff --git a/mysql-test/suite/maria/r/group_commit.result b/mysql-test/suite/maria/r/group_commit.result new file mode 100644 index 00000000000..4fb85b912ec --- /dev/null +++ b/mysql-test/suite/maria/r/group_commit.result @@ -0,0 +1,17 @@ +drop table if exists t1; +create table t1 (a int); +SET GLOBAL aria_group_commit="NONE"; +SET GLOBAL aria_group_commit_interval= 0; +SET GLOBAL aria_group_commit="NONE"; +SET GLOBAL aria_group_commit_interval= 100; +SET GLOBAL aria_group_commit="HARD"; +SET GLOBAL aria_group_commit_interval= 0; +SET GLOBAL aria_group_commit="HARD"; +SET GLOBAL aria_group_commit_interval= 100; +SET GLOBAL aria_group_commit="SOFT"; +SET GLOBAL aria_group_commit_interval= 0; +SET GLOBAL aria_group_commit="SOFT"; +SET GLOBAL aria_group_commit_interval= 100; +SET GLOBAL aria_group_commit="NONE"; +SET GLOBAL aria_group_commit_interval= 0; +drop table t1; diff --git a/mysql-test/suite/maria/r/maria-autozerofill.result b/mysql-test/suite/maria/r/maria-autozerofill.result index e31cf9fa19b..ad0ea32362a 100644 --- a/mysql-test/suite/maria/r/maria-autozerofill.result +++ b/mysql-test/suite/maria/r/maria-autozerofill.result @@ -2,7 +2,7 @@ call mtr.add_suppression("Table 't1' is marked as crashed and should be repaired drop database if exists mysqltest; create database mysqltest; use mysqltest; -create table t1(a int) engine=maria; +create table t1(a int) engine=aria; insert into t1 values(1); flush table t1; create_rename_lsn has non-magic value diff --git a/mysql-test/suite/maria/r/maria-big.result b/mysql-test/suite/maria/r/maria-big.result index 64b3296b6b2..cb6e02df00e 100644 --- a/mysql-test/suite/maria/r/maria-big.result +++ b/mysql-test/suite/maria/r/maria-big.result @@ -1,5 +1,5 @@ set global max_allowed_packet=400000000; -set storage_engine=maria; +set storage_engine=aria; affected rows: 0 drop table if exists t1, t2; affected rows: 0 diff --git a/mysql-test/suite/maria/r/maria-big2.result b/mysql-test/suite/maria/r/maria-big2.result index 7fc57d6a203..3e4c6973997 100644 --- a/mysql-test/suite/maria/r/maria-big2.result +++ b/mysql-test/suite/maria/r/maria-big2.result @@ -1,4 +1,4 @@ -create table t2(id int,a varchar(255),b varchar(255),key(a))engine=maria row_format=dynamic transactional=0; +create table t2(id int,a varchar(255),b varchar(255),key(a))engine=aria row_format=dynamic transactional=0; Table Op Msg_type Msg_text test.t2 check status OK Table Op Msg_type Msg_text diff --git a/mysql-test/suite/maria/r/maria-connect.result b/mysql-test/suite/maria/r/maria-connect.result index 8fe483c8467..a02c29f3d5f 100644 --- a/mysql-test/suite/maria/r/maria-connect.result +++ b/mysql-test/suite/maria/r/maria-connect.result @@ -1,5 +1,5 @@ -set global storage_engine=maria; -set session storage_engine=maria; +set global storage_engine=aria; +set session storage_engine=aria; drop table if exists t1; SET SQL_WARNINGS=1; RESET MASTER; diff --git a/mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result b/mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result index 189872e8e13..743f1785f5c 100644 --- a/mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result +++ b/mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result @@ -1,4 +1,4 @@ -set storage_engine=maria; +set storage_engine=aria; DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 ( fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -12,7 +12,7 @@ t1 CREATE TABLE `t1` ( `g` geometry NOT NULL, PRIMARY KEY (`fid`), SPATIAL KEY `g` (`g`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=DYNAMIC +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=DYNAMIC INSERT INTO t1 (g) VALUES (GeomFromText('LineString(150 150, 150 150)')); INSERT INTO t1 (g) VALUES (GeomFromText('LineString(149 149, 151 151)')); INSERT INTO t1 (g) VALUES (GeomFromText('LineString(148 148, 152 152)')); @@ -295,7 +295,7 @@ t2 CREATE TABLE `t2` ( `g` geometry NOT NULL, PRIMARY KEY (`fid`), SPATIAL KEY `g` (`g`) -) ENGINE=MARIA AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=DYNAMIC +) ENGINE=Aria AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=DYNAMIC SELECT count(*) FROM t2; count(*) 100 diff --git a/mysql-test/suite/maria/r/maria-gis-rtree-trans.result b/mysql-test/suite/maria/r/maria-gis-rtree-trans.result index 9e43daa9623..ae37b9d454d 100644 --- a/mysql-test/suite/maria/r/maria-gis-rtree-trans.result +++ b/mysql-test/suite/maria/r/maria-gis-rtree-trans.result @@ -1,4 +1,4 @@ -set storage_engine=maria; +set storage_engine=aria; DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 ( fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -12,7 +12,7 @@ t1 CREATE TABLE `t1` ( `g` geometry NOT NULL, PRIMARY KEY (`fid`), SPATIAL KEY `g` (`g`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=1 INSERT INTO t1 (g) VALUES (GeomFromText('LineString(150 150, 150 150)')); INSERT INTO t1 (g) VALUES (GeomFromText('LineString(149 149, 151 151)')); INSERT INTO t1 (g) VALUES (GeomFromText('LineString(148 148, 152 152)')); @@ -295,7 +295,7 @@ t2 CREATE TABLE `t2` ( `g` geometry NOT NULL, PRIMARY KEY (`fid`), SPATIAL KEY `g` (`g`) -) ENGINE=MARIA AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=1 +) ENGINE=Aria AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=1 SELECT count(*) FROM t2; count(*) 100 diff --git a/mysql-test/suite/maria/r/maria-gis-rtree.result b/mysql-test/suite/maria/r/maria-gis-rtree.result index 0c929fe1313..a61e93d2a3a 100644 --- a/mysql-test/suite/maria/r/maria-gis-rtree.result +++ b/mysql-test/suite/maria/r/maria-gis-rtree.result @@ -1,4 +1,4 @@ -set storage_engine=maria; +set storage_engine=aria; DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 ( fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -12,7 +12,7 @@ t1 CREATE TABLE `t1` ( `g` geometry NOT NULL, PRIMARY KEY (`fid`), SPATIAL KEY `g` (`g`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=0 INSERT INTO t1 (g) VALUES (GeomFromText('LineString(150 150, 150 150)')); INSERT INTO t1 (g) VALUES (GeomFromText('LineString(149 149, 151 151)')); INSERT INTO t1 (g) VALUES (GeomFromText('LineString(148 148, 152 152)')); @@ -295,7 +295,7 @@ t2 CREATE TABLE `t2` ( `g` geometry NOT NULL, PRIMARY KEY (`fid`), SPATIAL KEY `g` (`g`) -) ENGINE=MARIA AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=0 +) ENGINE=Aria AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=0 SELECT count(*) FROM t2; count(*) 100 diff --git a/mysql-test/suite/maria/r/maria-mvcc.result b/mysql-test/suite/maria/r/maria-mvcc.result index 3919dfc597e..671b1bbf53c 100644 --- a/mysql-test/suite/maria/r/maria-mvcc.result +++ b/mysql-test/suite/maria/r/maria-mvcc.result @@ -1,11 +1,11 @@ -set global maria_page_checksum=1; +set global aria_page_checksum=1; drop table if exists t1; -create table t1 (i int) engine=maria; +create table t1 (i int) engine=aria; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 insert into t1 values (0); lock tables t1 write concurrent; insert into t1 values (1); @@ -151,7 +151,7 @@ select count(*) from t1; count(*) 8 drop table t1; -CREATE TABLE t1 (fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, g GEOMETRY NOT NULL, SPATIAL KEY(g) ) transactional=1 row_format=page engine=maria; +CREATE TABLE t1 (fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, g GEOMETRY NOT NULL, SPATIAL KEY(g) ) transactional=1 row_format=page engine=aria; lock tables t1 write concurrent, t1 as t2 write concurrent; insert into t1 (fid,g) values (NULL,GeomFromText('LineString(0 0,1 1)')); select fid from t1 as t2; diff --git a/mysql-test/suite/maria/r/maria-no-logging.result b/mysql-test/suite/maria/r/maria-no-logging.result index e72842ae71b..0d3d7804853 100644 --- a/mysql-test/suite/maria/r/maria-no-logging.result +++ b/mysql-test/suite/maria/r/maria-no-logging.result @@ -1,8 +1,8 @@ -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; drop database if exists mysqltest; create database mysqltest; use mysqltest; -set global maria_checkpoint_interval=0; +set global aria_checkpoint_interval=0; create table t2 (a varchar(100)) engine=myisam; insert into t2 select repeat('z',100); insert into t2 select * from t2; @@ -12,40 +12,40 @@ insert into t2 select * from t2; insert into t2 select * from t2; insert into t2 select * from t2; * shut down mysqld, removed logs, restarted it -create table t1 (a varchar(100)) engine=maria transactional=1; +create table t1 (a varchar(100)) engine=aria transactional=1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(100) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 -show engine maria logs; +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +show engine aria logs; Type Name Status -MARIA Size 16384 maria_log.00000001 unknown +Aria Size 16384 aria_log.00000001 unknown insert into t1 values('a'); insert into t1 select * from t2; -show engine maria logs; +show engine aria logs; Type Name Status -MARIA Size 24576 maria_log.00000001 unknown +Aria Size 24576 aria_log.00000001 unknown * shut down mysqld, removed logs, restarted it truncate table t1; insert into t1 select * from t2; -show engine maria logs; +show engine aria logs; Type Name Status -MARIA Size 16384 maria_log.00000001 unknown +Aria Size 16384 aria_log.00000001 unknown drop table t1; * shut down mysqld, removed logs, restarted it -create table t1 (a varchar(100)) engine=maria transactional=1; +create table t1 (a varchar(100)) engine=aria transactional=1; insert into t1 values('a'); create table if not exists t1 select * from t2; Warnings: Note 1050 Table 't1' already exists -show engine maria logs; +show engine aria logs; Type Name Status -MARIA Size 24576 maria_log.00000001 unknown +Aria Size 24576 aria_log.00000001 unknown * shut down mysqld, removed logs, restarted it drop table t1; -create table t1 engine=maria transactional=1 select * from t2; -show engine maria logs; +create table t1 engine=aria transactional=1 select * from t2; +show engine aria logs; Type Name Status -MARIA Size 16384 maria_log.00000001 unknown +Aria Size 16384 aria_log.00000001 unknown drop database mysqltest; diff --git a/mysql-test/suite/maria/r/maria-page-checksum.result b/mysql-test/suite/maria/r/maria-page-checksum.result index 0319bd9e9ca..c4d1b71e33a 100644 --- a/mysql-test/suite/maria/r/maria-page-checksum.result +++ b/mysql-test/suite/maria/r/maria-page-checksum.result @@ -1,940 +1,940 @@ drop table if exists t1; -select @@global.maria_page_checksum; -@@global.maria_page_checksum +select @@global.aria_page_checksum; +@@global.aria_page_checksum 1 # iteration 1 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 2 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 3 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 4 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 5 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 6 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 7 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 8 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 9 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 10 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 11 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 12 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 13 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 14 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 15 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 16 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 17 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 18 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 19 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 20 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 21 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 22 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 23 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 24 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 25 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 26 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 27 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 28 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 29 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 30 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 31 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 32 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 33 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 34 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 35 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 Page checksums are not used drop table t1; # iteration 36 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Page checksums are used drop table t1; # iteration 1 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Crashsafe: yes alter table t1 modify a bigint ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` bigint(20) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Crashsafe: yes drop table t1; # iteration 2 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Crashsafe: yes alter table t1 transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no drop table t1; # iteration 3 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Crashsafe: yes alter table t1 transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes drop table t1; # iteration 4 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Crashsafe: yes -alter table t1 engine=maria ; +alter table t1 engine=aria ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Crashsafe: yes drop table t1; # iteration 5 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Crashsafe: yes -alter table t1 engine=maria transactional=0 ; +alter table t1 engine=aria transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no drop table t1; # iteration 6 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 Crashsafe: yes -alter table t1 engine=maria transactional=1 ; +alter table t1 engine=aria transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes drop table t1; # iteration 7 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no alter table t1 modify a bigint ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` bigint(20) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no drop table t1; # iteration 8 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no alter table t1 transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no drop table t1; # iteration 9 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no alter table t1 transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes drop table t1; # iteration 10 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no -alter table t1 engine=maria ; +alter table t1 engine=aria ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no drop table t1; # iteration 11 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no -alter table t1 engine=maria transactional=0 ; +alter table t1 engine=aria transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no drop table t1; # iteration 12 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no -alter table t1 engine=maria transactional=1 ; +alter table t1 engine=aria transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes drop table t1; # iteration 13 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes alter table t1 modify a bigint ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` bigint(20) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes drop table t1; # iteration 14 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes alter table t1 transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no drop table t1; # iteration 15 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes alter table t1 transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes drop table t1; # iteration 16 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes -alter table t1 engine=maria ; +alter table t1 engine=aria ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes drop table t1; # iteration 17 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes -alter table t1 engine=maria transactional=0 ; +alter table t1 engine=aria transactional=0 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=0 Crashsafe: no drop table t1; # iteration 18 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes -alter table t1 engine=maria transactional=1 ; +alter table t1 engine=aria transactional=1 ; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 Crashsafe: yes drop table t1; diff --git a/mysql-test/suite/maria/r/maria-partitioning.result b/mysql-test/suite/maria/r/maria-partitioning.result index ff3035e560e..840c7c0b3b4 100644 --- a/mysql-test/suite/maria/r/maria-partitioning.result +++ b/mysql-test/suite/maria/r/maria-partitioning.result @@ -1,11 +1,11 @@ -set global storage_engine=maria; -set session storage_engine=maria; +set global storage_engine=aria; +set session storage_engine=aria; DROP TABLE if exists t1,t2; Warnings: Note 1051 Unknown table 't1' Note 1051 Unknown table 't2' -create table t2(a blob) engine=maria; -create table t1(a int primary key) engine=maria; +create table t2(a blob) engine=aria; +create table t1(a int primary key) engine=aria; insert into t2 values ('foo'),('bar'); select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb'; a a @@ -16,8 +16,8 @@ insert into t1 values (2); select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb'; a a drop table t1,t2; -create table t2(a blob) engine= maria; -create table t1(a int primary key) engine= maria PARTITION BY HASH (a) PARTITIONS 2; +create table t2(a blob) engine= aria; +create table t1(a int primary key) engine= aria PARTITION BY HASH (a) PARTITIONS 2; insert into t2 values ('foo'),('bar'); select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb'; a a diff --git a/mysql-test/suite/maria/r/maria-preload.result b/mysql-test/suite/maria/r/maria-preload.result index b7c65ba8bb4..a693b6768ac 100644 --- a/mysql-test/suite/maria/r/maria-preload.result +++ b/mysql-test/suite/maria/r/maria-preload.result @@ -1,20 +1,20 @@ drop table if exists t1, t2; -set global maria_checkpoint_interval=0; +set global aria_checkpoint_interval=0; create temporary table initial select variable_name,variable_value from -information_schema.global_status where variable_name like "Maria_pagecache_reads"; +information_schema.global_status where variable_name like "Aria_pagecache_reads"; create table t1 ( a int not null auto_increment, b char(16) not null, primary key (a), key (b) -) engine=maria row_format=dynamic; +) engine=aria row_format=dynamic; create table t2( a int not null auto_increment, b char(16) not null, primary key (a), key (b) -) engine=maria row_format=dynamic; +) engine=aria row_format=dynamic; insert into t1(b) values ('test0'), ('test1'), @@ -50,21 +50,21 @@ count(*) 20672 flush tables; flush status; -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 2 +ARIA_PAGECACHE_READS 2 select count(*) from t1 where b = 'test1'; count(*) 4181 -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 9 +ARIA_PAGECACHE_READS 9 select count(*) from t1 where b = 'test1'; count(*) 4181 -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 9 +ARIA_PAGECACHE_READS 9 flush tables; flush status; select @@preload_buffer_size; @@ -73,20 +73,20 @@ select @@preload_buffer_size; load index into cache t1; Table Op Msg_type Msg_text test.t1 preload_keys status OK -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 80 +ARIA_PAGECACHE_READS 80 select count(*) from t1 where b = 'test1'; count(*) 4181 -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 80 +ARIA_PAGECACHE_READS 80 flush tables; flush status; -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 80 +ARIA_PAGECACHE_READS 80 set session preload_buffer_size=256*1024; select @@preload_buffer_size; @@preload_buffer_size @@ -94,20 +94,20 @@ select @@preload_buffer_size; load index into cache t1 ignore leaves; Table Op Msg_type Msg_text test.t1 preload_keys status OK -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 151 +ARIA_PAGECACHE_READS 151 select count(*) from t1 where b = 'test1'; count(*) 4181 -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 157 +ARIA_PAGECACHE_READS 157 flush tables; flush status; -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 157 +ARIA_PAGECACHE_READS 157 set session preload_buffer_size=1*1024; select @@preload_buffer_size; @@preload_buffer_size @@ -116,45 +116,45 @@ load index into cache t1, t2 key (primary,b) ignore leaves; Table Op Msg_type Msg_text test.t1 preload_keys status OK test.t2 preload_keys status OK -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 271 +ARIA_PAGECACHE_READS 271 select count(*) from t1 where b = 'test1'; count(*) 4181 select count(*) from t2 where b = 'test1'; count(*) 2584 -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 274 +ARIA_PAGECACHE_READS 274 flush tables; flush status; -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 274 +ARIA_PAGECACHE_READS 274 load index into cache t3, t2 key (primary,b) ; Table Op Msg_type Msg_text test.t3 preload_keys Error Table 'test.t3' doesn't exist test.t3 preload_keys status Operation failed test.t2 preload_keys status OK -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 317 +ARIA_PAGECACHE_READS 317 flush tables; flush status; -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 317 +ARIA_PAGECACHE_READS 317 load index into cache t3 key (b), t2 key (c) ; Table Op Msg_type Msg_text test.t3 preload_keys Error Table 'test.t3' doesn't exist test.t3 preload_keys status Operation failed test.t2 preload_keys Error Key 'c' doesn't exist in table 't2' test.t2 preload_keys status Operation failed -select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; variable_name g.variable_value-i.variable_value -MARIA_PAGECACHE_READS 317 +ARIA_PAGECACHE_READS 317 drop table t1, t2; drop temporary table initial; show status like "key_read%"; diff --git a/mysql-test/suite/maria/r/maria-purge.result b/mysql-test/suite/maria/r/maria-purge.result index eb67bab8cde..263e3270d26 100644 --- a/mysql-test/suite/maria/r/maria-purge.result +++ b/mysql-test/suite/maria/r/maria-purge.result @@ -1,7 +1,7 @@ * shut down mysqld, removed logs, restarted it -set global storage_engine=maria; -set session storage_engine=maria; -set global maria_log_file_size=4294967295; +set global storage_engine=aria; +set session storage_engine=aria; +set global aria_log_file_size=4294967295; drop table if exists t1,t2; SET SQL_WARNINGS=1; CREATE TABLE t1 ( @@ -34,60 +34,60 @@ insert into t2 select * from t1; insert into t1 select * from t2; insert into t2 select * from t1; insert into t1 select * from t2; -set global maria_log_file_size=16777216; -set global maria_checkpoint_interval=30; -SHOW ENGINE maria logs; +set global aria_log_file_size=16777216; +set global aria_checkpoint_interval=30; +SHOW ENGINE aria logs; Type Name Status -MARIA maria_log.00000002 in use +Aria aria_log.00000002 in use insert into t2 select * from t1; insert into t1 select * from t2; -set global maria_checkpoint_interval=30; -SHOW ENGINE maria logs; +set global aria_checkpoint_interval=30; +SHOW ENGINE aria logs; Type Name Status -MARIA maria_log.00000004 in use -set global maria_log_file_size=16777216; -select @@global.maria_log_file_size; -@@global.maria_log_file_size +Aria aria_log.00000004 in use +set global aria_log_file_size=16777216; +select @@global.aria_log_file_size; +@@global.aria_log_file_size 16777216 -set global maria_checkpoint_interval=30; -SHOW ENGINE maria logs; +set global aria_checkpoint_interval=30; +SHOW ENGINE aria logs; Type Name Status -MARIA maria_log.00000004 in use -set global maria_log_file_size=8388608; -select @@global.maria_log_file_size; -@@global.maria_log_file_size +Aria aria_log.00000004 in use +set global aria_log_file_size=8388608; +select @@global.aria_log_file_size; +@@global.aria_log_file_size 8388608 -set global maria_log_purge_type=at_flush; +set global aria_log_purge_type=at_flush; insert into t1 select * from t2; -set global maria_checkpoint_interval=30; -SHOW ENGINE maria logs; +set global aria_checkpoint_interval=30; +SHOW ENGINE aria logs; Type Name Status -MARIA maria_log.00000004 free -MARIA maria_log.00000005 free -MARIA maria_log.00000006 free -MARIA maria_log.00000007 free -MARIA maria_log.00000008 in use +Aria aria_log.00000004 free +Aria aria_log.00000005 free +Aria aria_log.00000006 free +Aria aria_log.00000007 free +Aria aria_log.00000008 in use flush logs; -SHOW ENGINE maria logs; +SHOW ENGINE aria logs; Type Name Status -MARIA maria_log.00000008 in use -set global maria_log_file_size=16777216; -set global maria_log_purge_type=external; +Aria aria_log.00000008 in use +set global aria_log_file_size=16777216; +set global aria_log_purge_type=external; insert into t1 select * from t2; -set global maria_checkpoint_interval=30; -SHOW ENGINE maria logs; +set global aria_checkpoint_interval=30; +SHOW ENGINE aria logs; Type Name Status -MARIA maria_log.00000008 free -MARIA maria_log.00000009 in use +Aria aria_log.00000008 free +Aria aria_log.00000009 in use flush logs; -SHOW ENGINE maria logs; +SHOW ENGINE aria logs; Type Name Status -MARIA maria_log.00000008 free -MARIA maria_log.00000009 in use -set global maria_log_purge_type=immediate; +Aria aria_log.00000008 free +Aria aria_log.00000009 in use +set global aria_log_purge_type=immediate; insert into t1 select * from t2; -set global maria_checkpoint_interval=30; -SHOW ENGINE maria logs; +set global aria_checkpoint_interval=30; +SHOW ENGINE aria logs; Type Name Status -MARIA maria_log.00000011 in use +Aria aria_log.00000011 in use drop table t1, t2; diff --git a/mysql-test/suite/maria/r/maria-recover.result b/mysql-test/suite/maria/r/maria-recover.result index 41155d683e4..128467a278c 100644 --- a/mysql-test/suite/maria/r/maria-recover.result +++ b/mysql-test/suite/maria/r/maria-recover.result @@ -1,22 +1,22 @@ -select @@global.maria_recover; -@@global.maria_recover +select @@global.aria_recover; +@@global.aria_recover BACKUP -set global maria_recover=off; -select @@global.maria_recover; -@@global.maria_recover +set global aria_recover=off; +select @@global.aria_recover; +@@global.aria_recover OFF -set global maria_recover=default; -select @@global.maria_recover; -@@global.maria_recover +set global aria_recover=default; +select @@global.aria_recover; +@@global.aria_recover NORMAL -set global maria_recover=normal; -select @@global.maria_recover; -@@global.maria_recover +set global aria_recover=normal; +select @@global.aria_recover; +@@global.aria_recover NORMAL drop database if exists mysqltest; create database mysqltest; use mysqltest; -create table t1 (a varchar(1000), index(a)) engine=maria; +create table t1 (a varchar(1000), index(a)) engine=aria; insert into t1 values("ThursdayMorningsMarket"); flush table t1; insert into t1 select concat(a,'b') from t1 limit 1; @@ -35,5 +35,5 @@ a ThursdayMorningsMarket ThursdayMorningsMarketb drop database mysqltest; -set global maria_recover=backup; -set global maria_checkpoint_interval=30; +set global aria_recover=backup; +set global aria_checkpoint_interval=30; diff --git a/mysql-test/suite/maria/r/maria-recovery-big.result b/mysql-test/suite/maria/r/maria-recovery-big.result index ecc53de437e..b205265f0da 100644 --- a/mysql-test/suite/maria/r/maria-recovery-big.result +++ b/mysql-test/suite/maria/r/maria-recovery-big.result @@ -1,10 +1,10 @@ -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; drop database if exists mysqltest; create database mysqltest; use mysqltest; * TEST of recovery with blobs * shut down mysqld, removed logs, restarted it -create table t1 (a int, b longtext) engine=maria table_checksum=1; +create table t1 (a int, b longtext) engine=aria table_checksum=1; * copied t1 for feeding_recovery insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321"); flush table t1; @@ -62,7 +62,7 @@ a length(b) 2 5 SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * copied t1 back for feeding_recovery * recovery happens diff --git a/mysql-test/suite/maria/r/maria-recovery-bitmap.result b/mysql-test/suite/maria/r/maria-recovery-bitmap.result index 01255c2394f..884825d4792 100644 --- a/mysql-test/suite/maria/r/maria-recovery-bitmap.result +++ b/mysql-test/suite/maria/r/maria-recovery-bitmap.result @@ -2,7 +2,7 @@ drop database if exists mysqltest; create database mysqltest; use mysqltest; * shut down mysqld, removed logs, restarted it -create table t1 (a varchar(10000)) engine=maria; +create table t1 (a varchar(10000)) engine=aria; * TEST of over-allocated bitmap not flushed by checkpoint insert into t1 values ("bbbbbbb"); flush table t1; @@ -11,10 +11,10 @@ insert into t1 values ("bbbbbbb"); delete from t1 limit 1; set session debug="+d,info,enter,exit,maria_over_alloc_bitmap"; insert into t1 values ("aaaaaaaaa"); -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; SET SESSION debug="+d,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -31,7 +31,7 @@ lock tables t1 write; insert into t1 values (REPEAT('a', 6000)); SET SESSION debug="+d,maria_flush_bitmap,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; diff --git a/mysql-test/suite/maria/r/maria-recovery-rtree-ft.result b/mysql-test/suite/maria/r/maria-recovery-rtree-ft.result index b8b0daa0ad8..57a2927c749 100644 --- a/mysql-test/suite/maria/r/maria-recovery-rtree-ft.result +++ b/mysql-test/suite/maria/r/maria-recovery-rtree-ft.result @@ -1,4 +1,4 @@ -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; drop database if exists mysqltest; create database mysqltest; use mysqltest; @@ -8,12 +8,12 @@ line LINESTRING NOT NULL, kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po', name VARCHAR(32) ,SPATIAL key (line) -) transactional=1 row_format=page engine=maria; +) transactional=1 row_format=page engine=aria; SHOW INDEX FROM t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 1 line 1 line A NULL 32 NULL SPATIAL CREATE TABLE t2 (a VARCHAR(200), b TEXT, FULLTEXT (a,b) -) transactional=1 row_format=page engine=maria; +) transactional=1 row_format=page engine=aria; SHOW INDEX FROM t2; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t2 1 a 1 a NULL NULL NULL NULL YES FULLTEXT @@ -27,7 +27,7 @@ flush table t1; * copied t1 for comparison SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * copied t2 back for feeding_recovery * copied t1 back for feeding_recovery @@ -53,7 +53,7 @@ flush table t1; lock tables t1 write, t2 write; SET SESSION debug="+d,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t2 extended; @@ -76,7 +76,7 @@ flush table t1; lock tables t1 write, t2 write; SET SESSION debug="+d,maria_flush_whole_page_cache,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t2 extended; @@ -99,7 +99,7 @@ flush table t1; lock tables t1 write, t2 write; SET SESSION debug="+d,maria_flush_states,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t2 extended; @@ -122,7 +122,7 @@ flush table t1; lock tables t1 write, t2 write; SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t2 extended; @@ -140,7 +140,7 @@ ok use mysqltest; SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t2 extended; diff --git a/mysql-test/suite/maria/r/maria-recovery.result b/mysql-test/suite/maria/r/maria-recovery.result index b0440489cd1..cfabbf10be9 100644 --- a/mysql-test/suite/maria/r/maria-recovery.result +++ b/mysql-test/suite/maria/r/maria-recovery.result @@ -1,9 +1,9 @@ -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; drop database if exists mysqltest; create database mysqltest; use mysqltest; * shut down mysqld, removed logs, restarted it -create table t1 (a varchar(1000)) engine=maria; +create table t1 (a varchar(1000)) engine=aria; * TEST of REDO: see if recovery can reconstruct if we give it an old table * copied t1 for feeding_recovery insert into t1 values ("00000000"); @@ -11,7 +11,7 @@ flush table t1; * copied t1 for comparison SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * copied t1 back for feeding_recovery * recovery happens @@ -34,7 +34,7 @@ lock tables t1 write; insert into t1 values ("aaaaaaaaa"); SET SESSION debug="+d,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -55,7 +55,7 @@ lock tables t1 write; insert into t1 values ("aaaaaaaaa"); SET SESSION debug="+d,maria_flush_whole_page_cache,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -77,7 +77,7 @@ lock tables t1 write; insert into t1 values ("aaaaaaaaa"); SET SESSION debug="+d,maria_flush_states,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -100,7 +100,7 @@ lock tables t1 write; insert into t1 values ("aaaaaaaaa"); SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -124,7 +124,7 @@ CREATE TABLE t1 ( i int, b blob default NULL, c varchar(6000) default NULL -) ENGINE=MARIA CHECKSUM=1; +) ENGINE=ARIA CHECKSUM=1; * copied t1 for feeding_recovery INSERT INTO t1 VALUES (1, REPEAT('a', 5000), REPEAT('b', 5000)); UPDATE t1 SET i=3, b=CONCAT(b,'c') WHERE i=1; @@ -135,7 +135,7 @@ flush table t1; * copied t1 for comparison SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * copied t1 back for feeding_recovery * recovery happens @@ -156,7 +156,7 @@ CREATE TABLE t1 ( i int auto_increment primary key, c varchar(6), key(c) -) ENGINE=MARIA; +) ENGINE=ARIA; insert into t1 values(null,"b"); * copied t1 for feeding_recovery insert into t1 values(null,"a"), (null,"c"), (null,"d"); @@ -165,7 +165,7 @@ flush table t1; * copied t1 for comparison SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * copied t1 back for feeding_recovery * recovery happens @@ -183,7 +183,7 @@ t1 CREATE TABLE `t1` ( `c` varchar(6) DEFAULT NULL, PRIMARY KEY (`i`), KEY `c` (`c`) -) ENGINE=MARIA AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 * TEST of UPDATE vs state.auto_increment * copied t1 for feeding_recovery update t1 set i=15 where c="a"; @@ -191,7 +191,7 @@ flush table t1; * copied t1 for comparison SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * copied t1 back for feeding_recovery * recovery happens @@ -209,7 +209,7 @@ t1 CREATE TABLE `t1` ( `c` varchar(6) DEFAULT NULL, PRIMARY KEY (`i`), KEY `c` (`c`) -) ENGINE=MARIA AUTO_INCREMENT=16 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria AUTO_INCREMENT=16 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 * TEST of INSERT's rollback vs state.auto_increment flush table t1; * copied t1 for comparison @@ -217,7 +217,7 @@ lock tables t1 write; insert into t1 values(null, "e"); SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -234,7 +234,7 @@ t1 CREATE TABLE `t1` ( `c` varchar(6) DEFAULT NULL, PRIMARY KEY (`i`), KEY `c` (`c`) -) ENGINE=MARIA AUTO_INCREMENT=17 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria AUTO_INCREMENT=17 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 insert into t1 values(null, "f"); drop table t1; drop database mysqltest_for_feeding_recovery; diff --git a/mysql-test/suite/maria/r/maria-recovery2.result b/mysql-test/suite/maria/r/maria-recovery2.result index bca6d0d7c74..b78d7dcc4e7 100644 --- a/mysql-test/suite/maria/r/maria-recovery2.result +++ b/mysql-test/suite/maria/r/maria-recovery2.result @@ -1,13 +1,13 @@ -call mtr.add_suppression("File '.*maria_log.000.*' not found \\(Errcode: 2\\)"); -call mtr.add_suppression("Table '.\/mysqltest\/t_corrupted1' is crashed, skipping it. Please repair it with maria_chk -r"); -set global maria_log_file_size=4294967295; +call mtr.add_suppression("File '.*aria_log.000.*' not found \\(Errcode: 2\\)"); +call mtr.add_suppression("Table '.\/mysqltest\/t_corrupted1' is crashed, skipping it. Please repair it with aria_chk -r"); +set global aria_log_file_size=4294967295; drop database if exists mysqltest; create database mysqltest; use mysqltest; * TEST of removing logs manually * shut down mysqld, removed logs, restarted it * TEST of UNDO_ROW_DELETE preserving rowid -create table t1(a int) engine=maria; +create table t1(a int) engine=aria; insert into t1 values(1),(2); flush table t1; * copied t1 for comparison @@ -16,7 +16,7 @@ insert into t1 values(3); delete from t1 where a in (1,2,3); SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -29,8 +29,8 @@ use mysqltest; drop table t1; * TEST of checkpoint set global debug="+d,info,query,enter,exit,loop,maria_checkpoint_indirect"; -set global maria_checkpoint_interval=10000; -create table t1(a int, b varchar(10), index(a,b)) engine=maria; +set global aria_checkpoint_interval=10000; +create table t1(a int, b varchar(10), index(a,b)) engine=aria; insert into t1 values(1,"a"),(2,"b"),(3,"c"); delete from t1 where b="b"; update t1 set b="d" where a=1; @@ -40,14 +40,14 @@ lock tables t1 write; insert into t1 values(4,"e"),(5,"f"),(6,"g"); update t1 set b="h" where a=5; delete from t1 where b="g"; -show status like "Maria_pagecache_blocks_not_flushed"; +show status like "Aria_pagecache_blocks_not_flushed"; Variable_name Value -Maria_pagecache_blocks_not_flushed 3 -set global maria_checkpoint_interval=10000; +Aria_pagecache_blocks_not_flushed 3 +set global aria_checkpoint_interval=10000; update t1 set b="i" where a=5; SET SESSION debug="+d,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -59,7 +59,7 @@ ok use mysqltest; drop table t1; Test of REPAIR's implicit commit -create table t1 (a varchar(100), key(a)) engine=maria; +create table t1 (a varchar(100), key(a)) engine=aria; insert into t1 values(3); flush table t1; * copied t1 for comparison @@ -76,7 +76,7 @@ a 3 SET SESSION debug="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -92,7 +92,7 @@ a 3 drop table t1; * TEST of recovery when crash before bulk-insert-with-repair is committed -create table t1 (a varchar(100), key(a)) engine=maria; +create table t1 (a varchar(100), key(a)) engine=aria; create table t2 (a varchar(100)) engine=myisam; set rand_seed1=12, rand_seed2=254; insert into t2 values (rand()); @@ -110,7 +110,7 @@ delete from t1 limit 1; insert into t1 select * from t2; SET SESSION debug="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -125,7 +125,7 @@ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_par t1 1 a 1 a A 1 NULL NULL YES BTREE drop table t1; * TEST of recovery when OPTIMIZE has replaced the index file and crash -create table t_corrupted1 (a varchar(100), key(a)) engine=maria; +create table t_corrupted1 (a varchar(100), key(a)) engine=aria; insert into t_corrupted1 select (rand()) from t2; flush table t_corrupted1; * copied t_corrupted1 for comparison diff --git a/mysql-test/suite/maria/r/maria-recovery3.result b/mysql-test/suite/maria/r/maria-recovery3.result index 118ec537901..cab3fd55091 100644 --- a/mysql-test/suite/maria/r/maria-recovery3.result +++ b/mysql-test/suite/maria/r/maria-recovery3.result @@ -1,20 +1,20 @@ -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; drop database if exists mysqltest; create database mysqltest; use mysqltest; * shut down mysqld, removed logs, restarted it * TEST of Checkpoint between writing the commit log record and committing in trnman -create table t1(a int primary key) engine=maria; +create table t1(a int primary key) engine=aria; insert into t1 values(1); flush table t1; * copied t1 for comparison set session debug="+d,maria_sleep_in_commit"; insert into t1 values(2); -set global maria_checkpoint_interval=1000; +set global aria_checkpoint_interval=1000; delete from t1 where a=2; SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; @@ -29,11 +29,11 @@ drop table t1; CREATE TABLE `t1` ( `blob` blob, `blob_key` blob -) ENGINE=maria ROW_FORMAT=page +) ENGINE=aria ROW_FORMAT=page ; * copied t1 for feeding_recovery * compared t1 to old version -set global maria_checkpoint_interval=0; +set global aria_checkpoint_interval=0; INSERT INTO `t1` VALUES (NULL,repeat('A',5198)); INSERT INTO `t1` VALUES (NULL,repeat('B',65535)); INSERT INTO `t1` VALUES (repeat('K',5198),repeat('L',2325)); @@ -50,7 +50,7 @@ flush table t1; * compared t1 to old version SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; * crashing mysqld intentionally -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; ERROR HY000: Lost connection to MySQL server during query * copied t1 back for feeding_recovery * recovery happens @@ -63,9 +63,9 @@ ok * compared t1 to old version use mysqltest; drop table t1; -create table t1 engine=maria select 1; +create table t1 engine=aria select 1; * copied t1 for feeding_recovery -set global maria_checkpoint_interval=0; +set global aria_checkpoint_interval=0; insert into t1 values(2); truncate table t1; flush table t1; @@ -78,7 +78,7 @@ ERROR HY000: Lost connection to MySQL server during query * recovery happens check table t1 extended; Table Op Msg_type Msg_text -mysqltest.t1 check warning Size of indexfile is: 372 Should be: 8192 +mysqltest.t1 check warning Size of indexfile is: 372 Expected: 8192 mysqltest.t1 check status OK * testing that checksum after recovery is as expected Checksum-check diff --git a/mysql-test/suite/maria/r/maria.result b/mysql-test/suite/maria/r/maria.result index 5d1e8f98c38..217955310f9 100644 --- a/mysql-test/suite/maria/r/maria.result +++ b/mysql-test/suite/maria/r/maria.result @@ -1,10 +1,10 @@ -select * from INFORMATION_SCHEMA.ENGINES where ENGINE="MARIA"; +select * from INFORMATION_SCHEMA.ENGINES where ENGINE="ARIA"; ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS -MARIA YES Crash-safe tables with MyISAM heritage YES NO NO -set global storage_engine=maria; -set session storage_engine=maria; -set global maria_page_checksum=0; -set global maria_log_file_size=4294967295; +Aria YES Crash-safe tables with MyISAM heritage NO NO NO +set global storage_engine=aria; +set session storage_engine=aria; +set global aria_page_checksum=0; +set global aria_log_file_size=4294967295; drop table if exists t1,t2; drop view if exists v1; SET SQL_WARNINGS=1; @@ -702,9 +702,9 @@ checksum table t1; Table Checksum test.t1 4183529555 drop table t1; -show variables like 'maria_stats_method'; +show variables like 'aria_stats_method'; Variable_name Value -maria_stats_method nulls_unequal +aria_stats_method nulls_unequal create table t1 (a int, key(a)); insert into t1 values (0),(1),(2),(3),(4); insert into t1 select NULL from t1; @@ -722,10 +722,10 @@ test.t1 check status OK show index from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 1 a 1 a A 10 NULL NULL YES BTREE -set maria_stats_method=nulls_equal; -show variables like 'maria_stats_method'; +set aria_stats_method=nulls_equal; +show variables like 'aria_stats_method'; Variable_name Value -maria_stats_method nulls_equal +aria_stats_method nulls_equal insert into t1 values (11); delete from t1 where a=11; analyze table t1; @@ -742,10 +742,10 @@ test.t1 check status OK show index from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 1 a 1 a A 5 NULL NULL YES BTREE -set maria_stats_method=DEFAULT; -show variables like 'maria_stats_method'; +set aria_stats_method=DEFAULT; +show variables like 'aria_stats_method'; Variable_name Value -maria_stats_method nulls_unequal +aria_stats_method nulls_unequal insert into t1 values (11); delete from t1 where a=11; analyze table t1; @@ -763,10 +763,10 @@ show index from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 1 a 1 a A 10 NULL NULL YES BTREE drop table t1; -set maria_stats_method=nulls_ignored; -show variables like 'maria_stats_method'; +set aria_stats_method=nulls_ignored; +show variables like 'aria_stats_method'; Variable_name Value -maria_stats_method nulls_ignored +aria_stats_method nulls_ignored create table t1 ( a char(3), b char(4), c char(5), d char(6), key(a,b,c,d) @@ -794,7 +794,7 @@ t1 1 a 1 a A 0 NULL NULL YES BTREE t1 1 a 2 b A 0 NULL NULL YES BTREE t1 1 a 3 c A 0 NULL NULL YES BTREE t1 1 a 4 d A 0 NULL NULL YES BTREE -set maria_stats_method=DEFAULT; +set aria_stats_method=DEFAULT; drop table t1; create table t1( cip INT NOT NULL, @@ -819,7 +819,7 @@ id2 int not null default '0', t text not null, primary key (id1), key x (id2, t(32)) -) engine=maria; +) engine=aria; insert into t1 (id2, t) values (10, 'abc'), (10, 'abc'), (10, 'abc'), (20, 'abc'), (20, 'abc'), (20, 'def'), @@ -852,10 +852,10 @@ a b xxxxxxxxx bbbbbb xxxxxxxxx bbbbbb DROP TABLE t1; -SET @@maria_repair_threads=2; -SHOW VARIABLES LIKE 'maria_repair%'; +SET @@aria_repair_threads=2; +SHOW VARIABLES LIKE 'aria_repair%'; Variable_name Value -maria_repair_threads 2 +aria_repair_threads 2 CREATE TABLE t1 ( `_id` int(11) NOT NULL default '0', `url` text, @@ -897,7 +897,7 @@ _id DELETE FROM t1 WHERE _id < 8; SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 2 # # # # 0 # # # # # # +t1 Aria 10 Page 2 # # # # 0 # # # # # # CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK @@ -909,7 +909,7 @@ Table Op Msg_type Msg_text test.t1 check status OK SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 2 # # # # 0 # # # # # # +t1 Aria 10 Page 2 # # # # 0 # # # # # # SELECT _id FROM t1; _id 8 @@ -956,7 +956,7 @@ _id DELETE FROM t1 WHERE _id < 8; SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 2 # # # # 0 # # # # # # +t1 Aria 10 Page 2 # # # # 0 # # # # # # CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK @@ -968,16 +968,16 @@ Table Op Msg_type Msg_text test.t1 check status OK SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 2 # # # # 0 # # # # # # +t1 Aria 10 Page 2 # # # # 0 # # # # # # SELECT _id FROM t1; _id 8 9 DROP TABLE t1; -SET @@maria_repair_threads=1; -SHOW VARIABLES LIKE 'maria_repair%'; +SET @@aria_repair_threads=1; +SHOW VARIABLES LIKE 'aria_repair%'; Variable_name Value -maria_repair_threads 1 +aria_repair_threads 1 drop table if exists t1,t2,t3; --- Testing varchar --- --- Testing varchar --- @@ -997,7 +997,7 @@ t1 CREATE TABLE `t1` ( `v` varchar(10) DEFAULT NULL, `c` char(10) DEFAULT NULL, `t` text -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 create table t2 like t1; show create table t2; Table Create Table @@ -1005,7 +1005,7 @@ t2 CREATE TABLE `t2` ( `v` varchar(10) DEFAULT NULL, `c` char(10) DEFAULT NULL, `t` text -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 create table t3 select * from t1; show create table t3; Table Create Table @@ -1013,7 +1013,7 @@ t3 CREATE TABLE `t3` ( `v` varchar(10) DEFAULT NULL, `c` char(10) DEFAULT NULL, `t` text -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 alter table t1 modify c varchar(10); show create table t1; Table Create Table @@ -1021,7 +1021,7 @@ t1 CREATE TABLE `t1` ( `v` varchar(10) DEFAULT NULL, `c` varchar(10) DEFAULT NULL, `t` text -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 alter table t1 modify v char(10); show create table t1; Table Create Table @@ -1029,7 +1029,7 @@ t1 CREATE TABLE `t1` ( `v` char(10) DEFAULT NULL, `c` varchar(10) DEFAULT NULL, `t` text -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 alter table t1 modify t varchar(10); Warnings: Note 1265 Data truncated for column 't' at row 2 @@ -1039,7 +1039,7 @@ t1 CREATE TABLE `t1` ( `v` char(10) DEFAULT NULL, `c` varchar(10) DEFAULT NULL, `t` varchar(10) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 select concat('*',v,'*',c,'*',t,'*') from t1; concat('*',v,'*',c,'*',t,'*') *+*+*+ * @@ -1055,7 +1055,7 @@ t1 CREATE TABLE `t1` ( KEY `v` (`v`), KEY `c` (`c`), KEY `t` (`t`(10)) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 select count(*) from t1; count(*) 270 @@ -1274,7 +1274,7 @@ t1 CREATE TABLE `t1` ( KEY `c` (`c`), KEY `t` (`t`(10)), KEY `v` (`v`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 select count(*) from t1 where v='a'; count(*) 10 @@ -1354,7 +1354,7 @@ t1 CREATE TABLE `t1` ( KEY `c` (`c`), KEY `t` (`t`(10)), KEY `v` (`v`(30)) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 select count(*) from t1 where v='a'; count(*) 10 @@ -1434,7 +1434,7 @@ t1 CREATE TABLE `t1` ( KEY `c` (`c`), KEY `t` (`t`(10)), KEY `v` (`v`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 select v,count(*) from t1 group by v limit 10; v count(*) a 1 @@ -1512,14 +1512,14 @@ t1 CREATE TABLE `t1` ( KEY `v` (`v`(5)), KEY `c` (`c`(5)), KEY `t` (`t`(5)) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (v char(10) character set utf8); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `v` char(10) CHARACTER SET utf8 DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (v varchar(10), c char(10)) row_format=fixed; show create table t1; @@ -1527,7 +1527,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `v` varchar(10) DEFAULT NULL, `c` char(10) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED insert into t1 values('a','a'),('a ','a '); select concat('*',v,'*',c,'*') from t1; concat('*',v,'*',c,'*') @@ -1560,7 +1560,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `v` mediumtext -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (v varchar(65530) character set utf8); Warnings: @@ -1569,7 +1569,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `v` mediumtext CHARACTER SET utf8 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (v varchar(65535)); ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs @@ -1696,32 +1696,32 @@ DROP TABLE t1; CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE INDEX (c1), INDEX (c2)); SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 0 # # # 8192 # # # # # # # +t1 Aria 10 Page 0 # # # 8192 # # # # # # # INSERT INTO t1 VALUES (1,1); SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 1 # # # 24576 # # # # # # # +t1 Aria 10 Page 1 # # # 24576 # # # # # # # ALTER TABLE t1 DISABLE KEYS; SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 1 # # # 24576 # # # # # # # +t1 Aria 10 Page 1 # # # 24576 # # # # # # # ALTER TABLE t1 ENABLE KEYS; SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 1 # # # 24576 # # # # # # # +t1 Aria 10 Page 1 # # # 24576 # # # # # # # ALTER TABLE t1 DISABLE KEYS; SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 1 # # # 24576 # # # # # # # +t1 Aria 10 Page 1 # # # 24576 # # # # # # # ALTER TABLE t1 ENABLE KEYS; SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 1 # # # 24576 # # # # # # # +t1 Aria 10 Page 1 # # # 24576 # # # # # # # # Enable keys with parallel repair -SET @@maria_repair_threads=2; +SET @@aria_repair_threads=2; ALTER TABLE t1 DISABLE KEYS; ALTER TABLE t1 ENABLE KEYS; -SET @@maria_repair_threads=1; +SET @@aria_repair_threads=1; CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK @@ -1748,7 +1748,7 @@ id ref 3 2 4 5 DROP TABLE t1, t2; -CREATE TABLE t1 (a INT) ENGINE=MARIA CHECKSUM=1 ROW_FORMAT=DYNAMIC; +CREATE TABLE t1 (a INT) ENGINE=ARIA CHECKSUM=1 ROW_FORMAT=DYNAMIC; INSERT INTO t1 VALUES (0); UPDATE t1 SET a=1; SELECT a FROM t1; @@ -1777,7 +1777,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, key `a` (a) key_block_size=2048); show create table t1; @@ -1785,7 +1785,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a varchar(2048), key `a` (a)); Warnings: @@ -1795,7 +1795,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(2048) DEFAULT NULL, KEY `a` (`a`(1208)) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a varchar(2048), key `a` (a) key_block_size=1024); Warnings: @@ -1805,7 +1805,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(2048) DEFAULT NULL, KEY `a` (`a`(1208)) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024; Warnings: @@ -1817,7 +1817,7 @@ t1 CREATE TABLE `t1` ( `b` varchar(2048) DEFAULT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192, KEY `b` (`b`(1208)) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=1024 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=1024 alter table t1 key_block_size=2048; show create table t1; Table Create Table @@ -1826,7 +1826,7 @@ t1 CREATE TABLE `t1` ( `b` varchar(2048) DEFAULT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192, KEY `b` (`b`(1208)) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=2048 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=2048 alter table t1 add c int, add key (c); show create table t1; Table Create Table @@ -1837,7 +1837,7 @@ t1 CREATE TABLE `t1` ( KEY `a` (`a`) KEY_BLOCK_SIZE=8192, KEY `b` (`b`(1208)) KEY_BLOCK_SIZE=8192, KEY `c` (`c`) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=2048 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=2048 alter table t1 key_block_size=0; alter table t1 add d int, add key (d); show create table t1; @@ -1851,7 +1851,7 @@ t1 CREATE TABLE `t1` ( KEY `b` (`b`(1208)) KEY_BLOCK_SIZE=8192, KEY `c` (`c`) KEY_BLOCK_SIZE=8192, KEY `d` (`d`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192; Warnings: @@ -1863,7 +1863,7 @@ t1 CREATE TABLE `t1` ( `b` varchar(2048) DEFAULT NULL, KEY `a` (`a`), KEY `b` (`b`(1208)) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=8192 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=8192 drop table t1; create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192; Warnings: @@ -1875,7 +1875,7 @@ t1 CREATE TABLE `t1` ( `b` varchar(2048) DEFAULT NULL, KEY `a` (`a`), KEY `b` (`b`(1208)) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=8192 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=8192 drop table t1; create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384; show create table t1; @@ -1885,7 +1885,7 @@ t1 CREATE TABLE `t1` ( `b` int(11) DEFAULT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192, KEY `b` (`b`) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=16384 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=16384 drop table t1; create table t1 (a int not null, key `a` (a) key_block_size=512); show create table t1; @@ -1893,7 +1893,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000); Warnings: @@ -1903,7 +1903,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(2048) DEFAULT NULL, KEY `a` (`a`(1208)) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, key `a` (a) key_block_size=1025); show create table t1; @@ -1911,7 +1911,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, key key_block_size=1024 (a)); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=1024 (a))' at line 1 @@ -1965,7 +1965,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(130), c2 VARCHAR(1) -) ENGINE=maria; +) ENGINE=aria; INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); SELECT COUNT(*) FROM t1; COUNT(*) @@ -1986,7 +1986,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(130), c2 VARCHAR(1) -) ENGINE=maria; +) ENGINE=aria; INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); SELECT COUNT(*) FROM t1; COUNT(*) @@ -2007,7 +2007,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(130), c2 VARCHAR(1) -) ENGINE=maria; +) ENGINE=aria; INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); INSERT INTO t1 VALUES('b', 'b'); INSERT INTO t1 VALUES('c', 'b'); @@ -2026,13 +2026,13 @@ CREATE TABLE t1 ( c1 CHAR(130), c2 VARCHAR(1), KEY (c1) -) ENGINE=maria; +) ENGINE=aria; # Insert 100 rows. Query log disabled. UPDATE t1 SET c1=REPEAT("a",128) LIMIT 90; SELECT COUNT(*) FROM t1; COUNT(*) 100 -ALTER TABLE t1 ENGINE=maria; +ALTER TABLE t1 ENGINE=aria; SELECT COUNT(*) FROM t1; COUNT(*) 100 @@ -2046,7 +2046,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(50), c2 VARCHAR(1) -) ENGINE=maria DEFAULT CHARSET UTF8; +) ENGINE=aria DEFAULT CHARSET UTF8; INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); SELECT COUNT(*) FROM t1; COUNT(*) @@ -2067,7 +2067,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(50), c2 VARCHAR(1) -) ENGINE=maria DEFAULT CHARSET UTF8; +) ENGINE=aria DEFAULT CHARSET UTF8; INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); SELECT COUNT(*) FROM t1; COUNT(*) @@ -2088,7 +2088,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(50), c2 VARCHAR(1) -) ENGINE=maria DEFAULT CHARSET UTF8; +) ENGINE=aria DEFAULT CHARSET UTF8; INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); INSERT INTO t1 VALUES('b', 'b'); INSERT INTO t1 VALUES('c', 'b'); @@ -2107,13 +2107,13 @@ CREATE TABLE t1 ( c1 CHAR(50), c2 VARCHAR(1), KEY (c1) -) ENGINE=maria DEFAULT CHARSET UTF8; +) ENGINE=aria DEFAULT CHARSET UTF8; # Insert 100 rows. Query log disabled. UPDATE t1 SET c1=REPEAT(_utf8 x'e0ae85',43) LIMIT 90; SELECT COUNT(*) FROM t1; COUNT(*) 100 -ALTER TABLE t1 ENGINE=maria; +ALTER TABLE t1 ENGINE=aria; SELECT COUNT(*) FROM t1; COUNT(*) 100 @@ -2130,8 +2130,8 @@ c2 CHAR(10) DEFAULT NULL, c3 VARCHAR(10) NOT NULL, KEY (c1), KEY (c2) -) ENGINE=maria DEFAULT CHARSET=utf8 PACK_KEYS=0; -MARIA file: MYSQLD_DATADIR/test/t1 +) ENGINE=aria DEFAULT CHARSET=utf8 PACK_KEYS=0; +Aria file: MYSQLD_DATADIR/test/t1 Record format: Block Crashsafe: yes Character set: utf8_general_ci (33) @@ -2150,14 +2150,14 @@ Table Create Table t1 CREATE TABLE `t1` ( `n` int(11) NOT NULL, `c` char(1) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 TRANSACTIONAL=1 drop table t1; -CREATE TABLE t1 (line LINESTRING NOT NULL) engine=maria; +CREATE TABLE t1 (line LINESTRING NOT NULL) engine=aria; INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)")); checksum table t1; Table Checksum test.t1 326284887 -CREATE TABLE t2 (line LINESTRING NOT NULL) engine=maria; +CREATE TABLE t2 (line LINESTRING NOT NULL) engine=aria; INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)")); checksum table t2; Table Checksum @@ -2168,7 +2168,7 @@ Table Checksum test.t3 326284887 drop table t1,t2,t3; End of 5.1 tests -create table t2(a varchar(255),key(a))engine=maria row_format=dynamic transactional=0; +create table t2(a varchar(255),key(a))engine=aria row_format=dynamic transactional=0; insert into t2 values (repeat('o',124)), (repeat('h',226)), (repeat('i',236)), (repeat('l',234)), (repeat('b',13)), (repeat('g',236)), (repeat('y',205)), (repeat('c',99)), (repeat('g',145)), (repeat('o',131)), (repeat('e',63)), @@ -2380,7 +2380,7 @@ col172 tinyint(1) DEFAULT NULL, col173 tinytext, col174 decimal(10,0) DEFAULT NULL, col175 double DEFAULT NULL -) engine=maria; +) engine=aria; insert ignore into t1 set col10=abs(28449) % 2, col11='1973', @@ -2505,7 +2505,7 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; -create table t1 (a char(200) primary key, b int default 12345) engine=maria; +create table t1 (a char(200) primary key, b int default 12345) engine=aria; insert t1 (a) values (repeat('0', 200)); insert t1 (a) values (repeat('1', 200)), (repeat('2', 200)), (repeat('3', 200)), (repeat('4', 200)), (repeat('5', 200)), (repeat('6', 200)), (repeat('7', 200)), @@ -2525,14 +2525,14 @@ b 12345 12345 drop table t1; -create table t1 (a int) engine=maria transactional=1; +create table t1 (a int) engine=aria transactional=1; insert into t1 values (1); lock table t1 write concurrent; delete from t1; ERROR 42000: The storage engine for the table doesn't support DELETE in WRITE CONCURRENT drop table t1; create table t1 (p int primary key, i int, a char(10), key k1(i), key k2(a)) -engine maria; +engine aria; insert into t1 values (1, 1, 'qqqq'), (2, 1, 'pppp'), (3, 1, 'yyyy'), (4, 3, 'zzzz'); insert into t1 values (5, 3, 'yyyy'), (6, 3, 'yyyy'), (7, 0, NULL), @@ -2563,8 +2563,8 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; -create table t1 (f1 int unique, f2 int) engine=maria; -create table t2 (f3 int, f4 int) engine=maria; +create table t1 (f1 int unique, f2 int) engine=aria; +create table t2 (f3 int, f4 int) engine=aria; create view v1 as select * from t1, t2 where f1= f3; insert into t1 values (1,11), (2,22); insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; @@ -2573,7 +2573,7 @@ insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; ERROR HY000: Can not modify more than one base table through a join view 'test.v1' drop table t1,t2; drop view v1; -CREATE TABLE t1 (id int, c varchar(10)) engine=maria; +CREATE TABLE t1 (id int, c varchar(10)) engine=aria; INSERT INTO t1 VALUES (1,"1"); ALTER TABLE t1 CHANGE c d varchar(10); affected rows: 0 @@ -2590,7 +2590,7 @@ lock table t1 read, t2 read; flush tables with read lock; unlock tables; drop table t1, t2; -create table t1(a int primary key, b blob, c blob) engine=maria; +create table t1(a int primary key, b blob, c blob) engine=aria; insert into t1 values(1,repeat('a',100), repeat('b',657860)); Warnings: Warning 1265 Data truncated for column 'c' at row 1 @@ -2605,7 +2605,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; CREATE TABLE t1 ( f1 DOUBLE , f2 DOUBLE , f3 DOUBLE , f4 DOUBLE , v3 DOUBLE , v4 DOUBLE , KEY ( v3 ) , KEY ( v4 ) ) engine=maria; REPLACE t1 ( f2 , f1 ) VALUES ( f2 , 56 ) ; @@ -2618,7 +2618,7 @@ f1 CHAR(255) BINARY , f2 CHAR(255) BINARY NOT NULL DEFAULT '0', f3 CHAR(255) BINARY NOT NULL , f4 CHAR(255) BINARY NOT NULL DEFAULT '0' , -v3 CHAR(255) BINARY NOT NULL DEFAULT '0' , +v3 CHAR(255) BINARY AS ( ( f1 NOT LIKE '%' ) ) PERSISTENT, KEY (v3) ) ENGINE=Maria; INSERT INTO t1 ( f1 , f2 , f3 , f4 ) SELECT f1 , f4 , f1 , f4 FROM t1; diff --git a/mysql-test/suite/maria/r/maria2.result b/mysql-test/suite/maria/r/maria2.result index e721ceaafae..f145a4884e7 100644 --- a/mysql-test/suite/maria/r/maria2.result +++ b/mysql-test/suite/maria/r/maria2.result @@ -3,7 +3,7 @@ CREATE TABLE t1 ( line BLOB, kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po', name VARCHAR(32) -) transactional=0 row_format=page engine=maria; +) transactional=0 row_format=page engine=aria; select count(*) from t1; count(*) 810 @@ -17,8 +17,8 @@ check table t1 extended; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; -create table t1 (i int) engine=maria; -create table t2 (j int) engine=maria; +create table t1 (i int) engine=aria; +create table t2 (j int) engine=aria; lock table t1 write, t2 read; alter table t1 modify i int default 1; insert into t1 values (2); @@ -30,7 +30,7 @@ select * from t1; i 2 drop table t1,t2; -create table t1(id int, s char(1), unique(s)) engine=maria; +create table t1(id int, s char(1), unique(s)) engine=aria; insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1; insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1; insert into t1 select 1,"a" on duplicate key update t1.id=t1.id+1; @@ -42,7 +42,7 @@ select * from t1; id s 1 a drop table t1; -create table t1 (pk int primary key, apk int unique, data int) engine=maria; +create table t1 (pk int primary key, apk int unique, data int) engine=aria; insert into t1 values (1, 1, 1), (4, 4, 4), (6, 6, 6); load data concurrent infile '../../std_data/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk); select * from t1 order by pk; diff --git a/mysql-test/suite/maria/r/maria3.result b/mysql-test/suite/maria/r/maria3.result index f7cc08bfd0d..383dce6fd57 100644 --- a/mysql-test/suite/maria/r/maria3.result +++ b/mysql-test/suite/maria/r/maria3.result @@ -1,10 +1,10 @@ -select * from INFORMATION_SCHEMA.ENGINES where ENGINE="MARIA"; +select * from INFORMATION_SCHEMA.ENGINES where ENGINE="ARIA"; ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS -MARIA YES Crash-safe tables with MyISAM heritage YES NO NO -set global storage_engine=maria; -set session storage_engine=maria; -set global maria_page_checksum=0; -set global maria_log_file_size=4294967295; +Aria YES Crash-safe tables with MyISAM heritage NO NO NO +set global storage_engine=aria; +set session storage_engine=aria; +set global aria_page_checksum=0; +set global aria_log_file_size=4294967295; drop table if exists t1,t2; SET SQL_WARNINGS=1; create table t1 (a int not null, key `a` (a) key_block_size=512); @@ -13,7 +13,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000); Warnings: @@ -23,7 +23,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(2048) DEFAULT NULL, KEY `a` (`a`(1208)) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, key `a` (a) key_block_size=1025); show create table t1; @@ -31,7 +31,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192 -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, key key_block_size=1024 (a)); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=1024 (a))' at line 1 @@ -87,14 +87,14 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 TRANSACTIONAL=0 drop table t1; create table t1 (a int) row_format=dynamic transactional=0; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0 drop table t1; create table t1 (a int) row_format=dynamic transactional=1; Warnings: @@ -103,13 +103,13 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 alter table t1 row_format=PAGE; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 alter table t1 row_format=DYNAMIC; Warnings: Note 1478 Row format set to PAGE because of TRANSACTIONAL=1 option @@ -117,46 +117,46 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 alter table t1 transactional=0; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0 alter table t1 row_format=DYNAMIC; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0 drop table t1; create table t1 (a int) row_format=PAGE; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE drop table t1; create table t1 (a int) row_format=PAGE TRANSACTIONAL=DEFAULT; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE alter table t1 row_format=DYNAMIC; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=DYNAMIC +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=DYNAMIC drop table t1; create table t1 (a int) transactional=0 row_format=FIXED; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED TRANSACTIONAL=0 alter table t1 transactional=1; Warnings: Note 1478 Row format set to PAGE because of TRANSACTIONAL=1 option @@ -164,20 +164,20 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 alter table t1 transactional=0; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED TRANSACTIONAL=0 drop table t1; create table t1 (a int) transactional=0 row_format=FIXED; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED TRANSACTIONAL=0 alter table t1 transactional=1; Warnings: Note 1478 Row format set to PAGE because of TRANSACTIONAL=1 option @@ -185,20 +185,20 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=PAGE TRANSACTIONAL=1 alter table t1 transactional=0; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED TRANSACTIONAL=0 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 ROW_FORMAT=FIXED TRANSACTIONAL=0 drop table t1; create table `t1` ( t1_name varchar(255) default null, t1_id int(10) unsigned not null auto_increment, key (t1_name), primary key (t1_id) -) engine=maria auto_increment = 1000 default charset=latin1; +) engine=aria auto_increment = 1000 default charset=latin1; lock tables t1 write; INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002); check table t1; @@ -226,7 +226,7 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; -CREATE TABLE t1 (a int, b int, v varchar(60000)) checksum=1 engine=maria; +CREATE TABLE t1 (a int, b int, v varchar(60000)) checksum=1 engine=aria; insert into t1 values (1,1,"aaa"),(1,2,null); checksum table t1; Table Checksum @@ -278,9 +278,9 @@ KEY (umedium), KEY (ulong), KEY (ulonglong,ulong), KEY (options,flags) -) engine=maria; +) engine=aria; insert into t1 values (10,1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one'); -create table t2 (primary key (auto)) engine=maria row_format=page select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; +create table t2 (primary key (auto)) engine=aria row_format=page select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; check table t1,t2; Table Op Msg_type Msg_text test.t1 check status OK @@ -289,7 +289,7 @@ select t1,t2,length(t3),length(t4),length(t5),length(t6),t7,t8 from t2; t1 t2 length(t3) length(t4) length(t5) length(t6) t7 t8 1 a 256 256 4096 4096 drop table t2; -create table t2 (primary key (auto)) engine=maria row_format=dynamic select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; +create table t2 (primary key (auto)) engine=aria row_format=dynamic select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; check table t2; Table Op Msg_type Msg_text test.t2 check status OK @@ -301,32 +301,36 @@ check table t1 extended; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; -select lower(variable_name) as Variable_name, Variable_value as Value from information_schema.session_variables where variable_name like "maria%" and variable_name not like "maria_used_for_temp_tables" order by 1; +select lower(variable_name) as Variable_name, Variable_value as Value from information_schema.session_variables where variable_name like "aria%" and variable_name not like "aria_used_for_temp_tables" order by 1; Variable_name Value -maria_block_size 8192 -maria_checkpoint_interval 30 -maria_force_start_after_recovery_failures 0 -maria_log_file_size 4294959104 -maria_log_purge_type immediate -maria_max_sort_file_size 9223372036853727232 -maria_pagecache_age_threshold 300 -maria_pagecache_buffer_size 134213632 -maria_pagecache_division_limit 100 -maria_page_checksum OFF -maria_recover NORMAL -maria_repair_threads 1 -maria_sort_buffer_size 134217728 -maria_stats_method nulls_unequal -maria_sync_log_dir NEWFILE -show status like 'maria%'; +aria_block_size 8192 +aria_checkpoint_interval 30 +aria_checkpoint_log_activity 1048576 +aria_force_start_after_recovery_failures 0 +aria_group_commit none +aria_group_commit_interval 0 +aria_log_file_size 4294959104 +aria_log_purge_type immediate +aria_max_sort_file_size 9223372036853727232 +aria_pagecache_age_threshold 300 +aria_pagecache_buffer_size 134213632 +aria_pagecache_division_limit 100 +aria_page_checksum OFF +aria_recover NORMAL +aria_repair_threads 1 +aria_sort_buffer_size 134217728 +aria_stats_method nulls_unequal +aria_sync_log_dir NEWFILE +show status like 'aria%'; Variable_name Value -Maria_pagecache_blocks_not_flushed # -Maria_pagecache_blocks_unused # -Maria_pagecache_blocks_used # -Maria_pagecache_read_requests # -Maria_pagecache_reads # -Maria_pagecache_write_requests # -Maria_pagecache_writes # +Aria_pagecache_blocks_not_flushed # +Aria_pagecache_blocks_unused # +Aria_pagecache_blocks_used # +Aria_pagecache_read_requests # +Aria_pagecache_reads # +Aria_pagecache_write_requests # +Aria_pagecache_writes # +Aria_transaction_log_syncs # create table t1 (b char(0)); insert into t1 values(NULL),(""); select length(b) from t1; @@ -382,15 +386,15 @@ drop table t1; CREATE TABLE t1 (col1 int, s1 char(16) DEFAULT NULL, s2 char(16) DEFAULT NULL, KEY (s1,s2)); insert into t1 (col1) values(0); drop table t1; -set global maria_page_checksum=1; +set global aria_page_checksum=1; create table t1 (a int); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 drop table t1; -set global maria_log_file_size=4294967296; +set global aria_log_file_size=4294967296; Warnings: Warning 1292 Truncated incorrect log_file_size value: '4294967296' create table t1 (a int not null); @@ -412,7 +416,7 @@ create table t3 select * from t1, t2; ERROR 42S21: Duplicate column name 'c' create table t3 select t1.c AS c1, t2.c AS c2,1 as "const" from t1, t2; drop table t1, t2, t3; -create table t1 (t datetime) engine=maria; +create table t1 (t datetime) engine=aria; insert into t1 values (101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959),(20030100000000),(20030000000000); select * from t1; t @@ -497,38 +501,38 @@ n c 301 c 302 d drop table t1; -create table t1 (n int not null, c char(1)) engine=maria; +create table t1 (n int not null, c char(1)) engine=aria; alter table t1 engine=myisam; -alter table t1 engine=maria; +alter table t1 engine=aria; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `n` int(11) NOT NULL, `c` char(1) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 drop table t1; -create table t1 (n int not null, c char(1)) engine=maria transactional=1; +create table t1 (n int not null, c char(1)) engine=aria transactional=1; alter table t1 engine=myisam; Warnings: Error 1478 Table storage engine 'MyISAM' does not support the create option 'TRANSACTIONAL=1' -alter table t1 engine=maria; +alter table t1 engine=aria; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `n` int(11) NOT NULL, `c` char(1) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 drop table t1; create table t1 (n int not null, c char(1)) engine=myisam transactional=1; Warnings: Error 1478 Table storage engine 'MyISAM' does not support the create option 'TRANSACTIONAL=1' -alter table t1 engine=maria; +alter table t1 engine=aria; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `n` int(11) NOT NULL, `c` char(1) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 drop table t1; create table t1 (a int, key(a)) transactional=0; insert into t1 values (0),(1),(2),(3),(4); @@ -600,17 +604,17 @@ SELECT a FROM t1 WHERE MATCH a AGAINST ('+city (of)*' IN BOOLEAN MODE); a City Of God DROP TABLE t1; -create table t1(a int) engine=maria transactional=1; +create table t1(a int) engine=aria transactional=1; select CREATE_OPTIONS from information_schema.TABLES where TABLE_SCHEMA='test' and TABLE_NAME='t1'; CREATE_OPTIONS transactional=1 drop table t1; -create table t1 (a int, unique(a)) engine=maria transactional=1; +create table t1 (a int, unique(a)) engine=aria transactional=1; insert into t1 values(1); insert into t1 values(2),(2); ERROR 23000: Duplicate entry '2' for key 'a' -create table t2 (a int, unique(a)) engine=maria transactional=0 row_format=dynamic; +create table t2 (a int, unique(a)) engine=aria transactional=0 row_format=dynamic; insert into t2 values(1); insert into t2 values(2),(2); ERROR 23000: Duplicate entry '2' for key 'a' diff --git a/mysql-test/suite/maria/r/maria_notembedded.result b/mysql-test/suite/maria/r/maria_notembedded.result index 77325d24421..f9d8bbfedc8 100644 --- a/mysql-test/suite/maria/r/maria_notembedded.result +++ b/mysql-test/suite/maria/r/maria_notembedded.result @@ -1,4 +1,4 @@ -set session storage_engine=maria; +set session storage_engine=aria; create table t1 (a int) row_format=page; insert delayed into t1 values(1); ERROR HY000: DELAYED option not supported for table 't1' diff --git a/mysql-test/suite/maria/r/maria_partition.result b/mysql-test/suite/maria/r/maria_partition.result index e501af7ec4a..372230c0b71 100644 --- a/mysql-test/suite/maria/r/maria_partition.result +++ b/mysql-test/suite/maria/r/maria_partition.result @@ -1,6 +1,6 @@ -set global storage_engine=maria; -set session storage_engine=maria; -set global maria_page_checksum=0; +set global storage_engine=aria; +set session storage_engine=aria; +set global aria_page_checksum=0; drop table if exists t1,t2; drop view if exists v1; SET SQL_WARNINGS=1; @@ -9,8 +9,8 @@ insert into t1 values (1); alter table t1 partition by list (s1) (partition p1 values in (2)); ERROR HY000: Table has no partition for value 1 drop table t1; -create table t2(a blob) engine=maria; -create table t1(a int primary key) engine=maria; +create table t2(a blob) engine=aria; +create table t1(a int primary key) engine=aria; insert into t2 values ('foo'),('bar'); select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb'; a a diff --git a/mysql-test/suite/maria/r/maria_showlog_error.result b/mysql-test/suite/maria/r/maria_showlog_error.result index b27b4a5b21c..e2434efec28 100644 --- a/mysql-test/suite/maria/r/maria_showlog_error.result +++ b/mysql-test/suite/maria/r/maria_showlog_error.result @@ -1,5 +1,5 @@ * shut down mysqld, removed logs, restarted it -show engine maria logs; +show engine aria logs; Type Name Status -MARIA Size unknown ; maria_log.00000001 can't stat +Aria Size unknown ; aria_log.00000001 can't stat * shut down mysqld, removed logs, restarted it diff --git a/mysql-test/suite/maria/r/max_length.result b/mysql-test/suite/maria/r/max_length.result index 668ba01bba5..6db58622698 100644 --- a/mysql-test/suite/maria/r/max_length.result +++ b/mysql-test/suite/maria/r/max_length.result @@ -7,8 +7,8 @@ create table t2 (id int(10) unsigned not null auto_increment primary key, v varc lock tables t1 write,t2 write; show table status like "t_"; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MARIA 10 Page 0 0 8192 268320768 8192 0 1 # # # latin1_swedish_ci NULL max_rows=2 row_format=PAGE -t2 MARIA 10 Page 0 0 8192 17592186011648 8192 0 1 # # # latin1_swedish_ci NULL max_rows=20000000 row_format=PAGE +t1 Aria 10 Page 0 0 8192 268320768 8192 0 1 # # # latin1_swedish_ci NULL max_rows=2 row_format=PAGE +t2 Aria 10 Page 0 0 8192 17592186011648 8192 0 1 # # # latin1_swedish_ci NULL max_rows=20000000 row_format=PAGE insert into t1 values(null, repeat("ab",100),repeat("def",1000)); insert into t1 values(null, repeat("de",200),repeat("ghi",2000)); insert into t1 values(null, repeat("fe",300),repeat("ghi",3000)); diff --git a/mysql-test/suite/maria/r/ps_maria.result b/mysql-test/suite/maria/r/ps_maria.result index c4dfe826b4d..04c14f9c1e4 100644 --- a/mysql-test/suite/maria/r/ps_maria.result +++ b/mysql-test/suite/maria/r/ps_maria.result @@ -4,7 +4,7 @@ create table t1 ( a int, b varchar(30), primary key(a) -) engine = 'MARIA' ; +) engine = 'ARIA' ; create table t9 ( c1 tinyint, c2 smallint, c3 mediumint, c4 int, @@ -17,7 +17,7 @@ c25 blob, c26 text, c27 mediumblob, c28 mediumtext, c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'), c32 set('monday', 'tuesday', 'wednesday'), primary key(c1) -) engine = 'MARIA' ; +) engine = 'ARIA' ; delete from t1 ; insert into t1 values (1,'one'); insert into t1 values (2,'two'); @@ -1166,7 +1166,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 drop table if exists t2 ; create table t2 (s varchar(25), fulltext(s)) TRANSACTIONAL= 0 -ENGINE = 'MARIA' ; +ENGINE = 'ARIA' ; insert into t2 values ('Gravedigger'), ('Greed'),('Hollow Dogs') ; commit ; prepare stmt1 from ' select s from t2 where match (s) against (?) ' ; @@ -1352,7 +1352,7 @@ create table t2 ( a int, b varchar(30), primary key(a) -) engine = 'MARIA' ; +) engine = 'ARIA' ; insert into t2(a,b) select a, b from t1 ; prepare stmt1 from 'update t1 set a=? where b=? and a in (select ? from t2 @@ -1542,7 +1542,7 @@ execute stmt1 using @arg00, @arg01; ERROR 23000: Duplicate entry '82' for key 'PRIMARY' drop table if exists t2 ; create table t2 (id int auto_increment primary key) -ENGINE= 'MARIA' ; +ENGINE= 'ARIA' ; prepare stmt1 from ' select last_insert_id() ' ; insert into t2 values (NULL) ; execute stmt1 ; diff --git a/mysql-test/suite/maria/r/small_blocksize.result b/mysql-test/suite/maria/r/small_blocksize.result new file mode 100644 index 00000000000..f418a1f92ef --- /dev/null +++ b/mysql-test/suite/maria/r/small_blocksize.result @@ -0,0 +1,33 @@ +DROP TABLE if exists t1; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE t1 (col_longtext_ucs2 longtext, col_longtext_utf8 longtext, col_varchar_255_ucs2_key varchar(255), col_set_utf8 set ('a','b'), col_char_255_ucs2 char(255), col_char_255_ucs2_key char(255), col_enum_ucs2 enum ('a','b'), col_varchar_255_ucs2 varchar(255), col_longtext_ucs2_key longtext, col_longtext_utf8_key longtext, col_enum_utf8 enum ('a','b'), col_varchar_255_utf8_key varchar(1024), col_varchar_255_utf8 varchar(255), col_enum_ucs2_key enum ('a','b'), col_enum_utf8_key enum ('a','b'), col_set_utf8_key set ('a','b'), col_char_255_utf8 char(255), pk integer auto_increment, col_set_ucs2_key set ('a','b'), col_char_255_utf8_key char(255), col_set_ucs2 set ('a','b'), primary key (pk)) ENGINE=aria; +INSERT INTO t1 ( col_char_255_utf8, col_varchar_255_utf8_key, col_longtext_utf8_key ) VALUES ( 'lggnqojgqectqlkvskffihliqcwoakzzzjvhkqlwjybkngdbubskflpmzegdrk', REPEAT( 'a', 627 ), 'mlggnqojgqectqlkvskffihliqcwoakzzzjvhkqlwjybkngdbubskflpmzegdrklnipcmzbtwdqfnyinqfohgtiwmvfpbuslgobjhslxnaybcyebhsrlipnuvalhmvhlwbwujtvjsdrbyapfzprnxfgtrukwhywtkaoupsaogxsjxhqjkidvnpeytjgndtnrrbm' ); +UPDATE t1 SET col_varchar_255_utf8 = REPEAT('a', 197 ); +UPDATE t1 SET col_char_255_utf8 = 'bmjihzjtxegprqfvmczyzbavjuozkyxrlxvqyzcfvsjrhcccqnecyohzhzbgsbqkqvzmtlhtlcgzheirkyfwczoolilkrfimfnuoapyylbghdhdgfebjjajfoigagozypqtrflrvdiwfgqalsqbmlllsanvtuuutiaastqtbzeoaawl'; +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +create table t1 (a int primary key auto_increment, e1 enum('a','b'), e2 enum('a','b'), vl int, bl int, c char(10), v1 varchar(10000), v2 varchar(10000), b1 blob, b2 blob) engine=aria; +insert into t1 (vl,bl) values (10,10),(100,100),(1000,1000),(5000,5000),(8000,12000); +update t1 set c="test", v1=repeat('a',vl),v2=repeat('b',vl/2),b1=repeat('c',bl),b2=repeat('d',bl); +insert into t1 (vl,bl) values (10,10),(100,100),(1000,1000),(1000,5000); +update t1 set c="test", v1=repeat('a',vl/4),v2=repeat('b',vl/5),b1=repeat('c',bl*2),b2=repeat('d',bl/2); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',vl),v2=repeat('b',vl),b1=repeat('c',bl*2),b2=repeat('d',bl/2); +update t1 set c="test", v1=repeat('a',vl/2),v2=repeat('b',vl/2),b1=repeat('c',bl/2),b2=repeat('d',bl/2); +update t1 set c="test", v1=repeat('a',vl/4),v2=repeat('b',vl/4),b1=repeat('c',bl/4),b2=repeat('d',bl/4); +update t1 set c="test", v1=repeat('a',vl/20),v2=repeat('b',vl),b1=repeat('c',bl/20),b2=repeat('d',bl/20); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',vl/100),b1=repeat('c',bl/100); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',vl),b1=repeat('c',bl); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',10),v2=repeat('b',10); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',2000),v2=repeat('b',2000); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; diff --git a/mysql-test/suite/maria/suite.pm b/mysql-test/suite/maria/suite.pm new file mode 100644 index 00000000000..e6efcdca829 --- /dev/null +++ b/mysql-test/suite/maria/suite.pm @@ -0,0 +1,8 @@ +package My::Suite::Maria; + +@ISA = qw(My::Suite); + +return "Need Aria engine" unless $::mysqld_variables{'aria'} eq "ON"; + +bless { }; + diff --git a/mysql-test/suite/maria/t/compat_aliases-master.opt b/mysql-test/suite/maria/t/compat_aliases-master.opt new file mode 100644 index 00000000000..73f18586361 --- /dev/null +++ b/mysql-test/suite/maria/t/compat_aliases-master.opt @@ -0,0 +1 @@ +--maria-max-sort-file-size=100M --aria-repair-threads=10000 diff --git a/mysql-test/suite/maria/t/compat_aliases.test b/mysql-test/suite/maria/t/compat_aliases.test new file mode 100644 index 00000000000..7b94d24e643 --- /dev/null +++ b/mysql-test/suite/maria/t/compat_aliases.test @@ -0,0 +1,59 @@ +# +# test for maria* aliases (system variables, status variables, +# command-line options). They should match aria* variables. +# + +--replace_column 5 # +select * from information_schema.plugins where plugin_name like '%aria'; + +select maria_vars.variable_name, aria_vars.variable_name from + information_schema.session_variables as maria_vars left join + information_schema.session_variables as aria_vars + on (maria_vars.variable_name = concat('m', aria_vars.variable_name)) + where maria_vars.variable_name like 'maria_%' + and not (maria_vars.variable_value <=> aria_vars.variable_value); + +select maria_vars.variable_name, aria_vars.variable_name from + information_schema.session_status as maria_vars left join + information_schema.session_status as aria_vars + on (maria_vars.variable_name = concat('m', aria_vars.variable_name)) + where maria_vars.variable_name like 'maria_%' + and not (maria_vars.variable_value <=> aria_vars.variable_value); + +select maria_vars.variable_name, aria_vars.variable_name from + information_schema.session_variables as aria_vars left join + information_schema.session_variables as maria_vars + on (maria_vars.variable_name = concat('m', aria_vars.variable_name)) + where aria_vars.variable_name like 'aria_%' + and not (maria_vars.variable_value <=> aria_vars.variable_value); + +select maria_vars.variable_name, aria_vars.variable_name from + information_schema.session_status as aria_vars left join + information_schema.session_status as maria_vars + on (maria_vars.variable_name = concat('m', aria_vars.variable_name)) + where aria_vars.variable_name like 'aria_%' + and not (maria_vars.variable_value <=> aria_vars.variable_value); + +set @old_checkpoint_interval=@@global.aria_checkpoint_interval; +set global maria_checkpoint_interval=10; +select @@global.aria_checkpoint_interval; +set global maria_checkpoint_interval=@old_checkpoint_interval; + +set @old_sort_buffer_size=@@global.maria_sort_buffer_size; +set global aria_sort_buffer_size=1024; +select @@global.maria_sort_buffer_size; +set global aria_sort_buffer_size=@old_sort_buffer_size; + +set @old_sort_buffer_size=@@session.maria_sort_buffer_size; +set session aria_sort_buffer_size=2048; +select @@session.maria_sort_buffer_size; +set session aria_sort_buffer_size=@old_sort_buffer_size; + +set @old_max_sort_file_size=@@global.maria_max_sort_file_size, + @old_repair_threads=@@global.aria_repair_threads; +set @@global.maria_max_sort_file_size=default, @@global.aria_repair_threads=default; +--replace_result 4293918720 9223372036853727232 +select @@global.maria_max_sort_file_size, @@global.aria_repair_threads; +set @@global.aria_max_sort_file_size=@old_max_sort_file_size, + @@global.maria_repair_threads=@old_repair_threads; + diff --git a/mysql-test/suite/maria/t/group_commit.test b/mysql-test/suite/maria/t/group_commit.test new file mode 100644 index 00000000000..38b2c9d3bf4 --- /dev/null +++ b/mysql-test/suite/maria/t/group_commit.test @@ -0,0 +1,72 @@ +# Test different ways of syncing (mostly syntax) +--source include/have_maria.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (a int); + +SET GLOBAL aria_group_commit="NONE"; +SET GLOBAL aria_group_commit_interval= 0; +--disable_query_log +let $num = 5000; +while ($num) +{ + insert into t1 values (1); + dec $num; +} +--enable_query_log +SET GLOBAL aria_group_commit="NONE"; +SET GLOBAL aria_group_commit_interval= 100; +--disable_query_log +let $num = 5000; +while ($num) +{ + insert into t1 values (1); + dec $num; +} +--enable_query_log +SET GLOBAL aria_group_commit="HARD"; +SET GLOBAL aria_group_commit_interval= 0; +--disable_query_log +let $num = 5000; +while ($num) +{ + insert into t1 values (1); + dec $num; +} +--enable_query_log +SET GLOBAL aria_group_commit="HARD"; +SET GLOBAL aria_group_commit_interval= 100; +--disable_query_log +let $num = 5000; +while ($num) +{ + insert into t1 values (1); + dec $num; +} +--enable_query_log +SET GLOBAL aria_group_commit="SOFT"; +SET GLOBAL aria_group_commit_interval= 0; +--disable_query_log +let $num = 5000; +while ($num) +{ + insert into t1 values (1); + dec $num; +} +--enable_query_log +SET GLOBAL aria_group_commit="SOFT"; +SET GLOBAL aria_group_commit_interval= 100; +--disable_query_log +let $num = 5000; +while ($num) +{ + insert into t1 values (1); + dec $num; +} +--enable_query_log +SET GLOBAL aria_group_commit="NONE"; +SET GLOBAL aria_group_commit_interval= 0; +drop table t1; diff --git a/mysql-test/suite/maria/t/maria-autozerofill.test b/mysql-test/suite/maria/t/maria-autozerofill.test index b46b458d89e..b42b8e177dc 100644 --- a/mysql-test/suite/maria/t/maria-autozerofill.test +++ b/mysql-test/suite/maria/t/maria-autozerofill.test @@ -1,5 +1,5 @@ # Test to verify that auto-zerofilling happens when a table is -# imported from a different Maria instance +# imported from a different Aria instance # can't restart in embedded --source include/not_embedded.inc @@ -22,16 +22,16 @@ connection default; use mysqltest; --enable_reconnect -create table t1(a int) engine=maria; +create table t1(a int) engine=aria; insert into t1 values(1); flush table t1; # Check that table is not zerofilled, not movable let $MYSQLD_DATADIR= `select @@datadir`; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/mysqltest/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/mysqltest/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= <FILE>; print grep(/Status:.*(zerofilled|movable)/, @content); @@ -39,23 +39,23 @@ perl; close FILE; EOF -# this will remove control file, so change the uuid of the Maria +# this will remove control file, so change the uuid of the Aria # instance, thus t1 will appear as imported from elsewhere. -- source include/maria_empty_logs.inc -disable_ps_protocol; # see maria-recover.test +disable_ps_protocol; # see aria-recover.test replace_regex /Table.*t1/t1/ ; select * from t1; enable_ps_protocol; flush table t1; # Check that table is auto-zerofilled, movable ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/mysqltest/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/mysqltest/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= <FILE>; print grep(/Status:.*zerofilled/, @content); @@ -63,16 +63,16 @@ perl; close FILE; EOF -# this will attach t1 to the current Maria instance +# this will attach t1 to the current Aria instance insert into t1 values(2); flush table t1; # Check that table is not zerofilled, not movable ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/mysqltest/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/mysqltest/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= <FILE>; print grep(/Status:.*(zerofilled|movable)/, @content); diff --git a/mysql-test/suite/maria/t/maria-big.test b/mysql-test/suite/maria/t/maria-big.test index 612cdbabb81..5b4b6c4defe 100644 --- a/mysql-test/suite/maria/t/maria-big.test +++ b/mysql-test/suite/maria/t/maria-big.test @@ -9,7 +9,7 @@ connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection root; enable_info; -set storage_engine=maria; +set storage_engine=aria; disable_warnings; drop table if exists t1, t2; enable_warnings; @@ -68,7 +68,7 @@ drop table t1; # Set defaults back --disable_result_log --disable_query_log -set global maria_log_file_size=default; +set global aria_log_file_size=default; set global max_allowed_packet=default; --enable_result_log --enable_query_log diff --git a/mysql-test/suite/maria/t/maria-big2.test b/mysql-test/suite/maria/t/maria-big2.test index 867ce71d4b5..d138892fe3c 100644 --- a/mysql-test/suite/maria/t/maria-big2.test +++ b/mysql-test/suite/maria/t/maria-big2.test @@ -5,7 +5,7 @@ # (CHECK TABLE said Invalid key block position: 15731098820608 key # block size: 8192 file_length: 425984) -create table t2(id int,a varchar(255),b varchar(255),key(a))engine=maria row_format=dynamic transactional=0; +create table t2(id int,a varchar(255),b varchar(255),key(a))engine=aria row_format=dynamic transactional=0; disable_query_log; insert into t2(a,b) values ('zmysnptvgzljpaumbdhrzkmbhefugcyhncbl','urecietrsfhgusavxffpdszrfcpdqbwxzvygsuwammwunjhpxanvozwnngnnjbwfenjgosaixpccjyviiutzpxkwiecuprltzrpxvkrjnjqgsneniewbagpvwelajvnckbbkqpaicxor') diff --git a/mysql-test/suite/maria/t/maria-connect.test b/mysql-test/suite/maria/t/maria-connect.test index 31b15b1f8f1..9efb5844bc2 100644 --- a/mysql-test/suite/maria/t/maria-connect.test +++ b/mysql-test/suite/maria/t/maria-connect.test @@ -6,8 +6,8 @@ -- source include/have_log_bin.inc let $default=`select @@global.storage_engine`; -set global storage_engine=maria; -set session storage_engine=maria; +set global storage_engine=aria; +set session storage_engine=aria; # Initialise --disable_warnings @@ -18,7 +18,7 @@ SET SQL_WARNINGS=1; # # UNIQUE key test # -# as long as maria cannot rollback, binlog should contain both inserts +# as long as aria cannot rollback, binlog should contain both inserts # RESET MASTER; set binlog_format=statement; @@ -36,6 +36,6 @@ set binlog_format=default; --disable_result_log --disable_query_log eval set global storage_engine=$default; -set global maria_log_file_size=default; +set global aria_log_file_size=default; --enable_result_log --enable_query_log diff --git a/mysql-test/suite/maria/t/maria-gis-rtree-dynamic.test b/mysql-test/suite/maria/t/maria-gis-rtree-dynamic.test index 228998c01c3..166c88cab36 100644 --- a/mysql-test/suite/maria/t/maria-gis-rtree-dynamic.test +++ b/mysql-test/suite/maria/t/maria-gis-rtree-dynamic.test @@ -1,7 +1,7 @@ -- source include/have_maria.inc -- source include/have_geometry.inc -set storage_engine=maria; +set storage_engine=aria; # # test of rtree (using with spatial data) diff --git a/mysql-test/suite/maria/t/maria-gis-rtree-trans.test b/mysql-test/suite/maria/t/maria-gis-rtree-trans.test index f530699c755..ec1573c3e29 100644 --- a/mysql-test/suite/maria/t/maria-gis-rtree-trans.test +++ b/mysql-test/suite/maria/t/maria-gis-rtree-trans.test @@ -1,10 +1,10 @@ # Because state.key_root is updated differently between transactional -# and non-trans tables, we have several maria-gis-rtree-* tests. +# and non-trans tables, we have several aria-gis-rtree-* tests. -- source include/have_maria.inc -- source include/have_geometry.inc -set storage_engine=maria; +set storage_engine=aria; # # test of rtree (using with spatial data) diff --git a/mysql-test/suite/maria/t/maria-gis-rtree.test b/mysql-test/suite/maria/t/maria-gis-rtree.test index 7a3e5634388..beffbfc99fe 100644 --- a/mysql-test/suite/maria/t/maria-gis-rtree.test +++ b/mysql-test/suite/maria/t/maria-gis-rtree.test @@ -1,7 +1,7 @@ -- source include/have_maria.inc -- source include/have_geometry.inc -set storage_engine=maria; +set storage_engine=aria; # # test of rtree (using with spatial data) diff --git a/mysql-test/suite/maria/t/maria-mvcc.test b/mysql-test/suite/maria/t/maria-mvcc.test index 4b6f8a3996d..8be8e2ea630 100644 --- a/mysql-test/suite/maria/t/maria-mvcc.test +++ b/mysql-test/suite/maria/t/maria-mvcc.test @@ -4,7 +4,7 @@ # -- source include/have_maria.inc -set global maria_page_checksum=1; +set global aria_page_checksum=1; --disable_warnings drop table if exists t1; @@ -13,7 +13,7 @@ drop table if exists t1; connect (con1,localhost,root,,); connection con1; -create table t1 (i int) engine=maria; +create table t1 (i int) engine=aria; show create table t1; # versioning is disabled when table is empty, so insert a row @@ -94,7 +94,7 @@ drop table t1; # Test count(*) for not versioned tables # -CREATE TABLE t1 (fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, g GEOMETRY NOT NULL, SPATIAL KEY(g) ) transactional=1 row_format=page engine=maria; +CREATE TABLE t1 (fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, g GEOMETRY NOT NULL, SPATIAL KEY(g) ) transactional=1 row_format=page engine=aria; lock tables t1 write concurrent, t1 as t2 write concurrent; insert into t1 (fid,g) values (NULL,GeomFromText('LineString(0 0,1 1)')); diff --git a/mysql-test/suite/maria/t/maria-no-logging.test b/mysql-test/suite/maria/t/maria-no-logging.test index bca99848250..f0533686588 100644 --- a/mysql-test/suite/maria/t/maria-no-logging.test +++ b/mysql-test/suite/maria/t/maria-no-logging.test @@ -4,7 +4,7 @@ # can't restart server in embedded --source include/not_embedded.inc -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; --disable_warnings drop database if exists mysqltest; @@ -19,8 +19,8 @@ use mysqltest; --enable_reconnect # checkpoints can make log unrepeatable -let $def_checkinterval=`select @@global.maria_checkpoint_interval`; -set global maria_checkpoint_interval=0; +let $def_checkinterval=`select @@global.aria_checkpoint_interval`; +set global aria_checkpoint_interval=0; # Prepare table to help for big load create table t2 (a varchar(100)) engine=myisam; @@ -36,24 +36,24 @@ insert into t2 select * from t2; # no optimization because table not empty -# SHOW ENGINE MARIA LOGS could be influenced by older logs +# SHOW ENGINE ARIA LOGS could be influenced by older logs -- source include/maria_empty_logs.inc -create table t1 (a varchar(100)) engine=maria transactional=1; +create table t1 (a varchar(100)) engine=aria transactional=1; show create table t1; ---replace_regex /; .+maria_log/maria_log/ -show engine maria logs; +--replace_regex /; .+aria_log/aria_log/ +show engine aria logs; insert into t1 values('a'); insert into t1 select * from t2; ---replace_regex /; .+maria_log/maria_log/ -show engine maria logs; +--replace_regex /; .+aria_log/aria_log/ +show engine aria logs; # optimization because table is empty -- source include/maria_empty_logs.inc truncate table t1; insert into t1 select * from t2; ---replace_regex /; .+maria_log/maria_log/ -show engine maria logs; +--replace_regex /; .+aria_log/aria_log/ +show engine aria logs; drop table t1; @@ -61,23 +61,23 @@ drop table t1; # no optimization because table not empty -- source include/maria_empty_logs.inc -create table t1 (a varchar(100)) engine=maria transactional=1; +create table t1 (a varchar(100)) engine=aria transactional=1; insert into t1 values('a'); create table if not exists t1 select * from t2; ---replace_regex /; .+maria_log/maria_log/ -show engine maria logs; +--replace_regex /; .+aria_log/aria_log/ +show engine aria logs; # optimization because table is empty -- source include/maria_empty_logs.inc drop table t1; -create table t1 engine=maria transactional=1 select * from t2; ---replace_regex /; .+maria_log/maria_log/ -show engine maria logs; +create table t1 engine=aria transactional=1 select * from t2; +--replace_regex /; .+aria_log/aria_log/ +show engine aria logs; drop database mysqltest; --disable_result_log --disable_query_log -eval set global maria_checkpoint_interval=$def_checkinterval; +eval set global aria_checkpoint_interval=$def_checkinterval; --enable_result_log --enable_query_log diff --git a/mysql-test/suite/maria/t/maria-page-checksum.test b/mysql-test/suite/maria/t/maria-page-checksum.test index 9b05b00a371..8dd68fce245 100644 --- a/mysql-test/suite/maria/t/maria-page-checksum.test +++ b/mysql-test/suite/maria/t/maria-page-checksum.test @@ -1,4 +1,4 @@ -# Tests for two bugs related to ALTER TABLE and maria-specific alter +# Tests for two bugs related to ALTER TABLE and aria-specific alter # options (PAGE_CHECKSUM and TRANSACTIONAL). -- source include/have_maria.inc @@ -13,34 +13,34 @@ drop table if exists t1; let $MYSQLD_DATADIR= `select @@datadir`; -select @@global.maria_page_checksum; +select @@global.aria_page_checksum; # we scan through combinations in the cartesian product of -# (first value of maria_page_checksum) x (clauses in CREATE TABLE) x -# (second value of maria_page_checksum) x (clauses in ALTER TABLE). +# (first value of aria_page_checksum) x (clauses in CREATE TABLE) x +# (second value of aria_page_checksum) x (clauses in ALTER TABLE). --echo # iteration 1 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -49,27 +49,27 @@ EOF drop table t1; --echo # iteration 2 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -78,27 +78,27 @@ EOF drop table t1; --echo # iteration 3 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -107,27 +107,27 @@ EOF drop table t1; --echo # iteration 4 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -136,27 +136,27 @@ EOF drop table t1; --echo # iteration 5 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -165,27 +165,27 @@ EOF drop table t1; --echo # iteration 6 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -194,27 +194,27 @@ EOF drop table t1; --echo # iteration 7 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -223,27 +223,27 @@ EOF drop table t1; --echo # iteration 8 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -252,27 +252,27 @@ EOF drop table t1; --echo # iteration 9 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -281,27 +281,27 @@ EOF drop table t1; --echo # iteration 10 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -310,27 +310,27 @@ EOF drop table t1; --echo # iteration 11 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -339,27 +339,27 @@ EOF drop table t1; --echo # iteration 12 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -368,27 +368,27 @@ EOF drop table t1; --echo # iteration 13 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -397,27 +397,27 @@ EOF drop table t1; --echo # iteration 14 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -426,27 +426,27 @@ EOF drop table t1; --echo # iteration 15 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -455,27 +455,27 @@ EOF drop table t1; --echo # iteration 16 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -484,27 +484,27 @@ EOF drop table t1; --echo # iteration 17 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -513,27 +513,27 @@ EOF drop table t1; --echo # iteration 18 -set global maria_page_checksum = 0 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 0 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -542,27 +542,27 @@ EOF drop table t1; --echo # iteration 19 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -571,27 +571,27 @@ EOF drop table t1; --echo # iteration 20 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -600,27 +600,27 @@ EOF drop table t1; --echo # iteration 21 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -629,27 +629,27 @@ EOF drop table t1; --echo # iteration 22 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -658,27 +658,27 @@ EOF drop table t1; --echo # iteration 23 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -687,27 +687,27 @@ EOF drop table t1; --echo # iteration 24 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -716,27 +716,27 @@ EOF drop table t1; --echo # iteration 25 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -745,27 +745,27 @@ EOF drop table t1; --echo # iteration 26 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -774,27 +774,27 @@ EOF drop table t1; --echo # iteration 27 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -803,27 +803,27 @@ EOF drop table t1; --echo # iteration 28 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -832,27 +832,27 @@ EOF drop table t1; --echo # iteration 29 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -861,27 +861,27 @@ EOF drop table t1; --echo # iteration 30 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=0 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -890,27 +890,27 @@ EOF drop table t1; --echo # iteration 31 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 0 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -919,27 +919,27 @@ EOF drop table t1; --echo # iteration 32 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -948,27 +948,27 @@ EOF drop table t1; --echo # iteration 33 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 0 ; +set global aria_page_checksum = 0 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -977,27 +977,27 @@ EOF drop table t1; --echo # iteration 34 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; -alter table t1 engine=maria ; +set global aria_page_checksum = 1 ; +alter table t1 engine=aria ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -1006,27 +1006,27 @@ EOF drop table t1; --echo # iteration 35 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=0 ; show create table t1 /* expecting PAGE_CHECKSUM=0 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -1035,27 +1035,27 @@ EOF drop table t1; --echo # iteration 36 -set global maria_page_checksum = 1 ; -create table t1(a int) engine=maria PAGE_CHECKSUM=1 ; +set global aria_page_checksum = 1 ; +create table t1(a int) engine=aria PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; close FILE; EOF -set global maria_page_checksum = 1 ; +set global aria_page_checksum = 1 ; alter table t1 PAGE_CHECKSUM=1 ; show create table t1 /* expecting PAGE_CHECKSUM=1 */ ; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; my @content= grep(/Page checksums are used/, <FILE>); print @content ? $content[0] : "Page checksums are not used\n"; @@ -1065,20 +1065,20 @@ drop table t1; # # Test for BUG#37005 -# "Maria: ALTER TABLE TRANSACTIONAL=0 leaves table transactional inside Maria" +# "Aria: ALTER TABLE TRANSACTIONAL=0 leaves table transactional inside Aria" # # we scan through combinations in the cartesian product of # (clauses in CREATE TABLE) x (clauses in ALTER TABLE). --echo # iteration 1 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1086,11 +1086,11 @@ EOF alter table t1 modify a bigint ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1099,13 +1099,13 @@ drop table t1; --echo # iteration 2 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1113,11 +1113,11 @@ EOF alter table t1 transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1126,13 +1126,13 @@ drop table t1; --echo # iteration 3 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1140,11 +1140,11 @@ EOF alter table t1 transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1153,25 +1153,25 @@ drop table t1; --echo # iteration 4 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; EOF -alter table t1 engine=maria ; +alter table t1 engine=aria ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1180,25 +1180,25 @@ drop table t1; --echo # iteration 5 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; EOF -alter table t1 engine=maria transactional=0 ; +alter table t1 engine=aria transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1207,25 +1207,25 @@ drop table t1; --echo # iteration 6 -create table t1(a int) engine=maria ; +create table t1(a int) engine=aria ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; EOF -alter table t1 engine=maria transactional=1 ; +alter table t1 engine=aria transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1234,13 +1234,13 @@ drop table t1; --echo # iteration 7 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1248,11 +1248,11 @@ EOF alter table t1 modify a bigint ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1261,13 +1261,13 @@ drop table t1; --echo # iteration 8 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1275,11 +1275,11 @@ EOF alter table t1 transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1288,13 +1288,13 @@ drop table t1; --echo # iteration 9 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1302,11 +1302,11 @@ EOF alter table t1 transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1315,25 +1315,25 @@ drop table t1; --echo # iteration 10 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; EOF -alter table t1 engine=maria ; +alter table t1 engine=aria ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1342,25 +1342,25 @@ drop table t1; --echo # iteration 11 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; EOF -alter table t1 engine=maria transactional=0 ; +alter table t1 engine=aria transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1369,25 +1369,25 @@ drop table t1; --echo # iteration 12 -create table t1(a int) engine=maria transactional=0 ; +create table t1(a int) engine=aria transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; EOF -alter table t1 engine=maria transactional=1 ; +alter table t1 engine=aria transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1396,13 +1396,13 @@ drop table t1; --echo # iteration 13 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1410,11 +1410,11 @@ EOF alter table t1 modify a bigint ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1423,13 +1423,13 @@ drop table t1; --echo # iteration 14 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1437,11 +1437,11 @@ EOF alter table t1 transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1450,13 +1450,13 @@ drop table t1; --echo # iteration 15 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1464,11 +1464,11 @@ EOF alter table t1 transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1477,25 +1477,25 @@ drop table t1; --echo # iteration 16 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; EOF -alter table t1 engine=maria ; +alter table t1 engine=aria ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1504,25 +1504,25 @@ drop table t1; --echo # iteration 17 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; EOF -alter table t1 engine=maria transactional=0 ; +alter table t1 engine=aria transactional=0 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; @@ -1531,25 +1531,25 @@ drop table t1; --echo # iteration 18 -create table t1(a int) engine=maria transactional=1 ; +create table t1(a int) engine=aria transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; EOF -alter table t1 engine=maria transactional=1 ; +alter table t1 engine=aria transactional=1 ; show create table t1; ---exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/mariachk.txt +--exec $MARIA_CHK -dv $MYSQLD_DATADIR/test/t1 >$MYSQLTEST_VARDIR/tmp/ariachk.txt perl; use strict; use warnings; - my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/mariachk.txt"; + my $fname= "$ENV{'MYSQLTEST_VARDIR'}/tmp/ariachk.txt"; open(FILE, "<", $fname) or die; print grep(/Crashsafe/, <FILE>); close FILE; diff --git a/mysql-test/suite/maria/t/maria-partitioning.test b/mysql-test/suite/maria/t/maria-partitioning.test index 589b489331d..612c44be57e 100644 --- a/mysql-test/suite/maria/t/maria-partitioning.test +++ b/mysql-test/suite/maria/t/maria-partitioning.test @@ -1,21 +1,21 @@ # -# Testing of potential problems in Maria with partitioning +# Testing of potential problems in Aria with partitioning # --source include/have_maria.inc --source include/have_partition.inc let $default_engine=`select @@global.storage_engine`; -let $default_checksum=`select @@global.maria_page_checksum`; -set global storage_engine=maria; -set session storage_engine=maria; +let $default_checksum=`select @@global.aria_page_checksum`; +set global storage_engine=aria; +set session storage_engine=aria; # # Test outer join const propagation # DROP TABLE if exists t1,t2; -create table t2(a blob) engine=maria; -create table t1(a int primary key) engine=maria; +create table t2(a blob) engine=aria; +create table t1(a int primary key) engine=aria; insert into t2 values ('foo'),('bar'); select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb'; insert into t1 values (1); @@ -24,8 +24,8 @@ insert into t1 values (2); select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb'; drop table t1,t2; -create table t2(a blob) engine= maria; -create table t1(a int primary key) engine= maria PARTITION BY HASH (a) PARTITIONS 2; +create table t2(a blob) engine= aria; +create table t1(a int primary key) engine= aria PARTITION BY HASH (a) PARTITIONS 2; insert into t2 values ('foo'),('bar'); select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb'; insert into t1 values (1); diff --git a/mysql-test/suite/maria/t/maria-preload.test b/mysql-test/suite/maria/t/maria-preload.test index 5012ca64f31..efac10ecbec 100644 --- a/mysql-test/suite/maria/t/maria-preload.test +++ b/mysql-test/suite/maria/t/maria-preload.test @@ -11,15 +11,15 @@ drop table if exists t1, t2; --enable_warnings # Background dirty pages flushing may influence page cache stats: -let $def_checkinterval=`select @@global.maria_checkpoint_interval`; -set global maria_checkpoint_interval=0; +let $def_checkinterval=`select @@global.aria_checkpoint_interval`; +set global aria_checkpoint_interval=0; # Work around BUG#34911 "FLUSH STATUS doesn't flush what it should": # compute differences in status variables before and after relevant -# queries. Maria_pagecache_read_requests varies accross machines. +# queries. Aria_pagecache_read_requests varies accross machines. create temporary table initial select variable_name,variable_value from -information_schema.global_status where variable_name like "Maria_pagecache_reads"; +information_schema.global_status where variable_name like "Aria_pagecache_reads"; # we don't use block-format because we want page cache stats # about indices and not data pages. @@ -29,14 +29,14 @@ create table t1 ( b char(16) not null, primary key (a), key (b) -) engine=maria row_format=dynamic; +) engine=aria row_format=dynamic; create table t2( a int not null auto_increment, b char(16) not null, primary key (a), key (b) -) engine=maria row_format=dynamic; +) engine=aria row_format=dynamic; insert into t1(b) values ('test0'), @@ -71,7 +71,7 @@ select count(*) from t1; select count(*) from t2; flush tables; flush status; -let $show_stat=select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Maria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; +let $show_stat=select g.variable_name,g.variable_value-i.variable_value from information_schema.global_status as g,initial as i where g.variable_name like "Aria_pagecache_read%" and g.variable_name=i.variable_name order by g.variable_name desc; eval $show_stat; select count(*) from t1 where b = 'test1'; eval $show_stat; @@ -116,11 +116,11 @@ eval $show_stat; drop table t1, t2; drop temporary table initial; -# check that Maria didn't use key cache +# check that Aria didn't use key cache show status like "key_read%"; --disable_result_log --disable_query_log -eval set global maria_checkpoint_interval=$def_checkinterval; +eval set global aria_checkpoint_interval=$def_checkinterval; --enable_result_log --enable_query_log diff --git a/mysql-test/suite/maria/t/maria-purge.test b/mysql-test/suite/maria/t/maria-purge.test index 0aa720543f6..c38a58bc492 100644 --- a/mysql-test/suite/maria/t/maria-purge.test +++ b/mysql-test/suite/maria/t/maria-purge.test @@ -2,7 +2,7 @@ -- source include/big_test.inc -- source include/not_embedded.inc -# pre-requisites for maria_empty_logs +# pre-requisites for aria_empty_logs connect (admin, localhost, root,,test,,); # --enable_reconnect @@ -10,18 +10,18 @@ connection default; --enable_reconnect # end of pre-requisites -# SHOW ENGINE MARIA LOGS could be influenced by older logs +# SHOW ENGINE ARIA LOGS could be influenced by older logs # Also, possibly automatic checkpoints (see if that happens in # practice) -- source include/maria_empty_logs.inc let $default=`select @@global.storage_engine`; -set global storage_engine=maria; -set session storage_engine=maria; -let $def_logsize=`select @@global.maria_log_file_size`; -let $def_checkinterval=`select @@global.maria_checkpoint_interval`; +set global storage_engine=aria; +set session storage_engine=aria; +let $def_logsize=`select @@global.aria_log_file_size`; +let $def_checkinterval=`select @@global.aria_checkpoint_interval`; -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; # Initialise --disable_warnings drop table if exists t1,t2; @@ -61,58 +61,58 @@ insert into t1 select * from t2; insert into t2 select * from t1; insert into t1 select * from t2; -set global maria_log_file_size=16777216; +set global aria_log_file_size=16777216; # force a checkpoint to allow log purge -eval set global maria_checkpoint_interval=$def_checkinterval; ---replace_regex /Size +[0-9]+ ; .+maria_log/maria_log/ -SHOW ENGINE maria logs; +eval set global aria_checkpoint_interval=$def_checkinterval; +--replace_regex /Size +[0-9]+ ; .+aria_log/aria_log/ +SHOW ENGINE aria logs; insert into t2 select * from t1; insert into t1 select * from t2; -eval set global maria_checkpoint_interval=$def_checkinterval; ---replace_regex /Size +[0-9]+ ; .+maria_log/maria_log/ -SHOW ENGINE maria logs; -set global maria_log_file_size=16777216; -select @@global.maria_log_file_size; -eval set global maria_checkpoint_interval=$def_checkinterval; ---replace_regex /Size +[0-9]+ ; .+maria_log/maria_log/ -SHOW ENGINE maria logs; -set global maria_log_file_size=8388608; -select @@global.maria_log_file_size; +eval set global aria_checkpoint_interval=$def_checkinterval; +--replace_regex /Size +[0-9]+ ; .+aria_log/aria_log/ +SHOW ENGINE aria logs; +set global aria_log_file_size=16777216; +select @@global.aria_log_file_size; +eval set global aria_checkpoint_interval=$def_checkinterval; +--replace_regex /Size +[0-9]+ ; .+aria_log/aria_log/ +SHOW ENGINE aria logs; +set global aria_log_file_size=8388608; +select @@global.aria_log_file_size; -set global maria_log_purge_type=at_flush; +set global aria_log_purge_type=at_flush; insert into t1 select * from t2; -eval set global maria_checkpoint_interval=$def_checkinterval; ---replace_regex /Size +[0-9]+ ; .+maria_log/maria_log/ -SHOW ENGINE maria logs; +eval set global aria_checkpoint_interval=$def_checkinterval; +--replace_regex /Size +[0-9]+ ; .+aria_log/aria_log/ +SHOW ENGINE aria logs; flush logs; ---replace_regex /Size +[0-9]+ ; .+maria_log/maria_log/ -SHOW ENGINE maria logs; +--replace_regex /Size +[0-9]+ ; .+aria_log/aria_log/ +SHOW ENGINE aria logs; -set global maria_log_file_size=16777216; -set global maria_log_purge_type=external; +set global aria_log_file_size=16777216; +set global aria_log_purge_type=external; insert into t1 select * from t2; -eval set global maria_checkpoint_interval=$def_checkinterval; ---replace_regex /Size +[0-9]+ ; .+maria_log/maria_log/ -SHOW ENGINE maria logs; +eval set global aria_checkpoint_interval=$def_checkinterval; +--replace_regex /Size +[0-9]+ ; .+aria_log/aria_log/ +SHOW ENGINE aria logs; flush logs; ---replace_regex /Size +[0-9]+ ; .+maria_log/maria_log/ -SHOW ENGINE maria logs; +--replace_regex /Size +[0-9]+ ; .+aria_log/aria_log/ +SHOW ENGINE aria logs; -set global maria_log_purge_type=immediate; +set global aria_log_purge_type=immediate; insert into t1 select * from t2; -eval set global maria_checkpoint_interval=$def_checkinterval; ---replace_regex /Size +[0-9]+ ; .+maria_log/maria_log/ -SHOW ENGINE maria logs; +eval set global aria_checkpoint_interval=$def_checkinterval; +--replace_regex /Size +[0-9]+ ; .+aria_log/aria_log/ +SHOW ENGINE aria logs; drop table t1, t2; --disable_result_log --disable_query_log -set global maria_log_purge_type=immediate; +set global aria_log_purge_type=immediate; eval set global storage_engine=$default; -eval set global maria_log_file_size=$def_logsize; -eval set global maria_checkpoint_interval=$def_checkinterval; +eval set global aria_log_file_size=$def_logsize; +eval set global aria_checkpoint_interval=$def_checkinterval; --enable_result_log --enable_query_log diff --git a/mysql-test/suite/maria/t/maria-recover-master.opt b/mysql-test/suite/maria/t/maria-recover-master.opt index 0cdefeadf3d..7582a381a32 100644 --- a/mysql-test/suite/maria/t/maria-recover-master.opt +++ b/mysql-test/suite/maria/t/maria-recover-master.opt @@ -1 +1 @@ ---loose-maria-recover=backup --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp +--loose-aria-recover=backup --loose-aria-log-dir-path=$MYSQLTEST_VARDIR/tmp diff --git a/mysql-test/suite/maria/t/maria-recover.test b/mysql-test/suite/maria/t/maria-recover.test index 4db02fcbb45..29b05879967 100644 --- a/mysql-test/suite/maria/t/maria-recover.test +++ b/mysql-test/suite/maria/t/maria-recover.test @@ -1,4 +1,4 @@ -# Test of the --maria-recover option. +# Test of the --aria-recover option. --source include/have_maria.inc @@ -18,13 +18,13 @@ let $def_checkinterval=`select @@global.maria_checkpoint_interval`; # so that the perl code below can access it. let MYSQLD_DATADIR= `select @@datadir`; -select @@global.maria_recover; -set global maria_recover=off; -select @@global.maria_recover; -set global maria_recover=default; -select @@global.maria_recover; -set global maria_recover=normal; -select @@global.maria_recover; +select @@global.aria_recover; +set global aria_recover=off; +select @@global.aria_recover; +set global aria_recover=default; +select @@global.aria_recover; +set global aria_recover=normal; +select @@global.aria_recover; --disable_warnings drop database if exists mysqltest; @@ -33,7 +33,7 @@ create database mysqltest; use mysqltest; -create table t1 (a varchar(1000), index(a)) engine=maria; +create table t1 (a varchar(1000), index(a)) engine=aria; insert into t1 values("ThursdayMorningsMarket"); flush table t1; # put index page on disk @@ -53,7 +53,7 @@ copy_file $MYSQLD_DATADIR/mysqltest/t1.MAD $MYSQLD_DATADIR/mysqltest/t_corrupted copy_file $MYSQLD_DATADIR/mysqltest/t1.MAI $MYSQLD_DATADIR/mysqltest/t_corrupted2.MAI; # Ruin the index file. -# If maria-block-size is smaller than the default, the corruption +# If aria-block-size is smaller than the default, the corruption # messages will differ. perl; use strict; @@ -72,5 +72,5 @@ select * from t_corrupted2; # should show corruption and repair messages select * from t_corrupted2; # should show just rows drop database mysqltest; -set global maria_recover=backup; -eval set global maria_checkpoint_interval=$def_checkinterval; +set global aria_recover=backup; +eval set global aria_checkpoint_interval=$def_checkinterval; diff --git a/mysql-test/suite/maria/t/maria-recovery-big.test b/mysql-test/suite/maria/t/maria-recovery-big.test index 4de8f934ec1..7a9a56c67ea 100644 --- a/mysql-test/suite/maria/t/maria-recovery-big.test +++ b/mysql-test/suite/maria/t/maria-recovery-big.test @@ -1,4 +1,4 @@ -# Maria recovery test which cannot run in shared memory +# Aria recovery test which cannot run in shared memory # because it generates too much data, or which takes a lot of time. --source include/not_embedded.inc @@ -9,7 +9,7 @@ --source include/have_maria.inc --source include/big_test.inc -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; --disable_warnings drop database if exists mysqltest; @@ -33,7 +33,7 @@ use mysqltest; --echo * TEST of recovery with blobs -- source include/maria_empty_logs.inc -create table t1 (a int, b longtext) engine=maria table_checksum=1; +create table t1 (a int, b longtext) engine=aria table_checksum=1; let $mms_tables=1; -- source include/maria_make_snapshot_for_feeding_recovery.inc insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321"); @@ -57,7 +57,7 @@ select a,length(b) from t1; let $mvr_restore_old_snapshot=1; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; -- source include/maria_verify_recovery.inc drop table t1; diff --git a/mysql-test/suite/maria/t/maria-recovery-bitmap.test b/mysql-test/suite/maria/t/maria-recovery-bitmap.test index f6b6583e9df..856785a04a8 100644 --- a/mysql-test/suite/maria/t/maria-recovery-bitmap.test +++ b/mysql-test/suite/maria/t/maria-recovery-bitmap.test @@ -1,4 +1,4 @@ -# Tests of Maria's recovery of the bitmap pages +# Tests of Aria's recovery of the bitmap pages --source include/not_embedded.inc # Don't test this under valgrind, memory leaks will occur as we crash @@ -25,14 +25,14 @@ use mysqltest; -- source include/maria_empty_logs.inc let $mms_tables=1; -create table t1 (a varchar(10000)) engine=maria; +create table t1 (a varchar(10000)) engine=aria; # we want recovery to use the tables as they were at time of crash let $mvr_restore_old_snapshot=0; # UNDO phase prevents physical comparison, normally, # so we'll only use checksums to compare. let $mms_compare_physically=0; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; --echo * TEST of over-allocated bitmap not flushed by checkpoint let $mvr_debug_option="+d,maria_crash"; @@ -45,7 +45,7 @@ insert into t1 values ("bbbbbbb"); insert into t1 values ("bbbbbbb"); delete from t1 limit 1; # Use a separate connection here. The reason is that we leave a dangling -# --send on the connection during maria_verify_recovery.inc, which makes that +# --send on the connection during aria_verify_recovery.inc, which makes that # script fail if it were to try to use that connection before --reap. connect (extra, localhost, root,,mysqltest,,); set session debug="+d,info,enter,exit,maria_over_alloc_bitmap"; @@ -59,7 +59,7 @@ sleep 5; # bitmap page; as REDO-UNDO was not written, bitmap and data page # would be inconsistent. Correct checkpoint will wait until UNDO is # written. -set global maria_checkpoint_interval=1; +set global aria_checkpoint_interval=1; -- source include/maria_verify_recovery.inc connection default; diff --git a/mysql-test/suite/maria/t/maria-recovery-master.opt b/mysql-test/suite/maria/t/maria-recovery-master.opt index 9023fb74e8b..58d0d012c54 100644 --- a/mysql-test/suite/maria/t/maria-recovery-master.opt +++ b/mysql-test/suite/maria/t/maria-recovery-master.opt @@ -1 +1 @@ ---skip-stack-trace --skip-core-file --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp +--skip-stack-trace --skip-core-file --loose-aria-log-dir-path=$MYSQLTEST_VARDIR/tmp diff --git a/mysql-test/suite/maria/t/maria-recovery-rtree-ft.test b/mysql-test/suite/maria/t/maria-recovery-rtree-ft.test index ac71be376f1..01ab5740258 100644 --- a/mysql-test/suite/maria/t/maria-recovery-rtree-ft.test +++ b/mysql-test/suite/maria/t/maria-recovery-rtree-ft.test @@ -8,7 +8,7 @@ --source include/have_maria.inc --source include/long_test.inc -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; let $MARIA_LOG=.; --disable_warnings @@ -35,10 +35,10 @@ CREATE TABLE t1 ( kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po', name VARCHAR(32) ,SPATIAL key (line) -) transactional=1 row_format=page engine=maria; +) transactional=1 row_format=page engine=aria; SHOW INDEX FROM t1; CREATE TABLE t2 (a VARCHAR(200), b TEXT, FULLTEXT (a,b) -) transactional=1 row_format=page engine=maria; +) transactional=1 row_format=page engine=aria; SHOW INDEX FROM t2; let $query1= INSERT INTO t1 (name, kind, line) VALUES @@ -114,7 +114,7 @@ while($1) let $mvr_restore_old_snapshot=1; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; # the script below will trigger recovery and compare checksums -- source include/maria_verify_recovery.inc @@ -133,7 +133,7 @@ let $mvr_restore_old_snapshot=0; # UNDO phase prevents physical comparison, normally, # so we'll only use checksums to compare. let $mms_compare_physically=0; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; # Note that we don't remove logs between iterations. Test is # cumulative (each new recovery processes more log records than the previous). diff --git a/mysql-test/suite/maria/t/maria-recovery.test b/mysql-test/suite/maria/t/maria-recovery.test index 6ba8e65e658..6eb91c59dc1 100644 --- a/mysql-test/suite/maria/t/maria-recovery.test +++ b/mysql-test/suite/maria/t/maria-recovery.test @@ -5,7 +5,7 @@ --source include/have_debug.inc --source include/have_maria.inc -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; let $MARIA_LOG=../../tmp; --disable_warnings @@ -27,7 +27,7 @@ use mysqltest; # A sample test -- source include/maria_empty_logs.inc let $mms_tables=1; -create table t1 (a varchar(1000)) engine=maria; +create table t1 (a varchar(1000)) engine=aria; --echo * TEST of REDO: see if recovery can reconstruct if we give it an old table @@ -42,7 +42,7 @@ let $mvr_restore_old_snapshot=1; # produce a physically identical table. let $mms_compare_physically=1; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; # the script below will trigger recovery and compare checksums -- source include/maria_verify_recovery.inc let $mms_compare_physically=0; @@ -63,7 +63,7 @@ let $mvr_restore_old_snapshot=0; # UNDO phase prevents physical comparison, normally, # so we'll only use checksums to compare. let $mms_compare_physically=0; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; # Note that we don't remove logs between iterations. Test is # cumulative (each new recovery processes more log records than the previous). @@ -131,7 +131,7 @@ CREATE TABLE t1 ( i int, b blob default NULL, c varchar(6000) default NULL -) ENGINE=MARIA CHECKSUM=1; +) ENGINE=ARIA CHECKSUM=1; -- source include/maria_make_snapshot_for_feeding_recovery.inc INSERT INTO t1 VALUES (1, REPEAT('a', 5000), REPEAT('b', 5000)); UPDATE t1 SET i=3, b=CONCAT(b,'c') WHERE i=1; @@ -141,7 +141,7 @@ SELECT LENGTH(b) FROM t1 WHERE i=3; let $mvr_restore_old_snapshot=1; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; -- source include/maria_verify_recovery.inc SELECT LENGTH(b) FROM t1 WHERE i=3; drop table t1; @@ -154,7 +154,7 @@ CREATE TABLE t1 ( i int auto_increment primary key, c varchar(6), key(c) -) ENGINE=MARIA; +) ENGINE=ARIA; insert into t1 values(null,"b"); -- source include/maria_make_snapshot_for_feeding_recovery.inc insert into t1 values(null,"a"), (null,"c"), (null,"d"); @@ -164,7 +164,7 @@ delete from t1 where c="d"; let $mvr_restore_old_snapshot=1; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; -- source include/maria_verify_recovery.inc show create table t1; @@ -176,7 +176,7 @@ update t1 set i=15 where c="a"; let $mvr_restore_old_snapshot=1; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; -- source include/maria_verify_recovery.inc show create table t1; @@ -187,7 +187,7 @@ show create table t1; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; lock tables t1 write; insert into t1 values(null, "e"); -- source include/maria_verify_recovery.inc diff --git a/mysql-test/suite/maria/t/maria-recovery2-master.opt b/mysql-test/suite/maria/t/maria-recovery2-master.opt index 36b4216a4b4..9b232472a24 100644 --- a/mysql-test/suite/maria/t/maria-recovery2-master.opt +++ b/mysql-test/suite/maria/t/maria-recovery2-master.opt @@ -1 +1 @@ ---skip-stack-trace --skip-core-file --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp --myisam-recover= +--skip-stack-trace --skip-core-file --loose-aria-log-dir-path=$MYSQLTEST_VARDIR/tmp --myisam-recover= diff --git a/mysql-test/suite/maria/t/maria-recovery2.test b/mysql-test/suite/maria/t/maria-recovery2.test index 017256a5ec8..81ea45fbd42 100644 --- a/mysql-test/suite/maria/t/maria-recovery2.test +++ b/mysql-test/suite/maria/t/maria-recovery2.test @@ -5,10 +5,10 @@ --source include/have_debug.inc --source include/have_maria.inc -call mtr.add_suppression("File '.*maria_log.000.*' not found \\(Errcode: 2\\)"); -call mtr.add_suppression("Table '.\/mysqltest\/t_corrupted1' is crashed, skipping it. Please repair it with maria_chk -r"); +call mtr.add_suppression("File '.*aria_log.000.*' not found \\(Errcode: 2\\)"); +call mtr.add_suppression("Table '.\/mysqltest\/t_corrupted1' is crashed, skipping it. Please repair it with aria_chk -r"); -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; let $MARIA_LOG=../../tmp; --disable_warnings @@ -31,13 +31,13 @@ let $mms_tables=1; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; # Test of removing logs manually --echo * TEST of removing logs manually let $mel_keep_control_file=1; # this will shut mysqld down cleanly (so, take a checkpoint) and -# remove only logs; at restart Maria will create a new log with a high +# remove only logs; at restart Aria will create a new log with a high # number -- source include/maria_empty_logs.inc let $mel_keep_control_file=0; @@ -49,8 +49,8 @@ let $mvr_restore_old_snapshot=0; # UNDO phase prevents physical comparison, normally, # so we'll only use checksums to compare. let $mms_compare_physically=0; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; -create table t1(a int) engine=maria; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; +create table t1(a int) engine=aria; insert into t1 values(1),(2); -- source include/maria_make_snapshot_for_comparison.inc lock tables t1 write; @@ -64,8 +64,8 @@ drop table t1; # Don't take a full checkpoints, we want to test checkpoint vs dirty pages set global debug="+d,info,query,enter,exit,loop,maria_checkpoint_indirect"; # restart checkpoint thread for it to notice the above -set global maria_checkpoint_interval=10000; -create table t1(a int, b varchar(10), index(a,b)) engine=maria; +set global aria_checkpoint_interval=10000; +create table t1(a int, b varchar(10), index(a,b)) engine=aria; insert into t1 values(1,"a"),(2,"b"),(3,"c"); delete from t1 where b="b"; update t1 set b="d" where a=1; @@ -74,15 +74,15 @@ lock tables t1 write; insert into t1 values(4,"e"),(5,"f"),(6,"g"); update t1 set b="h" where a=5; delete from t1 where b="g"; -show status like "Maria_pagecache_blocks_not_flushed"; +show status like "Aria_pagecache_blocks_not_flushed"; # force a checkpoint; there should be dirty pages and an open transaction -set global maria_checkpoint_interval=10000; +set global aria_checkpoint_interval=10000; # do some more work update t1 set b="i" where a=5; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; # Now we have a recovery, which should use the checkpoint record # and its dirty pages list. -- source include/maria_verify_recovery.inc @@ -90,10 +90,10 @@ drop table t1; --echo Test of REPAIR's implicit commit let $mms_tables=1; -create table t1 (a varchar(100), key(a)) engine=maria; +create table t1 (a varchar(100), key(a)) engine=aria; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash"; insert into t1 values(3); @@ -111,11 +111,11 @@ select * from t1; drop table t1; --echo * TEST of recovery when crash before bulk-insert-with-repair is committed -create table t1 (a varchar(100), key(a)) engine=maria; +create table t1 (a varchar(100), key(a)) engine=aria; create table t2 (a varchar(100)) engine=myisam; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; let $mvr_debug_option="+d,maria_flush_whole_log,maria_flush_whole_page_cache,maria_crash"; set rand_seed1=12, rand_seed2=254; # repeatable insert into t2 values (rand()); @@ -136,7 +136,7 @@ show keys from t1; # should be enabled drop table t1; --echo * TEST of recovery when OPTIMIZE has replaced the index file and crash -create table t_corrupted1 (a varchar(100), key(a)) engine=maria; +create table t_corrupted1 (a varchar(100), key(a)) engine=aria; # we use a special name because this test portion will generate # corruption warnings, which we tell mtr_report.pl to ignore by # putting the message in mtr_report.pl, but we don't want to it ignore diff --git a/mysql-test/suite/maria/t/maria-recovery3-master.opt b/mysql-test/suite/maria/t/maria-recovery3-master.opt index 9023fb74e8b..58d0d012c54 100644 --- a/mysql-test/suite/maria/t/maria-recovery3-master.opt +++ b/mysql-test/suite/maria/t/maria-recovery3-master.opt @@ -1 +1 @@ ---skip-stack-trace --skip-core-file --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp +--skip-stack-trace --skip-core-file --loose-aria-log-dir-path=$MYSQLTEST_VARDIR/tmp diff --git a/mysql-test/suite/maria/t/maria-recovery3.test b/mysql-test/suite/maria/t/maria-recovery3.test index a241473f457..192361633ca 100644 --- a/mysql-test/suite/maria/t/maria-recovery3.test +++ b/mysql-test/suite/maria/t/maria-recovery3.test @@ -5,7 +5,7 @@ --source include/have_debug.inc --source include/have_maria.inc -set global maria_log_file_size=4294967295; +set global aria_log_file_size=4294967295; let $MARIA_LOG=../../tmp; --disable_warnings @@ -28,7 +28,7 @@ let $mms_tables=1; let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; -- source include/maria_empty_logs.inc @@ -39,7 +39,7 @@ let $mvr_restore_old_snapshot=0; # UNDO phase prevents physical comparison, normally, # so we'll only use checksums to compare. let $mms_compare_physically=0; -create table t1(a int primary key) engine=maria; +create table t1(a int primary key) engine=aria; insert into t1 values(1); -- source include/maria_make_snapshot_for_comparison.inc set session debug="+d,maria_sleep_in_commit"; @@ -49,7 +49,7 @@ sleep 1; # but not yet called trnman_commit(), so for checkpoint it's not # committed. connection admin; -set global maria_checkpoint_interval=1000; # force a checkpoint +set global aria_checkpoint_interval=1000; # force a checkpoint connection default; reap; # end of INSERT delete from t1 where a=2; @@ -64,17 +64,17 @@ drop table t1; # before checkpoint happens, test should still pass (though it won't # reproduce the conditions of the bug). -# Test for BUG#41493 Maria: two recovery failures (wrong logging of BLOB pages) +# Test for BUG#41493 Aria: two recovery failures (wrong logging of BLOB pages) --echo * TEST of logging of BLOBs let $mvr_restore_old_snapshot=1; let $mms_compare_physically=1; CREATE TABLE `t1` ( `blob` blob, `blob_key` blob -) ENGINE=maria ROW_FORMAT=page +) ENGINE=aria ROW_FORMAT=page ; -- source include/maria_make_snapshot_for_feeding_recovery.inc -set global maria_checkpoint_interval=0; # no checkpoints +set global aria_checkpoint_interval=0; # no checkpoints INSERT INTO `t1` VALUES (NULL,repeat('A',5198)); INSERT INTO `t1` VALUES (NULL,repeat('B',65535)); INSERT INTO `t1` VALUES (repeat('K',5198),repeat('L',2325)); @@ -88,14 +88,14 @@ check table t1 extended; -- source include/maria_verify_recovery.inc drop table t1; -# Test for BUG#42112 "Maria: recovery failure (pushbuild2) Assertion +# Test for BUG#42112 "Aria: recovery failure (pushbuild2) Assertion # `rownr == 0 && new_page' failed" let $mvr_restore_old_snapshot=0; let $mms_compare_physically=0; -create table t1 engine=maria select 1; +create table t1 engine=aria select 1; -- source include/maria_make_snapshot_for_feeding_recovery.inc -set global maria_checkpoint_interval=0; # no checkpoints +set global aria_checkpoint_interval=0; # no checkpoints insert into t1 values(2); truncate table t1; -- source include/maria_make_snapshot_for_comparison.inc diff --git a/mysql-test/suite/maria/t/maria.test b/mysql-test/suite/maria/t/maria.test index 8a370fbd25a..e23821b8be9 100644 --- a/mysql-test/suite/maria/t/maria.test +++ b/mysql-test/suite/maria/t/maria.test @@ -1,20 +1,20 @@ # -# Testing of potential problems in Maria +# Testing of potential problems in Aria # This code was initially taken from myisam.test # -- source include/have_maria.inc -- source include/have_partition.inc -select * from INFORMATION_SCHEMA.ENGINES where ENGINE="MARIA"; +select * from INFORMATION_SCHEMA.ENGINES where ENGINE="ARIA"; let $default_engine=`select @@global.storage_engine`; -let $default_checksum=`select @@global.maria_page_checksum`; -set global storage_engine=maria; -set session storage_engine=maria; -set global maria_page_checksum=0; -let $default_log_file_size=`select @@global.maria_log_file_size`; -set global maria_log_file_size=4294967295; +let $default_checksum=`select @@global.aria_page_checksum`; +set global storage_engine=aria; +set session storage_engine=aria; +set global aria_page_checksum=0; +let $default_log_file_size=`select @@global.aria_log_file_size`; +set global aria_log_file_size=4294967295; # Initialise --disable_warnings @@ -116,7 +116,7 @@ DROP TABLE t1; # # Test of optimize, when only mi_sort_index (but not mi_repair*) is done -# in ha_maria::repair, and index size is changed (decreased). +# in ha_aria::repair, and index size is changed (decreased). # create table t1 ( t1 char(255), key(t1(250))); @@ -154,7 +154,7 @@ check table t1; drop table t1; # -# test of maria with huge number of packed fields +# test of aria with huge number of packed fields # create table t1 (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int, i7 int, i8 @@ -533,7 +533,7 @@ drop table t1; # # Test join that could miss concurrently inserted row -# Note that for the moment Maria only supports multiple writers if we have +# Note that for the moment Aria only supports multiple writers if we have # static or dynamic row format # # Partial key. @@ -664,10 +664,10 @@ checksum table t1; drop table t1; # -# maria_stats_method variable. +# aria_stats_method variable. # -show variables like 'maria_stats_method'; +show variables like 'aria_stats_method'; create table t1 (a int, key(a)); insert into t1 values (0),(1),(2),(3),(4); @@ -682,8 +682,8 @@ check table t1; show index from t1; # Set nulls to be equal: -set maria_stats_method=nulls_equal; -show variables like 'maria_stats_method'; +set aria_stats_method=nulls_equal; +show variables like 'aria_stats_method'; insert into t1 values (11); delete from t1 where a=11; @@ -697,8 +697,8 @@ check table t1; show index from t1; # Set nulls back to be equal -set maria_stats_method=DEFAULT; -show variables like 'maria_stats_method'; +set aria_stats_method=DEFAULT; +show variables like 'aria_stats_method'; insert into t1 values (11); delete from t1 where a=11; @@ -713,9 +713,9 @@ show index from t1; drop table t1; -# WL#2609, CSC#XXXX: MARIA -set maria_stats_method=nulls_ignored; -show variables like 'maria_stats_method'; +# WL#2609, CSC#XXXX: ARIA +set aria_stats_method=nulls_ignored; +show variables like 'aria_stats_method'; create table t1 ( a char(3), b char(4), c char(5), d char(6), @@ -735,7 +735,7 @@ delete from t1; analyze table t1; show index from t1; -set maria_stats_method=DEFAULT; +set aria_stats_method=DEFAULT; drop table t1; @@ -768,7 +768,7 @@ create table t1 ( t text not null, primary key (id1), key x (id2, t(32)) -) engine=maria; # engine clause is redundant but it's to test its parsing +) engine=aria; # engine clause is redundant but it's to test its parsing insert into t1 (id2, t) values (10, 'abc'), (10, 'abc'), (10, 'abc'), (20, 'abc'), (20, 'abc'), (20, 'def'), @@ -801,8 +801,8 @@ DROP TABLE t1; # # OPTIMIZE TABLE with multiple threads # -SET @@maria_repair_threads=2; -SHOW VARIABLES LIKE 'maria_repair%'; +SET @@aria_repair_threads=2; +SHOW VARIABLES LIKE 'aria_repair%'; # # Test OPTIMIZE. This creates a new data file. CREATE TABLE t1 ( @@ -888,8 +888,8 @@ SHOW TABLE STATUS LIKE 't1'; SELECT _id FROM t1; DROP TABLE t1; # -SET @@maria_repair_threads=1; -SHOW VARIABLES LIKE 'maria_repair%'; +SET @@aria_repair_threads=1; +SHOW VARIABLES LIKE 'aria_repair%'; # # Test varchar @@ -910,7 +910,7 @@ create table t1 (v varchar(65530) character set utf8); show create table t1; drop table t1; -# MARIA specific varchar tests +# ARIA specific varchar tests --error 1118 create table t1 (v varchar(65535)); @@ -1040,7 +1040,7 @@ create table t4 (c1 int) pack_keys=2; drop table t1, t2, t3; # -# Bug#28476: force index on a disabled maria index gives error 124 +# Bug#28476: force index on a disabled aria index gives error 124 # CREATE TABLE t1(a INT, b INT, KEY inx (a), UNIQUE KEY uinx (b)); @@ -1078,13 +1078,13 @@ ALTER TABLE t1 ENABLE KEYS; --replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # SHOW TABLE STATUS LIKE 't1'; #--exec ls -log var/mysqld.1/data/test/t1 -#--exec maria_chk -dvv var/mysqld.1/data/test/t1 -#--exec maria_chk -iev var/mysqld.1/data/test/t1 +#--exec aria_chk -dvv var/mysqld.1/data/test/t1 +#--exec aria_chk -iev var/mysqld.1/data/test/t1 --echo # Enable keys with parallel repair -SET @@maria_repair_threads=2; +SET @@aria_repair_threads=2; ALTER TABLE t1 DISABLE KEYS; ALTER TABLE t1 ENABLE KEYS; -SET @@maria_repair_threads=1; +SET @@aria_repair_threads=1; CHECK TABLE t1 EXTENDED; DROP TABLE t1; @@ -1108,7 +1108,7 @@ DROP TABLE t1, t2; # # Bug#37310: 'on update CURRENT_TIMESTAMP' option crashes the table # -CREATE TABLE t1 (a INT) ENGINE=MARIA CHECKSUM=1 ROW_FORMAT=DYNAMIC; +CREATE TABLE t1 (a INT) ENGINE=ARIA CHECKSUM=1 ROW_FORMAT=DYNAMIC; INSERT INTO t1 VALUES (0); UPDATE t1 SET a=1; SELECT a FROM t1; @@ -1237,7 +1237,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(130), c2 VARCHAR(1) -) ENGINE=maria; +) ENGINE=aria; INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); SELECT COUNT(*) FROM t1; CHECK TABLE t1; @@ -1252,7 +1252,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(130), c2 VARCHAR(1) -) ENGINE=maria; +) ENGINE=aria; INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); SELECT COUNT(*) FROM t1; CHECK TABLE t1 EXTENDED; @@ -1267,7 +1267,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(130), c2 VARCHAR(1) -) ENGINE=maria; +) ENGINE=aria; INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); # Insert more rows and delete one in the middle to force optimize. INSERT INTO t1 VALUES('b', 'b'); @@ -1286,7 +1286,7 @@ CREATE TABLE t1 ( c1 CHAR(130), c2 VARCHAR(1), KEY (c1) -) ENGINE=maria; +) ENGINE=aria; # # Insert 100 rows. This turns bulk insert on during the copy phase of # ALTER TABLE. Bulk insert disables keys before the insert and re-enables @@ -1304,7 +1304,7 @@ while ($count) # Change most of the rows into long character values with > 127 characters. UPDATE t1 SET c1=REPEAT("a",128) LIMIT 90; SELECT COUNT(*) FROM t1; -ALTER TABLE t1 ENGINE=maria; +ALTER TABLE t1 ENGINE=aria; # # With bug present, this shows that all long rows are gone. SELECT COUNT(*) FROM t1; @@ -1318,7 +1318,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(50), c2 VARCHAR(1) -) ENGINE=maria DEFAULT CHARSET UTF8; +) ENGINE=aria DEFAULT CHARSET UTF8; # Using Tamil Letter A, Unicode U+0B85 INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); SELECT COUNT(*) FROM t1; @@ -1334,7 +1334,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(50), c2 VARCHAR(1) -) ENGINE=maria DEFAULT CHARSET UTF8; +) ENGINE=aria DEFAULT CHARSET UTF8; # Using Tamil Letter A, Unicode U+0B85 INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); SELECT COUNT(*) FROM t1; @@ -1350,7 +1350,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 CHAR(50), c2 VARCHAR(1) -) ENGINE=maria DEFAULT CHARSET UTF8; +) ENGINE=aria DEFAULT CHARSET UTF8; # Using Tamil Letter A, Unicode U+0B85 INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); # Insert more rows and delete one in the middle to force optimize. @@ -1370,7 +1370,7 @@ CREATE TABLE t1 ( c1 CHAR(50), c2 VARCHAR(1), KEY (c1) -) ENGINE=maria DEFAULT CHARSET UTF8; +) ENGINE=aria DEFAULT CHARSET UTF8; # # Insert 100 rows. This turns bulk insert on during the copy phase of # ALTER TABLE. Bulk insert disables keys before the insert and re-enables @@ -1389,7 +1389,7 @@ while ($count) # Using Tamil Letter A, Unicode U+0B85 UPDATE t1 SET c1=REPEAT(_utf8 x'e0ae85',43) LIMIT 90; SELECT COUNT(*) FROM t1; -ALTER TABLE t1 ENGINE=maria; +ALTER TABLE t1 ENGINE=aria; # # With bug present, this shows that all long rows are gone. SELECT COUNT(*) FROM t1; @@ -1406,7 +1406,7 @@ CREATE TABLE t1 ( c3 VARCHAR(10) NOT NULL, KEY (c1), KEY (c2) -) ENGINE=maria DEFAULT CHARSET=utf8 PACK_KEYS=0; +) ENGINE=aria DEFAULT CHARSET=utf8 PACK_KEYS=0; let $MYSQLD_DATADIR= `select @@datadir`; --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --exec $MARIA_CHK -d $MYSQLD_DATADIR/test/t1 @@ -1423,10 +1423,10 @@ drop table t1; # (same content / differen checksum) # -CREATE TABLE t1 (line LINESTRING NOT NULL) engine=maria; +CREATE TABLE t1 (line LINESTRING NOT NULL) engine=aria; INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)")); checksum table t1; -CREATE TABLE t2 (line LINESTRING NOT NULL) engine=maria; +CREATE TABLE t2 (line LINESTRING NOT NULL) engine=aria; INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)")); checksum table t2; CREATE TABLE t3 select * from t1; @@ -1437,7 +1437,7 @@ drop table t1,t2,t3; # # from bug37276_reduced_corruption.sql # -create table t2(a varchar(255),key(a))engine=maria row_format=dynamic transactional=0; +create table t2(a varchar(255),key(a))engine=aria row_format=dynamic transactional=0; insert into t2 values (repeat('o',124)), (repeat('h',226)), (repeat('i',236)), (repeat('l',234)), (repeat('b',13)), (repeat('g',236)), (repeat('y',205)), (repeat('c',99)), (repeat('g',145)), (repeat('o',131)), (repeat('e',63)), @@ -1649,7 +1649,7 @@ col172 tinyint(1) DEFAULT NULL, col173 tinytext, col174 decimal(10,0) DEFAULT NULL, col175 double DEFAULT NULL -) engine=maria; +) engine=aria; insert ignore into t1 set col10=abs(28449) % 2, @@ -1766,10 +1766,10 @@ check table t1; drop table t1; # -# Bug#38466 maria: range query returns no data +# Bug#38466 aria: range query returns no data # -create table t1 (a char(200) primary key, b int default 12345) engine=maria; +create table t1 (a char(200) primary key, b int default 12345) engine=aria; insert t1 (a) values (repeat('0', 200)); insert t1 (a) values (repeat('1', 200)), (repeat('2', 200)), (repeat('3', 200)), (repeat('4', 200)), (repeat('5', 200)), (repeat('6', 200)), (repeat('7', 200)), @@ -1787,7 +1787,7 @@ drop table t1; # # BUG#38606 test suite # -create table t1 (a int) engine=maria transactional=1; +create table t1 (a int) engine=aria transactional=1; insert into t1 values (1); lock table t1 write concurrent; # should be fixed with fully implemented versioning @@ -1801,7 +1801,7 @@ drop table t1; # create table t1 (p int primary key, i int, a char(10), key k1(i), key k2(a)) -engine maria; +engine aria; insert into t1 values (1, 1, 'qqqq'), (2, 1, 'pppp'), (3, 1, 'yyyy'), (4, 3, 'zzzz'); insert into t1 values (5, 3, 'yyyy'), (6, 3, 'yyyy'), (7, 0, NULL), @@ -1819,8 +1819,8 @@ drop table t1; # --mysqld=--binlog-format=row --ps-protocol # -create table t1 (f1 int unique, f2 int) engine=maria; -create table t2 (f3 int, f4 int) engine=maria; +create table t1 (f1 int unique, f2 int) engine=aria; +create table t2 (f3 int, f4 int) engine=aria; create view v1 as select * from t1, t2 where f1= f3; insert into t1 values (1,11), (2,22); --error 1393 @@ -1834,7 +1834,7 @@ drop view v1; # BUG#39399 ALTER TABLE renaming column: affected_rows > 0 # -CREATE TABLE t1 (id int, c varchar(10)) engine=maria; +CREATE TABLE t1 (id int, c varchar(10)) engine=aria; INSERT INTO t1 VALUES (1,"1"); --enable_info ALTER TABLE t1 CHANGE c d varchar(10); @@ -1842,7 +1842,7 @@ ALTER TABLE t1 CHANGE c d varchar(10); drop table t1; # -# Bug #39227 Maria: crash with ALTER TABLE PARTITION +# Bug #39227 Aria: crash with ALTER TABLE PARTITION # create table t1 (s1 int); @@ -1852,7 +1852,7 @@ alter table t1 partition by list (s1) (partition p1 values in (2)); drop table t1; # -# Bug #39226 Maria: crash with FLUSH TABLES WITH READ LOCK after LOCK TABLES +# Bug #39226 Aria: crash with FLUSH TABLES WITH READ LOCK after LOCK TABLES create table t1 (c1 int); create table t2 (c1 int); @@ -1866,7 +1866,7 @@ drop table t1, t2; # Crash when aborting inserting of row with 2 blobs where first is short # -create table t1(a int primary key, b blob, c blob) engine=maria; +create table t1(a int primary key, b blob, c blob) engine=aria; insert into t1 values(1,repeat('a',100), repeat('b',657860)); --error ER_DUP_ENTRY insert into t1 values(1,repeat('a',100), repeat('b',657860)); @@ -1903,7 +1903,7 @@ CREATE TABLE t1 ( f2 CHAR(255) BINARY NOT NULL DEFAULT '0', f3 CHAR(255) BINARY NOT NULL , f4 CHAR(255) BINARY NOT NULL DEFAULT '0' , - v3 CHAR(255) BINARY NOT NULL DEFAULT '0' , + v3 CHAR(255) BINARY AS ( ( f1 NOT LIKE '%' ) ) PERSISTENT, KEY (v3) ) ENGINE=Maria; INSERT INTO t1 ( f1 , f2 , f3 , f4 ) SELECT f1 , f4 , f1 , f4 FROM t1; @@ -1962,7 +1962,7 @@ drop table t1; --disable_result_log --disable_query_log eval set global storage_engine=$default_engine, -maria_page_checksum=$default_checksum, -maria_log_file_size=$default_log_file_size; +aria_page_checksum=$default_checksum, +aria_log_file_size=$default_log_file_size; --enable_result_log --enable_query_log diff --git a/mysql-test/suite/maria/t/maria2.test b/mysql-test/suite/maria/t/maria2.test index 45155ab9cae..00bbea165ee 100644 --- a/mysql-test/suite/maria/t/maria2.test +++ b/mysql-test/suite/maria/t/maria2.test @@ -6,13 +6,13 @@ drop table if exists t1,t2; --enable_warnings # Test for BUG#36319 -# "Maria: table is not empty but DELETE and SELECT find no rows" +# "Aria: table is not empty but DELETE and SELECT find no rows" CREATE TABLE t1 ( line BLOB, kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po', name VARCHAR(32) -) transactional=0 row_format=page engine=maria; +) transactional=0 row_format=page engine=aria; let $query= INSERT INTO t1 (name, kind, line) VALUES ("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")), @@ -74,8 +74,8 @@ drop table t1; # Testing of ALTER TABLE under lock tables # -create table t1 (i int) engine=maria; -create table t2 (j int) engine=maria; +create table t1 (i int) engine=aria; +create table t2 (j int) engine=aria; lock table t1 write, t2 read; alter table t1 modify i int default 1; insert into t1 values (2); @@ -89,7 +89,7 @@ drop table t1,t2; # test INSERT ON DUPLICATE KEY UPDATE # -create table t1(id int, s char(1), unique(s)) engine=maria; +create table t1(id int, s char(1), unique(s)) engine=aria; insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1; insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1; insert into t1 select 1,"a" on duplicate key update t1.id=t1.id+1; @@ -101,7 +101,7 @@ select * from t1; drop table t1; # test LOAD DATA INFILE REPLACE -create table t1 (pk int primary key, apk int unique, data int) engine=maria; +create table t1 (pk int primary key, apk int unique, data int) engine=aria; insert into t1 values (1, 1, 1), (4, 4, 4), (6, 6, 6); load data concurrent infile '../../std_data/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk); select * from t1 order by pk; diff --git a/mysql-test/suite/maria/t/maria3.test b/mysql-test/suite/maria/t/maria3.test index a6dd0ca6639..b73b75ecfce 100644 --- a/mysql-test/suite/maria/t/maria3.test +++ b/mysql-test/suite/maria/t/maria3.test @@ -1,14 +1,14 @@ -- source include/have_maria.inc -select * from INFORMATION_SCHEMA.ENGINES where ENGINE="MARIA"; +select * from INFORMATION_SCHEMA.ENGINES where ENGINE="ARIA"; let $default_engine=`select @@global.storage_engine`; -let $default_checksum=`select @@global.maria_page_checksum`; -set global storage_engine=maria; -set session storage_engine=maria; -set global maria_page_checksum=0; -let $default_log_file_size=`select @@global.maria_log_file_size`; -set global maria_log_file_size=4294967295; +let $default_checksum=`select @@global.aria_page_checksum`; +set global storage_engine=aria; +set session storage_engine=aria; +set global aria_page_checksum=0; +let $default_log_file_size=`select @@global.aria_log_file_size`; +set global aria_log_file_size=4294967295; # Initialise --disable_warnings @@ -142,7 +142,7 @@ create table `t1` ( t1_id int(10) unsigned not null auto_increment, key (t1_name), primary key (t1_id) -) engine=maria auto_increment = 1000 default charset=latin1; +) engine=aria auto_increment = 1000 default charset=latin1; lock tables t1 write; INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002); check table t1; @@ -190,7 +190,7 @@ drop table t1; # Test where we shrink varchar # -CREATE TABLE t1 (a int, b int, v varchar(60000)) checksum=1 engine=maria; +CREATE TABLE t1 (a int, b int, v varchar(60000)) checksum=1 engine=aria; insert into t1 values (1,1,"aaa"),(1,2,null); checksum table t1; lock table t1 write; @@ -241,13 +241,13 @@ CREATE TABLE t1 ( KEY (ulong), KEY (ulonglong,ulong), KEY (options,flags) -) engine=maria; +) engine=aria; insert into t1 values (10,1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one'); -create table t2 (primary key (auto)) engine=maria row_format=page select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; +create table t2 (primary key (auto)) engine=aria row_format=page select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; check table t1,t2; select t1,t2,length(t3),length(t4),length(t5),length(t6),t7,t8 from t2; drop table t2; -create table t2 (primary key (auto)) engine=maria row_format=dynamic select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; +create table t2 (primary key (auto)) engine=aria row_format=dynamic select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; check table t2; drop table t1,t2; @@ -261,9 +261,9 @@ drop table t1; # Fix if we are using safemalloc --replace_result 8388572 8388600 -select lower(variable_name) as Variable_name, Variable_value as Value from information_schema.session_variables where variable_name like "maria%" and variable_name not like "maria_used_for_temp_tables" order by 1; +select lower(variable_name) as Variable_name, Variable_value as Value from information_schema.session_variables where variable_name like "aria%" and variable_name not like "aria_used_for_temp_tables" order by 1; --replace_column 2 # -show status like 'maria%'; +show status like 'aria%'; # # Test creating table with no field data and index on zero length columns @@ -302,7 +302,7 @@ drop table t1; # # Show that page_checksum is remembered # -set global maria_page_checksum=1; +set global aria_page_checksum=1; create table t1 (a int); show create table t1; drop table t1; @@ -312,7 +312,7 @@ drop table t1; # --enable_warnings -set global maria_log_file_size=4294967296; +set global aria_log_file_size=4294967296; # # Test delete of all rows in autocommit and not autocommit @@ -340,10 +340,10 @@ create table t3 select * from t1, t2; # Should give an error create table t3 select t1.c AS c1, t2.c AS c2,1 as "const" from t1, t2; drop table t1, t2, t3; -# Test for bug "maria_repair() (OPTIMIZE) leaves wrong +# Test for bug "aria_repair() (OPTIMIZE) leaves wrong # data_file_length" (originally from type_datetime.test) -create table t1 (t datetime) engine=maria; +create table t1 (t datetime) engine=aria; insert into t1 values (101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959),(20030100000000),(20030000000000); select * from t1; optimize table t1; @@ -396,18 +396,18 @@ drop table t1; # Test warnings with transactional=1 with MyISAM # -create table t1 (n int not null, c char(1)) engine=maria; +create table t1 (n int not null, c char(1)) engine=aria; alter table t1 engine=myisam; -alter table t1 engine=maria; +alter table t1 engine=aria; show create table t1; drop table t1; -create table t1 (n int not null, c char(1)) engine=maria transactional=1; +create table t1 (n int not null, c char(1)) engine=aria transactional=1; alter table t1 engine=myisam; -alter table t1 engine=maria; +alter table t1 engine=aria; show create table t1; drop table t1; create table t1 (n int not null, c char(1)) engine=myisam transactional=1; -alter table t1 engine=maria; +alter table t1 engine=aria; show create table t1; drop table t1; @@ -455,7 +455,7 @@ drop table t1, t2; # # Test problems with small rows and row_type=page -# Bug 35048 "maria table corruption reported when transactional=0" +# Bug 35048 "aria table corruption reported when transactional=0" # create table t1 (i int auto_increment not null primary key) transactional=0; @@ -501,19 +501,19 @@ DROP TABLE t1; # BUG#36104 - INFORMATION_SCHEMA.TABLES shows TRANSACTIONAL=1 twice in # CREATE_OPTIONS # -create table t1(a int) engine=maria transactional=1; +create table t1(a int) engine=aria transactional=1; select CREATE_OPTIONS from information_schema.TABLES where TABLE_SCHEMA='test' and TABLE_NAME='t1'; drop table t1; # -# BUG#39697 - Maria: hang when failing to insert due to UNIQUE +# BUG#39697 - Aria: hang when failing to insert due to UNIQUE # -create table t1 (a int, unique(a)) engine=maria transactional=1; +create table t1 (a int, unique(a)) engine=aria transactional=1; insert into t1 values(1); --error 1062 insert into t1 values(2),(2); -create table t2 (a int, unique(a)) engine=maria transactional=0 row_format=dynamic; +create table t2 (a int, unique(a)) engine=aria transactional=0 row_format=dynamic; insert into t2 values(1); --error 1062 insert into t2 values(2),(2); @@ -529,7 +529,7 @@ drop table t1, t2; --disable_result_log --disable_query_log eval set global storage_engine=$default_engine, -maria_page_checksum=$default_checksum, -maria_log_file_size=$default_log_file_size; +aria_page_checksum=$default_checksum, +aria_log_file_size=$default_log_file_size; --enable_result_log --enable_query_log diff --git a/mysql-test/suite/maria/t/maria_notembedded.test b/mysql-test/suite/maria/t/maria_notembedded.test index 0f27802de27..f1d71e90354 100644 --- a/mysql-test/suite/maria/t/maria_notembedded.test +++ b/mysql-test/suite/maria/t/maria_notembedded.test @@ -4,7 +4,7 @@ -- source include/have_maria.inc let $default_engine=`select @@session.storage_engine`; -set session storage_engine=maria; +set session storage_engine=aria; # Verify that INSERT DELAYED is disabled only for transactional tables # ("embedded" server translates them to plain INSERT) diff --git a/mysql-test/suite/maria/t/maria_partition.test b/mysql-test/suite/maria/t/maria_partition.test index ced87903c21..47571c7a4be 100644 --- a/mysql-test/suite/maria/t/maria_partition.test +++ b/mysql-test/suite/maria/t/maria_partition.test @@ -1,13 +1,13 @@ -# Maria tests which require partitioning enabled +# Aria tests which require partitioning enabled --source include/have_partition.inc -- source include/have_maria.inc let $default_engine=`select @@global.storage_engine`; -let $default_checksum=`select @@global.maria_page_checksum`; -set global storage_engine=maria; -set session storage_engine=maria; -set global maria_page_checksum=0; +let $default_checksum=`select @@global.aria_page_checksum`; +set global storage_engine=aria; +set session storage_engine=aria; +set global aria_page_checksum=0; # Initialise --disable_warnings @@ -17,7 +17,7 @@ drop view if exists v1; SET SQL_WARNINGS=1; # -# Bug #39227 Maria: crash with ALTER TABLE PARTITION +# Bug #39227 Aria: crash with ALTER TABLE PARTITION # create table t1 (s1 int); @@ -29,8 +29,8 @@ drop table t1; # # Test outer join const propagation # -create table t2(a blob) engine=maria; -create table t1(a int primary key) engine=maria; +create table t2(a blob) engine=aria; +create table t1(a int primary key) engine=aria; insert into t2 values ('foo'),('bar'); select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb'; insert into t1 values (1); @@ -52,7 +52,7 @@ drop table t1,t2; # Set defaults back --disable_result_log --disable_query_log -eval set global storage_engine=$default_engine, maria_page_checksum=$default_checksum; -set global maria_log_file_size=default; +eval set global storage_engine=$default_engine, aria_page_checksum=$default_checksum; +set global aria_log_file_size=default; --enable_result_log --enable_query_log diff --git a/mysql-test/suite/maria/t/maria_showlog_error.test b/mysql-test/suite/maria/t/maria_showlog_error.test index 9c4d5b8ef2c..d6c59c5a0a6 100644 --- a/mysql-test/suite/maria/t/maria_showlog_error.test +++ b/mysql-test/suite/maria/t/maria_showlog_error.test @@ -19,9 +19,9 @@ connection default; connection default; let MYSQLD_DATADIR= `select @@datadir`; -remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000001; ---replace_regex /Size unknown ; .*maria_log.00000001/Size unknown ; maria_log.00000001/ -show engine maria logs; +remove_file $MYSQLD_DATADIR/$MARIA_LOG/aria_log.00000001; +--replace_regex /Size unknown ; .*aria_log.00000001/Size unknown ; aria_log.00000001/ +show engine aria logs; # cleunup after this test -- source include/maria_empty_logs.inc diff --git a/mysql-test/suite/maria/t/optimize.test b/mysql-test/suite/maria/t/optimize.test index 9f38a68edeb..fe87bc558cb 100644 --- a/mysql-test/suite/maria/t/optimize.test +++ b/mysql-test/suite/maria/t/optimize.test @@ -5,13 +5,13 @@ drop table if exists t1; --enable_warnings # -# Test for LP#603026: RQG: pagecache_read: Assertion `pageno < ((1ULL) << 40)' on OPTIMIZE TABLE of a Maria table +# Test for LP#603026: RQG: pagecache_read: Assertion `pageno < ((1ULL) << 40)' on OPTIMIZE TABLE of a Aria table # --disable_query_log set autocommit=1; --disable_warnings -CREATE TABLE t1 ( `col_varchar_1024_utf8_not_null_key` varchar(1024) CHARACTER SET utf8 not null, `col_varchar_1024_utf8_key` varchar(1024) CHARACTER SET utf8, `col_varchar_1024_utf8_not_null` varchar(1024) CHARACTER SET utf8 not null, `col_varchar_1024_utf8` varchar(1024) CHARACTER SET utf8, pk varchar(1024) not null, `col_varchar_1024_latin1` varchar(1024) CHARACTER SET latin1, `col_varchar_1024_latin1_not_null_key` varchar(1024) CHARACTER SET latin1 not null, `col_varchar_1024_latin1_not_null` varchar(1024) CHARACTER SET latin1 not null, `col_varchar_1024_latin1_key` varchar(1024) CHARACTER SET latin1, /*Indices*/ key (`col_varchar_1024_utf8_not_null_key` ), key (`col_varchar_1024_utf8_key` ), primary key (pk), key (`col_varchar_1024_latin1_not_null_key` ), key (`col_varchar_1024_latin1_key` )) ENGINE=maria; +CREATE TABLE t1 ( `col_varchar_1024_utf8_not_null_key` varchar(1024) CHARACTER SET utf8 not null, `col_varchar_1024_utf8_key` varchar(1024) CHARACTER SET utf8, `col_varchar_1024_utf8_not_null` varchar(1024) CHARACTER SET utf8 not null, `col_varchar_1024_utf8` varchar(1024) CHARACTER SET utf8, pk varchar(1024) not null, `col_varchar_1024_latin1` varchar(1024) CHARACTER SET latin1, `col_varchar_1024_latin1_not_null_key` varchar(1024) CHARACTER SET latin1 not null, `col_varchar_1024_latin1_not_null` varchar(1024) CHARACTER SET latin1 not null, `col_varchar_1024_latin1_key` varchar(1024) CHARACTER SET latin1, /*Indices*/ key (`col_varchar_1024_utf8_not_null_key` ), key (`col_varchar_1024_utf8_key` ), primary key (pk), key (`col_varchar_1024_latin1_not_null_key` ), key (`col_varchar_1024_latin1_key` )) ENGINE=aria; --enable_warnings INSERT /*! IGNORE */ INTO t1 VALUES ('dbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzb', 'wdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwby', 'something', 'pwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfa', 1, 'dpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjr', 'can', 'hdpwdbhfatqokbosjofmpdxvhq', 'rhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxw') , ('urhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxci', 'turhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidl', 'to', 'rturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftka', 2, 'grturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmh', 'ygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvh', 'rygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbnfwvhwdjgrhlfusfplamodraqbpgtdgviqngjtlykclmdokwpttsicss', 'vrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizw') , ('c', 'wvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbld', 'had', 'twvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxw', 3, 'htwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjd', 'q', 'z', 'phtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfi') , ('vphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapn', 'jvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjv', 'ejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgq', 'vejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqyt', 4, 't', 'why', 'your', 'cvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxrey') , ('v', 'rcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambx', 'frcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilx', 'p', 5, 'kfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbnfwvhwdjgrhlfusfplamodr', 'i', 'ikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmy', 'jikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmu'); INSERT /*! IGNORE */ INTO t1 VALUES ('wjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcq', 'uwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnng', 'zuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajy', 'i', 6, 'u', 'q', 'd', 'izuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkq') , ('bizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdub', 'd', 'lbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbn', 'llbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfz', 7, 'bllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutf', 'rbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmf', 'really', 'yrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnngh') , ('tyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwp', 'xtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmsw', 'kxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgkne', 'mkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjv', 8, 'zmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgx', 'ezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbnfwvhwdjgrhlfusfplamodraqbpgtdgviqngjtlykclm', 'no', 'eezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczs') , ('m', 'keezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfep', 'tkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqh', 'ztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbnfwvhwdjgrhlf', 9, 'n', 'hey', 'hztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxw', 'shztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveamb') , ('bshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvf', 'on', 'look', 'I', 10, 'xbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxz', 'lxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjr', 'what', 'ilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnrolj'); diff --git a/mysql-test/suite/maria/t/ps_maria.test b/mysql-test/suite/maria/t/ps_maria.test index 34960d90f8f..d3623314631 100644 --- a/mysql-test/suite/maria/t/ps_maria.test +++ b/mysql-test/suite/maria/t/ps_maria.test @@ -1,6 +1,6 @@ ############################################### # # -# Prepared Statements test on MARIA tables # +# Prepared Statements test on ARIA tables # # # ############################################### @@ -12,7 +12,7 @@ use test; -let $type= 'MARIA' ; +let $type= 'ARIA' ; -- source include/ps_create.inc -- source include/ps_renew.inc @@ -47,6 +47,6 @@ drop table t1, t9; --disable_result_log --disable_query_log -set global maria_log_file_size=default; +set global aria_log_file_size=default; --enable_result_log --enable_query_log diff --git a/mysql-test/suite/maria/t/small_blocksize-master.opt b/mysql-test/suite/maria/t/small_blocksize-master.opt new file mode 100644 index 00000000000..59fd35a7846 --- /dev/null +++ b/mysql-test/suite/maria/t/small_blocksize-master.opt @@ -0,0 +1 @@ +--aria-block-size=1024 diff --git a/mysql-test/suite/maria/t/small_blocksize.test b/mysql-test/suite/maria/t/small_blocksize.test new file mode 100644 index 00000000000..0acf8df6e66 --- /dev/null +++ b/mysql-test/suite/maria/t/small_blocksize.test @@ -0,0 +1,34 @@ +DROP TABLE if exists t1; + +# +# Test of extending updated rows. +# This caused failures in lp:815022 +# +CREATE TABLE t1 (col_longtext_ucs2 longtext, col_longtext_utf8 longtext, col_varchar_255_ucs2_key varchar(255), col_set_utf8 set ('a','b'), col_char_255_ucs2 char(255), col_char_255_ucs2_key char(255), col_enum_ucs2 enum ('a','b'), col_varchar_255_ucs2 varchar(255), col_longtext_ucs2_key longtext, col_longtext_utf8_key longtext, col_enum_utf8 enum ('a','b'), col_varchar_255_utf8_key varchar(1024), col_varchar_255_utf8 varchar(255), col_enum_ucs2_key enum ('a','b'), col_enum_utf8_key enum ('a','b'), col_set_utf8_key set ('a','b'), col_char_255_utf8 char(255), pk integer auto_increment, col_set_ucs2_key set ('a','b'), col_char_255_utf8_key char(255), col_set_ucs2 set ('a','b'), primary key (pk)) ENGINE=aria; +INSERT INTO t1 ( col_char_255_utf8, col_varchar_255_utf8_key, col_longtext_utf8_key ) VALUES ( 'lggnqojgqectqlkvskffihliqcwoakzzzjvhkqlwjybkngdbubskflpmzegdrk', REPEAT( 'a', 627 ), 'mlggnqojgqectqlkvskffihliqcwoakzzzjvhkqlwjybkngdbubskflpmzegdrklnipcmzbtwdqfnyinqfohgtiwmvfpbuslgobjhslxnaybcyebhsrlipnuvalhmvhlwbwujtvjsdrbyapfzprnxfgtrukwhywtkaoupsaogxsjxhqjkidvnpeytjgndtnrrbm' ); +UPDATE t1 SET col_varchar_255_utf8 = REPEAT('a', 197 ); +UPDATE t1 SET col_char_255_utf8 = 'bmjihzjtxegprqfvmczyzbavjuozkyxrlxvqyzcfvsjrhcccqnecyohzhzbgsbqkqvzmtlhtlcgzheirkyfwczoolilkrfimfnuoapyylbghdhdgfebjjajfoigagozypqtrflrvdiwfgqalsqbmlllsanvtuuutiaastqtbzeoaawl'; +check table t1; +drop table t1; + +create table t1 (a int primary key auto_increment, e1 enum('a','b'), e2 enum('a','b'), vl int, bl int, c char(10), v1 varchar(10000), v2 varchar(10000), b1 blob, b2 blob) engine=aria; + +insert into t1 (vl,bl) values (10,10),(100,100),(1000,1000),(5000,5000),(8000,12000); +update t1 set c="test", v1=repeat('a',vl),v2=repeat('b',vl/2),b1=repeat('c',bl),b2=repeat('d',bl); +insert into t1 (vl,bl) values (10,10),(100,100),(1000,1000),(1000,5000); +update t1 set c="test", v1=repeat('a',vl/4),v2=repeat('b',vl/5),b1=repeat('c',bl*2),b2=repeat('d',bl/2); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',vl),v2=repeat('b',vl),b1=repeat('c',bl*2),b2=repeat('d',bl/2); +update t1 set c="test", v1=repeat('a',vl/2),v2=repeat('b',vl/2),b1=repeat('c',bl/2),b2=repeat('d',bl/2); +update t1 set c="test", v1=repeat('a',vl/4),v2=repeat('b',vl/4),b1=repeat('c',bl/4),b2=repeat('d',bl/4); +update t1 set c="test", v1=repeat('a',vl/20),v2=repeat('b',vl),b1=repeat('c',bl/20),b2=repeat('d',bl/20); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',vl/100),b1=repeat('c',bl/100); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',vl),b1=repeat('c',bl); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',10),v2=repeat('b',10); +insert into t1 (vl,bl) values (100,100); +update t1 set c="test", v1=repeat('a',2000),v2=repeat('b',2000); +check table t1; +drop table t1; diff --git a/mysql-test/suite/oqgraph/r/basic.result b/mysql-test/suite/oqgraph/r/basic.result new file mode 100644 index 00000000000..e90659c0986 --- /dev/null +++ b/mysql-test/suite/oqgraph/r/basic.result @@ -0,0 +1,63 @@ +drop table if exists graph; +Warnings: +Note 1051 Unknown table 'graph' +CREATE TABLE graph ( +latch SMALLINT UNSIGNED NULL, +origid BIGINT UNSIGNED NULL, +destid BIGINT UNSIGNED NULL, +weight DOUBLE NULL, +seq BIGINT UNSIGNED NULL, +linkid BIGINT UNSIGNED NULL, +KEY (latch, origid, destid) USING HASH, +KEY (latch, destid, origid) USING HASH +) ENGINE=OQGRAPH; +delete from graph; +insert into graph(origid, destid) values (1,2), (2,1); +insert into graph(origid, destid) values (1,3), (3,1); +insert into graph(origid, destid) values (3,4), (4,3); +insert into graph(origid, destid) values (3,5), (5,3); +insert into graph(origid, destid) values (5,6), (6,5); +select * from graph where latch = 2 and origid = 1 and weight = 1; +latch origid destid weight seq linkid +2 1 NULL 1 3 3 +2 1 NULL 1 2 2 +select * from graph where latch = 2 and origid = 1 and weight = 2; +latch origid destid weight seq linkid +2 1 NULL 2 5 5 +2 1 NULL 2 4 4 +select * from graph +where latch = 2 and origid = 1 and (weight = 1 or weight = 2); +latch origid destid weight seq linkid +2 1 NULL 2 5 5 +2 1 NULL 2 4 4 +2 1 NULL 1 3 3 +2 1 NULL 1 2 2 +select * from graph where latch=1 and origid=1 and destid=6; +latch origid destid weight seq linkid +1 1 6 NULL 0 1 +1 1 6 1 1 3 +1 1 6 1 2 5 +1 1 6 1 3 6 +select * from graph where latch=1 and origid=1 and destid=4; +latch origid destid weight seq linkid +1 1 4 NULL 0 1 +1 1 4 1 1 3 +1 1 4 1 2 4 +select * from graph where latch=1 and origid=4 and destid=1; +latch origid destid weight seq linkid +1 4 1 NULL 0 4 +1 4 1 1 1 3 +1 4 1 1 2 1 +insert into graph (origid,destid) values (4,6); +delete from graph where origid=5; +delete from graph where origid=3 and destid=5; +select * from graph where latch=1 and origid=1 and destid=6; +latch origid destid weight seq linkid +1 1 6 NULL 0 1 +1 1 6 1 1 3 +1 1 6 1 2 4 +1 1 6 1 3 6 +select * from graph where latch=1 and origid=6 and destid=1; +latch origid destid weight seq linkid +truncate table graph; +drop table graph; diff --git a/mysql-test/suite/oqgraph/r/binlog.result b/mysql-test/suite/oqgraph/r/binlog.result new file mode 100644 index 00000000000..ee0a8c081f4 --- /dev/null +++ b/mysql-test/suite/oqgraph/r/binlog.result @@ -0,0 +1,18 @@ +drop table if exists graph; +CREATE TABLE graph ( +latch SMALLINT UNSIGNED NULL, +origid BIGINT UNSIGNED NULL, +destid BIGINT UNSIGNED NULL, +weight DOUBLE NULL, +seq BIGINT UNSIGNED NULL, +linkid BIGINT UNSIGNED NULL, +KEY (latch, origid, destid) USING HASH, +KEY (latch, destid, origid) USING HASH +) ENGINE=OQGRAPH; +SET binlog_format = row; +insert into graph(origid, destid) values (1,3), (3,1); +SET binlog_format = statement; +insert into graph(origid, destid) values (3,4), (4,3); +SET binlog_format = mixed; +insert into graph(origid, destid) values (3,5), (5,3); +drop table graph; diff --git a/mysql-test/suite/oqgraph/suite.opt b/mysql-test/suite/oqgraph/suite.opt new file mode 100644 index 00000000000..bc7ccfc1414 --- /dev/null +++ b/mysql-test/suite/oqgraph/suite.opt @@ -0,0 +1 @@ +--plugin-load=$HA_OQGRAPH_SO diff --git a/mysql-test/suite/oqgraph/suite.pm b/mysql-test/suite/oqgraph/suite.pm new file mode 100644 index 00000000000..5066d4e9f8a --- /dev/null +++ b/mysql-test/suite/oqgraph/suite.pm @@ -0,0 +1,8 @@ +package My::Suite::OQGraph; + +@ISA = qw(My::Suite); + +return "No OQGraph" unless $ENV{HA_OQGRAPH_SO}; + +bless { }; + diff --git a/mysql-test/suite/oqgraph/t/basic.test b/mysql-test/suite/oqgraph/t/basic.test new file mode 100644 index 00000000000..731f07c0eeb --- /dev/null +++ b/mysql-test/suite/oqgraph/t/basic.test @@ -0,0 +1,43 @@ +drop table if exists graph; + +CREATE TABLE graph ( + latch SMALLINT UNSIGNED NULL, + origid BIGINT UNSIGNED NULL, + destid BIGINT UNSIGNED NULL, + weight DOUBLE NULL, + seq BIGINT UNSIGNED NULL, + linkid BIGINT UNSIGNED NULL, + KEY (latch, origid, destid) USING HASH, + KEY (latch, destid, origid) USING HASH + ) ENGINE=OQGRAPH; + +delete from graph; + +insert into graph(origid, destid) values (1,2), (2,1); +insert into graph(origid, destid) values (1,3), (3,1); +insert into graph(origid, destid) values (3,4), (4,3); +insert into graph(origid, destid) values (3,5), (5,3); +insert into graph(origid, destid) values (5,6), (6,5); + +select * from graph where latch = 2 and origid = 1 and weight = 1; + +select * from graph where latch = 2 and origid = 1 and weight = 2; + +select * from graph +where latch = 2 and origid = 1 and (weight = 1 or weight = 2); + +select * from graph where latch=1 and origid=1 and destid=6; +select * from graph where latch=1 and origid=1 and destid=4; +select * from graph where latch=1 and origid=4 and destid=1; + +insert into graph (origid,destid) values (4,6); + +delete from graph where origid=5; +delete from graph where origid=3 and destid=5; + +select * from graph where latch=1 and origid=1 and destid=6; +select * from graph where latch=1 and origid=6 and destid=1; + +truncate table graph; + +drop table graph; diff --git a/mysql-test/suite/oqgraph/t/binlog.test b/mysql-test/suite/oqgraph/t/binlog.test new file mode 100644 index 00000000000..7b3b6bdb8a9 --- /dev/null +++ b/mysql-test/suite/oqgraph/t/binlog.test @@ -0,0 +1,27 @@ +-- source include/have_log_bin.inc + +--disable_warnings +drop table if exists graph; +--enable_warnings + +CREATE TABLE graph ( + latch SMALLINT UNSIGNED NULL, + origid BIGINT UNSIGNED NULL, + destid BIGINT UNSIGNED NULL, + weight DOUBLE NULL, + seq BIGINT UNSIGNED NULL, + linkid BIGINT UNSIGNED NULL, + KEY (latch, origid, destid) USING HASH, + KEY (latch, destid, origid) USING HASH + ) ENGINE=OQGRAPH; + +# MBug#524625: OQGraph error with binary logging enabled +# Test that OQGraph works with different binlogging modes. +SET binlog_format = row; +insert into graph(origid, destid) values (1,3), (3,1); +SET binlog_format = statement; +insert into graph(origid, destid) values (3,4), (4,3); +SET binlog_format = mixed; +insert into graph(origid, destid) values (3,5), (5,3); + +drop table graph; diff --git a/mysql-test/suite/parts/r/partition_alter2_1_maria.result b/mysql-test/suite/parts/r/partition_alter2_1_maria.result index 3d4553e8d0f..4f52cb3c131 100644 --- a/mysql-test/suite/parts/r/partition_alter2_1_maria.result +++ b/mysql-test/suite/parts/r/partition_alter2_1_maria.result @@ -1,5 +1,5 @@ SET @max_row = 20; -SET @@session.storage_engine = 'MARIA'; +SET @@session.storage_engine = 'Aria'; #------------------------------------------------------------------------ # 0. Setting of auxiliary variables + Creation of an auxiliary tables @@ -73,7 +73,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -538,7 +538,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -1017,16 +1017,16 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -1507,14 +1507,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -1987,14 +1987,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -2477,21 +2477,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -2972,21 +2972,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -3465,13 +3465,13 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -3951,7 +3951,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -4468,7 +4468,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -4999,16 +4999,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -5541,14 +5541,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -6073,14 +6073,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -6615,21 +6615,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -7162,21 +7162,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -7707,13 +7707,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -8243,7 +8243,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -8760,7 +8760,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -9291,16 +9291,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -9833,14 +9833,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -10365,14 +10365,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -10907,21 +10907,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -11454,21 +11454,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -11999,13 +11999,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -12539,7 +12539,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -13004,7 +13004,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -13483,16 +13483,16 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -13973,14 +13973,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -14453,14 +14453,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -14943,21 +14943,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -15438,21 +15438,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -15931,13 +15931,13 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -16415,7 +16415,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1 + f_int2) PARTITIONS 2 */ @@ -16880,7 +16880,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1,f_int2) PARTITIONS 5 */ @@ -17359,16 +17359,16 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1 + f_int2,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -17849,14 +17849,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE ((f_int1 + f_int2) DIV 2) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -18329,14 +18329,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY HASH (f_int2) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -18817,21 +18817,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int2) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -19312,21 +19312,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int2 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -19805,13 +19805,13 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int2) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -20291,7 +20291,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -20808,7 +20808,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -21339,16 +21339,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -21881,14 +21881,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -22413,14 +22413,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -22955,21 +22955,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -23502,21 +23502,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -24047,13 +24047,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -24583,7 +24583,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1 + f_int2) PARTITIONS 2 */ @@ -25100,7 +25100,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1,f_int2) PARTITIONS 5 */ @@ -25631,16 +25631,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1 + f_int2,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -26173,14 +26173,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE ((f_int1 + f_int2) DIV 2) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -26705,14 +26705,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY HASH (f_int2) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -27245,21 +27245,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int2) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -27792,21 +27792,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int2 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -28337,13 +28337,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int2) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -28873,7 +28873,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -29390,7 +29390,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -29921,16 +29921,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -30463,14 +30463,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -30995,14 +30995,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -31537,21 +31537,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -32084,21 +32084,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -32629,13 +32629,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -33165,7 +33165,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1 + f_int2) PARTITIONS 2 */ @@ -33682,7 +33682,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1,f_int2) PARTITIONS 5 */ @@ -34213,16 +34213,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1 + f_int2,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -34755,14 +34755,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE ((f_int1 + f_int2) DIV 2) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -35287,14 +35287,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY HASH (f_int2) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -35827,21 +35827,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int2) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -36374,21 +36374,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int2 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -36919,13 +36919,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int2) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD diff --git a/mysql-test/suite/parts/r/partition_alter2_2_maria.result b/mysql-test/suite/parts/r/partition_alter2_2_maria.result index 2dc7023100c..f310169fb6e 100644 --- a/mysql-test/suite/parts/r/partition_alter2_2_maria.result +++ b/mysql-test/suite/parts/r/partition_alter2_2_maria.result @@ -1,5 +1,5 @@ SET @max_row = 20; -SET @@session.storage_engine = 'MARIA'; +SET @@session.storage_engine = 'Aria'; #------------------------------------------------------------------------ # 0. Setting of auxiliary variables + Creation of an auxiliary tables @@ -73,7 +73,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -540,7 +540,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -1021,16 +1021,16 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -1513,14 +1513,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -1993,14 +1993,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -2485,21 +2485,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -2980,21 +2980,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -3475,13 +3475,13 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -3963,7 +3963,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -4482,7 +4482,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -5015,16 +5015,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -5559,14 +5559,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -6091,14 +6091,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -6635,21 +6635,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -7182,21 +7182,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -7729,13 +7729,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -8267,7 +8267,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -8786,7 +8786,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -9319,16 +9319,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -9863,14 +9863,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -10395,14 +10395,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -10939,21 +10939,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -11486,21 +11486,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -12033,13 +12033,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx1` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -12574,7 +12574,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -13042,7 +13042,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -13524,16 +13524,16 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -14017,14 +14017,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -14502,14 +14502,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -14995,21 +14995,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -15495,21 +15495,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -15991,13 +15991,13 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -16478,7 +16478,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1 + f_int2) PARTITIONS 2 */ @@ -16946,7 +16946,7 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1,f_int2) PARTITIONS 5 */ @@ -17428,16 +17428,16 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1 + f_int2,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -17921,14 +17921,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE ((f_int1 + f_int2) DIV 2) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -18406,14 +18406,14 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY HASH (f_int2) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -18899,21 +18899,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int2) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -19399,21 +19399,21 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int2 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -19895,13 +19895,13 @@ t1 CREATE TABLE `t1` ( `f_char1` char(20) DEFAULT NULL, `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int2) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -20384,7 +20384,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -20904,7 +20904,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -21438,16 +21438,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -21983,14 +21983,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -22520,14 +22520,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -23065,21 +23065,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -23617,21 +23617,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -24165,13 +24165,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -24704,7 +24704,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1 + f_int2) PARTITIONS 2 */ @@ -25224,7 +25224,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1,f_int2) PARTITIONS 5 */ @@ -25758,16 +25758,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1 + f_int2,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -26303,14 +26303,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE ((f_int1 + f_int2) DIV 2) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -26840,14 +26840,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY HASH (f_int2) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -27385,21 +27385,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int2) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -27937,21 +27937,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int2 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -28485,13 +28485,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int1`,`f_int2`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int2) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -29024,7 +29024,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1) PARTITIONS 2 */ @@ -29544,7 +29544,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) PARTITIONS 5 */ @@ -30078,16 +30078,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -30623,14 +30623,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -31160,14 +31160,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1 DIV 2) SUBPARTITION BY HASH (f_int1) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -31705,21 +31705,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int1) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -32257,21 +32257,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int1 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -32805,13 +32805,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int1) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD @@ -33344,7 +33344,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (f_int1 + f_int2) PARTITIONS 2 */ @@ -33864,7 +33864,7 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1,f_int2) PARTITIONS 5 */ @@ -34398,16 +34398,16 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (MOD(f_int1 + f_int2,4)) -(PARTITION part_3 VALUES IN (-3) ENGINE = MARIA, - PARTITION part_2 VALUES IN (-2) ENGINE = MARIA, - PARTITION part_1 VALUES IN (-1) ENGINE = MARIA, - PARTITION part_N VALUES IN (NULL) ENGINE = MARIA, - PARTITION part0 VALUES IN (0) ENGINE = MARIA, - PARTITION part1 VALUES IN (1) ENGINE = MARIA, - PARTITION part2 VALUES IN (2) ENGINE = MARIA, - PARTITION part3 VALUES IN (3) ENGINE = MARIA) */ +(PARTITION part_3 VALUES IN (-3) ENGINE = Aria, + PARTITION part_2 VALUES IN (-2) ENGINE = Aria, + PARTITION part_1 VALUES IN (-1) ENGINE = Aria, + PARTITION part_N VALUES IN (NULL) ENGINE = Aria, + PARTITION part0 VALUES IN (0) ENGINE = Aria, + PARTITION part1 VALUES IN (1) ENGINE = Aria, + PARTITION part2 VALUES IN (2) ENGINE = Aria, + PARTITION part3 VALUES IN (3) ENGINE = Aria) */ unified filelist t1#P#part0.MAD @@ -34943,14 +34943,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE ((f_int1 + f_int2) DIV 2) -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (15) ENGINE = MARIA, - PARTITION parte VALUES LESS THAN (20) ENGINE = MARIA, - PARTITION partf VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (15) ENGINE = Aria, + PARTITION parte VALUES LESS THAN (20) ENGINE = Aria, + PARTITION partf VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta.MAD @@ -35480,14 +35480,14 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY HASH (f_int2) SUBPARTITIONS 2 -(PARTITION parta VALUES LESS THAN (0) ENGINE = MARIA, - PARTITION partb VALUES LESS THAN (5) ENGINE = MARIA, - PARTITION partc VALUES LESS THAN (10) ENGINE = MARIA, - PARTITION partd VALUES LESS THAN (2147483646) ENGINE = MARIA) */ +(PARTITION parta VALUES LESS THAN (0) ENGINE = Aria, + PARTITION partb VALUES LESS THAN (5) ENGINE = Aria, + PARTITION partc VALUES LESS THAN (10) ENGINE = Aria, + PARTITION partd VALUES LESS THAN (2147483646) ENGINE = Aria) */ unified filelist t1#P#parta#SP#partasp0.MAD @@ -36025,21 +36025,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (f_int1) SUBPARTITION BY KEY (f_int2) (PARTITION part1 VALUES LESS THAN (0) - (SUBPARTITION subpart11 ENGINE = MARIA, - SUBPARTITION subpart12 ENGINE = MARIA), + (SUBPARTITION subpart11 ENGINE = Aria, + SUBPARTITION subpart12 ENGINE = Aria), PARTITION part2 VALUES LESS THAN (5) - (SUBPARTITION subpart21 ENGINE = MARIA, - SUBPARTITION subpart22 ENGINE = MARIA), + (SUBPARTITION subpart21 ENGINE = Aria, + SUBPARTITION subpart22 ENGINE = Aria), PARTITION part3 VALUES LESS THAN (10) - (SUBPARTITION subpart31 ENGINE = MARIA, - SUBPARTITION subpart32 ENGINE = MARIA), + (SUBPARTITION subpart31 ENGINE = Aria, + SUBPARTITION subpart32 ENGINE = Aria), PARTITION part4 VALUES LESS THAN (2147483646) - (SUBPARTITION subpart41 ENGINE = MARIA, - SUBPARTITION subpart42 ENGINE = MARIA)) */ + (SUBPARTITION subpart41 ENGINE = Aria, + SUBPARTITION subpart42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#subpart11.MAD @@ -36577,21 +36577,21 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,3))) SUBPARTITION BY HASH (f_int2 + 1) (PARTITION part1 VALUES IN (0) - (SUBPARTITION sp11 ENGINE = MARIA, - SUBPARTITION sp12 ENGINE = MARIA), + (SUBPARTITION sp11 ENGINE = Aria, + SUBPARTITION sp12 ENGINE = Aria), PARTITION part2 VALUES IN (1) - (SUBPARTITION sp21 ENGINE = MARIA, - SUBPARTITION sp22 ENGINE = MARIA), + (SUBPARTITION sp21 ENGINE = Aria, + SUBPARTITION sp22 ENGINE = Aria), PARTITION part3 VALUES IN (2) - (SUBPARTITION sp31 ENGINE = MARIA, - SUBPARTITION sp32 ENGINE = MARIA), + (SUBPARTITION sp31 ENGINE = Aria, + SUBPARTITION sp32 ENGINE = Aria), PARTITION part4 VALUES IN (NULL) - (SUBPARTITION sp41 ENGINE = MARIA, - SUBPARTITION sp42 ENGINE = MARIA)) */ + (SUBPARTITION sp41 ENGINE = Aria, + SUBPARTITION sp42 ENGINE = Aria)) */ unified filelist t1#P#part1#SP#sp11.MAD @@ -37125,13 +37125,13 @@ t1 CREATE TABLE `t1` ( `f_char2` char(20) DEFAULT NULL, `f_charbig` varchar(1000) DEFAULT NULL, UNIQUE KEY `uidx` (`f_int2`,`f_int1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (ABS(MOD(f_int1,2))) SUBPARTITION BY KEY (f_int2) SUBPARTITIONS 3 -(PARTITION part1 VALUES IN (0) ENGINE = MARIA, - PARTITION part2 VALUES IN (1) ENGINE = MARIA, - PARTITION part3 VALUES IN (NULL) ENGINE = MARIA) */ +(PARTITION part1 VALUES IN (0) ENGINE = Aria, + PARTITION part2 VALUES IN (1) ENGINE = Aria, + PARTITION part3 VALUES IN (NULL) ENGINE = Aria) */ unified filelist t1#P#part1#SP#part1sp0.MAD diff --git a/mysql-test/suite/parts/r/partition_auto_increment_maria.result b/mysql-test/suite/parts/r/partition_auto_increment_maria.result index 228f93196f2..b9310a2a314 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_maria.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_maria.result @@ -3,13 +3,13 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE='MARIA'; +ENGINE='Aria'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; AUTO_INCREMENT @@ -71,20 +71,20 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE='MARIA'; +ENGINE='Aria'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 FLUSH TABLE; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 INSERT INTO t1 VALUES (4); FLUSH TABLE; SHOW CREATE TABLE t1; @@ -92,7 +92,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 INSERT INTO t1 VALUES (NULL); FLUSH TABLE; SHOW CREATE TABLE t1; @@ -100,7 +100,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 DELETE FROM t1; INSERT INTO t1 VALUES (NULL); SHOW CREATE TABLE t1; @@ -108,7 +108,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 SELECT * FROM t1 ORDER BY c1; c1 6 @@ -119,7 +119,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 SELECT * FROM t1 ORDER BY c1; c1 1 @@ -134,12 +134,12 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=102 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria AUTO_INCREMENT=102 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 DROP TABLE t1; CREATE TABLE t1 (a INT NULL AUTO_INCREMENT, UNIQUE KEY (a)) -ENGINE='MARIA'; +ENGINE='Aria'; SET LAST_INSERT_ID = 999; SET INSERT_ID = 0; INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; @@ -176,7 +176,7 @@ SET INSERT_ID = 1; CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE='MARIA' +ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 2; INSERT INTO t1 VALUES (NULL); @@ -185,7 +185,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SELECT * FROM t1; @@ -197,7 +197,7 @@ CREATE TABLE t1 ( c1 INT, c2 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c2)) -ENGINE='MARIA' +ENGINE='Aria' PARTITION BY HASH(c2) PARTITIONS 2; INSERT INTO t1 VALUES (1, NULL); @@ -215,7 +215,7 @@ CREATE TABLE t1 ( c1 INT, c2 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c2)) -ENGINE='MARIA' +ENGINE='Aria' PARTITION BY HASH(c2) PARTITIONS 2; INSERT INTO t1 VALUES (1, 0); @@ -236,7 +236,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE='MARIA' +ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 2; INSERT INTO t1 VALUES (2), (4), (NULL); @@ -287,7 +287,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE='MARIA' +ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 2; SET @@session.auto_increment_increment = 10; @@ -335,7 +335,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE='MARIA' +ENGINE='Aria' PARTITION BY HASH (c1) PARTITIONS 2; SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='test' @@ -409,7 +409,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=27 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=27 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SELECT * FROM t1 ORDER BY c1; @@ -422,7 +422,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=28 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=28 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SELECT * FROM t1 ORDER BY c1; @@ -439,14 +439,14 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=102 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=102 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ DROP TABLE t1; # Test with two threads # con default CREATE TABLE t1 (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE = 'MARIA' +ENGINE = 'Aria' PARTITION BY HASH(c1) PARTITIONS 2; INSERT INTO t1 (c1) VALUES (2); @@ -485,7 +485,7 @@ DROP TABLE t1; # Test with two threads + start transaction NO PARTITIONING # con default CREATE TABLE t1 (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE = 'MARIA'; +ENGINE = 'Aria'; START TRANSACTION; INSERT INTO t1 (c1) VALUES (2); INSERT INTO t1 (c1) VALUES (4); @@ -566,7 +566,7 @@ DROP TABLE t1; # Test with two threads + start transaction # con default CREATE TABLE t1 (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE = 'MARIA' +ENGINE = 'Aria' PARTITION BY HASH(c1) PARTITIONS 2; START TRANSACTION; @@ -648,7 +648,7 @@ CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, c2 INT, PRIMARY KEY (c1,c2)) -ENGINE = 'MARIA' +ENGINE = 'Aria' PARTITION BY HASH(c2) PARTITIONS 2; INSERT INTO t1 VALUES (1, 0); @@ -678,7 +678,7 @@ CREATE TABLE t1 ( c1 INT, c2 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c2)) -ENGINE = 'MARIA' +ENGINE = 'Aria' PARTITION BY HASH(c2) PARTITIONS 2; INSERT INTO t1 VALUES (1, 0); @@ -706,7 +706,7 @@ CREATE TABLE t1 ( c1 INT, c2 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1,c2)) -ENGINE = 'MARIA' +ENGINE = 'Aria' PARTITION BY HASH(c2) PARTITIONS 2; INSERT INTO t1 VALUES (1, 0); @@ -731,7 +731,7 @@ c1 c2 DROP TABLE t1; # Test AUTO_INCREMENT in CREATE CREATE TABLE t1 (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE = 'MARIA' +ENGINE = 'Aria' AUTO_INCREMENT = 15 PARTITION BY HASH(c1) PARTITIONS 2; @@ -740,7 +740,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=15 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=15 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ INSERT INTO t1 (c1) VALUES (4); @@ -749,7 +749,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=15 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=15 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ INSERT INTO t1 (c1) VALUES (0); @@ -758,7 +758,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=16 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=16 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ INSERT INTO t1 (c1) VALUES (NULL); @@ -767,7 +767,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=17 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=17 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SELECT * FROM t1 ORDER BY c1; @@ -783,7 +783,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=301 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=301 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ INSERT INTO t1 (c1) VALUES (0); @@ -792,7 +792,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=301 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=301 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ INSERT INTO t1 (c1) VALUES (NULL); @@ -801,7 +801,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=302 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=302 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SELECT * FROM t1 ORDER BY c1; @@ -816,7 +816,7 @@ SET @@session.sql_mode = ''; DROP TABLE t1; # Test SET INSERT_ID CREATE TABLE t1 (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE = 'MARIA' +ENGINE = 'Aria' PARTITION BY HASH(c1) PARTITIONS 2; SHOW CREATE TABLE t1; @@ -824,7 +824,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ INSERT INTO t1 (c1) VALUES (NULL); @@ -833,7 +833,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SELECT * FROM t1; @@ -845,7 +845,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ INSERT INTO t1 (c1) VALUES (NULL); @@ -854,7 +854,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=24 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=24 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SET INSERT_ID = 22; @@ -871,7 +871,7 @@ DROP TABLE t1; CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1)) -ENGINE='MARIA' +ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 2; SHOW CREATE TABLE t1; @@ -879,7 +879,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ FLUSH TABLE; @@ -888,7 +888,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA DEFAULT CHARSET=latin1 +) ENGINE=Aria DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ INSERT INTO t1 VALUES (4); @@ -898,7 +898,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ INSERT INTO t1 VALUES (NULL); @@ -908,7 +908,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MARIA AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 +) ENGINE=Aria AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SELECT * FROM t1 ORDER BY c1; @@ -922,7 +922,7 @@ DROP TABLE t1; ############################################################################## # Inserting negative autoincrement values into a partition table (partitions >= 4) CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), -c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4; +c2 INT) ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 4; INSERT INTO t(c2) VALUES (10); INSERT INTO t(c2) VALUES (20); INSERT INTO t VALUES (-1,-10); @@ -939,7 +939,7 @@ DROP TABLE t; # Reading from a partition table (partitions >= 2 ) after inserting a negative # value into the auto increment column CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), -c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 2; +c2 INT) ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 2; INSERT INTO t VALUES (-2,-20); INSERT INTO t(c2) VALUES (30); SELECT * FROM t ORDER BY c1 ASC; @@ -950,7 +950,7 @@ DROP TABLE t; # Inserting negative auto increment value into a partition table (partitions >= 2) # auto increment value > 2. CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), -c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 2; +c2 INT) ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 2; INSERT INTO t VALUES (-4,-20); INSERT INTO t(c2) VALUES (30); INSERT INTO t(c2) VALUES (40); @@ -962,7 +962,7 @@ c1 c2 DROP TABLE t; # Inserting -1 into autoincrement column of a partition table (partition >= 4) CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), -c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4; +c2 INT) ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 4; INSERT INTO t(c2) VALUES (10); INSERT INTO t(c2) VALUES (20); INSERT INTO t VALUES (-1,-10); @@ -981,7 +981,7 @@ c1 c2 DROP TABLE t; # Deleting from an auto increment table after inserting negative values CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), -c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4; +c2 INT) ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 4; INSERT INTO t(c2) VALUES (10); INSERT INTO t(c2) VALUES (20); INSERT INTO t VALUES (-1,-10); @@ -1006,7 +1006,7 @@ DROP TABLE t; # Inserting a positive value that exceeds maximum allowed value for an # Auto Increment column (positive maximum) CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), -c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4; +c2 INT) ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 4; INSERT INTO t(c2) VALUES (10); INSERT INTO t(c2) VALUES (20); INSERT INTO t VALUES (126,30); @@ -1025,7 +1025,7 @@ DROP TABLE t; # Inserting a negative value that goes below minimum allowed value for an # Auto Increment column (negative minimum) CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), -c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4; +c2 INT) ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 4; INSERT INTO t(c2) VALUES (10); INSERT INTO t(c2) VALUES (20); INSERT INTO t VALUES (-127,30); @@ -1043,7 +1043,7 @@ c1 c2 DROP TABLE t; # Updating the partition table with a negative Auto Increment value CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), -c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4; +c2 INT) ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 4; INSERT INTO t(c2) VALUES (10); INSERT INTO t(c2) VALUES (20); INSERT INTO t VALUES (-1,-10); @@ -1076,7 +1076,7 @@ DROP TABLE t; # Updating the partition table with a value that crosses the upper limits # on both the positive and the negative side. CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), -c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4; +c2 INT) ENGINE='Aria' PARTITION BY HASH(c1) PARTITIONS 4; INSERT INTO t(c2) VALUES (10); INSERT INTO t(c2) VALUES (20); INSERT INTO t VALUES (126,30); @@ -1109,7 +1109,7 @@ DROP TABLE t; CREATE TABLE t1 (a INT NULL AUTO_INCREMENT, UNIQUE KEY (a)) -ENGINE='MARIA' +ENGINE='Aria' PARTITION BY KEY(a) PARTITIONS 2; SET LAST_INSERT_ID = 999; SET INSERT_ID = 0; diff --git a/mysql-test/suite/parts/r/partition_repair_myisam.result b/mysql-test/suite/parts/r/partition_repair_myisam.result index 4af00ddcc6d..058aff4ea4d 100644 --- a/mysql-test/suite/parts/r/partition_repair_myisam.result +++ b/mysql-test/suite/parts/r/partition_repair_myisam.result @@ -264,6 +264,7 @@ Table Op Msg_type Msg_text test.t1_will_crash analyze status OK OPTIMIZE TABLE t1_will_crash; Table Op Msg_type Msg_text +test.t1_will_crash optimize info Found row block followed by deleted block test.t1_will_crash optimize warning Number of rows changed from 8 to 7 test.t1_will_crash optimize status OK CHECK TABLE t1_will_crash; diff --git a/mysql-test/suite/parts/t/partition_alter2_1_maria.test b/mysql-test/suite/parts/t/partition_alter2_1_maria.test index 88be2fb785f..47f6c4cb302 100644 --- a/mysql-test/suite/parts/t/partition_alter2_1_maria.test +++ b/mysql-test/suite/parts/t/partition_alter2_1_maria.test @@ -3,7 +3,7 @@ # # # Purpose: # # Tests around Alter column used in partitioning function # -# MARIA branch # +# Aria branch # # # #------------------------------------------------------------------------------# # Original Author: mleich # @@ -14,7 +14,7 @@ ################################################################################ # -# NOTE: PLEASE DO NOT ADD NOT MARIA SPECIFIC TESTCASES HERE ! +# NOTE: PLEASE DO NOT ADD NOT Aria SPECIFIC TESTCASES HERE ! # TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN # THE SOURCED FILES ONLY. # @@ -54,14 +54,14 @@ let $more_pk_ui_tests= 0; ##### Storage engine to be tested --source include/have_maria.inc -let $engine= 'MARIA'; +let $engine= 'Aria'; ##### Execute the test of "table" files -# MARIA has files per PK, UI, ... +# Aria has files per PK, UI, ... let $do_file_tests= 1; ##### Execute PRIMARY KEY tests ##### -# AFAIK MARIA treats PRIMARY KEYs like UNIQUE INDEXes +# AFAIK Aria treats PRIMARY KEYs like UNIQUE INDEXes let $do_pk_tests= 0; ##### Assign a big number smaller than the maximum value for partitions ##### diff --git a/mysql-test/suite/parts/t/partition_alter2_2_maria.test b/mysql-test/suite/parts/t/partition_alter2_2_maria.test index 5e8b9b7d9f2..e8172de3fb4 100644 --- a/mysql-test/suite/parts/t/partition_alter2_2_maria.test +++ b/mysql-test/suite/parts/t/partition_alter2_2_maria.test @@ -3,7 +3,7 @@ # # # Purpose: # # Tests around Alter column used in partitioning function # -# MARIA branch # +# Aria branch # # # #------------------------------------------------------------------------------# # Original Author: mleich # @@ -14,7 +14,7 @@ ################################################################################ # -# NOTE: PLEASE DO NOT ADD NOT MARIA SPECIFIC TESTCASES HERE ! +# NOTE: PLEASE DO NOT ADD NOT Aria SPECIFIC TESTCASES HERE ! # TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN # THE SOURCED FILES ONLY. # @@ -54,14 +54,14 @@ let $more_pk_ui_tests= 0; ##### Storage engine to be tested --source include/have_maria.inc -let $engine= 'MARIA'; +let $engine= 'Aria'; ##### Execute the test of "table" files # MAARIA has files per PK, UI, ... let $do_file_tests= 1; ##### Execute PRIMARY KEY tests ##### -# AFAIK MARIA treats PRIMARY KEYs like UNIQUE INDEXes +# AFAIK Aria treats PRIMARY KEYs like UNIQUE INDEXes let $do_pk_tests= 0; ##### Assign a big number smaller than the maximum value for partitions ##### diff --git a/mysql-test/suite/parts/t/partition_auto_increment_maria.test b/mysql-test/suite/parts/t/partition_auto_increment_maria.test index 5f1515ec929..2a77a9e4b61 100644 --- a/mysql-test/suite/parts/t/partition_auto_increment_maria.test +++ b/mysql-test/suite/parts/t/partition_auto_increment_maria.test @@ -27,7 +27,7 @@ ##### Storage engine to be tested --source include/have_maria.inc -let $engine= 'MARIA'; +let $engine= 'Aria'; #------------------------------------------------------------------------------# # Execute the tests to be applied to all storage engines diff --git a/mysql-test/suite/pbxt/r/grant.result b/mysql-test/suite/pbxt/r/grant.result index 74cac3ea4f0..68395661db3 100644 --- a/mysql-test/suite/pbxt/r/grant.result +++ b/mysql-test/suite/pbxt/r/grant.result @@ -11,8 +11,8 @@ GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3 GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' grant delete on mysqltest.* to mysqltest_1@localhost; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' @@ -42,15 +42,15 @@ delete from mysql.user where user='mysqltest_1'; flush privileges; grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30 @@ -162,6 +162,7 @@ Warnings: Warning 1364 Field 'ssl_cipher' doesn't have a default value Warning 1364 Field 'x509_issuer' doesn't have a default value Warning 1364 Field 'x509_subject' doesn't have a default value +Warning 1364 Field 'auth_string' doesn't have a default value insert into mysql.db (host, db, user, select_priv) values ('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); alter table mysql.db order by db asc; diff --git a/mysql-test/suite/pbxt/r/group_min_max.result b/mysql-test/suite/pbxt/r/group_min_max.result index 0694a408f55..a591832bc0d 100644 --- a/mysql-test/suite/pbxt/r/group_min_max.result +++ b/mysql-test/suite/pbxt/r/group_min_max.result @@ -2199,7 +2199,7 @@ max(b) a SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value Handler_read_key 0 -Handler_read_next 0 +Handler_read_next 15 EXPLAIN SELECT max(b), a FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 10 NULL 15 Using index @@ -2208,7 +2208,7 @@ CREATE TABLE t2 SELECT max(b), a FROM t1 GROUP BY a; SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value Handler_read_key 0 -Handler_read_next 0 +Handler_read_next 15 FLUSH STATUS; SELECT * FROM (SELECT max(b), a FROM t1 GROUP BY a) b; max(b) a @@ -2219,7 +2219,7 @@ max(b) a SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value Handler_read_key 0 -Handler_read_next 0 +Handler_read_next 15 FLUSH STATUS; (SELECT max(b), a FROM t1 GROUP BY a) UNION (SELECT max(b), a FROM t1 GROUP BY a); @@ -2231,7 +2231,7 @@ max(b) a SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value Handler_read_key 0 -Handler_read_next 0 +Handler_read_next 30 EXPLAIN (SELECT max(b), a FROM t1 GROUP BY a) UNION (SELECT max(b), a FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra @@ -2282,7 +2282,7 @@ INSERT INTO t3 SELECT a,MAX(b) FROM t1 GROUP BY a; SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value Handler_read_key 0 -Handler_read_next 0 +Handler_read_next 15 DELETE FROM t3; FLUSH STATUS; INSERT INTO t3 SELECT 1, (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) @@ -2290,13 +2290,13 @@ FROM t1 LIMIT 1; SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value Handler_read_key 0 -Handler_read_next 0 +Handler_read_next 15 FLUSH STATUS; DELETE FROM t3 WHERE (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) > 10000; SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value Handler_read_key 0 -Handler_read_next 0 +Handler_read_next 15 FLUSH STATUS; DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x FROM t1) > 10000; @@ -2304,7 +2304,7 @@ ERROR 21000: Subquery returns more than 1 row SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value Handler_read_key 0 -Handler_read_next 0 +Handler_read_next 16 DROP TABLE t1,t2,t3; CREATE TABLE t1 (a int, INDEX idx(a)); INSERT INTO t1 VALUES diff --git a/mysql-test/suite/pbxt/r/limit.result b/mysql-test/suite/pbxt/r/limit.result index 9bbf54fcfe9..dd53cb7deec 100644 --- a/mysql-test/suite/pbxt/r/limit.result +++ b/mysql-test/suite/pbxt/r/limit.result @@ -23,7 +23,7 @@ a b 2 2 3 2 4 4 -delete from t1 where b=2 limit 1; +delete from t1 where b=2 order by a limit 1; select * from t1 order by a; a b 0 0 diff --git a/mysql-test/suite/pbxt/r/mysqlshow.result b/mysql-test/suite/pbxt/r/mysqlshow.result index 1957e00daef..674ec1a7cda 100644 --- a/mysql-test/suite/pbxt/r/mysqlshow.result +++ b/mysql-test/suite/pbxt/r/mysqlshow.result @@ -80,6 +80,7 @@ Database: information_schema | Tables | +---------------------------------------+ | CHARACTER_SETS | +| CLIENT_STATISTICS | | COLLATIONS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLUMNS | @@ -89,6 +90,8 @@ Database: information_schema | FILES | | GLOBAL_STATUS | | GLOBAL_VARIABLES | +| INDEX_STATISTICS | +| KEY_CACHES | | KEY_COLUMN_USAGE | | PARTITIONS | | PLUGINS | @@ -104,8 +107,10 @@ Database: information_schema | TABLES | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | +| TABLE_STATISTICS | | TRIGGERS | | USER_PRIVILEGES | +| USER_STATISTICS | | VIEWS | | INNODB_BUFFER_POOL_PAGES | | PBXT_STATISTICS | @@ -132,6 +137,7 @@ Database: INFORMATION_SCHEMA | Tables | +---------------------------------------+ | CHARACTER_SETS | +| CLIENT_STATISTICS | | COLLATIONS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLUMNS | @@ -141,6 +147,8 @@ Database: INFORMATION_SCHEMA | FILES | | GLOBAL_STATUS | | GLOBAL_VARIABLES | +| INDEX_STATISTICS | +| KEY_CACHES | | KEY_COLUMN_USAGE | | PARTITIONS | | PLUGINS | @@ -156,8 +164,10 @@ Database: INFORMATION_SCHEMA | TABLES | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | +| TABLE_STATISTICS | | TRIGGERS | | USER_PRIVILEGES | +| USER_STATISTICS | | VIEWS | | INNODB_BUFFER_POOL_PAGES | | PBXT_STATISTICS | diff --git a/mysql-test/suite/pbxt/r/null_key.result b/mysql-test/suite/pbxt/r/null_key.result index 753ebf31f1c..8a440284c53 100644 --- a/mysql-test/suite/pbxt/r/null_key.result +++ b/mysql-test/suite/pbxt/r/null_key.result @@ -423,9 +423,9 @@ FOUND_ROWS() SHOW STATUS LIKE "handler_read%"; Variable_name Value Handler_read_first 0 -Handler_read_key 0 -Handler_read_next 0 +Handler_read_key 6 +Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 -Handler_read_rnd_next 0 +Handler_read_rnd_next 5 DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/suite/pbxt/r/partition_pruning.result b/mysql-test/suite/pbxt/r/partition_pruning.result index 7f96e6d06d9..fc17fe37a36 100644 --- a/mysql-test/suite/pbxt/r/partition_pruning.result +++ b/mysql-test/suite/pbxt/r/partition_pruning.result @@ -390,7 +390,7 @@ flush status; update t1 set a=100 where a+1=5+1; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 0 +Handler_read_rnd_next 10 flush status; delete from t1 where a=5; show status like 'Handler_read_rnd_next'; @@ -400,7 +400,7 @@ flush status; delete from t1 where a+1=5+1; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 0 +Handler_read_rnd_next 10 create table t2 like t1; insert into t2 select * from t2; flush status; @@ -468,7 +468,7 @@ flush status; update t2 set b = 100 where b = 6; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 0 +Handler_read_rnd_next 1015 flush status; update t2 set a = 1002 where a = 1001; show status like 'Handler_read_rnd_next'; @@ -478,17 +478,17 @@ flush status; update t2 set b = 6 where a = 600; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 0 +Handler_read_rnd_next 201 flush status; update t2 set b = 6 where a > 600 and a < 800; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 0 +Handler_read_rnd_next 201 flush status; delete from t2 where a > 600; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 0 +Handler_read_rnd_next 402 drop table t2; CREATE TABLE `t2` ( `a` int(11) default NULL, @@ -605,7 +605,7 @@ Variable_name Value Handler_read_rnd_next 0 show status like 'Handler_read_key'; Variable_name Value -Handler_read_key 0 +Handler_read_key 5 flush status; update t2 set a = 111 where b in (5,6); show status like 'Handler_read_rnd_next'; @@ -613,7 +613,7 @@ Variable_name Value Handler_read_rnd_next 0 show status like 'Handler_read_key'; Variable_name Value -Handler_read_key 0 +Handler_read_key 10 flush status; update t2 set a = 222 where b = 7; show status like 'Handler_read_rnd_next'; @@ -621,7 +621,7 @@ Variable_name Value Handler_read_rnd_next 0 show status like 'Handler_read_key'; Variable_name Value -Handler_read_key 0 +Handler_read_key 5 flush status; delete from t2 where b = 7; show status like 'Handler_read_rnd_next'; @@ -629,7 +629,7 @@ Variable_name Value Handler_read_rnd_next 0 show status like 'Handler_read_key'; Variable_name Value -Handler_read_key 0 +Handler_read_key 5 flush status; delete from t2 where b > 5; show status like 'Handler_read_rnd_next'; @@ -637,13 +637,13 @@ Variable_name Value Handler_read_rnd_next 0 show status like 'Handler_read_key'; Variable_name Value -Handler_read_key 0 +Handler_read_key 5 show status like 'Handler_read_prev'; Variable_name Value Handler_read_prev 0 show status like 'Handler_read_next'; Variable_name Value -Handler_read_next 0 +Handler_read_next 300 flush status; delete from t2 where b < 5 or b > 3; show status like 'Handler_read_rnd_next'; @@ -651,13 +651,13 @@ Variable_name Value Handler_read_rnd_next 0 show status like 'Handler_read_key'; Variable_name Value -Handler_read_key 0 +Handler_read_key 10 show status like 'Handler_read_prev'; Variable_name Value Handler_read_prev 0 show status like 'Handler_read_next'; Variable_name Value -Handler_read_next 0 +Handler_read_next 510 drop table t1, t2; create table t1 ( f_int1 mediumint, f_int2 integer) partition by list(mod(f_int1,4)) ( diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result index ebe74e442a2..0cdec48e192 100644 --- a/mysql-test/suite/pbxt/r/subselect.result +++ b/mysql-test/suite/pbxt/r/subselect.result @@ -270,7 +270,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)) select * from t3 where a >= all (select b from t2); a 7 @@ -1407,7 +1407,7 @@ INSERT INTO t1 VALUES ('z','?'); select * from t1 where s1 > (select max(s2) from t1); ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>' select * from t1 where s1 > any (select max(s2) from t1); -ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>' +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<' drop table t1; create table t1(toid int,rd int); create table t2(userid int,pmnew int,pmtotal int); @@ -1483,7 +1483,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1` drop table t1,t2; -create table t2 (a int, b int); +create table t2 (a int, b int not null); create table t3 (a int); insert into t3 values (6),(7),(3); select * from t3 where a >= all (select b from t2); @@ -1496,7 +1496,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00 Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < (select max(`test`.`t2`.`b`) from `test`.`t2`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(((select max(`test`.`t2`.`b`) from `test`.`t2`) > `test`.`t3`.`a`)) select * from t3 where a >= some (select b from t2); a explain extended select * from t3 where a >= some (select b from t2); @@ -1504,7 +1504,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00 Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)) select * from t3 where a >= all (select b from t2 group by 1); a 6 @@ -1515,7 +1515,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00 Using temporary; Using filesort Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < <max>(select `test`.`t2`.`b` from `test`.`t2` group by 1))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((<max>(select `test`.`t2`.`b` from `test`.`t2` group by 1) > `test`.`t3`.`a`)) select * from t3 where a >= some (select b from t2 group by 1); a explain extended select * from t3 where a >= some (select b from t2 group by 1); @@ -1523,7 +1523,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00 Using temporary; Using filesort Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= <min>(select `test`.`t2`.`b` from `test`.`t2` group by 1))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((<min>(select `test`.`t2`.`b` from `test`.`t2` group by 1) <= `test`.`t3`.`a`)) select * from t3 where NULL >= any (select b from t2); a explain extended select * from t3 where NULL >= any (select b from t2); @@ -1566,7 +1566,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary; Using filesort Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`a`)) drop table t2, t3; CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ; INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now()); diff --git a/mysql-test/suite/pbxt/r/update.result b/mysql-test/suite/pbxt/r/update.result index 3a690709c28..9154583fa81 100644 --- a/mysql-test/suite/pbxt/r/update.result +++ b/mysql-test/suite/pbxt/r/update.result @@ -271,7 +271,7 @@ a 0 show status like 'handler_read%'; Variable_name Value -Handler_read_first 0 +Handler_read_first 1 Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 @@ -289,8 +289,8 @@ Handler_read_first 0 Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 -Handler_read_rnd 0 -Handler_read_rnd_next 0 +Handler_read_rnd 2 +Handler_read_rnd_next 18 flush status; delete from t1 order by a limit 1; show status like 'handler_read%'; @@ -299,8 +299,8 @@ Handler_read_first 0 Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 -Handler_read_rnd 0 -Handler_read_rnd_next 0 +Handler_read_rnd 1 +Handler_read_rnd_next 9 flush status; delete from t1 order by a desc limit 1; show status like 'handler_read%'; @@ -309,8 +309,8 @@ Handler_read_first 0 Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 -Handler_read_rnd 0 -Handler_read_rnd_next 0 +Handler_read_rnd 1 +Handler_read_rnd_next 8 alter table t1 disable keys; Warnings: Note 1031 Table storage engine for 't1' doesn't have this option @@ -322,8 +322,8 @@ Handler_read_first 0 Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 -Handler_read_rnd 0 -Handler_read_rnd_next 0 +Handler_read_rnd 1 +Handler_read_rnd_next 7 select * from t1; a b 0 0 @@ -372,10 +372,10 @@ update t2 set a=3 where a=2; show status like 'handler_read%'; Variable_name Value Handler_read_first 0 -Handler_read_key 0 -Handler_read_next 0 +Handler_read_key 1 +Handler_read_next 1 Handler_read_prev 0 -Handler_read_rnd 0 +Handler_read_rnd 1 Handler_read_rnd_next 0 drop table t1, t2; create table t1(f1 int, `*f2` int); diff --git a/mysql-test/suite/pbxt/t/limit.test b/mysql-test/suite/pbxt/t/limit.test index 0844af8705d..a65d5060e4d 100644 --- a/mysql-test/suite/pbxt/t/limit.test +++ b/mysql-test/suite/pbxt/t/limit.test @@ -15,7 +15,7 @@ update t1 set b=2 where b=1 limit 2; select * from t1 order by a; # PBXT: required for consistent result update t1 set b=4 where b=1; select * from t1 order by a; # PBXT: required for consistent result -delete from t1 where b=2 limit 1; +delete from t1 where b=2 order by a limit 1; select * from t1 order by a; # PBXT: required for consistent result delete from t1 limit 1; select * from t1 order by a; # PBXT: required for consistent result diff --git a/mysql-test/suite/pbxt/t/multi_update.test b/mysql-test/suite/pbxt/t/multi_update.test index 12e91c79f22..1acd59ea626 100644 --- a/mysql-test/suite/pbxt/t/multi_update.test +++ b/mysql-test/suite/pbxt/t/multi_update.test @@ -20,6 +20,7 @@ create table t1(id1 int not null auto_increment primary key, t char(12)); create table t2(id2 int not null, t char(12)); create table t3(id3 int not null, t char(12), index(id3)); disable_query_log; +begin; let $1 = 100; while ($1) { @@ -38,6 +39,7 @@ while ($1) } dec $1; } +commit; enable_query_log; select count(*) from t1 where id1 > 95; @@ -75,6 +77,7 @@ drop table t1,t2,t3; create table t1(id1 int not null primary key, t varchar(100)) pack_keys = 1; create table t2(id2 int not null, t varchar(100), index(id2)) pack_keys = 1; disable_query_log; +begin; let $1 = 1000; while ($1) { @@ -87,6 +90,7 @@ while ($1) } dec $1; } +commit; enable_query_log; delete t1 from t1,t2 where t1.id1 = t2.id2 and t1.id1 > 500; drop table t1,t2; @@ -328,6 +332,7 @@ drop table t1,t2; create table t1 ( a int not null, b int not null) ; --disable_query_log +begin; insert into t1 values (1,1),(2,2),(3,3),(4,4); let $1=19; set @d=4; @@ -337,7 +342,7 @@ while ($1) eval set @d=@d*2; dec $1; } - +commit; --enable_query_log alter table t1 add index i1(a); delete from t1 where a > 2000000; diff --git a/mysql-test/suite/pbxt/t/subselect.test b/mysql-test/suite/pbxt/t/subselect.test index 15ccef0e025..154e8d1e627 100644 --- a/mysql-test/suite/pbxt/t/subselect.test +++ b/mysql-test/suite/pbxt/t/subselect.test @@ -925,7 +925,7 @@ drop table t1,t2; # # correct ALL optimisation # -create table t2 (a int, b int); +create table t2 (a int, b int not null); create table t3 (a int); insert into t3 values (6),(7),(3); select * from t3 where a >= all (select b from t2); diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result index e48d8b36fab..52bcb90f357 100644 --- a/mysql-test/suite/rpl/r/rpl_do_grant.result +++ b/mysql-test/suite/rpl/r/rpl_do_grant.result @@ -158,9 +158,9 @@ SELECT * FROM mysql.procs_priv; Host Db User Routine_name Routine_type Grantor Proc_priv Timestamp SELECT upgrade_alter_func(); ERROR HY000: The user specified as a definer ('create_rout_db'@'localhost') does not exist -USE bug42217_db; -DROP FUNCTION upgrade_del_func; -DROP FUNCTION upgrade_alter_func; +USE test; +DROP FUNCTION bug42217_db.upgrade_del_func; +DROP FUNCTION bug42217_db.upgrade_alter_func; DROP DATABASE bug42217_db; stop slave; SET SQL_LOG_BIN= 0; diff --git a/mysql-test/suite/rpl/r/rpl_flushlog_loop.result b/mysql-test/suite/rpl/r/rpl_flushlog_loop.result index 26b7640ccbc..d53d057b470 100644 --- a/mysql-test/suite/rpl/r/rpl_flushlog_loop.result +++ b/mysql-test/suite/rpl/r/rpl_flushlog_loop.result @@ -2,7 +2,7 @@ include/rpl_init.inc [topology=1->2->1] show variables like 'relay_log%'; Variable_name Value relay_log master-relay-bin -relay_log_index +relay_log_index master-relay-bin.index relay_log_info_file relay-log.info relay_log_purge ON relay_log_space_limit 0 diff --git a/mysql-test/suite/rpl/r/rpl_idempotency.result b/mysql-test/suite/rpl/r/rpl_idempotency.result index 76abd0f64c0..ed04335d5f0 100644 --- a/mysql-test/suite/rpl/r/rpl_idempotency.result +++ b/mysql-test/suite/rpl/r/rpl_idempotency.result @@ -1,6 +1,6 @@ include/master-slave.inc [connection master] -call mtr.add_suppression("Can.t find record in .t[12].* Error_code: 1032"); +call mtr.add_suppression("Can.t find record in .t[12].*"); call mtr.add_suppression("Slave: Cannot delete or update a parent row: a foreign key constraint fails .* Error_code: 1451"); call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452"); call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table test.* Duplicate entry .1. for key .PRIMARY.* Error_code: 1062"); diff --git a/mysql-test/suite/rpl/r/rpl_ignore_table.result b/mysql-test/suite/rpl/r/rpl_ignore_table.result index 3025f1f10fa..20d51b72f96 100644 --- a/mysql-test/suite/rpl/r/rpl_ignore_table.result +++ b/mysql-test/suite/rpl/r/rpl_ignore_table.result @@ -33,6 +33,7 @@ Warnings: Warning 1364 Field 'ssl_cipher' doesn't have a default value Warning 1364 Field 'x509_issuer' doesn't have a default value Warning 1364 Field 'x509_subject' doesn't have a default value +Warning 1364 Field 'auth_string' doesn't have a default value GRANT SELECT ON *.* TO mysqltest6@localhost; GRANT INSERT ON *.* TO mysqltest6@localhost; GRANT INSERT ON test.* TO mysqltest6@localhost; diff --git a/mysql-test/suite/rpl/r/rpl_stm_000001.result b/mysql-test/suite/rpl/r/rpl_stm_000001.result index d4290331b8c..3a67772d11a 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_000001.result +++ b/mysql-test/suite/rpl/r/rpl_stm_000001.result @@ -61,6 +61,7 @@ Warnings: Warning 1364 Field 'ssl_cipher' doesn't have a default value Warning 1364 Field 'x509_issuer' doesn't have a default value Warning 1364 Field 'x509_subject' doesn't have a default value +Warning 1364 Field 'auth_string' doesn't have a default value select select_priv,user from mysql.user where user = _binary'blafasel2'; select_priv user N blafasel2 diff --git a/mysql-test/suite/rpl/r/rpl_table_options.result b/mysql-test/suite/rpl/r/rpl_table_options.result new file mode 100644 index 00000000000..423a2b65583 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_table_options.result @@ -0,0 +1,22 @@ +include/master-slave.inc +[connection master] +install plugin example soname 'ha_example.so'; +set storage_engine=example; +create table t1 (a int not null) ull=12340; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 `ull`=12340 +drop table t1; +set storage_engine=default; +select 1; +1 +1 +uninstall plugin example; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/rpl_1slave_base.cnf b/mysql-test/suite/rpl/rpl_1slave_base.cnf index 2e2ae79888e..e1d2d026acb 100644 --- a/mysql-test/suite/rpl/rpl_1slave_base.cnf +++ b/mysql-test/suite/rpl/rpl_1slave_base.cnf @@ -6,8 +6,9 @@ # Run the master.sh script before starting this process #!run-master-sh -log-bin= master-bin -relay-log= master-relay-bin +log-basename= master +# log-bin= master-bin +# relay-log= master-relay-bin [mysqld.2] # Run the slave.sh script before starting this process @@ -17,7 +18,8 @@ relay-log= master-relay-bin # starting the mysqld #!use-slave-opt -relay-log= slave-relay-bin +log-basename= slave +# relay-log= slave-relay-bin init-rpl-role= slave log-slave-updates diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test index 6965dfc9047..54d9a076245 100644 --- a/mysql-test/suite/rpl/t/rpl_do_grant.test +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -208,9 +208,9 @@ SELECT upgrade_alter_func(); disconnect create_rout_db_master; disconnect create_rout_db_slave; connection master; -USE bug42217_db; -DROP FUNCTION upgrade_del_func; -DROP FUNCTION upgrade_alter_func; +USE test; +DROP FUNCTION bug42217_db.upgrade_del_func; +DROP FUNCTION bug42217_db.upgrade_alter_func; DROP DATABASE bug42217_db; -- sync_slave_with_master diff --git a/mysql-test/suite/rpl/t/rpl_idempotency.test b/mysql-test/suite/rpl/t/rpl_idempotency.test index aa63ac47d81..1b02795dfc6 100644 --- a/mysql-test/suite/rpl/t/rpl_idempotency.test +++ b/mysql-test/suite/rpl/t/rpl_idempotency.test @@ -9,7 +9,7 @@ source include/have_innodb.inc; # Add suppression for expected warning(s) in slaves error log -call mtr.add_suppression("Can.t find record in .t[12].* Error_code: 1032"); +call mtr.add_suppression("Can.t find record in .t[12].*"); call mtr.add_suppression("Slave: Cannot delete or update a parent row: a foreign key constraint fails .* Error_code: 1451"); call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452"); call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table test.* Duplicate entry .1. for key .PRIMARY.* Error_code: 1062"); diff --git a/mysql-test/suite/rpl/t/rpl_table_options.test b/mysql-test/suite/rpl/t/rpl_table_options.test new file mode 100644 index 00000000000..2252192adeb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_table_options.test @@ -0,0 +1,34 @@ +--source include/not_windows_embedded.inc +--source include/have_example_plugin.inc +--source include/master-slave.inc + +--replace_regex /\.dll/.so/ +eval install plugin example soname '$HA_EXAMPLE_SO'; +set storage_engine=example; + +sync_slave_with_master; +connection master; + +# +# only master has example engine installed, +# the slave will have the table created in myisam, +# that does not have ULL table option. +# but because the table was created by the replication +# slave thread, the table will be created anyway, even if +# the option is unknown. +# +create table t1 (a int not null) ull=12340; +show create table t1; + +sync_slave_with_master; +connection slave; +show create table t1; + +connection master; +drop table t1; +set storage_engine=default; +select 1; + +# Cleanup +uninstall plugin example; +--source include/rpl_end.inc diff --git a/mysql-test/suite/sphinx/my.cnf b/mysql-test/suite/sphinx/my.cnf new file mode 100644 index 00000000000..ba5dd7578e8 --- /dev/null +++ b/mysql-test/suite/sphinx/my.cnf @@ -0,0 +1,30 @@ +!include include/default_my.cnf + +[source src1] +type = xmlpipe2 +xmlpipe_command = cat suite/sphinx/testdata.xml + +[index test1] +source = src1 +docinfo = extern +charset_type = utf-8 +path = @OPT.vardir/searchd/test1 + +[indexer] +mem_limit = 32M + +[searchd] +read_timeout = 5 +max_children = 30 +max_matches = 1000 +seamless_rotate = 1 +preopen_indexes = 0 +unlink_old = 1 +log = @OPT.vardir/searchd/sphinx-searchd.log +query_log = @OPT.vardir/searchd/sphinx-query.log +#log-error = @OPT.vardir/searchd/sphinx.log +pid_file = @OPT.vardir/run/searchd.pid +port = @ENV.SPHINXSEARCH_PORT + +[ENV] +SPHINXSEARCH_PORT = @OPT.port diff --git a/mysql-test/suite/sphinx/sphinx.result b/mysql-test/suite/sphinx/sphinx.result new file mode 100644 index 00000000000..46fefc6f8ae --- /dev/null +++ b/mysql-test/suite/sphinx/sphinx.result @@ -0,0 +1,39 @@ +create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:SPHINXSEARCH_PORT/*"; +select * from ts where q='test'; +id w q +1 2 test +2 2 test +4 1 test +drop table ts; +create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:SPHINXSEARCH_PORT/*"; +select * from ts where q='test;filter=gid,1;mode=extended'; +id w q +1 2421 test;filter=gid,1;mode=extended +2 2421 test;filter=gid,1;mode=extended +select * from ts where q='test|one;mode=extended'; +id w q +1 3595 test|one;mode=extended +2 2460 test|one;mode=extended +4 1471 test|one;mode=extended +select * from ts where q='test;offset=1;limit=1'; +id w q +2 2 test;offset=1;limit=1 +alter table ts connection="sphinx://127.0.0.1:SPHINXSEARCH_PORT/test1"; +select id, w from ts where q='one'; +id w +1 2 +drop table ts; +create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, gid int not null, _sph_count int not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:SPHINXSEARCH_PORT/test1"; +select * from ts; +id w q gid _sph_count +select * from ts where q=''; +id w q gid _sph_count +1 1 1 0 +2 1 1 0 +3 1 2 0 +4 1 2 0 +select * from ts where q=';groupby=attr:gid'; +id w q gid _sph_count +3 1 ;groupby=attr:gid 2 2 +1 1 ;groupby=attr:gid 1 2 +drop table ts; diff --git a/mysql-test/suite/sphinx/sphinx.test b/mysql-test/suite/sphinx/sphinx.test new file mode 100644 index 00000000000..f6d2c7ac709 --- /dev/null +++ b/mysql-test/suite/sphinx/sphinx.test @@ -0,0 +1,23 @@ + +--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT +eval create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:$SPHINXSEARCH_PORT/*"; +select * from ts where q='test'; +drop table ts; + +--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT +eval create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:$SPHINXSEARCH_PORT/*"; +select * from ts where q='test;filter=gid,1;mode=extended'; +select * from ts where q='test|one;mode=extended'; +select * from ts where q='test;offset=1;limit=1'; +--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT +eval alter table ts connection="sphinx://127.0.0.1:$SPHINXSEARCH_PORT/test1"; +select id, w from ts where q='one'; +drop table ts; + +--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT +eval create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, gid int not null, _sph_count int not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:$SPHINXSEARCH_PORT/test1"; +select * from ts; +select * from ts where q=''; +select * from ts where q=';groupby=attr:gid'; +drop table ts; + diff --git a/mysql-test/suite/sphinx/suite.opt b/mysql-test/suite/sphinx/suite.opt new file mode 100644 index 00000000000..b8964ecd9e9 --- /dev/null +++ b/mysql-test/suite/sphinx/suite.opt @@ -0,0 +1 @@ +--plugin-load=$HA_SPHINX_SO diff --git a/mysql-test/suite/sphinx/suite.pm b/mysql-test/suite/sphinx/suite.pm new file mode 100644 index 00000000000..e708b12faea --- /dev/null +++ b/mysql-test/suite/sphinx/suite.pm @@ -0,0 +1,129 @@ +package My::Suite::Sphinx; + +use My::SafeProcess; +use My::File::Path; +use mtr_report; + +@ISA = qw(My::Suite); + +use Carp; +$Carp::Verbose=1; + +############# initialization ###################### +sub locate_sphinx_binary { + my ($name)= @_; + my $res; + my @list= map "$_/$name", split /:/, $ENV{PATH}; + my $env_override= $ENV{"SPHINXSEARCH_\U$name"}; + @list= ($env_override) if $env_override; + for (@list) { return $_ if -x $_; } +} + +# Look for Sphinx binaries. +my $exe_sphinx_indexer = &locate_sphinx_binary('indexer'); +my $exe_sphinx_searchd = &locate_sphinx_binary('searchd'); + +return "No Sphinx" unless $exe_sphinx_indexer and $exe_sphinx_searchd; +return "No SphinxSE" unless $ENV{HA_SPHINX_SO} or + $::mysqld_variables{'sphinx'} eq "ON"; + +{ + local $_ = `"$exe_sphinx_searchd" --help`; + mtr_verbose("tool: $exe_sphinx_searchd\n$_"); + my $ver = sprintf "%04d.%04d.%04d", (/([0-9]+)\.([0-9]+)\.([0-9]+)/); + if ($ver eq "0000.0000.0000") + { + $ver = sprintf "%04d.%04d", (/([0-9]+)\.([0-9]+)-(alpha|beta|gamma|RC)/); + return "Sphinx 0.9.9 or later is needed" unless $ver ge '0001.0010'; + } + else + { + return "Sphinx 0.9.9 or later is needed" unless $ver ge '0000.0009.0009'; + } +} + +############# action methods ###################### + +sub write_sphinx_conf { + my ($config) = @_; # My::Config + my $res; + + foreach my $group ($config->groups()) { + my $name= $group->{name}; + # Only the ones relevant to Sphinx search. + next unless ($name eq 'indexer' or $name eq 'searchd' or + $name =~ /^(source|index) \w+$/); + $res .= "$name\n{\n"; + foreach my $option ($group->options()) { + $res .= $option->name(); + my $value= $option->value(); + if (defined $value) { + $res .= "=$value"; + } + $res .= "\n"; + } + $res .= "}\n\n"; + } + $res; +} + +sub searchd_start { + my ($sphinx, $test) = @_; # My::Config::Group, My::Test + + return unless $exe_sphinx_indexer and $exe_sphinx_searchd; + + # First we must run the indexer to create the data. + my $sphinx_data_dir= "$::opt_vardir/" . $sphinx->name(); + mkpath($sphinx_data_dir); + my $sphinx_log= $sphinx->value('#log-error'); + my $sphinx_config= "$::opt_vardir/my_sphinx.conf"; + my $cmd= "\"$exe_sphinx_indexer\" --config \"$sphinx_config\" test1 > \"$sphinx_log\" 2>&1"; + &::mtr_verbose("cmd: $cmd"); + system $cmd; + + # Then start the searchd daemon. + my $args; + &::mtr_init_args(\$args); + &::mtr_add_arg($args, "--config"); + &::mtr_add_arg($args, $sphinx_config); + &::mtr_add_arg($args, "--console"); + &::mtr_add_arg($args, "--pidfile"); + + $sphinx->{'proc'}= My::SafeProcess->new + ( + name => 'sphinx-' . $sphinx->name(), + path => $exe_sphinx_searchd, + args => \$args, + output => $sphinx_log, + error => $sphinx_log, + append => 1, + nocore => 1, + ); + &::mtr_verbose("Started $sphinx->{proc}"); +} + +sub searchd_wait { + my ($sphinx) = @_; # My::Config::Group + + return not &::sleep_until_file_created($sphinx->value('pid_file'), 20, + $sphinx->{'proc'}) +} + +############# declaration methods ###################### + +sub config_files() { + ( 'my_sphinx.conf' => \&write_sphinx_conf ) +} + +sub servers { + ( qr/^searchd$/ => { + SORT => 400, + START => \&searchd_start, + WAIT => \&searchd_wait, + } + ) +} + +############# return an object ###################### +bless { }; + diff --git a/mysql-test/suite/sphinx/testdata.xml b/mysql-test/suite/sphinx/testdata.xml new file mode 100644 index 00000000000..e0d7394190f --- /dev/null +++ b/mysql-test/suite/sphinx/testdata.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<sphinx:docset> + +<sphinx:schema> +<sphinx:field name="title"/> +<sphinx:field name="content"/> +<sphinx:attr name="gid" type="int"/> +</sphinx:schema> + +<sphinx:document id="1"> +<title>test one</title> +<content>this is my test document number one. also checking search within phrases.</content> +<gid>1</gid> +</sphinx:document> + +<sphinx:document id="2"> +<title>test two</title> +<content>this is my test document number two</content> +<gid>1</gid> +</sphinx:document> + +<sphinx:document id="3"> +<title>another doc</title> +<content>this is another group</content> +<gid>2</gid> +</sphinx:document> + +<sphinx:document id="4"> +<title>doc number four</title> +<content>this is to test groups</content> +<gid>2</gid> +</sphinx:document> + +</sphinx:docset> + diff --git a/mysql-test/suite/vcol/inc/vcol_blocked_sql_funcs_main.inc b/mysql-test/suite/vcol/inc/vcol_blocked_sql_funcs_main.inc new file mode 100644 index 00000000000..01f939337ed --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_blocked_sql_funcs_main.inc @@ -0,0 +1,344 @@ +################################################################################ +# inc/vcol_blocked_sql_funcs_main.inc # +# # +# Purpose: # +# Tests around sql functions # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-08-31 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +# +# NOTE: All SQL functions should be rejected, otherwise BUG. +# + +--echo # RAND() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (b double as (rand())); + +--echo # LOAD_FILE() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(64), b varchar(1024) as (load_file(a))); + +--echo # CURDATE() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime as (curdate())); + +--echo # CURRENT_DATE(), CURRENT_DATE +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime as (current_date)); +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime as (current_date())); + +--echo # CURRENT_TIME(), CURRENT_TIME +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime as (current_time)); +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime as (current_time())); + +--echo # CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime as (current_timestamp())); +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime as (current_timestamp)); + +--echo # CURTIME() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime as (curtime())); + +--echo # LOCALTIME(), LOCALTIME +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime, b varchar(10) as (localtime())); +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime, b varchar(10) as (localtime)); + +--echo # LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6) +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime, b varchar(10) as (localtimestamp())); +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime, b varchar(10) as (localtimestamp)); + +--echo # NOW() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime, b varchar(10) as (now())); + +--echo # SYSDATE() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b varchar(10) as (sysdate())); + +--echo # UNIX_TIMESTAMP() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime, b datetime as (unix_timestamp())); + +--echo # UTC_DATE() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime, b datetime as (utc_date())); + +--echo # UTC_TIME() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime, b datetime as (utc_time())); + +--echo # UTC_TIMESTAMP() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a datetime, b datetime as (utc_timestamp())); + +--echo # MATCH() +if (!$skip_full_text_checks) +{ + -- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED + create table t1 (a varchar(32), b bool as (match a against ('sample text'))); +} + +--echo # BENCHMARK() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (benchmark(a,3))); + +--echo # CONNECTION_ID() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int as (connection_id())); + +--echo # CURRENT_USER(), CURRENT_USER +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(32) as (current_user())); +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(32) as (current_user)); + +--echo # DATABASE() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (database())); + +--echo # FOUND_ROWS() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (found_rows())); + +--echo # GET_LOCK() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (get_lock(a,10))); + +--echo # IS_FREE_LOCK() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (is_free_lock(a))); + +--echo # IS_USED_LOCK() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (is_used_lock(a))); + +--echo # LAST_INSERT_ID() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int as (last_insert_id())); + +--echo # MASTER_POS_WAIT() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(32), b int as (master_pos_wait(a,0,2))); + +--echo # NAME_CONST() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(32) as (name_const('test',1))); + +--echo # RELEASE_LOCK() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(32), b int as (release_lock(a))); + +--echo # ROW_COUNT() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int as (row_count())); + +--echo # SCHEMA() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(32) as (schema())); + +--echo # SESSION_USER() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(32) as (session_user())); + +--echo # SLEEP() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (sleep(a))); + +--echo # SYSTEM_USER() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(32) as (system_user())); + +--echo # USER() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (user())); + +--echo # UUID_SHORT() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024) as (uuid_short())); + +--echo # UUID() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024) as (uuid())); + +--echo # VALUES() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (values(a))); + +--echo # VERSION() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (version())); + +--echo # ENCRYPT() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (encrypt(a))); + +--echo # Stored procedures + +delimiter //; +create procedure p1() +begin + select current_user(); +end // + +create function f1() +returns int +begin + return 1; +end // + +delimiter ;// + +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int as (p1())); +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int as (f1())); + +drop procedure p1; +drop function f1; + +--echo # Unknown functions +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int as (f1())); + +--echo # +--echo # GROUP BY FUNCTIONS +--echo # + +--echo # AVG() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (avg(a))); + +--echo # BIT_AND() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (bit_and(a))); + +--echo # BIT_OR() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (bit_or(a))); + +--echo # BIT_XOR() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (bit_xor(a))); + +--echo # COUNT(DISTINCT) +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (count(distinct a))); + +--echo # COUNT() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (count(a))); + +--echo # GROUP_CONCAT() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(32), b int as (group_concat(a,''))); + +--echo # MAX() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (max(a))); + +--echo # MIN() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (min(a))); + +--echo # STD() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (std(a))); + +--echo # STDDEV_POP() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (stddev_pop(a))); + +--echo # STDDEV_SAMP() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (stddev_samp(a))); + +--echo # STDDEV() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (stddev(a))); + +--echo # SUM() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (sum(a))); + +--echo # VAR_POP() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (var_pop(a))); + +--echo # VAR_SAMP() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (var_samp(a))); + +--echo # VARIANCE() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (variance(a))); + +--echo # +--echo # XML FUNCTIONS +--echo # + +--echo # ExtractValue() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (ExtractValue(a,'//b[$@j]'))); + +--echo # UpdateXML() +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a varchar(1024), b varchar(1024) as (UpdateXML(a,'/a','<e>fff</e>'))); + +--echo # +--echo # Sub-selects +--echo # + +create table t1 (a int); +-- error ER_PARSE_ERROR +create table t2 (a int, b int as (select count(*) from t1)); +drop table t1; + +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as ((select 1))); +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (a+(select 1))); + +--echo # +--echo # SP functions +--echo # + +--disable_warnings +drop function if exists sub1; +--enable_warnings +create function sub1(i int) returns int deterministic + return i+1; +select sub1(1); +-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b int as (a+sub3(1))); +drop function sub1; + +--echo # +--echo # Long expression + +let $tmp_long_string = `SELECT repeat('a',240)`; +eval create table t1 (a int, b varchar(300) as (concat(a,'$tmp_long_string'))); +drop table t1; +let $tmp_long_string = `SELECT repeat('a',243)`; +--error ER_WRONG_STRING_LENGTH +eval create table t1 (a int, b varchar(300) as (concat(a,'$tmp_long_string'))); + +--echo # +--echo # Constant expression +--error ER_CONST_EXPR_IN_VCOL +create table t1 (a int as (PI())); diff --git a/mysql-test/suite/vcol/inc/vcol_cleanup.inc b/mysql-test/suite/vcol/inc/vcol_cleanup.inc new file mode 100644 index 00000000000..f8adec03b07 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_cleanup.inc @@ -0,0 +1,25 @@ +################################################################################ +# inc/vcol_cleanup.inc # +# # +# Purpose: # +# Removal of the objects created by the t/<test_name>.test # +# scripts. # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-08-31 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +--disable_warnings +--disable_query_log +DROP VIEW IF EXISTS v1,v2; +DROP TABLE IF EXISTS t1,t2,t3; +DROP PROCEDURE IF EXISTS p1; +DROP FUNCTION IF EXISTS f1; +DROP TRIGGER IF EXISTS trg1; +DROP TRIGGER IF EXISTS trg2; +--enable_query_log +--enable_warnings diff --git a/mysql-test/suite/vcol/inc/vcol_column_def_options.inc b/mysql-test/suite/vcol/inc/vcol_column_def_options.inc new file mode 100644 index 00000000000..2f28136ad63 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_column_def_options.inc @@ -0,0 +1,113 @@ +################################################################################ +# inc/vcol_column_def_options.inc # +# # +# Purpose: # +# Testing different optional parameters specified when defining # +# a virtual column. # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +--echo # +--echo # Section 1. Wrong column definition options +--echo # - NOT NULL +--echo # - NULL +--echo # - DEFAULT <value> +--echo # - AUTO_INCREMENT +--echo # - [PRIMARY] KEY + +--echo # NOT NULL +--error ER_PARSE_ERROR +create table t1 (a int, b int as (a+1) not null); +create table t1 (a int); +--error ER_PARSE_ERROR +alter table t1 add column b int as (a+1) not null; +drop table t1; + +--echo # NULL +--error ER_PARSE_ERROR +create table t1 (a int, b int as (a+1) null); +create table t1 (a int); +--error ER_PARSE_ERROR +alter table t1 add column b int as (a+1) null; +drop table t1; + +--echo # DEFAULT +--error ER_PARSE_ERROR +create table t1 (a int, b int as (a+1) default 0); +create table t1 (a int); +--error ER_PARSE_ERROR +alter table t1 add column b int as (a+1) default 0; +drop table t1; + +--echo # AUTO_INCREMENT +--error ER_PARSE_ERROR +create table t1 (a int, b int as (a+1) AUTO_INCREMENT); +create table t1 (a int); +--error ER_PARSE_ERROR +alter table t1 add column b int as (a+1) AUTO_INCREMENT; +drop table t1; + +--echo # [PRIMARY] KEY +--error ER_PARSE_ERROR +create table t1 (a int, b int as (a+1) key); +--error ER_PARSE_ERROR +create table t1 (a int, b int as (a+1) primary key); +create table t1 (a int); +--error ER_PARSE_ERROR +alter table t1 add column b int as (a+1) key; +--error ER_PARSE_ERROR +alter table t1 add column b int as (a+1) primary key; +drop table t1; + +--echo # Section 2. Other column definition options +--echo # - COMMENT +--echo # - REFERENCES (only syntax testing here) +--echo # - STORED (only systax testing here) +create table t1 (a int, b int as (a % 2) comment 'my comment'); +show create table t1; +describe t1; +drop table t1; +create table t1 (a int, b int as (a % 2)); +alter table t1 modify b int as (a % 2) comment 'my comment'; +show create table t1; +describe t1; +insert into t1 (a) values (1); +select * from t1; +insert into t1 values (2,default); +select a,b from t1; +create table t2 like t1; +show create table t2; +describe t2; +insert into t2 (a) values (1); +select * from t2; +insert into t2 values (2,default); +select a,b from t2; +drop table t2; +drop table t1; + +create table t1 (a int, b int as (a % 2) persistent); +show create table t1; +describe t1; +insert into t1 (a) values (1); +select * from t1; +insert into t1 values (2,default); +select a,b from t1; +drop table t1; + + +create table t2 (a int); +create table t1 (a int, b int as (a % 2) persistent references t2(a)); +show create table t1; +drop table t1; +create table t1 (a int, b int as (a % 2)); +--error ER_PARSE_ERROR +alter table t1 modify b int as (a % 2) persistent references t2(a); +show create table t1; +drop table t1; diff --git a/mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc b/mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc new file mode 100644 index 00000000000..91a55013699 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc @@ -0,0 +1,43 @@ +################################################################################ +# inc/vcol_dependencies_on_vcol.inc # +# # +# Purpose: # +# Testing scenarios when columns depend on virtual columns, i.e. such as # +# - a virtual column is based on a virtual column # +# - a "real" column on which a virtual one is renamed/dropped # +# - a virtual column involved in partitioning is renamed/dropped # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +--echo # Can't define a virtual column on another virtual column +--error ER_VCOL_BASED_ON_VCOL +create table t1 (a int, b int as (a+1), c int as (b+1)); +create table t1 (a int, b int as (a+1)); +--error ER_VCOL_BASED_ON_VCOL +alter table t1 add column c int as (b+1); +drop table t1; + +--echo # Can't rename or drop a column used in the function of a virtual column +create table t1 (a int, b int as (a+1)); +--echo # On renaming/dropping a column on which a virtual field is +--echo # defined the following error is displayed: +--echo # "Unknown column 'a' in 'virtual column function'" +--error ER_BAD_FIELD_ERROR +alter table t1 drop column a; +--error ER_BAD_FIELD_ERROR +alter table t1 change a c int; +drop table t1; + +--echo # Can't rename or drop a virtual column used by the paritition function +create table t1 (a int, b int as (a+1)) partition by hash(b); +--error ER_BAD_FIELD_ERROR +alter table t1 drop b; +--error ER_BAD_FIELD_ERROR +alter table t1 change b c int as (a+1); + diff --git a/mysql-test/suite/vcol/inc/vcol_handler.inc b/mysql-test/suite/vcol/inc/vcol_handler.inc new file mode 100644 index 00000000000..49e2ddc2973 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_handler.inc @@ -0,0 +1,77 @@ +################################################################################ +# inc/vcol_handler.inc # +# # +# Purpose: # +# Testing HANDLER. # +# # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +create table t1 (a int, + b int as (-a), + c int as (-a) persistent, + d char(1), + index (a), + index (c)); +insert into t1 (a,d) values (4,'a'), (2,'b'), (1,'c'), (3,'d'); +select * from t1; + +--echo # HANDLER tbl_name OPEN +handler t1 open; + +--echo # HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) +handler t1 read a > (2); + +--echo # HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE non-vcol_field=expr +handler t1 read a > (2) where d='c'; + +--echo # HANDLER tbl_name READ vcol_index_name = (value1,value2,...) +handler t1 read c = (-2); + +--echo # HANDLER tbl_name READ vcol_index_name = (value1,value2,...) WHERE non-vcol_field=expr +handler t1 read c = (-2) where d='c'; + +--echo # HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE vcol_field=expr +handler t1 read a > (2) where b=-3 && c=-3; + +--echo # HANDLER tbl_name READ vcol_index_name <= (value1,value2,...) +handler t1 read c <= (-2); + +--echo # HANDLER tbl_name READ vcol_index_name > (value1,value2,...) WHERE vcol_field=expr +handler t1 read c <= (-2) where b=-3; + +--echo # HANDLER tbl_name READ vcol_index_name FIRST +handler t1 read c first; + +--echo # HANDLER tbl_name READ vcol_index_name NEXT +handler t1 read c next; + +--echo # HANDLER tbl_name READ vcol_index_name PREV +handler t1 read c prev; + +--echo # HANDLER tbl_name READ vcol_index_name LAST +handler t1 read c last; + +--echo # HANDLER tbl_name READ FIRST where non-vcol=expr +handler t1 read FIRST where a >= 2; + +--echo # HANDLER tbl_name READ FIRST where vcol=expr +handler t1 read FIRST where b >= -2; + +--echo # HANDLER tbl_name READ NEXT where non-vcol=expr +handler t1 read NEXT where d='c'; + +--echo # HANDLER tbl_name READ NEXT where vcol=expr +handler t1 read NEXT where b<=-4; + +--echo # HANDLER tbl_name CLOSE +handler t1 close; + +drop table t1; diff --git a/mysql-test/suite/vcol/inc/vcol_init_vars.pre b/mysql-test/suite/vcol/inc/vcol_init_vars.pre new file mode 100644 index 00000000000..f3c55c22df8 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_init_vars.pre @@ -0,0 +1,17 @@ +################################################################################ +# inc/vcol_init_vars.pre # +# # +# Purpose: # +# Initialize variables used in t/<name> test cases. # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-08-31 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +let $skip_full_text_check = 0; +let $skip_spatial_index_check = 0; diff --git a/mysql-test/suite/vcol/inc/vcol_ins_upd.inc b/mysql-test/suite/vcol/inc/vcol_ins_upd.inc new file mode 100644 index 00000000000..8d0a51f42c0 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_ins_upd.inc @@ -0,0 +1,289 @@ +################################################################################ +# inc/vcol_ins_upd.inc # +# # +# Purpose: # +# Testing DDL operations such as INSERT, UPDATE, REPLACE and DELETE. # +# # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +let $create1 = create table t1 (a int, + b int as (-a), + c int as (-a) persistent); +let $create2 = create table t1 (a int unique, + b int as (-a), + c int as (-a) persistent); +let $create3 = create table t1 (a int, + b int as (-a), + c int as (-a) persistent unique); +let $create4 = create table t1 (a int, + b int as (-a), + c int as (-a) persistent unique, + d varchar(16)); +eval $create1; +set sql_warnings = 1; + +--echo # +--echo # *** INSERT *** +--echo # + +--echo # INSERT INTO tbl_name VALUES... DEFAULT is specified against vcols +insert into t1 values (1,default,default); +select * from t1; +delete from t1; +select * from t1; + +--echo # INSERT INTO tbl_name VALUES... NULL is specified against vcols +insert into t1 values (1,null,null); +select * from t1; +delete from t1; +select * from t1; + +--echo # INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols +insert into t1 values (1,2,3); +select * from t1; +delete from t1; +select * from t1; + +--echo # INSERT INTO tbl_name (<non_vcol_list>) VALUES... +insert into t1 (a) values (1), (2); +select * from t1; +delete from t1; +select * from t1; + +--echo # INSERT INTO tbl_name (<normal+vcols>) VALUES... DEFAULT is specified +--echo # against vcols +insert into t1 (a,b) values (1,default), (2,default); +select * from t1; +delete from t1; +select * from t1; + +--echo # INSERT INTO tbl_name (<normal+vcols>) VALUES... NULL is specified against vcols +insert into t1 (a,b) values (1,null), (2,null); +select * from t1; +delete from t1; +select * from t1; + +--echo # INSERT INTO tbl_name (<normal+vcols>) VALUES... a non-NULL value is specified +--echo # against vcols +insert into t1 (a,b) values (1,3), (2,4); +select * from t1; +delete from t1; +select * from t1; +drop table t1; + +--echo # Table with UNIQUE non-vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE +--echo # KEY UPDATE <non_vcol>=expr, <vcol>=expr +eval $create2; +insert into t1 values (1,default,default); +insert into t1 values (1,default,default) + on duplicate key update a=2, b=default; +select a,b,c from t1; +delete from t1 where b in (1,2); +select * from t1; +drop table t1; + +--echo # Table with UNIQUE vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE +--echo # KEY UPDATE <non_vcol>=expr, <vcol>=expr +eval $create3; +insert into t1 values (1,default,default); +insert into t1 values (1,default,default) + on duplicate key update a=2, b=default; +select a,b,c from t1; + +--echo # CREATE new_table ... LIKE old_table +--echo # INSERT INTO new_table SELECT * from old_table +create table t2 like t1; +insert into t2 select * from t1; +select * from t1; +drop table t2; + +--echo # CREATE new_table ... LIKE old_table INSERT INTO new_table (<non-vcols>, <vcols>) +--echo # SELECT <non-vcols>, <vcols> from old_table +insert into t1 values (1,default,default); +select * from t1; +create table t2 like t1; +insert into t2 (a,b) select a,b from t1; +select * from t2; +drop table t2; +drop table t1; + +--echo # +--echo # *** UPDATE *** +--echo # + +--echo # UPDATE tbl_name SET non-vcol=expr WHERE non-vcol=expr +eval $create1; +insert into t1 (a) values (1), (2); +select * from t1; +update t1 set a=3 where a=2; +select * from t1; +delete from t1; +select * from t1; + +--echo # UPDATE tbl_name SET vcol=expr WHERE non-vcol=expr +insert into t1 (a) values (1), (2); +select * from t1; +update t1 set c=3 where a=2; +select * from t1; +delete from t1; +select * from t1; + +--echo # UPDATE tbl_name SET non-vcol=expr WHERE vcol=expr +insert into t1 (a) values (1), (2); +select * from t1; +update t1 set a=3 where b=-2; +select * from t1; +delete from t1; +select * from t1; + +--echo # UPDATE tbl_name SET vcol=expr WHERE vcol=expr +insert into t1 (a) values (1), (2); +select * from t1; +update t1 set c=3 where b=-2; +select * from t1; +delete from t1; +select * from t1; +drop table t1; + +--echo # INDEX created on vcol +--echo # UPDATE tbl_name SET non-vcol=expr WHERE vcol=const +eval $create3; +insert into t1 (a) values (1), (2); +select * from t1; +update t1 set a=3 where c=-2; +select * from t1; +delete from t1; +select * from t1; + + +--echo # INDEX created on vcol +--echo # UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2 +insert into t1 (a) values (1), (2); +select * from t1; +update t1 set a=3 where c between -3 and -2; +select * from t1; +delete from t1; +select * from t1; + +--echo # No INDEX created on vcol +--echo # UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2 +insert into t1 (a) values (1), (2); +select * from t1; +update t1 set a=3 where b between -3 and -2; +select * from t1; +delete from t1; +select * from t1; + +--echo # INDEX created on vcol +--echo # UPDATE tbl_name SET non-vcol=expr +--echo # WHERE vcol=between const1 and const2 ORDER BY vcol +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +update t1 set a=6 where c between -1 and 0 + order by c; +select * from t1; +delete from t1 where c between -6 and 0; +select * from t1; + +--echo # INDEX created on vcol +--echo # UPDATE tbl_name SET non-vcol=expr +--echo # WHERE vcol=between const1 and const2 ORDER BY vcol LIMIT 2 +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +update t1 set a=6 where c between -1 and 0 + order by c limit 2; +select * from t1; +delete from t1 where c between -2 and 0 order by c; +select * from t1; +delete from t1; + +--echo # INDEX created on vcol +--echo # UPDATE tbl_name SET non-vcol=expr +--echo # WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3 +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +update t1 set a=6 where (c between -2 and 0) and (b=-1); +select * from t1; +delete from t1; + +--echo # INDEX created on vcol +--echo # UPDATE tbl_name SET non-vcol=expr +--echo # WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3 +--echo # ORDER BY indexed vcol +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +update t1 set a=6 where (c between -2 and 0) and (b=-1) order by c; +select * from t1; +delete from t1; +drop table t1; + +let $innodb_engine = `SELECT @@session.storage_engine='innodb'`; +if ($innodb_engine) +{ + --echo # + --echo # Verify ON UPDATE/DELETE actions of FOREIGN KEYs + create table t2 (a int primary key, name varchar(10)); + create table t1 (a int primary key, b int as (a % 10) persistent); + insert into t2 values (1, 'value1'), (2,'value2'), (3,'value3'); + insert into t1 (a) values (1),(2),(3); + select * from t1; + select * from t2; + select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a; + + --echo # - ON UPDATE RESTRICT + alter table t1 add foreign key (b) references t2(a) on update restrict; + --error ER_NO_REFERENCED_ROW_2 + insert into t1 (a) values (4); + --error ER_ROW_IS_REFERENCED_2 + update t2 set a=4 where a=3; + select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a; + alter table t1 drop foreign key t1_ibfk_1; + + --echo # - ON DELETE RESTRICT + alter table t1 add foreign key (b) references t2(a) on delete restrict; + --error ER_ROW_IS_REFERENCED_2 + delete from t2 where a=3; + select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a; + select t1.a, t1.b, t2.name from t1 left outer join t2 on (t1.b=t2.a); + alter table t1 drop foreign key t1_ibfk_1; + + --echo # - ON DELETE CASCADE + alter table t1 add foreign key (b) references t2(a) on delete cascade; + delete from t2 where a=3; + select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a; + select t1.a, t1.b, t2.name from t1 left outer join t2 on (t1.b=t2.a); + alter table t1 drop foreign key t1_ibfk_1; + + drop table t1; + drop table t2; +} + +--echo # +--echo # *** REPLACE *** +--echo # + +--echo # UNIQUE INDEX on vcol +--echo # REPLACE tbl_name (non-vcols) VALUES (non-vcols); +eval $create4; +insert into t1 (a,d) values (1,'a'), (2,'b'); +select * from t1; +replace t1 (a,d) values (1,'c'); +select * from t1; +delete from t1; +select * from t1; + + +# *** DELETE +# All required tests for DELETE are performed as part of the above testing +# for INSERT, UPDATE and REPLACE. + +set sql_warnings = 0; +drop table t1; diff --git a/mysql-test/suite/vcol/inc/vcol_keys.inc b/mysql-test/suite/vcol/inc/vcol_keys.inc new file mode 100644 index 00000000000..062f4e3f72c --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_keys.inc @@ -0,0 +1,162 @@ +################################################################################ +# inc/vcol_keys.inc # +# # +# Purpose: # +# Testing keys, indexes defined upon virtual columns. # +# # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + + +--echo # - UNIQUE KEY +--echo # - INDEX +--echo # - FULLTEXT INDEX +--echo # - SPATIAL INDEX (not supported) +--echo # - FOREIGN INDEX (partially supported) +--echo # - CHECK (allowed but not used) + +--echo # UNIQUE +--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +create table t1 (a int, b int as (a*2) unique); +create table t1 (a int, b int as (a*2) persistent unique); +show create table t1; +describe t1; +drop table t1; + +--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +create table t1 (a int, b int as (a*2), unique key (b)); +create table t1 (a int, b int as (a*2) persistent, unique (b)); +show create table t1; +describe t1; +drop table t1; + +create table t1 (a int, b int as (a*2)); +--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +alter table t1 add unique key (b); +drop table t1; +create table t1 (a int, b int as (a*2) persistent); +alter table t1 add unique key (b); +drop table t1; + +--echo # Testing data manipulation operations involving UNIQUE keys +--echo # on virtual columns can be found in: +--echo # - vcol_ins_upd.inc +--echo # - vcol_select.inc + +--echo # +--echo # INDEX +--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +create table t1 (a int, b int as (a*2), index (b)); +--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +create table t1 (a int, b int as (a*2), index (a,b)); + +create table t1 (a int, b int as (a*2) persistent, index (b)); +show create table t1; +describe t1; +drop table t1; + +create table t1 (a int, b int as (a*2) persistent, index (a,b)); +show create table t1; +describe t1; +drop table t1; + +create table t1 (a int, b int as (a*2)); +--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +alter table t1 add index (b); +--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +alter table t1 add index (a,b); +drop table t1; + +create table t1 (a int, b int as (a*2) persistent); +alter table t1 add index (b); +drop table t1; + +create table t1 (a int, b int as (a*2) persistent); +alter table t1 add index (a,b); +create table t2 like t1; +drop table t2; +drop table t1; + +--echo # Testing data manipulation operations involving INDEX +--echo # on virtual columns can be found in: +--echo # - vcol_select.inc + +--echo # +--echo # TODO: FULLTEXT INDEX + +--echo # SPATIAL INDEX +if (!$skip_spatial_index_check) +{ + --error ER_WRONG_ARGUMENTS + create table t1 (a int, b int as (a+1) persistent, spatial index (b)); + create table t1 (a int, b int as (a+1) persistent); + --error ER_WRONG_ARGUMENTS + alter table t1 add spatial index (b); + drop table t1; +} + +--echo # FOREIGN KEY + +--echo # Rejected FK options. +--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN +create table t1 (a int, b int as (a+1) persistent, + foreign key (b) references t2(a) on update set null); +--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN +create table t1 (a int, b int as (a+1) persistent, + foreign key (b) references t2(a) on update cascade); +--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN +create table t1 (a int, b int as (a+1) persistent, + foreign key (b) references t2(a) on delete set null); + +create table t1 (a int, b int as (a+1) persistent); +--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN +alter table t1 add foreign key (b) references t2(a) on update set null; +--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN +alter table t1 add foreign key (b) references t2(a) on update cascade; +--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN +alter table t1 add foreign key (b) references t2(a) on delete set null; +drop table t1; + +--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +create table t1 (a int, b int as (a+1), + foreign key (b) references t2(a)); + +create table t1 (a int, b int as (a+1)); +--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +alter table t1 add foreign key (b) references t2(a); +drop table t1; + +--echo # Allowed FK options. +create table t2 (a int primary key, b char(5)); +create table t1 (a int, b int as (a % 10) persistent, + foreign key (b) references t2(a) on update restrict); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, + foreign key (b) references t2(a) on update no action); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, + foreign key (b) references t2(a) on delete restrict); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, + foreign key (b) references t2(a) on delete cascade); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, + foreign key (b) references t2(a) on delete no action); +drop table t1; + +--echo +--echo # Testing data manipulation operations involving FOREIGN KEY +--echo # on virtual columns can be found in: +--echo # - vcol_ins_upd.inc +--echo # - vcol_select.inc + +--echo # +--echo # TODO: CHECK + diff --git a/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc b/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc new file mode 100644 index 00000000000..c586479618a --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc @@ -0,0 +1,162 @@ +################################################################################ +# inc/vcol_non_stored_columns.inc # +# # +# Purpose: # +# Ensure that MySQL behaviour is consistent irrelevant of # +# - the place of a non-stored column among other columns, # +# - the total number of non-stored fields. # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +--echo # Case 1. All non-stored columns. +--echo # This scenario is currently impossible due to the fact that virtual columns +--echo # with a constant expression are not allowed. + +--echo # Case 2. CREATE +--echo # - Column1: "real" +--echo # - Column 2: virtual non-stored +create table t1 (a int, b int as (-a)); +insert into t1 values (1,default); +select * from t1; +insert into t1 values (2,default); +select * from t1; +drop table t1; + +--echo # Case 3. CREATE +--echo # - Column1: "real" +--echo # - Column 2: virtual stored +create table t1 (a int, b int as (-a) persistent); +insert into t1 values (1,default); +select * from t1; +insert into t1 values (2,default); +select * from t1; +drop table t1; + +--echo # Case 4. CREATE +--echo # - Column1: virtual non-stored +--echo # - Column2: "real" +create table t1 (a int as (-b), b int); +insert into t1 values (default,1); +select * from t1; +insert into t1 values (default,2); +select * from t1; +drop table t1; + +--echo # Case 5. CREATE +--echo # - Column1: virtual stored +--echo # - Column2: "real" +create table t1 (a int as (-b) persistent, b int); +insert into t1 values (default,1); +select * from t1; +insert into t1 values (default,2); +select * from t1; +drop table t1; + +--echo # Case 6. CREATE +--echo # - Column1: "real" +--echo # - Column2: virtual non-stored +--echo # - Column3: virtual stored +create table t1 (a int, b int as (-a), c int as (-a) persistent); +insert into t1 values (1,default,default); +select * from t1; +insert into t1 values (2,default,default); +select * from t1; +drop table t1; + +--echo # Case 7. ALTER. Modify virtual stored -> virtual non-stored +create table t1 (a int, b int as (a % 2) persistent); +--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN +alter table t1 modify b int as (a % 2); +show create table t1; +drop table t1; + +--echo # Case 8. ALTER. Modify virtual non-stored -> virtual stored +create table t1 (a int, b int as (a % 2)); +--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN +alter table t1 modify b int as (a % 2) persistent; +show create table t1; +drop table t1; + +--echo # Case 9. CREATE LIKE +--echo # - Column1: "real" +--echo # - Column2: virtual non-stored +--echo # - Column3: virtual stored +create table t1 (a int, b int as (-a), c int as (-a) persistent); +create table t2 like t1; +insert into t2 values (1,default,default); +select * from t2; +insert into t2 values (2,default,default); +select * from t2; +drop table t2; +drop table t1; + +--echo # Case 10. ALTER. Dropping a virtual non-stored column. +--echo # - Column1: virtual non-stored +--echo # - Column2: "real" +create table t1 (a int as (-b), b int, c varchar(5)); +insert into t1 values (default,1,'v1'); +insert into t1 values (default,2,'v2'); +select * from t1; +alter table t1 drop column a; +select * from t1; +show create table t1; +drop table t1; + +--echo # Case 11. ALTER. Dropping a virtual stored column. +--echo # - Column1: virtual stored +--echo # - Column2: "real" +create table t1 (a int as (-b) persistent, b int, c char(5)); +insert into t1 values (default,1,'v1'); +insert into t1 values (default,2,'v2'); +select * from t1; +alter table t1 drop column a; +select * from t1; +show create table t1; +drop table t1; + +--echo # Case 12. ALTER. Adding a new virtual non-stored column. +create table t1 (a int, b datetime); +insert into t1 values (1,'2008-09-04'); +insert into t1 values (2,'2008-09-05'); +select * from t1; +alter table t1 add column c int as (dayofyear(b)) after a; +select * from t1; +show create table t1; +drop table t1; + +--echo # Case 13. ALTER. Adding a new virtual stored column. +create table t1 (a int, b datetime); +insert into t1 values (1,'2008-09-04'); +insert into t1 values (2,'2008-09-05'); +select * from t1; +alter table t1 add column c int as (dayofyear(b)) persistent after a; +select * from t1; +show create table t1; +drop table t1; + +--echo # Case 14. ALTER. Changing the expression of a virtual stored column. +create table t1 (a int, b datetime, c int as (week(b)) persistent); +insert into t1 values (1,'2008-09-04',default); +insert into t1 values (2,'2008-09-05',default); +select * from t1; +alter table t1 change column c c int as (week(b,1)) persistent; +select * from t1; +show create table t1; +drop table t1; + +--echo # Case 15. ALTER. Changing the expression of a virtual non-stored column. +create table t1 (a int, b datetime, c int as (week(b))); +insert into t1 values (1,'2008-09-04',default); +insert into t1 values (2,'2008-09-05',default); +select * from t1; +alter table t1 change column c c int as (week(b,1)); +select * from t1; +show create table t1; +drop table t1; + diff --git a/mysql-test/suite/vcol/inc/vcol_partition.inc b/mysql-test/suite/vcol/inc/vcol_partition.inc new file mode 100644 index 00000000000..c20dfaaa2a4 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_partition.inc @@ -0,0 +1,127 @@ +################################################################################ +# inc/vcol_partition.inc # +# # +# Purpose: # +# Testing partitioning tables with virtual columns. # +# # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +--source include/have_partition.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +--echo # Case 1. Partitioning by RANGE based on a non-stored virtual column. + +CREATE TABLE t1 ( + a DATE NOT NULL, + b int as (year(a)) +) +PARTITION BY RANGE( b ) ( + PARTITION p0 VALUES LESS THAN (2006), + PARTITION p2 VALUES LESS THAN (2008) +); + +insert into t1 values ('2006-01-01',default); +insert into t1 values ('2007-01-01',default); +insert into t1 values ('2005-01-01',default); +select * from t1; + +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; + +--echo # Modify the expression of virtual column b +ALTER TABLE t1 modify b int as (year(a)-1); + +select * from t1; + +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; + +drop table t1; + +--echo # Case 2. Partitioning by LIST based on a stored virtual column. + +CREATE TABLE t1 (a int, b int as (a % 3 ) persistent) +PARTITION BY LIST (a+1) +(PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2)); + +insert into t1 values (1,default); +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +select * from t1; + +# +# NOTE: The following tests are currently failing due to a +# [suspected] bug in the existing partition functionality. +# Here is what was observed when using mysqld compiled prior +# to adding the virtual column functionality. +# mysql> create table t1 (a int) partition by list (a) +# (partition p1 values in (1), partition p2 values in (2)); +# Query OK, 0 rows affected (0.00 sec) +# +# mysql> insert into t1 values (1), (1), (2); +# Query OK, 3 rows affected (0.00 sec) +# Records: 3 Duplicates: 0 Warnings: 0 +# +# mysql> select * from t1; +# +------+ +# | a | +# +------+ +# | 1 | +# | 1 | +# | 2 | +# +------+ +# 3 rows in set (0.00 sec) +# +# mysql> alter table t1 reorganize partition p1 into +# (partition p1 values in (3)); +# Query OK, 2 rows affected (3.90 sec) +# Records: 2 Duplicates: 2 Warnings: 0 +# +# mysql> select * from t1; +# +------+ +# | a | +# +------+ +# | 2 | <- Two row have been lost!!! +# +------+ +# 1 row in set (0.00 sec) + +# +#alter table t1 change b b int as ((a % 3)+1) persistent; +#--error ER_NO_PARTITION_FOR_GIVEN_VALUE +#alter table t1 change b b int as (a % 2) persistent; +#select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; + +select * from t1; + +drop table t1; + +--echo # Case 3. Partitioning by HASH based on a non-stored virtual column. + +CREATE TABLE t1 ( + a DATE NOT NULL, + b int as (year(a)) +) +PARTITION BY HASH( b % 3 ) PARTITIONS 3; + +insert into t1 values ('2005-01-01',default); +insert into t1 values ('2006-01-01',default); +select * from t1; + +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; + +--echo # Modify the expression of virtual column b +ALTER TABLE t1 modify b int as (year(a)-1); + +select * from t1; + +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; + +drop table t1; diff --git a/mysql-test/suite/vcol/inc/vcol_select.inc b/mysql-test/suite/vcol/inc/vcol_select.inc new file mode 100644 index 00000000000..28c3416a55a --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_select.inc @@ -0,0 +1,216 @@ +################################################################################ +# inc/vcol_select.inc # +# # +# Purpose: # +# Testing different SELECTs. # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-18 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +# Table t1 is used below to test: +# - Join type of ALL (sequential scan of the entire table) +# - Join type of Index +# - Join type of Range +# - Join type of Ref_or_null +create table t1 (a int, + b int as (-a), + c int as (-a) persistent, + index (c)); +insert into t1 (a) values (2), (1), (1), (3), (NULL); + +# Table t2 is used below to test: +# - Join type of system and const +create table t2 like t1; +insert into t2 (a) values (1); + +# Table t3 is used below to test +# - Join type of Eq_ref with a unique virtual column +# - Join type of Const +create table t3 (a int primary key, + b int as (-a), + c int as (-a) persistent unique); +insert into t3 (a) values (2),(1),(3); + + +--echo # select_type=SIMPLE, type=system +let $s = select * from t2; +eval $s; +eval explain $s; + +let $s = select * from t2 where c=-1; +eval $s; +eval explain $s; + +--echo # select_type=SIMPLE, type=ALL +let $s = select * from t1 where b=-1; +eval $s; +eval explain $s; + +--echo # select_type=SIMPLE, type=const +let $s = select * from t3 where a=1; +eval $s; +eval explain $s; + +--echo # select_type=SIMPLE, type=range +let $s = select * from t3 where c>=-1; +eval $s; +eval explain $s; + +--echo # select_type=SIMPLE, type=ref +let $s = select * from t1,t3 where t1.c=t3.c and t3.c=-1; +eval $s; +eval explain $s; + +--echo # select_type=PRIMARY, type=index,ALL +let $s = select * from t1 where b in (select c from t3); +eval $s; +eval explain $s; + +--echo # select_type=PRIMARY, type=range,ref +let $s = select * from t1 where c in (select c from t3 where c between -2 and -1); +eval $s; +eval explain $s; + +--echo # select_type=UNION, type=system +--echo # select_type=UNION RESULT, type=<union1,2> +let $s = select * from t1 union select * from t2; +eval $s; +eval explain $s; + +--echo # select_type=DERIVED, type=system +let $s = select * from (select a,b,c from t1) as t11; +eval $s; +eval explain $s; + +--echo ### +--echo ### Using aggregate functions with/without DISTINCT +--echo ### +--echo # SELECT COUNT(*) FROM tbl_name +let $s = select count(*) from t1; +eval $s; +eval explain $s; + +--echo # SELECT COUNT(DISTINCT <non-vcol>) FROM tbl_name +let $s = select count(distinct a) from t1; +eval $s; +eval explain $s; + +--echo # SELECT COUNT(DISTINCT <non-stored vcol>) FROM tbl_name +let $s = select count(distinct b) from t1; +eval $s; +eval explain $s; + +--echo # SELECT COUNT(DISTINCT <stored vcol>) FROM tbl_name +let $s = select count(distinct c) from t1; +eval $s; +eval explain $s; + +--echo ### +--echo ### filesort & range-based utils +--echo ### +--echo # SELECT * FROM tbl_name WHERE <vcol expr> +let $s = select * from t3 where c >= -2; +eval $s; +eval explain $s; + +--echo # SELECT * FROM tbl_name WHERE <non-vcol expr> +let $s = select * from t3 where a between 1 and 2; +eval $s; +eval explain $s; + +--echo # SELECT * FROM tbl_name WHERE <non-indexed vcol expr> +let $s = select * from t3 where b between -2 and -1; +eval $s; +eval explain $s; + +--echo # SELECT * FROM tbl_name WHERE <indexed vcol expr> +let $s = select * from t3 where c between -2 and -1; +eval $s; +eval explain $s; + +#### Remove for MyISAM due to a bug +#### when all the three records are returned (a=1,2,3) +#### instead of just two (a=1,2). +#### This bug is presumably in base SQL routines as the same happens +#### with this table: +#### create table t4 (a int primary key, b int, c int unique); +let $myisam_engine = `SELECT @@session.storage_engine='myisam'`; +if (!$myisam_engine) +{ + --echo # SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <non-indexed vcol> + let $s = select * from t3 where a between 1 and 2 order by b; + eval $s; + eval explain $s; +} + +--echo # SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <indexed vcol> +let $s = select * from t3 where a between 1 and 2 order by c; +eval $s; +eval explain $s; + +--echo # SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-vcol> +let $s = select * from t3 where b between -2 and -1 order by a; +eval $s; +eval explain $s; + +#### Remove for MyISAM due to a bug +#### when all the three records are returned (a=1,2,3) +#### instead of just two (a=1,2). +#### This bug is presumably in base SQL routines as the same happens +#### with this table: +#### create table t4 (a int primary key, b int, c int unique); +let $innodb_engine = `SELECT @@session.storage_engine='innodb'`; +if (!$innodb_engine) +{ + --echo # SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-vcol> + let $s = select * from t3 where c between -2 and -1 order by a; + eval $s; + eval explain $s; +} + +--echo # SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-indexed vcol> +let $s = select * from t3 where b between -2 and -1 order by b; +eval $s; +eval explain $s; + +--echo # SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-indexed vcol> +let $s = select * from t3 where c between -2 and -1 order by b; +eval $s; +eval explain $s; + +--echo # SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol> +let $s = select * from t3 where b between -2 and -1 order by c; +eval $s; +eval explain $s; + +--echo # SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <indexed vcol> +let $s = select * from t3 where c between -2 and -1 order by c; +eval $s; +eval explain $s; + +--echo # SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol> +let $s = select sum(b) from t1 group by b; +eval $s; +eval explain $s; + +--echo # SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <indexed vcol> +let $s = select sum(c) from t1 group by c; +eval $s; +eval explain $s; + +--echo # SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <indexed vcol> +let $s = select sum(b) from t1 group by c; +eval $s; +eval explain $s; + +--echo # SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol> +let $s = select sum(c) from t1 group by b; +eval $s; +eval explain $s; + diff --git a/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc b/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc new file mode 100644 index 00000000000..f19bec04c7a --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc @@ -0,0 +1,42 @@ +################################################################################ +# inc/vcol_supported_sql_funcs.inc # +# # +# Purpose: # +# Tests frame for allowed sql functions # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-08-31 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +--enable_warnings +set sql_warnings = 1; +eval create table t1 ($cols); +show create table t1; +if ($rows) +{ + eval insert into t1 values ($values1); + dec $rows; +} +if ($rows) +{ + eval insert into t1 values ($values2); + dec $rows; +} +if ($rows) +{ + eval insert into t1 values ($values3); + dec $rows; +} +if ($rows) +{ + eval insert into t1 values ($values4); + dec $rows; +} +select * from t1; +drop table t1; +set sql_warnings = 0; diff --git a/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs_main.inc b/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs_main.inc new file mode 100644 index 00000000000..4f6b960f9d0 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs_main.inc @@ -0,0 +1,1229 @@ +################################################################################ +# inc/vcol_supported_sql_funcs_main.inc # +# # +# Purpose: # +# Tests frame for allowed sql functions # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-08-31 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +--echo # +--echo # NUMERIC FUNCTIONS +--echo # + +--echo # ABS() +let $cols = a int, b int as (abs(a)); +let $values1 = -1, default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ACOS() +let $cols = a double, b double as (format(acos(a),6)); +let $values1 = 1, default; +let $values2 = 1.0001,default; +let $values3 = 0,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ASIN() +let $cols = a double, b double as (format(asin(a),6)); +let $values1 = 0.2, default; +let $values2 = 1.0001,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo #ATAN +let $cols = a double, b double, c double as (format(atan(a,b),6)); +let $values1 = -2,2,default; +let $values2 = format(PI(),6),0,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +let $cols = a double, c double as (format(atan(a),6)); +let $values1 = -2,default; +let $values2 = format(PI(),6),default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ATAN2 +let $cols = a double, b double, c double as (format(atan2(a,b),6)); +let $values1 = -2,2,default; +let $values2 = format(PI(),6),0,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CEIL() +let $cols = a double, b int as (ceil(a)); +let $values1 = 1.23,default; +let $values2 = -1.23,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CONV() +let $cols = a varchar(10), b int, c int, d varchar(10) as (conv(a,b,c)); +let $values1 = 'a',16,2,default; +let $values2 = '6e',18,8,default; +let $values3 = -17,10,-18,default; +let $values4 = 10+'10'+'10'+0xa,10,10,default; +let $rows = 4; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # COS() +let $cols = a double, b double as (format(cos(a),6)); +let $values1 = format(PI(),6),default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # COT() +let $cols = a double, b double as (format(cot(a),6)); +let $values1 = 12,default; +let $values2 = 0,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CRC32() +let $cols = a varchar(10), b long as (crc32(a)); +let $values1 = 'MySQL',default; +let $values2 = 'mysql',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DEGREES() +let $cols = a double, b double as (format(degrees(a),6)); +let $values1 = format(PI(),6),default; +let $values2 = format(PI()/2,6),default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # / +let $cols = a double, b double as (a/2); +let $values1 = 2,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # EXP() +let $cols = a double, b double as (format(exp(a),6)); +let $values1 = 2,default; +let $values2 = -2,default; +let $values3 = 0,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # FLOOR() +let $cols = a double, b long as (floor(a)); +let $values1 = 1.23,default; +let $values2 = -1.23,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LN() +let $cols = a double, b double as (format(ln(a),6)); +let $values1 = 2,default; +let $values2 = -2,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LOG() +let $cols = a double, b double, c double as (format(log(a,b),6)); +let $values1 = 2,65536,default; +let $values2 = 10,100,default; +let $values3 = 1,100,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +let $cols = a double, b double as (format(log(a),6)); +let $values1 = 2,default; +let $values2 = -2,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LOG2() +let $cols = a double, b double as (format(log2(a),6)); +let $values1 = 65536,default; +let $values2 = -100,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LOG10() +let $cols = a double, b double as (format(log10(a),6)); +let $values1 = 2,default; +let $values2 = 100,default; +let $values3 = -100,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # - +let $cols = a double, b double as (a-1); +let $values1 = 2,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MOD() +let $cols = a int, b int as (mod(a,10)); +let $values1 = 1,default; +let $values2 = 11,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # % +let $cols = a int, b int as (a % 10); +let $values1 = 1,default; +let $values2 = 11,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # OCT() +let $cols = a double, b varchar(10) as (oct(a)); +let $values1 = 12,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # PI() +let $cols = a double, b double as (format(PI()*a*a,6)); +let $values1 = 1,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # + +let $cols = a int, b int as (a+1); +let $values1 = 1,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # POW, POWER +let $cols = a int, b int as (pow(a,2)), c int as (power(a,2)); +let $values1 = 1,default,default; +let $values2 = 2,default,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # RADIANS() +let $cols = a double, b double as (format(radians(a),6)); +let $values1 = 90,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ROUND() +let $cols = a double, b int as (round(a)); +let $values1 = -1.23,default; +let $values2 = -1.58,default; +let $values3 = 1.58,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +let $cols = a double, b double, c int as (round(a,b)); +let $values1 = 1.298,1,default; +let $values2 = 1.298,0,default; +let $values3 = 23.298,-1,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SIGN() +let $cols = a double, b int as (sign(a)); +let $values1 = -32,default; +let $values2 = 0,default; +let $values3 = 234,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SIN() +let $cols = a double, b double as (format(sin(a),6)); +let $values1 = format(PI()/2,6),default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SQRT() +let $cols = a double, b double as (format(sqrt(a),6)); +let $values1 = 4,default; +let $values2 = 20,default; +let $values3 = -16,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TAN() +let $cols = a double, b double as (format(tan(a),6)); +let $values1 = format(PI(),6),default; +let $values2 = format(PI()+1,6),default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # * +let $cols = a double, b double as (a*3); +let $values1 = 0,default; +let $values2 = 1,default; +let $values3 = 2,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TRUNCATE() +let $cols = a double, b double as (truncate(a,4)); +let $values1 = 1.223,default; +let $values2 = 1.999,default; +let $values3 = 1.999,default; +let $values4 = 122,default; +let $rows = 4; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # Unary - +let $cols = a double, b double as (-a); +let $values1 = 1,default; +let $values2 = -1,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # +--echo # STRING FUNCTIONS +--echo # + +--echo # ASCII() +let $cols = a char(2), b int as (ascii(a)); +let $values1 = '2',default; +let $values2 = 2,default; +let $values3 = 'dx',default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # BIN() +let $cols = a int, b varchar(10) as (bin(a)); +let $values1 = 12,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # BIT_LENGTH() +let $cols = a varchar(10), b long as (bit_length(a)); +let $values1 = 'text',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CHAR_LENGTH() +let $cols = a varchar(10), b long as (char_length(a)); +let $values1 = 'text',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CHAR() +let $cols = a int, b int, c varbinary(10) as (char(a,b)); +let $values1 = 77,121,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CHARACTER_LENGTH() +let $cols = a varchar(10), b long as (character_length(a)); +let $values1 = 'text',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CONCAT_WS() +let $cols = a varchar(10), b varchar(10), c varchar(20) as (concat_ws(',',a,b)); +let $values1 = 'value1','value2',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CONCAT() +let $cols = a varchar(10), b varchar(10), c varchar(20) as (concat(a,',',b)); +let $values1 = 'value1','value2',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ELT() +let $cols = a varchar(10), b varchar(10), c int, d varchar(10) as (elt(c,a,b)); +let $values1 = 'value1','value2',1,default; +let $values2 = 'value1','value2',2,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # EXPORT_SET() +let $cols = a int, b varchar(10) as (export_set(a,'1','0','',10)); +let $values1 = 6,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # FIELD() +let $cols = a varchar(10), b varchar(10), c int as (field('aa',a,b)); +let $values1 = 'aa','bb',default; +let $values2 = 'bb','aa',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # FIND_IN_SET() +let $cols = a varchar(10), b varchar(10), c int as (find_in_set(a,b)); +let $values1 = 'aa','aa,bb,cc',default; +let $values2 = 'aa','bb,aa,cc',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # FORMAT() +let $cols = a double, b varchar(20) as (format(a,2)); +let $values1 = 12332.123456,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # HEX() +let $cols = a int, b varchar(10) as (hex(a)); +let $values1 = 17,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +let $cols = a varchar(10), b varchar(10) as (hex(a)); +let $values1 = 'abc',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # INSERT() +let $cols = a varchar(10), b varchar(10), c varchar(20) as (insert(a,length(a),length(b),b)); +let $values1 = 'start,','end',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # INSTR() +let $cols = a varchar(10), b varchar(10), c int as (instr(a,b)); +let $values1 = 'foobarbar,','bar',default; +let $values2 = 'xbar,','foobar',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LCASE() +let $cols = a varchar(10), b varchar(10) as (lcase(a)); +let $values1 = 'MySQL',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LEFT() +let $cols = a varchar(10), b varchar(5) as (left(a,5)); +let $values1 = 'foobarbar',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LENGTH() +let $cols = a varchar(10), b int as (length(a)); +let $values1 = 'text',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LIKE +let $cols = a varchar(10), b bool as (a like 'H%!o' escape '!'); +let $values1 = 'Hello',default; +let $values2 = 'MySQL',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LOCATE() +let $cols = a varchar(10), b varchar(10) as (locate('bar',a)); +let $values1 = 'foobarbar',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LOWER() +let $cols = a varchar(10), b varchar(10) as (lower(a)); +let $values1 = 'MySQL',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LPAD() +let $cols = a varchar(10), b varchar(10) as (lpad(a,4,' ')); +let $values1 = 'MySQL',default; +let $values2 = 'M',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LTRIM() +let $cols = a varchar(10), b varchar(10) as (ltrim(a)); +let $values1 = ' MySQL',default; +let $values2 = 'MySQL',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MAKE_SET() +let $cols = a varchar(10), b varchar(10), c int, d varchar(30) as (make_set(c,a,b)); +let $values1 = 'a','b',1,default; +let $values2 = 'a','b',3,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MID() +let $cols = a varchar(10), b varchar(10) as (mid(a,1,2)); +let $values1 = 'foobarbar',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # NOT LIKE +let $cols = a varchar(10), b bool as (a not like 'H%o'); +let $values1 = 'Hello',default; +let $values2 = 'MySQL',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # NOT REGEXP +let $cols = a varchar(10), b bool as (a not regexp 'H.+o'); +let $values1 = 'Hello',default; +let $values2 = 'hello',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # OCTET_LENGTH() +let $cols = a varchar(10), b int as (octet_length(a)); +let $values1 = 'text',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ORD() +let $cols = a varchar(10), b long as (ord(a)); +let $values1 = '2',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # POSITION() +let $cols = a varchar(10), b varchar(10) as (position('bar' in a)); +let $values1 = 'foobarbar',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # QUOTE() +let $cols = a varchar(10), b varchar(10) as (quote(a)); +let $values1 = 'Don\'t',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # REGEXP() +let $cols = a varchar(10), b bool as (a regexp 'H.+o'); +let $values1 = 'Hello',default; +let $values2 = 'hello',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # REPEAT() +let $cols = a varchar(10), b varchar(30) as (repeat(a,3)); +let $values1 = 'MySQL',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # REPLACE() +let $cols = a varchar(10), b varchar(30) as (replace(a,'aa','bb')); +let $values1 = 'maa',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # REVERSE() +let $cols = a varchar(10), b varchar(30) as (reverse(a)); +let $values1 = 'maa',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # RIGHT() +let $cols = a varchar(10), b varchar(10) as (right(a,4)); +let $values1 = 'foobarbar',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # RLIKE() +let $cols = a varchar(10), b bool as (a rlike 'H.+o'); +let $values1 = 'Hello',default; +let $values2 = 'MySQL',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # RPAD() +let $cols = a varchar(10), b varchar(10) as (rpad(a,4,'??')); +let $values1 = 'He',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # RTRIM(); +let $cols = a varchar(10), b varchar(10) as (rtrim(a)); +let $values1 = 'Hello ',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SOUNDEX() +let $cols = a varchar(10), b varchar(20) as (soundex(a)); +let $values1 = 'Hello',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SOUNDS LIKE +let $cols = a varchar(10), b varchar(10), c bool as (a sounds like b); +let $values1 = 'Hello','Hello',default; +let $values2 = 'Hello','MySQL',default; +let $values3 = 'Hello','hello',default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SPACE() +let $cols = a varchar(5), b varchar(10) as (concat(a,space(5))); +let $values1 = 'Hello', default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # STRCMP() +let $cols = a varchar(9), b varchar(9), c tinyint(1) as (strcmp(a,b)); +let $values1 = 'Hello','Hello', default; +let $values2 = 'Hello','Hello1', default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SUBSTR() +let $cols = a varchar(5), b varchar(10) as (substr(a,2)); +let $values1 = 'Hello',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SUBSTRING_INDEX() +let $cols = a varchar(15), b varchar(10) as (substring_index(a,'.',2)); +let $values1 = 'www.mysql.com',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SUBSTRING() +let $cols = a varchar(5), b varchar(10) as (substring(a from 2 for 2)); +let $values1 = 'Hello',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TRIM() +let $cols = a varchar(15), b varchar(10) as (trim(a)); +let $values1 = ' aa ',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # UCASE() +let $cols = a varchar(5), b varchar(10) as (ucase(a)); +let $values1 = 'MySQL',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # UNHEX() +let $cols = a varchar(15), b varchar(10) as (unhex(a)); +let $values1 = '4D7953514C',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # UPPER() +let $cols = a varchar(5), b varchar(10) as (upper(a)); +let $values1 = 'MySQL',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # +--echo # CONTROL FLOW FUNCTIONS +--echo # + +--echo # CASE +let $cols = a varchar(10), b varchar(16) as (case a when NULL then 'asd' when 'b' then 'B' else a end); +let $values1 = NULL,default; +let $values2 = 'b',default; +let $values3 = 'c',default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # IF +let $cols = a int, b int, c int as (if(a=1,a,b)); +let $values1 = 1,2,default; +let $values2 = 3,4,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # IFNULL +let $cols = a varchar(10), b varchar(10), c varchar(10) as (ifnull(a,'DEFAULT')); +let $values1 = NULL,'adf',default; +let $values2 = 'a','adf',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # NULLIF +let $cols = a varchar(10), b varchar(10) as (nullif(a,'DEFAULT')); +let $values1 = 'DEFAULT',default; +let $values2 = 'a',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # +--echo # OPERATORS +--echo # + +--echo # AND, && +let $cols = a int, b bool as (a>0 && a<2); +let $values1 = -1,default; +let $values2 = 1,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # BETWEEN ... AND ... +let $cols = a int, b bool as (a between 0 and 2); +let $values1 = -1,default; +let $values2 = 1,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # BINARY +let $cols = a varchar(10), b varbinary(10) as (binary a); +let $values1 = '11',default; +let $values2 = 1,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # & +let $cols = a int, b int as (a & 5); +let $values1 = 1,default; +let $values2 = 0,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ~ +let $cols = a int, b int as (~a); +let $values1 = 1,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # | +let $cols = a int, b int as (a | 5); +let $values1 = 1,default; +let $values2 = 0,default; +let $values3 = 2,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ^ +let $cols = a int, b int as (a ^ 5); +let $values1 = 1,default; +let $values2 = 0,default; +let $values3 = 2,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DIV +let $cols = a int, b int as (a div 5); +let $values1 = 1,default; +let $values2 = 7,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # <=> +let $cols = a int, b int, c bool as (a <=> b); +let $values1 = 1,1,default; +let $values2 = NULL,NULL,default; +let $values3 = 1,NULL,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # = +let $cols = a varchar(10), b varchar(10), c bool as (a=b); +let $values1 = 'a','b',default; +let $values2 = 'a','a',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # >= +let $cols = a varchar(10), b varchar(10), c bool as (a >= b); +let $values1 = 'a','b',default; +let $values2 = 'a','a',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # > +let $cols = a varchar(10), b varchar(10), c bool as (a > b); +let $values1 = 'a','b',default; +let $values2 = 'a','a',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # IS NOT NULL +let $cols = a int, b bool as (a is not null); +let $values1 = 1,default; +let $values2 = NULL,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # IS NULL +let $cols = a int, b bool as (a is null); +let $values1 = 1,default; +let $values2 = NULL,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # << +let $cols = a int, b int as (a << 2); +let $values1 = 1,default; +let $values2 = 3,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # <= +let $cols = a varchar(10), b varchar(10), c bool as (a <= b); +let $values1 = 'b','a',default; +let $values2 = 'b','b',default; +let $values3 = 'b','c',default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # < +let $cols = a varchar(10), b varchar(10), c bool as (a < b); +let $values1 = 'b','a',default; +let $values2 = 'b','b',default; +let $values3 = 'b','c',default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # NOT BETWEEN ... AND ... +let $cols = a int, b bool as (a not between 0 and 2); +let $values1 = -1,default; +let $values2 = 1,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # <> +let $cols = a varchar(10), b varchar(10), c bool as (a <> b); +let $values1 = 'b','a',default; +let $values2 = 'b','b',default; +let $values3 = 'b','c',default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # != +let $cols = a varchar(10), b varchar(10), c bool as (a != b); +let $values1 = 'b','a',default; +let $values2 = 'b','b',default; +let $values3 = 'b','c',default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ||, OR +let $cols = a int, b int as (a>5 || a<3); +let $values1 = 1,default; +let $values2 = 4,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # >> +let $cols = a int, b int as (a >> 2); +let $values1 = 8,default; +let $values2 = 3,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # XOR +let $cols = a int, b int as (a xor 5); +let $values1 = 0,default; +let $values2 = 1,default; +let $values3 = 2,default; +let $rows = 3; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # +--echo # DATE AND TIME FUNCTIONS +--echo # + +--echo # ADDDATE() +let $cols = a datetime, b datetime as (adddate(a,interval 1 month)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ADDTIME() +let $cols = a datetime, b datetime as (addtime(a,'02:00:00')); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CONVERT_TZ() +let $cols = a datetime, b datetime as (convert_tz(a,'MET','UTC')); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DATE_ADD() +let $cols = a datetime, b datetime as (date_add(a,interval 1 month)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DATE_FORMAT() +let $cols = a datetime, b varchar(64) as (date_format(a,'%W %M %D')); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DATE_SUB() +let $cols = a datetime, b datetime as (date_sub(a,interval 1 month)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DATE() +let $cols = a datetime, b datetime as (date(a)); +let $values1 = '2008-08-31 02:00:00',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DATEDIFF() +let $cols = a datetime, b long as (datediff(a,'2000-01-01')); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DAY() +let $cols = a datetime, b int as (day(a)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DAYNAME() +let $cols = a datetime, b varchar(10) as (dayname(a)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DAYOFMONTH() +let $cols = a datetime, b int as (dayofmonth(a)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DAYOFWEEK() +let $cols = a datetime, b int as (dayofweek(a)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DAYOFYEAR() +let $cols = a datetime, b int as (dayofyear(a)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # EXTRACT +let $cols = a datetime, b int as (extract(year from a)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # FROM_DAYS() +let $cols = a long, b datetime as (from_days(a)); +let $values1 = 730669,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # FROM_UNIXTIME() +let $cols = a long, b datetime as (from_unixtime(a)); +let $values1 = 1196440219,default; +let $rows = 1; +set time_zone='UTC'; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # GET_FORMAT() +let $cols = a datetime, b varchar(32) as (date_format(a,get_format(DATE,'EUR'))); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # HOUR() +let $cols = a time, b long as (hour(a)); +let $values1 = '10:05:03',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # LAST_DAY() +let $cols = a datetime, b datetime as (last_day(a)); +let $values1 = '2003-02-05',default; +let $values2 = '2003-02-32',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MAKEDATE() +let $cols = a int, b datetime as (makedate(a,1)); +let $values1 = 2001,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MAKETIME() +let $cols = a int, b time as (maketime(a,1,3)); +let $values1 = 12,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MICROSECOND() +let $cols = a datetime, b long as (microsecond(a)); +let $values1 = '2009-12-31 12:00:00.123456',default; +let $values2 = '2009-12-31 23:59:59.000010',default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MINUTE() +let $cols = a datetime, b int as (minute(a)); +let $values1 = '2009-12-31 23:59:59.000010',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MONTH() +let $cols = a datetime, b int as (month(a)); +let $values1 = '2009-12-31 23:59:59.000010',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MONTHNAME() +let $cols = a datetime, b varchar(16) as (monthname(a)); +let $values1 = '2009-12-31 23:59:59.000010',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # PERIOD_ADD() +let $cols = a int, b int as (period_add(a,2)); +let $values1 = 200801,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # PERIOD_DIFF() +let $cols = a int, b int, c int as (period_diff(a,b)); +let $values1 = 200802,200703,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # QUARTER() +let $cols = a datetime, b int as (quarter(a)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SEC_TO_TIME() +let $cols = a long, b time as (sec_to_time(a)); +let $values1 = 2378,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SECOND() +let $cols = a datetime, b int as (second(a)); +let $values1 = '10:05:03',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # STR_TO_DATE() +let $cols = a varchar(64), b datetime as (str_to_date(a,'%m/%d/%Y')); +let $values1 = '04/30/2004',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SUBDATE() +let $cols = a datetime, b datetime as (subdate(a,interval 1 month)); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SUBTIME() +let $cols = a datetime, b datetime as (subtime(a,'02:00:00')); +let $values1 = '2008-08-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TIME_FORMAT() +let $cols = a datetime, b varchar(32) as (time_format(a,'%r')); +let $values1 = '2008-08-31 02:03:04',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TIME_TO_SEC() +let $cols = a time, b long as (time_to_sec(a)); +let $values1 = '22:23:00',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TIME() +let $cols = a datetime, b time as (time(a)); +let $values1 = '2008-08-31 02:03:04',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TIMEDIFF() +let $cols = a datetime, b datetime, c long as (timediff(a,b)); +let $values1 = '2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TIMESTAMP() +let $cols = a datetime, b timestamp as (timestamp(a)); +let $values1 = '2008-12-31',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TIMESTAMPADD() +let $cols = a datetime, b timestamp as (timestampadd(minute,1,a)); +let $values1 = '2003-01-02',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TIMESTAMPDIFF() +let $cols = a timestamp, b timestamp, c long as (timestampdiff(MONTH, a,b)); +let $values1 = '2003-02-01','2003-05-01',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # TO_DAYS() +let $cols = a datetime, b long as (to_days(a)); +let $values1 = '2007-10-07',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # WEEK() +let $cols = a datetime, b int as (week(a)); +let $values1 = '2008-09-01',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # WEEKDAY() +let $cols = a datetime, b int as (weekday(a)); +let $values1 = '2008-09-01',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # WEEKOFYEAR() +let $cols = a datetime, b int as (weekofyear(a)); +let $values1 = '2008-09-01',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # YEAR() +let $cols = a datetime, b int as (year(a)); +let $values1 = '2008-09-01',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # YEARWEEK() +let $cols = a datetime, b int as (yearweek(a)); +let $values1 = '2008-09-01',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # +--echo # FULL TEXT SEARCH FUNCTIONS +--echo # +--echo # None. + +--echo # +--echo # CAST FUNCTIONS AND OPERATORS +--echo # + +--echo # CAST() +let $cols = a int, b long as (cast(a as unsigned)); +let $values1 = 1,default; +let $values2 = -1,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # Convert() +let $cols = a int, b long as (convert(a,unsigned)); +let $values1 = 1,default; +let $values2 = -1,default; +let $rows = 2; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # +--echo # XML FUNCTIONS +--echo # +--echo # None. + + +--echo # +--echo # OTHER FUNCTIONS +--echo # + +--echo # AES_DECRYPT(), AES_ENCRYPT() +let $cols = a varchar(1024), b varchar(1024) as (aes_encrypt(aes_decrypt(a,'adf'),'adf')); +let $values1 = 'MySQL',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # BIT_COUNT() +let $cols = a int, b int as (bit_count(a)); +let $values1 = 5,default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # CHARSET() +let $cols = a varchar(1024), b varchar(1024) as (charset(a)); +let $values1 = 'abc',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # COERCIBILITY() +let $cols = a varchar(1024), b int as (coercibility(a)); +let $values1 = 'abc',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # COLLATION() +let $cols = a varchar(1024), b varchar(1024) as (collation(a)); +let $values1 = 'abc',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # COMPRESS(), UNCOMPRESS() +let $cols = a varchar(1024), b varchar(1024) as (uncompress(compress(a))); +let $values1 = 'MySQL',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # ENCODE(), DECODE() +let $cols = a varchar(1024), b varchar(1024) as (decode(encode(a,'abc'),'abc')); +let $values1 = 'MySQL',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # DEFAULT() +let $cols = a varchar(1024) default 'aaa', b varchar(1024) as (ifnull(a,default(a))); +let $values1 = 'any value',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +#--echo # DES_ENCRYPT(), DES_DECRYPT() +#--source include/have_ssl.inc +#let $cols = a varchar(1024), b varchar(1024) as (des_encrypt(des_decrypt(a,'adf'),'adf')); +#let $values1 = 'MySQL',default; +#let $rows = 1; +#--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # INET_ATON(), INET_NTOA() +let $cols = a varchar(1024), b varchar(1024) as (inet_ntoa(inet_aton(a))); +let $values1 = '127.0.0.1',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # MD5() +let $cols = a varchar(1024), b varbinary(32) as (md5(a)); +let $values1 = 'testing',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # OLD_PASSWORD() +let $cols = a varchar(1024), b varchar(1024) as (old_password(a)); +let $values1 = 'badpwd',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # PASSWORD() +let $cols = a varchar(1024), b varchar(1024) as (password(a)); +let $values1 = 'badpwd',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SHA1() +let $cols = a varchar(1024), b varchar(1024) as (sha1(a)); +let $values1 = 'abc',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # SHA() +let $cols = a varchar(1024), b varchar(1024) as (sha(a)); +let $values1 = 'abc',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + +--echo # UNCOMPRESSED_LENGTH() +let $cols = a char, b varchar(1024) as (uncompressed_length(compress(repeat(a,30)))); +let $values1 = 'a',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + diff --git a/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc new file mode 100644 index 00000000000..ddf13fef6a1 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc @@ -0,0 +1,110 @@ +################################################################################ +# inc/vcol_trigger_sp.inc # +# # +# Purpose: # +# Testing triggers, stored procedures and functions # +# defined on tables with virtual columns. # +# # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +create table t1 (a int, + b int as (a/10), + c int as (a/10) persistent); + +create table t2 (a timestamp); + +delimiter |; + +create trigger trg1 before insert on t1 for each row +begin + if (new.b < 10) then + set new.a:= 100; + set new.b:= 9; + set new.c:= 9; + end if; + + if (new.c > 50) then + set new.a:= 500; + end if; +end| + +create trigger trg2 after insert on t1 for each row +begin + if (new.b >= 60) then + insert into t2 values (now()); + end if; +end| + +create function f1() +returns int +begin + declare sum1 int default '0'; + declare cur1 cursor for select sum(b) from t1; + open cur1; + fetch cur1 into sum1; + close cur1; + return sum1; +end| + +delimiter ;| + +set sql_warnings = 1; + +insert into t1 (a) values (200); +select * from t1; +select * from t2; + +insert into t1 (a) values (10); +select * from t1; +select * from t2; + +insert into t1 (a) values (600); +select * from t1; +--replace_column 1 <timestamp> +select * from t2; + +select f1(); + +set sql_warnings = 0; + +drop trigger trg1; +drop trigger trg2; +drop table t2; + +delimiter |; + +create procedure p1() +begin + declare i int default '0'; + create table t2 like t1; + insert into t2 (a) values (100), (200); + begin + declare cur1 cursor for select sum(c) from t2; + open cur1; + fetch cur1 into i; + close cur1; + if (i=30) then + insert into t1 values (300,default,default); + end if; + end; +end| + +delimiter ;| + +delete from t1; + +call p1(); + +select * from t2; +select * from t1; + +drop table t1,t2; +drop procedure p1; diff --git a/mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc b/mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc new file mode 100644 index 00000000000..4ec98ebf3f4 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc @@ -0,0 +1,21 @@ +################################################################################ +# inc/vcol_unsupported_storage_engines.inc # +# # +# Purpose: # +# Ensure that defining a virtual column for an unsupported table type # +# results in a graceful error. # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +--error ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS +create table t1 (a int, b int as (a+1)); +create table t1 (a int not null); +--error ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS +alter table t1 add column b int as (a+1); +drop table t1; diff --git a/mysql-test/suite/vcol/inc/vcol_view.inc b/mysql-test/suite/vcol/inc/vcol_view.inc new file mode 100644 index 00000000000..2bf413e2471 --- /dev/null +++ b/mysql-test/suite/vcol/inc/vcol_view.inc @@ -0,0 +1,201 @@ +################################################################################ +# inc/vcol_view.inc # +# # +# Purpose: # +# Testing views defined on tables with virtual columns. # +# # +# # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + + + +create table t1 (a int not null, + b int as (-a), + c int as (-a) persistent); +insert into t1 (a) values (1), (1), (2), (2), (3); + +# simple view +create view v1 (d,e) as select abs(b), abs(c) from t1; +select d,e from v1; +select is_updatable from information_schema.views where table_name='v1'; + +# view with different algorithms (explain output differs) +explain extended select d,e from v1; +create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1; +show create view v2; +select d,e from v2; +explain extended select d,e from v2; + +# VIEW on VIEW test +create view v3 (d,e) as select d*2, e*2 from v1; +select * from v3; +explain extended select * from v3; + +drop view v1,v2,v3; +drop table t1; + +# +# DISTINCT option for VIEW +# +create table t1 (a int not null, + b int as (-a), + c int as (-a) persistent); +insert into t1 (a) values (1), (2), (3), (1), (2), (3); +create view v1 as select distinct b from t1; +select * from v1; +explain select * from v1; +select * from t1; +drop view v1; +create view v1 as select distinct c from t1; +select * from v1; +explain select * from v1; +select * from t1; +drop view v1; +drop table t1; + +# +# LIMIT clause test +# +create table t1 (a int not null, + b int as (-a), + c int as (-a) persistent); +insert into t1 (a) values (1), (2), (3), (4); +create view v1 as select b+1 from t1 order by 1 desc limit 2; +select * from v1; +explain select * from v1; +drop view v1; +create view v1 as select c+1 from t1 order by 1 desc limit 2; +select * from v1; +explain select * from v1; +drop view v1; +drop table t1; + +# +# simple view + simple update, insert and delete +# +create table t1 (a int, + b int, + c int as (-a), + d int as (-a) persistent, + primary key(a)); +insert into t1 (a,b) values (10,2), (20,3), (30,4), (40,5), (50,10); +create view v1 (a,e,f,g) as select a, b+1,c+1,d+1 from t1; +# updatable field of updateable view +update v1 set a=a+e; +select * from v1; +select * from t1; +delete from v1; +select * from v1; +select * from t1; +--error ER_NON_INSERTABLE_TABLE +insert into v1 (a,e) values (60,15); +drop table t1; +drop view v1; + +# +# outer join based on VIEW with WHERE clause +# +create table t1 (a int, + b int as (-a), + c int as (-a) persistent, + primary key(a)); +insert into t1 (a) values (1), (2), (3); +create view v1 (x,y,z) as select a,b,c from t1 where b < -1; +select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.b= v1.y); +drop view v1; +create view v1 (x,y,z) as select a,b,c from t1 where c < -1; +select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.c= v1.z); +drop view v1; +drop table t1; + +# +# VIEW built over UNION +# +create table t1 (a1 int, + b1 int as (-a1), + c1 int as (-a1) persistent); +create table t2 (a2 int, + b2 int as (-a2), + c2 int as (-a2) persistent); +insert into t1 (a1) values (1), (2); +insert into t2 (a2) values (2), (3); +create view v1 as select * from t1,t2 union all select * from t1,t2; +select * from v1; +drop view v1; +drop table t1, t2; + +# +# Showing VIEW with VIEWs in subquery +# +create table t1 (a int, + b int as (-a), + c int as (-a) persistent); +create table t2 like t1; +create view v1 as select a,b,c from t1; +create view v2 as select a,b,c from t2 where b in (select b from v1); +show create view v2; +drop view v2, v1; +drop table t1, t2; + +# +# TODO: VIEW with full text +# +#CREATE TABLE t1 (c1 int not null auto_increment primary key, c2 varchar(20), fulltext(c2)); +#insert into t1 (c2) VALUES ('real Beer'),('Water'),('Kossu'),('Coca-Cola'),('Vodka'),('Wine'),('almost real Beer'); +#select * from t1 WHERE match (c2) against ('Beer'); +#CREATE VIEW v1 AS SELECT * from t1 WHERE match (c2) against ('Beer'); +#select * from v1; +#drop view v1; +#drop table t1; + +# +# distinct in temporary table with a VIEW +# +create table t1 (a int, + b int as (-a), + c int as (-a) persistent); +insert into t1 (a) values (1),(1),(2),(2),(3),(3); +create view v1 as select b from t1; +select distinct b from v1; +select distinct b from v1 limit 2; +select distinct b from t1 limit 2; +prepare stmt1 from "select distinct b from v1 limit 2"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; +drop view v1; +create view v1 as select c from t1; +select distinct c from v1; +select distinct c from v1 limit 2; +select distinct c from t1 limit 2; +prepare stmt1 from "select distinct c from v1 limit 2"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; +drop view v1; +drop table t1; + +# +# WITH CHECK OPTION insert/update test +# +create table t1 (a int, + b int as (-a), + c int as (-a) persistent); +create view v1 as select * from t1 where b > -2 && c >-2 with check option; +# simple insert +insert into v1 (a) values (1); +-- error 1369 +insert into v1 (a) values (3); +# simple insert with ignore +insert ignore into v1 (a) values (2),(3),(0); +select * from t1; +drop view v1; +drop table t1; + diff --git a/mysql-test/suite/vcol/r/rpl_vcol.result b/mysql-test/suite/vcol/r/rpl_vcol.result new file mode 100644 index 00000000000..120ce38031f --- /dev/null +++ b/mysql-test/suite/vcol/r/rpl_vcol.result @@ -0,0 +1,22 @@ +SET @@session.storage_engine = 'InnoDB'; +include/master-slave.inc +[connection master] +create table t1 (a int, b int as (a+1)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a+1) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (2,default); +select * from t1; +a b +1 2 +2 3 +select * from t1; +a b +1 2 +2 3 +drop table t1; +include/rpl_end.inc diff --git a/mysql-test/suite/vcol/r/vcol_archive.result b/mysql-test/suite/vcol/r/vcol_archive.result new file mode 100644 index 00000000000..5ed2f3768ca --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_archive.result @@ -0,0 +1,7 @@ +SET @@session.storage_engine = 'archive'; +create table t1 (a int, b int as (a+1)); +ERROR HY000: ARCHIVE storage engine does not support computed columns +create table t1 (a int not null); +alter table t1 add column b int as (a+1); +ERROR HY000: ARCHIVE storage engine does not support computed columns +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_blackhole.result b/mysql-test/suite/vcol/r/vcol_blackhole.result new file mode 100644 index 00000000000..2d33937a2f1 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_blackhole.result @@ -0,0 +1,7 @@ +SET @@session.storage_engine = 'blackhole'; +create table t1 (a int, b int as (a+1)); +ERROR HY000: BLACKHOLE storage engine does not support computed columns +create table t1 (a int not null); +alter table t1 add column b int as (a+1); +ERROR HY000: BLACKHOLE storage engine does not support computed columns +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_innodb.result b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_innodb.result new file mode 100644 index 00000000000..a4099dff381 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_innodb.result @@ -0,0 +1,243 @@ +SET @@session.storage_engine = 'InnoDB'; +# RAND() +create table t1 (b double as (rand())); +ERROR HY000: Function or expression is not allowed for column 'b' +# LOAD_FILE() +create table t1 (a varchar(64), b varchar(1024) as (load_file(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# CURDATE() +create table t1 (a datetime as (curdate())); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURRENT_DATE(), CURRENT_DATE +create table t1 (a datetime as (current_date)); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a datetime as (current_date())); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURRENT_TIME(), CURRENT_TIME +create table t1 (a datetime as (current_time)); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a datetime as (current_time())); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP +create table t1 (a datetime as (current_timestamp())); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a datetime as (current_timestamp)); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURTIME() +create table t1 (a datetime as (curtime())); +ERROR HY000: Function or expression is not allowed for column 'a' +# LOCALTIME(), LOCALTIME +create table t1 (a datetime, b varchar(10) as (localtime())); +ERROR HY000: Function or expression is not allowed for column 'b' +create table t1 (a datetime, b varchar(10) as (localtime)); +ERROR HY000: Function or expression is not allowed for column 'b' +# LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6) +create table t1 (a datetime, b varchar(10) as (localtimestamp())); +ERROR HY000: Function or expression is not allowed for column 'b' +create table t1 (a datetime, b varchar(10) as (localtimestamp)); +ERROR HY000: Function or expression is not allowed for column 'b' +# NOW() +create table t1 (a datetime, b varchar(10) as (now())); +ERROR HY000: Function or expression is not allowed for column 'b' +# SYSDATE() +create table t1 (a int, b varchar(10) as (sysdate())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UNIX_TIMESTAMP() +create table t1 (a datetime, b datetime as (unix_timestamp())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UTC_DATE() +create table t1 (a datetime, b datetime as (utc_date())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UTC_TIME() +create table t1 (a datetime, b datetime as (utc_time())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UTC_TIMESTAMP() +create table t1 (a datetime, b datetime as (utc_timestamp())); +ERROR HY000: Function or expression is not allowed for column 'b' +# MATCH() +# BENCHMARK() +create table t1 (a varchar(1024), b varchar(1024) as (benchmark(a,3))); +ERROR HY000: Function or expression is not allowed for column 'b' +# CONNECTION_ID() +create table t1 (a int as (connection_id())); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURRENT_USER(), CURRENT_USER +create table t1 (a varchar(32) as (current_user())); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a varchar(32) as (current_user)); +ERROR HY000: Function or expression is not allowed for column 'a' +# DATABASE() +create table t1 (a varchar(1024), b varchar(1024) as (database())); +ERROR HY000: Function or expression is not allowed for column 'b' +# FOUND_ROWS() +create table t1 (a varchar(1024), b varchar(1024) as (found_rows())); +ERROR HY000: Function or expression is not allowed for column 'b' +# GET_LOCK() +create table t1 (a varchar(1024), b varchar(1024) as (get_lock(a,10))); +ERROR HY000: Function or expression is not allowed for column 'b' +# IS_FREE_LOCK() +create table t1 (a varchar(1024), b varchar(1024) as (is_free_lock(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# IS_USED_LOCK() +create table t1 (a varchar(1024), b varchar(1024) as (is_used_lock(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# LAST_INSERT_ID() +create table t1 (a int as (last_insert_id())); +ERROR HY000: Function or expression is not allowed for column 'a' +# MASTER_POS_WAIT() +create table t1 (a varchar(32), b int as (master_pos_wait(a,0,2))); +ERROR HY000: Function or expression is not allowed for column 'b' +# NAME_CONST() +create table t1 (a varchar(32) as (name_const('test',1))); +ERROR HY000: Function or expression is not allowed for column 'a' +# RELEASE_LOCK() +create table t1 (a varchar(32), b int as (release_lock(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# ROW_COUNT() +create table t1 (a int as (row_count())); +ERROR HY000: Function or expression is not allowed for column 'a' +# SCHEMA() +create table t1 (a varchar(32) as (schema())); +ERROR HY000: Function or expression is not allowed for column 'a' +# SESSION_USER() +create table t1 (a varchar(32) as (session_user())); +ERROR HY000: Function or expression is not allowed for column 'a' +# SLEEP() +create table t1 (a int, b int as (sleep(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# SYSTEM_USER() +create table t1 (a varchar(32) as (system_user())); +ERROR HY000: Function or expression is not allowed for column 'a' +# USER() +create table t1 (a varchar(1024), b varchar(1024) as (user())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UUID_SHORT() +create table t1 (a varchar(1024) as (uuid_short())); +ERROR HY000: Function or expression is not allowed for column 'a' +# UUID() +create table t1 (a varchar(1024) as (uuid())); +ERROR HY000: Function or expression is not allowed for column 'a' +# VALUES() +create table t1 (a varchar(1024), b varchar(1024) as (values(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# VERSION() +create table t1 (a varchar(1024), b varchar(1024) as (version())); +ERROR HY000: Function or expression is not allowed for column 'b' +# ENCRYPT() +create table t1 (a varchar(1024), b varchar(1024) as (encrypt(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# Stored procedures +create procedure p1() +begin +select current_user(); +end // +create function f1() +returns int +begin +return 1; +end // +create table t1 (a int as (p1())); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a int as (f1())); +ERROR HY000: Function or expression is not allowed for column 'a' +drop procedure p1; +drop function f1; +# Unknown functions +create table t1 (a int as (f1())); +ERROR HY000: Function or expression is not allowed for column 'a' +# +# GROUP BY FUNCTIONS +# +# AVG() +create table t1 (a int, b int as (avg(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# BIT_AND() +create table t1 (a int, b int as (bit_and(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# BIT_OR() +create table t1 (a int, b int as (bit_or(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# BIT_XOR() +create table t1 (a int, b int as (bit_xor(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# COUNT(DISTINCT) +create table t1 (a int, b int as (count(distinct a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# COUNT() +create table t1 (a int, b int as (count(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# GROUP_CONCAT() +create table t1 (a varchar(32), b int as (group_concat(a,''))); +ERROR HY000: Function or expression is not allowed for column 'b' +# MAX() +create table t1 (a int, b int as (max(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# MIN() +create table t1 (a int, b int as (min(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# STD() +create table t1 (a int, b int as (std(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# STDDEV_POP() +create table t1 (a int, b int as (stddev_pop(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# STDDEV_SAMP() +create table t1 (a int, b int as (stddev_samp(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# STDDEV() +create table t1 (a int, b int as (stddev(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# SUM() +create table t1 (a int, b int as (sum(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# VAR_POP() +create table t1 (a int, b int as (var_pop(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# VAR_SAMP() +create table t1 (a int, b int as (var_samp(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# VARIANCE() +create table t1 (a int, b int as (variance(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# +# XML FUNCTIONS +# +# ExtractValue() +create table t1 (a varchar(1024), b varchar(1024) as (ExtractValue(a,'//b[$@j]'))); +ERROR HY000: Function or expression is not allowed for column 'b' +# UpdateXML() +create table t1 (a varchar(1024), b varchar(1024) as (UpdateXML(a,'/a','<e>fff</e>'))); +ERROR HY000: Function or expression is not allowed for column 'b' +# +# Sub-selects +# +create table t1 (a int); +create table t2 (a int, b int as (select count(*) from t1)); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select count(*) from t1))' at line 1 +drop table t1; +create table t1 (a int, b int as ((select 1))); +ERROR HY000: Function or expression is not allowed for column 'b' +create table t1 (a int, b int as (a+(select 1))); +ERROR HY000: Function or expression is not allowed for column 'b' +# +# SP functions +# +drop function if exists sub1; +create function sub1(i int) returns int deterministic +return i+1; +select sub1(1); +sub1(1) +2 +create table t1 (a int, b int as (a+sub3(1))); +ERROR HY000: Function or expression is not allowed for column 'b' +drop function sub1; +# +# Long expression +create table t1 (a int, b varchar(300) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'))); +drop table t1; +create table t1 (a int, b varchar(300) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'))); +ERROR HY000: String 'concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long for VIRTUAL COLUMN EXPRESSION (should be no longer than 252) +# +# Constant expression +create table t1 (a int as (PI())); +ERROR HY000: Constant expression in computed column function is not allowed diff --git a/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_myisam.result b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_myisam.result new file mode 100644 index 00000000000..dda222f5e8a --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_myisam.result @@ -0,0 +1,245 @@ +SET @@session.storage_engine = 'MyISAM'; +# RAND() +create table t1 (b double as (rand())); +ERROR HY000: Function or expression is not allowed for column 'b' +# LOAD_FILE() +create table t1 (a varchar(64), b varchar(1024) as (load_file(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# CURDATE() +create table t1 (a datetime as (curdate())); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURRENT_DATE(), CURRENT_DATE +create table t1 (a datetime as (current_date)); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a datetime as (current_date())); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURRENT_TIME(), CURRENT_TIME +create table t1 (a datetime as (current_time)); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a datetime as (current_time())); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP +create table t1 (a datetime as (current_timestamp())); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a datetime as (current_timestamp)); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURTIME() +create table t1 (a datetime as (curtime())); +ERROR HY000: Function or expression is not allowed for column 'a' +# LOCALTIME(), LOCALTIME +create table t1 (a datetime, b varchar(10) as (localtime())); +ERROR HY000: Function or expression is not allowed for column 'b' +create table t1 (a datetime, b varchar(10) as (localtime)); +ERROR HY000: Function or expression is not allowed for column 'b' +# LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6) +create table t1 (a datetime, b varchar(10) as (localtimestamp())); +ERROR HY000: Function or expression is not allowed for column 'b' +create table t1 (a datetime, b varchar(10) as (localtimestamp)); +ERROR HY000: Function or expression is not allowed for column 'b' +# NOW() +create table t1 (a datetime, b varchar(10) as (now())); +ERROR HY000: Function or expression is not allowed for column 'b' +# SYSDATE() +create table t1 (a int, b varchar(10) as (sysdate())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UNIX_TIMESTAMP() +create table t1 (a datetime, b datetime as (unix_timestamp())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UTC_DATE() +create table t1 (a datetime, b datetime as (utc_date())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UTC_TIME() +create table t1 (a datetime, b datetime as (utc_time())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UTC_TIMESTAMP() +create table t1 (a datetime, b datetime as (utc_timestamp())); +ERROR HY000: Function or expression is not allowed for column 'b' +# MATCH() +create table t1 (a varchar(32), b bool as (match a against ('sample text'))); +ERROR HY000: Function or expression is not allowed for column 'b' +# BENCHMARK() +create table t1 (a varchar(1024), b varchar(1024) as (benchmark(a,3))); +ERROR HY000: Function or expression is not allowed for column 'b' +# CONNECTION_ID() +create table t1 (a int as (connection_id())); +ERROR HY000: Function or expression is not allowed for column 'a' +# CURRENT_USER(), CURRENT_USER +create table t1 (a varchar(32) as (current_user())); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a varchar(32) as (current_user)); +ERROR HY000: Function or expression is not allowed for column 'a' +# DATABASE() +create table t1 (a varchar(1024), b varchar(1024) as (database())); +ERROR HY000: Function or expression is not allowed for column 'b' +# FOUND_ROWS() +create table t1 (a varchar(1024), b varchar(1024) as (found_rows())); +ERROR HY000: Function or expression is not allowed for column 'b' +# GET_LOCK() +create table t1 (a varchar(1024), b varchar(1024) as (get_lock(a,10))); +ERROR HY000: Function or expression is not allowed for column 'b' +# IS_FREE_LOCK() +create table t1 (a varchar(1024), b varchar(1024) as (is_free_lock(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# IS_USED_LOCK() +create table t1 (a varchar(1024), b varchar(1024) as (is_used_lock(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# LAST_INSERT_ID() +create table t1 (a int as (last_insert_id())); +ERROR HY000: Function or expression is not allowed for column 'a' +# MASTER_POS_WAIT() +create table t1 (a varchar(32), b int as (master_pos_wait(a,0,2))); +ERROR HY000: Function or expression is not allowed for column 'b' +# NAME_CONST() +create table t1 (a varchar(32) as (name_const('test',1))); +ERROR HY000: Function or expression is not allowed for column 'a' +# RELEASE_LOCK() +create table t1 (a varchar(32), b int as (release_lock(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# ROW_COUNT() +create table t1 (a int as (row_count())); +ERROR HY000: Function or expression is not allowed for column 'a' +# SCHEMA() +create table t1 (a varchar(32) as (schema())); +ERROR HY000: Function or expression is not allowed for column 'a' +# SESSION_USER() +create table t1 (a varchar(32) as (session_user())); +ERROR HY000: Function or expression is not allowed for column 'a' +# SLEEP() +create table t1 (a int, b int as (sleep(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# SYSTEM_USER() +create table t1 (a varchar(32) as (system_user())); +ERROR HY000: Function or expression is not allowed for column 'a' +# USER() +create table t1 (a varchar(1024), b varchar(1024) as (user())); +ERROR HY000: Function or expression is not allowed for column 'b' +# UUID_SHORT() +create table t1 (a varchar(1024) as (uuid_short())); +ERROR HY000: Function or expression is not allowed for column 'a' +# UUID() +create table t1 (a varchar(1024) as (uuid())); +ERROR HY000: Function or expression is not allowed for column 'a' +# VALUES() +create table t1 (a varchar(1024), b varchar(1024) as (values(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# VERSION() +create table t1 (a varchar(1024), b varchar(1024) as (version())); +ERROR HY000: Function or expression is not allowed for column 'b' +# ENCRYPT() +create table t1 (a varchar(1024), b varchar(1024) as (encrypt(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# Stored procedures +create procedure p1() +begin +select current_user(); +end // +create function f1() +returns int +begin +return 1; +end // +create table t1 (a int as (p1())); +ERROR HY000: Function or expression is not allowed for column 'a' +create table t1 (a int as (f1())); +ERROR HY000: Function or expression is not allowed for column 'a' +drop procedure p1; +drop function f1; +# Unknown functions +create table t1 (a int as (f1())); +ERROR HY000: Function or expression is not allowed for column 'a' +# +# GROUP BY FUNCTIONS +# +# AVG() +create table t1 (a int, b int as (avg(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# BIT_AND() +create table t1 (a int, b int as (bit_and(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# BIT_OR() +create table t1 (a int, b int as (bit_or(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# BIT_XOR() +create table t1 (a int, b int as (bit_xor(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# COUNT(DISTINCT) +create table t1 (a int, b int as (count(distinct a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# COUNT() +create table t1 (a int, b int as (count(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# GROUP_CONCAT() +create table t1 (a varchar(32), b int as (group_concat(a,''))); +ERROR HY000: Function or expression is not allowed for column 'b' +# MAX() +create table t1 (a int, b int as (max(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# MIN() +create table t1 (a int, b int as (min(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# STD() +create table t1 (a int, b int as (std(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# STDDEV_POP() +create table t1 (a int, b int as (stddev_pop(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# STDDEV_SAMP() +create table t1 (a int, b int as (stddev_samp(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# STDDEV() +create table t1 (a int, b int as (stddev(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# SUM() +create table t1 (a int, b int as (sum(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# VAR_POP() +create table t1 (a int, b int as (var_pop(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# VAR_SAMP() +create table t1 (a int, b int as (var_samp(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# VARIANCE() +create table t1 (a int, b int as (variance(a))); +ERROR HY000: Function or expression is not allowed for column 'b' +# +# XML FUNCTIONS +# +# ExtractValue() +create table t1 (a varchar(1024), b varchar(1024) as (ExtractValue(a,'//b[$@j]'))); +ERROR HY000: Function or expression is not allowed for column 'b' +# UpdateXML() +create table t1 (a varchar(1024), b varchar(1024) as (UpdateXML(a,'/a','<e>fff</e>'))); +ERROR HY000: Function or expression is not allowed for column 'b' +# +# Sub-selects +# +create table t1 (a int); +create table t2 (a int, b int as (select count(*) from t1)); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select count(*) from t1))' at line 1 +drop table t1; +create table t1 (a int, b int as ((select 1))); +ERROR HY000: Function or expression is not allowed for column 'b' +create table t1 (a int, b int as (a+(select 1))); +ERROR HY000: Function or expression is not allowed for column 'b' +# +# SP functions +# +drop function if exists sub1; +create function sub1(i int) returns int deterministic +return i+1; +select sub1(1); +sub1(1) +2 +create table t1 (a int, b int as (a+sub3(1))); +ERROR HY000: Function or expression is not allowed for column 'b' +drop function sub1; +# +# Long expression +create table t1 (a int, b varchar(300) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'))); +drop table t1; +create table t1 (a int, b varchar(300) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'))); +ERROR HY000: String 'concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long for VIRTUAL COLUMN EXPRESSION (should be no longer than 252) +# +# Constant expression +create table t1 (a int as (PI())); +ERROR HY000: Constant expression in computed column function is not allowed diff --git a/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result b/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result new file mode 100644 index 00000000000..b1f96f8f4d9 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result @@ -0,0 +1,146 @@ +SET @@session.storage_engine = 'InnoDB'; +# +# Section 1. Wrong column definition options +# - NOT NULL +# - NULL +# - DEFAULT <value> +# - AUTO_INCREMENT +# - [PRIMARY] KEY +# NOT NULL +create table t1 (a int, b int as (a+1) not null); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'not null)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) not null; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'not null' at line 1 +drop table t1; +# NULL +create table t1 (a int, b int as (a+1) null); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) null; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null' at line 1 +drop table t1; +# DEFAULT +create table t1 (a int, b int as (a+1) default 0); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default 0)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) default 0; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default 0' at line 1 +drop table t1; +# AUTO_INCREMENT +create table t1 (a int, b int as (a+1) AUTO_INCREMENT); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AUTO_INCREMENT)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) AUTO_INCREMENT; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AUTO_INCREMENT' at line 1 +drop table t1; +# [PRIMARY] KEY +create table t1 (a int, b int as (a+1) key); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key)' at line 1 +create table t1 (a int, b int as (a+1) primary key); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'primary key)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) key; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key' at line 1 +alter table t1 add column b int as (a+1) primary key; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'primary key' at line 1 +drop table t1; +# Section 2. Other column definition options +# - COMMENT +# - REFERENCES (only syntax testing here) +# - STORED (only systax testing here) +create table t1 (a int, b int as (a % 2) comment 'my comment'); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a % 2)); +alter table t1 modify b int as (a % 2) comment 'my comment'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES NULL VIRTUAL +insert into t1 (a) values (1); +select * from t1; +a b +1 1 +insert into t1 values (2,default); +select a,b from t1; +a b +1 1 +2 0 +create table t2 like t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +describe t2; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES NULL VIRTUAL +insert into t2 (a) values (1); +select * from t2; +a b +1 1 +insert into t2 values (2,default); +select a,b from t2; +a b +1 1 +2 0 +drop table t2; +drop table t1; +create table t1 (a int, b int as (a % 2) persistent); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) PERSISTENT +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES NULL VIRTUAL +insert into t1 (a) values (1); +select * from t1; +a b +1 1 +insert into t1 values (2,default); +select a,b from t1; +a b +1 1 +2 0 +drop table t1; +create table t2 (a int); +create table t1 (a int, b int as (a % 2) persistent references t2(a)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) PERSISTENT +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int, b int as (a % 2)); +alter table t1 modify b int as (a % 2) persistent references t2(a); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'references t2(a)' at line 1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result b/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result new file mode 100644 index 00000000000..9fde339cb06 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result @@ -0,0 +1,146 @@ +SET @@session.storage_engine = 'MyISAM'; +# +# Section 1. Wrong column definition options +# - NOT NULL +# - NULL +# - DEFAULT <value> +# - AUTO_INCREMENT +# - [PRIMARY] KEY +# NOT NULL +create table t1 (a int, b int as (a+1) not null); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'not null)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) not null; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'not null' at line 1 +drop table t1; +# NULL +create table t1 (a int, b int as (a+1) null); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) null; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null' at line 1 +drop table t1; +# DEFAULT +create table t1 (a int, b int as (a+1) default 0); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default 0)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) default 0; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default 0' at line 1 +drop table t1; +# AUTO_INCREMENT +create table t1 (a int, b int as (a+1) AUTO_INCREMENT); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AUTO_INCREMENT)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) AUTO_INCREMENT; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AUTO_INCREMENT' at line 1 +drop table t1; +# [PRIMARY] KEY +create table t1 (a int, b int as (a+1) key); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key)' at line 1 +create table t1 (a int, b int as (a+1) primary key); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'primary key)' at line 1 +create table t1 (a int); +alter table t1 add column b int as (a+1) key; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key' at line 1 +alter table t1 add column b int as (a+1) primary key; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'primary key' at line 1 +drop table t1; +# Section 2. Other column definition options +# - COMMENT +# - REFERENCES (only syntax testing here) +# - STORED (only systax testing here) +create table t1 (a int, b int as (a % 2) comment 'my comment'); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a % 2)); +alter table t1 modify b int as (a % 2) comment 'my comment'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES NULL VIRTUAL +insert into t1 (a) values (1); +select * from t1; +a b +1 1 +insert into t1 values (2,default); +select a,b from t1; +a b +1 1 +2 0 +create table t2 like t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t2; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES NULL VIRTUAL +insert into t2 (a) values (1); +select * from t2; +a b +1 1 +insert into t2 values (2,default); +select a,b from t2; +a b +1 1 +2 0 +drop table t2; +drop table t1; +create table t1 (a int, b int as (a % 2) persistent); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) PERSISTENT +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES NULL VIRTUAL +insert into t1 (a) values (1); +select * from t1; +a b +1 1 +insert into t1 values (2,default); +select a,b from t1; +a b +1 1 +2 0 +drop table t1; +create table t2 (a int); +create table t1 (a int, b int as (a % 2) persistent references t2(a)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) PERSISTENT +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int, b int as (a % 2)); +alter table t1 modify b int as (a % 2) persistent references t2(a); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'references t2(a)' at line 1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_csv.result b/mysql-test/suite/vcol/r/vcol_csv.result new file mode 100644 index 00000000000..920e614c0b1 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_csv.result @@ -0,0 +1,7 @@ +SET @@session.storage_engine = 'CSV'; +create table t1 (a int, b int as (a+1)); +ERROR HY000: CSV storage engine does not support computed columns +create table t1 (a int not null); +alter table t1 add column b int as (a+1); +ERROR HY000: CSV storage engine does not support computed columns +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_handler_innodb.result b/mysql-test/suite/vcol/r/vcol_handler_innodb.result new file mode 100644 index 00000000000..f7576299e9a --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_handler_innodb.result @@ -0,0 +1,76 @@ +SET @@session.storage_engine = 'InnoDB'; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent, +d char(1), +index (a), +index (c)); +insert into t1 (a,d) values (4,'a'), (2,'b'), (1,'c'), (3,'d'); +select * from t1; +a b c d +4 -4 -4 a +2 -2 -2 b +1 -1 -1 c +3 -3 -3 d +# HANDLER tbl_name OPEN +handler t1 open; +# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) +handler t1 read a > (2); +a b c d +3 -3 -3 d +# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE non-vcol_field=expr +handler t1 read a > (2) where d='c'; +a b c d +# HANDLER tbl_name READ vcol_index_name = (value1,value2,...) +handler t1 read c = (-2); +a b c d +2 -2 -2 b +# HANDLER tbl_name READ vcol_index_name = (value1,value2,...) WHERE non-vcol_field=expr +handler t1 read c = (-2) where d='c'; +a b c d +# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE vcol_field=expr +handler t1 read a > (2) where b=-3 && c=-3; +a b c d +3 -3 -3 d +# HANDLER tbl_name READ vcol_index_name <= (value1,value2,...) +handler t1 read c <= (-2); +a b c d +2 -2 -2 b +# HANDLER tbl_name READ vcol_index_name > (value1,value2,...) WHERE vcol_field=expr +handler t1 read c <= (-2) where b=-3; +a b c d +3 -3 -3 d +# HANDLER tbl_name READ vcol_index_name FIRST +handler t1 read c first; +a b c d +4 -4 -4 a +# HANDLER tbl_name READ vcol_index_name NEXT +handler t1 read c next; +a b c d +3 -3 -3 d +# HANDLER tbl_name READ vcol_index_name PREV +handler t1 read c prev; +a b c d +4 -4 -4 a +# HANDLER tbl_name READ vcol_index_name LAST +handler t1 read c last; +a b c d +1 -1 -1 c +# HANDLER tbl_name READ FIRST where non-vcol=expr +handler t1 read FIRST where a >= 2; +a b c d +4 -4 -4 a +# HANDLER tbl_name READ FIRST where vcol=expr +handler t1 read FIRST where b >= -2; +a b c d +2 -2 -2 b +# HANDLER tbl_name READ NEXT where non-vcol=expr +handler t1 read NEXT where d='c'; +a b c d +1 -1 -1 c +# HANDLER tbl_name READ NEXT where vcol=expr +handler t1 read NEXT where b<=-4; +a b c d +# HANDLER tbl_name CLOSE +handler t1 close; +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_handler_maria.result b/mysql-test/suite/vcol/r/vcol_handler_maria.result new file mode 100644 index 00000000000..df36d0fbbf3 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_handler_maria.result @@ -0,0 +1,76 @@ +SET @@session.storage_engine = 'maria'; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent, +d char(1), +index (a), +index (c)); +insert into t1 (a,d) values (4,'a'), (2,'b'), (1,'c'), (3,'d'); +select * from t1; +a b c d +4 -4 -4 a +2 -2 -2 b +1 -1 -1 c +3 -3 -3 d +# HANDLER tbl_name OPEN +handler t1 open; +# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) +handler t1 read a > (2); +a b c d +3 -3 -3 d +# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE non-vcol_field=expr +handler t1 read a > (2) where d='c'; +a b c d +# HANDLER tbl_name READ vcol_index_name = (value1,value2,...) +handler t1 read c = (-2); +a b c d +2 -2 -2 b +# HANDLER tbl_name READ vcol_index_name = (value1,value2,...) WHERE non-vcol_field=expr +handler t1 read c = (-2) where d='c'; +a b c d +# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE vcol_field=expr +handler t1 read a > (2) where b=-3 && c=-3; +a b c d +3 -3 -3 d +# HANDLER tbl_name READ vcol_index_name <= (value1,value2,...) +handler t1 read c <= (-2); +a b c d +2 -2 -2 b +# HANDLER tbl_name READ vcol_index_name > (value1,value2,...) WHERE vcol_field=expr +handler t1 read c <= (-2) where b=-3; +a b c d +3 -3 -3 d +# HANDLER tbl_name READ vcol_index_name FIRST +handler t1 read c first; +a b c d +4 -4 -4 a +# HANDLER tbl_name READ vcol_index_name NEXT +handler t1 read c next; +a b c d +3 -3 -3 d +# HANDLER tbl_name READ vcol_index_name PREV +handler t1 read c prev; +a b c d +4 -4 -4 a +# HANDLER tbl_name READ vcol_index_name LAST +handler t1 read c last; +a b c d +1 -1 -1 c +# HANDLER tbl_name READ FIRST where non-vcol=expr +handler t1 read FIRST where a >= 2; +a b c d +4 -4 -4 a +# HANDLER tbl_name READ FIRST where vcol=expr +handler t1 read FIRST where b >= -2; +a b c d +2 -2 -2 b +# HANDLER tbl_name READ NEXT where non-vcol=expr +handler t1 read NEXT where d='c'; +a b c d +1 -1 -1 c +# HANDLER tbl_name READ NEXT where vcol=expr +handler t1 read NEXT where b<=-4; +a b c d +# HANDLER tbl_name CLOSE +handler t1 close; +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_handler_myisam.result b/mysql-test/suite/vcol/r/vcol_handler_myisam.result new file mode 100644 index 00000000000..ff93756adc5 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_handler_myisam.result @@ -0,0 +1,76 @@ +SET @@session.storage_engine = 'MyISAM'; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent, +d char(1), +index (a), +index (c)); +insert into t1 (a,d) values (4,'a'), (2,'b'), (1,'c'), (3,'d'); +select * from t1; +a b c d +4 -4 -4 a +2 -2 -2 b +1 -1 -1 c +3 -3 -3 d +# HANDLER tbl_name OPEN +handler t1 open; +# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) +handler t1 read a > (2); +a b c d +3 -3 -3 d +# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE non-vcol_field=expr +handler t1 read a > (2) where d='c'; +a b c d +# HANDLER tbl_name READ vcol_index_name = (value1,value2,...) +handler t1 read c = (-2); +a b c d +2 -2 -2 b +# HANDLER tbl_name READ vcol_index_name = (value1,value2,...) WHERE non-vcol_field=expr +handler t1 read c = (-2) where d='c'; +a b c d +# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE vcol_field=expr +handler t1 read a > (2) where b=-3 && c=-3; +a b c d +3 -3 -3 d +# HANDLER tbl_name READ vcol_index_name <= (value1,value2,...) +handler t1 read c <= (-2); +a b c d +2 -2 -2 b +# HANDLER tbl_name READ vcol_index_name > (value1,value2,...) WHERE vcol_field=expr +handler t1 read c <= (-2) where b=-3; +a b c d +3 -3 -3 d +# HANDLER tbl_name READ vcol_index_name FIRST +handler t1 read c first; +a b c d +4 -4 -4 a +# HANDLER tbl_name READ vcol_index_name NEXT +handler t1 read c next; +a b c d +3 -3 -3 d +# HANDLER tbl_name READ vcol_index_name PREV +handler t1 read c prev; +a b c d +4 -4 -4 a +# HANDLER tbl_name READ vcol_index_name LAST +handler t1 read c last; +a b c d +1 -1 -1 c +# HANDLER tbl_name READ FIRST where non-vcol=expr +handler t1 read FIRST where a >= 2; +a b c d +4 -4 -4 a +# HANDLER tbl_name READ FIRST where vcol=expr +handler t1 read FIRST where b >= -2; +a b c d +2 -2 -2 b +# HANDLER tbl_name READ NEXT where non-vcol=expr +handler t1 read NEXT where d='c'; +a b c d +1 -1 -1 c +# HANDLER tbl_name READ NEXT where vcol=expr +handler t1 read NEXT where b<=-4; +a b c d +# HANDLER tbl_name CLOSE +handler t1 close; +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result new file mode 100644 index 00000000000..a2ebc7a8cd8 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result @@ -0,0 +1,427 @@ +SET @@session.storage_engine = 'InnoDB'; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +set sql_warnings = 1; +# +# *** INSERT *** +# +# INSERT INTO tbl_name VALUES... DEFAULT is specified against vcols +insert into t1 values (1,default,default); +select * from t1; +a b c +1 -1 -1 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name VALUES... NULL is specified against vcols +insert into t1 values (1,null,null); +select * from t1; +a b c +1 -1 -1 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols +insert into t1 values (1,2,3); +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'c' in table 't1' ignored +select * from t1; +a b c +1 -1 -1 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name (<non_vcol_list>) VALUES... +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name (<normal+vcols>) VALUES... DEFAULT is specified +# against vcols +insert into t1 (a,b) values (1,default), (2,default); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name (<normal+vcols>) VALUES... NULL is specified against vcols +insert into t1 (a,b) values (1,null), (2,null); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name (<normal+vcols>) VALUES... a non-NULL value is specified +# against vcols +insert into t1 (a,b) values (1,3), (2,4); +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +drop table t1; +# Table with UNIQUE non-vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE +# KEY UPDATE <non_vcol>=expr, <vcol>=expr +create table t1 (a int unique, +b int as (-a), +c int as (-a) persistent); +insert into t1 values (1,default,default); +insert into t1 values (1,default,default) +on duplicate key update a=2, b=default; +select a,b,c from t1; +a b c +2 -2 -2 +delete from t1 where b in (1,2); +select * from t1; +a b c +2 -2 -2 +drop table t1; +# Table with UNIQUE vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE +# KEY UPDATE <non_vcol>=expr, <vcol>=expr +create table t1 (a int, +b int as (-a), +c int as (-a) persistent unique); +insert into t1 values (1,default,default); +insert into t1 values (1,default,default) +on duplicate key update a=2, b=default; +select a,b,c from t1; +a b c +2 -2 -2 +# CREATE new_table ... LIKE old_table +# INSERT INTO new_table SELECT * from old_table +create table t2 like t1; +insert into t2 select * from t1; +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'c' in table 't2' ignored +select * from t1; +a b c +2 -2 -2 +drop table t2; +# CREATE new_table ... LIKE old_table INSERT INTO new_table (<non-vcols>, <vcols>) +# SELECT <non-vcols>, <vcols> from old_table +insert into t1 values (1,default,default); +select * from t1; +a b c +2 -2 -2 +1 -1 -1 +create table t2 like t1; +insert into t2 (a,b) select a,b from t1; +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +select * from t2; +a b c +2 -2 -2 +1 -1 -1 +drop table t2; +drop table t1; +# +# *** UPDATE *** +# +# UPDATE tbl_name SET non-vcol=expr WHERE non-vcol=expr +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where a=2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# UPDATE tbl_name SET vcol=expr WHERE non-vcol=expr +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set c=3 where a=2; +Warnings: +Warning 1647 The value specified for computed column 'c' in table 't1' ignored +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +# UPDATE tbl_name SET non-vcol=expr WHERE vcol=expr +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where b=-2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# UPDATE tbl_name SET vcol=expr WHERE vcol=expr +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set c=3 where b=-2; +Warnings: +Warning 1647 The value specified for computed column 'c' in table 't1' ignored +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +drop table t1; +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr WHERE vcol=const +create table t1 (a int, +b int as (-a), +c int as (-a) persistent unique); +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where c=-2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2 +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where c between -3 and -2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# No INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2 +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where b between -3 and -2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr +# WHERE vcol=between const1 and const2 ORDER BY vcol +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +update t1 set a=6 where c between -1 and 0 +order by c; +select * from t1; +a b c +6 -6 -6 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +delete from t1 where c between -6 and 0; +select * from t1; +a b c +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr +# WHERE vcol=between const1 and const2 ORDER BY vcol LIMIT 2 +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +update t1 set a=6 where c between -1 and 0 +order by c limit 2; +select * from t1; +a b c +6 -6 -6 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +delete from t1 where c between -2 and 0 order by c; +select * from t1; +a b c +6 -6 -6 +3 -3 -3 +4 -4 -4 +5 -5 -5 +delete from t1; +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr +# WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3 +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +update t1 set a=6 where (c between -2 and 0) and (b=-1); +select * from t1; +a b c +6 -6 -6 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +delete from t1; +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr +# WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3 +# ORDER BY indexed vcol +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +update t1 set a=6 where (c between -2 and 0) and (b=-1) order by c; +select * from t1; +a b c +6 -6 -6 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +delete from t1; +drop table t1; +# +# Verify ON UPDATE/DELETE actions of FOREIGN KEYs +create table t2 (a int primary key, name varchar(10)); +create table t1 (a int primary key, b int as (a % 10) persistent); +insert into t2 values (1, 'value1'), (2,'value2'), (3,'value3'); +insert into t1 (a) values (1),(2),(3); +select * from t1; +a b +1 1 +2 2 +3 3 +select * from t2; +a name +1 value1 +2 value2 +3 value3 +select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a; +a b name +1 1 value1 +2 2 value2 +3 3 value3 +# - ON UPDATE RESTRICT +alter table t1 add foreign key (b) references t2(a) on update restrict; +insert into t1 (a) values (4); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t2` (`a`)) +update t2 set a=4 where a=3; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t2` (`a`)) +select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a; +a b name +1 1 value1 +2 2 value2 +3 3 value3 +alter table t1 drop foreign key t1_ibfk_1; +# - ON DELETE RESTRICT +alter table t1 add foreign key (b) references t2(a) on delete restrict; +delete from t2 where a=3; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t2` (`a`)) +select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a; +a b name +1 1 value1 +2 2 value2 +3 3 value3 +select t1.a, t1.b, t2.name from t1 left outer join t2 on (t1.b=t2.a); +a b name +1 1 value1 +2 2 value2 +3 3 value3 +alter table t1 drop foreign key t1_ibfk_1; +# - ON DELETE CASCADE +alter table t1 add foreign key (b) references t2(a) on delete cascade; +delete from t2 where a=3; +select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a; +a b name +1 1 value1 +2 2 value2 +select t1.a, t1.b, t2.name from t1 left outer join t2 on (t1.b=t2.a); +a b name +1 1 value1 +2 2 value2 +alter table t1 drop foreign key t1_ibfk_1; +drop table t1; +drop table t2; +# +# *** REPLACE *** +# +# UNIQUE INDEX on vcol +# REPLACE tbl_name (non-vcols) VALUES (non-vcols); +create table t1 (a int, +b int as (-a), +c int as (-a) persistent unique, +d varchar(16)); +insert into t1 (a,d) values (1,'a'), (2,'b'); +select * from t1; +a b c d +1 -1 -1 a +2 -2 -2 b +replace t1 (a,d) values (1,'c'); +select * from t1; +a b c d +1 -1 -1 c +2 -2 -2 b +delete from t1; +select * from t1; +a b c d +set sql_warnings = 0; +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result new file mode 100644 index 00000000000..161a82171ce --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result @@ -0,0 +1,365 @@ +SET @@session.storage_engine = 'MyISAM'; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +set sql_warnings = 1; +# +# *** INSERT *** +# +# INSERT INTO tbl_name VALUES... DEFAULT is specified against vcols +insert into t1 values (1,default,default); +select * from t1; +a b c +1 -1 -1 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name VALUES... NULL is specified against vcols +insert into t1 values (1,null,null); +select * from t1; +a b c +1 -1 -1 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols +insert into t1 values (1,2,3); +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'c' in table 't1' ignored +select * from t1; +a b c +1 -1 -1 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name (<non_vcol_list>) VALUES... +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name (<normal+vcols>) VALUES... DEFAULT is specified +# against vcols +insert into t1 (a,b) values (1,default), (2,default); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name (<normal+vcols>) VALUES... NULL is specified against vcols +insert into t1 (a,b) values (1,null), (2,null); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +# INSERT INTO tbl_name (<normal+vcols>) VALUES... a non-NULL value is specified +# against vcols +insert into t1 (a,b) values (1,3), (2,4); +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +Warning 1647 The value specified for computed column 'b' in table 't1' ignored +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +drop table t1; +# Table with UNIQUE non-vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE +# KEY UPDATE <non_vcol>=expr, <vcol>=expr +create table t1 (a int unique, +b int as (-a), +c int as (-a) persistent); +insert into t1 values (1,default,default); +insert into t1 values (1,default,default) +on duplicate key update a=2, b=default; +select a,b,c from t1; +a b c +2 -2 -2 +delete from t1 where b in (1,2); +select * from t1; +a b c +2 -2 -2 +drop table t1; +# Table with UNIQUE vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE +# KEY UPDATE <non_vcol>=expr, <vcol>=expr +create table t1 (a int, +b int as (-a), +c int as (-a) persistent unique); +insert into t1 values (1,default,default); +insert into t1 values (1,default,default) +on duplicate key update a=2, b=default; +select a,b,c from t1; +a b c +2 -2 -2 +# CREATE new_table ... LIKE old_table +# INSERT INTO new_table SELECT * from old_table +create table t2 like t1; +insert into t2 select * from t1; +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'c' in table 't2' ignored +select * from t1; +a b c +2 -2 -2 +drop table t2; +# CREATE new_table ... LIKE old_table INSERT INTO new_table (<non-vcols>, <vcols>) +# SELECT <non-vcols>, <vcols> from old_table +insert into t1 values (1,default,default); +select * from t1; +a b c +2 -2 -2 +1 -1 -1 +create table t2 like t1; +insert into t2 (a,b) select a,b from t1; +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +select * from t2; +a b c +2 -2 -2 +1 -1 -1 +drop table t2; +drop table t1; +# +# *** UPDATE *** +# +# UPDATE tbl_name SET non-vcol=expr WHERE non-vcol=expr +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where a=2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# UPDATE tbl_name SET vcol=expr WHERE non-vcol=expr +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set c=3 where a=2; +Warnings: +Warning 1647 The value specified for computed column 'c' in table 't1' ignored +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +# UPDATE tbl_name SET non-vcol=expr WHERE vcol=expr +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where b=-2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# UPDATE tbl_name SET vcol=expr WHERE vcol=expr +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set c=3 where b=-2; +Warnings: +Warning 1647 The value specified for computed column 'c' in table 't1' ignored +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +delete from t1; +select * from t1; +a b c +drop table t1; +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr WHERE vcol=const +create table t1 (a int, +b int as (-a), +c int as (-a) persistent unique); +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where c=-2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2 +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where c between -3 and -2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# No INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2 +insert into t1 (a) values (1), (2); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +update t1 set a=3 where b between -3 and -2; +select * from t1; +a b c +1 -1 -1 +3 -3 -3 +delete from t1; +select * from t1; +a b c +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr +# WHERE vcol=between const1 and const2 ORDER BY vcol +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +update t1 set a=6 where c between -1 and 0 +order by c; +select * from t1; +a b c +6 -6 -6 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +delete from t1 where c between -6 and 0; +select * from t1; +a b c +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr +# WHERE vcol=between const1 and const2 ORDER BY vcol LIMIT 2 +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +a b c +5 -5 -5 +4 -4 -4 +3 -3 -3 +2 -2 -2 +1 -1 -1 +update t1 set a=6 where c between -1 and 0 +order by c limit 2; +select * from t1; +a b c +5 -5 -5 +4 -4 -4 +3 -3 -3 +2 -2 -2 +6 -6 -6 +delete from t1 where c between -2 and 0 order by c; +select * from t1; +a b c +5 -5 -5 +4 -4 -4 +3 -3 -3 +6 -6 -6 +delete from t1; +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr +# WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3 +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +update t1 set a=6 where (c between -2 and 0) and (b=-1); +select * from t1; +a b c +6 -6 -6 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +delete from t1; +# INDEX created on vcol +# UPDATE tbl_name SET non-vcol=expr +# WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3 +# ORDER BY indexed vcol +insert into t1 (a) values (1), (2), (3), (4), (5); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +update t1 set a=6 where (c between -2 and 0) and (b=-1) order by c; +select * from t1; +a b c +6 -6 -6 +2 -2 -2 +3 -3 -3 +4 -4 -4 +5 -5 -5 +delete from t1; +drop table t1; +# +# *** REPLACE *** +# +# UNIQUE INDEX on vcol +# REPLACE tbl_name (non-vcols) VALUES (non-vcols); +create table t1 (a int, +b int as (-a), +c int as (-a) persistent unique, +d varchar(16)); +insert into t1 (a,d) values (1,'a'), (2,'b'); +select * from t1; +a b c d +1 -1 -1 a +2 -2 -2 b +replace t1 (a,d) values (1,'c'); +select * from t1; +a b c d +1 -1 -1 c +2 -2 -2 b +delete from t1; +select * from t1; +a b c d +set sql_warnings = 0; +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_keys_innodb.result b/mysql-test/suite/vcol/r/vcol_keys_innodb.result new file mode 100644 index 00000000000..857dcb8423f --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_keys_innodb.result @@ -0,0 +1,151 @@ +SET @@session.storage_engine = 'InnoDB'; +# - UNIQUE KEY +# - INDEX +# - FULLTEXT INDEX +# - SPATIAL INDEX (not supported) +# - FOREIGN INDEX (partially supported) +# - CHECK (allowed but not used) +# UNIQUE +create table t1 (a int, b int as (a*2) unique); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a*2) persistent unique); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) PERSISTENT, + UNIQUE KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES UNI NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a*2), unique key (b)); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a*2) persistent, unique (b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) PERSISTENT, + UNIQUE KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES UNI NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a*2)); +alter table t1 add unique key (b); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; +create table t1 (a int, b int as (a*2) persistent); +alter table t1 add unique key (b); +drop table t1; +# Testing data manipulation operations involving UNIQUE keys +# on virtual columns can be found in: +# - vcol_ins_upd.inc +# - vcol_select.inc +# +# INDEX +create table t1 (a int, b int as (a*2), index (b)); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a*2), index (a,b)); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a*2) persistent, index (b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) PERSISTENT, + KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES MUL NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a*2) persistent, index (a,b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) PERSISTENT, + KEY `a` (`a`,`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES MUL NULL +b int(11) YES NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a*2)); +alter table t1 add index (b); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +alter table t1 add index (a,b); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; +create table t1 (a int, b int as (a*2) persistent); +alter table t1 add index (b); +drop table t1; +create table t1 (a int, b int as (a*2) persistent); +alter table t1 add index (a,b); +create table t2 like t1; +drop table t2; +drop table t1; +# Testing data manipulation operations involving INDEX +# on virtual columns can be found in: +# - vcol_select.inc +# +# TODO: FULLTEXT INDEX +# SPATIAL INDEX +# FOREIGN KEY +# Rejected FK options. +create table t1 (a int, b int as (a+1) persistent, +foreign key (b) references t2(a) on update set null); +ERROR HY000: Cannot define foreign key with ON UPDATE SET NULL clause on a computed column +create table t1 (a int, b int as (a+1) persistent, +foreign key (b) references t2(a) on update cascade); +ERROR HY000: Cannot define foreign key with ON UPDATE CASCADE clause on a computed column +create table t1 (a int, b int as (a+1) persistent, +foreign key (b) references t2(a) on delete set null); +ERROR HY000: Cannot define foreign key with ON DELETE SET NULL clause on a computed column +create table t1 (a int, b int as (a+1) persistent); +alter table t1 add foreign key (b) references t2(a) on update set null; +ERROR HY000: Cannot define foreign key with ON UPDATE SET NULL clause on a computed column +alter table t1 add foreign key (b) references t2(a) on update cascade; +ERROR HY000: Cannot define foreign key with ON UPDATE CASCADE clause on a computed column +alter table t1 add foreign key (b) references t2(a) on delete set null; +ERROR HY000: Cannot define foreign key with ON DELETE SET NULL clause on a computed column +drop table t1; +create table t1 (a int, b int as (a+1), +foreign key (b) references t2(a)); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a+1)); +alter table t1 add foreign key (b) references t2(a); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; +# Allowed FK options. +create table t2 (a int primary key, b char(5)); +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on update restrict); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on update no action); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on delete restrict); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on delete cascade); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on delete no action); +drop table t1; + +# Testing data manipulation operations involving FOREIGN KEY +# on virtual columns can be found in: +# - vcol_ins_upd.inc +# - vcol_select.inc +# +# TODO: CHECK diff --git a/mysql-test/suite/vcol/r/vcol_keys_myisam.result b/mysql-test/suite/vcol/r/vcol_keys_myisam.result new file mode 100644 index 00000000000..f7b47316ca8 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_keys_myisam.result @@ -0,0 +1,157 @@ +SET @@session.storage_engine = 'MyISAM'; +# - UNIQUE KEY +# - INDEX +# - FULLTEXT INDEX +# - SPATIAL INDEX (not supported) +# - FOREIGN INDEX (partially supported) +# - CHECK (allowed but not used) +# UNIQUE +create table t1 (a int, b int as (a*2) unique); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a*2) persistent unique); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) PERSISTENT, + UNIQUE KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES UNI NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a*2), unique key (b)); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a*2) persistent, unique (b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) PERSISTENT, + UNIQUE KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES UNI NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a*2)); +alter table t1 add unique key (b); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; +create table t1 (a int, b int as (a*2) persistent); +alter table t1 add unique key (b); +drop table t1; +# Testing data manipulation operations involving UNIQUE keys +# on virtual columns can be found in: +# - vcol_ins_upd.inc +# - vcol_select.inc +# +# INDEX +create table t1 (a int, b int as (a*2), index (b)); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a*2), index (a,b)); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a*2) persistent, index (b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) PERSISTENT, + KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES MUL NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a*2) persistent, index (a,b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) PERSISTENT, + KEY `a` (`a`,`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES MUL NULL +b int(11) YES NULL VIRTUAL +drop table t1; +create table t1 (a int, b int as (a*2)); +alter table t1 add index (b); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +alter table t1 add index (a,b); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; +create table t1 (a int, b int as (a*2) persistent); +alter table t1 add index (b); +drop table t1; +create table t1 (a int, b int as (a*2) persistent); +alter table t1 add index (a,b); +create table t2 like t1; +drop table t2; +drop table t1; +# Testing data manipulation operations involving INDEX +# on virtual columns can be found in: +# - vcol_select.inc +# +# TODO: FULLTEXT INDEX +# SPATIAL INDEX +create table t1 (a int, b int as (a+1) persistent, spatial index (b)); +ERROR HY000: Incorrect arguments to SPATIAL INDEX +create table t1 (a int, b int as (a+1) persistent); +alter table t1 add spatial index (b); +ERROR HY000: Incorrect arguments to SPATIAL INDEX +drop table t1; +# FOREIGN KEY +# Rejected FK options. +create table t1 (a int, b int as (a+1) persistent, +foreign key (b) references t2(a) on update set null); +ERROR HY000: Cannot define foreign key with ON UPDATE SET NULL clause on a computed column +create table t1 (a int, b int as (a+1) persistent, +foreign key (b) references t2(a) on update cascade); +ERROR HY000: Cannot define foreign key with ON UPDATE CASCADE clause on a computed column +create table t1 (a int, b int as (a+1) persistent, +foreign key (b) references t2(a) on delete set null); +ERROR HY000: Cannot define foreign key with ON DELETE SET NULL clause on a computed column +create table t1 (a int, b int as (a+1) persistent); +alter table t1 add foreign key (b) references t2(a) on update set null; +ERROR HY000: Cannot define foreign key with ON UPDATE SET NULL clause on a computed column +alter table t1 add foreign key (b) references t2(a) on update cascade; +ERROR HY000: Cannot define foreign key with ON UPDATE CASCADE clause on a computed column +alter table t1 add foreign key (b) references t2(a) on delete set null; +ERROR HY000: Cannot define foreign key with ON DELETE SET NULL clause on a computed column +drop table t1; +create table t1 (a int, b int as (a+1), +foreign key (b) references t2(a)); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a+1)); +alter table t1 add foreign key (b) references t2(a); +ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; +# Allowed FK options. +create table t2 (a int primary key, b char(5)); +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on update restrict); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on update no action); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on delete restrict); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on delete cascade); +drop table t1; +create table t1 (a int, b int as (a % 10) persistent, +foreign key (b) references t2(a) on delete no action); +drop table t1; + +# Testing data manipulation operations involving FOREIGN KEY +# on virtual columns can be found in: +# - vcol_ins_upd.inc +# - vcol_select.inc +# +# TODO: CHECK diff --git a/mysql-test/suite/vcol/r/vcol_memory.result b/mysql-test/suite/vcol/r/vcol_memory.result new file mode 100644 index 00000000000..4503c51e39a --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_memory.result @@ -0,0 +1,7 @@ +SET @@session.storage_engine = 'memory'; +create table t1 (a int, b int as (a+1)); +ERROR HY000: MEMORY storage engine does not support computed columns +create table t1 (a int not null); +alter table t1 add column b int as (a+1); +ERROR HY000: MEMORY storage engine does not support computed columns +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_merge.result b/mysql-test/suite/vcol/r/vcol_merge.result new file mode 100644 index 00000000000..4b5ed838c3a --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_merge.result @@ -0,0 +1,8 @@ +drop table if exists t1, t2, t3; +create table t1 (a int, b int as (a % 10)); +create table t2 (a int, b int as (a % 10)); +insert into t1 values (1,default); +insert into t2 values (2,default); +create table t3 (a int, b int as (a % 10)) engine=MERGE UNION=(t1,t2); +ERROR HY000: MRG_MYISAM storage engine does not support computed columns +drop table t1,t2; diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result new file mode 100644 index 00000000000..e83a89c44c3 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -0,0 +1,135 @@ +drop table if exists t1,t2; +create table t1 (a int, b int, v int as (a+1), index idx(b)); +insert into t1(a, b) values +(4, 40), (3, 30), (5, 50), (7, 70), (8, 80), (2, 20), (1, 10); +select * from t1 order by b; +a b v +1 10 2 +2 20 3 +3 30 4 +4 40 5 +5 50 6 +7 70 8 +8 80 9 +delete from t1 where v > 6 order by b limit 1; +select * from t1 order by b; +a b v +1 10 2 +2 20 3 +3 30 4 +4 40 5 +5 50 6 +8 80 9 +update t1 set a=v order by b limit 1; +select * from t1 order by b; +a b v +2 10 3 +2 20 3 +3 30 4 +4 40 5 +5 50 6 +8 80 9 +drop table t1; +CREATE TABLE t1 ( +a int NOT NULL DEFAULT '0', +v double AS ((1, a)) VIRTUAL +); +ERROR HY000: Expression for computed column cannot return a row +CREATE TABLE t1 ( +a CHAR(255) BINARY NOT NULL DEFAULT 0, +b CHAR(255) BINARY NOT NULL DEFAULT 0, +v CHAR(255) BINARY AS (CONCAT(a,b)) VIRTUAL ); +INSERT INTO t1(a,b) VALUES ('4','7'), ('4','6'); +SELECT 1 AS C FROM t1 ORDER BY v; +C +1 +1 +DROP TABLE t1; +CREATE TABLE t1(a int, b int DEFAULT 0, v INT AS (b+10) PERSISTENT); +INSERT INTO t1(a) VALUES (1); +SELECT b, v FROM t1; +b v +0 10 +DROP TABLE t1; +CREATE TABLE t1(a int DEFAULT 100, v int AS (a+1) PERSISTENT); +INSERT INTO t1 () VALUES (); +CREATE TABLE t2(a int DEFAULT 100 , v int AS (a+1)); +INSERT INTO t2 () VALUES (); +SELECT a, v FROM t1; +a v +100 101 +SELECT a, v FROM t2; +a v +100 101 +DROP TABLE t1,t2; +CREATE TABLE t1 ( +a datetime NOT NULL DEFAULT '2000-01-01', +v boolean AS (a < '2001-01-01') +); +INSERT INTO t1(a) VALUES ('2002-02-15'); +INSERT INTO t1(a) VALUES ('2000-10-15'); +SELECT a, v FROM t1; +a v +2002-02-15 00:00:00 0 +2000-10-15 00:00:00 1 +SELECT a, v FROM t1; +a v +2002-02-15 00:00:00 0 +2000-10-15 00:00:00 1 +CREATE TABLE t2 ( +a datetime NOT NULL DEFAULT '2000-01-01', +v boolean AS (a < '2001-01-01') PERSISTENT +); +INSERT INTO t2(a) VALUES ('2002-02-15'); +INSERT INTO t2(a) VALUES ('2000-10-15'); +SELECT * FROM t2; +a v +2002-02-15 00:00:00 0 +2000-10-15 00:00:00 1 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +a char(255), b char(255), c char(255), d char(255), +v char(255) AS (CONCAT(c,d) ) VIRTUAL +); +INSERT INTO t1(a,b,c,d) VALUES ('w','x','y','z'), ('W','X','Y','Z'); +SELECT v FROM t1 ORDER BY CONCAT(a,b); +v +yz +YZ +DROP TABLE t1; +CREATE TABLE t1 (f1 INTEGER, v1 INTEGER AS (f1) VIRTUAL); +CREATE TABLE t2 AS SELECT v1 FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `v1` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1,t2; +CREATE TABLE t1 (p int, a double NOT NULL, v double AS (ROUND(a,p)) VIRTUAL); +INSERT INTO t1 VALUES (0,1,0); +Warnings: +Warning 1647 The value specified for computed column 'v' in table 't1' ignored +INSERT INTO t1 VALUES (NULL,0,0); +Warnings: +Warning 1647 The value specified for computed column 'v' in table 't1' ignored +SELECT a, p, v, ROUND(a,p), ROUND(a,p+NULL) FROM t1; +a p v ROUND(a,p) ROUND(a,p+NULL) +1 0 1 1 NULL +0 NULL NULL NULL NULL +DROP TABLE t1; +CREATE TABLE t1 (p int, a double NOT NULL); +INSERT INTO t1(p,a) VALUES (0,1); +INSERT INTO t1(p,a) VALUES (NULL,0); +SELECT a, p, ROUND(a,p), ROUND(a,p+NULL) FROM t1; +a p ROUND(a,p) ROUND(a,p+NULL) +1 0 1 NULL +0 NULL NULL NULL +DROP TABLE t1; +CREATE TABLE t1 (a char(32), v char(32) CHARACTER SET ucs2 AS (a) VIRTUAL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(32) DEFAULT NULL, + `v` char(32) CHARACTER SET ucs2 AS (a) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result b/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result new file mode 100644 index 00000000000..0379a71922d --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result @@ -0,0 +1,242 @@ +SET @@session.storage_engine = 'InnoDB'; +# Case 1. All non-stored columns. +# This scenario is currently impossible due to the fact that virtual columns +# with a constant expression are not allowed. +# Case 2. CREATE +# - Column1: "real" +# - Column 2: virtual non-stored +create table t1 (a int, b int as (-a)); +insert into t1 values (1,default); +select * from t1; +a b +1 -1 +insert into t1 values (2,default); +select * from t1; +a b +1 -1 +2 -2 +drop table t1; +# Case 3. CREATE +# - Column1: "real" +# - Column 2: virtual stored +create table t1 (a int, b int as (-a) persistent); +insert into t1 values (1,default); +select * from t1; +a b +1 -1 +insert into t1 values (2,default); +select * from t1; +a b +1 -1 +2 -2 +drop table t1; +# Case 4. CREATE +# - Column1: virtual non-stored +# - Column2: "real" +create table t1 (a int as (-b), b int); +insert into t1 values (default,1); +select * from t1; +a b +-1 1 +insert into t1 values (default,2); +select * from t1; +a b +-1 1 +-2 2 +drop table t1; +# Case 5. CREATE +# - Column1: virtual stored +# - Column2: "real" +create table t1 (a int as (-b) persistent, b int); +insert into t1 values (default,1); +select * from t1; +a b +-1 1 +insert into t1 values (default,2); +select * from t1; +a b +-1 1 +-2 2 +drop table t1; +# Case 6. CREATE +# - Column1: "real" +# - Column2: virtual non-stored +# - Column3: virtual stored +create table t1 (a int, b int as (-a), c int as (-a) persistent); +insert into t1 values (1,default,default); +select * from t1; +a b c +1 -1 -1 +insert into t1 values (2,default,default); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +drop table t1; +# Case 7. ALTER. Modify virtual stored -> virtual non-stored +create table t1 (a int, b int as (a % 2) persistent); +alter table t1 modify b int as (a % 2); +ERROR HY000: This is not yet supported for computed columns +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) PERSISTENT +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +# Case 8. ALTER. Modify virtual non-stored -> virtual stored +create table t1 (a int, b int as (a % 2)); +alter table t1 modify b int as (a % 2) persistent; +ERROR HY000: This is not yet supported for computed columns +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +# Case 9. CREATE LIKE +# - Column1: "real" +# - Column2: virtual non-stored +# - Column3: virtual stored +create table t1 (a int, b int as (-a), c int as (-a) persistent); +create table t2 like t1; +insert into t2 values (1,default,default); +select * from t2; +a b c +1 -1 -1 +insert into t2 values (2,default,default); +select * from t2; +a b c +1 -1 -1 +2 -2 -2 +drop table t2; +drop table t1; +# Case 10. ALTER. Dropping a virtual non-stored column. +# - Column1: virtual non-stored +# - Column2: "real" +create table t1 (a int as (-b), b int, c varchar(5)); +insert into t1 values (default,1,'v1'); +insert into t1 values (default,2,'v2'); +select * from t1; +a b c +-1 1 v1 +-2 2 v2 +alter table t1 drop column a; +select * from t1; +b c +1 v1 +2 v2 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `b` int(11) DEFAULT NULL, + `c` varchar(5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +# Case 11. ALTER. Dropping a virtual stored column. +# - Column1: virtual stored +# - Column2: "real" +create table t1 (a int as (-b) persistent, b int, c char(5)); +insert into t1 values (default,1,'v1'); +insert into t1 values (default,2,'v2'); +select * from t1; +a b c +-1 1 v1 +-2 2 v2 +alter table t1 drop column a; +select * from t1; +b c +1 v1 +2 v2 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `b` int(11) DEFAULT NULL, + `c` char(5) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +# Case 12. ALTER. Adding a new virtual non-stored column. +create table t1 (a int, b datetime); +insert into t1 values (1,'2008-09-04'); +insert into t1 values (2,'2008-09-05'); +select * from t1; +a b +1 2008-09-04 00:00:00 +2 2008-09-05 00:00:00 +alter table t1 add column c int as (dayofyear(b)) after a; +select * from t1; +a c b +1 248 2008-09-04 00:00:00 +2 249 2008-09-05 00:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `c` int(11) AS (dayofyear(b)) VIRTUAL, + `b` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +# Case 13. ALTER. Adding a new virtual stored column. +create table t1 (a int, b datetime); +insert into t1 values (1,'2008-09-04'); +insert into t1 values (2,'2008-09-05'); +select * from t1; +a b +1 2008-09-04 00:00:00 +2 2008-09-05 00:00:00 +alter table t1 add column c int as (dayofyear(b)) persistent after a; +select * from t1; +a c b +1 248 2008-09-04 00:00:00 +2 249 2008-09-05 00:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `c` int(11) AS (dayofyear(b)) PERSISTENT, + `b` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +# Case 14. ALTER. Changing the expression of a virtual stored column. +create table t1 (a int, b datetime, c int as (week(b)) persistent); +insert into t1 values (1,'2008-09-04',default); +insert into t1 values (2,'2008-09-05',default); +select * from t1; +a b c +1 2008-09-04 00:00:00 35 +2 2008-09-05 00:00:00 35 +alter table t1 change column c c int as (week(b,1)) persistent; +select * from t1; +a b c +1 2008-09-04 00:00:00 36 +2 2008-09-05 00:00:00 36 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` datetime DEFAULT NULL, + `c` int(11) AS (week(b,1)) PERSISTENT +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +# Case 15. ALTER. Changing the expression of a virtual non-stored column. +create table t1 (a int, b datetime, c int as (week(b))); +insert into t1 values (1,'2008-09-04',default); +insert into t1 values (2,'2008-09-05',default); +select * from t1; +a b c +1 2008-09-04 00:00:00 35 +2 2008-09-05 00:00:00 35 +alter table t1 change column c c int as (week(b,1)); +select * from t1; +a b c +1 2008-09-04 00:00:00 36 +2 2008-09-05 00:00:00 36 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` datetime DEFAULT NULL, + `c` int(11) AS (week(b,1)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result b/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result new file mode 100644 index 00000000000..de9a962ac2c --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result @@ -0,0 +1,242 @@ +SET @@session.storage_engine = 'MyISAM'; +# Case 1. All non-stored columns. +# This scenario is currently impossible due to the fact that virtual columns +# with a constant expression are not allowed. +# Case 2. CREATE +# - Column1: "real" +# - Column 2: virtual non-stored +create table t1 (a int, b int as (-a)); +insert into t1 values (1,default); +select * from t1; +a b +1 -1 +insert into t1 values (2,default); +select * from t1; +a b +1 -1 +2 -2 +drop table t1; +# Case 3. CREATE +# - Column1: "real" +# - Column 2: virtual stored +create table t1 (a int, b int as (-a) persistent); +insert into t1 values (1,default); +select * from t1; +a b +1 -1 +insert into t1 values (2,default); +select * from t1; +a b +1 -1 +2 -2 +drop table t1; +# Case 4. CREATE +# - Column1: virtual non-stored +# - Column2: "real" +create table t1 (a int as (-b), b int); +insert into t1 values (default,1); +select * from t1; +a b +-1 1 +insert into t1 values (default,2); +select * from t1; +a b +-1 1 +-2 2 +drop table t1; +# Case 5. CREATE +# - Column1: virtual stored +# - Column2: "real" +create table t1 (a int as (-b) persistent, b int); +insert into t1 values (default,1); +select * from t1; +a b +-1 1 +insert into t1 values (default,2); +select * from t1; +a b +-1 1 +-2 2 +drop table t1; +# Case 6. CREATE +# - Column1: "real" +# - Column2: virtual non-stored +# - Column3: virtual stored +create table t1 (a int, b int as (-a), c int as (-a) persistent); +insert into t1 values (1,default,default); +select * from t1; +a b c +1 -1 -1 +insert into t1 values (2,default,default); +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +drop table t1; +# Case 7. ALTER. Modify virtual stored -> virtual non-stored +create table t1 (a int, b int as (a % 2) persistent); +alter table t1 modify b int as (a % 2); +ERROR HY000: This is not yet supported for computed columns +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) PERSISTENT +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# Case 8. ALTER. Modify virtual non-stored -> virtual stored +create table t1 (a int, b int as (a % 2)); +alter table t1 modify b int as (a % 2) persistent; +ERROR HY000: This is not yet supported for computed columns +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 2) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# Case 9. CREATE LIKE +# - Column1: "real" +# - Column2: virtual non-stored +# - Column3: virtual stored +create table t1 (a int, b int as (-a), c int as (-a) persistent); +create table t2 like t1; +insert into t2 values (1,default,default); +select * from t2; +a b c +1 -1 -1 +insert into t2 values (2,default,default); +select * from t2; +a b c +1 -1 -1 +2 -2 -2 +drop table t2; +drop table t1; +# Case 10. ALTER. Dropping a virtual non-stored column. +# - Column1: virtual non-stored +# - Column2: "real" +create table t1 (a int as (-b), b int, c varchar(5)); +insert into t1 values (default,1,'v1'); +insert into t1 values (default,2,'v2'); +select * from t1; +a b c +-1 1 v1 +-2 2 v2 +alter table t1 drop column a; +select * from t1; +b c +1 v1 +2 v2 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `b` int(11) DEFAULT NULL, + `c` varchar(5) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# Case 11. ALTER. Dropping a virtual stored column. +# - Column1: virtual stored +# - Column2: "real" +create table t1 (a int as (-b) persistent, b int, c char(5)); +insert into t1 values (default,1,'v1'); +insert into t1 values (default,2,'v2'); +select * from t1; +a b c +-1 1 v1 +-2 2 v2 +alter table t1 drop column a; +select * from t1; +b c +1 v1 +2 v2 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `b` int(11) DEFAULT NULL, + `c` char(5) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# Case 12. ALTER. Adding a new virtual non-stored column. +create table t1 (a int, b datetime); +insert into t1 values (1,'2008-09-04'); +insert into t1 values (2,'2008-09-05'); +select * from t1; +a b +1 2008-09-04 00:00:00 +2 2008-09-05 00:00:00 +alter table t1 add column c int as (dayofyear(b)) after a; +select * from t1; +a c b +1 248 2008-09-04 00:00:00 +2 249 2008-09-05 00:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `c` int(11) AS (dayofyear(b)) VIRTUAL, + `b` datetime DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# Case 13. ALTER. Adding a new virtual stored column. +create table t1 (a int, b datetime); +insert into t1 values (1,'2008-09-04'); +insert into t1 values (2,'2008-09-05'); +select * from t1; +a b +1 2008-09-04 00:00:00 +2 2008-09-05 00:00:00 +alter table t1 add column c int as (dayofyear(b)) persistent after a; +select * from t1; +a c b +1 248 2008-09-04 00:00:00 +2 249 2008-09-05 00:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `c` int(11) AS (dayofyear(b)) PERSISTENT, + `b` datetime DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# Case 14. ALTER. Changing the expression of a virtual stored column. +create table t1 (a int, b datetime, c int as (week(b)) persistent); +insert into t1 values (1,'2008-09-04',default); +insert into t1 values (2,'2008-09-05',default); +select * from t1; +a b c +1 2008-09-04 00:00:00 35 +2 2008-09-05 00:00:00 35 +alter table t1 change column c c int as (week(b,1)) persistent; +select * from t1; +a b c +1 2008-09-04 00:00:00 36 +2 2008-09-05 00:00:00 36 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` datetime DEFAULT NULL, + `c` int(11) AS (week(b,1)) PERSISTENT +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# Case 15. ALTER. Changing the expression of a virtual non-stored column. +create table t1 (a int, b datetime, c int as (week(b))); +insert into t1 values (1,'2008-09-04',default); +insert into t1 values (2,'2008-09-05',default); +select * from t1; +a b c +1 2008-09-04 00:00:00 35 +2 2008-09-05 00:00:00 35 +alter table t1 change column c c int as (week(b,1)); +select * from t1; +a b c +1 2008-09-04 00:00:00 36 +2 2008-09-05 00:00:00 36 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` datetime DEFAULT NULL, + `c` int(11) AS (week(b,1)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_partition_innodb.result b/mysql-test/suite/vcol/r/vcol_partition_innodb.result new file mode 100644 index 00000000000..466c1851800 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_partition_innodb.result @@ -0,0 +1,80 @@ +SET @@session.storage_engine = 'InnoDB'; +drop table if exists t1; +# Case 1. Partitioning by RANGE based on a non-stored virtual column. +CREATE TABLE t1 ( +a DATE NOT NULL, +b int as (year(a)) +) +PARTITION BY RANGE( b ) ( +PARTITION p0 VALUES LESS THAN (2006), +PARTITION p2 VALUES LESS THAN (2008) +); +insert into t1 values ('2006-01-01',default); +insert into t1 values ('2007-01-01',default); +insert into t1 values ('2005-01-01',default); +select * from t1; +a b +2005-01-01 2005 +2006-01-01 2006 +2007-01-01 2007 +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p0 1 16384 +p2 2 16384 +# Modify the expression of virtual column b +ALTER TABLE t1 modify b int as (year(a)-1); +select * from t1; +a b +2005-01-01 2004 +2006-01-01 2005 +2007-01-01 2006 +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p0 2 16384 +p2 1 16384 +drop table t1; +# Case 2. Partitioning by LIST based on a stored virtual column. +CREATE TABLE t1 (a int, b int as (a % 3 ) persistent) +PARTITION BY LIST (a+1) +(PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2)); +insert into t1 values (1,default); +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p1 0 16384 +p2 1 16384 +select * from t1; +a b +1 1 +select * from t1; +a b +1 1 +drop table t1; +# Case 3. Partitioning by HASH based on a non-stored virtual column. +CREATE TABLE t1 ( +a DATE NOT NULL, +b int as (year(a)) +) +PARTITION BY HASH( b % 3 ) PARTITIONS 3; +insert into t1 values ('2005-01-01',default); +insert into t1 values ('2006-01-01',default); +select * from t1; +a b +2005-01-01 2005 +2006-01-01 2006 +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p0 0 16384 +p1 1 16384 +p2 1 16384 +# Modify the expression of virtual column b +ALTER TABLE t1 modify b int as (year(a)-1); +select * from t1; +a b +2005-01-01 2004 +2006-01-01 2005 +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p0 1 16384 +p1 1 16384 +p2 0 16384 +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_partition_myisam.result b/mysql-test/suite/vcol/r/vcol_partition_myisam.result new file mode 100644 index 00000000000..9a92f308c45 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_partition_myisam.result @@ -0,0 +1,80 @@ +SET @@session.storage_engine = 'MyISAM'; +drop table if exists t1; +# Case 1. Partitioning by RANGE based on a non-stored virtual column. +CREATE TABLE t1 ( +a DATE NOT NULL, +b int as (year(a)) +) +PARTITION BY RANGE( b ) ( +PARTITION p0 VALUES LESS THAN (2006), +PARTITION p2 VALUES LESS THAN (2008) +); +insert into t1 values ('2006-01-01',default); +insert into t1 values ('2007-01-01',default); +insert into t1 values ('2005-01-01',default); +select * from t1; +a b +2005-01-01 2005 +2006-01-01 2006 +2007-01-01 2007 +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p0 1 7 +p2 2 14 +# Modify the expression of virtual column b +ALTER TABLE t1 modify b int as (year(a)-1); +select * from t1; +a b +2005-01-01 2004 +2006-01-01 2005 +2007-01-01 2006 +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p0 2 14 +p2 1 7 +drop table t1; +# Case 2. Partitioning by LIST based on a stored virtual column. +CREATE TABLE t1 (a int, b int as (a % 3 ) persistent) +PARTITION BY LIST (a+1) +(PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2)); +insert into t1 values (1,default); +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p1 0 0 +p2 1 9 +select * from t1; +a b +1 1 +select * from t1; +a b +1 1 +drop table t1; +# Case 3. Partitioning by HASH based on a non-stored virtual column. +CREATE TABLE t1 ( +a DATE NOT NULL, +b int as (year(a)) +) +PARTITION BY HASH( b % 3 ) PARTITIONS 3; +insert into t1 values ('2005-01-01',default); +insert into t1 values ('2006-01-01',default); +select * from t1; +a b +2005-01-01 2005 +2006-01-01 2006 +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p0 0 0 +p1 1 7 +p2 1 7 +# Modify the expression of virtual column b +ALTER TABLE t1 modify b int as (year(a)-1); +select * from t1; +a b +2005-01-01 2004 +2006-01-01 2005 +select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1'; +partition_name table_rows data_length +p0 1 7 +p1 1 7 +p2 0 0 +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result new file mode 100644 index 00000000000..0612d5a06b3 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result @@ -0,0 +1,264 @@ +SET @@session.storage_engine = 'InnoDB'; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent, +index (c)); +insert into t1 (a) values (2), (1), (1), (3), (NULL); +create table t2 like t1; +insert into t2 (a) values (1); +create table t3 (a int primary key, +b int as (-a), +c int as (-a) persistent unique); +insert into t3 (a) values (2),(1),(3); +# select_type=SIMPLE, type=system +select * from t2; +a b c +1 -1 -1 +explain select * from t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 +select * from t2 where c=-1; +a b c +1 -1 -1 +explain select * from t2 where c=-1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref c c 5 const 1 Using where +# select_type=SIMPLE, type=ALL +select * from t1 where b=-1; +a b c +1 -1 -1 +1 -1 -1 +explain select * from t1 where b=-1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where +# select_type=SIMPLE, type=const +select * from t3 where a=1; +a b c +1 -1 -1 +explain select * from t3 where a=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 const PRIMARY PRIMARY 4 const 1 +# select_type=SIMPLE, type=range +select * from t3 where c>=-1; +a b c +1 -1 -1 +explain select * from t3 where c>=-1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 1 Using where +# select_type=SIMPLE, type=ref +select * from t1,t3 where t1.c=t3.c and t3.c=-1; +a b c a b c +1 -1 -1 1 -1 -1 +1 -1 -1 1 -1 -1 +explain select * from t1,t3 where t1.c=t3.c and t3.c=-1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 const c c 5 const 1 +1 SIMPLE t1 ref c c 5 const 2 Using where +# select_type=PRIMARY, type=index,ALL +select * from t1 where b in (select c from t3); +a b c +2 -2 -2 +1 -1 -1 +1 -1 -1 +3 -3 -3 +explain select * from t1 where b in (select c from t3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +2 DEPENDENT SUBQUERY t3 index_subquery c c 5 func 1 Using index; Using where +# select_type=PRIMARY, type=range,ref +select * from t1 where c in (select c from t3 where c between -2 and -1); +a b c +2 -2 -2 +1 -1 -1 +1 -1 -1 +explain select * from t1 where c in (select c from t3 where c between -2 and -1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +2 DEPENDENT SUBQUERY t3 index_subquery c c 5 func 1 Using index; Using where +# select_type=UNION, type=system +# select_type=UNION RESULT, type=<union1,2> +select * from t1 union select * from t2; +a b c +2 -2 -2 +1 -1 -1 +3 -3 -3 +NULL NULL NULL +explain select * from t1 union select * from t2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 +2 UNION t2 ALL NULL NULL NULL NULL 1 +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +# select_type=DERIVED, type=system +select * from (select a,b,c from t1) as t11; +a b c +2 -2 -2 +1 -1 -1 +1 -1 -1 +3 -3 -3 +NULL NULL NULL +explain select * from (select a,b,c from t1) as t11; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 +2 DERIVED t1 ALL NULL NULL NULL NULL 5 +### +### Using aggregate functions with/without DISTINCT +### +# SELECT COUNT(*) FROM tbl_name +select count(*) from t1; +count(*) +5 +explain select count(*) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c 5 NULL 5 Using index +# SELECT COUNT(DISTINCT <non-vcol>) FROM tbl_name +select count(distinct a) from t1; +count(distinct a) +3 +explain select count(distinct a) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +# SELECT COUNT(DISTINCT <non-stored vcol>) FROM tbl_name +select count(distinct b) from t1; +count(distinct b) +3 +explain select count(distinct b) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +# SELECT COUNT(DISTINCT <stored vcol>) FROM tbl_name +select count(distinct c) from t1; +count(distinct c) +3 +explain select count(distinct c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c 5 NULL 5 Using index +### +### filesort & range-based utils +### +# SELECT * FROM tbl_name WHERE <vcol expr> +select * from t3 where c >= -2; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where c >= -2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 2 Using where +# SELECT * FROM tbl_name WHERE <non-vcol expr> +select * from t3 where a between 1 and 2; +a b c +1 -1 -1 +2 -2 -2 +explain select * from t3 where a between 1 and 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where +# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> +select * from t3 where b between -2 and -1; +a b c +1 -1 -1 +2 -2 -2 +explain select * from t3 where b between -2 and -1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where +# SELECT * FROM tbl_name WHERE <indexed vcol expr> +select * from t3 where c between -2 and -1; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where c between -2 and -1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 2 Using where +# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <non-indexed vcol> +select * from t3 where a between 1 and 2 order by b; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where a between 1 and 2 order by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <indexed vcol> +select * from t3 where a between 1 and 2 order by c; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where a between 1 and 2 order by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-vcol> +select * from t3 where b between -2 and -1 order by a; +a b c +1 -1 -1 +2 -2 -2 +explain select * from t3 where b between -2 and -1 order by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 index NULL PRIMARY 4 NULL 3 Using where +# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-indexed vcol> +select * from t3 where b between -2 and -1 order by b; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where b between -2 and -1 order by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-indexed vcol> +select * from t3 where c between -2 and -1 order by b; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where c between -2 and -1 order by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 2 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol> +select * from t3 where b between -2 and -1 order by c; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where b between -2 and -1 order by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <indexed vcol> +select * from t3 where c between -2 and -1 order by c; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where c between -2 and -1 order by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 2 Using where +# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol> +select sum(b) from t1 group by b; +sum(b) +NULL +-3 +-2 +-2 +explain select sum(b) from t1 group by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort +# SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <indexed vcol> +select sum(c) from t1 group by c; +sum(c) +NULL +-3 +-2 +-2 +explain select sum(c) from t1 group by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c 5 NULL 5 Using index +# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <indexed vcol> +select sum(b) from t1 group by c; +sum(b) +NULL +-3 +-2 +-2 +explain select sum(b) from t1 group by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c 5 NULL 5 +# SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol> +select sum(c) from t1 group by b; +sum(c) +NULL +-3 +-2 +-2 +explain select sum(c) from t1 group by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result new file mode 100644 index 00000000000..45e4defd315 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result @@ -0,0 +1,264 @@ +SET @@session.storage_engine = 'MyISAM'; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent, +index (c)); +insert into t1 (a) values (2), (1), (1), (3), (NULL); +create table t2 like t1; +insert into t2 (a) values (1); +create table t3 (a int primary key, +b int as (-a), +c int as (-a) persistent unique); +insert into t3 (a) values (2),(1),(3); +# select_type=SIMPLE, type=system +select * from t2; +a b c +1 -1 -1 +explain select * from t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 system NULL NULL NULL NULL 1 +select * from t2 where c=-1; +a b c +1 -1 -1 +explain select * from t2 where c=-1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 system c NULL NULL NULL 1 +# select_type=SIMPLE, type=ALL +select * from t1 where b=-1; +a b c +1 -1 -1 +1 -1 -1 +explain select * from t1 where b=-1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where +# select_type=SIMPLE, type=const +select * from t3 where a=1; +a b c +1 -1 -1 +explain select * from t3 where a=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 const PRIMARY PRIMARY 4 const 1 +# select_type=SIMPLE, type=range +select * from t3 where c>=-1; +a b c +1 -1 -1 +explain select * from t3 where c>=-1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 2 Using where +# select_type=SIMPLE, type=ref +select * from t1,t3 where t1.c=t3.c and t3.c=-1; +a b c a b c +1 -1 -1 1 -1 -1 +1 -1 -1 1 -1 -1 +explain select * from t1,t3 where t1.c=t3.c and t3.c=-1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 const c c 5 const 1 +1 SIMPLE t1 ref c c 5 const 2 Using where +# select_type=PRIMARY, type=index,ALL +select * from t1 where b in (select c from t3); +a b c +2 -2 -2 +1 -1 -1 +1 -1 -1 +3 -3 -3 +explain select * from t1 where b in (select c from t3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +2 DEPENDENT SUBQUERY t3 index_subquery c c 5 func 2 Using index; Using where +# select_type=PRIMARY, type=range,ref +select * from t1 where c in (select c from t3 where c between -2 and -1); +a b c +2 -2 -2 +1 -1 -1 +1 -1 -1 +explain select * from t1 where c in (select c from t3 where c between -2 and -1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +2 DEPENDENT SUBQUERY t3 index_subquery c c 5 func 2 Using index; Using where +# select_type=UNION, type=system +# select_type=UNION RESULT, type=<union1,2> +select * from t1 union select * from t2; +a b c +2 -2 -2 +1 -1 -1 +3 -3 -3 +NULL NULL NULL +explain select * from t1 union select * from t2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 +2 UNION t2 system NULL NULL NULL NULL 1 +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +# select_type=DERIVED, type=system +select * from (select a,b,c from t1) as t11; +a b c +2 -2 -2 +1 -1 -1 +1 -1 -1 +3 -3 -3 +NULL NULL NULL +explain select * from (select a,b,c from t1) as t11; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 +2 DERIVED t1 ALL NULL NULL NULL NULL 5 +### +### Using aggregate functions with/without DISTINCT +### +# SELECT COUNT(*) FROM tbl_name +select count(*) from t1; +count(*) +5 +explain select count(*) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +# SELECT COUNT(DISTINCT <non-vcol>) FROM tbl_name +select count(distinct a) from t1; +count(distinct a) +3 +explain select count(distinct a) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +# SELECT COUNT(DISTINCT <non-stored vcol>) FROM tbl_name +select count(distinct b) from t1; +count(distinct b) +3 +explain select count(distinct b) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +# SELECT COUNT(DISTINCT <stored vcol>) FROM tbl_name +select count(distinct c) from t1; +count(distinct c) +3 +explain select count(distinct c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c 5 NULL 5 Using index +### +### filesort & range-based utils +### +# SELECT * FROM tbl_name WHERE <vcol expr> +select * from t3 where c >= -2; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where c >= -2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 2 Using where +# SELECT * FROM tbl_name WHERE <non-vcol expr> +select * from t3 where a between 1 and 2; +a b c +1 -1 -1 +2 -2 -2 +explain select * from t3 where a between 1 and 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using where +# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> +select * from t3 where b between -2 and -1; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where b between -2 and -1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where +# SELECT * FROM tbl_name WHERE <indexed vcol expr> +select * from t3 where c between -2 and -1; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where c between -2 and -1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 1 Using where +# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <indexed vcol> +select * from t3 where a between 1 and 2 order by c; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where a between 1 and 2 order by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-vcol> +select * from t3 where b between -2 and -1 order by a; +a b c +1 -1 -1 +2 -2 -2 +explain select * from t3 where b between -2 and -1 order by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-vcol> +select * from t3 where c between -2 and -1 order by a; +a b c +1 -1 -1 +2 -2 -2 +explain select * from t3 where c between -2 and -1 order by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 1 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-indexed vcol> +select * from t3 where b between -2 and -1 order by b; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where b between -2 and -1 order by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-indexed vcol> +select * from t3 where c between -2 and -1 order by b; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where c between -2 and -1 order by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 1 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol> +select * from t3 where b between -2 and -1 order by c; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where b between -2 and -1 order by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using filesort +# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <indexed vcol> +select * from t3 where c between -2 and -1 order by c; +a b c +2 -2 -2 +1 -1 -1 +explain select * from t3 where c between -2 and -1 order by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range c c 5 NULL 1 Using where +# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol> +select sum(b) from t1 group by b; +sum(b) +NULL +-3 +-2 +-2 +explain select sum(b) from t1 group by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort +# SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <indexed vcol> +select sum(c) from t1 group by c; +sum(c) +NULL +-3 +-2 +-2 +explain select sum(c) from t1 group by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c 5 NULL 5 Using index +# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <indexed vcol> +select sum(b) from t1 group by c; +sum(b) +NULL +-3 +-2 +-2 +explain select sum(b) from t1 group by c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort +# SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol> +select sum(c) from t1 group by b; +sum(c) +NULL +-3 +-2 +-2 +explain select sum(c) from t1 group by b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort diff --git a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result new file mode 100644 index 00000000000..83f755a2e7f --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result @@ -0,0 +1,2943 @@ +SET @@session.storage_engine = 'InnoDB'; +# +# NUMERIC FUNCTIONS +# +# ABS() +set sql_warnings = 1; +create table t1 (a int, b int as (abs(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (abs(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (-1, default); +select * from t1; +a b +-1 1 +drop table t1; +set sql_warnings = 0; +# ACOS() +set sql_warnings = 1; +create table t1 (a double, b double as (format(acos(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(acos(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1, default); +insert into t1 values (1.0001,default); +insert into t1 values (0,default); +select * from t1; +a b +1 0 +1.0001 NULL +0 1.570796 +drop table t1; +set sql_warnings = 0; +# ASIN() +set sql_warnings = 1; +create table t1 (a double, b double as (format(asin(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(asin(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (0.2, default); +insert into t1 values (1.0001,default); +select * from t1; +a b +0.2 0.201358 +1.0001 NULL +drop table t1; +set sql_warnings = 0; +#ATAN +set sql_warnings = 1; +create table t1 (a double, b double, c double as (format(atan(a,b),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double DEFAULT NULL, + `c` double AS (format(atan(a,b),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (-2,2,default); +insert into t1 values (format(PI(),6),0,default); +select * from t1; +a b c +-2 2 -0.785398 +3.141593 0 1.570796 +drop table t1; +set sql_warnings = 0; +set sql_warnings = 1; +create table t1 (a double, c double as (format(atan(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `c` double AS (format(atan(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (-2,default); +insert into t1 values (format(PI(),6),default); +select * from t1; +a c +-2 -1.107149 +3.141593 1.262627 +drop table t1; +set sql_warnings = 0; +# ATAN2 +set sql_warnings = 1; +create table t1 (a double, b double, c double as (format(atan2(a,b),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double DEFAULT NULL, + `c` double AS (format(atan2(a,b),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (-2,2,default); +insert into t1 values (format(PI(),6),0,default); +select * from t1; +a b c +-2 2 -0.785398 +3.141593 0 1.570796 +drop table t1; +set sql_warnings = 0; +# CEIL() +set sql_warnings = 1; +create table t1 (a double, b int as (ceil(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` int(11) AS (ceil(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1.23,default); +insert into t1 values (-1.23,default); +select * from t1; +a b +1.23 2 +-1.23 -1 +drop table t1; +set sql_warnings = 0; +# CONV() +set sql_warnings = 1; +create table t1 (a varchar(10), b int, c int, d varchar(10) as (conv(a,b,c))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` varchar(10) AS (conv(a,b,c)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('a',16,2,default); +insert into t1 values ('6e',18,8,default); +insert into t1 values (-17,10,-18,default); +insert into t1 values (10+'10'+'10'+0xa,10,10,default); +select * from t1; +a b c d +a 16 2 1010 +6e 18 8 172 +-17 10 -18 -H +40 10 10 40 +drop table t1; +set sql_warnings = 0; +# COS() +set sql_warnings = 1; +create table t1 (a double, b double as (format(cos(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(cos(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (format(PI(),6),default); +select * from t1; +a b +3.141593 -1 +drop table t1; +set sql_warnings = 0; +# COT() +set sql_warnings = 1; +create table t1 (a double, b double as (format(cot(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(cot(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (12,default); +insert into t1 values (0,default); +select * from t1; +a b +12 -1.572673 +0 NULL +drop table t1; +set sql_warnings = 0; +# CRC32() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (crc32(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (crc32(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +insert into t1 values ('mysql',default); +select * from t1; +a b +MySQL 3259397556 +mysql 2501908538 +drop table t1; +set sql_warnings = 0; +# DEGREES() +set sql_warnings = 1; +create table t1 (a double, b double as (format(degrees(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(degrees(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (format(PI(),6),default); +insert into t1 values (format(PI()/2,6),default); +select * from t1; +a b +3.141593 180.00002 +1.570796 89.999981 +drop table t1; +set sql_warnings = 0; +# / +set sql_warnings = 1; +create table t1 (a double, b double as (a/2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (a/2) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +select * from t1; +a b +2 1 +drop table t1; +set sql_warnings = 0; +# EXP() +set sql_warnings = 1; +create table t1 (a double, b double as (format(exp(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(exp(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +insert into t1 values (-2,default); +insert into t1 values (0,default); +select * from t1; +a b +2 7.389056 +-2 0.135335 +0 1 +drop table t1; +set sql_warnings = 0; +# FLOOR() +set sql_warnings = 1; +create table t1 (a double, b long as (floor(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` mediumtext AS (floor(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1.23,default); +insert into t1 values (-1.23,default); +select * from t1; +a b +1.23 1 +-1.23 -2 +drop table t1; +set sql_warnings = 0; +# LN() +set sql_warnings = 1; +create table t1 (a double, b double as (format(ln(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(ln(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +insert into t1 values (-2,default); +select * from t1; +a b +2 0.693147 +-2 NULL +drop table t1; +set sql_warnings = 0; +# LOG() +set sql_warnings = 1; +create table t1 (a double, b double, c double as (format(log(a,b),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double DEFAULT NULL, + `c` double AS (format(log(a,b),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (2,65536,default); +insert into t1 values (10,100,default); +insert into t1 values (1,100,default); +select * from t1; +a b c +2 65536 16 +10 100 2 +1 100 NULL +drop table t1; +set sql_warnings = 0; +set sql_warnings = 1; +create table t1 (a double, b double as (format(log(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(log(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +insert into t1 values (-2,default); +select * from t1; +a b +2 0.693147 +-2 NULL +drop table t1; +set sql_warnings = 0; +# LOG2() +set sql_warnings = 1; +create table t1 (a double, b double as (format(log2(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(log2(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (65536,default); +insert into t1 values (-100,default); +select * from t1; +a b +65536 16 +-100 NULL +drop table t1; +set sql_warnings = 0; +# LOG10() +set sql_warnings = 1; +create table t1 (a double, b double as (format(log10(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(log10(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +insert into t1 values (100,default); +insert into t1 values (-100,default); +select * from t1; +a b +2 0.30103 +100 2 +-100 NULL +drop table t1; +set sql_warnings = 0; +# - +set sql_warnings = 1; +create table t1 (a double, b double as (a-1)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (a-1) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +select * from t1; +a b +2 1 +drop table t1; +set sql_warnings = 0; +# MOD() +set sql_warnings = 1; +create table t1 (a int, b int as (mod(a,10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (mod(a,10)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (11,default); +select * from t1; +a b +1 1 +11 1 +drop table t1; +set sql_warnings = 0; +# % +set sql_warnings = 1; +create table t1 (a int, b int as (a % 10)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 10) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (11,default); +select * from t1; +a b +1 1 +11 1 +drop table t1; +set sql_warnings = 0; +# OCT() +set sql_warnings = 1; +create table t1 (a double, b varchar(10) as (oct(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` varchar(10) AS (oct(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (12,default); +select * from t1; +a b +12 14 +drop table t1; +set sql_warnings = 0; +# PI() +set sql_warnings = 1; +create table t1 (a double, b double as (format(PI()*a*a,6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(PI()*a*a,6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +select * from t1; +a b +1 3.141593 +drop table t1; +set sql_warnings = 0; +# + +set sql_warnings = 1; +create table t1 (a int, b int as (a+1)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a+1) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +select * from t1; +a b +1 2 +drop table t1; +set sql_warnings = 0; +# POW, POWER +set sql_warnings = 1; +create table t1 (a int, b int as (pow(a,2)), c int as (power(a,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (pow(a,2)) VIRTUAL, + `c` int(11) AS (power(a,2)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default,default); +insert into t1 values (2,default,default); +select * from t1; +a b c +1 1 1 +2 4 4 +drop table t1; +set sql_warnings = 0; +# RADIANS() +set sql_warnings = 1; +create table t1 (a double, b double as (format(radians(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(radians(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (90,default); +select * from t1; +a b +90 1.570796 +drop table t1; +set sql_warnings = 0; +# ROUND() +set sql_warnings = 1; +create table t1 (a double, b int as (round(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` int(11) AS (round(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (-1.23,default); +insert into t1 values (-1.58,default); +insert into t1 values (1.58,default); +select * from t1; +a b +-1.23 -1 +-1.58 -2 +1.58 2 +drop table t1; +set sql_warnings = 0; +set sql_warnings = 1; +create table t1 (a double, b double, c int as (round(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double DEFAULT NULL, + `c` int(11) AS (round(a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1.298,1,default); +insert into t1 values (1.298,0,default); +insert into t1 values (23.298,-1,default); +select * from t1; +a b c +1.298 1 1 +1.298 0 1 +23.298 -1 20 +drop table t1; +set sql_warnings = 0; +# SIGN() +set sql_warnings = 1; +create table t1 (a double, b int as (sign(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` int(11) AS (sign(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (-32,default); +insert into t1 values (0,default); +insert into t1 values (234,default); +select * from t1; +a b +-32 -1 +0 0 +234 1 +drop table t1; +set sql_warnings = 0; +# SIN() +set sql_warnings = 1; +create table t1 (a double, b double as (format(sin(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(sin(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (format(PI()/2,6),default); +select * from t1; +a b +1.570796 1 +drop table t1; +set sql_warnings = 0; +# SQRT() +set sql_warnings = 1; +create table t1 (a double, b double as (format(sqrt(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(sqrt(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (4,default); +insert into t1 values (20,default); +insert into t1 values (-16,default); +select * from t1; +a b +4 2 +20 4.472136 +-16 NULL +drop table t1; +set sql_warnings = 0; +# TAN() +set sql_warnings = 1; +create table t1 (a double, b double as (format(tan(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(tan(a),6)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (format(PI(),6),default); +insert into t1 values (format(PI()+1,6),default); +select * from t1; +a b +3.141593 0 +4.141593 1.557409 +drop table t1; +set sql_warnings = 0; +# * +set sql_warnings = 1; +create table t1 (a double, b double as (a*3)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (a*3) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (0,default); +insert into t1 values (1,default); +insert into t1 values (2,default); +select * from t1; +a b +0 0 +1 3 +2 6 +drop table t1; +set sql_warnings = 0; +# TRUNCATE() +set sql_warnings = 1; +create table t1 (a double, b double as (truncate(a,4))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (truncate(a,4)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1.223,default); +insert into t1 values (1.999,default); +insert into t1 values (1.999,default); +insert into t1 values (122,default); +select * from t1; +a b +1.223 1.223 +1.999 1.999 +1.999 1.999 +122 122 +drop table t1; +set sql_warnings = 0; +# Unary - +set sql_warnings = 1; +create table t1 (a double, b double as (-a)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (-a) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (-1,default); +select * from t1; +a b +1 -1 +-1 1 +drop table t1; +set sql_warnings = 0; +# +# STRING FUNCTIONS +# +# ASCII() +set sql_warnings = 1; +create table t1 (a char(2), b int as (ascii(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(2) DEFAULT NULL, + `b` int(11) AS (ascii(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2',default); +insert into t1 values (2,default); +insert into t1 values ('dx',default); +select * from t1; +a b +2 50 +2 50 +dx 100 +drop table t1; +set sql_warnings = 0; +# BIN() +set sql_warnings = 1; +create table t1 (a int, b varchar(10) as (bin(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(10) AS (bin(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (12,default); +select * from t1; +a b +12 1100 +drop table t1; +set sql_warnings = 0; +# BIT_LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (bit_length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (bit_length(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 32 +drop table t1; +set sql_warnings = 0; +# CHAR_LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (char_length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (char_length(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 4 +drop table t1; +set sql_warnings = 0; +# CHAR() +set sql_warnings = 1; +create table t1 (a int, b int, c varbinary(10) as (char(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` varbinary(10) AS (char(a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (77,121,default); +select * from t1; +a b c +77 121 My +drop table t1; +set sql_warnings = 0; +# CHARACTER_LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (character_length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (character_length(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 4 +drop table t1; +set sql_warnings = 0; +# CONCAT_WS() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c varchar(20) as (concat_ws(',',a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` varchar(20) AS (concat_ws(',',a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('value1','value2',default); +select * from t1; +a b c +value1 value2 value1,value2 +drop table t1; +set sql_warnings = 0; +# CONCAT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c varchar(20) as (concat(a,',',b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` varchar(20) AS (concat(a,',',b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('value1','value2',default); +select * from t1; +a b c +value1 value2 value1,value2 +drop table t1; +set sql_warnings = 0; +# ELT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int, d varchar(10) as (elt(c,a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` varchar(10) AS (elt(c,a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('value1','value2',1,default); +insert into t1 values ('value1','value2',2,default); +select * from t1; +a b c d +value1 value2 1 value1 +value1 value2 2 value2 +drop table t1; +set sql_warnings = 0; +# EXPORT_SET() +set sql_warnings = 1; +create table t1 (a int, b varchar(10) as (export_set(a,'1','0','',10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(10) AS (export_set(a,'1','0','',10)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (6,default); +select * from t1; +a b +6 0110000000 +drop table t1; +set sql_warnings = 0; +# FIELD() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int as (field('aa',a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) AS (field('aa',a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('aa','bb',default); +insert into t1 values ('bb','aa',default); +select * from t1; +a b c +aa bb 1 +bb aa 2 +drop table t1; +set sql_warnings = 0; +# FIND_IN_SET() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int as (find_in_set(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) AS (find_in_set(a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('aa','aa,bb,cc',default); +insert into t1 values ('aa','bb,aa,cc',default); +select * from t1; +a b c +aa aa,bb,cc 1 +aa bb,aa,cc 2 +drop table t1; +set sql_warnings = 0; +# FORMAT() +set sql_warnings = 1; +create table t1 (a double, b varchar(20) as (format(a,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` varchar(20) AS (format(a,2)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (12332.123456,default); +select * from t1; +a b +12332.123456 12,332.12 +drop table t1; +set sql_warnings = 0; +# HEX() +set sql_warnings = 1; +create table t1 (a int, b varchar(10) as (hex(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(10) AS (hex(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (17,default); +select * from t1; +a b +17 11 +drop table t1; +set sql_warnings = 0; +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (hex(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (hex(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc 616263 +drop table t1; +set sql_warnings = 0; +# INSERT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c varchar(20) as (insert(a,length(a),length(b),b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` varchar(20) AS (insert(a,length(a),length(b),b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('start,','end',default); +select * from t1; +a b c +start, end startend +drop table t1; +set sql_warnings = 0; +# INSTR() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int as (instr(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) AS (instr(a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar,','bar',default); +insert into t1 values ('xbar,','foobar',default); +select * from t1; +a b c +foobarbar, bar 4 +xbar, foobar 0 +drop table t1; +set sql_warnings = 0; +# LCASE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (lcase(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (lcase(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL mysql +drop table t1; +set sql_warnings = 0; +# LEFT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(5) as (left(a,5))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(5) AS (left(a,5)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar fooba +drop table t1; +set sql_warnings = 0; +# LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b int as (length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` int(11) AS (length(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 4 +drop table t1; +set sql_warnings = 0; +# LIKE +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a like 'H%!o' escape '!')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a like 'H%!o' escape '!') VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('MySQL',default); +select * from t1; +a b +Hello 1 +MySQL 0 +drop table t1; +set sql_warnings = 0; +# LOCATE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (locate('bar',a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (locate('bar',a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar 4 +drop table t1; +set sql_warnings = 0; +# LOWER() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (lower(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (lower(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL mysql +drop table t1; +set sql_warnings = 0; +# LPAD() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (lpad(a,4,' '))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (lpad(a,4,' ')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +insert into t1 values ('M',default); +select * from t1; +a b +MySQL MySQ +M M +drop table t1; +set sql_warnings = 0; +# LTRIM() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (ltrim(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (ltrim(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (' MySQL',default); +insert into t1 values ('MySQL',default); +select * from t1; +a b + MySQL MySQL +MySQL MySQL +drop table t1; +set sql_warnings = 0; +# MAKE_SET() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int, d varchar(30) as (make_set(c,a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` varchar(30) AS (make_set(c,a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('a','b',1,default); +insert into t1 values ('a','b',3,default); +select * from t1; +a b c d +a b 1 a +a b 3 a,b +drop table t1; +set sql_warnings = 0; +# MID() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (mid(a,1,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (mid(a,1,2)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar fo +drop table t1; +set sql_warnings = 0; +# NOT LIKE +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a not like 'H%o')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a not like 'H%o') VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('MySQL',default); +select * from t1; +a b +Hello 0 +MySQL 1 +drop table t1; +set sql_warnings = 0; +# NOT REGEXP +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a not regexp 'H.+o')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a not regexp 'H.+o') VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('hello',default); +select * from t1; +a b +Hello 0 +hello 0 +drop table t1; +set sql_warnings = 0; +# OCTET_LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b int as (octet_length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` int(11) AS (octet_length(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 4 +drop table t1; +set sql_warnings = 0; +# ORD() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (ord(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (ord(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2',default); +select * from t1; +a b +2 50 +drop table t1; +set sql_warnings = 0; +# POSITION() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (position('bar' in a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (position('bar' in a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar 4 +drop table t1; +set sql_warnings = 0; +# QUOTE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (quote(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (quote(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Don\'t',default); +select * from t1; +a b +Don't 'Don\'t' +drop table t1; +set sql_warnings = 0; +# REGEXP() +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a regexp 'H.+o')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a regexp 'H.+o') VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('hello',default); +select * from t1; +a b +Hello 1 +hello 1 +drop table t1; +set sql_warnings = 0; +# REPEAT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(30) as (repeat(a,3))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(30) AS (repeat(a,3)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MySQLMySQLMySQL +drop table t1; +set sql_warnings = 0; +# REPLACE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(30) as (replace(a,'aa','bb'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(30) AS (replace(a,'aa','bb')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('maa',default); +select * from t1; +a b +maa mbb +drop table t1; +set sql_warnings = 0; +# REVERSE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(30) as (reverse(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(30) AS (reverse(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('maa',default); +select * from t1; +a b +maa aam +drop table t1; +set sql_warnings = 0; +# RIGHT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (right(a,4))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (right(a,4)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar rbar +drop table t1; +set sql_warnings = 0; +# RLIKE() +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a rlike 'H.+o')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a rlike 'H.+o') VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('MySQL',default); +select * from t1; +a b +Hello 1 +MySQL 0 +drop table t1; +set sql_warnings = 0; +# RPAD() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (rpad(a,4,'??'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (rpad(a,4,'??')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('He',default); +select * from t1; +a b +He He?? +drop table t1; +set sql_warnings = 0; +# RTRIM(); +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (rtrim(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (rtrim(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello ',default); +select * from t1; +a b +Hello Hello +drop table t1; +set sql_warnings = 0; +# SOUNDEX() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(20) as (soundex(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(20) AS (soundex(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +select * from t1; +a b +Hello H400 +drop table t1; +set sql_warnings = 0; +# SOUNDS LIKE +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a sounds like b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a sounds like b) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello','Hello',default); +insert into t1 values ('Hello','MySQL',default); +insert into t1 values ('Hello','hello',default); +select * from t1; +a b c +Hello Hello 1 +Hello MySQL 0 +Hello hello 1 +drop table t1; +set sql_warnings = 0; +# SPACE() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (concat(a,space(5)))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (concat(a,space(5))) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello', default); +select * from t1; +a b +Hello Hello +drop table t1; +set sql_warnings = 0; +# STRCMP() +set sql_warnings = 1; +create table t1 (a varchar(9), b varchar(9), c tinyint(1) as (strcmp(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(9) DEFAULT NULL, + `b` varchar(9) DEFAULT NULL, + `c` tinyint(1) AS (strcmp(a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello','Hello', default); +insert into t1 values ('Hello','Hello1', default); +select * from t1; +a b c +Hello Hello 0 +Hello Hello1 -1 +drop table t1; +set sql_warnings = 0; +# SUBSTR() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (substr(a,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (substr(a,2)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +select * from t1; +a b +Hello ello +drop table t1; +set sql_warnings = 0; +# SUBSTRING_INDEX() +set sql_warnings = 1; +create table t1 (a varchar(15), b varchar(10) as (substring_index(a,'.',2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(15) DEFAULT NULL, + `b` varchar(10) AS (substring_index(a,'.',2)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('www.mysql.com',default); +select * from t1; +a b +www.mysql.com www.mysql +drop table t1; +set sql_warnings = 0; +# SUBSTRING() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (substring(a from 2 for 2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (substring(a from 2 for 2)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +select * from t1; +a b +Hello el +drop table t1; +set sql_warnings = 0; +# TRIM() +set sql_warnings = 1; +create table t1 (a varchar(15), b varchar(10) as (trim(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(15) DEFAULT NULL, + `b` varchar(10) AS (trim(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (' aa ',default); +select * from t1; +a b + aa aa +drop table t1; +set sql_warnings = 0; +# UCASE() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (ucase(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (ucase(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MYSQL +drop table t1; +set sql_warnings = 0; +# UNHEX() +set sql_warnings = 1; +create table t1 (a varchar(15), b varchar(10) as (unhex(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(15) DEFAULT NULL, + `b` varchar(10) AS (unhex(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('4D7953514C',default); +select * from t1; +a b +4D7953514C MySQL +drop table t1; +set sql_warnings = 0; +# UPPER() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (upper(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (upper(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MYSQL +drop table t1; +set sql_warnings = 0; +# +# CONTROL FLOW FUNCTIONS +# +# CASE +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(16) as (case a when NULL then 'asd' when 'b' then 'B' else a end)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(16) AS (case a when NULL then 'asd' when 'b' then 'B' else a end) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (NULL,default); +insert into t1 values ('b',default); +insert into t1 values ('c',default); +select * from t1; +a b +NULL NULL +b B +c c +drop table t1; +set sql_warnings = 0; +# IF +set sql_warnings = 1; +create table t1 (a int, b int, c int as (if(a=1,a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS (if(a=1,a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,2,default); +insert into t1 values (3,4,default); +select * from t1; +a b c +1 2 1 +3 4 4 +drop table t1; +set sql_warnings = 0; +# IFNULL +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c varchar(10) as (ifnull(a,'DEFAULT'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` varchar(10) AS (ifnull(a,'DEFAULT')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (NULL,'adf',default); +insert into t1 values ('a','adf',default); +select * from t1; +a b c +NULL adf DEFAULT +a adf a +drop table t1; +set sql_warnings = 0; +# NULLIF +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (nullif(a,'DEFAULT'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (nullif(a,'DEFAULT')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('DEFAULT',default); +insert into t1 values ('a',default); +select * from t1; +a b +DEFAULT NULL +a a +drop table t1; +set sql_warnings = 0; +# +# OPERATORS +# +# AND, && +set sql_warnings = 1; +create table t1 (a int, b bool as (a>0 && a<2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a>0 && a<2) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (-1,default); +insert into t1 values (1,default); +select * from t1; +a b +-1 0 +1 1 +drop table t1; +set sql_warnings = 0; +# BETWEEN ... AND ... +set sql_warnings = 1; +create table t1 (a int, b bool as (a between 0 and 2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a between 0 and 2) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (-1,default); +insert into t1 values (1,default); +select * from t1; +a b +-1 0 +1 1 +drop table t1; +set sql_warnings = 0; +# BINARY +set sql_warnings = 1; +create table t1 (a varchar(10), b varbinary(10) as (binary a)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varbinary(10) AS (binary a) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('11',default); +insert into t1 values (1,default); +select * from t1; +a b +11 11 +1 1 +drop table t1; +set sql_warnings = 0; +# & +set sql_warnings = 1; +create table t1 (a int, b int as (a & 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a & 5) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (0,default); +select * from t1; +a b +1 1 +0 0 +drop table t1; +set sql_warnings = 0; +# ~ +set sql_warnings = 1; +create table t1 (a int, b int as (~a)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (~a) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 +select * from t1; +a b +1 2147483647 +drop table t1; +set sql_warnings = 0; +# | +set sql_warnings = 1; +create table t1 (a int, b int as (a | 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a | 5) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (0,default); +insert into t1 values (2,default); +select * from t1; +a b +1 5 +0 5 +2 7 +drop table t1; +set sql_warnings = 0; +# ^ +set sql_warnings = 1; +create table t1 (a int, b int as (a ^ 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a ^ 5) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (0,default); +insert into t1 values (2,default); +select * from t1; +a b +1 4 +0 5 +2 7 +drop table t1; +set sql_warnings = 0; +# DIV +set sql_warnings = 1; +create table t1 (a int, b int as (a div 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a div 5) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (7,default); +select * from t1; +a b +1 0 +7 1 +drop table t1; +set sql_warnings = 0; +# <=> +set sql_warnings = 1; +create table t1 (a int, b int, c bool as (a <=> b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` tinyint(1) AS (a <=> b) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,1,default); +insert into t1 values (NULL,NULL,default); +insert into t1 values (1,NULL,default); +select * from t1; +a b c +1 1 1 +NULL NULL 1 +1 NULL 0 +drop table t1; +set sql_warnings = 0; +# = +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a=b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a=b) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('a','b',default); +insert into t1 values ('a','a',default); +select * from t1; +a b c +a b 0 +a a 1 +drop table t1; +set sql_warnings = 0; +# >= +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a >= b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a >= b) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('a','b',default); +insert into t1 values ('a','a',default); +select * from t1; +a b c +a b 0 +a a 1 +drop table t1; +set sql_warnings = 0; +# > +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a > b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a > b) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('a','b',default); +insert into t1 values ('a','a',default); +select * from t1; +a b c +a b 0 +a a 0 +drop table t1; +set sql_warnings = 0; +# IS NOT NULL +set sql_warnings = 1; +create table t1 (a int, b bool as (a is not null)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a is not null) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (NULL,default); +select * from t1; +a b +1 1 +NULL 0 +drop table t1; +set sql_warnings = 0; +# IS NULL +set sql_warnings = 1; +create table t1 (a int, b bool as (a is null)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a is null) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (NULL,default); +select * from t1; +a b +1 0 +NULL 1 +drop table t1; +set sql_warnings = 0; +# << +set sql_warnings = 1; +create table t1 (a int, b int as (a << 2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a << 2) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (3,default); +select * from t1; +a b +1 4 +3 12 +drop table t1; +set sql_warnings = 0; +# <= +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a <= b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a <= b) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('b','a',default); +insert into t1 values ('b','b',default); +insert into t1 values ('b','c',default); +select * from t1; +a b c +b a 0 +b b 1 +b c 1 +drop table t1; +set sql_warnings = 0; +# < +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a < b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a < b) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('b','a',default); +insert into t1 values ('b','b',default); +insert into t1 values ('b','c',default); +select * from t1; +a b c +b a 0 +b b 0 +b c 1 +drop table t1; +set sql_warnings = 0; +# NOT BETWEEN ... AND ... +set sql_warnings = 1; +create table t1 (a int, b bool as (a not between 0 and 2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a not between 0 and 2) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (-1,default); +insert into t1 values (1,default); +select * from t1; +a b +-1 1 +1 0 +drop table t1; +set sql_warnings = 0; +# <> +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a <> b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a <> b) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('b','a',default); +insert into t1 values ('b','b',default); +insert into t1 values ('b','c',default); +select * from t1; +a b c +b a 1 +b b 0 +b c 1 +drop table t1; +set sql_warnings = 0; +# != +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a != b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a != b) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('b','a',default); +insert into t1 values ('b','b',default); +insert into t1 values ('b','c',default); +select * from t1; +a b c +b a 1 +b b 0 +b c 1 +drop table t1; +set sql_warnings = 0; +# ||, OR +set sql_warnings = 1; +create table t1 (a int, b int as (a>5 || a<3)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a>5 || a<3) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (4,default); +select * from t1; +a b +1 1 +4 0 +drop table t1; +set sql_warnings = 0; +# >> +set sql_warnings = 1; +create table t1 (a int, b int as (a >> 2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a >> 2) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (8,default); +insert into t1 values (3,default); +select * from t1; +a b +8 2 +3 0 +drop table t1; +set sql_warnings = 0; +# XOR +set sql_warnings = 1; +create table t1 (a int, b int as (a xor 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a xor 5) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (0,default); +insert into t1 values (1,default); +insert into t1 values (2,default); +select * from t1; +a b +0 1 +1 0 +2 0 +drop table t1; +set sql_warnings = 0; +# +# DATE AND TIME FUNCTIONS +# +# ADDDATE() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (adddate(a,interval 1 month))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (adddate(a,interval 1 month)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-09-30 00:00:00 +drop table t1; +set sql_warnings = 0; +# ADDTIME() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (addtime(a,'02:00:00'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (addtime(a,'02:00:00')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-08-31 02:00:00 +drop table t1; +set sql_warnings = 0; +# CONVERT_TZ() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (convert_tz(a,'MET','UTC'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (convert_tz(a,'MET','UTC')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-08-30 22:00:00 +drop table t1; +set sql_warnings = 0; +# DATE_ADD() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (date_add(a,interval 1 month))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (date_add(a,interval 1 month)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-09-30 00:00:00 +drop table t1; +set sql_warnings = 0; +# DATE_FORMAT() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(64) as (date_format(a,'%W %M %D'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(64) AS (date_format(a,'%W %M %D')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 Sunday August 31st +drop table t1; +set sql_warnings = 0; +# DATE_SUB() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (date_sub(a,interval 1 month))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (date_sub(a,interval 1 month)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-07-31 00:00:00 +drop table t1; +set sql_warnings = 0; +# DATE() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (date(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (date(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31 02:00:00',default); +select * from t1; +a b +2008-08-31 02:00:00 2008-08-31 00:00:00 +drop table t1; +set sql_warnings = 0; +# DATEDIFF() +set sql_warnings = 1; +create table t1 (a datetime, b long as (datediff(a,'2000-01-01'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` mediumtext AS (datediff(a,'2000-01-01')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 3165 +drop table t1; +set sql_warnings = 0; +# DAY() +set sql_warnings = 1; +create table t1 (a datetime, b int as (day(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (day(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 31 +drop table t1; +set sql_warnings = 0; +# DAYNAME() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(10) as (dayname(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(10) AS (dayname(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 Sunday +drop table t1; +set sql_warnings = 0; +# DAYOFMONTH() +set sql_warnings = 1; +create table t1 (a datetime, b int as (dayofmonth(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (dayofmonth(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 31 +drop table t1; +set sql_warnings = 0; +# DAYOFWEEK() +set sql_warnings = 1; +create table t1 (a datetime, b int as (dayofweek(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (dayofweek(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 1 +drop table t1; +set sql_warnings = 0; +# DAYOFYEAR() +set sql_warnings = 1; +create table t1 (a datetime, b int as (dayofyear(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (dayofyear(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 244 +drop table t1; +set sql_warnings = 0; +# EXTRACT +set sql_warnings = 1; +create table t1 (a datetime, b int as (extract(year from a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (extract(year from a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008 +drop table t1; +set sql_warnings = 0; +# FROM_DAYS() +set sql_warnings = 1; +create table t1 (a long, b datetime as (from_days(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` mediumtext, + `b` datetime AS (from_days(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (730669,default); +select * from t1; +a b +730669 2000-07-03 00:00:00 +drop table t1; +set sql_warnings = 0; +# FROM_UNIXTIME() +set time_zone='UTC'; +set sql_warnings = 1; +create table t1 (a long, b datetime as (from_unixtime(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` mediumtext, + `b` datetime AS (from_unixtime(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1196440219,default); +select * from t1; +a b +1196440219 2007-11-30 16:30:19 +drop table t1; +set sql_warnings = 0; +# GET_FORMAT() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(32) as (date_format(a,get_format(DATE,'EUR')))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(32) AS (date_format(a,get_format(DATE,'EUR'))) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 31.08.2008 +drop table t1; +set sql_warnings = 0; +# HOUR() +set sql_warnings = 1; +create table t1 (a time, b long as (hour(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` time DEFAULT NULL, + `b` mediumtext AS (hour(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('10:05:03',default); +select * from t1; +a b +10:05:03 10 +drop table t1; +set sql_warnings = 0; +# LAST_DAY() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (last_day(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (last_day(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2003-02-05',default); +insert into t1 values ('2003-02-32',default); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a b +2003-02-05 00:00:00 2003-02-28 00:00:00 +0000-00-00 00:00:00 NULL +drop table t1; +set sql_warnings = 0; +# MAKEDATE() +set sql_warnings = 1; +create table t1 (a int, b datetime as (makedate(a,1))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` datetime AS (makedate(a,1)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (2001,default); +select * from t1; +a b +2001 2001-01-01 00:00:00 +drop table t1; +set sql_warnings = 0; +# MAKETIME() +set sql_warnings = 1; +create table t1 (a int, b time as (maketime(a,1,3))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` time AS (maketime(a,1,3)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (12,default); +select * from t1; +a b +12 12:01:03 +drop table t1; +set sql_warnings = 0; +# MICROSECOND() +set sql_warnings = 1; +create table t1 (a datetime, b long as (microsecond(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` mediumtext AS (microsecond(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2009-12-31 12:00:00.123456',default); +insert into t1 values ('2009-12-31 23:59:59.000010',default); +select * from t1; +a b +2009-12-31 12:00:00 0 +2009-12-31 23:59:59 0 +drop table t1; +set sql_warnings = 0; +# MINUTE() +set sql_warnings = 1; +create table t1 (a datetime, b int as (minute(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (minute(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2009-12-31 23:59:59.000010',default); +select * from t1; +a b +2009-12-31 23:59:59 59 +drop table t1; +set sql_warnings = 0; +# MONTH() +set sql_warnings = 1; +create table t1 (a datetime, b int as (month(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (month(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2009-12-31 23:59:59.000010',default); +select * from t1; +a b +2009-12-31 23:59:59 12 +drop table t1; +set sql_warnings = 0; +# MONTHNAME() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(16) as (monthname(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(16) AS (monthname(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2009-12-31 23:59:59.000010',default); +select * from t1; +a b +2009-12-31 23:59:59 December +drop table t1; +set sql_warnings = 0; +# PERIOD_ADD() +set sql_warnings = 1; +create table t1 (a int, b int as (period_add(a,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (period_add(a,2)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (200801,default); +select * from t1; +a b +200801 200803 +drop table t1; +set sql_warnings = 0; +# PERIOD_DIFF() +set sql_warnings = 1; +create table t1 (a int, b int, c int as (period_diff(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS (period_diff(a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (200802,200703,default); +select * from t1; +a b c +200802 200703 11 +drop table t1; +set sql_warnings = 0; +# QUARTER() +set sql_warnings = 1; +create table t1 (a datetime, b int as (quarter(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (quarter(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 3 +drop table t1; +set sql_warnings = 0; +# SEC_TO_TIME() +set sql_warnings = 1; +create table t1 (a long, b time as (sec_to_time(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` mediumtext, + `b` time AS (sec_to_time(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (2378,default); +select * from t1; +a b +2378 00:39:38 +drop table t1; +set sql_warnings = 0; +# SECOND() +set sql_warnings = 1; +create table t1 (a datetime, b int as (second(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (second(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('10:05:03',default); +select * from t1; +a b +2010-05-03 00:00:00 0 +drop table t1; +set sql_warnings = 0; +# STR_TO_DATE() +set sql_warnings = 1; +create table t1 (a varchar(64), b datetime as (str_to_date(a,'%m/%d/%Y'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(64) DEFAULT NULL, + `b` datetime AS (str_to_date(a,'%m/%d/%Y')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('04/30/2004',default); +select * from t1; +a b +04/30/2004 2004-04-30 00:00:00 +drop table t1; +set sql_warnings = 0; +# SUBDATE() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (subdate(a,interval 1 month))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (subdate(a,interval 1 month)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-07-31 00:00:00 +drop table t1; +set sql_warnings = 0; +# SUBTIME() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (subtime(a,'02:00:00'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (subtime(a,'02:00:00')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-08-30 22:00:00 +drop table t1; +set sql_warnings = 0; +# TIME_FORMAT() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(32) as (time_format(a,'%r'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(32) AS (time_format(a,'%r')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31 02:03:04',default); +select * from t1; +a b +2008-08-31 02:03:04 02:03:04 AM +drop table t1; +set sql_warnings = 0; +# TIME_TO_SEC() +set sql_warnings = 1; +create table t1 (a time, b long as (time_to_sec(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` time DEFAULT NULL, + `b` mediumtext AS (time_to_sec(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('22:23:00',default); +select * from t1; +a b +22:23:00 80580 +drop table t1; +set sql_warnings = 0; +# TIME() +set sql_warnings = 1; +create table t1 (a datetime, b time as (time(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` time AS (time(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31 02:03:04',default); +select * from t1; +a b +2008-08-31 02:03:04 02:03:04 +drop table t1; +set sql_warnings = 0; +# TIMEDIFF() +set sql_warnings = 1; +create table t1 (a datetime, b datetime, c long as (timediff(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime DEFAULT NULL, + `c` mediumtext AS (timediff(a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002',default); +select * from t1; +a b c +2008-12-31 23:59:59 2008-12-30 01:01:01 46:58:58 +drop table t1; +set sql_warnings = 0; +# TIMESTAMP() +set sql_warnings = 1; +create table t1 (a datetime, b timestamp as (timestamp(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` timestamp AS (timestamp(a)) VIRTUAL NULL ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-12-31',default); +select * from t1; +a b +2008-12-31 00:00:00 2008-12-31 00:00:00 +drop table t1; +set sql_warnings = 0; +# TIMESTAMPADD() +set sql_warnings = 1; +create table t1 (a datetime, b timestamp as (timestampadd(minute,1,a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` timestamp AS (timestampadd(minute,1,a)) VIRTUAL NULL ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2003-01-02',default); +select * from t1; +a b +2003-01-02 00:00:00 2003-01-02 00:01:00 +drop table t1; +set sql_warnings = 0; +# TIMESTAMPDIFF() +set sql_warnings = 1; +create table t1 (a timestamp, b timestamp, c long as (timestampdiff(MONTH, a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `b` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `c` mediumtext AS (timestampdiff(MONTH, a,b)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2003-02-01','2003-05-01',default); +select * from t1; +a b c +2003-02-01 00:00:00 2003-05-01 00:00:00 3 +drop table t1; +set sql_warnings = 0; +# TO_DAYS() +set sql_warnings = 1; +create table t1 (a datetime, b long as (to_days(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` mediumtext AS (to_days(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2007-10-07',default); +select * from t1; +a b +2007-10-07 00:00:00 733321 +drop table t1; +set sql_warnings = 0; +# WEEK() +set sql_warnings = 1; +create table t1 (a datetime, b int as (week(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (week(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 35 +drop table t1; +set sql_warnings = 0; +# WEEKDAY() +set sql_warnings = 1; +create table t1 (a datetime, b int as (weekday(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (weekday(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 0 +drop table t1; +set sql_warnings = 0; +# WEEKOFYEAR() +set sql_warnings = 1; +create table t1 (a datetime, b int as (weekofyear(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (weekofyear(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 36 +drop table t1; +set sql_warnings = 0; +# YEAR() +set sql_warnings = 1; +create table t1 (a datetime, b int as (year(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (year(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 2008 +drop table t1; +set sql_warnings = 0; +# YEARWEEK() +set sql_warnings = 1; +create table t1 (a datetime, b int as (yearweek(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (yearweek(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 200835 +drop table t1; +set sql_warnings = 0; +# +# FULL TEXT SEARCH FUNCTIONS +# +# None. +# +# CAST FUNCTIONS AND OPERATORS +# +# CAST() +set sql_warnings = 1; +create table t1 (a int, b long as (cast(a as unsigned))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` mediumtext AS (cast(a as unsigned)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (-1,default); +select * from t1; +a b +1 1 +-1 18446744073709551615 +drop table t1; +set sql_warnings = 0; +# Convert() +set sql_warnings = 1; +create table t1 (a int, b long as (convert(a,unsigned))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` mediumtext AS (convert(a,unsigned)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (-1,default); +select * from t1; +a b +1 1 +-1 18446744073709551615 +drop table t1; +set sql_warnings = 0; +# +# XML FUNCTIONS +# +# None. +# +# OTHER FUNCTIONS +# +# AES_DECRYPT(), AES_ENCRYPT() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (aes_encrypt(aes_decrypt(a,'adf'),'adf'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (aes_encrypt(aes_decrypt(a,'adf'),'adf')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL NULL +drop table t1; +set sql_warnings = 0; +# BIT_COUNT() +set sql_warnings = 1; +create table t1 (a int, b int as (bit_count(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (bit_count(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values (5,default); +select * from t1; +a b +5 2 +drop table t1; +set sql_warnings = 0; +# CHARSET() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (charset(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (charset(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc latin1 +drop table t1; +set sql_warnings = 0; +# COERCIBILITY() +set sql_warnings = 1; +create table t1 (a varchar(1024), b int as (coercibility(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` int(11) AS (coercibility(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc 2 +drop table t1; +set sql_warnings = 0; +# COLLATION() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (collation(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (collation(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc latin1_swedish_ci +drop table t1; +set sql_warnings = 0; +# COMPRESS(), UNCOMPRESS() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (uncompress(compress(a)))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (uncompress(compress(a))) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MySQL +drop table t1; +set sql_warnings = 0; +# ENCODE(), DECODE() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (decode(encode(a,'abc'),'abc'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (decode(encode(a,'abc'),'abc')) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MySQL +drop table t1; +set sql_warnings = 0; +# DEFAULT() +set sql_warnings = 1; +create table t1 (a varchar(1024) default 'aaa', b varchar(1024) as (ifnull(a,default(a)))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT 'aaa', + `b` varchar(1024) AS (ifnull(a,default(a))) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('any value',default); +select * from t1; +a b +any value any value +drop table t1; +set sql_warnings = 0; +# INET_ATON(), INET_NTOA() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (inet_ntoa(inet_aton(a)))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (inet_ntoa(inet_aton(a))) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('127.0.0.1',default); +select * from t1; +a b +127.0.0.1 127.0.0.1 +drop table t1; +set sql_warnings = 0; +# MD5() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varbinary(32) as (md5(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varbinary(32) AS (md5(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('testing',default); +select * from t1; +a b +testing ae2b1fca515949e5d54fb22b8ed95575 +drop table t1; +set sql_warnings = 0; +# OLD_PASSWORD() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (old_password(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (old_password(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('badpwd',default); +select * from t1; +a b +badpwd 7f84554057dd964b +drop table t1; +set sql_warnings = 0; +# PASSWORD() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (password(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (password(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('badpwd',default); +select * from t1; +a b +badpwd *AAB3E285149C0135D51A520E1940DD3263DC008C +drop table t1; +set sql_warnings = 0; +# SHA1() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (sha1(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (sha1(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc a9993e364706816aba3e25717850c26c9cd0d89d +drop table t1; +set sql_warnings = 0; +# SHA() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (sha(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (sha(a)) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc a9993e364706816aba3e25717850c26c9cd0d89d +drop table t1; +set sql_warnings = 0; +# UNCOMPRESSED_LENGTH() +set sql_warnings = 1; +create table t1 (a char, b varchar(1024) as (uncompressed_length(compress(repeat(a,30))))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(1) DEFAULT NULL, + `b` varchar(1024) AS (uncompressed_length(compress(repeat(a,30)))) VIRTUAL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +insert into t1 values ('a',default); +select * from t1; +a b +a 30 +drop table t1; +set sql_warnings = 0; diff --git a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result new file mode 100644 index 00000000000..844aae38af2 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result @@ -0,0 +1,2943 @@ +SET @@session.storage_engine = 'MyISAM'; +# +# NUMERIC FUNCTIONS +# +# ABS() +set sql_warnings = 1; +create table t1 (a int, b int as (abs(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (abs(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (-1, default); +select * from t1; +a b +-1 1 +drop table t1; +set sql_warnings = 0; +# ACOS() +set sql_warnings = 1; +create table t1 (a double, b double as (format(acos(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(acos(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1, default); +insert into t1 values (1.0001,default); +insert into t1 values (0,default); +select * from t1; +a b +1 0 +1.0001 NULL +0 1.570796 +drop table t1; +set sql_warnings = 0; +# ASIN() +set sql_warnings = 1; +create table t1 (a double, b double as (format(asin(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(asin(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (0.2, default); +insert into t1 values (1.0001,default); +select * from t1; +a b +0.2 0.201358 +1.0001 NULL +drop table t1; +set sql_warnings = 0; +#ATAN +set sql_warnings = 1; +create table t1 (a double, b double, c double as (format(atan(a,b),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double DEFAULT NULL, + `c` double AS (format(atan(a,b),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (-2,2,default); +insert into t1 values (format(PI(),6),0,default); +select * from t1; +a b c +-2 2 -0.785398 +3.141593 0 1.570796 +drop table t1; +set sql_warnings = 0; +set sql_warnings = 1; +create table t1 (a double, c double as (format(atan(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `c` double AS (format(atan(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (-2,default); +insert into t1 values (format(PI(),6),default); +select * from t1; +a c +-2 -1.107149 +3.141593 1.262627 +drop table t1; +set sql_warnings = 0; +# ATAN2 +set sql_warnings = 1; +create table t1 (a double, b double, c double as (format(atan2(a,b),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double DEFAULT NULL, + `c` double AS (format(atan2(a,b),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (-2,2,default); +insert into t1 values (format(PI(),6),0,default); +select * from t1; +a b c +-2 2 -0.785398 +3.141593 0 1.570796 +drop table t1; +set sql_warnings = 0; +# CEIL() +set sql_warnings = 1; +create table t1 (a double, b int as (ceil(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` int(11) AS (ceil(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1.23,default); +insert into t1 values (-1.23,default); +select * from t1; +a b +1.23 2 +-1.23 -1 +drop table t1; +set sql_warnings = 0; +# CONV() +set sql_warnings = 1; +create table t1 (a varchar(10), b int, c int, d varchar(10) as (conv(a,b,c))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` varchar(10) AS (conv(a,b,c)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('a',16,2,default); +insert into t1 values ('6e',18,8,default); +insert into t1 values (-17,10,-18,default); +insert into t1 values (10+'10'+'10'+0xa,10,10,default); +select * from t1; +a b c d +a 16 2 1010 +6e 18 8 172 +-17 10 -18 -H +40 10 10 40 +drop table t1; +set sql_warnings = 0; +# COS() +set sql_warnings = 1; +create table t1 (a double, b double as (format(cos(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(cos(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (format(PI(),6),default); +select * from t1; +a b +3.141593 -1 +drop table t1; +set sql_warnings = 0; +# COT() +set sql_warnings = 1; +create table t1 (a double, b double as (format(cot(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(cot(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (12,default); +insert into t1 values (0,default); +select * from t1; +a b +12 -1.572673 +0 NULL +drop table t1; +set sql_warnings = 0; +# CRC32() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (crc32(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (crc32(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +insert into t1 values ('mysql',default); +select * from t1; +a b +MySQL 3259397556 +mysql 2501908538 +drop table t1; +set sql_warnings = 0; +# DEGREES() +set sql_warnings = 1; +create table t1 (a double, b double as (format(degrees(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(degrees(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (format(PI(),6),default); +insert into t1 values (format(PI()/2,6),default); +select * from t1; +a b +3.141593 180.00002 +1.570796 89.999981 +drop table t1; +set sql_warnings = 0; +# / +set sql_warnings = 1; +create table t1 (a double, b double as (a/2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (a/2) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +select * from t1; +a b +2 1 +drop table t1; +set sql_warnings = 0; +# EXP() +set sql_warnings = 1; +create table t1 (a double, b double as (format(exp(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(exp(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +insert into t1 values (-2,default); +insert into t1 values (0,default); +select * from t1; +a b +2 7.389056 +-2 0.135335 +0 1 +drop table t1; +set sql_warnings = 0; +# FLOOR() +set sql_warnings = 1; +create table t1 (a double, b long as (floor(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` mediumtext AS (floor(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1.23,default); +insert into t1 values (-1.23,default); +select * from t1; +a b +1.23 1 +-1.23 -2 +drop table t1; +set sql_warnings = 0; +# LN() +set sql_warnings = 1; +create table t1 (a double, b double as (format(ln(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(ln(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +insert into t1 values (-2,default); +select * from t1; +a b +2 0.693147 +-2 NULL +drop table t1; +set sql_warnings = 0; +# LOG() +set sql_warnings = 1; +create table t1 (a double, b double, c double as (format(log(a,b),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double DEFAULT NULL, + `c` double AS (format(log(a,b),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (2,65536,default); +insert into t1 values (10,100,default); +insert into t1 values (1,100,default); +select * from t1; +a b c +2 65536 16 +10 100 2 +1 100 NULL +drop table t1; +set sql_warnings = 0; +set sql_warnings = 1; +create table t1 (a double, b double as (format(log(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(log(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +insert into t1 values (-2,default); +select * from t1; +a b +2 0.693147 +-2 NULL +drop table t1; +set sql_warnings = 0; +# LOG2() +set sql_warnings = 1; +create table t1 (a double, b double as (format(log2(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(log2(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (65536,default); +insert into t1 values (-100,default); +select * from t1; +a b +65536 16 +-100 NULL +drop table t1; +set sql_warnings = 0; +# LOG10() +set sql_warnings = 1; +create table t1 (a double, b double as (format(log10(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(log10(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +insert into t1 values (100,default); +insert into t1 values (-100,default); +select * from t1; +a b +2 0.30103 +100 2 +-100 NULL +drop table t1; +set sql_warnings = 0; +# - +set sql_warnings = 1; +create table t1 (a double, b double as (a-1)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (a-1) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (2,default); +select * from t1; +a b +2 1 +drop table t1; +set sql_warnings = 0; +# MOD() +set sql_warnings = 1; +create table t1 (a int, b int as (mod(a,10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (mod(a,10)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (11,default); +select * from t1; +a b +1 1 +11 1 +drop table t1; +set sql_warnings = 0; +# % +set sql_warnings = 1; +create table t1 (a int, b int as (a % 10)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a % 10) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (11,default); +select * from t1; +a b +1 1 +11 1 +drop table t1; +set sql_warnings = 0; +# OCT() +set sql_warnings = 1; +create table t1 (a double, b varchar(10) as (oct(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` varchar(10) AS (oct(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (12,default); +select * from t1; +a b +12 14 +drop table t1; +set sql_warnings = 0; +# PI() +set sql_warnings = 1; +create table t1 (a double, b double as (format(PI()*a*a,6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(PI()*a*a,6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +select * from t1; +a b +1 3.141593 +drop table t1; +set sql_warnings = 0; +# + +set sql_warnings = 1; +create table t1 (a int, b int as (a+1)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a+1) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +select * from t1; +a b +1 2 +drop table t1; +set sql_warnings = 0; +# POW, POWER +set sql_warnings = 1; +create table t1 (a int, b int as (pow(a,2)), c int as (power(a,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (pow(a,2)) VIRTUAL, + `c` int(11) AS (power(a,2)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default,default); +insert into t1 values (2,default,default); +select * from t1; +a b c +1 1 1 +2 4 4 +drop table t1; +set sql_warnings = 0; +# RADIANS() +set sql_warnings = 1; +create table t1 (a double, b double as (format(radians(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(radians(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (90,default); +select * from t1; +a b +90 1.570796 +drop table t1; +set sql_warnings = 0; +# ROUND() +set sql_warnings = 1; +create table t1 (a double, b int as (round(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` int(11) AS (round(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (-1.23,default); +insert into t1 values (-1.58,default); +insert into t1 values (1.58,default); +select * from t1; +a b +-1.23 -1 +-1.58 -2 +1.58 2 +drop table t1; +set sql_warnings = 0; +set sql_warnings = 1; +create table t1 (a double, b double, c int as (round(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double DEFAULT NULL, + `c` int(11) AS (round(a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1.298,1,default); +insert into t1 values (1.298,0,default); +insert into t1 values (23.298,-1,default); +select * from t1; +a b c +1.298 1 1 +1.298 0 1 +23.298 -1 20 +drop table t1; +set sql_warnings = 0; +# SIGN() +set sql_warnings = 1; +create table t1 (a double, b int as (sign(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` int(11) AS (sign(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (-32,default); +insert into t1 values (0,default); +insert into t1 values (234,default); +select * from t1; +a b +-32 -1 +0 0 +234 1 +drop table t1; +set sql_warnings = 0; +# SIN() +set sql_warnings = 1; +create table t1 (a double, b double as (format(sin(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(sin(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (format(PI()/2,6),default); +select * from t1; +a b +1.570796 1 +drop table t1; +set sql_warnings = 0; +# SQRT() +set sql_warnings = 1; +create table t1 (a double, b double as (format(sqrt(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(sqrt(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (4,default); +insert into t1 values (20,default); +insert into t1 values (-16,default); +select * from t1; +a b +4 2 +20 4.472136 +-16 NULL +drop table t1; +set sql_warnings = 0; +# TAN() +set sql_warnings = 1; +create table t1 (a double, b double as (format(tan(a),6))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (format(tan(a),6)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (format(PI(),6),default); +insert into t1 values (format(PI()+1,6),default); +select * from t1; +a b +3.141593 0 +4.141593 1.557409 +drop table t1; +set sql_warnings = 0; +# * +set sql_warnings = 1; +create table t1 (a double, b double as (a*3)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (a*3) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (0,default); +insert into t1 values (1,default); +insert into t1 values (2,default); +select * from t1; +a b +0 0 +1 3 +2 6 +drop table t1; +set sql_warnings = 0; +# TRUNCATE() +set sql_warnings = 1; +create table t1 (a double, b double as (truncate(a,4))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (truncate(a,4)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1.223,default); +insert into t1 values (1.999,default); +insert into t1 values (1.999,default); +insert into t1 values (122,default); +select * from t1; +a b +1.223 1.223 +1.999 1.999 +1.999 1.999 +122 122 +drop table t1; +set sql_warnings = 0; +# Unary - +set sql_warnings = 1; +create table t1 (a double, b double as (-a)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` double AS (-a) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (-1,default); +select * from t1; +a b +1 -1 +-1 1 +drop table t1; +set sql_warnings = 0; +# +# STRING FUNCTIONS +# +# ASCII() +set sql_warnings = 1; +create table t1 (a char(2), b int as (ascii(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(2) DEFAULT NULL, + `b` int(11) AS (ascii(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2',default); +insert into t1 values (2,default); +insert into t1 values ('dx',default); +select * from t1; +a b +2 50 +2 50 +dx 100 +drop table t1; +set sql_warnings = 0; +# BIN() +set sql_warnings = 1; +create table t1 (a int, b varchar(10) as (bin(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(10) AS (bin(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (12,default); +select * from t1; +a b +12 1100 +drop table t1; +set sql_warnings = 0; +# BIT_LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (bit_length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (bit_length(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 32 +drop table t1; +set sql_warnings = 0; +# CHAR_LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (char_length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (char_length(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 4 +drop table t1; +set sql_warnings = 0; +# CHAR() +set sql_warnings = 1; +create table t1 (a int, b int, c varbinary(10) as (char(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` varbinary(10) AS (char(a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (77,121,default); +select * from t1; +a b c +77 121 My +drop table t1; +set sql_warnings = 0; +# CHARACTER_LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (character_length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (character_length(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 4 +drop table t1; +set sql_warnings = 0; +# CONCAT_WS() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c varchar(20) as (concat_ws(',',a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` varchar(20) AS (concat_ws(',',a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('value1','value2',default); +select * from t1; +a b c +value1 value2 value1,value2 +drop table t1; +set sql_warnings = 0; +# CONCAT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c varchar(20) as (concat(a,',',b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` varchar(20) AS (concat(a,',',b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('value1','value2',default); +select * from t1; +a b c +value1 value2 value1,value2 +drop table t1; +set sql_warnings = 0; +# ELT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int, d varchar(10) as (elt(c,a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` varchar(10) AS (elt(c,a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('value1','value2',1,default); +insert into t1 values ('value1','value2',2,default); +select * from t1; +a b c d +value1 value2 1 value1 +value1 value2 2 value2 +drop table t1; +set sql_warnings = 0; +# EXPORT_SET() +set sql_warnings = 1; +create table t1 (a int, b varchar(10) as (export_set(a,'1','0','',10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(10) AS (export_set(a,'1','0','',10)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (6,default); +select * from t1; +a b +6 0110000000 +drop table t1; +set sql_warnings = 0; +# FIELD() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int as (field('aa',a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) AS (field('aa',a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('aa','bb',default); +insert into t1 values ('bb','aa',default); +select * from t1; +a b c +aa bb 1 +bb aa 2 +drop table t1; +set sql_warnings = 0; +# FIND_IN_SET() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int as (find_in_set(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) AS (find_in_set(a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('aa','aa,bb,cc',default); +insert into t1 values ('aa','bb,aa,cc',default); +select * from t1; +a b c +aa aa,bb,cc 1 +aa bb,aa,cc 2 +drop table t1; +set sql_warnings = 0; +# FORMAT() +set sql_warnings = 1; +create table t1 (a double, b varchar(20) as (format(a,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` double DEFAULT NULL, + `b` varchar(20) AS (format(a,2)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (12332.123456,default); +select * from t1; +a b +12332.123456 12,332.12 +drop table t1; +set sql_warnings = 0; +# HEX() +set sql_warnings = 1; +create table t1 (a int, b varchar(10) as (hex(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(10) AS (hex(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (17,default); +select * from t1; +a b +17 11 +drop table t1; +set sql_warnings = 0; +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (hex(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (hex(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc 616263 +drop table t1; +set sql_warnings = 0; +# INSERT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c varchar(20) as (insert(a,length(a),length(b),b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` varchar(20) AS (insert(a,length(a),length(b),b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('start,','end',default); +select * from t1; +a b c +start, end startend +drop table t1; +set sql_warnings = 0; +# INSTR() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int as (instr(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) AS (instr(a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar,','bar',default); +insert into t1 values ('xbar,','foobar',default); +select * from t1; +a b c +foobarbar, bar 4 +xbar, foobar 0 +drop table t1; +set sql_warnings = 0; +# LCASE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (lcase(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (lcase(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL mysql +drop table t1; +set sql_warnings = 0; +# LEFT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(5) as (left(a,5))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(5) AS (left(a,5)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar fooba +drop table t1; +set sql_warnings = 0; +# LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b int as (length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` int(11) AS (length(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 4 +drop table t1; +set sql_warnings = 0; +# LIKE +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a like 'H%!o' escape '!')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a like 'H%!o' escape '!') VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('MySQL',default); +select * from t1; +a b +Hello 1 +MySQL 0 +drop table t1; +set sql_warnings = 0; +# LOCATE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (locate('bar',a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (locate('bar',a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar 4 +drop table t1; +set sql_warnings = 0; +# LOWER() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (lower(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (lower(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL mysql +drop table t1; +set sql_warnings = 0; +# LPAD() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (lpad(a,4,' '))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (lpad(a,4,' ')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +insert into t1 values ('M',default); +select * from t1; +a b +MySQL MySQ +M M +drop table t1; +set sql_warnings = 0; +# LTRIM() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (ltrim(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (ltrim(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (' MySQL',default); +insert into t1 values ('MySQL',default); +select * from t1; +a b + MySQL MySQL +MySQL MySQL +drop table t1; +set sql_warnings = 0; +# MAKE_SET() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c int, d varchar(30) as (make_set(c,a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` varchar(30) AS (make_set(c,a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('a','b',1,default); +insert into t1 values ('a','b',3,default); +select * from t1; +a b c d +a b 1 a +a b 3 a,b +drop table t1; +set sql_warnings = 0; +# MID() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (mid(a,1,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (mid(a,1,2)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar fo +drop table t1; +set sql_warnings = 0; +# NOT LIKE +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a not like 'H%o')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a not like 'H%o') VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('MySQL',default); +select * from t1; +a b +Hello 0 +MySQL 1 +drop table t1; +set sql_warnings = 0; +# NOT REGEXP +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a not regexp 'H.+o')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a not regexp 'H.+o') VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('hello',default); +select * from t1; +a b +Hello 0 +hello 0 +drop table t1; +set sql_warnings = 0; +# OCTET_LENGTH() +set sql_warnings = 1; +create table t1 (a varchar(10), b int as (octet_length(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` int(11) AS (octet_length(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('text',default); +select * from t1; +a b +text 4 +drop table t1; +set sql_warnings = 0; +# ORD() +set sql_warnings = 1; +create table t1 (a varchar(10), b long as (ord(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` mediumtext AS (ord(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2',default); +select * from t1; +a b +2 50 +drop table t1; +set sql_warnings = 0; +# POSITION() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (position('bar' in a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (position('bar' in a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar 4 +drop table t1; +set sql_warnings = 0; +# QUOTE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (quote(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (quote(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Don\'t',default); +select * from t1; +a b +Don't 'Don\'t' +drop table t1; +set sql_warnings = 0; +# REGEXP() +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a regexp 'H.+o')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a regexp 'H.+o') VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('hello',default); +select * from t1; +a b +Hello 1 +hello 1 +drop table t1; +set sql_warnings = 0; +# REPEAT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(30) as (repeat(a,3))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(30) AS (repeat(a,3)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MySQLMySQLMySQL +drop table t1; +set sql_warnings = 0; +# REPLACE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(30) as (replace(a,'aa','bb'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(30) AS (replace(a,'aa','bb')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('maa',default); +select * from t1; +a b +maa mbb +drop table t1; +set sql_warnings = 0; +# REVERSE() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(30) as (reverse(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(30) AS (reverse(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('maa',default); +select * from t1; +a b +maa aam +drop table t1; +set sql_warnings = 0; +# RIGHT() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (right(a,4))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (right(a,4)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('foobarbar',default); +select * from t1; +a b +foobarbar rbar +drop table t1; +set sql_warnings = 0; +# RLIKE() +set sql_warnings = 1; +create table t1 (a varchar(10), b bool as (a rlike 'H.+o')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` tinyint(1) AS (a rlike 'H.+o') VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +insert into t1 values ('MySQL',default); +select * from t1; +a b +Hello 1 +MySQL 0 +drop table t1; +set sql_warnings = 0; +# RPAD() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (rpad(a,4,'??'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (rpad(a,4,'??')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('He',default); +select * from t1; +a b +He He?? +drop table t1; +set sql_warnings = 0; +# RTRIM(); +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (rtrim(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (rtrim(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello ',default); +select * from t1; +a b +Hello Hello +drop table t1; +set sql_warnings = 0; +# SOUNDEX() +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(20) as (soundex(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(20) AS (soundex(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +select * from t1; +a b +Hello H400 +drop table t1; +set sql_warnings = 0; +# SOUNDS LIKE +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a sounds like b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a sounds like b) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello','Hello',default); +insert into t1 values ('Hello','MySQL',default); +insert into t1 values ('Hello','hello',default); +select * from t1; +a b c +Hello Hello 1 +Hello MySQL 0 +Hello hello 1 +drop table t1; +set sql_warnings = 0; +# SPACE() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (concat(a,space(5)))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (concat(a,space(5))) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello', default); +select * from t1; +a b +Hello Hello +drop table t1; +set sql_warnings = 0; +# STRCMP() +set sql_warnings = 1; +create table t1 (a varchar(9), b varchar(9), c tinyint(1) as (strcmp(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(9) DEFAULT NULL, + `b` varchar(9) DEFAULT NULL, + `c` tinyint(1) AS (strcmp(a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello','Hello', default); +insert into t1 values ('Hello','Hello1', default); +select * from t1; +a b c +Hello Hello 0 +Hello Hello1 -1 +drop table t1; +set sql_warnings = 0; +# SUBSTR() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (substr(a,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (substr(a,2)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +select * from t1; +a b +Hello ello +drop table t1; +set sql_warnings = 0; +# SUBSTRING_INDEX() +set sql_warnings = 1; +create table t1 (a varchar(15), b varchar(10) as (substring_index(a,'.',2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(15) DEFAULT NULL, + `b` varchar(10) AS (substring_index(a,'.',2)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('www.mysql.com',default); +select * from t1; +a b +www.mysql.com www.mysql +drop table t1; +set sql_warnings = 0; +# SUBSTRING() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (substring(a from 2 for 2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (substring(a from 2 for 2)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('Hello',default); +select * from t1; +a b +Hello el +drop table t1; +set sql_warnings = 0; +# TRIM() +set sql_warnings = 1; +create table t1 (a varchar(15), b varchar(10) as (trim(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(15) DEFAULT NULL, + `b` varchar(10) AS (trim(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (' aa ',default); +select * from t1; +a b + aa aa +drop table t1; +set sql_warnings = 0; +# UCASE() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (ucase(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (ucase(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MYSQL +drop table t1; +set sql_warnings = 0; +# UNHEX() +set sql_warnings = 1; +create table t1 (a varchar(15), b varchar(10) as (unhex(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(15) DEFAULT NULL, + `b` varchar(10) AS (unhex(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('4D7953514C',default); +select * from t1; +a b +4D7953514C MySQL +drop table t1; +set sql_warnings = 0; +# UPPER() +set sql_warnings = 1; +create table t1 (a varchar(5), b varchar(10) as (upper(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL, + `b` varchar(10) AS (upper(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MYSQL +drop table t1; +set sql_warnings = 0; +# +# CONTROL FLOW FUNCTIONS +# +# CASE +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(16) as (case a when NULL then 'asd' when 'b' then 'B' else a end)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(16) AS (case a when NULL then 'asd' when 'b' then 'B' else a end) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (NULL,default); +insert into t1 values ('b',default); +insert into t1 values ('c',default); +select * from t1; +a b +NULL NULL +b B +c c +drop table t1; +set sql_warnings = 0; +# IF +set sql_warnings = 1; +create table t1 (a int, b int, c int as (if(a=1,a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS (if(a=1,a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,2,default); +insert into t1 values (3,4,default); +select * from t1; +a b c +1 2 1 +3 4 4 +drop table t1; +set sql_warnings = 0; +# IFNULL +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c varchar(10) as (ifnull(a,'DEFAULT'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` varchar(10) AS (ifnull(a,'DEFAULT')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (NULL,'adf',default); +insert into t1 values ('a','adf',default); +select * from t1; +a b c +NULL adf DEFAULT +a adf a +drop table t1; +set sql_warnings = 0; +# NULLIF +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10) as (nullif(a,'DEFAULT'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) AS (nullif(a,'DEFAULT')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('DEFAULT',default); +insert into t1 values ('a',default); +select * from t1; +a b +DEFAULT NULL +a a +drop table t1; +set sql_warnings = 0; +# +# OPERATORS +# +# AND, && +set sql_warnings = 1; +create table t1 (a int, b bool as (a>0 && a<2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a>0 && a<2) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (-1,default); +insert into t1 values (1,default); +select * from t1; +a b +-1 0 +1 1 +drop table t1; +set sql_warnings = 0; +# BETWEEN ... AND ... +set sql_warnings = 1; +create table t1 (a int, b bool as (a between 0 and 2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a between 0 and 2) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (-1,default); +insert into t1 values (1,default); +select * from t1; +a b +-1 0 +1 1 +drop table t1; +set sql_warnings = 0; +# BINARY +set sql_warnings = 1; +create table t1 (a varchar(10), b varbinary(10) as (binary a)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varbinary(10) AS (binary a) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('11',default); +insert into t1 values (1,default); +select * from t1; +a b +11 11 +1 1 +drop table t1; +set sql_warnings = 0; +# & +set sql_warnings = 1; +create table t1 (a int, b int as (a & 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a & 5) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (0,default); +select * from t1; +a b +1 1 +0 0 +drop table t1; +set sql_warnings = 0; +# ~ +set sql_warnings = 1; +create table t1 (a int, b int as (~a)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (~a) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 +select * from t1; +a b +1 2147483647 +drop table t1; +set sql_warnings = 0; +# | +set sql_warnings = 1; +create table t1 (a int, b int as (a | 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a | 5) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (0,default); +insert into t1 values (2,default); +select * from t1; +a b +1 5 +0 5 +2 7 +drop table t1; +set sql_warnings = 0; +# ^ +set sql_warnings = 1; +create table t1 (a int, b int as (a ^ 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a ^ 5) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (0,default); +insert into t1 values (2,default); +select * from t1; +a b +1 4 +0 5 +2 7 +drop table t1; +set sql_warnings = 0; +# DIV +set sql_warnings = 1; +create table t1 (a int, b int as (a div 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a div 5) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (7,default); +select * from t1; +a b +1 0 +7 1 +drop table t1; +set sql_warnings = 0; +# <=> +set sql_warnings = 1; +create table t1 (a int, b int, c bool as (a <=> b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` tinyint(1) AS (a <=> b) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,1,default); +insert into t1 values (NULL,NULL,default); +insert into t1 values (1,NULL,default); +select * from t1; +a b c +1 1 1 +NULL NULL 1 +1 NULL 0 +drop table t1; +set sql_warnings = 0; +# = +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a=b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a=b) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('a','b',default); +insert into t1 values ('a','a',default); +select * from t1; +a b c +a b 0 +a a 1 +drop table t1; +set sql_warnings = 0; +# >= +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a >= b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a >= b) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('a','b',default); +insert into t1 values ('a','a',default); +select * from t1; +a b c +a b 0 +a a 1 +drop table t1; +set sql_warnings = 0; +# > +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a > b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a > b) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('a','b',default); +insert into t1 values ('a','a',default); +select * from t1; +a b c +a b 0 +a a 0 +drop table t1; +set sql_warnings = 0; +# IS NOT NULL +set sql_warnings = 1; +create table t1 (a int, b bool as (a is not null)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a is not null) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (NULL,default); +select * from t1; +a b +1 1 +NULL 0 +drop table t1; +set sql_warnings = 0; +# IS NULL +set sql_warnings = 1; +create table t1 (a int, b bool as (a is null)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a is null) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (NULL,default); +select * from t1; +a b +1 0 +NULL 1 +drop table t1; +set sql_warnings = 0; +# << +set sql_warnings = 1; +create table t1 (a int, b int as (a << 2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a << 2) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (3,default); +select * from t1; +a b +1 4 +3 12 +drop table t1; +set sql_warnings = 0; +# <= +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a <= b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a <= b) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('b','a',default); +insert into t1 values ('b','b',default); +insert into t1 values ('b','c',default); +select * from t1; +a b c +b a 0 +b b 1 +b c 1 +drop table t1; +set sql_warnings = 0; +# < +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a < b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a < b) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('b','a',default); +insert into t1 values ('b','b',default); +insert into t1 values ('b','c',default); +select * from t1; +a b c +b a 0 +b b 0 +b c 1 +drop table t1; +set sql_warnings = 0; +# NOT BETWEEN ... AND ... +set sql_warnings = 1; +create table t1 (a int, b bool as (a not between 0 and 2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` tinyint(1) AS (a not between 0 and 2) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (-1,default); +insert into t1 values (1,default); +select * from t1; +a b +-1 1 +1 0 +drop table t1; +set sql_warnings = 0; +# <> +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a <> b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a <> b) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('b','a',default); +insert into t1 values ('b','b',default); +insert into t1 values ('b','c',default); +select * from t1; +a b c +b a 1 +b b 0 +b c 1 +drop table t1; +set sql_warnings = 0; +# != +set sql_warnings = 1; +create table t1 (a varchar(10), b varchar(10), c bool as (a != b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL, + `c` tinyint(1) AS (a != b) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('b','a',default); +insert into t1 values ('b','b',default); +insert into t1 values ('b','c',default); +select * from t1; +a b c +b a 1 +b b 0 +b c 1 +drop table t1; +set sql_warnings = 0; +# ||, OR +set sql_warnings = 1; +create table t1 (a int, b int as (a>5 || a<3)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a>5 || a<3) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (4,default); +select * from t1; +a b +1 1 +4 0 +drop table t1; +set sql_warnings = 0; +# >> +set sql_warnings = 1; +create table t1 (a int, b int as (a >> 2)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a >> 2) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (8,default); +insert into t1 values (3,default); +select * from t1; +a b +8 2 +3 0 +drop table t1; +set sql_warnings = 0; +# XOR +set sql_warnings = 1; +create table t1 (a int, b int as (a xor 5)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a xor 5) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (0,default); +insert into t1 values (1,default); +insert into t1 values (2,default); +select * from t1; +a b +0 1 +1 0 +2 0 +drop table t1; +set sql_warnings = 0; +# +# DATE AND TIME FUNCTIONS +# +# ADDDATE() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (adddate(a,interval 1 month))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (adddate(a,interval 1 month)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-09-30 00:00:00 +drop table t1; +set sql_warnings = 0; +# ADDTIME() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (addtime(a,'02:00:00'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (addtime(a,'02:00:00')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-08-31 02:00:00 +drop table t1; +set sql_warnings = 0; +# CONVERT_TZ() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (convert_tz(a,'MET','UTC'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (convert_tz(a,'MET','UTC')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-08-30 22:00:00 +drop table t1; +set sql_warnings = 0; +# DATE_ADD() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (date_add(a,interval 1 month))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (date_add(a,interval 1 month)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-09-30 00:00:00 +drop table t1; +set sql_warnings = 0; +# DATE_FORMAT() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(64) as (date_format(a,'%W %M %D'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(64) AS (date_format(a,'%W %M %D')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 Sunday August 31st +drop table t1; +set sql_warnings = 0; +# DATE_SUB() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (date_sub(a,interval 1 month))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (date_sub(a,interval 1 month)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-07-31 00:00:00 +drop table t1; +set sql_warnings = 0; +# DATE() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (date(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (date(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31 02:00:00',default); +select * from t1; +a b +2008-08-31 02:00:00 2008-08-31 00:00:00 +drop table t1; +set sql_warnings = 0; +# DATEDIFF() +set sql_warnings = 1; +create table t1 (a datetime, b long as (datediff(a,'2000-01-01'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` mediumtext AS (datediff(a,'2000-01-01')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 3165 +drop table t1; +set sql_warnings = 0; +# DAY() +set sql_warnings = 1; +create table t1 (a datetime, b int as (day(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (day(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 31 +drop table t1; +set sql_warnings = 0; +# DAYNAME() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(10) as (dayname(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(10) AS (dayname(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 Sunday +drop table t1; +set sql_warnings = 0; +# DAYOFMONTH() +set sql_warnings = 1; +create table t1 (a datetime, b int as (dayofmonth(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (dayofmonth(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 31 +drop table t1; +set sql_warnings = 0; +# DAYOFWEEK() +set sql_warnings = 1; +create table t1 (a datetime, b int as (dayofweek(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (dayofweek(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 1 +drop table t1; +set sql_warnings = 0; +# DAYOFYEAR() +set sql_warnings = 1; +create table t1 (a datetime, b int as (dayofyear(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (dayofyear(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 244 +drop table t1; +set sql_warnings = 0; +# EXTRACT +set sql_warnings = 1; +create table t1 (a datetime, b int as (extract(year from a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (extract(year from a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008 +drop table t1; +set sql_warnings = 0; +# FROM_DAYS() +set sql_warnings = 1; +create table t1 (a long, b datetime as (from_days(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` mediumtext, + `b` datetime AS (from_days(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (730669,default); +select * from t1; +a b +730669 2000-07-03 00:00:00 +drop table t1; +set sql_warnings = 0; +# FROM_UNIXTIME() +set time_zone='UTC'; +set sql_warnings = 1; +create table t1 (a long, b datetime as (from_unixtime(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` mediumtext, + `b` datetime AS (from_unixtime(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1196440219,default); +select * from t1; +a b +1196440219 2007-11-30 16:30:19 +drop table t1; +set sql_warnings = 0; +# GET_FORMAT() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(32) as (date_format(a,get_format(DATE,'EUR')))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(32) AS (date_format(a,get_format(DATE,'EUR'))) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 31.08.2008 +drop table t1; +set sql_warnings = 0; +# HOUR() +set sql_warnings = 1; +create table t1 (a time, b long as (hour(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` time DEFAULT NULL, + `b` mediumtext AS (hour(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('10:05:03',default); +select * from t1; +a b +10:05:03 10 +drop table t1; +set sql_warnings = 0; +# LAST_DAY() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (last_day(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (last_day(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2003-02-05',default); +insert into t1 values ('2003-02-32',default); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a b +2003-02-05 00:00:00 2003-02-28 00:00:00 +0000-00-00 00:00:00 NULL +drop table t1; +set sql_warnings = 0; +# MAKEDATE() +set sql_warnings = 1; +create table t1 (a int, b datetime as (makedate(a,1))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` datetime AS (makedate(a,1)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (2001,default); +select * from t1; +a b +2001 2001-01-01 00:00:00 +drop table t1; +set sql_warnings = 0; +# MAKETIME() +set sql_warnings = 1; +create table t1 (a int, b time as (maketime(a,1,3))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` time AS (maketime(a,1,3)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (12,default); +select * from t1; +a b +12 12:01:03 +drop table t1; +set sql_warnings = 0; +# MICROSECOND() +set sql_warnings = 1; +create table t1 (a datetime, b long as (microsecond(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` mediumtext AS (microsecond(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2009-12-31 12:00:00.123456',default); +insert into t1 values ('2009-12-31 23:59:59.000010',default); +select * from t1; +a b +2009-12-31 12:00:00 0 +2009-12-31 23:59:59 0 +drop table t1; +set sql_warnings = 0; +# MINUTE() +set sql_warnings = 1; +create table t1 (a datetime, b int as (minute(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (minute(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2009-12-31 23:59:59.000010',default); +select * from t1; +a b +2009-12-31 23:59:59 59 +drop table t1; +set sql_warnings = 0; +# MONTH() +set sql_warnings = 1; +create table t1 (a datetime, b int as (month(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (month(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2009-12-31 23:59:59.000010',default); +select * from t1; +a b +2009-12-31 23:59:59 12 +drop table t1; +set sql_warnings = 0; +# MONTHNAME() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(16) as (monthname(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(16) AS (monthname(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2009-12-31 23:59:59.000010',default); +select * from t1; +a b +2009-12-31 23:59:59 December +drop table t1; +set sql_warnings = 0; +# PERIOD_ADD() +set sql_warnings = 1; +create table t1 (a int, b int as (period_add(a,2))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (period_add(a,2)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (200801,default); +select * from t1; +a b +200801 200803 +drop table t1; +set sql_warnings = 0; +# PERIOD_DIFF() +set sql_warnings = 1; +create table t1 (a int, b int, c int as (period_diff(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS (period_diff(a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (200802,200703,default); +select * from t1; +a b c +200802 200703 11 +drop table t1; +set sql_warnings = 0; +# QUARTER() +set sql_warnings = 1; +create table t1 (a datetime, b int as (quarter(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (quarter(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 3 +drop table t1; +set sql_warnings = 0; +# SEC_TO_TIME() +set sql_warnings = 1; +create table t1 (a long, b time as (sec_to_time(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` mediumtext, + `b` time AS (sec_to_time(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (2378,default); +select * from t1; +a b +2378 00:39:38 +drop table t1; +set sql_warnings = 0; +# SECOND() +set sql_warnings = 1; +create table t1 (a datetime, b int as (second(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (second(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('10:05:03',default); +select * from t1; +a b +2010-05-03 00:00:00 0 +drop table t1; +set sql_warnings = 0; +# STR_TO_DATE() +set sql_warnings = 1; +create table t1 (a varchar(64), b datetime as (str_to_date(a,'%m/%d/%Y'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(64) DEFAULT NULL, + `b` datetime AS (str_to_date(a,'%m/%d/%Y')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('04/30/2004',default); +select * from t1; +a b +04/30/2004 2004-04-30 00:00:00 +drop table t1; +set sql_warnings = 0; +# SUBDATE() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (subdate(a,interval 1 month))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (subdate(a,interval 1 month)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-07-31 00:00:00 +drop table t1; +set sql_warnings = 0; +# SUBTIME() +set sql_warnings = 1; +create table t1 (a datetime, b datetime as (subtime(a,'02:00:00'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime AS (subtime(a,'02:00:00')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31',default); +select * from t1; +a b +2008-08-31 00:00:00 2008-08-30 22:00:00 +drop table t1; +set sql_warnings = 0; +# TIME_FORMAT() +set sql_warnings = 1; +create table t1 (a datetime, b varchar(32) as (time_format(a,'%r'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` varchar(32) AS (time_format(a,'%r')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31 02:03:04',default); +select * from t1; +a b +2008-08-31 02:03:04 02:03:04 AM +drop table t1; +set sql_warnings = 0; +# TIME_TO_SEC() +set sql_warnings = 1; +create table t1 (a time, b long as (time_to_sec(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` time DEFAULT NULL, + `b` mediumtext AS (time_to_sec(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('22:23:00',default); +select * from t1; +a b +22:23:00 80580 +drop table t1; +set sql_warnings = 0; +# TIME() +set sql_warnings = 1; +create table t1 (a datetime, b time as (time(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` time AS (time(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-08-31 02:03:04',default); +select * from t1; +a b +2008-08-31 02:03:04 02:03:04 +drop table t1; +set sql_warnings = 0; +# TIMEDIFF() +set sql_warnings = 1; +create table t1 (a datetime, b datetime, c long as (timediff(a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` datetime DEFAULT NULL, + `c` mediumtext AS (timediff(a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002',default); +select * from t1; +a b c +2008-12-31 23:59:59 2008-12-30 01:01:01 46:58:58 +drop table t1; +set sql_warnings = 0; +# TIMESTAMP() +set sql_warnings = 1; +create table t1 (a datetime, b timestamp as (timestamp(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` timestamp AS (timestamp(a)) VIRTUAL NULL ON UPDATE CURRENT_TIMESTAMP +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-12-31',default); +select * from t1; +a b +2008-12-31 00:00:00 2008-12-31 00:00:00 +drop table t1; +set sql_warnings = 0; +# TIMESTAMPADD() +set sql_warnings = 1; +create table t1 (a datetime, b timestamp as (timestampadd(minute,1,a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` timestamp AS (timestampadd(minute,1,a)) VIRTUAL NULL ON UPDATE CURRENT_TIMESTAMP +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2003-01-02',default); +select * from t1; +a b +2003-01-02 00:00:00 2003-01-02 00:01:00 +drop table t1; +set sql_warnings = 0; +# TIMESTAMPDIFF() +set sql_warnings = 1; +create table t1 (a timestamp, b timestamp, c long as (timestampdiff(MONTH, a,b))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `b` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `c` mediumtext AS (timestampdiff(MONTH, a,b)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2003-02-01','2003-05-01',default); +select * from t1; +a b c +2003-02-01 00:00:00 2003-05-01 00:00:00 3 +drop table t1; +set sql_warnings = 0; +# TO_DAYS() +set sql_warnings = 1; +create table t1 (a datetime, b long as (to_days(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` mediumtext AS (to_days(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2007-10-07',default); +select * from t1; +a b +2007-10-07 00:00:00 733321 +drop table t1; +set sql_warnings = 0; +# WEEK() +set sql_warnings = 1; +create table t1 (a datetime, b int as (week(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (week(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 35 +drop table t1; +set sql_warnings = 0; +# WEEKDAY() +set sql_warnings = 1; +create table t1 (a datetime, b int as (weekday(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (weekday(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 0 +drop table t1; +set sql_warnings = 0; +# WEEKOFYEAR() +set sql_warnings = 1; +create table t1 (a datetime, b int as (weekofyear(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (weekofyear(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 36 +drop table t1; +set sql_warnings = 0; +# YEAR() +set sql_warnings = 1; +create table t1 (a datetime, b int as (year(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (year(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 2008 +drop table t1; +set sql_warnings = 0; +# YEARWEEK() +set sql_warnings = 1; +create table t1 (a datetime, b int as (yearweek(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (yearweek(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2008-09-01',default); +select * from t1; +a b +2008-09-01 00:00:00 200835 +drop table t1; +set sql_warnings = 0; +# +# FULL TEXT SEARCH FUNCTIONS +# +# None. +# +# CAST FUNCTIONS AND OPERATORS +# +# CAST() +set sql_warnings = 1; +create table t1 (a int, b long as (cast(a as unsigned))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` mediumtext AS (cast(a as unsigned)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (-1,default); +select * from t1; +a b +1 1 +-1 18446744073709551615 +drop table t1; +set sql_warnings = 0; +# Convert() +set sql_warnings = 1; +create table t1 (a int, b long as (convert(a,unsigned))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` mediumtext AS (convert(a,unsigned)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (1,default); +insert into t1 values (-1,default); +select * from t1; +a b +1 1 +-1 18446744073709551615 +drop table t1; +set sql_warnings = 0; +# +# XML FUNCTIONS +# +# None. +# +# OTHER FUNCTIONS +# +# AES_DECRYPT(), AES_ENCRYPT() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (aes_encrypt(aes_decrypt(a,'adf'),'adf'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (aes_encrypt(aes_decrypt(a,'adf'),'adf')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL NULL +drop table t1; +set sql_warnings = 0; +# BIT_COUNT() +set sql_warnings = 1; +create table t1 (a int, b int as (bit_count(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (bit_count(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (5,default); +select * from t1; +a b +5 2 +drop table t1; +set sql_warnings = 0; +# CHARSET() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (charset(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (charset(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc latin1 +drop table t1; +set sql_warnings = 0; +# COERCIBILITY() +set sql_warnings = 1; +create table t1 (a varchar(1024), b int as (coercibility(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` int(11) AS (coercibility(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc 2 +drop table t1; +set sql_warnings = 0; +# COLLATION() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (collation(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (collation(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc latin1_swedish_ci +drop table t1; +set sql_warnings = 0; +# COMPRESS(), UNCOMPRESS() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (uncompress(compress(a)))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (uncompress(compress(a))) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MySQL +drop table t1; +set sql_warnings = 0; +# ENCODE(), DECODE() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (decode(encode(a,'abc'),'abc'))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (decode(encode(a,'abc'),'abc')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('MySQL',default); +select * from t1; +a b +MySQL MySQL +drop table t1; +set sql_warnings = 0; +# DEFAULT() +set sql_warnings = 1; +create table t1 (a varchar(1024) default 'aaa', b varchar(1024) as (ifnull(a,default(a)))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT 'aaa', + `b` varchar(1024) AS (ifnull(a,default(a))) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('any value',default); +select * from t1; +a b +any value any value +drop table t1; +set sql_warnings = 0; +# INET_ATON(), INET_NTOA() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (inet_ntoa(inet_aton(a)))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (inet_ntoa(inet_aton(a))) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('127.0.0.1',default); +select * from t1; +a b +127.0.0.1 127.0.0.1 +drop table t1; +set sql_warnings = 0; +# MD5() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varbinary(32) as (md5(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varbinary(32) AS (md5(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('testing',default); +select * from t1; +a b +testing ae2b1fca515949e5d54fb22b8ed95575 +drop table t1; +set sql_warnings = 0; +# OLD_PASSWORD() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (old_password(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (old_password(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('badpwd',default); +select * from t1; +a b +badpwd 7f84554057dd964b +drop table t1; +set sql_warnings = 0; +# PASSWORD() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (password(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (password(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('badpwd',default); +select * from t1; +a b +badpwd *AAB3E285149C0135D51A520E1940DD3263DC008C +drop table t1; +set sql_warnings = 0; +# SHA1() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (sha1(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (sha1(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc a9993e364706816aba3e25717850c26c9cd0d89d +drop table t1; +set sql_warnings = 0; +# SHA() +set sql_warnings = 1; +create table t1 (a varchar(1024), b varchar(1024) as (sha(a))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1024) DEFAULT NULL, + `b` varchar(1024) AS (sha(a)) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('abc',default); +select * from t1; +a b +abc a9993e364706816aba3e25717850c26c9cd0d89d +drop table t1; +set sql_warnings = 0; +# UNCOMPRESSED_LENGTH() +set sql_warnings = 1; +create table t1 (a char, b varchar(1024) as (uncompressed_length(compress(repeat(a,30))))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(1) DEFAULT NULL, + `b` varchar(1024) AS (uncompressed_length(compress(repeat(a,30)))) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('a',default); +select * from t1; +a b +a 30 +drop table t1; +set sql_warnings = 0; diff --git a/mysql-test/suite/vcol/r/vcol_syntax.result b/mysql-test/suite/vcol/r/vcol_syntax.result new file mode 100644 index 00000000000..8515d790359 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_syntax.result @@ -0,0 +1,52 @@ +drop table if exists t1; +set @OLD_SQL_MODE=@@SESSION.SQL_MODE; +create table t1 (a int, b int generated always as (a+1)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a+1) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int, b int as (a+1) virtual); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a+1) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int, b int generated always as (a+1) persistent); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a+1) PERSISTENT +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +set session sql_mode='ORACLE'; +create table t1 (a int, b int as (a+1)); +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" int(11) DEFAULT NULL, + "b" int(11) AS (a+1) VIRTUAL +) +drop table t1; +create table t1 (a int, b int generated always as (a+1) virtual); +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" int(11) DEFAULT NULL, + "b" int(11) AS (a+1) VIRTUAL +) +drop table t1; +create table t1 (a int, b int as (a+1) persistent); +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" int(11) DEFAULT NULL, + "b" int(11) AS (a+1) PERSISTENT +) +drop table t1; +set session sql_mode=@OLD_SQL_MODE; diff --git a/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result new file mode 100644 index 00000000000..e903bc4eafd --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result @@ -0,0 +1,87 @@ +SET @@session.storage_engine = 'InnoDB'; +create table t1 (a int, +b int as (a/10), +c int as (a/10) persistent); +create table t2 (a timestamp); +create trigger trg1 before insert on t1 for each row +begin +if (new.b < 10) then +set new.a:= 100; +set new.b:= 9; +set new.c:= 9; +end if; +if (new.c > 50) then +set new.a:= 500; +end if; +end| +create trigger trg2 after insert on t1 for each row +begin +if (new.b >= 60) then +insert into t2 values (now()); +end if; +end| +create function f1() +returns int +begin +declare sum1 int default '0'; +declare cur1 cursor for select sum(b) from t1; +open cur1; +fetch cur1 into sum1; +close cur1; +return sum1; +end| +set sql_warnings = 1; +insert into t1 (a) values (200); +select * from t1; +a b c +200 20 20 +select * from t2; +a +insert into t1 (a) values (10); +select * from t1; +a b c +200 20 20 +100 10 10 +select * from t2; +a +insert into t1 (a) values (600); +select * from t1; +a b c +200 20 20 +100 10 10 +500 50 50 +select * from t2; +a +select f1(); +f1() +80 +set sql_warnings = 0; +drop trigger trg1; +drop trigger trg2; +drop table t2; +create procedure p1() +begin +declare i int default '0'; +create table t2 like t1; +insert into t2 (a) values (100), (200); +begin +declare cur1 cursor for select sum(c) from t2; +open cur1; +fetch cur1 into i; +close cur1; +if (i=30) then +insert into t1 values (300,default,default); +end if; +end; +end| +delete from t1; +call p1(); +select * from t2; +a b c +100 10 10 +200 20 20 +select * from t1; +a b c +300 30 30 +drop table t1,t2; +drop procedure p1; diff --git a/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result new file mode 100644 index 00000000000..c2a66d656b5 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result @@ -0,0 +1,87 @@ +SET @@session.storage_engine = 'MyISAM'; +create table t1 (a int, +b int as (a/10), +c int as (a/10) persistent); +create table t2 (a timestamp); +create trigger trg1 before insert on t1 for each row +begin +if (new.b < 10) then +set new.a:= 100; +set new.b:= 9; +set new.c:= 9; +end if; +if (new.c > 50) then +set new.a:= 500; +end if; +end| +create trigger trg2 after insert on t1 for each row +begin +if (new.b >= 60) then +insert into t2 values (now()); +end if; +end| +create function f1() +returns int +begin +declare sum1 int default '0'; +declare cur1 cursor for select sum(b) from t1; +open cur1; +fetch cur1 into sum1; +close cur1; +return sum1; +end| +set sql_warnings = 1; +insert into t1 (a) values (200); +select * from t1; +a b c +200 20 20 +select * from t2; +a +insert into t1 (a) values (10); +select * from t1; +a b c +200 20 20 +100 10 10 +select * from t2; +a +insert into t1 (a) values (600); +select * from t1; +a b c +200 20 20 +100 10 10 +500 50 50 +select * from t2; +a +select f1(); +f1() +80 +set sql_warnings = 0; +drop trigger trg1; +drop trigger trg2; +drop table t2; +create procedure p1() +begin +declare i int default '0'; +create table t2 like t1; +insert into t2 (a) values (100), (200); +begin +declare cur1 cursor for select sum(c) from t2; +open cur1; +fetch cur1 into i; +close cur1; +if (i=30) then +insert into t1 values (300,default,default); +end if; +end; +end| +delete from t1; +call p1(); +select * from t2; +a b c +100 10 10 +200 20 20 +select * from t1; +a b c +300 30 30 +drop table t1,t2; +drop procedure p1; diff --git a/mysql-test/suite/vcol/r/vcol_view_innodb.result b/mysql-test/suite/vcol/r/vcol_view_innodb.result new file mode 100644 index 00000000000..ae834722606 --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_view_innodb.result @@ -0,0 +1,276 @@ +SET @@session.storage_engine = 'InnoDB'; +create table t1 (a int not null, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1), (1), (2), (2), (3); +create view v1 (d,e) as select abs(b), abs(c) from t1; +select d,e from v1; +d e +1 1 +1 1 +2 2 +2 2 +3 3 +select is_updatable from information_schema.views where table_name='v1'; +is_updatable +NO +explain extended select d,e from v1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 +Warnings: +Note 1003 select abs(`test`.`t1`.`b`) AS `d`,abs(`test`.`t1`.`c`) AS `e` from `test`.`t1` +create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1; +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select abs(`t1`.`b`) AS `d`,abs(`t1`.`c`) AS `e` from `t1` latin1 latin1_swedish_ci +select d,e from v2; +d e +1 1 +1 1 +2 2 +2 2 +3 3 +explain extended select d,e from v2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 100.00 +2 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00 +Warnings: +Note 1003 select `v2`.`d` AS `d`,`v2`.`e` AS `e` from `test`.`v2` +create view v3 (d,e) as select d*2, e*2 from v1; +select * from v3; +d e +2 2 +2 2 +4 4 +4 4 +6 6 +explain extended select * from v3; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 +Warnings: +Note 1003 select (abs(`test`.`t1`.`b`) * 2) AS `d`,(abs(`test`.`t1`.`c`) * 2) AS `e` from `test`.`t1` +drop view v1,v2,v3; +drop table t1; +create table t1 (a int not null, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1), (2), (3), (1), (2), (3); +create view v1 as select distinct b from t1; +select * from v1; +b +-1 +-2 +-3 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 +2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +1 -1 -1 +2 -2 -2 +3 -3 -3 +drop view v1; +create view v1 as select distinct c from t1; +select * from v1; +c +-1 +-2 +-3 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 +2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +1 -1 -1 +2 -2 -2 +3 -3 -3 +drop view v1; +drop table t1; +create table t1 (a int not null, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1), (2), (3), (4); +create view v1 as select b+1 from t1 order by 1 desc limit 2; +select * from v1; +b+1 +0 +-1 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort +drop view v1; +create view v1 as select c+1 from t1 order by 1 desc limit 2; +select * from v1; +c+1 +0 +-1 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort +drop view v1; +drop table t1; +create table t1 (a int, +b int, +c int as (-a), +d int as (-a) persistent, +primary key(a)); +insert into t1 (a,b) values (10,2), (20,3), (30,4), (40,5), (50,10); +create view v1 (a,e,f,g) as select a, b+1,c+1,d+1 from t1; +update v1 set a=a+e; +select * from v1; +a e f g +13 3 -12 -12 +24 4 -23 -23 +35 5 -34 -34 +46 6 -45 -45 +61 11 -60 -60 +select * from t1; +a b c d +13 2 -13 -13 +24 3 -24 -24 +35 4 -35 -35 +46 5 -46 -46 +61 10 -61 -61 +delete from v1; +select * from v1; +a e f g +select * from t1; +a b c d +insert into v1 (a,e) values (60,15); +ERROR HY000: The target table v1 of the INSERT is not insertable-into +drop table t1; +drop view v1; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent, +primary key(a)); +insert into t1 (a) values (1), (2), (3); +create view v1 (x,y,z) as select a,b,c from t1 where b < -1; +select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.b= v1.y); +a x y z +1 NULL NULL NULL +2 2 -2 -2 +3 3 -3 -3 +drop view v1; +create view v1 (x,y,z) as select a,b,c from t1 where c < -1; +select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.c= v1.z); +a x y z +1 NULL NULL NULL +2 2 -2 -2 +3 3 -3 -3 +drop view v1; +drop table t1; +create table t1 (a1 int, +b1 int as (-a1), +c1 int as (-a1) persistent); +create table t2 (a2 int, +b2 int as (-a2), +c2 int as (-a2) persistent); +insert into t1 (a1) values (1), (2); +insert into t2 (a2) values (2), (3); +create view v1 as select * from t1,t2 union all select * from t1,t2; +select * from v1; +a1 b1 c1 a2 b2 c2 +1 -1 -1 2 -2 -2 +2 -2 -2 2 -2 -2 +1 -1 -1 3 -3 -3 +2 -2 -2 3 -3 -3 +1 -1 -1 2 -2 -2 +2 -2 -2 2 -2 -2 +1 -1 -1 3 -3 -3 +2 -2 -2 3 -3 -3 +drop view v1; +drop table t1, t2; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +create table t2 like t1; +create view v1 as select a,b,c from t1; +create view v2 as select a,b,c from t2 where b in (select b from v1); +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a`,`t2`.`b` AS `b`,`t2`.`c` AS `c` from `t2` where `t2`.`b` in (select `v1`.`b` from `v1`) latin1 latin1_swedish_ci +drop view v2, v1; +drop table t1, t2; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1),(1),(2),(2),(3),(3); +create view v1 as select b from t1; +select distinct b from v1; +b +-1 +-2 +-3 +select distinct b from v1 limit 2; +b +-1 +-2 +select distinct b from t1 limit 2; +b +-1 +-2 +prepare stmt1 from "select distinct b from v1 limit 2"; +execute stmt1; +b +-1 +-2 +execute stmt1; +b +-1 +-2 +deallocate prepare stmt1; +drop view v1; +create view v1 as select c from t1; +select distinct c from v1; +c +-1 +-2 +-3 +select distinct c from v1 limit 2; +c +-1 +-2 +select distinct c from t1 limit 2; +c +-1 +-2 +prepare stmt1 from "select distinct c from v1 limit 2"; +execute stmt1; +c +-1 +-2 +execute stmt1; +c +-1 +-2 +deallocate prepare stmt1; +drop view v1; +drop table t1; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +create view v1 as select * from t1 where b > -2 && c >-2 with check option; +insert into v1 (a) values (1); +insert into v1 (a) values (3); +ERROR HY000: CHECK OPTION failed 'test.v1' +insert ignore into v1 (a) values (2),(3),(0); +Warnings: +Error 1369 CHECK OPTION failed 'test.v1' +Error 1369 CHECK OPTION failed 'test.v1' +select * from t1; +a b c +1 -1 -1 +0 0 0 +drop view v1; +drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_view_myisam.result b/mysql-test/suite/vcol/r/vcol_view_myisam.result new file mode 100644 index 00000000000..bd5999792ff --- /dev/null +++ b/mysql-test/suite/vcol/r/vcol_view_myisam.result @@ -0,0 +1,276 @@ +SET @@session.storage_engine = 'MyISAM'; +create table t1 (a int not null, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1), (1), (2), (2), (3); +create view v1 (d,e) as select abs(b), abs(c) from t1; +select d,e from v1; +d e +1 1 +1 1 +2 2 +2 2 +3 3 +select is_updatable from information_schema.views where table_name='v1'; +is_updatable +NO +explain extended select d,e from v1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 +Warnings: +Note 1003 select abs(`test`.`t1`.`b`) AS `d`,abs(`test`.`t1`.`c`) AS `e` from `test`.`t1` +create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1; +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select abs(`t1`.`b`) AS `d`,abs(`t1`.`c`) AS `e` from `t1` latin1 latin1_swedish_ci +select d,e from v2; +d e +1 1 +1 1 +2 2 +2 2 +3 3 +explain extended select d,e from v2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 100.00 +2 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00 +Warnings: +Note 1003 select `v2`.`d` AS `d`,`v2`.`e` AS `e` from `test`.`v2` +create view v3 (d,e) as select d*2, e*2 from v1; +select * from v3; +d e +2 2 +2 2 +4 4 +4 4 +6 6 +explain extended select * from v3; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 +Warnings: +Note 1003 select (abs(`test`.`t1`.`b`) * 2) AS `d`,(abs(`test`.`t1`.`c`) * 2) AS `e` from `test`.`t1` +drop view v1,v2,v3; +drop table t1; +create table t1 (a int not null, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1), (2), (3), (1), (2), (3); +create view v1 as select distinct b from t1; +select * from v1; +b +-1 +-2 +-3 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 +2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +1 -1 -1 +2 -2 -2 +3 -3 -3 +drop view v1; +create view v1 as select distinct c from t1; +select * from v1; +c +-1 +-2 +-3 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 +2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary +select * from t1; +a b c +1 -1 -1 +2 -2 -2 +3 -3 -3 +1 -1 -1 +2 -2 -2 +3 -3 -3 +drop view v1; +drop table t1; +create table t1 (a int not null, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1), (2), (3), (4); +create view v1 as select b+1 from t1 order by 1 desc limit 2; +select * from v1; +b+1 +0 +-1 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort +drop view v1; +create view v1 as select c+1 from t1 order by 1 desc limit 2; +select * from v1; +c+1 +0 +-1 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort +drop view v1; +drop table t1; +create table t1 (a int, +b int, +c int as (-a), +d int as (-a) persistent, +primary key(a)); +insert into t1 (a,b) values (10,2), (20,3), (30,4), (40,5), (50,10); +create view v1 (a,e,f,g) as select a, b+1,c+1,d+1 from t1; +update v1 set a=a+e; +select * from v1; +a e f g +13 3 -12 -12 +24 4 -23 -23 +35 5 -34 -34 +46 6 -45 -45 +61 11 -60 -60 +select * from t1; +a b c d +13 2 -13 -13 +24 3 -24 -24 +35 4 -35 -35 +46 5 -46 -46 +61 10 -61 -61 +delete from v1; +select * from v1; +a e f g +select * from t1; +a b c d +insert into v1 (a,e) values (60,15); +ERROR HY000: The target table v1 of the INSERT is not insertable-into +drop table t1; +drop view v1; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent, +primary key(a)); +insert into t1 (a) values (1), (2), (3); +create view v1 (x,y,z) as select a,b,c from t1 where b < -1; +select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.b= v1.y); +a x y z +1 NULL NULL NULL +2 2 -2 -2 +3 3 -3 -3 +drop view v1; +create view v1 (x,y,z) as select a,b,c from t1 where c < -1; +select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.c= v1.z); +a x y z +1 NULL NULL NULL +2 2 -2 -2 +3 3 -3 -3 +drop view v1; +drop table t1; +create table t1 (a1 int, +b1 int as (-a1), +c1 int as (-a1) persistent); +create table t2 (a2 int, +b2 int as (-a2), +c2 int as (-a2) persistent); +insert into t1 (a1) values (1), (2); +insert into t2 (a2) values (2), (3); +create view v1 as select * from t1,t2 union all select * from t1,t2; +select * from v1; +a1 b1 c1 a2 b2 c2 +1 -1 -1 2 -2 -2 +2 -2 -2 2 -2 -2 +1 -1 -1 3 -3 -3 +2 -2 -2 3 -3 -3 +1 -1 -1 2 -2 -2 +2 -2 -2 2 -2 -2 +1 -1 -1 3 -3 -3 +2 -2 -2 3 -3 -3 +drop view v1; +drop table t1, t2; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +create table t2 like t1; +create view v1 as select a,b,c from t1; +create view v2 as select a,b,c from t2 where b in (select b from v1); +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a`,`t2`.`b` AS `b`,`t2`.`c` AS `c` from `t2` where `t2`.`b` in (select `v1`.`b` from `v1`) latin1 latin1_swedish_ci +drop view v2, v1; +drop table t1, t2; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +insert into t1 (a) values (1),(1),(2),(2),(3),(3); +create view v1 as select b from t1; +select distinct b from v1; +b +-1 +-2 +-3 +select distinct b from v1 limit 2; +b +-1 +-2 +select distinct b from t1 limit 2; +b +-1 +-2 +prepare stmt1 from "select distinct b from v1 limit 2"; +execute stmt1; +b +-1 +-2 +execute stmt1; +b +-1 +-2 +deallocate prepare stmt1; +drop view v1; +create view v1 as select c from t1; +select distinct c from v1; +c +-1 +-2 +-3 +select distinct c from v1 limit 2; +c +-1 +-2 +select distinct c from t1 limit 2; +c +-1 +-2 +prepare stmt1 from "select distinct c from v1 limit 2"; +execute stmt1; +c +-1 +-2 +execute stmt1; +c +-1 +-2 +deallocate prepare stmt1; +drop view v1; +drop table t1; +create table t1 (a int, +b int as (-a), +c int as (-a) persistent); +create view v1 as select * from t1 where b > -2 && c >-2 with check option; +insert into v1 (a) values (1); +insert into v1 (a) values (3); +ERROR HY000: CHECK OPTION failed 'test.v1' +insert ignore into v1 (a) values (2),(3),(0); +Warnings: +Error 1369 CHECK OPTION failed 'test.v1' +Error 1369 CHECK OPTION failed 'test.v1' +select * from t1; +a b c +1 -1 -1 +0 0 0 +drop view v1; +drop table t1; diff --git a/mysql-test/suite/vcol/t/rpl_vcol.test b/mysql-test/suite/vcol/t/rpl_vcol.test new file mode 100644 index 00000000000..43003f80ee9 --- /dev/null +++ b/mysql-test/suite/vcol/t/rpl_vcol.test @@ -0,0 +1,70 @@ +################################################################################ +# t/vcol_rpl.test # +# # +# Purpose: # +# Test replication of tables with virtual columns. # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +SET @@session.storage_engine = 'InnoDB'; + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source include/master-slave.inc + +connection master; +create table t1 (a int, b int as (a+1)); +show create table t1; +insert into t1 values (1,default); +insert into t1 values (2,default); +select * from t1; +save_master_pos; + +connection slave; +sync_with_master; +select * from t1; + +connection master; +drop table t1; +save_master_pos; + +connection slave; +sync_with_master; + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc +--source include/rpl_end.inc diff --git a/mysql-test/suite/vcol/t/vcol_archive.test b/mysql-test/suite/vcol/t/vcol_archive.test new file mode 100644 index 00000000000..c0c9ecc445d --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_archive.test @@ -0,0 +1,49 @@ +################################################################################ +# t/vcol_archive.test # +# # +# Purpose: # +# ARCHIVE branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_archive.inc +SET @@session.storage_engine = 'archive'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests +--source suite/vcol/inc/vcol_unsupported_storage_engines.inc + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_blackhole.test b/mysql-test/suite/vcol/t/vcol_blackhole.test new file mode 100644 index 00000000000..eac074d9595 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_blackhole.test @@ -0,0 +1,49 @@ +################################################################################ +# t/vcol_blackhole.test # +# # +# Purpose: # +# BLACKHOLE branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_blackhole.inc +SET @@session.storage_engine = 'blackhole'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests +--source suite/vcol/inc/vcol_unsupported_storage_engines.inc + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_innodb.test b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_innodb.test new file mode 100644 index 00000000000..baefddc0fd1 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_innodb.test @@ -0,0 +1,52 @@ +################################################################################ +# t/vcol_supported_sql_funcs.test # +# # +# Purpose: # +# Test SQL functions not allowed for virtual columns # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-08-31 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +let $skip_full_text_checks = 1; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_blocked_sql_funcs_main.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_myisam.test b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_myisam.test new file mode 100644 index 00000000000..d8eddb4ef15 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_myisam.test @@ -0,0 +1,49 @@ +################################################################################ +# t/vcol_supported_sql_funcs.test # +# # +# Purpose: # +# Test SQL functions not allowed for virtual columns # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-08-31 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_blocked_sql_funcs_main.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test b/mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test new file mode 100644 index 00000000000..e11618163cc --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test @@ -0,0 +1,51 @@ +################################################################################ +# t/vcol_column_def_options_innodb.test # +# # +# Purpose: # +# Testing different optional parameters of virtual columns. # +# # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_column_def_options.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test b/mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test new file mode 100644 index 00000000000..5c3a4619834 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test @@ -0,0 +1,50 @@ +################################################################################ +# t/vcol_column_def_options_myisam.test # +# # +# Purpose: # +# Testing different optional parameters of virtual columns. # +# # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_column_def_options.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_csv.test b/mysql-test/suite/vcol/t/vcol_csv.test new file mode 100644 index 00000000000..75ddf819818 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_csv.test @@ -0,0 +1,48 @@ +################################################################################ +# t/vcol_csv.test # +# # +# Purpose: # +# CSV branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_csv.inc +SET @@session.storage_engine = 'CSV'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines + +#------------------------------------------------------------------------------# +--source suite/vcol/inc/vcol_unsupported_storage_engines.inc + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_handler_innodb.test b/mysql-test/suite/vcol/t/vcol_handler_innodb.test new file mode 100644 index 00000000000..1a50aeaaa86 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_handler_innodb.test @@ -0,0 +1,51 @@ +################################################################################ +# t/vcol_handler_innodb.test # +# # +# Purpose: # +# Testing HANDLER. +# # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_handler.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_handler_maria.test b/mysql-test/suite/vcol/t/vcol_handler_maria.test new file mode 100644 index 00000000000..9b69e600767 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_handler_maria.test @@ -0,0 +1,52 @@ +################################################################################ +# t/vcol_handler_maria.test # +# # +# Purpose: # +# Testing HANDLER. +# # +# Maria branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +--source include/have_maria.inc + +# +# NOTE: PLEASE DO NOT ADD NOT MARIA SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'maria'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_handler.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_handler_myisam.test b/mysql-test/suite/vcol/t/vcol_handler_myisam.test new file mode 100644 index 00000000000..5aa16da180a --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_handler_myisam.test @@ -0,0 +1,50 @@ +################################################################################ +# t/vcol_handler_myisam.test # +# # +# Purpose: # +# Testing HANDLER. +# # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_handler.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test b/mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test new file mode 100644 index 00000000000..3b83c7f4565 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test @@ -0,0 +1,51 @@ +################################################################################ +# t/vcol_ins_upd_innodb.test # +# # +# Purpose: # +# Testing DDL operations such as INSERT, UPDATE, REPLACE and DELETE. # +# # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_ins_upd.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test b/mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test new file mode 100644 index 00000000000..7840c191194 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test @@ -0,0 +1,50 @@ +################################################################################ +# t/vcol_ins_upd_myisam.test # +# # +# Purpose: # +# Testing DDL operations such as INSERT, UPDATE, REPLACE and DELETE. # +# # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_ins_upd.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_keys_innodb.test b/mysql-test/suite/vcol/t/vcol_keys_innodb.test new file mode 100644 index 00000000000..d44d2f701cf --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_keys_innodb.test @@ -0,0 +1,52 @@ +################################################################################ +# t/vcol_keys_innodb.test # +# # +# Purpose: # +# Testing keys, indexes defined upon virtual columns. # +# # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +let $skip_spatial_index_check = 1; +--source suite/vcol/inc/vcol_keys.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_keys_myisam.test b/mysql-test/suite/vcol/t/vcol_keys_myisam.test new file mode 100644 index 00000000000..87d7b79aa1c --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_keys_myisam.test @@ -0,0 +1,50 @@ +################################################################################ +# t/vcol_keys_myisam.test # +# # +# Purpose: # +# Testing keys, indexes defined upon virtual columns. # +# # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_keys.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_memory.test b/mysql-test/suite/vcol/t/vcol_memory.test new file mode 100644 index 00000000000..f481427fa93 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_memory.test @@ -0,0 +1,48 @@ +################################################################################ +# t/vcol_memory.test # +# # +# Purpose: # +# MEMORY branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-02 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +SET @@session.storage_engine = 'memory'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests +--source suite/vcol/inc/vcol_unsupported_storage_engines.inc + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_merge.test b/mysql-test/suite/vcol/t/vcol_merge.test new file mode 100644 index 00000000000..a1d3c628c8e --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_merge.test @@ -0,0 +1,57 @@ +################################################################################ +# t/vcol_merge.test # +# # +# Purpose: # +# MERGE branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-03 # +# Change Author: Oleksandr Byelkin (Monty program Ab) +# Date: 2009-03-24 +# Change: Syntax changed +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests +--disable_warnings +drop table if exists t1, t2, t3; +--enable_warnings + +create table t1 (a int, b int as (a % 10)); +create table t2 (a int, b int as (a % 10)); +insert into t1 values (1,default); +insert into t2 values (2,default); +--error ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS +create table t3 (a int, b int as (a % 10)) engine=MERGE UNION=(t1,t2); +drop table t1,t2; + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test new file mode 100644 index 00000000000..2a8d9a576b4 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -0,0 +1,142 @@ +--source include/have_ucs2.inc + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +# +# Bug#601164: DELETE/UPDATE with ORDER BY index and LIMIT +# + +create table t1 (a int, b int, v int as (a+1), index idx(b)); +insert into t1(a, b) values + (4, 40), (3, 30), (5, 50), (7, 70), (8, 80), (2, 20), (1, 10); + +select * from t1 order by b; + +delete from t1 where v > 6 order by b limit 1; +select * from t1 order by b; + +update t1 set a=v order by b limit 1; +select * from t1 order by b; + +drop table t1; + +# +# Bug#604549: Expression for virtual column returns row +# + +-- error ER_ROW_EXPR_FOR_VCOL +CREATE TABLE t1 ( + a int NOT NULL DEFAULT '0', + v double AS ((1, a)) VIRTUAL +); + +# +# Bug#603654: Virtual column in ORDER BY, no other references of table columns +# + +CREATE TABLE t1 ( + a CHAR(255) BINARY NOT NULL DEFAULT 0, + b CHAR(255) BINARY NOT NULL DEFAULT 0, + v CHAR(255) BINARY AS (CONCAT(a,b)) VIRTUAL ); +INSERT INTO t1(a,b) VALUES ('4','7'), ('4','6'); +SELECT 1 AS C FROM t1 ORDER BY v; + +DROP TABLE t1; + +# +# Bug#603186: Insert into a table with stored vurtual columns +# + +CREATE TABLE t1(a int, b int DEFAULT 0, v INT AS (b+10) PERSISTENT); +INSERT INTO t1(a) VALUES (1); +SELECT b, v FROM t1; + +DROP TABLE t1; + +CREATE TABLE t1(a int DEFAULT 100, v int AS (a+1) PERSISTENT); +INSERT INTO t1 () VALUES (); +CREATE TABLE t2(a int DEFAULT 100 , v int AS (a+1)); +INSERT INTO t2 () VALUES (); + +SELECT a, v FROM t1; +SELECT a, v FROM t2; + +DROP TABLE t1,t2; + +# +# Bug#604503: Virtual column expression with datetime comparison +# + +CREATE TABLE t1 ( + a datetime NOT NULL DEFAULT '2000-01-01', + v boolean AS (a < '2001-01-01') +); +INSERT INTO t1(a) VALUES ('2002-02-15'); +INSERT INTO t1(a) VALUES ('2000-10-15'); + +SELECT a, v FROM t1; +SELECT a, v FROM t1; + +CREATE TABLE t2 ( + a datetime NOT NULL DEFAULT '2000-01-01', + v boolean AS (a < '2001-01-01') PERSISTENT +); +INSERT INTO t2(a) VALUES ('2002-02-15'); +INSERT INTO t2(a) VALUES ('2000-10-15'); + +SELECT * FROM t2; + +DROP TABLE t1, t2; + +# +# Bug#607566: Virtual column in the select list of SELECT with ORDER BY +# + +CREATE TABLE t1 ( + a char(255), b char(255), c char(255), d char(255), + v char(255) AS (CONCAT(c,d) ) VIRTUAL +); + +INSERT INTO t1(a,b,c,d) VALUES ('w','x','y','z'), ('W','X','Y','Z'); + +SELECT v FROM t1 ORDER BY CONCAT(a,b); + +DROP TABLE t1; + +# +# Bug#607168: CREATE TABLE AS SELECT that returns virtual columns +# + +CREATE TABLE t1 (f1 INTEGER, v1 INTEGER AS (f1) VIRTUAL); +CREATE TABLE t2 AS SELECT v1 FROM t1; +SHOW CREATE TABLE t2; + +DROP TABLE t1,t2; + +# +# Bug#607177: ROUND function in the expression for a virtual function +# + +CREATE TABLE t1 (p int, a double NOT NULL, v double AS (ROUND(a,p)) VIRTUAL); +INSERT INTO t1 VALUES (0,1,0); +INSERT INTO t1 VALUES (NULL,0,0); +SELECT a, p, v, ROUND(a,p), ROUND(a,p+NULL) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (p int, a double NOT NULL); +INSERT INTO t1(p,a) VALUES (0,1); +INSERT INTO t1(p,a) VALUES (NULL,0); +SELECT a, p, ROUND(a,p), ROUND(a,p+NULL) FROM t1; +DROP TABLE t1; + +# +# Bug#610890: SHOW CREATE TABLE with a virtual column +# + +CREATE TABLE t1 (a char(32), v char(32) CHARACTER SET ucs2 AS (a) VIRTUAL); + +SHOW CREATE TABLE t1; + +DROP TABLE t1; diff --git a/mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test b/mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test new file mode 100644 index 00000000000..42834d5c0bb --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test @@ -0,0 +1,53 @@ +################################################################################ +# t/vcol_non_stored_columns_innodb.test # +# # +# Purpose: # +# Ensure that MySQL behaviour is consistent irrelevant of # +# - the place of a non-stored column among other columns, # +# - the total number of non-stored fields. # +# # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_non_stored_columns.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test b/mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test new file mode 100644 index 00000000000..32481e792ec --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test @@ -0,0 +1,52 @@ +################################################################################ +# t/vcol_non_stored_columns_myisam.test # +# # +# Purpose: # +# Ensure that MySQL behaviour is consistent irrelevant of # +# - the place of a non-stored column among other columns, # +# - the total number of non-stored fields. # +# # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_non_stored_columns.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_partition_innodb.test b/mysql-test/suite/vcol/t/vcol_partition_innodb.test new file mode 100644 index 00000000000..47f1581fc96 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_partition_innodb.test @@ -0,0 +1,52 @@ +################################################################################ +# t/vcol_partition_innodb.test # +# # +# Purpose: # +# Testing partitioning tables with virtual columns. # +# # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ +--source include/have_partition.inc + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_partition.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_partition_myisam.test b/mysql-test/suite/vcol/t/vcol_partition_myisam.test new file mode 100644 index 00000000000..25f0d42c300 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_partition_myisam.test @@ -0,0 +1,51 @@ +################################################################################ +# t/vcol_partition_myisam.test # +# # +# Purpose: # +# Testing partitioning tables with virtual columns. # +# # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ +--source include/have_partition.inc + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_partition.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_select_innodb.test b/mysql-test/suite/vcol/t/vcol_select_innodb.test new file mode 100644 index 00000000000..787f5fe77a7 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_select_innodb.test @@ -0,0 +1,51 @@ +################################################################################ +# t/vcol_select_innodb.test # +# # +# Purpose: # +# Testing different SELECTs. # +# # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-18 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_select.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_select_myisam.test b/mysql-test/suite/vcol/t/vcol_select_myisam.test new file mode 100644 index 00000000000..855e02ac113 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_select_myisam.test @@ -0,0 +1,50 @@ +################################################################################ +# t/vcol_select.test # +# # +# Purpose: # +# Testing different SELECTs. # +# # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-18 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_select.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_innodb.test b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_innodb.test new file mode 100644 index 00000000000..32e2600c2fc --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_innodb.test @@ -0,0 +1,50 @@ +################################################################################ +# t/vcol_supported_sql_funcs.test # +# # +# Purpose: # +# Test SQL functions allowed for virtual columns # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-08-31 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_supported_sql_funcs_main.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_myisam.test b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_myisam.test new file mode 100644 index 00000000000..aa5833451c6 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_myisam.test @@ -0,0 +1,49 @@ +################################################################################ +# t/vcol_supported_sql_funcs.test # +# # +# Purpose: # +# Test SQL functions allowed for virtual columns # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-08-31 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_supported_sql_funcs_main.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_syntax.test b/mysql-test/suite/vcol/t/vcol_syntax.test new file mode 100644 index 00000000000..6dc3cf43317 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_syntax.test @@ -0,0 +1,30 @@ +# +# test syntax +# +--disable_warnings +drop table if exists t1; +--enable_warnings + +set @OLD_SQL_MODE=@@SESSION.SQL_MODE; +create table t1 (a int, b int generated always as (a+1)); +show create table t1; +drop table t1; +create table t1 (a int, b int as (a+1) virtual); +show create table t1; +drop table t1; +create table t1 (a int, b int generated always as (a+1) persistent); +show create table t1; +drop table t1; + +set session sql_mode='ORACLE'; +create table t1 (a int, b int as (a+1)); +show create table t1; +drop table t1; +create table t1 (a int, b int generated always as (a+1) virtual); +show create table t1; +drop table t1; +create table t1 (a int, b int as (a+1) persistent); +show create table t1; +drop table t1; +set session sql_mode=@OLD_SQL_MODE; + diff --git a/mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test b/mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test new file mode 100644 index 00000000000..57655d6d3fe --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test @@ -0,0 +1,52 @@ +################################################################################ +# t/vcol_trigger_sp_innodb.test # +# # +# Purpose: # +# Testing triggers, stored procedures and functions # +# defined on tables with virtual columns. # +# # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_trigger_sp.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test b/mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test new file mode 100644 index 00000000000..c475a31eaa6 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test @@ -0,0 +1,51 @@ +################################################################################ +# t/vcol_trigger_sp_myisam.test # +# # +# Purpose: # +# Testing triggers, stored procedures and functions # +# defined on tables with virtual columns. # +# # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_trigger_sp.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_view_innodb.test b/mysql-test/suite/vcol/t/vcol_view_innodb.test new file mode 100644 index 00000000000..322fb122436 --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_view_innodb.test @@ -0,0 +1,51 @@ +################################################################################ +# t/vcol_view_innodb.test # +# # +# Purpose: # +# Testing views defined on tables with virtual columns. # +# # +# InnoDB branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +--source include/have_xtradb.inc +eval SET @@session.storage_engine = 'InnoDB'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_view.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_view_myisam.test b/mysql-test/suite/vcol/t/vcol_view_myisam.test new file mode 100644 index 00000000000..2ebd36431bc --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_view_myisam.test @@ -0,0 +1,50 @@ +################################################################################ +# t/vcol_view_myisam.test # +# # +# Purpose: # +# Testing views defined on tables with virtual columns. # +# # +# MyISAM branch # +# # +#------------------------------------------------------------------------------# +# Original Author: Andrey Zhakov # +# Original Date: 2008-09-04 # +# Change Author: # +# Change Date: # +# Change: # +################################################################################ + +# +# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE ! +# TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN +# THE SOURCED FILES ONLY. +# + +#------------------------------------------------------------------------------# +# General not engine specific settings and requirements +--source suite/vcol/inc/vcol_init_vars.pre + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc + +#------------------------------------------------------------------------------# +# Engine specific settings and requirements + +##### Storage engine to be tested +# Set the session storage engine +eval SET @@session.storage_engine = 'MyISAM'; + +##### Workarounds for known open engine specific bugs +# none + +#------------------------------------------------------------------------------# +# Execute the tests to be applied to all storage engines +--source suite/vcol/inc/vcol_view.inc + +#------------------------------------------------------------------------------# +# Execute storage engine specific tests + +#------------------------------------------------------------------------------# +# Cleanup +--source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/t/bug46080-master.opt b/mysql-test/t/bug46080-master.opt index ff809c0cc69..b1c244a121c 100644 --- a/mysql-test/t/bug46080-master.opt +++ b/mysql-test/t/bug46080-master.opt @@ -1 +1 @@ ---skip-grant-tables --skip-name-resolve --safemalloc-mem-limit=20000000 --loose-maria-pagecache-buffer-size=1M +--skip-grant-tables --skip-name-resolve --safemalloc-mem-limit=20000000 --loose-aria-pagecache-buffer-size=1M diff --git a/mysql-test/t/change_user.test b/mysql-test/t/change_user.test index 1d3a3fd810f..b4ac526a80e 100644 --- a/mysql-test/t/change_user.test +++ b/mysql-test/t/change_user.test @@ -1,4 +1,61 @@ # +# functional change user tests +# + +grant select on test.* to test_nopw; +grant select on test.* to test_oldpw identified by password "09301740536db389"; +grant select on test.* to test_newpw identified by "newpw"; + +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); + +# +# massaging the data for tests to pass in the embedded server, +# that has authentication completely disabled or, if enabled, can +# only do new auth (20-byte scramble). +# + +change_user test_nopw; +--replace_result <@> <test_nopw@%> @> @localhost> +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); + +# +# embedded with enabled privilege control cannot do plugin negotiation. +# that is, it cannot try to authenticate with a new scramble, receive a request +# to switch to an old scramble, and retry with an old scramble. +# As a result, it cannot change to a user that has old scramble and +# and it stays logged as a previous user - test_nopw in this test file. +# For the embedded with auth we replace nopw with oldpw in the results. +# +let $repl = `select if(version() like '%embedded%' and user() like '%nopw%', 'nopw', 'oldpw')`; + +change_user test_oldpw, oldpw; +--replace_result <@> <test_oldpw@%> @> @localhost> $repl oldpw +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +change_user test_newpw, newpw; +--replace_result <@> <test_newpw@%> @> @localhost> +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +change_user root; +--replace_result <@> <root@localhost> @> @localhost> +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); + +change_user test_nopw,,test; +--replace_result <@> <test_nopw@%> @> @localhost> +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +change_user test_oldpw,oldpw,test; +--replace_result <@> <test_oldpw@%> @> @localhost> $repl oldpw +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +change_user test_newpw,newpw,test; +--replace_result <@> <test_newpw@%> @> @localhost> +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); +change_user root,,test; +--replace_result <@> <root@localhost> @> @localhost> +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); + +drop user test_nopw; +drop user test_oldpw; +drop user test_newpw; + +# # Bug#20023 mysql_change_user() resets the value of SQL_BIG_SELECTS # The replace's are here to fix things for 32 bit systems # diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index 671f7baa61e..e5c6e8371bf 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -353,6 +353,47 @@ FLUSH PRIVILEGES; --disconnect extracon2 --connection default +# +# A couple of plugin tests - for builtin plugins only +# +CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB'; +CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389'; + +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon1,localhost,mysqltest_up1,foo,,$MASTER_MYPORT,); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +connect(pcon2,localhost,mysqltest_up1,bar,,$MASTER_MYPORT,); +connection pcon2; +select user(), current_user(); +disconnect pcon2; + +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon3,localhost,mysqltest_up2,newpw,,$MASTER_MYPORT,); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +connect(pcon4,localhost,mysqltest_up2,oldpw,,$MASTER_MYPORT,); +connection pcon4; +select user(), current_user(); +disconnect pcon4; + +# +# lpbug#683112 Maria 5.2 incorrectly reports "(using password: NO)" +# even when password is specified +# +# test "access denied" error for nonexisting user with and without a password +# +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon5,localhost,mysqltest_nouser,newpw,,$MASTER_MYPORT,); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon5,localhost,mysqltest_nouser,,,$MASTER_MYPORT,); + +connection default; +DROP USER mysqltest_up1@'%'; +DROP USER mysqltest_up2@'%'; + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index fa991aab0d7..8f39fb0e0b9 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1384,11 +1384,11 @@ drop function f1; # Bug#25629 CREATE TABLE LIKE does not work with INFORMATION_SCHEMA # create table t1 like information_schema.processlist; ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" show create table t1; drop table t1; create temporary table t1 like information_schema.processlist; ---replace_result ENGINE=MyISAM "" ENGINE=MARIA "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" +--replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" show create table t1; drop table t1; create table t1 like information_schema.character_sets; diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index a57235d744b..85b51335329 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -1205,7 +1205,6 @@ create event e1 on schedule every 1 day do select 1; select @@sql_mode; set @@sql_mode= @old_mode; # Rename SQL modes that differ in name between the server and the table definition. -select replace(@full_mode, '?', 'NOT_USED') into @full_mode; select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; select name from mysql.event where name = 'p' and sql_mode = @full_mode; drop event e1; diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index e764ee80578..f516ec6ab03 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -152,7 +152,7 @@ DROP TABLE t1; --echo # explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode --echo # -CREATE TABLE t1 (f1 INT); +CREATE TABLE t1 (f1 INT not null); SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 177a1ca2471..8c2be79ee7d 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1142,3 +1142,12 @@ DROP TABLE t1; --echo # --echo End of 5.1 tests +--echo # LP BUG#813418 - incorrect optimisation of max/min by index for +--echo # negated BETWEEN +CREATE TABLE t1 (a int, KEY (a)); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +SELECT MAX(a) FROM t1 WHERE a NOT BETWEEN 3 AND 9; +drop table t1; + +--echo # +--echo End of 5.1 tests diff --git a/mysql-test/t/information_schema_all_engines.test b/mysql-test/t/information_schema_all_engines.test index b3b1d2d2f6b..b20ce60985c 100644 --- a/mysql-test/t/information_schema_all_engines.test +++ b/mysql-test/t/information_schema_all_engines.test @@ -12,7 +12,7 @@ use INFORMATION_SCHEMA; show tables; # -# Bug#18925: subqueries with MIN/MAX functions on INFORMARTION_SCHEMA +# Bug#18925: subqueries with MIN/MAX functions on INFORMATION_SCHEMA # SELECT t.table_name, c1.column_name diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index f12d20e962e..f415d670bf1 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -1,11 +1,13 @@ # -# Test of multiple key caches +# Test of multiple key caches, simple and segmented # --disable_warnings drop table if exists t1, t2, t3; --enable_warnings -SET @save_key_buffer=@@key_buffer_size; +SET @save_key_buffer_size=@@key_buffer_size; +SET @save_key_cache_block_size=@@key_cache_block_size; +SET @save_key_cache_segments=@@key_cache_segments; SELECT @@key_buffer_size, @@small.key_buffer_size; @@ -33,7 +35,7 @@ SELECT @@`default`.key_buffer_size; SELECT @@small.key_buffer_size; SELECT @@medium.key_buffer_size; -SET @@global.key_buffer_size=@save_key_buffer; +SET @@global.key_buffer_size=@save_key_buffer_size; # # Errors @@ -248,3 +250,272 @@ SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; DROP TABLE t1; # End of 4.1 tests + +# End of 5.1 tests + +# +# Test cases for segmented key caches +# + +# Test usage of the KEY_CACHE table from information schema +# for a simple key cache + +set global key_buffer_size=@save_key_buffer_size; +set global key_cache_block_size=@save_key_cache_block_size; +select @@key_buffer_size; +select @@key_cache_block_size; +select @@key_cache_segments; + +create table t1 ( + p int not null auto_increment primary key, + a char(10)); +create table t2 ( + p int not null auto_increment primary key, + i int, a char(10), key k1(i), key k2(a)); + +select @@key_cache_segments; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +insert into t1 values (1, 'qqqq'), (2, 'yyyy'); +insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), + (3, 1, 'yyyy'), (4, 3, 'zzzz'); +select * from t1; +select * from t2; +update t1 set p=3 where p=1; +update t2 set i=2 where i=1; + +--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED 1789 KEY_BLOCKS_UNUSED +show status like 'key_%'; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +delete from t2 where a='zzzz'; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +delete from t1; +delete from t2; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +# For the key cache with 2 segments execute the same sequence of +# statements as for the simple cache above. +# The statistical information on the number of i/o requests and +# the number of is expected to be the same. + +set global key_cache_segments=2; +select @@key_cache_segments; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +insert into t1 values (1, 'qqqq'), (2, 'yyyy'); +insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), + (3, 1, 'yyyy'), (4, 3, 'zzzz'); +select * from t1; +select * from t2; +update t1 set p=3 where p=1; +update t2 set i=2 where i=1; + +--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED 1788 KEY_BLOCKS_UNUSED +show status like 'key_%'; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +delete from t1; +delete from t2; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +# Check that we can work with one segment with the same results + +set global key_cache_segments=1; +select @@key_cache_segments; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +insert into t1 values (1, 'qqqq'), (2, 'yyyy'); +insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), + (3, 1, 'yyyy'), (4, 3, 'zzzz'); +select * from t1; +select * from t2; +update t1 set p=3 where p=1; +update t2 set i=2 where i=1; + +--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED 1789 KEY_BLOCKS_UNUSED +show status like 'key_%'; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +delete from t1; +delete from t2; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +flush tables; flush status; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +# Switch back to 2 segments + +set global key_buffer_size=32*1024; +select @@key_buffer_size; +set global key_cache_segments=2; +select @@key_cache_segments; +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +insert into t1 values (1, 'qqqq'), (2, 'yyyy'); +insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), + (3, 1, 'yyyy'), (4, 3, 'zzzz'); +select * from t1; +select * from t2; +update t1 set p=3 where p=1; +update t2 set i=2 where i=1; + +--replace_column 7 # +select * from information_schema.key_caches where segment_number is null; + +# Add more rows to tables t1 and t2 + +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; +insert into t1(a) select a from t1; + +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; +insert into t2(i,a) select i,a from t2; + +--replace_column 6 # 7 # 10 # +select * from information_schema.key_caches where segment_number is null; + +select * from t1 where p between 1010 and 1020 ; +select * from t2 where p between 1010 and 1020 ; +--replace_column 6 # 7 # 10 # +select * from information_schema.key_caches where segment_number is null; + +flush tables; flush status; +update t1 set a='zzzz' where a='qqqq'; +update t2 set i=1 where i=2; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +# Now test how we can work with 7 segments + +set global keycache1.key_buffer_size=256*1024; +select @@keycache1.key_buffer_size; +set global keycache1.key_cache_segments=7; +select @@keycache1.key_cache_segments; + +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; +--replace_column 7 # +select * from information_schema.key_caches where key_cache_name like "key%" + and segment_number is null; + +cache index t1 key (`primary`) in keycache1; + +explain select p from t1 where p between 1010 and 1020; +select p from t1 where p between 1010 and 1020; +explain select i from t2 where p between 1010 and 1020; +select i from t2 where p between 1010 and 1020; +explain select count(*) from t1, t2 where t1.p = t2.i; +select count(*) from t1, t2 where t1.p = t2.i; + +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; +--replace_column 7 # +select * from information_schema.key_caches where key_cache_name like "key%" + and segment_number is null; + +cache index t2 in keycache1; +update t2 set p=p+3000, i=2 where a='qqqq'; +--replace_column 7 # +select * from information_schema.key_caches where key_cache_name like "key%" + and segment_number is null; + +set global keycache2.key_buffer_size=1024*1024; +cache index t2 in keycache2; +insert into t2 values (2000, 3, 'yyyy'); +--replace_column 7 # +select * from information_schema.key_caches where key_cache_name like "keycache2" + and segment_number is null; +--replace_column 7 # +select * from information_schema.key_caches where key_cache_name like "key%" + and segment_number is null; + +cache index t2 in keycache1; +update t2 set p=p+5000 where a='zzzz'; +select * from t2 where p between 1010 and 1020; +explain select p from t2 where p between 1010 and 1020; +select p from t2 where p between 1010 and 1020; +explain select i from t2 where a='yyyy' and i=3; +select i from t2 where a='yyyy' and i=3; +explain select a from t2 where a='yyyy' and i=3; +select a from t2 where a='yyyy' and i=3 ; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_cache_block_size=2*1024; +insert into t2 values (7000, 3, 'yyyy'); +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_cache_block_size=8*1024; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; +insert into t2 values (8000, 3, 'yyyy'); +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_buffer_size=64*1024; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_cache_block_size=2*1024; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_cache_block_size=8*1024; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_buffer_size=0; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_cache_block_size=8*1024; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_buffer_size=0; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_buffer_size=128*1024; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +set global keycache1.key_cache_block_size=1024; +--replace_column 6 # 7 # +select * from information_schema.key_caches where segment_number is null; + +drop table t1,t2; + +set global keycache1.key_buffer_size=0; +set global keycache2.key_buffer_size=0; + +set global key_buffer_size=@save_key_buffer_size; +set global key_cache_segments=@save_key_cache_segments; + +# End of 5.2 tests diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test index 30f4d4d6c61..fdacb9c57d4 100644 --- a/mysql-test/t/lock.test +++ b/mysql-test/t/lock.test @@ -245,3 +245,28 @@ UNLOCK TABLES; DROP TABLE t1,t2; --echo End of 5.1 tests. + +# +# Test concurrent lock and read locks +# This gave a warning: +# Warning at 'read lock with old write lock' for lock: 5: +# Found lock of type 8 that is write and read locked. Read_no_write_count: 1 +# +create table t1 (a int) engine=myisam; +lock tables t1 write concurrent, t1 as t2 read; +connect (con1,localhost,root,,); +connection con1; +lock tables t1 read local; +unlock tables; +connection default; +unlock tables; +connection con1; +lock tables t1 read local; +connection default; +lock tables t1 write concurrent, t1 as t2 read; +unlock tables; +connection con1; +unlock tables; +disconnect con1; +connection default; +drop table t1; diff --git a/mysql-test/t/log_slow.test b/mysql-test/t/log_slow.test index 303d5bf8deb..d624e9f2520 100644 --- a/mysql-test/t/log_slow.test +++ b/mysql-test/t/log_slow.test @@ -36,6 +36,12 @@ select @@log_slow_verbosity; show fields from mysql.slow_log; +# +# Check flush command +# + +flush slow query logs; + # Reset used variables set @@log_slow_filter=default; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 0af9a7b7692..27352ca3c6f 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1711,3 +1711,6 @@ DROP TABLE t1; SET GLOBAL myisam_use_mmap=default; --echo End of 5.1 tests + +show variables like 'myisam_block_size'; +select @@global.myisam_block_size; diff --git a/mysql-test/t/mysqlbinlog-innodb.test b/mysql-test/t/mysqlbinlog-innodb.test new file mode 100644 index 00000000000..49702e8db38 --- /dev/null +++ b/mysql-test/t/mysqlbinlog-innodb.test @@ -0,0 +1,31 @@ +-- source include/have_binlog_format_statement.inc +-- source include/have_log_bin.inc +-- source include/have_innodb.inc + +# +# MBug#702303: Spurious `use` statements in output from mysqlbinlog --rewrite-db="a->b" +# +let $MYSQLD_DATADIR= `select @@datadir`; +SET TIMESTAMP=1000000000; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb; +CREATE DATABASE test2; + +RESET MASTER; +USE test2; +BEGIN; +USE test; +INSERT INTO t1 VALUES (1); +USE test2; +COMMIT; +BEGIN; +USE test; +INSERT INTO t1 VALUES (2); +USE test2; +COMMIT; +USE test; +SELECT * FROM t1 ORDER BY a; +FLUSH LOGS; +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --short-form +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --short-form --rewrite-db="test->foo" --rewrite-db="test2->bar" +DROP DATABASE test2; +DROP TABLE t1; diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 986b5aba385..ce6e3dc8bf7 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -136,6 +136,7 @@ DROP TABLE `@`; CREATE TABLE `Ñ` (a INT); SET NAMES DEFAULT; +call mtr.add_suppression("@003f.frm' \\(errno: 22\\)"); --echo mysqlcheck --default-character-set="latin1" --databases test # Error returned depends on platform, replace it with "Table doesn't exist" --replace_result "Can't find file: './test/@003f.frm' (errno: 22)" "Table doesn't exist" "Table 'test.?' doesn't exist" "Table doesn't exist" diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 99537618011..a28dff09bce 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -661,6 +661,10 @@ a int(10), b varchar(30), c datetime, d blob, e text); insert into t1 values (NULL), (10), (20); insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thirty"); --exec $MYSQL_DUMP --skip-comments --xml --no-create-info test + +# Test if UNIQUE_CHECK is done correctly +--exec $MYSQL_DUMP --skip-comments --no-create-info test +--exec $MYSQL_DUMP --skip-comments test drop table t1, t2; diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index 7e574fd6a42..9db3ff93634 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -696,11 +696,13 @@ FLUSH TABLES; --remove_file $MYSQLD_DATADIR/test/t1.par --replace_result $MYSQLD_DATADIR ./ CHECK TABLE t1; ---error ER_UNKNOWN_ERROR +--replace_result $MYSQLD_DATADIR ./ +--error 29 SELECT * FROM t1; --echo # Note that it is currently impossible to drop a partitioned table --echo # without the .par file ---error ER_BAD_TABLE_ERROR +--replace_result $MYSQLD_DATADIR ./ +--error 29 DROP TABLE t1; --remove_file $MYSQLD_DATADIR/test/t1.frm --remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI diff --git a/mysql-test/t/partition_example.test b/mysql-test/t/partition_example.test new file mode 100644 index 00000000000..8c1b92b2e33 --- /dev/null +++ b/mysql-test/t/partition_example.test @@ -0,0 +1,23 @@ +--source include/not_windows_embedded.inc +--source include/have_example_plugin.inc +--source include/have_partition.inc + +--replace_regex /\.dll/.so/ +eval install plugin example soname '$HA_EXAMPLE_SO'; + +create table t1 (a int not null) +engine=example +partition by list (a) +(partition p0 values in (1), partition p1 values in (2)); +show create table t1; +drop table t1; + +create table t1 (a int not null) +engine=example ull=12340 +partition by list (a) +(partition p0 values in (1), partition p1 values in (2)); +show create table t1; +drop table t1; + +select 1; +uninstall plugin example; diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test index 9a1a750378c..406821e7a7c 100644 --- a/mysql-test/t/plugin.test +++ b/mysql-test/t/plugin.test @@ -22,6 +22,12 @@ SELECT * FROM t1; DROP TABLE t1; +# a couple of tests for variables +set global example_ulong_var=500; +set global example_enum_var= e1; +show status like 'example%'; +show variables like 'example%'; + UNINSTALL PLUGIN example; --error 1305 UNINSTALL PLUGIN EXAMPLE; @@ -78,4 +84,57 @@ set session sql_mode=@old_sql_mode; --error ER_INCORRECT_GLOBAL_LOCAL_VAR set session old=bla; +############################################################### +# engine-specific clauses in the CREATE TABLE: + +--echo #legal values +CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example ULL=10000 STR='dskj' one_or_two='one' YESNO=0; +show create table t1; +drop table t1; + +SET @OLD_SQL_MODE=@@SQL_MODE; +SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; + +--echo #illegal value fixed +CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS; +show create table t1; + +--echo #alter table +alter table t1 ULL=10000000; +show create table t1; +alter table t1 change a a int complex='c,c,c'; +show create table t1; +drop table t1; + +--echo #illegal value error +SET SQL_MODE=''; +--error ER_BAD_OPTION_VALUE +CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS; + +--error ER_PARSE_ERROR +CREATE TABLE t1 (a int) ENGINE=example ULL=10.00; + +--error ER_PARSE_ERROR +CREATE TABLE t1 (a int) ENGINE=example ULL=1e2; + +CREATE TABLE t1 (a int) ENGINE=example ULL=0x1234; +SHOW CREATE TABLE t1; + +select create_options from information_schema.tables where table_schema='test' and table_name='t1'; + +ALTER TABLE t1 ULL=DEFAULT; +SHOW CREATE TABLE t1; + +DROP TABLE t1; + +SET @@SQL_MODE=@OLD_SQL_MODE; + +# +# The only preparable statement above was CREATE TABLE. +# We need to prepare another statement here to force the +# previous one to be deallocated (mysqltest reuses the same handle) +# and to unlock all thread-local plugin locks. Otherwise the plugin won't +# uninstall. +# +select 1; UNINSTALL PLUGIN example; diff --git a/mysql-test/t/plugin_maturity-master.opt b/mysql-test/t/plugin_maturity-master.opt new file mode 100644 index 00000000000..70ba6280117 --- /dev/null +++ b/mysql-test/t/plugin_maturity-master.opt @@ -0,0 +1 @@ +--plugin-maturity=stable diff --git a/mysql-test/t/plugin_maturity.test b/mysql-test/t/plugin_maturity.test new file mode 100644 index 00000000000..fe95f19b803 --- /dev/null +++ b/mysql-test/t/plugin_maturity.test @@ -0,0 +1,6 @@ +--source include/have_example_plugin.inc + +# test for --plugin_maturity +--replace_regex /\.dll/.so/ +--error 1126 +eval INSTALL PLUGIN example SONAME '$HA_EXAMPLE_SO'; diff --git a/mysql-test/t/select_pkeycache-master.opt b/mysql-test/t/select_pkeycache-master.opt new file mode 100644 index 00000000000..a6c0f247334 --- /dev/null +++ b/mysql-test/t/select_pkeycache-master.opt @@ -0,0 +1 @@ +--key_cache_segments=7 diff --git a/mysql-test/t/select_pkeycache.test b/mysql-test/t/select_pkeycache.test new file mode 100644 index 00000000000..e0ee96e937a --- /dev/null +++ b/mysql-test/t/select_pkeycache.test @@ -0,0 +1,8 @@ + +# +# Run select.test with the segmented default key cache (with 7 segments) +# (see setting the number of segments in select_pkecache-master.opt) +# The result is expected the same as for select.test +# + +--source t/select.test diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 141d1604065..4fc48513652 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8210,7 +8210,6 @@ call p(); select @@sql_mode; set @@sql_mode= @old_mode; # Rename SQL modes that differ in name between the server and the table definition. -select replace(@full_mode, '?', 'NOT_USED') into @full_mode; select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; select name from mysql.proc where name = 'p' and sql_mode = @full_mode; drop procedure p; diff --git a/mysql-test/t/status_user-master.opt b/mysql-test/t/status_user-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/t/status_user-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/t/status_user.test b/mysql-test/t/status_user.test new file mode 100644 index 00000000000..d42f81b20e5 --- /dev/null +++ b/mysql-test/t/status_user.test @@ -0,0 +1,89 @@ +# +# Testing of user status (the userstat variable). +# Note that this test requires a fresh restart to not problems with +# old status + +-- source include/have_innodb.inc +-- source include/have_log_bin.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +select variable_value from information_schema.global_status where variable_name="handler_read_key" into @global_read_key; +show columns from information_schema.client_statistics; +show columns from information_schema.user_statistics; +show columns from information_schema.index_statistics; +show columns from information_schema.table_statistics; + +# Disable logging to get right number of writes into the tables. +set @save_general_log=@@global.general_log; +set @@global.general_log=0; +set @@global.userstat=1; +flush status; + +create table t1 (a int, primary key (a), b int default 0) engine=innodb; +insert into t1 (a) values (1),(2),(3),(4); +update t1 set b=1; +update t1 set b=5 where a=2; +delete from t1 where a=3; + +/* Empty query */ +select * from t1 where a=999; + +drop table t1; + +# +# Test the commit and rollback are counted +# + +create table t1 (a int, primary key (a), b int default 0) engine=innodb; +begin; +insert into t1 values(1,1); +commit; +begin; +insert into t1 values(2,2); +commit; +begin; +insert into t1 values(3,3); +rollback; +drop table t1; + +select sleep(1); + +show status like "rows%"; +show status like "ha%"; +select variable_value - @global_read_key as "handler_read_key" from information_schema.global_status where variable_name="handler_read_key"; + +# Ensure that the following commands doesn't change statistics + +set @@global.userstat=0; + +# +# Check that we got right statistics +# +select * from information_schema.index_statistics; +select * from information_schema.table_statistics; +show table_statistics; +show index_statistics; +--query_vertical select TOTAL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, OTHER_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.client_statistics; +--query_vertical select TOTAL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, OTHER_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.user_statistics; +flush table_statistics; +flush index_statistics; +select * from information_schema.index_statistics; +select * from information_schema.table_statistics; +show status like "%statistics%"; + +# +# Test that some variables are not 0 +# + +select connected_time <> 0, busy_time <> 0, bytes_received <> 0, + bytes_sent <> 0, binlog_bytes_written <> 0 + from information_schema.user_statistics; +select connected_time <> 0, busy_time <> 0, bytes_received <> 0, + bytes_sent <> 0, binlog_bytes_written <> 0 + from information_schema.client_statistics; + +# Cleanup +set @@global.general_log=@save_general_log; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 7ccc1390d41..b918e800dd5 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -488,6 +488,54 @@ SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1; explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1; drop table t1,t2,t3; +--echo # check correct NULL Processing for normal IN/ALL/ANY +--echo # and 2 ways of max/min optimization +create table t1 (a int); +insert into t1 values (1), (100), (NULL), (1000); +create table t2 (a int not null); + +--echo # subselect returns empty set (for NULL and non-NULL left part) +select a, a in (select * from t2) from t1; +select a, a > any (select * from t2) from t1; +select a, a > all (select * from t2) from t1; +select a from t1 where a in (select * from t2); +select a from t1 where a > any (select * from t2); +select a from t1 where a > all (select * from t2); +select a from t1 where a in (select * from t2 group by a); +select a from t1 where a > any (select * from t2 group by a); +select a from t1 where a > all (select * from t2 group by a); + +insert into t2 values (1),(200); + +--echo # sebselect returns non-empty set without NULLs +select a, a in (select * from t2) from t1; +select a, a > any (select * from t2) from t1; +select a, a > all (select * from t2) from t1; +select a from t1 where a in (select * from t2); +select a from t1 where a > any (select * from t2); +select a from t1 where a > all (select * from t2); +select a from t1 where a in (select * from t2 group by a); +select a from t1 where a > any (select * from t2 group by a); +select a from t1 where a > all (select * from t2 group by a); + +drop table t2; +create table t2 (a int); +insert into t2 values (1),(NULL),(200); + +--echo # sebselect returns non-empty set with NULLs +select a, a in (select * from t2) from t1; +select a, a > any (select * from t2) from t1; +select a, a > all (select * from t2) from t1; +select a from t1 where a in (select * from t2); +select a from t1 where a > any (select * from t2); +select a from t1 where a > all (select * from t2); +select a from t1 where a in (select * from t2 group by a); +select a from t1 where a > any (select * from t2 group by a); +select a from t1 where a > all (select * from t2 group by a); + + +drop table t1, t2; + #LIMIT is not supported now create table t1 (a float); -- error ER_NOT_SUPPORTED_YET @@ -924,7 +972,7 @@ drop table t1,t2; # # correct ALL optimisation # -create table t2 (a int, b int); +create table t2 (a int, b int not null); create table t3 (a int); insert into t3 values (6),(7),(3); select * from t3 where a >= all (select b from t2); @@ -3830,3 +3878,84 @@ SELECT 1 as foo FROM t1 WHERE a < SOME ); DROP TABLE t1; + +# +# LP BUG#823169 NULLs with ALL/ANY and maxmin optimization +# +CREATE TABLE t1 (a int(11), b varchar(1)); +INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g'); + +SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b ); + +SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b ); + +delete from t1; +INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g'); + +SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b ); + +SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b ); +SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 ); +SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b ); + +drop table t1; + +--echo # +--echo # Fix of LP BUG#780386 (NULL left part with empty ALL subquery). +--echo # +CREATE TABLE t1 ( f11 int) ; +INSERT IGNORE INTO t1 VALUES (0),(0); + +CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ; +INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0); + +DROP TABLE IF EXISTS t3; +CREATE TABLE t3 ( f3 int) ; +INSERT INTO t3 VALUES (0),(0); + +SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ; +DROP TABLE t1, t2, t3; + +--echo End of 5.2 tests diff --git a/mysql-test/t/table_options.test b/mysql-test/t/table_options.test new file mode 100644 index 00000000000..533e6829c00 --- /dev/null +++ b/mysql-test/t/table_options.test @@ -0,0 +1,68 @@ +--disable_warnings +drop table if exists t1; +--enable_warnings + +SET @OLD_SQL_MODE=@@SQL_MODE; +SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; + +create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1='1v1'; +show create table t1; +drop table t1; + +--echo #reassiginig options in the same line +create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1; +show create table t1; + +-- echo #add option +alter table t1 tkey4=4v1; +show create table t1; + +--echo #remove options +alter table t1 tkey3=DEFAULT tkey4=DEFAULT; +show create table t1; + +drop table t1; + +create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1; +show create table t1; + +--echo #change field with option with the same value +alter table t1 change a a int `FKEY1`='v1'; +show create table t1; +--echo #change field with option with a different value +alter table t1 change a a int fkey1=v2; +show create table t1; +--echo #new column no options +alter table t1 add column b int; +show create table t1; +--echo #new key with options +alter table t1 add key bkey (b) kkey2=v1; +show create table t1; +--echo #new column with options +alter table t1 add column c int fkey1=v1 fkey2=v2; +show create table t1; +--echo #new key no options +alter table t1 add key ckey (c); +show create table t1; +--echo #drop column +alter table t1 drop b; +show create table t1; +--echo #add column with options after delete +alter table t1 add column b int fkey2=v1; +show create table t1; +--echo #add key +alter table t1 add key bkey (b) kkey2=v2; +show create table t1; +drop table t1; + +#numeric (unquoted) value +create table t1 (a int) tkey1=100; +show create table t1; +drop table t1; + +--echo #error on unknown option +SET SQL_MODE=''; +--error ER_UNKNOWN_OPTION +create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1; + +SET @@SQL_MODE=@OLD_SQL_MODE; diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index a968e146d20..8d84330ec44 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -2409,3 +2409,28 @@ DROP DATABASE db1; USE test; --echo End of 5.1 tests. + +# +# Test that using a trigger will not open mysql.proc +# + +create table t1 (i int); +create table t2 (i int); +flush tables; +flush status; +delimiter //; +CREATE DEFINER=`root`@`localhost` TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW BEGIN DELETE FROM t2 WHERE t2.i = OLD.i; END // +delimiter ;// +insert into t1 values (1),(2); +insert into t2 values (1),(2); +delete from t1 where i=1; +# +# If mysql.proc would be used we would have 4 here. 3 is the correct number. +# (CREATE TRIGGER will open t1 and then flush it) +# +show status like 'Opened_tables'; +select * from t1; +select * from t2; +drop table t1,t2; + +--echo End of 5.2 tests. diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index ec6ed5702ee..2e1ecf9835a 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -36,6 +36,7 @@ set @my_thread_cache_size =@@global.thread_cache_size; set @my_max_allowed_packet =@@global.max_allowed_packet; set @my_delay_key_write =@@global.delay_key_write; set @my_join_buffer_size =@@global.join_buffer_size; +set @my_log_warnings =@@global.log_warnings; # case insensitivity tests (new in 5.0) set @`test`=1; select @test, @`test`, @TEST, @`TEST`, @"teSt"; @@ -843,6 +844,7 @@ set global thread_cache_size =@my_thread_cache_size; set global max_allowed_packet = default; set global delay_key_write =@my_delay_key_write; set global join_buffer_size =@my_join_buffer_size; +set global log_warnings =@my_log_warnings; # # Bug#28580 Repeatation of status variables diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index f48fe1b9967..4f4305a72f7 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -531,6 +531,22 @@ } { + dlsym memory loss from plugin on SuSE 11.3 x64 when using oqgraph + Memcheck:Leak + fun:*calloc + fun:do_lookup_x + fun:_dl_lookup_symbol_x + fun:_dl_relocate_object + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen@@GLIBC_2.2.5 +} + +{ dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 32/64 bit ver 1 Memcheck:Leak fun:*alloc @@ -581,6 +597,26 @@ fun:_Unwind_ForcedUnwind } +{ + dlsym memory loss from plugin + Memcheck:Leak + fun:malloc + fun:_dl_signal_error +} + +{ + dlsym memory loss from plugin + Memcheck:Leak + obj:/lib*/ld-*.so + obj:/lib*/ld-*.so + obj:/lib*/ld-*.so + obj:/lib*/libc-*.so + obj:/lib*/libdl-*.so + obj:/lib*/ld-*.so + obj:/lib*/libdl-*.so + fun:dlsym +} + # # Reading wrong addresses on SuSe Linux 10.3 32 bit # @@ -1042,6 +1078,27 @@ fun:nptl_pthread_exit_hack_handler } +{ + Invalid read within nptl_pthread_exit_hack_handler + Memcheck:Addr8 + obj:*/ld-*.so + obj:*/ld-*.so + obj:*/ld-*.so + obj:*/ld-*.so + obj:*/ld-*.so + obj:*/ld-*.so + obj:*/ld-*.so + obj:*/libc-*.so + obj:*/ld-*.so + obj:*/libc-*.so + fun:__libc_dlopen_mode + fun:pthread_cancel_init + fun:_Unwind_ForcedUnwind + fun:__pthread_unwind + fun:pthread_exit + fun:nptl_pthread_exit_hack_handler +} + # # Pthread doesn't free all thread specific memory before program exists # diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 78bc3c7994a..bff418370cc 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -49,6 +49,4 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_ IF(NOT SOURCE_SUBLIBS) ADD_LIBRARY(mysys ${MYSYS_SOURCES}) TARGET_LINK_LIBRARIES(mysys IPHLPAPI) - - INSTALL(TARGETS mysys DESTINATION lib/opt COMPONENT runtime) # TODO: Component? ENDIF(NOT SOURCE_SUBLIBS) diff --git a/mysys/Makefile.am b/mysys/Makefile.am index e4dfb0a44e5..f618f5d88e3 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -79,13 +79,13 @@ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ # testhash_DEPENDENCIES= $(LIBRARIES) # test_charset_DEPENDENCIES= $(LIBRARIES) # charset2html_DEPENDENCIES= $(LIBRARIES) -DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \ - -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ - -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \ - -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ +DEFS = -DDEFAULT_BASEDIR='"$(prefix)"' \ + -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \ + -DDEFAULT_CHARSET_HOME='"$(MYSQLBASEdir)"' \ + -DSHAREDIR'="$(MYSQLSHAREdir)"' \ -DDEFAULT_HOME_ENV=MYSQL_HOME \ -DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \ - -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \ + -DDEFAULT_SYSCONFDIR='"$(sysconfdir)"' \ @DEFS@ # I hope this always does the right thing. Otherwise this is only test programs diff --git a/mysys/charset-def.c b/mysys/charset-def.c index 5c68258ada1..db10000e174 100644 --- a/mysys/charset-def.c +++ b/mysys/charset-def.c @@ -24,49 +24,49 @@ #ifdef HAVE_UCA_COLLATIONS #ifdef HAVE_CHARSET_ucs2 -extern CHARSET_INFO my_charset_ucs2_icelandic_uca_ci; -extern CHARSET_INFO my_charset_ucs2_latvian_uca_ci; -extern CHARSET_INFO my_charset_ucs2_romanian_uca_ci; -extern CHARSET_INFO my_charset_ucs2_slovenian_uca_ci; -extern CHARSET_INFO my_charset_ucs2_polish_uca_ci; -extern CHARSET_INFO my_charset_ucs2_estonian_uca_ci; -extern CHARSET_INFO my_charset_ucs2_spanish_uca_ci; -extern CHARSET_INFO my_charset_ucs2_swedish_uca_ci; -extern CHARSET_INFO my_charset_ucs2_turkish_uca_ci; -extern CHARSET_INFO my_charset_ucs2_czech_uca_ci; -extern CHARSET_INFO my_charset_ucs2_danish_uca_ci; -extern CHARSET_INFO my_charset_ucs2_lithuanian_uca_ci; -extern CHARSET_INFO my_charset_ucs2_slovak_uca_ci; -extern CHARSET_INFO my_charset_ucs2_spanish2_uca_ci; -extern CHARSET_INFO my_charset_ucs2_roman_uca_ci; -extern CHARSET_INFO my_charset_ucs2_persian_uca_ci; -extern CHARSET_INFO my_charset_ucs2_esperanto_uca_ci; -extern CHARSET_INFO my_charset_ucs2_hungarian_uca_ci; -extern CHARSET_INFO my_charset_ucs2_croatian_uca_ci; +extern struct charset_info_st my_charset_ucs2_icelandic_uca_ci; +extern struct charset_info_st my_charset_ucs2_latvian_uca_ci; +extern struct charset_info_st my_charset_ucs2_romanian_uca_ci; +extern struct charset_info_st my_charset_ucs2_slovenian_uca_ci; +extern struct charset_info_st my_charset_ucs2_polish_uca_ci; +extern struct charset_info_st my_charset_ucs2_estonian_uca_ci; +extern struct charset_info_st my_charset_ucs2_spanish_uca_ci; +extern struct charset_info_st my_charset_ucs2_swedish_uca_ci; +extern struct charset_info_st my_charset_ucs2_turkish_uca_ci; +extern struct charset_info_st my_charset_ucs2_czech_uca_ci; +extern struct charset_info_st my_charset_ucs2_danish_uca_ci; +extern struct charset_info_st my_charset_ucs2_lithuanian_uca_ci; +extern struct charset_info_st my_charset_ucs2_slovak_uca_ci; +extern struct charset_info_st my_charset_ucs2_spanish2_uca_ci; +extern struct charset_info_st my_charset_ucs2_roman_uca_ci; +extern struct charset_info_st my_charset_ucs2_persian_uca_ci; +extern struct charset_info_st my_charset_ucs2_esperanto_uca_ci; +extern struct charset_info_st my_charset_ucs2_hungarian_uca_ci; +extern struct charset_info_st my_charset_ucs2_croatian_uca_ci; #endif #ifdef HAVE_CHARSET_utf8 -extern CHARSET_INFO my_charset_utf8_icelandic_uca_ci; -extern CHARSET_INFO my_charset_utf8_latvian_uca_ci; -extern CHARSET_INFO my_charset_utf8_romanian_uca_ci; -extern CHARSET_INFO my_charset_utf8_slovenian_uca_ci; -extern CHARSET_INFO my_charset_utf8_polish_uca_ci; -extern CHARSET_INFO my_charset_utf8_estonian_uca_ci; -extern CHARSET_INFO my_charset_utf8_spanish_uca_ci; -extern CHARSET_INFO my_charset_utf8_swedish_uca_ci; -extern CHARSET_INFO my_charset_utf8_turkish_uca_ci; -extern CHARSET_INFO my_charset_utf8_czech_uca_ci; -extern CHARSET_INFO my_charset_utf8_danish_uca_ci; -extern CHARSET_INFO my_charset_utf8_lithuanian_uca_ci; -extern CHARSET_INFO my_charset_utf8_slovak_uca_ci; -extern CHARSET_INFO my_charset_utf8_spanish2_uca_ci; -extern CHARSET_INFO my_charset_utf8_roman_uca_ci; -extern CHARSET_INFO my_charset_utf8_persian_uca_ci; -extern CHARSET_INFO my_charset_utf8_esperanto_uca_ci; -extern CHARSET_INFO my_charset_utf8_hungarian_uca_ci; -extern CHARSET_INFO my_charset_utf8_croatian_uca_ci; +extern struct charset_info_st my_charset_utf8_icelandic_uca_ci; +extern struct charset_info_st my_charset_utf8_latvian_uca_ci; +extern struct charset_info_st my_charset_utf8_romanian_uca_ci; +extern struct charset_info_st my_charset_utf8_slovenian_uca_ci; +extern struct charset_info_st my_charset_utf8_polish_uca_ci; +extern struct charset_info_st my_charset_utf8_estonian_uca_ci; +extern struct charset_info_st my_charset_utf8_spanish_uca_ci; +extern struct charset_info_st my_charset_utf8_swedish_uca_ci; +extern struct charset_info_st my_charset_utf8_turkish_uca_ci; +extern struct charset_info_st my_charset_utf8_czech_uca_ci; +extern struct charset_info_st my_charset_utf8_danish_uca_ci; +extern struct charset_info_st my_charset_utf8_lithuanian_uca_ci; +extern struct charset_info_st my_charset_utf8_slovak_uca_ci; +extern struct charset_info_st my_charset_utf8_spanish2_uca_ci; +extern struct charset_info_st my_charset_utf8_roman_uca_ci; +extern struct charset_info_st my_charset_utf8_persian_uca_ci; +extern struct charset_info_st my_charset_utf8_esperanto_uca_ci; +extern struct charset_info_st my_charset_utf8_hungarian_uca_ci; +extern struct charset_info_st my_charset_utf8_croatian_uca_ci; #ifdef HAVE_UTF8_GENERAL_CS -extern CHARSET_INFO my_charset_utf8_general_cs; +extern struct charset_info_st my_charset_utf8_general_cs; #endif #endif @@ -195,7 +195,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) /* Copy compiled charsets */ for (cs=compiled_charsets; cs->name; cs++) - add_compiled_collation(cs); + add_compiled_collation((struct charset_info_st *) cs); return FALSE; } diff --git a/mysys/charset.c b/mysys/charset.c index 3d157ae5bf7..6a6f25e34b4 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -55,21 +55,18 @@ get_collation_number_internal(const char *name) } -static my_bool init_state_maps(CHARSET_INFO *cs) +static my_bool init_state_maps(struct charset_info_st *cs) { uint i; uchar *state_map; uchar *ident_map; - if (!(cs->state_map= (uchar*) my_once_alloc(256, MYF(MY_WME)))) + if (!(cs->state_map= state_map= (uchar*) my_once_alloc(256, MYF(MY_WME)))) return 1; - if (!(cs->ident_map= (uchar*) my_once_alloc(256, MYF(MY_WME)))) + if (!(cs->ident_map= ident_map= (uchar*) my_once_alloc(256, MYF(MY_WME)))) return 1; - state_map= cs->state_map; - ident_map= cs->ident_map; - /* Fill state_map with states to get a faster parser */ for (i=0; i < 256 ; i++) { @@ -120,7 +117,7 @@ static my_bool init_state_maps(CHARSET_INFO *cs) } -static void simple_cs_init_functions(CHARSET_INFO *cs) +static void simple_cs_init_functions(struct charset_info_st *cs) { if (cs->state & MY_CS_BINSORT) cs->coll= &my_collation_8bit_bin_handler; @@ -132,7 +129,7 @@ static void simple_cs_init_functions(CHARSET_INFO *cs) -static int cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from) +static int cs_copy_data(struct charset_info_st *to, CHARSET_INFO *from) { to->number= from->number ? from->number : to->number; @@ -206,7 +203,7 @@ static my_bool simple_cs_is_full(CHARSET_INFO *cs) #if defined(HAVE_UCA_COLLATIONS) && (defined(HAVE_CHARSET_ucs2) || defined(HAVE_CHARSET_utf8)) static void -copy_uca_collation(CHARSET_INFO *to, CHARSET_INFO *from) +copy_uca_collation(struct charset_info_st *to, CHARSET_INFO *from) { to->cset= from->cset; to->coll= from->coll; @@ -221,18 +218,19 @@ copy_uca_collation(CHARSET_INFO *to, CHARSET_INFO *from) #endif -static int add_collation(CHARSET_INFO *cs) +static int add_collation(struct charset_info_st *cs) { if (cs->name && (cs->number || (cs->number=get_collation_number_internal(cs->name))) && cs->number < array_elements(all_charsets)) { - if (!all_charsets[cs->number]) + struct charset_info_st *newcs; + if (!(newcs= (struct charset_info_st*) all_charsets[cs->number])) { - if (!(all_charsets[cs->number]= - (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),MYF(0)))) + if (!(all_charsets[cs->number]= newcs= + (struct charset_info_st*) my_once_alloc(sizeof(CHARSET_INFO),MYF(0)))) return MY_XML_ERROR; - bzero((void*)all_charsets[cs->number],sizeof(CHARSET_INFO)); + bzero(newcs,sizeof(CHARSET_INFO)); } if (cs->primary_number == cs->number) @@ -241,12 +239,11 @@ static int add_collation(CHARSET_INFO *cs) if (cs->binary_number == cs->number) cs->state |= MY_CS_BINSORT; - all_charsets[cs->number]->state|= cs->state; + newcs->state|= cs->state; - if (!(all_charsets[cs->number]->state & MY_CS_COMPILED)) + if (!(newcs->state & MY_CS_COMPILED)) { - CHARSET_INFO *newcs= all_charsets[cs->number]; - if (cs_copy_data(all_charsets[cs->number],cs)) + if (cs_copy_data(newcs,cs)) return MY_XML_ERROR; newcs->caseup_multiply= newcs->casedn_multiply= 1; @@ -266,15 +263,15 @@ static int add_collation(CHARSET_INFO *cs) } else { - uchar *sort_order= all_charsets[cs->number]->sort_order; - simple_cs_init_functions(all_charsets[cs->number]); + const uchar *sort_order= newcs->sort_order; + simple_cs_init_functions(newcs); newcs->mbminlen= 1; newcs->mbmaxlen= 1; - if (simple_cs_is_full(all_charsets[cs->number])) + if (simple_cs_is_full(newcs)) { - all_charsets[cs->number]->state |= MY_CS_LOADED; + newcs->state |= MY_CS_LOADED; } - all_charsets[cs->number]->state|= MY_CS_AVAILABLE; + newcs->state|= MY_CS_AVAILABLE; /* Check if case sensitive sort order: A < a < B. @@ -284,12 +281,12 @@ static int add_collation(CHARSET_INFO *cs) */ if (sort_order && sort_order['A'] < sort_order['a'] && sort_order['a'] < sort_order['B']) - all_charsets[cs->number]->state|= MY_CS_CSSORT; + newcs->state|= MY_CS_CSSORT; - if (my_charset_is_8bit_pure_ascii(all_charsets[cs->number])) - all_charsets[cs->number]->state|= MY_CS_PUREASCII; + if (my_charset_is_8bit_pure_ascii(newcs)) + newcs->state|= MY_CS_PUREASCII; if (!my_charset_is_ascii_compatible(cs)) - all_charsets[cs->number]->state|= MY_CS_NONASCII; + newcs->state|= MY_CS_NONASCII; } } else @@ -303,16 +300,15 @@ static int add_collation(CHARSET_INFO *cs) If a character set was compiled, this information will get lost and overwritten in add_compiled_collation(). */ - CHARSET_INFO *dst= all_charsets[cs->number]; - dst->number= cs->number; + newcs->number= cs->number; if (cs->comment) - if (!(dst->comment= my_once_strdup(cs->comment,MYF(MY_WME)))) + if (!(newcs->comment= my_once_strdup(cs->comment,MYF(MY_WME)))) return MY_XML_ERROR; if (cs->csname) - if (!(dst->csname= my_once_strdup(cs->csname,MYF(MY_WME)))) + if (!(newcs->csname= my_once_strdup(cs->csname,MYF(MY_WME)))) return MY_XML_ERROR; if (cs->name) - if (!(dst->name= my_once_strdup(cs->name,MYF(MY_WME)))) + if (!(newcs->name= my_once_strdup(cs->name,MYF(MY_WME)))) return MY_XML_ERROR; } cs->number= 0; @@ -396,7 +392,7 @@ char *get_charsets_dir(char *buf) CHARSET_INFO *all_charsets[256]={NULL}; CHARSET_INFO *default_charset_info = &my_charset_latin1; -void add_compiled_collation(CHARSET_INFO *cs) +void add_compiled_collation(struct charset_info_st *cs) { all_charsets[cs->number]= cs; cs->state|= MY_CS_AVAILABLE; @@ -414,14 +410,15 @@ static my_pthread_once_t charsets_template= MY_PTHREAD_ONCE_INIT; static void init_available_charsets(void) { char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)]; - CHARSET_INFO **cs; + struct charset_info_st **cs; - bzero(&all_charsets,sizeof(all_charsets)); + bzero((char*) &all_charsets,sizeof(all_charsets)); init_compiled_charsets(MYF(0)); /* Copy compiled charsets */ - for (cs=all_charsets; - cs < all_charsets+array_elements(all_charsets)-1 ; + for (cs= (struct charset_info_st**) all_charsets; + cs < (struct charset_info_st**) all_charsets + + array_elements(all_charsets)-1 ; cs++) { if (*cs) @@ -482,9 +479,9 @@ const char *get_charset_name(uint charset_number) static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) { char buf[FN_REFLEN]; - CHARSET_INFO *cs; + struct charset_info_st *cs; - if ((cs= all_charsets[cs_number])) + if ((cs= (struct charset_info_st*) all_charsets[cs_number])) { if (cs->state & MY_CS_READY) /* if CS is already initialized */ return cs; diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index ac660df476e..e29b6415d42 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -180,11 +180,9 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize, if ((pos == (my_off_t) -1) && (my_errno == ESPIPE)) { /* - This kind of object doesn't support seek() or tell(). Don't set a - flag that will make us again try to seek() later and fail. - */ - info->seek_not_done= 0; - /* + This kind of object doesn't support seek() or tell(). Don't set a + seek_not_done that will make us again try to seek() later and fail. + Additionally, if we're supposed to start somewhere other than the the beginning of whatever this file is, then somebody made a bad assumption. @@ -1746,7 +1744,7 @@ int my_b_flush_io_cache(IO_CACHE *info, */ if (!append_cache && info->seek_not_done) { /* File touched, do seek */ - if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) == + if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(info->myflags & MY_WME)) == MY_FILEPOS_ERROR) { UNLOCK_APPEND_BUFFER; diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index ba85637b537..a038061d9d0 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -15,12 +15,43 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + + /** - @file + @file + The file contains the following modules: + + Simple Key Cache Module + + Partitioned Key Cache Module + + Key Cache Interface Module + +*/ + +#include "mysys_priv.h" +#include "mysys_err.h" +#include <keycache.h> +#include "my_static.h" +#include <m_string.h> +#include <my_bit.h> +#include <errno.h> +#include <stdarg.h> + +/****************************************************************************** + Simple Key Cache Module + + The module contains implementations of all key cache interface functions + employed by partitioned key caches. + +******************************************************************************/ + +/* These functions handle keyblock cacheing for ISAM and MyISAM tables. One cache can handle many files. It must contain buffers of the same blocksize. + init_key_cache() should be used to init cache handler. The free list (free_block_list) is a stack like structure. @@ -39,9 +70,7 @@ blocks_unused is the sum of never used blocks in the pool and of currently free blocks. blocks_used is the number of blocks fetched from the pool and as such gives the maximum number of in-use blocks at any time. -*/ -/* Key Cache Locking ================= @@ -106,14 +135,77 @@ I/O finished. */ -#include "mysys_priv.h" -#include "mysys_err.h" -#include <keycache.h> -#include "my_static.h" -#include <m_string.h> -#include <my_bit.h> -#include <errno.h> -#include <stdarg.h> +/* declare structures that is used by st_key_cache */ + +struct st_block_link; +typedef struct st_block_link BLOCK_LINK; +struct st_keycache_page; +typedef struct st_keycache_page KEYCACHE_PAGE; +struct st_hash_link; +typedef struct st_hash_link HASH_LINK; + +/* info about requests in a waiting queue */ +typedef struct st_keycache_wqueue +{ + struct st_my_thread_var *last_thread; /* circular list of waiting threads */ +} KEYCACHE_WQUEUE; + +#define CHANGED_BLOCKS_HASH 128 /* must be power of 2 */ + +/* Control block for a simple (non-partitioned) key cache */ + +typedef struct st_simple_key_cache_cb +{ + my_bool key_cache_inited; /* <=> control block is allocated */ + my_bool in_resize; /* true during resize operation */ + my_bool resize_in_flush; /* true during flush of resize operation */ + my_bool can_be_used; /* usage of cache for read/write is allowed */ + size_t key_cache_mem_size; /* specified size of the cache memory */ + uint key_cache_block_size; /* size of the page buffer of a cache block */ + ulong min_warm_blocks; /* min number of warm blocks; */ + ulong age_threshold; /* age threshold for hot blocks */ + ulonglong keycache_time; /* total number of block link operations */ + uint hash_entries; /* max number of entries in the hash table */ + int hash_links; /* max number of hash links */ + int hash_links_used; /* number of hash links currently used */ + int disk_blocks; /* max number of blocks in the cache */ + ulong blocks_used; /* maximum number of concurrently used blocks */ + ulong blocks_unused; /* number of currently unused blocks */ + ulong blocks_changed; /* number of currently dirty blocks */ + ulong warm_blocks; /* number of blocks in warm sub-chain */ + ulong cnt_for_resize_op; /* counter to block resize operation */ + long blocks_available; /* number of blocks available in the LRU chain */ + HASH_LINK **hash_root; /* arr. of entries into hash table buckets */ + HASH_LINK *hash_link_root; /* memory for hash table links */ + HASH_LINK *free_hash_list; /* list of free hash links */ + BLOCK_LINK *free_block_list; /* list of free blocks */ + BLOCK_LINK *block_root; /* memory for block links */ + uchar HUGE_PTR *block_mem; /* memory for block buffers */ + BLOCK_LINK *used_last; /* ptr to the last block of the LRU chain */ + BLOCK_LINK *used_ins; /* ptr to the insertion block in LRU chain */ + pthread_mutex_t cache_lock; /* to lock access to the cache structure */ + KEYCACHE_WQUEUE resize_queue; /* threads waiting during resize operation */ + /* + Waiting for a zero resize count. Using a queue for symmetry though + only one thread can wait here. + */ + KEYCACHE_WQUEUE waiting_for_resize_cnt; + KEYCACHE_WQUEUE waiting_for_hash_link; /* waiting for a free hash link */ + KEYCACHE_WQUEUE waiting_for_block; /* requests waiting for a free block */ + BLOCK_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; /* hash for dirty file bl.*/ + BLOCK_LINK *file_blocks[CHANGED_BLOCKS_HASH]; /* hash for other file bl.*/ + + /* Statistics variables. These are reset in reset_key_cache_counters(). */ + ulong global_blocks_changed; /* number of currently dirty blocks */ + ulonglong global_cache_w_requests;/* number of write requests (write hits) */ + ulonglong global_cache_write; /* number of writes from cache to files */ + ulonglong global_cache_r_requests;/* number of read requests (read hits) */ + ulonglong global_cache_read; /* number of reads from files to cache */ + + int blocks; /* max number of blocks in the cache */ + uint hash_factor; /* factor used to calculate hash function */ + my_bool in_init; /* Set to 1 in MySQL during init/resize */ +} SIMPLE_KEY_CACHE_CB; /* Some compilation flags have been added specifically for this module @@ -225,7 +317,8 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cache_var; #define FLUSH_CACHE 2000 /* sort this many blocks at once */ -static int flush_all_key_blocks(KEY_CACHE *keycache); +static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache); +static void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup); #ifdef THREAD static void wait_on_queue(KEYCACHE_WQUEUE *wqueue, pthread_mutex_t *mutex); @@ -234,15 +327,16 @@ static void release_whole_queue(KEYCACHE_WQUEUE *wqueue); #define wait_on_queue(wqueue, mutex) do {} while (0) #define release_whole_queue(wqueue) do {} while (0) #endif -static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block); +static void free_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block); #if !defined(DBUG_OFF) -static void test_key_cache(KEY_CACHE *keycache, +static void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache, const char *where, my_bool lock); #endif - +#define KEYCACHE_BASE_EXPR(f, pos) \ + ((ulong) ((pos) / keycache->key_cache_block_size) + (ulong) (f)) #define KEYCACHE_HASH(f, pos) \ -(((ulong) ((pos) / keycache->key_cache_block_size) + \ - (ulong) (f)) & (keycache->hash_entries-1)) + ((KEYCACHE_BASE_EXPR(f, pos) / keycache->hash_factor) & \ + (keycache->hash_entries-1)) #define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1)) #define DEFAULT_KEYCACHE_DEBUG_LOG "keycache_debug.log" @@ -338,9 +432,10 @@ static int keycache_pthread_cond_signal(pthread_cond_t *cond); #define inline /* disabled inline for easier debugging */ static int fail_block(BLOCK_LINK *block); static int fail_hlink(HASH_LINK *hlink); -static int cache_empty(KEY_CACHE *keycache); +static int cache_empty(SIMPLE_KEY_CACHE_CB *keycache); #endif + static inline uint next_power(uint value) { return (uint) my_round_up_to_next_power((uint32) value) << 1; @@ -348,19 +443,32 @@ static inline uint next_power(uint value) /* - Initialize a key cache + Initialize a simple key cache SYNOPSIS - init_key_cache() - keycache pointer to a key cache data structure - key_cache_block_size size of blocks to keep cached data - use_mem total memory to use for the key cache - division_limit division limit (may be zero) - age_threshold age threshold (may be zero) + init_simple_key_cache() + keycache pointer to the control block of a simple key cache + key_cache_block_size size of blocks to keep cached data + use_mem memory to use for the key cache buferrs/structures + division_limit division limit (may be zero) + age_threshold age threshold (may be zero) + + DESCRIPTION + This function is the implementation of the init_key_cache interface + function that is employed by simple (non-partitioned) key caches. + The function builds a simple key cache and initializes the control block + structure of the type SIMPLE_KEY_CACHE_CB that is used for this key cache. + The parameter keycache is supposed to point to this structure. + The parameter key_cache_block_size specifies the size of the blocks in + the key cache to be built. The parameters division_limit and age_threshhold + determine the initial values of those characteristics of the key cache + that are used for midpoint insertion strategy. The parameter use_mem + specifies the total amount of memory to be allocated for key cache blocks + and auxiliary structures. RETURN VALUE number of blocks in the key cache, if successful, - 0 - otherwise. + <= 0 - otherwise. NOTES. if keycache->key_cache_inited != 0 we assume that the key cache @@ -369,17 +477,17 @@ static inline uint next_power(uint value) It's assumed that no two threads call this function simultaneously referring to the same key cache handle. - */ -int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - size_t use_mem, uint division_limit, - uint age_threshold) +static +int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size, + size_t use_mem, uint division_limit, + uint age_threshold) { ulong blocks, hash_links; size_t length; int error; - DBUG_ENTER("init_key_cache"); + DBUG_ENTER("init_simple_key_cache"); DBUG_ASSERT(key_cache_block_size >= 512); KEYCACHE_DEBUG_OPEN; @@ -389,12 +497,15 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, DBUG_RETURN(0); } + keycache->blocks_used= keycache->blocks_unused= 0; + keycache->global_blocks_changed= 0; keycache->global_cache_w_requests= keycache->global_cache_r_requests= 0; keycache->global_cache_read= keycache->global_cache_write= 0; keycache->disk_blocks= -1; if (! keycache->key_cache_inited) { keycache->key_cache_inited= 1; + keycache->hash_factor= 1; /* Initialize these variables once only. Their value must survive re-initialization during resizing. @@ -536,51 +647,42 @@ err: /* - Resize a key cache + Prepare for resizing a simple key cache SYNOPSIS - resize_key_cache() - keycache pointer to a key cache data structure - key_cache_block_size size of blocks to keep cached data - use_mem total memory to use for the new key cache - division_limit new division limit (if not zero) - age_threshold new age threshold (if not zero) - - RETURN VALUE - number of blocks in the key cache, if successful, - 0 - otherwise. + prepare_resize_simple_key_cache() + keycache pointer to the control block of a simple key cache + with_resize_queue <=> resize queue is used + release_lock <=> release the key cache lock before return - NOTES. - The function first compares the memory size and the block size parameters - with the key cache values. + DESCRIPTION + This function flushes all dirty pages from a simple key cache and after + this it destroys the key cache calling end_simple_key_cache. The function + takes the parameter keycache as a pointer to the control block + structure of the type SIMPLE_KEY_CACHE_CB for this key cache. + The parameter with_resize_queue determines weather the resize queue is + involved (MySQL server never uses this queue). The parameter release_lock + says weather the key cache lock must be released before return from + the function. - If they differ the function free the the memory allocated for the - old key cache blocks by calling the end_key_cache function and - then rebuilds the key cache with new blocks by calling - init_key_cache. + RETURN VALUE + 0 - on success, + 1 - otherwise. - The function starts the operation only when all other threads - performing operations with the key cache let her to proceed - (when cnt_for_resize=0). + NOTES + This function is the called by resize_simple_key_cache and + resize_partitioned_key_cache that resize simple and partitioned key caches + respectively. */ -int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - size_t use_mem, uint division_limit, - uint age_threshold) +static +int prepare_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, + my_bool with_resize_queue, + my_bool release_lock) { - int blocks; - DBUG_ENTER("resize_key_cache"); - - if (!keycache->key_cache_inited) - DBUG_RETURN(keycache->disk_blocks); - - if(key_cache_block_size == keycache->key_cache_block_size && - use_mem == keycache->key_cache_mem_size) - { - change_key_cache_param(keycache, division_limit, age_threshold); - DBUG_RETURN(keycache->disk_blocks); - } - + int res= 0; + DBUG_ENTER("prepare_resize_simple_key_cache"); + keycache_pthread_mutex_lock(&keycache->cache_lock); #ifdef THREAD @@ -590,7 +692,7 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, one resizer only. In set_var.cc keycache->in_init is used to block multiple attempts. */ - while (keycache->in_resize) + while (with_resize_queue && keycache->in_resize) { /* purecov: begin inspected */ wait_on_queue(&keycache->resize_queue, &keycache->cache_lock); @@ -615,8 +717,8 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, { /* TODO: if this happens, we should write a warning in the log file ! */ keycache->resize_in_flush= 0; - blocks= 0; keycache->can_be_used= 0; + res= 1; goto finish; } DBUG_ASSERT(cache_empty(keycache)); @@ -642,29 +744,144 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, #else KEYCACHE_DBUG_ASSERT(keycache->cnt_for_resize_op == 0); #endif - - /* - Free old cache structures, allocate new structures, and initialize - them. Note that the cache_lock mutex and the resize_queue are left - untouched. We do not lose the cache_lock and will release it only at - the end of this function. - */ - end_key_cache(keycache, 0); /* Don't free mutex */ - /* The following will work even if use_mem is 0 */ - blocks= init_key_cache(keycache, key_cache_block_size, use_mem, - division_limit, age_threshold); + + end_simple_key_cache(keycache, 0); finish: + if (release_lock) + keycache_pthread_mutex_unlock(&keycache->cache_lock); + DBUG_RETURN(res); +} + + +/* + Finalize resizing a simple key cache + + SYNOPSIS + finish_resize_simple_key_cache() + keycache pointer to the control block of a simple key cache + with_resize_queue <=> resize queue is used + acquire_lock <=> acquire the key cache lock at start + + DESCRIPTION + This function performs finalizing actions for the operation of + resizing a simple key cache. The function takes the parameter + keycache as a pointer to the control block structure of the type + SIMPLE_KEY_CACHE_CB for this key cache. The function sets the flag + in_resize in this structure to FALSE. + The parameter with_resize_queue determines weather the resize queue + is involved (MySQL server never uses this queue). + The parameter acquire_lock says weather the key cache lock must be + acquired at the start of the function. + + RETURN VALUE + none + + NOTES + This function is the called by resize_simple_key_cache and + resize_partitioned_key_cache that resize simple and partitioned key caches + respectively. +*/ + +static +void finish_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, + my_bool with_resize_queue, + my_bool acquire_lock) +{ + DBUG_ENTER("finish_resize_simple_key_cache"); + + if (acquire_lock) + keycache_pthread_mutex_lock(&keycache->cache_lock); + + safe_mutex_assert_owner(&keycache->cache_lock); + /* Mark the resize finished. This allows other threads to start a resize or to request new cache blocks. */ keycache->in_resize= 0; - - /* Signal waiting threads. */ - release_whole_queue(&keycache->resize_queue); + + if (with_resize_queue) + { + /* Signal waiting threads. */ + release_whole_queue(&keycache->resize_queue); + } keycache_pthread_mutex_unlock(&keycache->cache_lock); + + DBUG_VOID_RETURN; +} + + +/* + Resize a simple key cache + + SYNOPSIS + resize_simple_key_cache() + keycache pointer to the control block of a simple key cache + key_cache_block_size size of blocks to keep cached data + use_mem memory to use for the key cache buffers/structures + division_limit new division limit (if not zero) + age_threshold new age threshold (if not zero) + + DESCRIPTION + This function is the implementation of the resize_key_cache interface + function that is employed by simple (non-partitioned) key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key + cache to be resized. + The parameter key_cache_block_size specifies the new size of the blocks in + the key cache. The parameters division_limit and age_threshold + determine the new initial values of those characteristics of the key cache + that are used for midpoint insertion strategy. The parameter use_mem + specifies the total amount of memory to be allocated for key cache blocks + and auxiliary structures in the new key cache. + + RETURN VALUE + number of blocks in the key cache, if successful, + 0 - otherwise. + + NOTES. + The function first calls the function prepare_resize_simple_key_cache + to flush all dirty blocks from key cache, to free memory used + for key cache blocks and auxiliary structures. After this the + function builds a new key cache with new parameters. + + This implementation doesn't block the calls and executions of other + functions from the key cache interface. However it assumes that the + calls of resize_simple_key_cache itself are serialized. + + The function starts the operation only when all other threads + performing operations with the key cache let her to proceed + (when cnt_for_resize=0). +*/ + +static +int resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size, + size_t use_mem, uint division_limit, + uint age_threshold) +{ + int blocks= 0; + DBUG_ENTER("resize_simple_key_cache"); + + if (!keycache->key_cache_inited) + DBUG_RETURN(blocks); + + /* + Note that the cache_lock mutex and the resize_queue are left untouched. + We do not lose the cache_lock and will release it only at the end of + this function. + */ + if (prepare_resize_simple_key_cache(keycache, 1, 0)) + goto finish; + + /* The following will work even if use_mem is 0 */ + blocks= init_simple_key_cache(keycache, key_cache_block_size, use_mem, + division_limit, age_threshold); + +finish: + finish_resize_simple_key_cache(keycache, 1, 0); + DBUG_RETURN(blocks); } @@ -672,7 +889,7 @@ finish: /* Increment counter blocking resize key cache operation */ -static inline void inc_counter_for_resize_op(KEY_CACHE *keycache) +static inline void inc_counter_for_resize_op(SIMPLE_KEY_CACHE_CB *keycache) { keycache->cnt_for_resize_op++; } @@ -682,35 +899,47 @@ static inline void inc_counter_for_resize_op(KEY_CACHE *keycache) Decrement counter blocking resize key cache operation; Signal the operation to proceed when counter becomes equal zero */ -static inline void dec_counter_for_resize_op(KEY_CACHE *keycache) +static inline void dec_counter_for_resize_op(SIMPLE_KEY_CACHE_CB *keycache) { if (!--keycache->cnt_for_resize_op) release_whole_queue(&keycache->waiting_for_resize_cnt); } + /* - Change the key cache parameters + Change key cache parameters of a simple key cache SYNOPSIS - change_key_cache_param() - keycache pointer to a key cache data structure - division_limit new division limit (if not zero) - age_threshold new age threshold (if not zero) + change_simple_key_cache_param() + keycache pointer to the control block of a simple key cache + division_limit new division limit (if not zero) + age_threshold new age threshold (if not zero) + + DESCRIPTION + This function is the implementation of the change_key_cache_param interface + function that is employed by simple (non-partitioned) key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key + cache where new values of the division limit and the age threshold used + for midpoint insertion strategy are to be set. The parameters + division_limit and age_threshold provide these new values. RETURN VALUE none NOTES. - Presently the function resets the key cache parameters - concerning midpoint insertion strategy - division_limit and - age_threshold. + Presently the function resets the key cache parameters concerning + midpoint insertion strategy - division_limit and age_threshold. + This function changes some parameters of a given key cache without + reformatting it. The function does not touch the contents the key + cache blocks. */ -void change_key_cache_param(KEY_CACHE *keycache, uint division_limit, - uint age_threshold) +static +void change_simple_key_cache_param(SIMPLE_KEY_CACHE_CB *keycache, uint division_limit, + uint age_threshold) { - DBUG_ENTER("change_key_cache_param"); - + DBUG_ENTER("change_simple_key_cache_param"); keycache_pthread_mutex_lock(&keycache->cache_lock); if (division_limit) keycache->min_warm_blocks= (keycache->disk_blocks * @@ -724,20 +953,31 @@ void change_key_cache_param(KEY_CACHE *keycache, uint division_limit, /* - Remove key_cache from memory + Destroy a simple key cache SYNOPSIS - end_key_cache() - keycache key cache handle - cleanup Complete free (Free also mutex for key cache) + end_simple_key_cache() + keycache pointer to the control block of a simple key cache + cleanup <=> complete free (free also mutex for key cache) + + DESCRIPTION + This function is the implementation of the end_key_cache interface + function that is employed by simple (non-partitioned) key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key + cache to be destroyed. + The function frees the memory allocated for the key cache blocks and + auxiliary structures. If the value of the parameter cleanup is TRUE + then even the key cache mutex is freed. RETURN VALUE none */ -void end_key_cache(KEY_CACHE *keycache, my_bool cleanup) +static +void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup) { - DBUG_ENTER("end_key_cache"); + DBUG_ENTER("end_simple_key_cache"); DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache)); if (!keycache->key_cache_inited) @@ -1028,7 +1268,7 @@ static inline void link_changed(BLOCK_LINK *block, BLOCK_LINK **phead) void */ -static void link_to_file_list(KEY_CACHE *keycache, +static void link_to_file_list(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block, int file, my_bool unlink_block) { @@ -1069,7 +1309,7 @@ static void link_to_file_list(KEY_CACHE *keycache, void */ -static void link_to_changed_list(KEY_CACHE *keycache, +static void link_to_changed_list(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block) { DBUG_ASSERT(block->status & BLOCK_IN_USE); @@ -1124,8 +1364,8 @@ static void link_to_changed_list(KEY_CACHE *keycache, not linked in the LRU ring. */ -static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot, - my_bool at_end) +static void link_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block, + my_bool hot, my_bool at_end) { BLOCK_LINK *ins; BLOCK_LINK **pins; @@ -1245,7 +1485,7 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot, See NOTES for link_block */ -static void unlink_block(KEY_CACHE *keycache, BLOCK_LINK *block) +static void unlink_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block) { DBUG_ASSERT((block->status & ~BLOCK_CHANGED) == (BLOCK_READ | BLOCK_IN_USE)); DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/ @@ -1303,7 +1543,8 @@ static void unlink_block(KEY_CACHE *keycache, BLOCK_LINK *block) RETURN void */ -static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count) +static void reg_requests(SIMPLE_KEY_CACHE_CB *keycache, + BLOCK_LINK *block, int count) { DBUG_ASSERT(block->status & BLOCK_IN_USE); DBUG_ASSERT(block->hash_link); @@ -1346,7 +1587,7 @@ static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count) not linked in the LRU ring. */ -static void unreg_request(KEY_CACHE *keycache, +static void unreg_request(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block, int at_end) { DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); @@ -1435,7 +1676,7 @@ static void remove_reader(BLOCK_LINK *block) signals on its termination */ -static void wait_for_readers(KEY_CACHE *keycache, +static void wait_for_readers(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block) { #ifdef THREAD @@ -1484,7 +1725,7 @@ static inline void link_hash(HASH_LINK **start, HASH_LINK *hash_link) Remove a hash link from the hash table */ -static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link) +static void unlink_hash(SIMPLE_KEY_CACHE_CB *keycache, HASH_LINK *hash_link) { KEYCACHE_DBUG_PRINT("unlink_hash", ("fd: %u pos_ %lu #requests=%u", (uint) hash_link->file,(ulong) hash_link->diskpos, hash_link->requests)); @@ -1540,7 +1781,7 @@ static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link) Get the hash link for a page */ -static HASH_LINK *get_hash_link(KEY_CACHE *keycache, +static HASH_LINK *get_hash_link(SIMPLE_KEY_CACHE_CB *keycache, int file, my_off_t filepos) { reg1 HASH_LINK *hash_link, **start; @@ -1661,7 +1902,7 @@ restart: waits until first of this operations links any block back. */ -static BLOCK_LINK *find_key_block(KEY_CACHE *keycache, +static BLOCK_LINK *find_key_block(SIMPLE_KEY_CACHE_CB *keycache, File file, my_off_t filepos, int init_hits_left, int wrmode, int *page_st) @@ -2421,7 +2662,7 @@ restart: portion is less than read_length, but not less than min_length. */ -static void read_block(KEY_CACHE *keycache, +static void read_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block, uint read_length, uint min_length, my_bool primary) { @@ -2509,43 +2750,60 @@ static void read_block(KEY_CACHE *keycache, /* - Read a block of data from a cached file into a buffer; + Read a block of data from a simple key cache into a buffer SYNOPSIS - key_cache_read() - keycache pointer to a key cache data structure - file handler for the file for the block of data to be read - filepos position of the block of data in the file - level determines the weight of the data - buff buffer to where the data must be placed - length length of the buffer - block_length length of the block in the key cache buffer - return_buffer return pointer to the key cache buffer with the data + simple_key_cache_read() + keycache pointer to the control block of a simple key cache + file handler for the file for the block of data to be read + filepos position of the block of data in the file + level determines the weight of the data + buff buffer to where the data must be placed + length length of the buffer + block_length length of the read data from a key cache block + return_buffer return pointer to the key cache buffer with the data + DESCRIPTION + This function is the implementation of the key_cache_read interface + function that is employed by simple (non-partitioned) key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key + cache. + In a general case the function reads a block of data from the key cache + into the buffer buff of the size specified by the parameter length. The + beginning of the block of data to be read is specified by the parameters + file and filepos. The length of the read data is the same as the length + of the buffer. The data is read into the buffer in key_cache_block_size + increments. If the next portion of the data is not found in any key cache + block, first it is read from file into the key cache. + If the parameter return_buffer is not ignored and its value is TRUE, and + the data to be read of the specified size block_length can be read from one + key cache buffer, then the function returns a pointer to the data in the + key cache buffer. + The function takse into account parameters block_length and return buffer + only in a single-threaded environment. + The parameter 'level' is used only by the midpoint insertion strategy + when the data or its portion cannot be found in the key cache. + RETURN VALUE - Returns address from where the data is placed if sucessful, 0 - otherwise. + Returns address from where the data is placed if successful, 0 - otherwise. - NOTES. - The function ensures that a block of data of size length from file - positioned at filepos is in the buffers for some key cache blocks. - Then the function either copies the data into the buffer buff, or, - if return_buffer is TRUE, it just returns the pointer to the key cache - buffer with the data. + NOTES Filepos must be a multiple of 'block_length', but it doesn't have to be a multiple of key_cache_block_size; */ -uchar *key_cache_read(KEY_CACHE *keycache, - File file, my_off_t filepos, int level, - uchar *buff, uint length, - uint block_length __attribute__((unused)), - int return_buffer __attribute__((unused))) +uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache, + File file, my_off_t filepos, int level, + uchar *buff, uint length, + uint block_length __attribute__((unused)), + int return_buffer __attribute__((unused))) { my_bool locked_and_incremented= FALSE; int error=0; uchar *start= buff; - DBUG_ENTER("key_cache_read"); + DBUG_ENTER("simple_key_cache_read"); DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u", (uint) file, (ulong) filepos, length)); @@ -2740,28 +2998,47 @@ end: /* - Insert a block of file data from a buffer into key cache + Insert a block of file data from a buffer into a simple key cache SYNOPSIS - key_cache_insert() - keycache pointer to a key cache data structure + simple_key_cache_insert() + keycache pointer to the control block of a simple key cache file handler for the file to insert data from filepos position of the block of data in the file to insert level determines the weight of the data buff buffer to read data from length length of the data in the buffer - NOTES - This is used by MyISAM to move all blocks from a index file to the key - cache - + DESCRIPTION + This function is the implementation of the key_cache_insert interface + function that is employed by simple (non-partitioned) key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key + cache. + The function writes a block of file data from a buffer into the key cache. + The buffer is specified with the parameters buff and length - the pointer + to the beginning of the buffer and its size respectively. It's assumed + the buffer contains the data from 'file' allocated from the position + filepos. The data is copied from the buffer in key_cache_block_size + increments. + The parameter level is used to set one characteristic for the key buffers + loaded with the data from buff. The characteristic is used only by the + midpoint insertion strategy. + RETURN VALUE 0 if a success, 1 - otherwise. + + NOTES + The function is used by MyISAM to move all blocks from a index file to + the key cache. It can be performed in parallel with reading the file data + from the key buffers by other threads. + */ -int key_cache_insert(KEY_CACHE *keycache, - File file, my_off_t filepos, int level, - uchar *buff, uint length) +static +int simple_key_cache_insert(SIMPLE_KEY_CACHE_CB *keycache, + File file, my_off_t filepos, int level, + uchar *buff, uint length) { int error= 0; DBUG_ENTER("key_cache_insert"); @@ -2981,43 +3258,64 @@ int key_cache_insert(KEY_CACHE *keycache, /* - Write a buffer into a cached file. + Write a buffer into a simple key cache SYNOPSIS - key_cache_write() - keycache pointer to a key cache data structure - file handler for the file to write data to - filepos position in the file to write data to - level determines the weight of the data - buff buffer with the data - length length of the buffer - dont_write if is 0 then all dirty pages involved in writing - should have been flushed from key cache + simple_key_cache_write() + keycache pointer to the control block of a simple key cache + file handler for the file to write data to + file_extra maps of key cache partitions containing + dirty pages from file + filepos position in the file to write data to + level determines the weight of the data + buff buffer with the data + length length of the buffer + dont_write if is 0 then all dirty pages involved in writing + should have been flushed from key cache + DESCRIPTION + This function is the implementation of the key_cache_write interface + function that is employed by simple (non-partitioned) key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key + cache. + In a general case the function copies data from a buffer into the key + cache. The buffer is specified with the parameters buff and length - + the pointer to the beginning of the buffer and its size respectively. + It's assumed the buffer contains the data to be written into 'file' + starting from the position filepos. The data is copied from the buffer + in key_cache_block_size increments. + If the value of the parameter dont_write is FALSE then the function + also writes the data into file. + The parameter level is used to set one characteristic for the key buffers + filled with the data from buff. The characteristic is employed only by + the midpoint insertion strategy. + The parameter file_extra currently makes sense only for simple key caches + that are elements of a partitioned key cache. It provides a pointer to the + shared bitmap of the partitions that may contains dirty pages for the file. + This bitmap is used to optimize the function + flush_partitioned_key_cache_blocks. + RETURN VALUE 0 if a success, 1 - otherwise. - NOTES. - The function copies the data of size length from buff into buffers - for key cache blocks that are assigned to contain the portion of - the file starting with position filepos. - It ensures that this data is flushed to the file if dont_write is FALSE. - Filepos must be a multiple of 'block_length', but it doesn't - have to be a multiple of key_cache_block_size; - - dont_write is always TRUE in the server (info->lock_type is never F_UNLCK). + NOTES + This implementation exploits the fact that the function is called only + when a thread has got an exclusive lock for the key file. */ -int key_cache_write(KEY_CACHE *keycache, - File file, my_off_t filepos, int level, - uchar *buff, uint length, - uint block_length __attribute__((unused)), - int dont_write) +static +int simple_key_cache_write(SIMPLE_KEY_CACHE_CB *keycache, + File file, void *file_extra __attribute__((unused)), + my_off_t filepos, int level, + uchar *buff, uint length, + uint block_length __attribute__((unused)), + int dont_write) { my_bool locked_and_incremented= FALSE; int error=0; - DBUG_ENTER("key_cache_write"); + DBUG_ENTER("simple_key_cache_write"); DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u block_length: %u" " key_block_length: %u", @@ -3332,7 +3630,7 @@ end: Block must have a request registered on it. */ -static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block) +static void free_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block) { KEYCACHE_THREAD_TRACE("free block"); KEYCACHE_DBUG_PRINT("free_block", @@ -3472,7 +3770,7 @@ static int cmp_sec_link(BLOCK_LINK **a, BLOCK_LINK **b) free used blocks if requested */ -static int flush_cached_blocks(KEY_CACHE *keycache, +static int flush_cached_blocks(SIMPLE_KEY_CACHE_CB *keycache, File file, BLOCK_LINK **cache, BLOCK_LINK **end, enum flush_type type) @@ -3516,9 +3814,9 @@ static int flush_cached_blocks(KEY_CACHE *keycache, (BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE)); block->status|= BLOCK_IN_FLUSHWRITE; keycache_pthread_mutex_unlock(&keycache->cache_lock); - error= my_pwrite(file, block->buffer+block->offset, + error= my_pwrite(file, block->buffer + block->offset, block->length - block->offset, - block->hash_link->diskpos+ block->offset, + block->hash_link->diskpos + block->offset, MYF(MY_NABP | MY_WAIT_IF_FULL)); keycache_pthread_mutex_lock(&keycache->cache_lock); keycache->global_cache_write++; @@ -3578,7 +3876,7 @@ static int flush_cached_blocks(KEY_CACHE *keycache, /* - Flush all key blocks for a file to disk, but don't do any mutex locks. + Flush all key blocks for a file to disk, but don't do any mutex locks SYNOPSIS flush_key_blocks_int() @@ -3600,7 +3898,7 @@ static int flush_cached_blocks(KEY_CACHE *keycache, 1 error */ -static int flush_key_blocks_int(KEY_CACHE *keycache, +static int flush_key_blocks_int(SIMPLE_KEY_CACHE_CB *keycache, File file, enum flush_type type) { BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache; @@ -4042,22 +4340,46 @@ err: /* - Flush all blocks for a file to disk + Flush all blocks for a file from key buffers of a simple key cache SYNOPSIS - flush_key_blocks() - keycache pointer to a key cache data structure - file handler for the file to flush to - flush_type type of the flush + flush_simple_key_blocks() + keycache pointer to the control block of a simple key cache + file handler for the file to flush to + file_extra maps of key cache partitions containing + dirty pages from file (not used) + flush_type type of the flush operation + DESCRIPTION + This function is the implementation of the flush_key_blocks interface + function that is employed by simple (non-partitioned) key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type S_KEY_CACHE_CB for a simple key + cache. + In a general case the function flushes the data from all dirty key + buffers related to the file 'file' into this file. The function does + exactly this if the value of the parameter type is FLUSH_KEEP. If the + value of this parameter is FLUSH_RELEASE, the function additionally + releases the key buffers containing data from 'file' for new usage. + If the value of the parameter type is FLUSH_IGNORE_CHANGED the function + just releases the key buffers containing data from 'file'. + The parameter file_extra currently is not used by this function. + RETURN 0 ok 1 error + + NOTES + This implementation exploits the fact that the function is called only + when a thread has got an exclusive lock for the key file. */ -int flush_key_blocks(KEY_CACHE *keycache, - File file, enum flush_type type) +static +int flush_simple_key_cache_blocks(SIMPLE_KEY_CACHE_CB *keycache, + File file, + void *file_extra __attribute__((unused)), + enum flush_type type) { int res= 0; DBUG_ENTER("flush_key_blocks"); @@ -4111,7 +4433,7 @@ int flush_key_blocks(KEY_CACHE *keycache, != 0 Error */ -static int flush_all_key_blocks(KEY_CACHE *keycache) +static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache) { BLOCK_LINK *block; uint total_found; @@ -4214,37 +4536,43 @@ static int flush_all_key_blocks(KEY_CACHE *keycache) /* - Reset the counters of a key cache. + Reset the counters of a simple key cache SYNOPSIS - reset_key_cache_counters() - name the name of a key cache - key_cache pointer to the key kache to be reset + reset_simple_key_cache_counters() + name the name of a key cache + keycache pointer to the control block of a simple key cache DESCRIPTION - This procedure is used by process_key_caches() to reset the counters of all - currently used key caches, both the default one and the named ones. + This function is the implementation of the reset_key_cache_counters + interface function that is employed by simple (non-partitioned) key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type S_KEY_CACHE_CB for a simple key cache. + This function resets the values of all statistical counters for the key + cache to 0. + The parameter name is currently not used. RETURN 0 on success (always because it can't fail) */ -int reset_key_cache_counters(const char *name __attribute__((unused)), - KEY_CACHE *key_cache) +static +int reset_simple_key_cache_counters(const char *name __attribute__((unused)), + SIMPLE_KEY_CACHE_CB *keycache) { - DBUG_ENTER("reset_key_cache_counters"); - if (!key_cache->key_cache_inited) + DBUG_ENTER("reset_simple_key_cache_counters"); + if (!keycache->key_cache_inited) { DBUG_PRINT("info", ("Key cache %s not initialized.", name)); DBUG_RETURN(0); } DBUG_PRINT("info", ("Resetting counters for key cache %s.", name)); - key_cache->global_blocks_changed= 0; /* Key_blocks_not_flushed */ - key_cache->global_cache_r_requests= 0; /* Key_read_requests */ - key_cache->global_cache_read= 0; /* Key_reads */ - key_cache->global_cache_w_requests= 0; /* Key_write_requests */ - key_cache->global_cache_write= 0; /* Key_writes */ + keycache->global_blocks_changed= 0; /* Key_blocks_not_flushed */ + keycache->global_cache_r_requests= 0; /* Key_read_requests */ + keycache->global_cache_read= 0; /* Key_reads */ + keycache->global_cache_w_requests= 0; /* Key_write_requests */ + keycache->global_cache_write= 0; /* Key_writes */ DBUG_RETURN(0); } @@ -4253,9 +4581,10 @@ int reset_key_cache_counters(const char *name __attribute__((unused)), /* Test if disk-cache is ok */ -static void test_key_cache(KEY_CACHE *keycache __attribute__((unused)), - const char *where __attribute__((unused)), - my_bool lock __attribute__((unused))) +static +void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache __attribute__((unused)), + const char *where __attribute__((unused)), + my_bool lock __attribute__((unused))) { /* TODO */ } @@ -4267,7 +4596,7 @@ static void test_key_cache(KEY_CACHE *keycache __attribute__((unused)), #define MAX_QUEUE_LEN 100 -static void keycache_dump(KEY_CACHE *keycache) +static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache) { FILE *keycache_dump_file=fopen(KEYCACHE_DUMP_FILE, "w"); struct st_my_thread_var *last; @@ -4507,7 +4836,7 @@ static int fail_hlink(HASH_LINK *hlink) return 0; /* Let the assert fail. */ } -static int cache_empty(KEY_CACHE *keycache) +static int cache_empty(SIMPLE_KEY_CACHE_CB *keycache) { int errcnt= 0; int idx; @@ -4545,3 +4874,1545 @@ static int cache_empty(KEY_CACHE *keycache) } #endif + +/* + Get statistics for a simple key cache + + SYNOPSIS + get_simple_key_cache_statistics() + keycache pointer to the control block of a simple key cache + partition_no partition number (not used) + key_cache_stats OUT pointer to the structure for the returned statistics + + DESCRIPTION + This function is the implementation of the get_key_cache_statistics + interface function that is employed by simple (non-partitioned) key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key + cache. This function returns the statistical data for the key cache. + The parameter partition_no is not used by this function. + + RETURN + none +*/ + +static +void get_simple_key_cache_statistics(SIMPLE_KEY_CACHE_CB *keycache, + uint partition_no __attribute__((unused)), + KEY_CACHE_STATISTICS *keycache_stats) +{ + DBUG_ENTER("simple_get_key_cache_statistics"); + + keycache_stats->mem_size= (longlong) keycache->key_cache_mem_size; + keycache_stats->block_size= (longlong) keycache->key_cache_block_size; + keycache_stats->blocks_used= keycache->blocks_used; + keycache_stats->blocks_unused= keycache->blocks_unused; + keycache_stats->blocks_changed= keycache->global_blocks_changed; + keycache_stats->blocks_warm= keycache->warm_blocks; + keycache_stats->read_requests= keycache->global_cache_r_requests; + keycache_stats->reads= keycache->global_cache_read; + keycache_stats->write_requests= keycache->global_cache_w_requests; + keycache_stats->writes= keycache->global_cache_write; + DBUG_VOID_RETURN; +} + + +/* + The array of pointer to the key cache interface functions used for simple + key caches. Any simple key cache objects including those incorporated into + partitioned keys caches exploit this array. + + The current implementation of these functions allows to call them from + the MySQL server code directly. We don't do it though. +*/ + +static KEY_CACHE_FUNCS simple_key_cache_funcs = +{ + (INIT_KEY_CACHE) init_simple_key_cache, + (RESIZE_KEY_CACHE) resize_simple_key_cache, + (CHANGE_KEY_CACHE_PARAM) change_simple_key_cache_param, + (KEY_CACHE_READ) simple_key_cache_read, + (KEY_CACHE_INSERT) simple_key_cache_insert, + (KEY_CACHE_WRITE) simple_key_cache_write, + (FLUSH_KEY_BLOCKS) flush_simple_key_cache_blocks, + (RESET_KEY_CACHE_COUNTERS) reset_simple_key_cache_counters, + (END_KEY_CACHE) end_simple_key_cache, + (GET_KEY_CACHE_STATISTICS) get_simple_key_cache_statistics, +}; + + +/****************************************************************************** + Partitioned Key Cache Module + + The module contains implementations of all key cache interface functions + employed by partitioned key caches. + + A partitioned key cache is a collection of structures for simple key caches + called key cache partitions. Any page from a file can be placed into a buffer + of only one partition. The number of the partition is calculated from + the file number and the position of the page in the file, and it's always the + same for the page. The function that maps pages into partitions takes care + of even distribution of pages among partitions. + + Partition key cache mitigate one of the major problem of simple key cache: + thread contention for key cache lock (mutex). Every call of a key cache + interface function must acquire this lock. So threads compete for this lock + even in the case when they have acquired shared locks for the file and + pages they want read from are in the key cache buffers. + When working with a partitioned key cache any key cache interface function + that needs only one page has to acquire the key cache lock only for the + partition the page is ascribed to. This makes the chances for threads not + compete for the same key cache lock better. Unfortunately if we use a + partitioned key cache with N partitions for B-tree indexes we can't say + that the chances becomes N times less. The fact is that any index lookup + operation requires reading from the root page that, for any index, is always + ascribed to the same partition. To resolve this problem we should have + employed more sophisticated mechanisms of working with root pages. + + Currently the number of partitions in a partitioned key cache is limited + by 64. We could increase this limit. Simultaneously we would have to increase + accordingly the size of the bitmap dirty_part_map from the MYISAM_SHARE + structure. + +******************************************************************************/ + +/* Control block for a partitioned key cache */ + +typedef struct st_partitioned_key_cache_cb +{ + my_bool key_cache_inited; /*<=> control block is allocated */ + SIMPLE_KEY_CACHE_CB **partition_array; /* the key cache partitions */ + size_t key_cache_mem_size; /* specified size of the cache memory */ + uint key_cache_block_size; /* size of the page buffer of a cache block */ + uint partitions; /* number of partitions in the key cache */ +} PARTITIONED_KEY_CACHE_CB; + +static +void end_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache, + my_bool cleanup); + +static int +reset_partitioned_key_cache_counters(const char *name, + PARTITIONED_KEY_CACHE_CB *keycache); + +/* + Determine the partition to which the index block to read is ascribed + + SYNOPSIS + get_key_cache_partition() + keycache pointer to the control block of a partitioned key cache + file handler for the file for the block of data to be read + filepos position of the block of data in the file + + DESCRIPTION + The function determines the number of the partition in whose buffer the + block from 'file' at the position filepos has to be placed for reading. + The function returns the control block of the simple key cache for this + partition to the caller. + + RETURN VALUE + The pointer to the control block of the partition to which the specified + file block is ascribed. +*/ + +static +SIMPLE_KEY_CACHE_CB * +get_key_cache_partition(PARTITIONED_KEY_CACHE_CB *keycache, + File file, my_off_t filepos) +{ + uint i= KEYCACHE_BASE_EXPR(file, filepos) % keycache->partitions; + return keycache->partition_array[i]; +} + + +/* + Determine the partition to which the index block to write is ascribed + + SYNOPSIS + get_key_cache_partition() + keycache pointer to the control block of a partitioned key cache + file handler for the file for the block of data to be read + filepos position of the block of data in the file + dirty_part_map pointer to the bitmap of dirty partitions for the file + + DESCRIPTION + The function determines the number of the partition in whose buffer the + block from 'file' at the position filepos has to be placed for writing and + marks the partition as dirty in the dirty_part_map bitmap. + The function returns the control block of the simple key cache for this + partition to the caller. + + RETURN VALUE + The pointer to the control block of the partition to which the specified + file block is ascribed. +*/ + +static SIMPLE_KEY_CACHE_CB +*get_key_cache_partition_for_write(PARTITIONED_KEY_CACHE_CB *keycache, + File file, my_off_t filepos, + ulonglong* dirty_part_map) +{ + uint i= KEYCACHE_BASE_EXPR( file, filepos) % keycache->partitions; + *dirty_part_map|= 1ULL << i; + return keycache->partition_array[i]; +} + + +/* + Initialize a partitioned key cache + + SYNOPSIS + init_partitioned_key_cache() + keycache pointer to the control block of a partitioned key cache + key_cache_block_size size of blocks to keep cached data + use_mem total memory to use for all key cache partitions + division_limit division limit (may be zero) + age_threshold age threshold (may be zero) + + DESCRIPTION + This function is the implementation of the init_key_cache interface function + that is employed by partitioned key caches. + The function builds and initializes an array of simple key caches, and then + initializes the control block structure of the type PARTITIONED_KEY_CACHE_CB + that is used for a partitioned key cache. The parameter keycache is + supposed to point to this structure. The number of partitions in the + partitioned key cache to be built must be passed through the field + 'partitions' of this structure. The parameter key_cache_block_size specifies + the size of the blocks in the the simple key caches to be built. + The parameters division_limit and age_threshold determine the initial + values of those characteristics of the simple key caches that are used for + midpoint insertion strategy. The parameter use_mem specifies the total + amount of memory to be allocated for the key cache blocks in all simple key + caches and for all auxiliary structures. + + RETURN VALUE + total number of blocks in key cache partitions, if successful, + <= 0 - otherwise. + + NOTES + If keycache->key_cache_inited != 0 then we assume that the memory for + the array of partitions has been already allocated. + + It's assumed that no two threads call this function simultaneously + referring to the same key cache handle. +*/ + +static +int init_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache, + uint key_cache_block_size, + size_t use_mem, uint division_limit, + uint age_threshold) +{ + int i; + size_t mem_per_cache; + size_t mem_decr; + int cnt; + SIMPLE_KEY_CACHE_CB *partition; + SIMPLE_KEY_CACHE_CB **partition_ptr; + uint partitions= keycache->partitions; + int blocks= 0; + DBUG_ENTER("partitioned_init_key_cache"); + + keycache->key_cache_block_size = key_cache_block_size; + + if (keycache->key_cache_inited) + partition_ptr= keycache->partition_array; + else + { + if(!(partition_ptr= + (SIMPLE_KEY_CACHE_CB **) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB *) * + partitions, MYF(MY_WME)))) + DBUG_RETURN(-1); + bzero(partition_ptr, sizeof(SIMPLE_KEY_CACHE_CB *) * partitions); + keycache->partition_array= partition_ptr; + } + + mem_per_cache = use_mem / partitions; + mem_decr= mem_per_cache / 5; + + for (i= 0; i < (int) partitions; i++) + { + my_bool key_cache_inited= keycache->key_cache_inited; + if (key_cache_inited) + partition= *partition_ptr; + else + { + if (!(partition= + (SIMPLE_KEY_CACHE_CB *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB), + MYF(MY_WME)))) + continue; + partition->key_cache_inited= 0; + } + + cnt= init_simple_key_cache(partition, key_cache_block_size, mem_per_cache, + division_limit, age_threshold); + if (cnt <= 0) + { + end_simple_key_cache(partition, 1); + if (!key_cache_inited) + { + my_free(partition, MYF(0)); + partition= 0; + } + if ((i == 0 && cnt < 0) || i > 0) + { + /* + Here we have two cases: + 1. i == 0 and cnt < 0 + cnt < 0 => mem_per_cache is not big enough to allocate minimal + number of key blocks in the key cache of the partition. + Decrease the the number of the partitions by 1 and start again. + 2. i > 0 + There is not enough memory for one of the succeeding partitions. + Just skip this partition decreasing the number of partitions in + the key cache by one. + Do not change the value of mem_per_cache in both cases. + */ + if (key_cache_inited) + { + my_free(partition, MYF(0)); + partition= 0; + if(key_cache_inited) + memmove(partition_ptr, partition_ptr+1, + sizeof(partition_ptr)*(partitions-i-1)); + } + if (!--partitions) + break; + } + else + { + /* + We come here when i == 0 && cnt == 0. + cnt == 0 => the memory allocator fails to allocate a block of + memory of the size mem_per_cache. Decrease the value of + mem_per_cache without changing the current number of partitions + and start again. Make sure that such a decrease may happen not + more than 5 times in total. + */ + if (use_mem <= mem_decr) + break; + use_mem-= mem_decr; + } + i--; + mem_per_cache= use_mem/partitions; + continue; + } + else + { + blocks+= cnt; + *partition_ptr++= partition; + } + } + + keycache->partitions= partitions= partition_ptr-keycache->partition_array; + keycache->key_cache_mem_size= mem_per_cache * partitions; + for (i= 0; i < (int) partitions; i++) + keycache->partition_array[i]->hash_factor= partitions; + + keycache->key_cache_inited= 1; + + if (!partitions) + blocks= -1; + + DBUG_RETURN(blocks); +} + + +/* + Resize a partitioned key cache + + SYNOPSIS + resize_partitioned_key_cache() + keycache pointer to the control block of a partitioned key cache + key_cache_block_size size of blocks to keep cached data + use_mem total memory to use for the new key cache + division_limit new division limit (if not zero) + age_threshold new age threshold (if not zero) + + DESCRIPTION + This function is the implementation of the resize_key_cache interface + function that is employed by partitioned key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type PARTITIONED_KEY_CACHE_CB for the + partitioned key cache to be resized. + The parameter key_cache_block_size specifies the new size of the blocks in + the simple key caches that comprise the partitioned key cache. + The parameters division_limit and age_threshold determine the new initial + values of those characteristics of the simple key cache that are used for + midpoint insertion strategy. The parameter use-mem specifies the total + amount of memory to be allocated for the key cache blocks in all new + simple key caches and for all auxiliary structures. + + RETURN VALUE + number of blocks in the key cache, if successful, + 0 - otherwise. + + NOTES. + The function first calls prepare_resize_simple_key_cache for each simple + key cache effectively flushing all dirty pages from it and destroying + the key cache. Then init_partitioned_key_cache is called. This call builds + a new array of simple key caches containing the same number of elements + as the old one. After this the function calls the function + finish_resize_simple_key_cache for each simple key cache from this array. + + This implementation doesn't block the calls and executions of other + functions from the key cache interface. However it assumes that the + calls of resize_partitioned_key_cache itself are serialized. +*/ + +static +int resize_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache, + uint key_cache_block_size, + size_t use_mem, uint division_limit, + uint age_threshold) +{ + uint i; + uint partitions= keycache->partitions; + my_bool cleanup= use_mem == 0; + int blocks= -1; + int err= 0; + DBUG_ENTER("partitioned_resize_key_cache"); + if (cleanup) + { + end_partitioned_key_cache(keycache, 0); + DBUG_RETURN(-1); + } + for (i= 0; i < partitions; i++) + { + err|= prepare_resize_simple_key_cache(keycache->partition_array[i], 0, 1); + } + if (!err) + blocks= init_partitioned_key_cache(keycache, key_cache_block_size, + use_mem, division_limit, age_threshold); + if (blocks > 0) + { + for (i= 0; i < partitions; i++) + { + finish_resize_simple_key_cache(keycache->partition_array[i], 0, 1); + } + } + DBUG_RETURN(blocks); +} + + +/* + Change key cache parameters of a partitioned key cache + + SYNOPSIS + partitioned_change_key_cache_param() + keycache pointer to the control block of a partitioned key cache + division_limit new division limit (if not zero) + age_threshold new age threshold (if not zero) + + DESCRIPTION + This function is the implementation of the change_key_cache_param interface + function that is employed by partitioned key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type PARTITIONED_KEY_CACHE_CB for the simple + key cache where new values of the division limit and the age threshold used + for midpoint insertion strategy are to be set. The parameters + division_limit and age_threshold provide these new values. + + RETURN VALUE + none + + NOTES + The function just calls change_simple_key_cache_param for each element from + the array of simple caches that comprise the partitioned key cache. +*/ + +static +void change_partitioned_key_cache_param(PARTITIONED_KEY_CACHE_CB *keycache, + uint division_limit, + uint age_threshold) +{ + uint i; + uint partitions= keycache->partitions; + DBUG_ENTER("partitioned_change_key_cache_param"); + for (i= 0; i < partitions; i++) + { + change_simple_key_cache_param(keycache->partition_array[i], division_limit, + age_threshold); + } + DBUG_VOID_RETURN; +} + + +/* + Destroy a partitioned key cache + + SYNOPSIS + end_partitioned_key_cache() + keycache pointer to the control block of a partitioned key cache + cleanup <=> complete free (free also control block structures + for all simple key caches) + + DESCRIPTION + This function is the implementation of the end_key_cache interface + function that is employed by partitioned key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type PARTITIONED_KEY_CACHE_CB for the + partitioned key cache to be destroyed. + The function frees the memory allocated for the cache blocks and + auxiliary structures used by simple key caches that comprise the + partitioned key cache. If the value of the parameter cleanup is TRUE + then even the memory used for control blocks of the simple key caches + and the array of pointers to them are freed. + + RETURN VALUE + none +*/ + +static +void end_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache, + my_bool cleanup) +{ + uint i; + uint partitions= keycache->partitions; + DBUG_ENTER("partitioned_end_key_cache"); + DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache)); + + for (i= 0; i < partitions; i++) + { + end_simple_key_cache(keycache->partition_array[i], cleanup); + } + if (cleanup) + { + for (i= 0; i < partitions; i++) + my_free((uchar*) keycache->partition_array[i], MYF(0)); + my_free((uchar*) keycache->partition_array, MYF(0)); + keycache->key_cache_inited= 0; + } + DBUG_VOID_RETURN; +} + + +/* + Read a block of data from a partitioned key cache into a buffer + + SYNOPSIS + + partitioned_key_cache_read() + keycache pointer to the control block of a partitioned key cache + file handler for the file for the block of data to be read + filepos position of the block of data in the file + level determines the weight of the data + buff buffer to where the data must be placed + length length of the buffer + block_length length of the read data from a key cache block + return_buffer return pointer to the key cache buffer with the data + + DESCRIPTION + This function is the implementation of the key_cache_read interface + function that is employed by partitioned key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type PARTITIONED_KEY_CACHE_CB for a + partitioned key cache. + In a general case the function reads a block of data from the key cache + into the buffer buff of the size specified by the parameter length. The + beginning of the block of data to be read is specified by the parameters + file and filepos. The length of the read data is the same as the length + of the buffer. The data is read into the buffer in key_cache_block_size + increments. To read each portion the function first finds out in what + partition of the key cache this portion(page) is to be saved, and calls + simple_key_cache_read with the pointer to the corresponding simple key as + its first parameter. + If the parameter return_buffer is not ignored and its value is TRUE, and + the data to be read of the specified size block_length can be read from one + key cache buffer, then the function returns a pointer to the data in the + key cache buffer. + The function takes into account parameters block_length and return buffer + only in a single-threaded environment. + The parameter 'level' is used only by the midpoint insertion strategy + when the data or its portion cannot be found in the key cache. + + RETURN VALUE + Returns address from where the data is placed if successful, 0 - otherwise. +*/ + +static +uchar *partitioned_key_cache_read(PARTITIONED_KEY_CACHE_CB *keycache, + File file, my_off_t filepos, int level, + uchar *buff, uint length, + uint block_length __attribute__((unused)), + int return_buffer __attribute__((unused))) +{ + uint r_length; + uint offset= (uint) (filepos % keycache->key_cache_block_size); + uchar *start= buff; + DBUG_ENTER("partitioned_key_cache_read"); + DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u", + (uint) file, (ulong) filepos, length)); + +#ifndef THREAD + if (block_length > keycache->key_cache_block_size || offset) + return_buffer=0; +#endif + + /* Read data in key_cache_block_size increments */ + do + { + SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition(keycache, + file, filepos); + uchar *ret_buff= 0; + r_length= length; + set_if_smaller(r_length, keycache->key_cache_block_size - offset); + ret_buff= simple_key_cache_read((void *) partition, + file, filepos, level, + buff, r_length, + block_length, return_buffer); + if (ret_buff == 0) + DBUG_RETURN(0); +#ifndef THREAD + /* This is only true if we were able to read everything in one block */ + if (return_buffer) + DBUG_RETURN(ret_buff); +#endif + filepos+= r_length; + buff+= r_length; + offset= 0; + } while ((length-= r_length)); + + DBUG_RETURN(start); +} + + +/* + Insert a block of file data from a buffer into a partitioned key cache + + SYNOPSIS + partitioned_key_cache_insert() + keycache pointer to the control block of a partitioned key cache + file handler for the file to insert data from + filepos position of the block of data in the file to insert + level determines the weight of the data + buff buffer to read data from + length length of the data in the buffer + + DESCRIPTION + This function is the implementation of the key_cache_insert interface + function that is employed by partitioned key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type PARTITIONED_KEY_CACHE_CB for a + partitioned key cache. + The function writes a block of file data from a buffer into the key cache. + The buffer is specified with the parameters buff and length - the pointer + to the beginning of the buffer and its size respectively. It's assumed + that the buffer contains the data from 'file' allocated from the position + filepos. The data is copied from the buffer in key_cache_block_size + increments. For every portion of data the function finds out in what simple + key cache from the array of partitions the data must be stored, and after + this calls simple_key_cache_insert to copy the data into a key buffer of + this simple key cache. + The parameter level is used to set one characteristic for the key buffers + loaded with the data from buff. The characteristic is used only by the + midpoint insertion strategy. + + RETURN VALUE + 0 if a success, 1 - otherwise. + + NOTES + The function is used by MyISAM to move all blocks from a index file to + the key cache. It can be performed in parallel with reading the file data + from the key buffers by other threads. +*/ + +static +int partitioned_key_cache_insert(PARTITIONED_KEY_CACHE_CB *keycache, + File file, my_off_t filepos, int level, + uchar *buff, uint length) +{ + uint w_length; + uint offset= (uint) (filepos % keycache->key_cache_block_size); + DBUG_ENTER("partitioned_key_cache_insert"); + DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u", + (uint) file,(ulong) filepos, length)); + + + /* Write data in key_cache_block_size increments */ + do + { + SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition(keycache, + file, filepos); + w_length= length; + set_if_smaller(w_length, keycache->key_cache_block_size - offset); + if (simple_key_cache_insert((void *) partition, + file, filepos, level, + buff, w_length)) + DBUG_RETURN(1); + + filepos+= w_length; + buff+= w_length; + offset = 0; + } while ((length-= w_length)); + + DBUG_RETURN(0); +} + + +/* + Write data from a buffer into a partitioned key cache + + SYNOPSIS + + partitioned_key_cache_write() + keycache pointer to the control block of a partitioned key cache + file handler for the file to write data to + filepos position in the file to write data to + level determines the weight of the data + buff buffer with the data + length length of the buffer + dont_write if is 0 then all dirty pages involved in writing + should have been flushed from key cache + file_extra maps of key cache partitions containing + dirty pages from file + + DESCRIPTION + This function is the implementation of the key_cache_write interface + function that is employed by partitioned key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type PARTITIONED_KEY_CACHE_CB for a + partitioned key cache. + In a general case the function copies data from a buffer into the key + cache. The buffer is specified with the parameters buff and length - + the pointer to the beginning of the buffer and its size respectively. + It's assumed the buffer contains the data to be written into 'file' + starting from the position filepos. The data is copied from the buffer + in key_cache_block_size increments. For every portion of data the + function finds out in what simple key cache from the array of partitions + the data must be stored, and after this calls simple_key_cache_write to + copy the data into a key buffer of this simple key cache. + If the value of the parameter dont_write is FALSE then the function + also writes the data into file. + The parameter level is used to set one characteristic for the key buffers + filled with the data from buff. The characteristic is employed only by + the midpoint insertion strategy. + The parameter file_expra provides a pointer to the shared bitmap of + the partitions that may contains dirty pages for the file. This bitmap + is used to optimize the function flush_partitioned_key_cache_blocks. + + RETURN VALUE + 0 if a success, 1 - otherwise. + + NOTES + This implementation exploits the fact that the function is called only + when a thread has got an exclusive lock for the key file. +*/ + +static +int partitioned_key_cache_write(PARTITIONED_KEY_CACHE_CB *keycache, + File file, void *file_extra, + my_off_t filepos, int level, + uchar *buff, uint length, + uint block_length __attribute__((unused)), + int dont_write) +{ + uint w_length; + ulonglong *part_map= (ulonglong *) file_extra; + uint offset= (uint) (filepos % keycache->key_cache_block_size); + DBUG_ENTER("partitioned_key_cache_write"); + DBUG_PRINT("enter", + ("fd: %u pos: %lu length: %u block_length: %u" + " key_block_length: %u", + (uint) file, (ulong) filepos, length, block_length, + keycache ? keycache->key_cache_block_size : 0)); + + + /* Write data in key_cache_block_size increments */ + do + { + SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition_for_write(keycache, + file, + filepos, + part_map); + w_length = length; + set_if_smaller(w_length, keycache->key_cache_block_size - offset ); + if (simple_key_cache_write(partition, + file, 0, filepos, level, + buff, w_length, block_length, + dont_write)) + DBUG_RETURN(1); + + filepos+= w_length; + buff+= w_length; + offset= 0; + } while ((length-= w_length)); + + DBUG_RETURN(0); +} + + +/* + Flush all blocks for a file from key buffers of a partitioned key cache + + SYNOPSIS + + flush_partitioned_key_cache_blocks() + keycache pointer to the control block of a partitioned key cache + file handler for the file to flush to + file_extra maps of key cache partitions containing + dirty pages from file (not used) + flush_type type of the flush operation + + DESCRIPTION + This function is the implementation of the flush_key_blocks interface + function that is employed by partitioned key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type PARTITIONED_KEY_CACHE_CB for a + partitioned key cache. + In a general case the function flushes the data from all dirty key + buffers related to the file 'file' into this file. The function does + exactly this if the value of the parameter type is FLUSH_KEEP. If the + value of this parameter is FLUSH_RELEASE, the function additionally + releases the key buffers containing data from 'file' for new usage. + If the value of the parameter type is FLUSH_IGNORE_CHANGED the function + just releases the key buffers containing data from 'file'. + The function performs the operation by calling the function + flush_simple_key_cache_blocks for the elements of the array of the + simple key caches that comprise the partitioned key_cache. If the value + of the parameter type is FLUSH_KEEP s_flush_key_blocks is called only + for the partitions with possibly dirty pages marked in the bitmap + pointed to by the parameter file_extra. + + RETURN + 0 ok + 1 error + + NOTES + This implementation exploits the fact that the function is called only + when a thread has got an exclusive lock for the key file. +*/ + +static +int flush_partitioned_key_cache_blocks(PARTITIONED_KEY_CACHE_CB *keycache, + File file, void *file_extra, + enum flush_type type) +{ + uint i; + uint partitions= keycache->partitions; + int err= 0; + ulonglong *dirty_part_map= (ulonglong *) file_extra; + DBUG_ENTER("partitioned_flush_key_blocks"); + DBUG_PRINT("enter", ("keycache: 0x%lx", (long) keycache)); + + for (i= 0; i < partitions; i++) + { + SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i]; + if ((type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE) && + !((*dirty_part_map) & ((ulonglong) 1 << i))) + continue; + err|= test(flush_simple_key_cache_blocks(partition, file, 0, type)); + } + *dirty_part_map= 0; + + DBUG_RETURN(err); +} + + +/* + Reset the counters of a partitioned key cache + + SYNOPSIS + reset_partitioned_key_cache_counters() + name the name of a key cache + keycache pointer to the control block of a partitioned key cache + + DESCRIPTION + This function is the implementation of the reset_key_cache_counters + interface function that is employed by partitioned key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type PARTITIONED_KEY_CACHE_CB for a partitioned + key cache. + This function resets the values of the statistical counters of the simple + key caches comprising partitioned key cache to 0. It does it by calling + reset_simple_key_cache_counters for each key cache partition. + The parameter name is currently not used. + + RETURN + 0 on success (always because it can't fail) +*/ + +static int +reset_partitioned_key_cache_counters(const char *name __attribute__((unused)), + PARTITIONED_KEY_CACHE_CB *keycache) +{ + uint i; + uint partitions= keycache->partitions; + DBUG_ENTER("partitioned_reset_key_cache_counters"); + + for (i = 0; i < partitions; i++) + { + reset_simple_key_cache_counters(name, keycache->partition_array[i]); + } + DBUG_RETURN(0); +} + + +/* + Get statistics for a partition key cache + + SYNOPSIS + get_partitioned_key_cache_statistics() + keycache pointer to the control block of a partitioned key cache + partition_no partition number to get statistics for + key_cache_stats OUT pointer to the structure for the returned statistics + + DESCRIPTION + This function is the implementation of the get_key_cache_statistics + interface function that is employed by partitioned key caches. + The function takes the parameter keycache as a pointer to the + control block structure of the type PARTITIONED_KEY_CACHE_CB for + a partitioned key cache. + If the value of the parameter partition_no is equal to 0 then aggregated + statistics for all partitions is returned in the fields of the + structure key_cache_stat of the type KEY_CACHE_STATISTICS . Otherwise + the function returns data for the partition number partition_no of the + key cache in the structure key_cache_stat. (Here partitions are numbered + starting from 1.) + + RETURN + none +*/ + +static +void +get_partitioned_key_cache_statistics(PARTITIONED_KEY_CACHE_CB *keycache, + uint partition_no, + KEY_CACHE_STATISTICS *keycache_stats) +{ + uint i; + SIMPLE_KEY_CACHE_CB *partition; + uint partitions= keycache->partitions; + DBUG_ENTER("get_partitioned_key_cache_statistics"); + + if (partition_no != 0) + { + partition= keycache->partition_array[partition_no-1]; + get_simple_key_cache_statistics((void *) partition, 0, keycache_stats); + DBUG_VOID_RETURN; + } + bzero(keycache_stats, sizeof(KEY_CACHE_STATISTICS)); + keycache_stats->mem_size= (longlong) keycache->key_cache_mem_size; + keycache_stats->block_size= (longlong) keycache->key_cache_block_size; + for (i = 0; i < partitions; i++) + { + partition= keycache->partition_array[i]; + keycache_stats->blocks_used+= partition->blocks_used; + keycache_stats->blocks_unused+= partition->blocks_unused; + keycache_stats->blocks_changed+= partition->global_blocks_changed; + keycache_stats->blocks_warm+= partition->warm_blocks; + keycache_stats->read_requests+= partition->global_cache_r_requests; + keycache_stats->reads+= partition->global_cache_read; + keycache_stats->write_requests+= partition->global_cache_w_requests; + keycache_stats->writes+= partition->global_cache_write; + } + DBUG_VOID_RETURN; +} + +/* + The array of pointers to the key cache interface functions used by + partitioned key caches. Any partitioned key cache object caches exploits + this array. + + The current implementation of these functions does not allow to call + them from the MySQL server code directly. The key cache interface + wrappers must be used for this purpose. +*/ + +static KEY_CACHE_FUNCS partitioned_key_cache_funcs = +{ + (INIT_KEY_CACHE) init_partitioned_key_cache, + (RESIZE_KEY_CACHE) resize_partitioned_key_cache, + (CHANGE_KEY_CACHE_PARAM) change_partitioned_key_cache_param, + (KEY_CACHE_READ) partitioned_key_cache_read, + (KEY_CACHE_INSERT) partitioned_key_cache_insert, + (KEY_CACHE_WRITE) partitioned_key_cache_write, + (FLUSH_KEY_BLOCKS) flush_partitioned_key_cache_blocks, + (RESET_KEY_CACHE_COUNTERS) reset_partitioned_key_cache_counters, + (END_KEY_CACHE) end_partitioned_key_cache, + (GET_KEY_CACHE_STATISTICS) get_partitioned_key_cache_statistics, +}; + + +/****************************************************************************** + Key Cache Interface Module + + The module contains wrappers for all key cache interface functions. + + Currently there are key caches of two types: simple key caches and + partitioned key caches. Each type (class) has its own implementation of the + basic key cache operations used the MyISAM storage engine. The pointers + to the implementation functions are stored in two static structures of the + type KEY_CACHE_FUNC: simple_key_cache_funcs - for simple key caches, and + partitioned_key_cache_funcs - for partitioned key caches. When a key cache + object is created the constructor procedure init_key_cache places a pointer + to the corresponding table into one of its fields. The procedure also + initializes a control block for the key cache oject and saves the pointer + to this block in another field of the key cache object. + When a key cache wrapper function is invoked for a key cache object to + perform a basic key cache operation it looks into the interface table + associated with the key cache oject and calls the corresponding + implementation of the operation. It passes the saved key cache control + block to this implementation. If, for some reasons, the control block + has not been fully initialized yet, the wrapper function either does not + do anything or, in the case when it perform a read/write operation, the + function do it directly through the system i/o functions. + + As we can see the model with which the key cache interface is supported + as quite conventional for interfaces in general. + +******************************************************************************/ + + +/* + Initialize a key cache + + SYNOPSIS + init_key_cache() + keycache pointer to the key cache to be initialized + key_cache_block_size size of blocks to keep cached data + use_mem total memory to use for cache buffers/structures + division_limit division limit (may be zero) + age_threshold age threshold (may be zero) + partitions number of partitions in the key cache + + DESCRIPTION + The function creates a control block structure for a key cache and + places the pointer to this block in the structure keycache. + If the value of the parameter 'partitions' is 0 then a simple key cache + is created. Otherwise a partitioned key cache with the specified number + of partitions is created. + The parameter key_cache_block_size specifies the size of the blocks in + the key cache to be created. The parameters division_limit and + age_threshold determine the initial values of those characteristics of + the key cache that are used for midpoint insertion strategy. The parameter + use_mem specifies the total amount of memory to be allocated for the + key cache buffers and for all auxiliary structures. + + RETURN VALUE + total number of blocks in key cache partitions, if successful, + <= 0 - otherwise. + + NOTES + if keycache->key_cache_inited != 0 we assume that the memory + for the control block of the key cache has been already allocated. + + It's assumed that no two threads call this function simultaneously + referring to the same key cache handle. +*/ + +int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, + size_t use_mem, uint division_limit, + uint age_threshold, uint partitions) +{ + void *keycache_cb; + int blocks; + if (keycache->key_cache_inited) + keycache_cb= keycache->keycache_cb; + else + { + if (partitions == 0) + { + if (!(keycache_cb= (void *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB), + MYF(0)))) + return 0; + ((SIMPLE_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0; + keycache->key_cache_type= SIMPLE_KEY_CACHE; + keycache->interface_funcs= &simple_key_cache_funcs; + } + else + { + if (!(keycache_cb= (void *) my_malloc(sizeof(PARTITIONED_KEY_CACHE_CB), + MYF(0)))) + return 0; + ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0; + keycache->key_cache_type= PARTITIONED_KEY_CACHE; + keycache->interface_funcs= &partitioned_key_cache_funcs; + } + keycache->keycache_cb= keycache_cb; + keycache->key_cache_inited= 1; + } + + if (partitions != 0) + { + ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions= partitions; + } + keycache->can_be_used= 0; + blocks= keycache->interface_funcs->init(keycache_cb, key_cache_block_size, + use_mem, division_limit, + age_threshold); + keycache->partitions= partitions ? + ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions : + 0; + DBUG_ASSERT(partitions <= MAX_KEY_CACHE_PARTITIONS); + if (blocks > 0) + keycache->can_be_used= 1; + return blocks; +} + + +/* + Resize a key cache + + SYNOPSIS + resize_key_cache() + keycache pointer to the key cache to be resized + key_cache_block_size size of blocks to keep cached data + use_mem total memory to use for the new key cache + division_limit new division limit (if not zero) + age_threshold new age threshold (if not zero) + + DESCRIPTION + The function operates over the key cache key cache. + The parameter key_cache_block_size specifies the new size of the block + buffers in the key cache. The parameters division_limit and age_threshold + determine the new initial values of those characteristics of the key cache + that are used for midpoint insertion strategy. The parameter use_mem + specifies the total amount of memory to be allocated for the key cache + buffers and for all auxiliary structures. + + RETURN VALUE + number of blocks in the key cache, if successful, + 0 - otherwise. + + NOTES + The function does not block the calls and executions of other functions + from the key cache interface. However it assumes that the calls of + resize_key_cache itself are serialized. + + Currently the function is called when the values of the variables + key_buffer_size and/or key_cache_block_size are being reset for + the key cache keycache. +*/ + +int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, + size_t use_mem, uint division_limit, uint age_threshold) +{ + int blocks= -1; + if (keycache->key_cache_inited) + { + if ((uint) keycache->param_partitions != keycache->partitions && use_mem) + blocks= repartition_key_cache(keycache, + key_cache_block_size, use_mem, + division_limit, age_threshold, + (uint) keycache->param_partitions); + else + { + blocks= keycache->interface_funcs->resize(keycache->keycache_cb, + key_cache_block_size, + use_mem, division_limit, + age_threshold); + + if (keycache->partitions) + keycache->partitions= + ((PARTITIONED_KEY_CACHE_CB *)(keycache->keycache_cb))->partitions; + } + + keycache->can_be_used= (blocks >= 0); + } + return blocks; +} + + +/* + Change key cache parameters of a key cache + + SYNOPSIS + change_key_cache_param() + keycache pointer to the key cache to change parameters for + division_limit new division limit (if not zero) + age_threshold new age threshold (if not zero) + + DESCRIPTION + The function sets new values of the division limit and the age threshold + used when the key cache keycach employs midpoint insertion strategy. + The parameters division_limit and age_threshold provide these new values. + + RETURN VALUE + none + + NOTES + Currently the function is called when the values of the variables + key_cache_division_limit and/or key_cache_age_threshold are being reset + for the key cache keycache. +*/ + +void change_key_cache_param(KEY_CACHE *keycache, uint division_limit, + uint age_threshold) +{ + if (keycache->key_cache_inited) + { + + keycache->interface_funcs->change_param(keycache->keycache_cb, + division_limit, + age_threshold); + } +} + + +/* + Destroy a key cache + + SYNOPSIS + end_key_cache() + keycache pointer to the key cache to be destroyed + cleanup <=> complete free + + DESCRIPTION + The function frees the memory allocated for the cache blocks and + auxiliary structures used by the key cache keycache. If the value + of the parameter cleanup is TRUE then all resources used by the key + cache are to be freed. + + RETURN VALUE + none +*/ + +void end_key_cache(KEY_CACHE *keycache, my_bool cleanup) +{ + if (keycache->key_cache_inited) + { + keycache->interface_funcs->end(keycache->keycache_cb, cleanup); + if (cleanup) + { + if (keycache->keycache_cb) + { + my_free((uchar *) keycache->keycache_cb, MYF(0)); + keycache->keycache_cb= 0; + } + keycache->key_cache_inited= 0; + } + keycache->can_be_used= 0; + } +} + + +/* + Read a block of data from a key cache into a buffer + + SYNOPSIS + + key_cache_read() + keycache pointer to the key cache to read data from + file handler for the file for the block of data to be read + filepos position of the block of data in the file + level determines the weight of the data + buff buffer to where the data must be placed + length length of the buffer + block_length length of the data read from a key cache block + return_buffer return pointer to the key cache buffer with the data + + DESCRIPTION + The function operates over buffers of the key cache keycache. + In a general case the function reads a block of data from the key cache + into the buffer buff of the size specified by the parameter length. The + beginning of the block of data to be read is specified by the parameters + file and filepos. The length of the read data is the same as the length + of the buffer. + If the parameter return_buffer is not ignored and its value is TRUE, and + the data to be read of the specified size block_length can be read from one + key cache buffer, then the function returns a pointer to the data in the + key cache buffer. + The parameter 'level' is used only by the midpoint insertion strategy + when the data or its portion cannot be found in the key cache. + The function reads data into the buffer directly from file if the control + block of the key cache has not been initialized yet. + + RETURN VALUE + Returns address from where the data is placed if successful, 0 - otherwise. + + NOTES. + Filepos must be a multiple of 'block_length', but it doesn't + have to be a multiple of key_cache_block_size; +*/ + +uchar *key_cache_read(KEY_CACHE *keycache, + File file, my_off_t filepos, int level, + uchar *buff, uint length, + uint block_length, int return_buffer) +{ + if (keycache->key_cache_inited && keycache->can_be_used) + return keycache->interface_funcs->read(keycache->keycache_cb, + file, filepos, level, + buff, length, + block_length, return_buffer); + + /* We can't use mutex here as the key cache may not be initialized */ + + if (my_pread(file, (uchar*) buff, length, filepos, MYF(MY_NABP))) + return (uchar *) 0; + + return buff; +} + + +/* + Insert a block of file data from a buffer into a key cache + + SYNOPSIS + key_cache_insert() + keycache pointer to the key cache to insert data into + file handler for the file to insert data from + filepos position of the block of data in the file to insert + level determines the weight of the data + buff buffer to read data from + length length of the data in the buffer + + DESCRIPTION + The function operates over buffers of the key cache keycache. + The function writes a block of file data from a buffer into the key cache. + The buffer is specified with the parameters buff and length - the pointer + to the beginning of the buffer and its size respectively. It's assumed + that the buffer contains the data from 'file' allocated from the position + filepos. + The parameter level is used to set one characteristic for the key buffers + loaded with the data from buff. The characteristic is used only by the + midpoint insertion strategy. + + RETURN VALUE + 0 if a success, 1 - otherwise. + + NOTES + The function is used by MyISAM to move all blocks from a index file to + the key cache. + It is assumed that it may be performed in parallel with reading the file + data from the key buffers by other threads. +*/ + +int key_cache_insert(KEY_CACHE *keycache, + File file, my_off_t filepos, int level, + uchar *buff, uint length) +{ + if (keycache->key_cache_inited && keycache->can_be_used) + return keycache->interface_funcs->insert(keycache->keycache_cb, + file, filepos, level, + buff, length); + return 0; +} + + +/* + Write data from a buffer into a key cache + + SYNOPSIS + + key_cache_write() + keycache pointer to the key cache to write data to + file handler for the file to write data to + filepos position in the file to write data to + level determines the weight of the data + buff buffer with the data + length length of the buffer + dont_write if is 0 then all dirty pages involved in writing + should have been flushed from key cache + file_extra pointer to optional file attributes + + DESCRIPTION + The function operates over buffers of the key cache keycache. + In a general case the function writes data from a buffer into the key + cache. The buffer is specified with the parameters buff and length - + the pointer to the beginning of the buffer and its size respectively. + It's assumed the buffer contains the data to be written into 'file' + starting from the position filepos. + If the value of the parameter dont_write is FALSE then the function + also writes the data into file. + The parameter level is used to set one characteristic for the key buffers + filled with the data from buff. The characteristic is employed only by + the midpoint insertion strategy. + The parameter file_expra may point to additional file attributes used + for optimization or other purposes. + The function writes data from the buffer directly into file if the control + block of the key cache has not been initialized yet. + + RETURN VALUE + 0 if a success, 1 - otherwise. + + NOTES + This implementation may exploit the fact that the function is called only + when a thread has got an exclusive lock for the key file. +*/ + +int key_cache_write(KEY_CACHE *keycache, + File file, void *file_extra, + my_off_t filepos, int level, + uchar *buff, uint length, + uint block_length, int force_write) +{ + if (keycache->key_cache_inited && keycache->can_be_used) + return keycache->interface_funcs->write(keycache->keycache_cb, + file, file_extra, + filepos, level, + buff, length, + block_length, force_write); + + /* We can't use mutex here as the key cache may not be initialized */ + if (my_pwrite(file, buff, length, filepos, MYF(MY_NABP | MY_WAIT_IF_FULL))) + return 1; + + return 0; +} + + +/* + Flush all blocks for a file from key buffers of a key cache + + SYNOPSIS + + flush_key_blocks() + keycache pointer to the key cache whose blocks are to be flushed + file handler for the file to flush to + file_extra maps of key cache (used for partitioned key caches) + flush_type type of the flush operation + + DESCRIPTION + The function operates over buffers of the key cache keycache. + In a general case the function flushes the data from all dirty key + buffers related to the file 'file' into this file. The function does + exactly this if the value of the parameter type is FLUSH_KEEP. If the + value of this parameter is FLUSH_RELEASE, the function additionally + releases the key buffers containing data from 'file' for new usage. + If the value of the parameter type is FLUSH_IGNORE_CHANGED the function + just releases the key buffers containing data from 'file'. + If the value of the parameter type is FLUSH_KEEP the function may use + the value of the parameter file_extra pointing to possibly dirty + partitions to optimize the operation for partitioned key caches. + + RETURN + 0 ok + 1 error + + NOTES + Any implementation of the function may exploit the fact that the function + is called only when a thread has got an exclusive lock for the key file. +*/ + +int flush_key_blocks(KEY_CACHE *keycache, + int file, void *file_extra, + enum flush_type type) +{ + if (keycache->key_cache_inited) + return keycache->interface_funcs->flush(keycache->keycache_cb, + file, file_extra, type); + return 0; +} + + +/* + Reset the counters of a key cache + + SYNOPSIS + reset_key_cache_counters() + name the name of a key cache (unused) + keycache pointer to the key cache for which to reset counters + + DESCRIPTION + This function resets the values of the statistical counters for the key + cache keycache. + The parameter name is currently not used. + + RETURN + 0 on success (always because it can't fail) + + NOTES + This procedure is used by process_key_caches() to reset the counters of all + currently used key caches, both the default one and the named ones. +*/ + +int reset_key_cache_counters(const char *name __attribute__((unused)), + KEY_CACHE *keycache) +{ + if (keycache->key_cache_inited) + { + + return keycache->interface_funcs->reset_counters(name, + keycache->keycache_cb); + } + return 0; +} + + +/* + Get statistics for a key cache + + SYNOPSIS + get_key_cache_statistics() + keycache pointer to the key cache to get statistics for + partition_no partition number to get statistics for + key_cache_stats OUT pointer to the structure for the returned statistics + + DESCRIPTION + If the value of the parameter partition_no is equal to 0 then statistics + for the whole key cache keycache (aggregated statistics) is returned in the + fields of the structure key_cache_stat of the type KEY_CACHE_STATISTICS. + Otherwise the value of the parameter partition_no makes sense only for + a partitioned key cache. In this case the function returns statistics + for the partition with the specified number partition_no. + + RETURN + none +*/ + +void get_key_cache_statistics(KEY_CACHE *keycache, uint partition_no, + KEY_CACHE_STATISTICS *key_cache_stats) +{ + if (keycache->key_cache_inited) + { + keycache->interface_funcs->get_stats(keycache->keycache_cb, + partition_no, key_cache_stats); + } +} + +/* + Repartition a key cache + + SYNOPSIS + repartition_key_cache() + keycache pointer to the key cache to be repartitioned + key_cache_block_size size of blocks to keep cached data + use_mem total memory to use for the new key cache + division_limit new division limit (if not zero) + age_threshold new age threshold (if not zero) + partitions new number of partitions in the key cache + + DESCRIPTION + The function operates over the key cache keycache. + The parameter partitions specifies the number of partitions in the key + cache after repartitioning. If the value of this parameter is 0 then + a simple key cache must be created instead of the old one. + The parameter key_cache_block_size specifies the new size of the block + buffers in the key cache. The parameters division_limit and age_threshold + determine the new initial values of those characteristics of the key cache + that are used for midpoint insertion strategy. The parameter use_mem + specifies the total amount of memory to be allocated for the new key + cache buffers and for all auxiliary structures. + + RETURN VALUE + number of blocks in the key cache, if successful, + 0 - otherwise. + + NOTES + The function does not block the calls and executions of other functions + from the key cache interface. However it assumes that the calls of + resize_key_cache itself are serialized. + + Currently the function is called when the value of the variable + key_cache_partitions is being reset for the key cache keycache. +*/ + +int repartition_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, + size_t use_mem, uint division_limit, + uint age_threshold, uint partitions) +{ + uint blocks= -1; + if (keycache->key_cache_inited) + { + keycache->interface_funcs->resize(keycache->keycache_cb, + key_cache_block_size, 0, + division_limit, age_threshold); + end_key_cache(keycache, 1); + blocks= init_key_cache(keycache, key_cache_block_size, use_mem, + division_limit, age_threshold, partitions); + } + return blocks; +} + diff --git a/mysys/mf_soundex.c b/mysys/mf_soundex.c index fe30d8c81af..3a3dab52dd6 100644 --- a/mysys/mf_soundex.c +++ b/mysys/mf_soundex.c @@ -47,7 +47,7 @@ void soundex(CHARSET_INFO * cs,register char * out_pntr, char * in_pntr, { char ch,last_ch; reg3 char * end; - register uchar *map=cs->to_upper; + register const uchar *map=cs->to_upper; if (remove_garbage) { diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 7f6d8450790..7e56c4ebe22 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -398,10 +398,12 @@ int handle_options(int *argc, char ***argv, */ (*argc)--; if (!optend || *optend == '1' || - !my_strcasecmp(&my_charset_latin1, optend, "true")) + !my_strcasecmp(&my_charset_latin1, optend, "true") || + !my_strcasecmp(&my_charset_latin1, optend, "on")) *((my_bool*) value)= (my_bool) 1; else if (*optend == '0' || - !my_strcasecmp(&my_charset_latin1, optend, "false")) + !my_strcasecmp(&my_charset_latin1, optend, "false") || + !my_strcasecmp(&my_charset_latin1, optend, "off")) *((my_bool*) value)= (my_bool) 0; else { @@ -1275,7 +1277,7 @@ void my_print_variables(const struct my_option *options) printf("%s\n", llstr(*((longlong*) value), buff)); break; case GET_ULL: - longlong2str(*((ulonglong*) value), buff, 10); + longlong10_to_str(*((ulonglong*) value), buff, 10); printf("%s\n", buff); break; case GET_DOUBLE: diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c index c6086b84537..6bffcd65d30 100644 --- a/mysys/my_getsystime.c +++ b/mysys/my_getsystime.c @@ -29,6 +29,10 @@ #ifdef __NETWARE__ #include <nks/time.h> #endif +#ifdef HAVE_LINUX_UNISTD_H +#include <linux/unistd.h> +#endif + ulonglong my_getsystime() { @@ -229,3 +233,25 @@ time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused))) return (time_t) (microtime / 1000000); #endif /* defined(__WIN__) */ } + + +/* + Return cpu time in milliseconds * 10 +*/ + +ulonglong my_getcputime() +{ +#ifdef HAVE_CLOCK_GETTIME + struct timespec tp; + if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)) + return 0; + return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100; +#elif defined(__NR_clock_gettime) + struct timespec tp; + if (syscall(__NR_clock_gettime, CLOCK_THREAD_CPUTIME_ID, &tp)) + return 0; + return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100; +#else + return 0; +#endif /* HAVE_CLOCK_GETTIME */ +} diff --git a/mysys/my_init.c b/mysys/my_init.c index d50256328c1..23567947adb 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -79,6 +79,8 @@ my_bool my_init(void) mysys_usage_id++; my_umask= 0660; /* Default umask for new files */ my_umask_dir= 0700; /* Default umask for new directories */ + my_global_flags= 0; + init_glob_errs(); my_progname_short= "unknown"; if (my_progname) diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c index 476006dcafd..9a219ca2b73 100644 --- a/mysys/my_malloc.c +++ b/mysys/my_malloc.c @@ -33,6 +33,8 @@ void *my_malloc(size_t size, myf my_flags) void* point; DBUG_ENTER("my_malloc"); DBUG_PRINT("my",("size: %lu my_flags: %d", (ulong) size, my_flags)); + if (!(my_flags & (MY_WME | MY_FAE))) + my_flags|= my_global_flags; if (!size) size=1; /* Safety */ @@ -50,7 +52,9 @@ void *my_malloc(size_t size, myf my_flags) if (my_flags & MY_FAE) error_handler_hook=fatal_error_handler_hook; if (my_flags & (MY_FAE+MY_WME)) - my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH),size); + my_error(EE_OUTOFMEMORY, + MYF(ME_BELL | ME_WAITTANG | ME_NOREFRESH | (my_flags & ME_JUST_INFO)), + size); DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_SET("-d,simulate_out_of_memory");); if (my_flags & MY_FAE) diff --git a/mysys/my_open.c b/mysys/my_open.c index fe7f65c450b..3980e3a9a77 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -43,6 +43,9 @@ File my_open(const char *FileName, int Flags, myf MyFlags) DBUG_ENTER("my_open"); DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d", FileName, Flags, MyFlags)); + if (!(MyFlags & (MY_WME | MY_FAE | MY_FFNF))) + MyFlags|= my_global_flags; + #if defined(__WIN__) /* Check that we don't try to open or create a file name that may @@ -92,6 +95,8 @@ int my_close(File fd, myf MyFlags) int err; DBUG_ENTER("my_close"); DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags)); + if (!(MyFlags & (MY_WME | MY_FAE))) + MyFlags|= my_global_flags; pthread_mutex_lock(&THR_LOCK_open); do @@ -104,7 +109,8 @@ int my_close(File fd, myf MyFlags) DBUG_PRINT("error",("Got error %d on close",err)); my_errno=errno; if (MyFlags & (MY_FAE | MY_WME)) - my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno); + my_error(EE_BADCLOSE, MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))), + my_filename(fd),errno); } if ((uint) fd < my_file_limit && my_file_info[fd].type != UNOPEN) { @@ -180,8 +186,8 @@ File my_register_filename(File fd, const char *FileName, enum file_type { if (my_errno == EMFILE) error_message_number= EE_OUT_OF_FILERESOURCES; - DBUG_PRINT("error",("print err: %d",error_message_number)); - my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG), + my_error(error_message_number, + MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))), FileName, my_errno); } DBUG_RETURN(-1); diff --git a/mysys/my_pread.c b/mysys/my_pread.c index 04ad85ceb57..5fd60f6ef8a 100644 --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -61,6 +61,9 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, Filedes, ullstr(offset, llbuf), (long) Buffer, (ulong)Count, MyFlags)); #endif + if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) + MyFlags|= my_global_flags; + for (;;) { errno= 0; /* Linux, Windows don't reset this on EOF/success */ @@ -95,11 +98,13 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { if (readbytes == (size_t) -1) - my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), + my_error(EE_READ, + MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))), my_filename(Filedes),my_errno); else if (MyFlags & (MY_NABP | MY_FNABP)) - my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), - my_filename(Filedes),my_errno); + my_error(EE_EOFERR, + MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))), + my_filename(Filedes),my_errno); } if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP))) DBUG_RETURN(MY_FILE_ERROR); /* Return with error */ @@ -146,6 +151,8 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count, #endif errors= 0; written= 0; + if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) + MyFlags|= my_global_flags; for (;;) { @@ -186,20 +193,19 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count, if ((writenbytes && writenbytes != (size_t) -1) || my_errno == EINTR) continue; /* Retry */ #endif + + /* Don't give a warning if it's ok that we only write part of the data */ if (MyFlags & (MY_NABP | MY_FNABP)) { if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) - { - my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG), - my_filename(Filedes),my_errno); - } - DBUG_RETURN(MY_FILE_ERROR); /* Error on read */ + my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))), + my_filename(Filedes),my_errno); + DBUG_RETURN(MY_FILE_ERROR); /* Error on write */ } - else - break; /* Return bytes written */ + break; /* Return bytes written */ } DBUG_EXECUTE_IF("check", my_seek(Filedes, -1, SEEK_SET, MYF(0));); if (MyFlags & (MY_NABP | MY_FNABP)) - DBUG_RETURN(0); /* Want only errors */ - DBUG_RETURN(writenbytes+written); /* purecov: inspected */ + DBUG_RETURN(0); /* Want only errors */ + DBUG_RETURN(writenbytes+written); /* purecov: inspected */ } /* my_pwrite */ diff --git a/mysys/my_read.c b/mysys/my_read.c index 25ffe73d813..e2023b14337 100644 --- a/mysys/my_read.c +++ b/mysys/my_read.c @@ -40,6 +40,8 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags) DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d", Filedes, (long) Buffer, (ulong) Count, MyFlags)); save_count= Count; + if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) + MyFlags|= my_global_flags; for (;;) { @@ -64,10 +66,12 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags) if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { if (readbytes == (size_t) -1) - my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), + my_error(EE_READ, + MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))), my_filename(Filedes),my_errno); else if (MyFlags & (MY_NABP | MY_FNABP)) - my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), + my_error(EE_EOFERR, + MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))), my_filename(Filedes),my_errno); } if (readbytes == (size_t) -1 || diff --git a/mysys/my_static.c b/mysys/my_static.c index d59be1ae01e..404ed477cb9 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -35,6 +35,8 @@ char NEAR curr_dir[FN_REFLEN]= {0}, ulong my_stream_opened=0,my_file_opened=0, my_tmp_file_created=0; ulong my_file_total_opened= 0; int NEAR my_umask=0664, NEAR my_umask_dir=0777; +myf my_global_flags= 0; +my_bool my_assert_on_error= 0; #ifndef THREAD int NEAR my_errno=0; #endif diff --git a/mysys/my_write.c b/mysys/my_write.c index 5d28e066814..07dbfe8eb40 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -31,6 +31,8 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags) DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d", Filedes, (long) Buffer, (ulong) Count, MyFlags)); errors=0; written=0; + if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) + MyFlags|= my_global_flags; /* The behavior of write(fd, buf, 0) is not portable */ if (unlikely(!Count)) @@ -81,19 +83,20 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags) else continue; /* Retry */ #endif + + /* Don't give a warning if it's ok that we only write part of the data */ if (MyFlags & (MY_NABP | MY_FNABP)) { if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { - my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG), + my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))), my_filename(Filedes),my_errno); } DBUG_RETURN(MY_FILE_ERROR); /* Error on read */ } - else - break; /* Return bytes written */ + break; /* Return bytes written */ } if (MyFlags & (MY_NABP | MY_FNABP)) - DBUG_RETURN(0); /* Want only errors */ + DBUG_RETURN(0); /* Want only errors */ DBUG_RETURN(writenbytes+written); } /* my_write */ diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index ca270df0a04..89cf0093969 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -227,6 +227,8 @@ void *_myrealloc(register void *ptr, register size_t size, struct st_irem *irem; char *data; DBUG_ENTER("_myrealloc"); + DBUG_PRINT("my",("ptr: 0x%lx size: %lu my_flags: %d", (long) ptr, + (ulong) size, MyFlags)); if (!ptr && (MyFlags & MY_ALLOW_ZERO_PTR)) DBUG_RETURN(_mymalloc(size, filename, lineno, MyFlags)); @@ -248,6 +250,8 @@ void *_myrealloc(register void *ptr, register size_t size, (void) fflush(stderr); DBUG_RETURN((uchar*) NULL); } + DBUG_PRINT("my", ("old_size: %lu -> new_size: %lu", + (ulong) irem->datasize, (ulong) size)); if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */ { diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 2f66fbd652e..de21e79458c 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -114,25 +114,37 @@ static inline pthread_cond_t *get_cond(void) /* + Sort locks in priority order + + LOCK_CMP() + A First lock + B Second lock + + Return: + 0 if A >= B + 1 if A < B + Priority for locks (decides in which order locks are locked) We want all write locks to be first, followed by read locks. Locks from MERGE tables has a little lower priority than other locks, to allow one to release merge tables without having to unlock and re-lock other locks. The lower the number, the higher the priority for the lock. - Read locks should have 4, write locks should have 0. - UNLOCK is 8, to force these last in thr_merge_locks. For MERGE tables we add 2 (THR_LOCK_MERGE_PRIV) to the lock priority. THR_LOCK_LATE_PRIV (1) is used when one locks other tables to be merged with existing locks. This way we prioritize the original locks over the new locks. */ -static uint lock_priority[(uint)TL_WRITE_ONLY+1] = -{ 8, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0}; - -#define LOCK_CMP(A,B) ((uchar*) ((A)->lock) + lock_priority[(uint) (A)->type] + (A)->priority < (uchar*) ((B)->lock) + lock_priority[(uint) (B)->type] + (B)->priority) +inline int LOCK_CMP(THR_LOCK_DATA *A, THR_LOCK_DATA *B) +{ + if (A->lock != B->lock) + return A->lock < B->lock; + if (A->type != B->type) + return A->type > B->type; /* Prioritize read */ + return A->priority < B->priority; +} /* For the future (now the thread specific cond is alloced by my_pthread.c) @@ -217,6 +229,7 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, static void check_locks(THR_LOCK *lock, const char *where, + enum thr_lock_type type, my_bool allow_no_locks) { uint old_found_errors=found_errors; @@ -281,6 +294,7 @@ static void check_locks(THR_LOCK *lock, const char *where, found_errors++; fprintf(stderr, "Warning at '%s': Write lock %d waiting while no exclusive read locks\n",where,(int) lock->write_wait.data->type); + DBUG_PRINT("warning", ("Warning at '%s': Write lock %d waiting while no exclusive read locks\n",where,(int) lock->write_wait.data->type)); } } } @@ -295,8 +309,10 @@ static void check_locks(THR_LOCK *lock, const char *where, if (data->type != TL_WRITE_CONCURRENT_INSERT) { fprintf(stderr, - "Warning at '%s': Found TL_WRITE_CONCURRENT_INSERT lock mixed with other write locks\n", - where); + "Warning at '%s': Found TL_WRITE_CONCURRENT_INSERT lock mixed with other write lock: %d\n", + where, data->type); + DBUG_PRINT("warning", ("Warning at '%s': Found TL_WRITE_CONCURRENT_INSERT lock mixed with other write lock: %d\n", + where, data->type)); break; } } @@ -311,26 +327,34 @@ static void check_locks(THR_LOCK *lock, const char *where, fprintf(stderr, "Warning at '%s': Found WRITE_ALLOW_WRITE lock waiting for WRITE_ALLOW_WRITE lock\n", where); + DBUG_PRINT("warning", ("Warning at '%s': Found WRITE_ALLOW_WRITE lock waiting for WRITE_ALLOW_WRITE lock\n", + where)); + } } if (lock->read.data) { - if (!thr_lock_owner_equal(lock->write.data->owner, - lock->read.data->owner) && + THR_LOCK_DATA *data; + for (data=lock->read.data ; data ; data=data->next) + { + if (!thr_lock_owner_equal(lock->write.data->owner, + data->owner) && ((lock->write.data->type > TL_WRITE_DELAYED && lock->write.data->type != TL_WRITE_ONLY) || ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT || lock->write.data->type == TL_WRITE_ALLOW_WRITE) && - lock->read_no_write_count))) - { - found_errors++; - fprintf(stderr, - "Warning at '%s': Found lock of type %d that is write and read locked\n", - where, lock->write.data->type); - DBUG_PRINT("warning",("At '%s': Found lock of type %d that is write and read locked\n", - where, lock->write.data->type)); - - } + data->type == TL_READ_NO_INSERT))) + { + found_errors++; + fprintf(stderr, + "Warning at '%s' for lock: %d: Found lock of type %d that is write and read locked. Read_no_write_count: %d\n", + where, (int) type, lock->write.data->type, + lock->read_no_write_count); + DBUG_PRINT("warning",("At '%s' for lock %d: Found lock of type %d that is write and read locked\n", + where, (int) type, + lock->write.data->type)); + } + } } if (lock->read_wait.data) { @@ -356,7 +380,7 @@ static void check_locks(THR_LOCK *lock, const char *where, } #else /* EXTRA_DEBUG */ -#define check_locks(A,B,C) +#define check_locks(A,B,C,D) #endif @@ -533,13 +557,14 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, else wait->last=data->prev; data->type= TL_UNLOCK; /* No lock */ - check_locks(data->lock, "killed or timed out wait_for_lock", 1); + check_locks(data->lock, "killed or timed out wait_for_lock", data->type, + 1); wake_up_waiters(data->lock); } else { DBUG_PRINT("thr_lock", ("lock aborted")); - check_locks(data->lock, "aborted wait_for_lock", 0); + check_locks(data->lock, "aborted wait_for_lock", data->type, 0); } } else @@ -548,7 +573,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, if (data->lock->get_status) (*data->lock->get_status)(data->status_param, data->type == TL_WRITE_CONCURRENT_INSERT); - check_locks(data->lock,"got wait_for_lock",0); + check_locks(data->lock,"got wait_for_lock", data->type, 0); } pthread_mutex_unlock(&data->lock->mutex); @@ -581,7 +606,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, (long) data, data->owner->info->thread_id, (long) lock, (int) lock_type)); check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ? - "enter read_lock" : "enter write_lock",0); + "enter read_lock" : "enter write_lock", lock_type, 0); if ((int) lock_type <= (int) TL_READ_NO_INSERT) { /* Request for READ lock */ @@ -610,7 +635,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, lock->read.last= &data->next; if (lock_type == TL_READ_NO_INSERT) lock->read_no_write_count++; - check_locks(lock,"read lock with old write lock",0); + check_locks(lock,"read lock with old write lock", lock_type, 0); if (lock->get_status) (*lock->get_status)(data->status_param, 0); statistic_increment(locks_immediate,&THR_LOCK_lock); @@ -634,7 +659,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, lock->read.last= &data->next; if (lock_type == TL_READ_NO_INSERT) lock->read_no_write_count++; - check_locks(lock,"read lock with no write locks",0); + check_locks(lock,"read lock with no write locks", lock_type, 0); if (lock->get_status) (*lock->get_status)(data->status_param, 0); statistic_increment(locks_immediate,&THR_LOCK_lock); @@ -719,7 +744,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, (*lock->write.last)=data; /* Add to running fifo */ data->prev=lock->write.last; lock->write.last= &data->next; - check_locks(lock,"second write lock",0); + check_locks(lock,"second write lock", lock_type, 0); if (lock->get_status) (*lock->get_status)(data->status_param, lock_type == TL_WRITE_CONCURRENT_INSERT); @@ -757,7 +782,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, lock->write.last= &data->next; if (lock->get_status) (*lock->get_status)(data->status_param, concurrent_insert); - check_locks(lock,"only write lock",0); + check_locks(lock,"only write lock", lock_type, 0); statistic_increment(locks_immediate,&THR_LOCK_lock); goto end; } @@ -793,7 +818,7 @@ static inline void free_all_read_locks(THR_LOCK *lock, { THR_LOCK_DATA *data=lock->read_wait.data; - check_locks(lock,"before freeing read locks",1); + check_locks(lock,"before freeing read locks", TL_UNLOCK, 1); /* move all locks from read_wait list to read list */ (*lock->read.last)=data; @@ -835,7 +860,7 @@ static inline void free_all_read_locks(THR_LOCK *lock, *lock->read_wait.last=0; if (!lock->read_wait.data) lock->write_lock_count=0; - check_locks(lock,"after giving read locks",0); + check_locks(lock,"after giving read locks", TL_UNLOCK, 0); } /* Unlock lock and free next thread on same lock */ @@ -848,7 +873,7 @@ void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags) DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx", (long) data, data->owner->info->thread_id, (long) lock)); pthread_mutex_lock(&lock->mutex); - check_locks(lock,"start of release lock",0); + check_locks(lock,"start of release lock", lock_type, 0); if (((*data->prev)=data->next)) /* remove from lock-list */ data->next->prev= data->prev; @@ -882,9 +907,9 @@ void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags) if (lock_type == TL_READ_NO_INSERT) lock->read_no_write_count--; data->type=TL_UNLOCK; /* Mark unlocked */ - check_locks(lock,"after releasing lock",1); + check_locks(lock,"after releasing lock", lock_type, 1); wake_up_waiters(lock); - check_locks(lock,"end of thr_unlock",1); + check_locks(lock,"end of thr_unlock", lock_type, 1); pthread_mutex_unlock(&lock->mutex); DBUG_VOID_RETURN; } @@ -1009,7 +1034,7 @@ static void wake_up_waiters(THR_LOCK *lock) free_all_read_locks(lock,0); } end: - check_locks(lock, "after waking up waiters", 0); + check_locks(lock, "after waking up waiters", TL_UNLOCK, 0); DBUG_VOID_RETURN; } @@ -1319,7 +1344,7 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, DBUG_ASSERT(old_lock_type == TL_WRITE_ONLY); DBUG_ASSERT(old_lock_type > new_lock_type); in_data->type= new_lock_type; - check_locks(lock,"after downgrading lock",0); + check_locks(lock,"after downgrading lock", old_lock_type, 0); #if TO_BE_REMOVED switch (old_lock_type) @@ -1419,7 +1444,8 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, data->prev= lock->write.last; lock->write.last= &data->next; data->next= 0; - check_locks(lock, "Started write lock after downgrade",0); + check_locks(lock, "Started write lock after downgrade", new_lock_type, + 0); data->cond= 0; pthread_cond_signal(cond); } @@ -1472,13 +1498,15 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, if (data->type == TL_READ_NO_INSERT) lock->read_no_write_count++; - check_locks(lock, "Started read lock after downgrade",0); + check_locks(lock, "Started read lock after downgrade", new_lock_type, + 0); data->cond= 0; pthread_cond_signal(cond); } } } - check_locks(lock,"after starting waiters after downgrading lock",0); + check_locks(lock,"after starting waiters after downgrading lock", + new_lock_type, 0); #endif pthread_mutex_unlock(&lock->mutex); DBUG_VOID_RETURN; @@ -1499,7 +1527,7 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data, pthread_mutex_unlock(&lock->mutex); DBUG_RETURN(data->type == TL_UNLOCK); /* Test if Aborted */ } - check_locks(lock,"before upgrading lock",0); + check_locks(lock,"before upgrading lock", data->type, 0); /* TODO: Upgrade to TL_WRITE_CONCURRENT_INSERT in some cases */ data->type= new_lock_type; /* Upgrade lock */ @@ -1527,11 +1555,11 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data, lock->write_wait.last= &data->next; data->prev= &lock->write_wait.data; lock->write_wait.data=data; - check_locks(lock,"upgrading lock",0); + check_locks(lock,"upgrading lock", new_lock_type, 0); } else { - check_locks(lock,"waiting for lock",0); + check_locks(lock,"waiting for lock", new_lock_type, 0); } res= wait_for_lock(&lock->write_wait,data,1); if (res == THR_LOCK_SUCCESS && lock->start_trans) diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index c98fbda4cd2..d881a68eb4e 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -838,6 +838,7 @@ static void print_deadlock_warning(safe_mutex_t *new_mutex, mutex_root->file, mutex_root->line)); } fflush(stderr); + DBUG_ASSERT(my_assert_on_error == 0); DBUG_VOID_RETURN; } diff --git a/plugin/auth/Makefile.am b/plugin/auth/Makefile.am new file mode 100644 index 00000000000..acca98e26f8 --- /dev/null +++ b/plugin/auth/Makefile.am @@ -0,0 +1,15 @@ +pkgplugindir=$(pkglibdir)/plugin + +AM_LDFLAGS=-module -rpath $(pkgplugindir) +AM_CPPFLAGS=-DMYSQL_DYNAMIC_PLUGIN -I$(top_srcdir)/include + +pkgplugin_LTLIBRARIES= dialog.la +dialog_la_SOURCES= dialog.c + +if HAVE_PEERCRED +pkgplugin_LTLIBRARIES+= auth_socket.la +auth_socket_la_SOURCES= auth_socket.c +endif + +EXTRA_DIST= plug.in + diff --git a/plugin/auth/auth_socket.c b/plugin/auth/auth_socket.c new file mode 100644 index 00000000000..cc406dac331 --- /dev/null +++ b/plugin/auth/auth_socket.c @@ -0,0 +1,119 @@ +/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + + socket_peercred authentication plugin. + + Authentication is successful if the connection is done via a unix socket and + the owner of the client process matches the user name that was used when + connecting to mysqld. +*/ +#define _GNU_SOURCE /* for struct ucred */ + +#include <mysql/plugin_auth.h> +#include <sys/socket.h> +#include <pwd.h> +#include <string.h> + +/** + perform the unix socket based authentication + + This authentication callback performs a unix socket based authentication - + it gets the uid of the client process and considers the user authenticated + if it uses username of this uid. That is - if the user is already + authenticated to the OS (if she is logged in) - she can use MySQL as herself +*/ + +static int socket_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) +{ + unsigned char *pkt; + MYSQL_PLUGIN_VIO_INFO vio_info; + struct ucred cred; + socklen_t cred_len= sizeof(cred); + struct passwd pwd_buf, *pwd; + char buf[1024]; + + /* no user name yet ? read the client handshake packet with the user name */ + if (info->user_name == 0) + { + if (vio->read_packet(vio, &pkt) < 0) + return CR_ERROR; + } + + info->password_used = 0; + + vio->info(vio, &vio_info); + if (vio_info.protocol != MYSQL_VIO_SOCKET) + return CR_ERROR; + + /* get the UID of the client process */ + if (getsockopt(vio_info.socket, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len)) + return CR_ERROR; + + if (cred_len != sizeof(cred)) + return CR_ERROR; + + /* and find the username for this uid */ + getpwuid_r(cred.uid, &pwd_buf, buf, sizeof(buf), &pwd); + if (pwd == NULL) + return CR_ERROR; + + /* now it's simple as that */ + return strcmp(pwd->pw_name, info->user_name) ? CR_ERROR : CR_OK; +} + +static struct st_mysql_auth socket_auth_handler= +{ + MYSQL_AUTHENTICATION_INTERFACE_VERSION, + 0, + socket_auth +}; + +mysql_declare_plugin(socket_auth) +{ + MYSQL_AUTHENTICATION_PLUGIN, + &socket_auth_handler, + "socket_peercred", + "Sergei Golubchik", + "Unix Socket based authentication", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + NULL +} +mysql_declare_plugin_end; +maria_declare_plugin(socket_auth) +{ + MYSQL_AUTHENTICATION_PLUGIN, + &socket_auth_handler, + "socket_peercred", + "Sergei Golubchik", + "Unix Socket based authentication", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + "1.0", + MariaDB_PLUGIN_MATURITY_BETA +} +maria_declare_plugin_end; + diff --git a/plugin/auth/dialog.c b/plugin/auth/dialog.c new file mode 100644 index 00000000000..49ab0c9a158 --- /dev/null +++ b/plugin/auth/dialog.c @@ -0,0 +1,349 @@ +/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + + dialog client authentication plugin with examples + + dialog is a general purpose client authentication plugin, it simply + asks the user the question, as provided by the server and reports + the answer back to the server. No encryption is involved, + the answers are sent in clear text. + + Two examples are provided: two_questions server plugin, that asks + the password and an "Are you sure?" question with a reply "yes, of course". + It demonstrates the usage of "password" (input is hidden) and "ordinary" + (input can be echoed) questions, and how to mark the last question, + to avoid an extra roundtrip. + + And three_attempts plugin that gives the user three attempts to enter + a correct password. It shows the situation when a number of questions + is not known in advance. +*/ +#define _GNU_SOURCE /* for RTLD_DEFAULT */ + +#include <mysql/plugin_auth.h> +#include <mysql/client_plugin.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +/** + first byte of the question string is the question "type". + It can be a "ordinary" or a "password" question. + The last bit set marks a last question in the authentication exchange. +*/ +#define ORDINARY_QUESTION "\2" +#define LAST_QUESTION "\3" +#define PASSWORD_QUESTION "\4" +#define LAST_PASSWORD "\5" + +typedef unsigned char uchar; + +/********************* SERVER SIDE ****************************************/ + +/** + dialog demo with two questions, one password and one ordinary. +*/ + +static int two_questions(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) +{ + unsigned char *pkt; + int pkt_len; + + /* send a password question */ + if (vio->write_packet(vio, + (const uchar*) (PASSWORD_QUESTION "Password, please:"), + 18)) + return CR_ERROR; + + /* read the answer */ + if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) + return CR_ERROR; + + info->password_used = 1; + + /* fail if the password is wrong */ + if (strcmp((char*) pkt, info->auth_string)) + return CR_ERROR; + + /* send the last, ordinary, question */ + if (vio->write_packet(vio, + (const uchar*) (LAST_QUESTION "Are you sure ?"), 15)) + return CR_ERROR; + + /* read the answer */ + if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) + return CR_ERROR; + + /* check the reply */ + return strcmp((char*) pkt, "yes, of course") ? CR_ERROR : CR_OK; +} + +static struct st_mysql_auth two_handler= +{ + MYSQL_AUTHENTICATION_INTERFACE_VERSION, + "dialog", /* requires dialog client plugin */ + two_questions +}; + + +/** + dialog demo where the number of questions is not known in advance +*/ + +static int three_attempts(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) +{ + unsigned char *pkt; + int pkt_len, i; + + for (i= 0; i < 3; i++) + { + /* send the prompt */ + if (vio->write_packet(vio, + (const uchar*) (PASSWORD_QUESTION "Password, please:"), 18)) + return CR_ERROR; + + /* read the password */ + if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) + return CR_ERROR; + + info->password_used = 1; + + /* + finish, if the password is correct. + note, that we did not mark the prompt packet as "last" + */ + if (strcmp((char*) pkt, info->auth_string) == 0) + return CR_OK; + } + + return CR_ERROR; +} + +static struct st_mysql_auth three_handler= +{ + MYSQL_AUTHENTICATION_INTERFACE_VERSION, + "dialog", /* requires dialog client plugin */ + three_attempts +}; + +mysql_declare_plugin(dialog) +{ + MYSQL_AUTHENTICATION_PLUGIN, + &two_handler, + "two_questions", + "Sergei Golubchik", + "Dialog plugin demo 1", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + NULL +}, +{ + MYSQL_AUTHENTICATION_PLUGIN, + &three_handler, + "three_attempts", + "Sergei Golubchik", + "Dialog plugin demo 2", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + NULL +} +mysql_declare_plugin_end; +maria_declare_plugin(dialog) +{ + MYSQL_AUTHENTICATION_PLUGIN, + &two_handler, + "two_questions", + "Sergei Golubchik", + "Dialog plugin demo 1", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + "1.0", + MariaDB_PLUGIN_MATURITY_BETA +}, +{ + MYSQL_AUTHENTICATION_PLUGIN, + &three_handler, + "three_attempts", + "Sergei Golubchik", + "Dialog plugin demo 2", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + "1.0", + MariaDB_PLUGIN_MATURITY_BETA +} +maria_declare_plugin_end; + +/********************* CLIENT SIDE ***************************************/ +/* + This plugin performs a dialog with the user, asking questions and + reading answers. Depending on the client it may be desirable to do it + using GUI, or console, with or without curses, or read answers + from a smardcard, for example. + + To support all this variety, the dialog plugin has a callback function + "authentication_dialog_ask". If the client has a function of this name + dialog plugin will use it for communication with the user. Otherwise + a default gets() based implementation will be used. +*/ +#include <mysql.h> +#include <dlfcn.h> + +static mysql_authentication_dialog_ask_t ask; + +static char *builtin_ask(MYSQL *mysql __attribute__((unused)), + int type __attribute__((unused)), + const char *prompt, + char *buf, int buf_len) +{ + int len; + + fputs(prompt, stdout); + fputc(' ', stdout); + if (fgets(buf, buf_len, stdin) == 0) + return 0; + + len= strlen(buf); + if (len && buf[len-1]=='\n') + buf[len-1]=0; + + return buf; +} + + +/** + The main function of the dialog plugin. + + Read the prompt, ask the question, send the reply, repeat until + the server is satisfied. + + @note + 1. this plugin shows how a client authentication plugin + may read a MySQL protocol OK packet internally - which is important + where a number of packets is not known in advance. + 2. the first byte of the prompt is special. it is not + shown to the user, but signals whether it is the last question + (prompt[0] & 1 == 1) or not last (prompt[0] & 1 == 0), + and whether the input is a password (not echoed). + 3. the prompt is expected to be sent zero-terminated +*/ + +static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) +{ + unsigned char *pkt, cmd= 0; + int pkt_len, res; + char reply_buf[1024], *reply; + + do + { + /* read the prompt */ + pkt_len= vio->read_packet(vio, &pkt); + if (pkt_len < 0) + return CR_ERROR; + + if (pkt == 0) + { + /* + in mysql_change_user() the client sends the first packet, so + the first vio->read_packet() does nothing (pkt == 0). + + We send the "password", assuming the client knows what its doing. + (in other words, the dialog plugin should be only set as a default + authentication plugin on the client if the first question + asks for a password - which will be sent in clear text, by the way) + */ + reply= mysql->passwd; + } + else + { + cmd= *pkt++; + + /* is it MySQL protocol packet ? */ + if (cmd == 0 || cmd == 254) + return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */ + + /* + asking for a password with an empty prompt means mysql->password + otherwise we ask the user and read the reply + */ + if ((cmd >> 1) == 2 && *pkt == 0) + reply= mysql->passwd; + else + reply= ask(mysql, cmd >> 1, (char*) pkt, reply_buf, sizeof(reply_buf)); + if (!reply) + return CR_ERROR; + } + /* send the reply to the server */ + res= vio->write_packet(vio, (uchar*) reply, strlen(reply)+1); + + if (reply != mysql->passwd && reply != reply_buf) + free(reply); + + if (res) + return CR_ERROR; + + /* repeat unless it was the last question */ + } while ((cmd & 1) != 1); + + /* the job of reading the ok/error packet is left to the server */ + return CR_OK; +} + + +/** + initialization function of the dialog plugin + + Pick up the client's authentication_dialog_ask() function, if exists, + or fall back to the default implementation. +*/ + +static int init_dialog(char *errbuf __attribute__((unused)), + size_t sizeof_errbuf __attribute__((unused)), + int argc __attribute__((unused)), + va_list args __attribute__((unused))) +{ + void *sym= dlsym(RTLD_DEFAULT, "mysql_authentication_dialog_ask"); + ask= sym ? (mysql_authentication_dialog_ask_t)sym : builtin_ask; + return 0; +} + +mysql_declare_client_plugin(AUTHENTICATION) + "dialog", + "Sergei Golubchik", + "Dialog Client Authentication Plugin", + {0,1,0}, + init_dialog, + NULL, + perform_dialog +mysql_end_client_plugin; + diff --git a/plugin/auth/plug.in b/plugin/auth/plug.in new file mode 100644 index 00000000000..ce31465b056 --- /dev/null +++ b/plugin/auth/plug.in @@ -0,0 +1,15 @@ +MYSQL_PLUGIN(auth, [Collection of Authentication Plugins], + [Collection of Authentication Plugins]) +MYSQL_PLUGIN_DYNAMIC(auth, [dialog.la]) +MYSQL_PLUGIN_ACTIONS(auth,[ +AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#define _GNU_SOURCE +#include <sys/socket.h> +]],[[ + struct ucred cred; + getsockopt(0, SOL_SOCKET, SO_PEERCRED, &cred, 0); +]])],have_peercred=yes) +AM_CONDITIONAL(HAVE_PEERCRED, test x$have_peercred = xyes) +]) +AM_CONDITIONAL(HAVE_PEERCRED, false) diff --git a/plugin/daemon_example/Makefile.am b/plugin/daemon_example/Makefile.am index 96be7171b08..4a7409518b6 100644 --- a/plugin/daemon_example/Makefile.am +++ b/plugin/daemon_example/Makefile.am @@ -26,7 +26,7 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ EXTRA_LTLIBRARIES = libdaemon_example.la pkgplugin_LTLIBRARIES = @plugin_daemon_example_shared_target@ -libdaemon_example_la_LDFLAGS = -module -rpath $(pkgplugindir) +libdaemon_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices libdaemon_example_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN libdaemon_example_la_SOURCES = daemon_example.cc diff --git a/plugin/daemon_example/daemon_example.cc b/plugin/daemon_example/daemon_example.cc index e683bf7ab7a..38c1f2f3181 100644 --- a/plugin/daemon_example/daemon_example.cc +++ b/plugin/daemon_example/daemon_example.cc @@ -200,3 +200,20 @@ mysql_declare_plugin(daemon_example) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(daemon_example) +{ + MYSQL_DAEMON_PLUGIN, + &daemon_example_plugin, + "daemon_example", + "Brian Aker", + "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log", + PLUGIN_LICENSE_GPL, + daemon_example_plugin_init, /* Plugin Init */ + daemon_example_plugin_deinit, /* Plugin Deinit */ + 0x0100 /* 1.0 */, + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */ +} +maria_declare_plugin_end; diff --git a/plugin/feedback/Makefile.am b/plugin/feedback/Makefile.am index 31727ad0d73..7d2a61d593f 100644 --- a/plugin/feedback/Makefile.am +++ b/plugin/feedback/Makefile.am @@ -4,7 +4,7 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ EXTRA_LTLIBRARIES = feedback.la libfeedback.la pkgplugin_LTLIBRARIES = @plugin_feedback_shared_target@ -feedback_la_LDFLAGS = -module -rpath $(pkgplugindir) +feedback_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices feedback_la_CXXFLAGS = -shared -DMYSQL_DYNAMIC_PLUGIN feedback_la_SOURCES = feedback.cc utils.cc url_base.cc url_http.cc \ sender_thread.cc diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index a8c7ee82ac2..3ade31b80b4 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -352,4 +352,22 @@ mysql_declare_plugin(feedback) NULL } mysql_declare_plugin_end; - +#ifdef MARIA_PLUGIN_INTERFACE_VERSION +maria_declare_plugin(feedback) +{ + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &feedback::feedback, + "FEEDBACK", + "Sergei Golubchik", + "MariaDB User Feedback Plugin", + PLUGIN_LICENSE_GPL, + feedback::init, + feedback::free, + 0x0101, + NULL, + feedback::settings, + "1.1", + MariaDB_PLUGIN_MATURITY_BETA +} +mysql_declare_plugin_end; +#endif diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index 86627add808..617ca0213dc 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -46,7 +46,7 @@ static int table_to_string(TABLE *table, String *result) dbug_tmp_use_all_columns(table, table->read_set); - while(!res && !table->file->rnd_next(table->record[0])) + while(!res && !table->file->ha_rnd_next(table->record[0])) { table->field[0]->val_str(&str1); table->field[1]->val_str(&str2); diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c index de951375820..cc84cb6161b 100644 --- a/plugin/fulltext/plugin_example.c +++ b/plugin/fulltext/plugin_example.c @@ -270,3 +270,21 @@ mysql_declare_plugin(ftexample) NULL } mysql_declare_plugin_end; + +maria_declare_plugin(ftexample) +{ + MYSQL_FTPARSER_PLUGIN, /* type */ + &simple_parser_descriptor, /* descriptor */ + "simple_parser", /* name */ + "Sergei Golubchik", /* author */ + "Simple Full-Text Parser", /* description */ + PLUGIN_LICENSE_GPL, + simple_parser_plugin_init, /* init function (when loaded) */ + simple_parser_plugin_deinit,/* deinit function (when unloaded) */ + 0x0001, /* version */ + simple_status, /* status variables */ + simple_system_variables, /* system variables */ + "0.01", /* string version */ + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */ +} +maria_declare_plugin_end; diff --git a/randgen/conf/maria_group_commit.yy b/randgen/conf/maria_group_commit.yy new file mode 100644 index 00000000000..e136cbf7b07 --- /dev/null +++ b/randgen/conf/maria_group_commit.yy @@ -0,0 +1,181 @@ +# test of group commit switching + +query: + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + select | insert | update| delete | + change_group_commit | change_interval; + + +select: + SELECT select_item FROM join where order_by limit; + +select_item: + * | X . _field ; + +join: + _table AS X | + _table AS X LEFT JOIN _table AS Y ON ( X . _field = Y . _field ) ; + +where: + | + WHERE X . _field < value | + WHERE X . _field > value | + WHERE X . _field = value ; + +where_delete: + | + WHERE _field < value | + WHERE _field > value | + WHERE _field = value ; + +order_by: + | ORDER BY X . _field ; + +limit: + | LIMIT _digit ; + +insert: + INSERT INTO _table ( _field , _field ) VALUES ( value , value ) ; + +update: + UPDATE _table AS X SET _field = value where order_by limit ; + +delete: + DELETE FROM _table where_delete LIMIT _digit ; + +value: + ' _letter ' | _digit | _date | _datetime | _time | _english ; + +change_group_commit: + SET GLOBAL MARIA_GROUP_COMMIT=none_soft_hard; + +none_soft_hard: + NONE | SOFT | HARD; + +change_interval: + set_interval | set_interval | set_interval | set_interval | + drop_interval; + +set_interval: + SET GLOBAL MARIA_GROUP_COMMIT_INTERVAL=_tinyint_unsigned; + +drop_interval: + SET GLOBAL MARIA_GROUP_COMMIT_INTERVAL=0; diff --git a/regex/CMakeLists.txt b/regex/CMakeLists.txt index d5f387f6eaa..7f447128876 100755 --- a/regex/CMakeLists.txt +++ b/regex/CMakeLists.txt @@ -21,6 +21,4 @@ SET(REGEX_SOURCES regcomp.c regerror.c regexec.c regfree.c reginit.c) IF(NOT SOURCE_SUBLIBS) ADD_LIBRARY(regex ${REGEX_SOURCES}) - - INSTALL(TARGETS regex DESTINATION lib/opt COMPONENT runtime) # TODO: Component ENDIF(NOT SOURCE_SUBLIBS) diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index eee70fdf776..a62569843db 100755 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -14,10 +14,12 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Build mysql_fix_privilege_tables.sql -ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tables.sql - COMMAND copy /b - mysql_system_tables.sql + mysql_system_tables_fix.sql - mysql_fix_privilege_tables.sql +FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/mysql_fix_privilege_tables.sql + native_outfile ) +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/scripts/mysql_fix_privilege_tables.sql + COMMAND COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} + cmd /c copy /b mysql_system_tables.sql + mysql_system_tables_fix.sql + ${native_outfile} DEPENDS ${PROJECT_SOURCE_DIR}/scripts/mysql_system_tables.sql ${PROJECT_SOURCE_DIR}/scripts/mysql_system_tables_fix.sql) @@ -29,24 +31,26 @@ TARGET_LINK_LIBRARIES(comp_sql debug dbug mysys strings) # Use comp_sql to build mysql_fix_privilege_tables_sql.c GET_TARGET_PROPERTY(COMP_SQL_EXE comp_sql LOCATION) -ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tables_sql.c +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/scripts/mysql_fix_privilege_tables_sql.c COMMAND ${COMP_SQL_EXE} mysql_fix_privilege_tables - mysql_fix_privilege_tables.sql + ${CMAKE_CURRENT_BINARY_DIR}/mysql_fix_privilege_tables.sql mysql_fix_privilege_tables_sql.c - DEPENDS comp_sql ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tables.sql) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS comp_sql + ${CMAKE_BINARY_DIR}/scripts/mysql_fix_privilege_tables.sql) # Add dummy target for the above to be built ADD_CUSTOM_TARGET(GenFixPrivs ALL - DEPENDS ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tables_sql.c) + DEPENDS ${CMAKE_BINARY_DIR}/scripts/mysql_fix_privilege_tables_sql.c) # ---------------------------------------------------------------------- # Replace some variables @foo@ in the .in/.sh file, and write the new script # ---------------------------------------------------------------------- SET(CFLAGS "-D_WINDOWS ${CMAKE_C_FLAGS_RELWITHDEBINFO}") -SET(prefix "${CMAKE_INSTALL_PREFIX}/MySQL Server ${MYSQL_BASE_VERSION}") +SET(prefix "${CMAKE_INSTALL_PREFIX}") SET(sysconfdir ${prefix}) SET(bindir ${prefix}/bin) SET(libexecdir ${prefix}/bin) @@ -76,11 +80,14 @@ CONFIGURE_FILE(mysqldumpslow.sh CONFIGURE_FILE(mysqlhotcopy.sh ${CMAKE_BINARY_DIR}/scripts/mysqlhotcopy.pl ESCAPE_QUOTES @ONLY) -INSTALL(FILES mysqldumpslow.pl mysqlhotcopy.pl mysql_config.pl +FOREACH(f mysqldumpslow.pl mysqlhotcopy.pl mysql_config.pl mysql_convert_table_format.pl mysql_install_db.pl - mysql_secure_installation.pl mysqld_multi.pl - DESTINATION scripts COMPONENT scripts) - -INSTALL(FILES fill_help_tables.sql mysql_fix_privilege_tables.sql mysql_system_tables.sql
- mysql_system_tables_data.sql mysql_system_tables_fix.sql mysql_test_data_timezone.sql
- DESTINATION share COMPONENT scripts)
+ mysql_secure_installation.pl mysqld_multi.pl) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${f} + DESTINATION scripts COMPONENT Server_Scripts) +ENDFOREACH() + +INSTALL(FILES fill_help_tables.sql mysql_system_tables.sql + mysql_system_tables_data.sql mysql_system_tables_fix.sql mysql_test_data_timezone.sql + DESTINATION share COMPONENT Server) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql_fix_privilege_tables.sql DESTINATION share COMPONENT Server)
\ No newline at end of file diff --git a/scripts/comp_sql.c b/scripts/comp_sql.c index 88e88e632b6..e067d0757bf 100644 --- a/scripts/comp_sql.c +++ b/scripts/comp_sql.c @@ -25,6 +25,10 @@ #include <stdarg.h> #include <stdlib.h> #include <stdio.h> +#include <sys/stat.h> + +/* Compiler-dependent constant for maximum string constant */ +#define MAX_STRING_CONSTANT_LENGTH 65535 FILE *in, *out; @@ -58,64 +62,98 @@ static void die(const char *fmt, ...) int main(int argc, char *argv[]) { char buff[512]; + struct stat st; char* struct_name= argv[1]; char* infile_name= argv[2]; char* outfile_name= argv[3]; + if (argc != 4) die("Usage: comp_sql <struct_name> <sql_filename> <c_filename>"); /* Open input and output file */ if (!(in= fopen(infile_name, "r"))) die("Failed to open SQL file '%s'", infile_name); + + if (!(out= fopen(outfile_name, "w"))) die("Failed to open output file '%s'", outfile_name); + fprintf(out, "const char %s[]={\n",struct_name); + + /* + Some compilers have limitations how long a string constant can be. + We'll output very long strings as hexadecimal arrays, and short ones + as strings (prettier) + */ + stat(infile_name, &st); + if (st.st_size > MAX_STRING_CONSTANT_LENGTH) + { + int cnt=0; + int c; + for(cnt=0;;cnt++) + { + c= fgetc(in); + if (c== -1) + break; + + if(cnt != 0) + fputc(',', out); - fprintf(out, "const char* %s={\n\"", struct_name); + /* Put line break after each 16 hex characters */ + if(cnt && (cnt%16 == 0)) + fputc('\n', out); - while (fgets(buff, sizeof(buff), in)) + fprintf(out,"0x%02x",c); + } + fprintf(out,",0x00"); + } + else { - char *curr= buff; - while (*curr) + fprintf(out,"\""); + while (fgets(buff, sizeof(buff), in)) { - if (*curr == '\n') - { - /* - Reached end of line, add escaped newline, escaped - backslash and a newline to outfile - */ - fprintf(out, "\\n \"\n\""); - curr++; - } - else if (*curr == '\r') - { - curr++; /* Skip */ - } - else + char *curr= buff; + while (*curr) { - if (*curr == '"') + if (*curr == '\n') { - /* Needs escape */ - fputc('\\', out); + /* + Reached end of line, add escaped newline, escaped + backslash and a newline to outfile + */ + fprintf(out, "\\n \"\n\""); + curr++; + } + else if (*curr == '\r') + { + curr++; /* Skip */ + } + else + { + if (*curr == '"') + { + /* Needs escape */ + fputc('\\', out); + } + + fputc(*curr, out); + curr++; } - - fputc(*curr, out); - curr++; + } + if (*(curr-1) != '\n') + { + /* + Some compilers have a max string length, + insert a newline at every 512th char in long + strings + */ + fprintf(out, "\"\n\""); } } - if (*(curr-1) != '\n') - { - /* - Some compilers have a max string length, - insert a newline at every 512th char in long - strings - */ - fprintf(out, "\"\n\""); - } + fprintf(out, "\\\n\""); } - - fprintf(out, "\\\n\"};\n"); - + + fprintf(out, "};\n"); fclose(in); fclose(out); diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index c89c7cd875e..828670d9408 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -431,9 +431,9 @@ BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \ extra/resolve_stack_dump$BS extra/mysql_waitpid$BS \ storage/myisam/myisamchk$BS storage/myisam/myisampack$BS \ storage/myisam/myisamlog$BS storage/myisam/myisam_ftdump$BS \ - storage/maria/maria_chk$BS storage/maria/maria_pack$BS \ - storage/maria/maria_ftdump$BS storage/maria/maria_read_log$BS \ - storage/maria/maria_dump_log$BS \ + storage/maria/aria_chk$BS storage/maria/aria_pack$BS \ + storage/maria/aria_ftdump$BS storage/maria/aria_read_log$BS \ + storage/maria/aria_dump_log$BS \ sql/mysqld$BS sql/mysqld-debug$BS \ sql/mysql_tzinfo_to_sql$BS \ server-tools/instance-manager/mysqlmanager$BS \ diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist index 5c782af9f6f..35299f771cd 100755 --- a/scripts/make_win_bin_dist +++ b/scripts/make_win_bin_dist @@ -141,7 +141,7 @@ fi # Copy executables, and client DLL # ---------------------------------------------------------------------- MYISAM_BINARIES="myisamchk myisamlog myisampack myisam_ftdump" -MARIA_BINARIES="maria_chk maria_dump_log maria_ftdump maria_pack maria_read_log" +MARIA_BINARIES="aria_chk aria_dump_log aria_ftdump aria_pack aria_read_log" mkdir $DESTDIR mkdir $DESTDIR/bin cp client/$TARGET/*.exe $DESTDIR/bin/ @@ -163,7 +163,7 @@ if [ -f "storage/pbxt/bin/xtstat.exe" ] ; then cp storage/pbxt/bin/xtstat.{exe,pdb} $DESTDIR/bin fi -cp server-tools/instance-manager/$TARGET/*.exe $DESTDIR/bin/ +cp server-tools/instance-manager/$TARGET/*.exe $DESTDIR/bin/ if [ x"$TARGET" != x"release" ] ; then cp server-tools/instance-manager/$TARGET/*.pdb $DESTDIR/bin/ cp client/$TARGET/mysql.pdb $DESTDIR/bin/ @@ -305,10 +305,7 @@ cp libmysql/$TARGET/libmysql.dll \ regex/$TARGET/regex.lib \ strings/$TARGET/strings.lib \ zlib/$TARGET/zlib.lib $DESTDIR/lib/opt/ -if [ -d storage/innodb_plugin ]; then - cp storage/innodb_plugin/$TARGET/ha_innodb_plugin.dll \ - $DESTDIR/lib/plugin/ -fi +cp storage/*/$TARGET/ha_*.dll $DESTDIR/lib/plugin/ if [ x"$TARGET" != x"release" ] ; then cp libmysql/$TARGET/libmysql.pdb \ @@ -317,10 +314,7 @@ if [ x"$TARGET" != x"release" ] ; then regex/$TARGET/regex.pdb \ strings/$TARGET/strings.pdb \ zlib/$TARGET/zlib.pdb $DESTDIR/lib/opt/ - if [ -d storage/innodb_plugin ]; then - cp storage/innodb_plugin/$TARGET/ha_innodb_plugin.pdb \ - $DESTDIR/lib/plugin/ - fi + cp storage/*/$TARGET/ha_*.pdb $DESTDIR/lib/plugin/ fi @@ -341,12 +335,10 @@ if [ x"$PACK_DEBUG" = x"" -a -f "libmysql/debug/libmysql.lib" -o \ strings/debug/strings.pdb \ zlib/debug/zlib.lib \ zlib/debug/zlib.pdb $DESTDIR/lib/debug/ - if [ -d storage/innodb_plugin ]; then - cp storage/innodb_plugin/debug/ha_innodb_plugin.dll \ - storage/innodb_plugin/debug/ha_innodb_plugin.lib \ - storage/innodb_plugin/debug/ha_innodb_plugin.pdb \ - $DESTDIR/lib/plugin/debug/ - fi + cp storage/*/debug/ha_*.dll \ + storage/*/debug/ha_*.lib \ + storage/*/debug/ha_*.pdb \ + $DESTDIR/lib/plugin/debug/ fi # ---------------------------------------------------------------------- diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index aaf0553151f..f0147b22878 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -103,7 +103,7 @@ do fi done -parse_arguments `$print_defaults $defaults mysql_install_db mysql_fix_privilege_tables` +parse_arguments `$print_defaults $defaults mysql_install_db client client-server client-mariadb mysql_fix_privilege_tables` parse_arguments PICK-ARGS-FROM-ARGV "$@" if test -z "$password" diff --git a/scripts/mysql_install_db.pl.in b/scripts/mysql_install_db.pl.in index 7bc1e97e7be..83756d686d2 100644 --- a/scripts/mysql_install_db.pl.in +++ b/scripts/mysql_install_db.pl.in @@ -121,7 +121,7 @@ sub parse_arguments "basedir=s", "builddir=s", # FIXME not documented "srcdir=s", - "ldata|datadir=s", + "ldata|datadir|data=s", # Note that the user will be passed to mysqld so that it runs # as 'user' (crucial e.g. if log-bin=/some_other_path/ @@ -279,7 +279,7 @@ else my @default_options; my $cmd = quote_options($print_defaults,$opt->{'defaults-file'}, - "mysqld","mysql_install_db"); + "mysqld","mariadb","mysql_install_db","server","client-server"); open(PIPE, "$cmd |") or error($opt,"can't run $cmd: $!"); while ( <PIPE> ) { @@ -365,7 +365,7 @@ my $hostname = hostname(); my $resolved; if ( !$opt->{'cross-bootstrap'} and !$opt->{rpm} and !$opt->{force} ) { - my $resolveip; + my $resolveip = $bindir/resolveip; $resolved = `$resolveip $hostname 2>&1`; if ( $? != 0 ) @@ -423,9 +423,7 @@ my $mysqld_install_cmd_line = quote_options($mysqld_bootstrap, "--bootstrap", "--basedir=$opt->{basedir}", "--datadir=$opt->{ldata}", - "--skip-innodb", - "--skip-bdb", - "--skip-ndbcluster", + "--loose-skip-innodb", "--max_allowed_packet=8M", "--net_buffer_length=16K", @args, diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 2ce108e0ba8..dfea57fad26 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -56,7 +56,8 @@ Usage: $0 [OPTIONS] --help Display this help and exit. --ldata=path The path to the MariaDB data directory. Same as --datadir. - --no-defaults Don't read default options from any option file. + --no-defaults Don't read any configuration files (my.cnf). + --defaults-file=path Read only this configuration file. --rpm For internal use. This option is used by RPM files during the MariaDB installation process. --skip-name-resolve Use IP addresses rather than hostnames when creating @@ -86,6 +87,13 @@ s_echo() fi } +link_to_help() +{ + echo + echo "The latest information about mysql_install_db is available at" + echo "http://kb.askmonty.org/v/installing-system-tables-mysql_install_db." +} + parse_arg() { echo "$1" | sed -e 's/^[^=]*=//' @@ -110,7 +118,7 @@ parse_arguments() --basedir=*) basedir=`parse_arg "$arg"` ;; --builddir=*) builddir=`parse_arg "$arg"` ;; --srcdir=*) srcdir=`parse_arg "$arg"` ;; - --ldata=*|--datadir=*) ldata=`parse_arg "$arg"` ;; + --ldata=*|--datadir=*|--data=*) ldata=`parse_arg "$arg"` ;; --user=*) # Note that the user will be passed to mysqld so that it runs # as 'user' (crucial e.g. if log-bin=/some_other_path/ @@ -201,7 +209,7 @@ cannot_find_file() echo "If you are using a binary release, you must either be at the top" echo "level of the extracted archive, or pass the --basedir option" echo "pointing to that location." - echo + link_to_help } # Ok, let's go. We first need to parse arguments which are required by @@ -220,6 +228,7 @@ parse_arguments PICK-ARGS-FROM-ARGV "$@" if test -n "$srcdir" && test -n "$basedir" then echo "ERROR: Specify either --basedir or --srcdir, not both." + link_to_help exit 1 fi if test -n "$srcdir" @@ -249,7 +258,7 @@ fi # Now we can get arguments from the groups [mysqld] and [mysql_install_db] # in the my.cfg file, then re-run to merge with command line arguments. -parse_arguments `$print_defaults $defaults mysqld mysql_install_db` +parse_arguments `$print_defaults $defaults mysqld mariadb mysql_install_db client-server` parse_arguments PICK-ARGS-FROM-ARGV "$@" # Configure paths to support files @@ -342,6 +351,7 @@ then echo "hostname." echo "If you want to solve this at a later stage, restart this script" echo "with the --force option" + link_to_help exit 1 fi echo "WARNING: The host '$hostname' could not be looked up with resolveip." @@ -363,7 +373,12 @@ for dir in $ldata $ldata/mysql $ldata/test do if test ! -d $dir then - mkdir -p $dir + if ! `mkdir -p $dir` + then + echo "Fatal error Can't create database directory '$dir'" + link_to_help + exit 1 + fi chmod 700 $dir fi if test -w / -a ! -z "$user" @@ -391,12 +406,12 @@ fi mysqld_bootstrap="${MYSQLD_BOOTSTRAP-$mysqld}" mysqld_install_cmd_line="$mysqld_bootstrap $defaults $mysqld_opt --bootstrap \ --basedir=$basedir --datadir=$ldata --log-warnings=0 --loose-skip-innodb \ - --loose-skip-ndbcluster $args --max_allowed_packet=8M \ + --loose-skip-ndbcluster --loose-skip-pbxt $args --max_allowed_packet=8M \ --default-storage-engine=myisam \ --net_buffer_length=16K" # Create the system and help tables by passing them to "mysqld --bootstrap" -s_echo "Installing MariaDB/MySQL system tables..." +s_echo "Installing MariaDB/MySQL system tables in '$ldata' ..." if { echo "use mysql;"; cat $create_system_tables $fill_system_tables; } | eval "$filter_cmd_line" | $mysqld_install_cmd_line > /dev/null then s_echo "OK" @@ -417,9 +432,7 @@ else echo echo "Try 'mysqld --help' if you have problems with paths. Using" echo "--general-log gives you a log in $ldata that may be helpful." - echo - echo "The latest information about mysql_install_db is available at" - echo "http://kb.askmonty.org/v/installing-system-tables-mysql_install_db." + link_to_help echo "MariaDB is hosted on launchpad; You can find the latest source and" echo "email lists at http://launchpad.net/maria" echo @@ -461,13 +474,13 @@ then echo "databases and anonymous user created by default. This is" echo "strongly recommended for production servers." echo - echo "See the MySQL manual for more instructions." + echo "See the MariaDB knowledge or the MySQL manual for more instructions." if test "$in_rpm" -eq 0 then echo echo "You can start the MariaDB daemon with:" - echo "cd $basedir ; $bindir/mysqld_safe &" + echo "cd $basedir ; $bindir/mysqld_safe --datadir=$ldata" echo echo "You can test the MariaDB daemon with mysql-test-run.pl" echo "cd $basedir/mysql-test ; perl mysql-test-run.pl" diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh index 534717b1b06..772a9d8b1d8 100644 --- a/scripts/mysql_secure_installation.sh +++ b/scripts/mysql_secure_installation.sh @@ -165,9 +165,9 @@ then exit 1 fi -# Now we can get arguments from the group [client] +# Now we can get arguments from the group [client] and [client-server] # in the my.cfg file, then re-run to merge with command line arguments. -parse_arguments `$print_defaults $defaults client` +parse_arguments `$print_defaults $defaults client client-server client-mariadb` parse_arguments PICK-ARGS-FROM-ARGV "$@" # Configure paths to support files diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 9742a046371..bfa9e9fbd37 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -30,7 +30,7 @@ set @had_db_table= @@warning_count != 0; CREATE TABLE IF NOT EXISTS host ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges'; -CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; +CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) unsigned DEFAULT 0 NOT NULL, plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, auth_string TEXT NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; -- Remember for later if user table already existed set @had_user_table= @@warning_count != 0; @@ -77,7 +77,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsign CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones'; -CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; +CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; @@ -97,7 +97,7 @@ PREPARE stmt FROM @str; EXECUTE stmt; DROP PREPARE stmt; -CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; +CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM; diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql index e82d5412d75..583c44fe51c 100644 --- a/scripts/mysql_system_tables_data.sql +++ b/scripts/mysql_system_tables_data.sql @@ -37,9 +37,9 @@ DROP TABLE tmp_db; -- from local machine if "users" table didn't exist before CREATE TEMPORARY TABLE tmp_user LIKE user; set @current_hostname= @@hostname; -INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0); -REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0 FROM dual WHERE LOWER( @current_hostname) != 'localhost'; -REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0); +INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'',''); +REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','' FROM dual WHERE LOWER( @current_hostname) != 'localhost'; +REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'',''); INSERT INTO tmp_user (host,user) VALUES ('localhost',''); INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE LOWER(@current_hostname ) != 'localhost'; INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 6d0c10bc31d..a50cffd0cec 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -400,7 +400,7 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL, 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', - 'NOT_USED', + 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', @@ -514,14 +514,14 @@ ALTER TABLE db MODIFY Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NO ALTER TABLE event DROP PRIMARY KEY; ALTER TABLE event ADD PRIMARY KEY(db, name); # Add sql_mode column just in case. -ALTER TABLE event ADD sql_mode set ('NOT_USED') AFTER on_completion; +ALTER TABLE event ADD sql_mode set ('IGNORE_BAD_TABLE_OPTIONS') AFTER on_completion; # Update list of sql_mode values. ALTER TABLE event MODIFY sql_mode set('REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', - 'NOT_USED', + 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', @@ -601,6 +601,9 @@ ALTER TABLE db MODIFY Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT UPDATE user SET Trigger_priv=Super_priv WHERE @hadTriggerPriv = 0; +ALTER TABLE user ADD plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, ADD auth_string TEXT NOT NULL; +ALTER TABLE user MODIFY plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL; + # Activate the new, possible modified privilege tables # This should not be needed, but gives us some extra testing that the above # changes was correct diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 176953691a9..ad6584f0571 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -217,7 +217,7 @@ sub defaults_for_group sub init_log { - foreach my $opt (defaults_for_group('mysqld')) + foreach my $opt (defaults_for_group('mysqld mariadb')) { if ($opt =~ m/^--datadir=(.*)/ && -d "$1" && -w "$1") { diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index e4e5f1a1510..cae63343cfc 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -159,9 +159,13 @@ parse_arguments() { case "$arg" in # these get passed explicitly to mysqld --basedir=*) MY_BASEDIR_VERSION="$val" ;; - --datadir=*) DATADIR="$val" ;; + --datadir=*|--data=*) DATADIR="$val" ;; --pid-file=*) pid_file="$val" ;; --user=*) user="$val"; SET_USER=1 ;; + --log-basename=*|--hostname=*|--loose-log-basename=*) + pid_file="$val.pid"; + err_log="$val.err"; + ;; # these might have been set in a [mysqld_safe] section of my.cnf # they are added to mysqld command line to override settings from my.cnf @@ -313,7 +317,7 @@ append_arg_to_args () { args= SET_USER=2 -parse_arguments `$print_defaults $defaults --loose-verbose mysqld server` +parse_arguments `$print_defaults $defaults --loose-verbose mysqld mariadb server client-server` if test $SET_USER -eq 2 then SET_USER=0 @@ -411,7 +415,11 @@ safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}} mysql_unix_port_dir=`dirname $safe_mysql_unix_port` if [ ! -d $mysql_unix_port_dir ] then - mkdir $mysql_unix_port_dir + if ! `mkdir -p $mysql_unix_port_dir` + then + echo "Fatal error Can't create database directory '$mysql_unix_port'" + exit 1 + fi chown $user $mysql_unix_port_dir chmod 755 $mysql_unix_port_dir fi @@ -434,14 +442,14 @@ fi if test -z "$pid_file" then - pid_file="$DATADIR/`@HOSTNAME@`.pid" -else - case "$pid_file" in - /* ) ;; - * ) pid_file="$DATADIR/$pid_file" ;; - esac + pid_file="`@HOSTNAME@`.pid" fi +# MariaDB wants pid file without datadir append_arg_to_args "--pid-file=$pid_file" +case "$pid_file" in + /* ) ;; + * ) pid_file="$DATADIR/$pid_file" ;; +esac if test -n "$mysql_unix_port" then diff --git a/scripts/mysqldumpslow.sh b/scripts/mysqldumpslow.sh index 776b7d06a2d..3694526c944 100644 --- a/scripts/mysqldumpslow.sh +++ b/scripts/mysqldumpslow.sh @@ -38,13 +38,13 @@ GetOptions(\%opt, 'v|verbose+',# verbose 'help+', # write usage info 'd|debug+', # debug - 's=s', # what to sort by (al, at, ar, c, t, l, r) + 's=s', # what to sort by (al, at, ar, ae, c, t, l, r, e) 'r!', # reverse the sort order (largest last instead of first) 't=i', # just show the top n queries 'a!', # don't abstract all numbers to N and strings to 'S' 'n=i', # abstract numbers with at least n digits within names 'g=s', # grep: only consider stmts that include this string - 'h=s', # hostname of db server for *-slow.log filename (can be wildcard) + 'h=s', # hostname/basename of db server for *-slow.log filename (can be wildcard) 'i=s', # name of server instance (if using mysql.server startup script) 'l!', # don't subtract lock time from total time ) or usage("bad option"); @@ -52,31 +52,42 @@ GetOptions(\%opt, $opt{'help'} and usage(); unless (@ARGV) { - my $defaults = `my_print_defaults mysqld`; + my $defaults = `my_print_defaults mysqld mariadb`; my $datadir = ($defaults =~ m/--datadir=(.*)/g)[-1]; - my $slowlog = ($defaults =~ m/--log-slow-queries=(.*)/)[0]; if (!$datadir or $opt{i}) { # determine the datadir from the instances section of /etc/my.cnf, if any my $instances = `my_print_defaults instances`; - die "Can't determine datadir from 'my_print_defaults mysqld' output: $defaults" + die "Can't determine datadir from 'my_print_defaults instances' output: $defaults" unless $instances; my @instances = ($instances =~ m/^--(\w+)-/mg); die "No -i 'instance_name' specified to select among known instances: @instances.\n" unless $opt{i}; die "Instance '$opt{i}' is unknown (known instances: @instances)\n" unless grep { $_ eq $opt{i} } @instances; - $datadir = ($instances =~ m/--$opt{i}-datadir=(.*)/)[0] + $datadir = ($instances =~ m/--$opt{i}-datadir=(.*)/g)[-1] or die "Can't determine --$opt{i}-datadir from 'my_print_defaults instances' output: $instances"; warn "datadir=$datadir\n" if $opt{v}; } - if ( -f $slowlog ) { + my $slowlog = ($defaults =~ m/--log[-_]slow[-_]queries=(.*)/g)[-1]; + if (!$slowlog) + { + $slowlog = ($defaults =~ m/--slow[-_]query[-_]log[-_]file=(.*)/g)[-1]; + } + if ( $slowlog ) + { @ARGV = ($slowlog); die "Can't find '$slowlog'\n" unless @ARGV; - } else { - @ARGV = <$datadir/$opt{h}-slow.log>; - die "Can't find '$datadir/$opt{h}-slow.log'\n" unless @ARGV; + } + else + { + if (!$opt{h}) + { + $opt{h}= ($defaults =~ m/--log[-_]basename=(.*)/g)[-1]; + } + @ARGV = <$datadir/$opt{h}-slow.log>; + die "Can't find '$datadir/$opt{h}-slow.log'\n" unless @ARGV; } } @@ -98,8 +109,10 @@ while ( defined($_ = shift @pending) or defined($_ = <>) ) { s/^#? Time: \d{6}\s+\d+:\d+:\d+.*\n//; my ($user,$host) = s/^#? User\@Host:\s+(\S+)\s+\@\s+(\S+).*\n// ? ($1,$2) : ('',''); - s/^# Query_time: ([0-9.]+)\s+Lock_time: ([0-9.]+)\s+Rows_sent: ([0-9.]+).*\n//; - my ($t, $l, $r) = ($1, $2, $3); + s/^# Thread_id: [0-9]+\s+Schema: [^\n]+\n//; + s/^# Query_time: ([0-9.]+)\s+Lock_time: ([0-9.]+)\s+Rows_sent: ([0-9.]+)\s+Rows_examined: ([0-9.]+).*\n//; + my ($t, $l, $r, $e) = ($1, $2, $3, $4); + $t -= $l unless $opt{l}; # remove fluff that mysqld writes to log when it (re)starts: @@ -107,6 +120,11 @@ while ( defined($_ = shift @pending) or defined($_ = <>) ) { s!^Tcp port: \d+ Unix socket: \S+\n!!mg; s!^Time.*Id.*Command.*Argument.*\n!!mg; + # Remove optimizer info + s!^# QC_Hit: \S+\s+Full_scan: \S+\s+Full_join: \S+\s+Tmp_table: \S+\s+Tmp_table_on_disk: \S+[^\n]+\n!!mg; + s!^# Filesort: \S+\s+Filesort_on_disk: \S+[^\n]+\n!!mg; + s!^# Full_scan: \S+\s+Full_join: \S+[^\n]+\n!!mg; + s/^use \w+;\n//; # not consistently added s/^SET timestamp=\d+;\n//; @@ -136,6 +154,7 @@ while ( defined($_ = shift @pending) or defined($_ = <>) ) { $s->{t} += $t; $s->{l} += $l; $s->{r} += $r; + $s->{e} += $e; $s->{users}->{$user}++ if $user; $s->{hosts}->{$host}++ if $host; @@ -144,10 +163,11 @@ while ( defined($_ = shift @pending) or defined($_ = <>) ) { foreach (keys %stmt) { my $v = $stmt{$_} || die; - my ($c, $t, $l, $r) = @{ $v }{qw(c t l r)}; + my ($c, $t, $l, $r, $e) = @{ $v }{qw(c t l r e)}; $v->{at} = $t / $c; $v->{al} = $l / $c; $v->{ar} = $r / $c; + $v->{ae} = $e / $c; } my @sorted = sort { $stmt{$b}->{$opt{s}} <=> $stmt{$a}->{$opt{s}} } keys %stmt; @@ -156,13 +176,13 @@ my @sorted = sort { $stmt{$b}->{$opt{s}} <=> $stmt{$a}->{$opt{s}} } keys %stmt; foreach (@sorted) { my $v = $stmt{$_} || die; - my ($c, $t,$at, $l,$al, $r,$ar) = @{ $v }{qw(c t at l al r ar)}; + my ($c, $t,$at, $l,$al, $r,$ar,$e, $ae) = @{ $v }{qw(c t at l al r ar e ae)}; my @users = keys %{$v->{users}}; my $user = (@users==1) ? $users[0] : sprintf "%dusers",scalar @users; my @hosts = keys %{$v->{hosts}}; my $host = (@hosts==1) ? $hosts[0] : sprintf "%dhosts",scalar @hosts; - printf "Count: %d Time=%.2fs (%ds) Lock=%.2fs (%ds) Rows=%.1f (%d), $user\@$host\n%s\n\n", - $c, $at,$t, $al,$l, $ar,$r, $_; + printf "Count: %d Time=%.2fs (%ds) Lock=%.2fs (%ds) Rows_sent=%.1f (%d), Rows_examined=%.1f (%d), $user\@$host\n%s\n\n", + $c, $at,$t, $al,$l, $ar,$r, $ae, $e, $_; } sub usage { @@ -178,7 +198,7 @@ Parse and summarize the MySQL slow query log. Options are -v verbose -d debug - -s ORDER what to sort by (al, at, ar, c, l, r, t), 'at' is default + -s ORDER what to sort by (al, at, ar, ae, c, l, r, e, t), 'at' is default al: average lock time ar: average rows sent at: average query time diff --git a/server-tools/CMakeLists.txt b/server-tools/CMakeLists.txt index c79ef1cfc40..74b16c5feb1 100644 --- a/server-tools/CMakeLists.txt +++ b/server-tools/CMakeLists.txt @@ -25,7 +25,7 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instanc user_management_commands.cc ../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c ../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c - ../../libmysql/errmsg.c) + ../../libmysql/errmsg.c ../../sql-common/client_plugin.c) ADD_DEPENDENCIES(mysqlmanager GenError) TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32) diff --git a/server-tools/instance-manager/CMakeLists.txt b/server-tools/instance-manager/CMakeLists.txt index cb6c4fa6d7b..8e96a3f6425 100755 --- a/server-tools/instance-manager/CMakeLists.txt +++ b/server-tools/instance-manager/CMakeLists.txt @@ -19,7 +19,6 @@ ADD_DEFINITIONS(-DMYSQL_SERVER -DMYSQL_INSTANCE_MANAGER) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/sql ${PROJECT_SOURCE_DIR}/extra/yassl/include) - ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instance.cc instance_map.cc instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc @@ -27,7 +26,7 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instanc user_management_commands.cc ../../mysys/my_rnd.c ../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c ../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c - ../../libmysql/errmsg.c) + ../../libmysql/errmsg.c ../../sql-common/client_plugin.c) ADD_DEPENDENCIES(mysqlmanager GenError) TARGET_LINK_LIBRARIES(mysqlmanager debug dbug mysys strings taocrypt vio yassl zlib wsock32) @@ -35,5 +34,3 @@ TARGET_LINK_LIBRARIES(mysqlmanager debug dbug mysys strings taocrypt vio yassl z IF(EMBED_MANIFESTS) MYSQL_EMBED_MANIFEST("mysqlmanager" "asInvoker") ENDIF(EMBED_MANIFESTS) - -INSTALL(TARGETS mysqlmanager DESTINATION bin COMPONENT runtime) diff --git a/server-tools/instance-manager/Makefile.am b/server-tools/instance-manager/Makefile.am index d480dacf5aa..dce7c77232d 100644 --- a/server-tools/instance-manager/Makefile.am +++ b/server-tools/instance-manager/Makefile.am @@ -46,7 +46,8 @@ libnet_a_LIBADD= $(top_builddir)/sql/password.$(OBJEXT) \ $(top_builddir)/sql/pack.$(OBJEXT) \ $(top_builddir)/sql/sql_state.$(OBJEXT) \ $(top_builddir)/sql/mini_client_errors.$(OBJEXT)\ - $(top_builddir)/sql/client.$(OBJEXT) + $(top_builddir)/sql/client.$(OBJEXT) \ + $(top_builddir)/sql/client_plugin.$(OBJEXT) CLEANFILES= net_serv.cc client_settings.h @@ -91,7 +92,7 @@ mysqlmanager_LDADD= @CLIENT_EXTRA_LDFLAGS@ \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a \ $(top_builddir)/dbug/libdbug.a \ - @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@ + @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@ @LIBDL@ EXTRA_DIST = WindowsService.cpp WindowsService.h IMService.cpp \ IMService.h CMakeLists.txt diff --git a/server-tools/instance-manager/user_map.cc b/server-tools/instance-manager/user_map.cc index cf37f0be0b4..928300b42d9 100644 --- a/server-tools/instance-manager/user_map.cc +++ b/server-tools/instance-manager/user_map.cc @@ -371,7 +371,7 @@ int User_map::authenticate(const LEX_STRING *user_name, const char *scramble) const { const User *user= find_user(user_name); - return user ? check_scramble(scrambled_password, scramble, user->salt) : 2; + return user ? check_scramble((uchar*)scrambled_password, scramble, user->salt) : 2; } diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh index 35512f36560..8b7cdfdb103 100644 --- a/sql-bench/server-cfg.sh +++ b/sql-bench/server-cfg.sh @@ -180,12 +180,23 @@ sub new { $limits{'working_blobs'} = 0; # HEAP tables can't handle BLOB's } + # HEAP is deprecated in favor of MEMORY + if (defined($main::opt_create_options) && + $main::opt_create_options =~ /engine=memory/i) + { + $limits{'working_blobs'} = 0; # MEMORY tables can't handle BLOB's + } if (defined($main::opt_create_options) && $main::opt_create_options =~ /engine=innodb/i) { $self->{'transactions'} = 1; # Transactions enabled } if (defined($main::opt_create_options) && + $main::opt_create_options =~ /engine=pbxt/i) + { + $self->{'transactions'} = 1; # Transactions enabled + } + if (defined($main::opt_create_options) && $main::opt_create_options =~ /engine=ndb/i) { $self->{'transactions'} = 1; # Transactions enabled diff --git a/sql-common/Makefile.am b/sql-common/Makefile.am index 3193efee754..2f5a049085f 100644 --- a/sql-common/Makefile.am +++ b/sql-common/Makefile.am @@ -14,4 +14,4 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## Process this file with automake to create Makefile.in -EXTRA_DIST = client.c pack.c my_time.c my_user.c +EXTRA_DIST = client.c pack.c my_time.c my_user.c client_plugin.c diff --git a/sql-common/client.c b/sql-common/client.c index cdb272e076e..c0045e8edc1 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -109,6 +109,10 @@ my_bool net_flush(NET *net); #include "client_settings.h" #include <sql_common.h> +#include <mysql/client_plugin.h> + +#define native_password_plugin_name "mysql_native_password" +#define old_password_plugin_name "mysql_old_password" uint mysql_port=0; char *mysql_unix_port= 0; @@ -334,7 +338,7 @@ void net_clear_error(NET *net) @param ... variable number of arguments */ -static void set_mysql_extended_error(MYSQL *mysql, int errcode, +void set_mysql_extended_error(MYSQL *mysql, int errcode, const char *sqlstate, const char *format, ...) { @@ -1004,9 +1008,20 @@ static const char *default_options[]= "replication-probe", "enable-reads-from-master", "repl-parse-query", "ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name", "multi-results", "multi-statements", "multi-queries", "secure-auth", - "report-data-truncation", + "report-data-truncation", "plugin-dir", "default-auth", NullS }; +enum option_id { + OPT_port=1, OPT_socket, OPT_compress, OPT_password, OPT_pipe, OPT_timeout, OPT_user, + OPT_init_command, OPT_host, OPT_database, OPT_debug, OPT_return_found_rows, + OPT_ssl_key, OPT_ssl_cert, OPT_ssl_ca, OPT_ssl_capath, + OPT_character_sets_dir, OPT_default_character_set, OPT_interactive_timeout, + OPT_connect_timeout, OPT_local_infile, OPT_disable_local_infile, + OPT_replication_probe, OPT_enable_reads_from_master, OPT_repl_parse_query, + OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name, + OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth, + OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth, +}; static TYPELIB option_types={array_elements(default_options)-1, "options",default_options, NULL}; @@ -1037,17 +1052,30 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd) return 0; } +#define extension_set_string(OPTS, X, STR) \ + if ((OPTS)->extension) \ + my_free((OPTS)->extension->X, MYF(MY_ALLOW_ZERO_PTR)); \ + else \ + (OPTS)->extension= (struct st_mysql_options_extention *) \ + my_malloc(sizeof(struct st_mysql_options_extention), \ + MYF(MY_WME | MY_ZEROFILL)); \ + (OPTS)->extension->X= my_strdup((STR), MYF(MY_WME)); + void mysql_read_default_options(struct st_mysql_options *options, const char *filename,const char *group) { int argc; char *argv_buff[1],**argv; - const char *groups[3]; + const char *groups[5]; DBUG_ENTER("mysql_read_default_options"); DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL")); argc=1; argv=argv_buff; argv_buff[0]= (char*) "client"; - groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0; + groups[0]= (char*) "client"; + groups[1]= (char*) "client-server"; + groups[2]= (char*) "client-mariadb"; + groups[3]= (char*) group; + groups[4]=0; my_load_defaults(filename, groups, &argc, &argv, NULL); if (argc != 1) /* If some default option */ @@ -1069,134 +1097,134 @@ void mysql_read_default_options(struct st_mysql_options *options, for (end= *option ; *(end= strcend(end,'_')) ; ) *end= '-'; switch (find_type(*option+2,&option_types,2)) { - case 1: /* port */ + case OPT_port: if (opt_arg) options->port=atoi(opt_arg); break; - case 2: /* socket */ + case OPT_socket: if (opt_arg) { my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR)); options->unix_socket=my_strdup(opt_arg,MYF(MY_WME)); } break; - case 3: /* compress */ + case OPT_compress: options->compress=1; options->client_flag|= CLIENT_COMPRESS; break; - case 4: /* password */ + case OPT_password: if (opt_arg) { my_free(options->password,MYF(MY_ALLOW_ZERO_PTR)); options->password=my_strdup(opt_arg,MYF(MY_WME)); } break; - case 5: + case OPT_pipe: options->protocol = MYSQL_PROTOCOL_PIPE; - case 20: /* connect_timeout */ - case 6: /* timeout */ + case OPT_connect_timeout: + case OPT_timeout: if (opt_arg) options->connect_timeout=atoi(opt_arg); break; - case 7: /* user */ + case OPT_user: if (opt_arg) { my_free(options->user,MYF(MY_ALLOW_ZERO_PTR)); options->user=my_strdup(opt_arg,MYF(MY_WME)); } break; - case 8: /* init-command */ + case OPT_init_command: add_init_command(options,opt_arg); break; - case 9: /* host */ + case OPT_host: if (opt_arg) { my_free(options->host,MYF(MY_ALLOW_ZERO_PTR)); options->host=my_strdup(opt_arg,MYF(MY_WME)); } break; - case 10: /* database */ + case OPT_database: if (opt_arg) { my_free(options->db,MYF(MY_ALLOW_ZERO_PTR)); options->db=my_strdup(opt_arg,MYF(MY_WME)); } break; - case 11: /* debug */ + case OPT_debug: #ifdef MYSQL_CLIENT mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace"); break; #endif - case 12: /* return-found-rows */ + case OPT_return_found_rows: options->client_flag|=CLIENT_FOUND_ROWS; break; #ifdef HAVE_OPENSSL - case 13: /* ssl_key */ + case OPT_ssl_key: my_free(options->ssl_key, MYF(MY_ALLOW_ZERO_PTR)); options->ssl_key = my_strdup(opt_arg, MYF(MY_WME)); break; - case 14: /* ssl_cert */ + case OPT_ssl_cert: my_free(options->ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); options->ssl_cert = my_strdup(opt_arg, MYF(MY_WME)); break; - case 15: /* ssl_ca */ + case OPT_ssl_ca: my_free(options->ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); options->ssl_ca = my_strdup(opt_arg, MYF(MY_WME)); break; - case 16: /* ssl_capath */ + case OPT_ssl_capath: my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME)); break; - case 26: /* ssl_cipher */ + case OPT_ssl_cipher: my_free(options->ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME)); break; #else - case 13: /* Ignore SSL options */ - case 14: - case 15: - case 16: - case 26: + case OPT_ssl_key: + case OPT_ssl_cert: + case OPT_ssl_ca: + case OPT_ssl_capath: + case OPT_ssl_cipher: break; #endif /* HAVE_OPENSSL */ - case 17: /* charset-lib */ + case OPT_character_sets_dir: my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR)); options->charset_dir = my_strdup(opt_arg, MYF(MY_WME)); break; - case 18: + case OPT_default_character_set: my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR)); options->charset_name = my_strdup(opt_arg, MYF(MY_WME)); break; - case 19: /* Interactive-timeout */ + case OPT_interactive_timeout: options->client_flag|= CLIENT_INTERACTIVE; break; - case 21: + case OPT_local_infile: if (!opt_arg || atoi(opt_arg) != 0) options->client_flag|= CLIENT_LOCAL_FILES; else options->client_flag&= ~CLIENT_LOCAL_FILES; break; - case 22: + case OPT_disable_local_infile: options->client_flag&= ~CLIENT_LOCAL_FILES; break; - case 23: /* replication probe */ + case OPT_replication_probe: #ifndef TO_BE_DELETED options->rpl_probe= 1; #endif break; - case 24: /* enable-reads-from-master */ + case OPT_enable_reads_from_master: options->no_master_reads= 0; break; - case 25: /* repl-parse-query */ + case OPT_repl_parse_query: #ifndef TO_BE_DELETED options->rpl_parse= 1; #endif break; - case 27: + case OPT_max_allowed_packet: if (opt_arg) options->max_allowed_packet= atoi(opt_arg); break; - case 28: /* protocol */ + case OPT_protocol: if ((options->protocol= find_type(opt_arg, &sql_protocol_typelib,0)) <= 0) { @@ -1204,26 +1232,32 @@ void mysql_read_default_options(struct st_mysql_options *options, exit(1); } break; - case 29: /* shared_memory_base_name */ + case OPT_shared_memory_base_name: #ifdef HAVE_SMEM if (options->shared_memory_base_name != def_shared_memory_base_name) my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME)); #endif break; - case 30: + case OPT_multi_results: options->client_flag|= CLIENT_MULTI_RESULTS; break; - case 31: - case 32: + case OPT_multi_statements: + case OPT_multi_queries: options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS; break; - case 33: /* secure-auth */ + case OPT_secure_auth: options->secure_auth= TRUE; break; - case 34: /* report-data-truncation */ + case OPT_report_data_truncation: options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1; break; + case OPT_plugin_dir: + extension_set_string(options, plugin_dir, opt_arg); + break; + case OPT_default_auth: + extension_set_string(options, default_auth, opt_arg); + break; default: DBUG_PRINT("warning",("unknown option: %s",option[0])); } @@ -1768,6 +1802,11 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname) static my_bool cli_read_query_result(MYSQL *mysql); static MYSQL_RES *cli_use_result(MYSQL *mysql); +int cli_read_change_user_result(MYSQL *mysql) +{ + return cli_safe_read(mysql); +} + static MYSQL_METHODS client_methods= { cli_read_query_result, /* read_query_result */ @@ -1775,7 +1814,8 @@ static MYSQL_METHODS client_methods= cli_read_rows, /* read_rows */ cli_use_result, /* use_result */ cli_fetch_lengths, /* fetch_lengths */ - cli_flush_use_result /* flush_use_result */ + cli_flush_use_result, /* flush_use_result */ + cli_read_change_user_result /* read_change_user_result */ #ifndef MYSQL_SERVER ,cli_list_fields, /* list_fields */ cli_read_prepare_result, /* read_prepare_result */ @@ -1785,7 +1825,6 @@ static MYSQL_METHODS client_methods= NULL, /* free_embedded_thd */ cli_read_statistics, /* read_statistics */ cli_read_query_result, /* next_result */ - cli_read_change_user_result, /* read_change_user_result */ cli_read_binary_rows /* read_rows_from_cursor */ #endif }; @@ -1859,6 +1898,646 @@ int mysql_init_character_set(MYSQL *mysql) } C_MODE_END +/*********** client side authentication support **************************/ + +typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t; +static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, int); +static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql); +static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql); + +static auth_plugin_t native_password_client_plugin= +{ + MYSQL_CLIENT_AUTHENTICATION_PLUGIN, + MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION, + native_password_plugin_name, + "R.J.Silk, Sergei Golubchik", + "Native MySQL authentication", + {1, 0, 0}, + NULL, + NULL, + native_password_auth_client +}; + +static auth_plugin_t old_password_client_plugin= +{ + MYSQL_CLIENT_AUTHENTICATION_PLUGIN, + MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION, + old_password_plugin_name, + "R.J.Silk, Sergei Golubchik", + "Old MySQL-3.23 authentication", + {1, 0, 0}, + NULL, + NULL, + old_password_auth_client +}; + +struct st_mysql_client_plugin *mysql_client_builtins[]= +{ + (struct st_mysql_client_plugin *)&native_password_client_plugin, + (struct st_mysql_client_plugin *)&old_password_client_plugin, + 0 +}; + + + +/* this is a "superset" of MYSQL_PLUGIN_VIO, in C++ I use inheritance */ +typedef struct { + int (*read_packet)(struct st_plugin_vio *vio, uchar **buf); + int (*write_packet)(struct st_plugin_vio *vio, const uchar *pkt, int pkt_len); + void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info); + /* -= end of MYSQL_PLUGIN_VIO =- */ + MYSQL *mysql; + auth_plugin_t *plugin; /**< what plugin we're under */ + const char *db; + struct { + uchar *pkt; /**< pointer into NET::buff */ + uint pkt_len; + } cached_server_reply; + uint packets_read, packets_written; /**< counters for send/received packets */ + my_bool mysql_change_user; /**< if it's mysql_change_user() */ + int last_read_packet_len; /**< the length of the last *read* packet */ +} MCPVIO_EXT; + +/** + sends a COM_CHANGE_USER command with a caller provided payload + + Packet format: + + Bytes Content + ----- ---- + n user name - \0-terminated string + n password + 3.23 scramble - \0-terminated string (9 bytes) + otherwise - length (1 byte) coded + n database name - \0-terminated string + 2 character set number (if the server >= 4.1.x) + n client auth plugin name - \0-terminated string, + (if the server supports plugin auth) + + @retval 0 ok + @retval 1 error +*/ + +static int send_change_user_packet(MCPVIO_EXT *mpvio, + const uchar *data, int data_len) +{ + MYSQL *mysql= mpvio->mysql; + char *buff, *end; + int res= 1; + + buff= my_alloca(USERNAME_LENGTH+1 + data_len+1 + NAME_LEN+1 + 2 + NAME_LEN+1); + + end= strmake(buff, mysql->user, USERNAME_LENGTH) + 1; + + if (!data_len) + *end++= 0; + else + { + if (mysql->client_flag & CLIENT_SECURE_CONNECTION) + { + DBUG_ASSERT(data_len <= 255); + if (data_len > 255) + { + set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate); + goto error; + } + *end++= data_len; + } + else + { + DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1); + DBUG_ASSERT(data[SCRAMBLE_LENGTH_323] == 0); + } + memcpy(end, data, data_len); + end+= data_len; + } + end= strmake(end, mpvio->db ? mpvio->db : "", NAME_LEN) + 1; + + if (mysql->server_capabilities & CLIENT_PROTOCOL_41) + { + int2store(end, (ushort) mysql->charset->number); + end+= 2; + } + + if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH) + end= strmake(end, mpvio->plugin->name, NAME_LEN) + 1; + + res= simple_command(mysql, COM_CHANGE_USER, + (uchar*)buff, (ulong)(end-buff), 1); + +error: + my_afree(buff); + return res; +} + + +/** + sends a client authentication packet (second packet in the 3-way handshake) + + Packet format (when the server is 4.0 or earlier): + + Bytes Content + ----- ---- + 2 client capabilities + 3 max packet size + n user name, \0-terminated + 9 scramble_323, \0-terminated + + Packet format (when the server is 4.1 or newer): + + Bytes Content + ----- ---- + 4 client capabilities + 4 max packet size + 1 charset number + 23 reserved (always 0) + n user name, \0-terminated + n plugin auth data (e.g. scramble), length (1 byte) coded + n database name, \0-terminated + (if CLIENT_CONNECT_WITH_DB is set in the capabilities) + n client auth plugin name - \0-terminated string, + (if CLIENT_PLUGIN_AUTH is set in the capabilities) + + @retval 0 ok + @retval 1 error +*/ + +static int send_client_reply_packet(MCPVIO_EXT *mpvio, + const uchar *data, int data_len) +{ + MYSQL *mysql= mpvio->mysql; + NET *net= &mysql->net; + char *buff, *end; + + /* see end= buff+32 below, fixed size of the packet is 32 bytes */ + buff= my_alloca(33 + USERNAME_LENGTH + data_len + NAME_LEN + NAME_LEN); + + mysql->client_flag|= mysql->options.client_flag; + mysql->client_flag|= CLIENT_CAPABILITIES; + + if (mysql->client_flag & CLIENT_MULTI_STATEMENTS) + mysql->client_flag|= CLIENT_MULTI_RESULTS; + +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) + if (mysql->options.ssl_key || mysql->options.ssl_cert || + mysql->options.ssl_ca || mysql->options.ssl_capath || + mysql->options.ssl_cipher) + mysql->options.use_ssl= 1; + if (mysql->options.use_ssl) + mysql->client_flag|= CLIENT_SSL; +#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY*/ + if (mpvio->db) + mysql->client_flag|= CLIENT_CONNECT_WITH_DB; + + /* Remove options that server doesn't support */ + mysql->client_flag= mysql->client_flag & + (~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41) + | mysql->server_capabilities); + +#ifndef HAVE_COMPRESS + mysql->client_flag&= ~CLIENT_COMPRESS; +#endif + + if (mysql->client_flag & CLIENT_PROTOCOL_41) + { + /* 4.1 server and 4.1 client has a 32 byte option flag */ + int4store(buff,mysql->client_flag); + int4store(buff+4, net->max_packet_size); + buff[8]= (char) mysql->charset->number; + bzero(buff+9, 32-9); + end= buff+32; + } + else + { + int2store(buff, mysql->client_flag); + int3store(buff+2, net->max_packet_size); + end= buff+5; + } +#ifdef HAVE_OPENSSL + if (mysql->client_flag & CLIENT_SSL) + { + /* Do the SSL layering. */ + struct st_mysql_options *options= &mysql->options; + struct st_VioSSLFd *ssl_fd; + char error_string[1024]; + + /* + Send mysql->client_flag, max_packet_size - unencrypted otherwise + the server does not know we want to do SSL + */ + if (my_net_write(net, (uchar*)buff, (size_t) (end-buff)) || net_flush(net)) + { + set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, + ER(CR_SERVER_LOST_EXTENDED), + "sending connection information to server", + errno); + goto error; + } + + /* Create the VioSSLConnectorFd - init SSL and load certs */ + if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key, + options->ssl_cert, + options->ssl_ca, + options->ssl_capath, + options->ssl_cipher))) + { + set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); + goto error; + } + mysql->connector_fd= (void*)ssl_fd; + + /* Connect to the server */ + DBUG_PRINT("info", ("IO layer change in progress...")); + if (sslconnect(ssl_fd, net->vio, + (long) (mysql->options.connect_timeout), + error_string)) + { + set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, + unknown_sqlstate, "SSL error: %s", + error_string[0] ? error_string : + ER(CR_SSL_CONNECTION_ERROR)); + goto error; + } + DBUG_PRINT("info", ("IO layer change done!")); + + /* Verify server cert */ + if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) && + ssl_verify_server_cert(net->vio, mysql->host)) + { + set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); + goto error; + } + } +#endif /* HAVE_OPENSSL */ + + DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu", + mysql->server_version, mysql->server_capabilities, + mysql->server_status, mysql->client_flag)); + + compile_time_assert(MYSQL_USERNAME_LENGTH == USERNAME_LENGTH); + + /* This needs to be changed as it's not useful with big packets */ + if (mysql->user[0]) + strmake(end, mysql->user, USERNAME_LENGTH); + else + read_user_name(end); + + /* We have to handle different version of handshake here */ + DBUG_PRINT("info",("user: %s",end)); + end= strend(end) + 1; + if (data_len) + { + if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION) + { + *end++= data_len; + memcpy(end, data, data_len); + end+= data_len; + } + else + { + DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1); /* incl. \0 at the end */ + memcpy(end, data, data_len); + end+= data_len; + } + } + else + *end++= 0; + + /* Add database if needed */ + if (mpvio->db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) + { + end= strmake(end, mpvio->db, NAME_LEN) + 1; + mysql->db= my_strdup(mpvio->db, MYF(MY_WME)); + } + + if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH) + end= strmake(end, mpvio->plugin->name, NAME_LEN) + 1; + + /* Write authentication package */ + if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net)) + { + set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, + ER(CR_SERVER_LOST_EXTENDED), + "sending authentication information", + errno); + goto error; + } + my_afree(buff); + return 0; + +error: + my_afree(buff); + return 1; +} + + +/** + vio->read_packet() callback method for client authentication plugins + + This function is called by a client authentication plugin, when it wants + to read data from the server. +*/ + +static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf) +{ + MCPVIO_EXT *mpvio= (MCPVIO_EXT*)mpv; + MYSQL *mysql= mpvio->mysql; + ulong pkt_len; + + /* there are cached data left, feed it to a plugin */ + if (mpvio->cached_server_reply.pkt) + { + *buf= mpvio->cached_server_reply.pkt; + mpvio->cached_server_reply.pkt= 0; + mpvio->packets_read++; + return mpvio->cached_server_reply.pkt_len; + } + + if (mpvio->packets_read == 0) + { + /* + the server handshake packet came from the wrong plugin, + or it's mysql_change_user(). Either way, there is no data + for a plugin to read. send a dummy packet to the server + to initiate a dialog. + */ + if (client_mpvio_write_packet(mpv, 0, 0)) + return (int)packet_error; + } + + /* otherwise read the data */ + pkt_len= (*mysql->methods->read_change_user_result)(mysql); + mpvio->last_read_packet_len= pkt_len; + *buf= mysql->net.read_pos; + + /* was it a request to change plugins ? */ + if (**buf == 254) + return (int)packet_error; /* if yes, this plugin shan't continue */ + + /* + the server sends \1\255 or \1\254 instead of just \255 or \254 - + for us to not confuse it with an error or "change plugin" packets. + We remove this escaping \1 here. + + See also server_mpvio_write_packet() where the escaping is done. + */ + if (pkt_len && **buf == 1) + { + (*buf)++; + pkt_len--; + } + mpvio->packets_read++; + return pkt_len; +} + + +/** + vio->write_packet() callback method for client authentication plugins + + This function is called by a client authentication plugin, when it wants + to send data to the server. + + It transparently wraps the data into a change user or authentication + handshake packet, if neccessary. +*/ + +static int client_mpvio_write_packet(struct st_plugin_vio *mpv, + const uchar *pkt, int pkt_len) +{ + int res; + MCPVIO_EXT *mpvio= (MCPVIO_EXT*)mpv; + + if (mpvio->packets_written == 0) + { + if (mpvio->mysql_change_user) + res= send_change_user_packet(mpvio, pkt, pkt_len); + else + res= send_client_reply_packet(mpvio, pkt, pkt_len); + } + else + { + NET *net= &mpvio->mysql->net; + if (mpvio->mysql->thd) + res= 1; /* no chit-chat in embedded */ + else + res= my_net_write(net, pkt, pkt_len) || net_flush(net); + if (res) + set_mysql_extended_error(mpvio->mysql, CR_SERVER_LOST, unknown_sqlstate, + ER(CR_SERVER_LOST_EXTENDED), + "sending authentication information", + errno); + } + mpvio->packets_written++; + return res; +} + + +/** + fills MYSQL_PLUGIN_VIO_INFO structure with the information about the + connection +*/ + +void mpvio_info(Vio *vio, MYSQL_PLUGIN_VIO_INFO *info) +{ + bzero(info, sizeof(*info)); + switch (vio->type) { + case VIO_TYPE_TCPIP: + info->protocol= MYSQL_VIO_TCP; + info->socket= vio->sd; + return; + case VIO_TYPE_SOCKET: + info->protocol= MYSQL_VIO_SOCKET; + info->socket= vio->sd; + return; + case VIO_TYPE_SSL: + { + struct sockaddr addr; + SOCKET_SIZE_TYPE addrlen= sizeof(addr); + if (getsockname(vio->sd, &addr, &addrlen)) + return; + info->protocol= addr.sa_family == AF_UNIX ? + MYSQL_VIO_SOCKET : MYSQL_VIO_TCP; + info->socket= vio->sd; + return; + } +#ifdef _WIN32 + case VIO_TYPE_NAMEDPIPE: + info->protocol= MYSQL_VIO_PIPE; + info->handle= vio->hPipe; + return; + case VIO_TYPE_SHARED_MEMORY: + info->protocol= MYSQL_VIO_MEMORY; + info->handle= vio->handle_file_map; /* or what ? */ + return; +#endif + default: DBUG_ASSERT(0); + } +} + + +static void client_mpvio_info(MYSQL_PLUGIN_VIO *vio, + MYSQL_PLUGIN_VIO_INFO *info) +{ + MCPVIO_EXT *mpvio= (MCPVIO_EXT*)vio; + mpvio_info(mpvio->mysql->net.vio, info); +} + + +/** + Client side of the plugin driver authentication. + + @note this is used by both the mysql_real_connect and mysql_change_user + + @param mysql mysql + @param data pointer to the plugin auth data (scramble) in the + handshake packet + @param data_len the length of the data + @param data_plugin a plugin that data were prepared for + or 0 if it's mysql_change_user() + @param db initial db to use, can be 0 + + @retval 0 ok + @retval 1 error +*/ + +int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, + const char *data_plugin, const char *db) +{ + const char *auth_plugin_name; + auth_plugin_t *auth_plugin; + MCPVIO_EXT mpvio; + ulong pkt_length; + int res; + + /* determine the default/initial plugin to use */ + if (mysql->options.extension && mysql->options.extension->default_auth && + mysql->server_capabilities & CLIENT_PLUGIN_AUTH) + { + auth_plugin_name= mysql->options.extension->default_auth; + if (!(auth_plugin= (auth_plugin_t*) mysql_client_find_plugin(mysql, + auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN))) + return 1; /* oops, not found */ + } + else + { + auth_plugin= mysql->server_capabilities & CLIENT_PROTOCOL_41 ? + &native_password_client_plugin : &old_password_client_plugin; + auth_plugin_name= auth_plugin->name; + } + + mysql->net.last_errno= 0; /* just in case */ + + if (data_plugin && strcmp(data_plugin, auth_plugin_name)) + { + /* data was prepared for a different plugin, don't show it to this one */ + data= 0; + data_len= 0; + } + + mpvio.mysql_change_user= data_plugin == 0; + mpvio.cached_server_reply.pkt= (uchar*)data; + mpvio.cached_server_reply.pkt_len= data_len; + mpvio.read_packet= client_mpvio_read_packet; + mpvio.write_packet= client_mpvio_write_packet; + mpvio.info= client_mpvio_info; + mpvio.mysql= mysql; + mpvio.packets_read= mpvio.packets_written= 0; + mpvio.db= db; + mpvio.plugin= auth_plugin; + + res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql); + + compile_time_assert(CR_OK == -1); + compile_time_assert(CR_ERROR == 0); + if (res > CR_OK && mysql->net.read_pos[0] != 254) + { + /* + the plugin returned an error. write it down in mysql, + unless the error code is CR_ERROR and mysql->net.last_errno + is already set (the plugin has done it) + */ + if (res > CR_ERROR) + set_mysql_error(mysql, res, unknown_sqlstate); + else + if (!mysql->net.last_errno) + set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate); + return 1; + } + + /* read the OK packet (or use the cached value in mysql->net.read_pos */ + if (res == CR_OK) + pkt_length= (*mysql->methods->read_change_user_result)(mysql); + else /* res == CR_OK_HANDSHAKE_COMPLETE */ + pkt_length= mpvio.last_read_packet_len; + + if (pkt_length == packet_error) + { + if (mysql->net.last_errno == CR_SERVER_LOST) + set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, + ER(CR_SERVER_LOST_EXTENDED), + "reading authorization packet", + errno); + return 1; + } + + if (mysql->net.read_pos[0] == 254) + { + /* The server asked to use a different authentication plugin */ + if (pkt_length == 1) + { + /* old "use short scramble" packet */ + auth_plugin_name= old_password_plugin_name; + mpvio.cached_server_reply.pkt= (uchar*)mysql->scramble; + mpvio.cached_server_reply.pkt_len= SCRAMBLE_LENGTH + 1; + } + else + { + /* new "use different plugin" packet */ + uint len; + auth_plugin_name= (char*)mysql->net.read_pos + 1; + len= strlen(auth_plugin_name); /* safe as my_net_read always appends \0 */ + mpvio.cached_server_reply.pkt_len= pkt_length - len - 2; + mpvio.cached_server_reply.pkt= mysql->net.read_pos + len + 2; + } + + if (!(auth_plugin= (auth_plugin_t *) mysql_client_find_plugin(mysql, + auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN))) + return 1; + + mpvio.plugin= auth_plugin; + res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql); + + if (res > CR_OK) + { + if (res > CR_ERROR) + set_mysql_error(mysql, res, unknown_sqlstate); + else + if (!mysql->net.last_errno) + set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate); + return 1; + } + + if (res != CR_OK_HANDSHAKE_COMPLETE) + { + /* Read what server thinks about out new auth message report */ + if (cli_safe_read(mysql) == packet_error) + { + if (mysql->net.last_errno == CR_SERVER_LOST) + set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, + ER(CR_SERVER_LOST_EXTENDED), + "reading final connect information", + errno); + return 1; + } + } + } + /* + net->read_pos[0] should always be 0 here if the server implements + the protocol correctly + */ + return mysql->net.read_pos[0] != 0; +} + MYSQL * STDCALL CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, @@ -1866,7 +2545,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, uint port, const char *unix_socket,ulong client_flag) { char buff[NAME_LEN+USERNAME_LENGTH+100]; - char *end,*host_info= NULL; + int scramble_data_len, pkt_scramble_len; + char *end, *host_info=0, *server_version_end, *pkt_end; + char *scramble_data; + const char *scramble_plugin; my_socket sock; in_addr_t ip_addr; struct sockaddr_in sock_addr; @@ -1884,6 +2566,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, #endif init_sigpipe_variables DBUG_ENTER("mysql_real_connect"); + LINT_INIT(pkt_scramble_len); DBUG_PRINT("enter",("host: %s db: %s user: %s", host ? host : "(Null)", @@ -2182,8 +2865,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, errno); goto error; } + pkt_end= (char*)net->read_pos + pkt_length; /* Check if version of protocol matches current one */ - mysql->protocol_version= net->read_pos[0]; DBUG_DUMP("packet",(uchar*) net->read_pos,10); DBUG_PRINT("info",("mysql protocol version %d, server=%d", @@ -2195,31 +2878,29 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, PROTOCOL_VERSION); goto error; } - end=strend((char*) net->read_pos+1); + server_version_end= end= strend((char*) net->read_pos+1); mysql->thread_id=uint4korr(end+1); end+=5; /* - Scramble is split into two parts because old clients does not understand + Scramble is split into two parts because old clients do not understand long scrambles; here goes the first part. */ - strmake(mysql->scramble, end, SCRAMBLE_LENGTH_323); - end+= SCRAMBLE_LENGTH_323+1; + scramble_data= end; + scramble_data_len= SCRAMBLE_LENGTH_323 + 1; + scramble_plugin= old_password_plugin_name; + end+= scramble_data_len; - if (pkt_length >= (uint) (end+1 - (char*) net->read_pos)) + if (pkt_end >= end + 1) mysql->server_capabilities=uint2korr(end); - if (pkt_length >= (uint) (end+18 - (char*) net->read_pos)) + if (pkt_end >= end + 18) { /* New protocol with 16 bytes to describe server characteristics */ mysql->server_language=end[2]; mysql->server_status=uint2korr(end+3); + mysql->server_capabilities|= uint2korr(end+5) << 16; + pkt_scramble_len= end[7]; } end+= 18; - if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 - - (char *) net->read_pos)) - strmake(mysql->scramble+SCRAMBLE_LENGTH_323, end, - SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323); - else - mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION; if (mysql->options.secure_auth && passwd[0] && !(mysql->server_capabilities & CLIENT_SECURE_CONNECTION)) @@ -2238,7 +2919,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, &mysql->unix_socket,unix_socket ? (uint) strlen(unix_socket)+1 : (uint) 1, &mysql->server_version, - (uint) (end - (char*) net->read_pos), + (uint) (server_version_end - (char*) net->read_pos + 1), NullS) || !(mysql->user=my_strdup(user,MYF(0))) || !(mysql->passwd=my_strdup(passwd,MYF(0)))) @@ -2255,204 +2936,47 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, strmov(mysql->server_version,(char*) net->read_pos+1); mysql->port=port; - /* - Part 2: format and send client info to the server for access check - */ - - client_flag|=mysql->options.client_flag; - client_flag|=CLIENT_CAPABILITIES; - if (client_flag & CLIENT_MULTI_STATEMENTS) - client_flag|= CLIENT_MULTI_RESULTS; - -#ifdef HAVE_OPENSSL - if (mysql->options.ssl_key || mysql->options.ssl_cert || - mysql->options.ssl_ca || mysql->options.ssl_capath || - mysql->options.ssl_cipher) - mysql->options.use_ssl= 1; - if (mysql->options.use_ssl) - client_flag|=CLIENT_SSL; -#endif /* HAVE_OPENSSL */ - if (db) - client_flag|=CLIENT_CONNECT_WITH_DB; - - /* Remove options that server doesn't support */ - client_flag= ((client_flag & - ~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) | - (client_flag & mysql->server_capabilities)); -#ifndef HAVE_COMPRESS - client_flag&= ~CLIENT_COMPRESS; -#endif - - if (client_flag & CLIENT_PROTOCOL_41) + if (pkt_end >= end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1) { - /* 4.1 server and 4.1 client has a 32 byte option flag */ - int4store(buff,client_flag); - int4store(buff+4, net->max_packet_size); - buff[8]= (char) mysql->charset->number; - bzero(buff+9, 32-9); - end= buff+32; - } - else - { - int2store(buff,client_flag); - int3store(buff+2,net->max_packet_size); - end= buff+5; - } - mysql->client_flag=client_flag; - -#ifdef HAVE_OPENSSL - if (client_flag & CLIENT_SSL) - { - /* Do the SSL layering. */ - struct st_mysql_options *options= &mysql->options; - struct st_VioSSLFd *ssl_fd; - char error_string[1024]; - /* - Send client_flag, max_packet_size - unencrypted otherwise - the server does not know we want to do SSL + move the first scramble part - directly in the NET buffer - + to get a full continuous scramble. We've read all the header, + and can overwrite it now. */ - if (my_net_write(net, (uchar*) buff, (uint) (end-buff)) || net_flush(net)) - { - set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, - ER(CR_SERVER_LOST_EXTENDED), - "sending connection information to server", - errno); - goto error; - } - - /* Create the VioSSLConnectorFd - init SSL and load certs */ - if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key, - options->ssl_cert, - options->ssl_ca, - options->ssl_capath, - options->ssl_cipher))) - { - set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); - goto error; - } - mysql->connector_fd= (void*)ssl_fd; - - /* Connect to the server */ - DBUG_PRINT("info", ("IO layer change in progress...")); - if (sslconnect(ssl_fd, mysql->net.vio, - (long) (mysql->options.connect_timeout), - error_string)) - { - set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, - unknown_sqlstate, - "SSL error: %s", - error_string[0] ? error_string : - ER(CR_SSL_CONNECTION_ERROR)); - goto error; - } - DBUG_PRINT("info", ("IO layer change done!")); - - /* Verify server cert */ - if ((client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) && - ssl_verify_server_cert(mysql->net.vio, mysql->host)) - { - set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); - goto error; - } - - } -#endif /* HAVE_OPENSSL */ - - DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu", - mysql->server_version,mysql->server_capabilities, - mysql->server_status, client_flag)); - /* This needs to be changed as it's not useful with big packets */ - if (user && user[0]) - strmake(end,user,USERNAME_LENGTH); /* Max user name */ - else - read_user_name((char*) end); - - /* We have to handle different version of handshake here */ -#ifdef _CUSTOMCONFIG_ -#include "_cust_libmysql.h" -#endif - DBUG_PRINT("info",("user: %s",end)); - end= strend(end) + 1; - if (passwd[0]) - { - if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION) + memmove(end - SCRAMBLE_LENGTH_323, scramble_data, + SCRAMBLE_LENGTH_323); + scramble_data= end - SCRAMBLE_LENGTH_323; + if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH) { - *end++= SCRAMBLE_LENGTH; - scramble(end, mysql->scramble, passwd); - end+= SCRAMBLE_LENGTH; + scramble_data_len= pkt_scramble_len; + scramble_plugin= scramble_data + scramble_data_len; + if (scramble_data + scramble_data_len > pkt_end) + scramble_data_len= pkt_end - scramble_data; } else { - scramble_323(end, mysql->scramble, passwd); - end+= SCRAMBLE_LENGTH_323 + 1; + scramble_data_len= pkt_end - scramble_data; + scramble_plugin= native_password_plugin_name; } } else - *end++= '\0'; /* empty password */ + mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION; + + mysql->client_flag= client_flag; - /* Add database if needed */ - if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) - { - end= strmake(end, db, NAME_LEN) + 1; - mysql->db= my_strdup(db,MYF(MY_WME)); - db= 0; - } - /* Write authentication package */ - if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net)) - { - set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, - ER(CR_SERVER_LOST_EXTENDED), - "sending authentication information", - errno); - goto error; - } - /* - Part 3: Authorization data's been sent. Now server can reply with - OK-packet, or re-request scrambled password. + Part 2: invoke the plugin to send the authentication data to the server */ - if ((pkt_length=cli_safe_read(mysql)) == packet_error) - { - if (mysql->net.last_errno == CR_SERVER_LOST) - set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, - ER(CR_SERVER_LOST_EXTENDED), - "reading authorization packet", - errno); + if (run_plugin_auth(mysql, scramble_data, scramble_data_len, + scramble_plugin, db)) goto error; - } - if (pkt_length == 1 && net->read_pos[0] == 254 && - mysql->server_capabilities & CLIENT_SECURE_CONNECTION) - { - /* - By sending this very specific reply server asks us to send scrambled - password in old format. - */ - scramble_323(buff, mysql->scramble, passwd); - if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) || - net_flush(net)) - { - set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, - ER(CR_SERVER_LOST_EXTENDED), - "sending password information", - errno); - goto error; - } - /* Read what server thinks about out new auth message report */ - if (cli_safe_read(mysql) == packet_error) - { - if (mysql->net.last_errno == CR_SERVER_LOST) - set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, - ER(CR_SERVER_LOST_EXTENDED), - "reading final connect information", - errno); - goto error; - } - } + /* + Part 3: authenticated, finish the initialization of the connection + */ - if (client_flag & CLIENT_COMPRESS) /* We will use compression */ + if (mysql->client_flag & CLIENT_COMPRESS) /* We will use compression */ net->compress=1; #ifdef CHECK_LICENSE @@ -2460,7 +2984,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, goto error; #endif - if (db && mysql_select_db(mysql, db)) + if (db && !mysql->db && mysql_select_db(mysql, db)) { if (mysql->net.last_errno == CR_SERVER_LOST) set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, @@ -2526,7 +3050,7 @@ error: /* Free alloced memory */ end_server(mysql); mysql_close_free(mysql); - if (!(((ulong) client_flag) & CLIENT_REMEMBER_OPTIONS)) + if (!(client_flag & CLIENT_REMEMBER_OPTIONS)) mysql_close_free_options(mysql); } DBUG_RETURN(0); @@ -2671,6 +3195,12 @@ static void mysql_close_free_options(MYSQL *mysql) if (mysql->options.shared_memory_base_name != def_shared_memory_base_name) my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif /* HAVE_SMEM */ + if (mysql->options.extension) + { + my_free(mysql->options.extension->plugin_dir,MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->options.extension->default_auth,MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->options.extension,MYF(0)); + } bzero((char*) &mysql->options,sizeof(mysql->options)); DBUG_VOID_RETURN; } @@ -3203,6 +3733,12 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) else mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT; break; + case MYSQL_PLUGIN_DIR: + extension_set_string(&mysql->options, plugin_dir, arg); + break; + case MYSQL_DEFAULT_AUTH: + extension_set_string(&mysql->options, default_auth, arg); + break; default: DBUG_RETURN(1); } @@ -3279,7 +3815,7 @@ mysql_get_server_version(MYSQL *mysql) */ int STDCALL mysql_set_character_set(MYSQL *mysql, const char *cs_name) { - struct charset_info_st *cs; + CHARSET_INFO *cs; const char *save_csdir= charsets_dir; if (mysql->options.charset_dir) @@ -3311,3 +3847,99 @@ int STDCALL mysql_set_character_set(MYSQL *mysql, const char *cs_name) } +/** + client authentication plugin that does native MySQL authentication + using a 20-byte (4.1+) scramble +*/ + +static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) +{ + int pkt_len; + uchar *pkt; + + if (((MCPVIO_EXT *)vio)->mysql_change_user) + { + /* + in mysql_change_user() the client sends the first packet. + we use the old scramble. + */ + pkt= (uchar*)mysql->scramble; + pkt_len= SCRAMBLE_LENGTH + 1; + } + else + { + /* read the scramble */ + if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) + return CR_ERROR; + + if (pkt_len != SCRAMBLE_LENGTH + 1) + return CR_SERVER_HANDSHAKE_ERR; + + /* save it in MYSQL */ + memcpy(mysql->scramble, pkt, SCRAMBLE_LENGTH); + mysql->scramble[SCRAMBLE_LENGTH] = 0; + } + + if (mysql->passwd[0]) + { + char scrambled[SCRAMBLE_LENGTH + 1]; + scramble(scrambled, (char*)pkt, mysql->passwd); + if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH)) + return CR_ERROR; + } + else + if (vio->write_packet(vio, 0, 0)) /* no password */ + return CR_ERROR; + + return CR_OK; +} + + +/** + client authentication plugin that does old MySQL authentication + using an 8-byte (4.0-) scramble +*/ + +static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) +{ + uchar *pkt; + int pkt_len; + + if (((MCPVIO_EXT *)vio)->mysql_change_user) + { + /* + in mysql_change_user() the client sends the first packet. + we use the old scramble. + */ + pkt= (uchar*)mysql->scramble; + pkt_len= SCRAMBLE_LENGTH_323 + 1; + } + else + { + /* read the scramble */ + if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) + return CR_ERROR; + + if (pkt_len != SCRAMBLE_LENGTH_323 + 1 && + pkt_len != SCRAMBLE_LENGTH + 1) + return CR_SERVER_HANDSHAKE_ERR; + + /* save it in MYSQL */ + memcpy(mysql->scramble, pkt, pkt_len); + mysql->scramble[pkt_len] = 0; + } + + if (mysql->passwd[0]) + { + char scrambled[SCRAMBLE_LENGTH_323 + 1]; + scramble_323(scrambled, (char*)pkt, mysql->passwd); + if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH_323 + 1)) + return CR_ERROR; + } + else + if (vio->write_packet(vio, 0, 0)) /* no password */ + return CR_ERROR; + + return CR_OK; +} + diff --git a/sql-common/client_plugin.c b/sql-common/client_plugin.c new file mode 100644 index 00000000000..0b1bdeae0be --- /dev/null +++ b/sql-common/client_plugin.c @@ -0,0 +1,447 @@ +/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + + Support code for the client side (libmysql) plugins + + Client plugins are somewhat different from server plugins, they are simpler. + + They do not need to be installed or in any way explicitly loaded on the + client, they are loaded automatically on demand. + One client plugin per shared object, soname *must* match the plugin name. + + There is no reference counting and no unloading either. +*/ + +#if _MSC_VER +/* Silence warnings about variable 'unused' being used. */ +#define FORCE_INIT_OF_VARS 1 +#endif + +#include <my_global.h> +#include "mysql.h" +#include <my_sys.h> +#include <m_string.h> +#ifdef THREAD +#include <my_pthread.h> +#else +#include <my_no_pthread.h> +#endif + +#include <sql_common.h> +#include "errmsg.h" +#include <mysql/client_plugin.h> + +struct st_client_plugin_int { + struct st_client_plugin_int *next; + void *dlhandle; + struct st_mysql_client_plugin *plugin; +}; + +static my_bool initialized= 0; +static MEM_ROOT mem_root; + +static const char *plugin_declarations_sym __attribute__((unused)) = + "_mysql_client_plugin_declaration_"; +static uint plugin_version[MYSQL_CLIENT_MAX_PLUGINS]= +{ + 0, /* these two are taken by Connector/C */ + 0, /* these two are taken by Connector/C */ + MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION +}; + +/* + Loaded plugins are stored in a linked list. + The list is append-only, the elements are added to the head (like in a stack). + The elements are added under a mutex, but the list can be read and traversed + without any mutex because once an element is added to the list, it stays + there. The main purpose of a mutex is to prevent two threads from + loading the same plugin twice in parallel. +*/ +struct st_client_plugin_int *plugin_list[MYSQL_CLIENT_MAX_PLUGINS]; +#ifdef THREAD +static pthread_mutex_t LOCK_load_client_plugin; +#endif + +static int is_not_initialized(MYSQL *mysql, const char *name) +{ + if (initialized) + return 0; + + set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, + unknown_sqlstate, ER(CR_AUTH_PLUGIN_CANNOT_LOAD), + name, "not initialized"); + return 1; +} + + +/** + finds a plugin in the list + + @param name plugin name to search for + @param type plugin type + + @note this does NOT necessarily need a mutex, take care! + + @retval a pointer to a found plugin or 0 +*/ + +static struct st_mysql_client_plugin *find_plugin(const char *name, int type) +{ + struct st_client_plugin_int *p; + + DBUG_ASSERT(initialized); + DBUG_ASSERT(type >= 0 && type < MYSQL_CLIENT_MAX_PLUGINS); + if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS) + return 0; + + for (p= plugin_list[type]; p; p= p->next) + { + if (strcmp(p->plugin->name, name) == 0) + return p->plugin; + } + return NULL; +} + + +/** + verifies the plugin and adds it to the list + + @param mysql MYSQL structure (for error reporting) + @param plugin plugin to install + @param dlhandle a handle to the shared object (returned by dlopen) + or 0 if the plugin was not dynamically loaded + @param argc number of arguments in the 'va_list args' + @param args arguments passed to the plugin initialization function + + @retval a pointer to an installed plugin or 0 +*/ + +static struct st_mysql_client_plugin * +add_plugin(MYSQL *mysql, struct st_mysql_client_plugin *plugin, void *dlhandle, + int argc, va_list args) +{ + const char *errmsg; + struct st_client_plugin_int plugin_int, *p; + char errbuf[1024]; + + DBUG_ASSERT(initialized); + + plugin_int.plugin= plugin; + plugin_int.dlhandle= dlhandle; + + if (plugin->type >= MYSQL_CLIENT_MAX_PLUGINS) + { + errmsg= "Unknown client plugin type"; + goto err1; + } + + if (plugin->interface_version < plugin_version[plugin->type] || + (plugin->interface_version >> 8) > + (plugin_version[plugin->type] >> 8)) + { + errmsg= "Incompatible client plugin interface"; + goto err1; + } + + /* Call the plugin initialization function, if any */ + if (plugin->init && plugin->init(errbuf, sizeof(errbuf), argc, args)) + { + errmsg= errbuf; + goto err1; + } + + p= (struct st_client_plugin_int *) + memdup_root(&mem_root, &plugin_int, sizeof(plugin_int)); + + if (!p) + { + errmsg= "Out of memory"; + goto err2; + } + + safe_mutex_assert_owner(&LOCK_load_client_plugin); + + p->next= plugin_list[plugin->type]; + plugin_list[plugin->type]= p; + + return plugin; + +err2: + if (plugin->deinit) + plugin->deinit(); +err1: + if (dlhandle) + (void)dlclose(dlhandle); + set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate, + ER(CR_AUTH_PLUGIN_CANNOT_LOAD), plugin->name, + errmsg); + return NULL; +} + + +/** + Loads plugins which are specified in the environment variable + LIBMYSQL_PLUGINS. + + Multiple plugins must be separated by semicolon. This function doesn't + return or log an error. + + The function is be called by mysql_client_plugin_init + + @todo + Support extended syntax, passing parameters to plugins, for example + LIBMYSQL_PLUGINS="plugin1(param1,param2);plugin2;..." + or + LIBMYSQL_PLUGINS="plugin1=int:param1,str:param2;plugin2;..." +*/ + +static void load_env_plugins(MYSQL *mysql) +{ + char *plugs, *free_env, *s= getenv("LIBMYSQL_PLUGINS"); + + /* no plugins to load */ + if (!s) + return; + + free_env= plugs= my_strdup(s, MYF(MY_WME)); + + do { + if ((s= strchr(plugs, ';'))) + *s= '\0'; + mysql_load_plugin(mysql, plugs, -1, 0); + plugs= s + 1; + } while (s); + + my_free(free_env, MYF(0)); +} + +/********** extern functions to be used by libmysql *********************/ + +/** + Initializes the client plugin layer. + + This function must be called before any other client plugin function. + + @retval 0 successful + @retval != 0 error occured +*/ + +int mysql_client_plugin_init() +{ + MYSQL mysql; + struct st_mysql_client_plugin **builtin; + va_list unused; + LINT_INIT_STRUCT(unused); + + if (initialized) + return 0; + + bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */ + + pthread_mutex_init(&LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW); + init_alloc_root(&mem_root, 128, 128); + + bzero(&plugin_list, sizeof(plugin_list)); + + initialized= 1; + + pthread_mutex_lock(&LOCK_load_client_plugin); + + for (builtin= mysql_client_builtins; *builtin; builtin++) + add_plugin(&mysql, *builtin, 0, 0, unused); + + pthread_mutex_unlock(&LOCK_load_client_plugin); + + load_env_plugins(&mysql); + + return 0; +} + + +/** + Deinitializes the client plugin layer. + + Unloades all client plugins and frees any associated resources. +*/ + +void mysql_client_plugin_deinit() +{ + int i; + struct st_client_plugin_int *p; + + if (!initialized) + return; + + for (i=0; i < MYSQL_CLIENT_MAX_PLUGINS; i++) + for (p= plugin_list[i]; p; p= p->next) + { + if (p->plugin->deinit) + p->plugin->deinit(); + if (p->dlhandle) + (void)dlclose(p->dlhandle); + } + + bzero(&plugin_list, sizeof(plugin_list)); + initialized= 0; + free_root(&mem_root, MYF(0)); + pthread_mutex_destroy(&LOCK_load_client_plugin); +} + +/************* public facing functions, for client consumption *********/ + +/* see <mysql/client_plugin.h> for a full description */ +struct st_mysql_client_plugin * +mysql_client_register_plugin(MYSQL *mysql, + struct st_mysql_client_plugin *plugin) +{ + va_list unused; + LINT_INIT_STRUCT(unused); + + if (is_not_initialized(mysql, plugin->name)) + return NULL; + + pthread_mutex_lock(&LOCK_load_client_plugin); + + /* make sure the plugin wasn't loaded meanwhile */ + if (find_plugin(plugin->name, plugin->type)) + { + set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, + unknown_sqlstate, ER(CR_AUTH_PLUGIN_CANNOT_LOAD), + plugin->name, "it is already loaded"); + plugin= NULL; + } + else + plugin= add_plugin(mysql, plugin, 0, 0, unused); + + pthread_mutex_unlock(&LOCK_load_client_plugin); + return plugin; +} + + +/* see <mysql/client_plugin.h> for a full description */ +struct st_mysql_client_plugin * +mysql_load_plugin_v(MYSQL *mysql, const char *name, int type, + int argc, va_list args) +{ + const char *errmsg; + char dlpath[FN_REFLEN+1]; + void *sym, *dlhandle; + struct st_mysql_client_plugin *plugin; + + if (is_not_initialized(mysql, name)) + return NULL; + + pthread_mutex_lock(&LOCK_load_client_plugin); + + /* make sure the plugin wasn't loaded meanwhile */ + if (type >= 0 && find_plugin(name, type)) + { + errmsg= "it is already loaded"; + goto err; + } + + /* Compile dll path */ + strxnmov(dlpath, sizeof(dlpath) - 1, + mysql->options.extension && mysql->options.extension->plugin_dir ? + mysql->options.extension->plugin_dir : PLUGINDIR, "/", + name, SO_EXT, NullS); + + /* Open new dll handle */ + if (!(dlhandle= dlopen(dlpath, RTLD_NOW))) + { + errmsg= dlerror(); + goto err; + } + + if (!(sym= dlsym(dlhandle, plugin_declarations_sym))) + { + errmsg= "not a plugin"; + (void)dlclose(dlhandle); + goto err; + } + + plugin= (struct st_mysql_client_plugin*)sym; + + if (type >=0 && type != plugin->type) + { + errmsg= "type mismatch"; + goto err; + } + + if (strcmp(name, plugin->name)) + { + errmsg= "name mismatch"; + goto err; + } + + if (type < 0 && find_plugin(name, plugin->type)) + { + errmsg= "it is already loaded"; + goto err; + } + + plugin= add_plugin(mysql, plugin, dlhandle, argc, args); + + pthread_mutex_unlock(&LOCK_load_client_plugin); + + return plugin; + +err: + pthread_mutex_unlock(&LOCK_load_client_plugin); + set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate, + ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, errmsg); + return NULL; +} + + +/* see <mysql/client_plugin.h> for a full description */ +struct st_mysql_client_plugin * +mysql_load_plugin(MYSQL *mysql, const char *name, int type, int argc, ...) +{ + struct st_mysql_client_plugin *p; + va_list args; + va_start(args, argc); + p= mysql_load_plugin_v(mysql, name, type, argc, args); + va_end(args); + return p; +} + + +/* see <mysql/client_plugin.h> for a full description */ +struct st_mysql_client_plugin * +mysql_client_find_plugin(MYSQL *mysql, const char *name, int type) +{ + struct st_mysql_client_plugin *p; + + if (is_not_initialized(mysql, name)) + return NULL; + + if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS) + { + set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate, + ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, + "invalid type"); + } + + if ((p= find_plugin(name, type))) + return p; + + /* not found, load it */ + return mysql_load_plugin(mysql, name, type, 0); +} + diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 535f53335be..e281b187149 100755 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -21,17 +21,19 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/regex ${CMAKE_SOURCE_DIR}/zlib - ${CMAKE_SOURCE_DIR}/extra/libevent + ${CMAKE_SOURCE_DIR}/extra/libevent + ${CMAKE_BINARY_DIR}/extra/libevent + ${CMAKE_CURRENT_BINARY_DIR} ) -SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/sql/sql_yacc.h - ${CMAKE_SOURCE_DIR}/sql/sql_yacc.cc - ${CMAKE_SOURCE_DIR}/include/mysql_version.h - ${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc - ${CMAKE_SOURCE_DIR}/sql/lex_hash.h - ${PROJECT_SOURCE_DIR}/include/mysqld_error.h - ${PROJECT_SOURCE_DIR}/include/mysqld_ername.h - ${PROJECT_SOURCE_DIR}/include/sql_state.h +SET_SOURCE_FILES_PROPERTIES(${CMAKE_BINARY_DIR}/sql/sql_yacc.h + ${CMAKE_BINARY_DIR}/sql/sql_yacc.cc + ${CMAKE_BINARY_DIR}/include/mysql_version.h + ${CMAKE_BINARY_DIR}/sql/sql_builtin.cc + ${CMAKE_BINARY_DIR}/sql/lex_hash.h + ${CMAKE_BINARY_DIR}/include/mysqld_error.h + ${CMAKE_BINARY_DIR}/include/mysqld_ername.h + ${CMAKE_BINARY_DIR}/include/sql_state.h PROPERTIES GENERATED 1) ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_DLOPEN -DHAVE_EVENT_SCHEDULER) @@ -44,7 +46,7 @@ SET (SQL_SOURCE discover.cc ../libmysql/errmsg.c field.cc field_conv.cc filesort.cc gstream.cc ha_partition.cc - handler.cc hash_filo.cc hash_filo.h + handler.cc hash_filo.cc hash_filo.h sql_plugin_services.h hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc item_create.cc item_func.cc item_geofunc.cc item_row.cc item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.cc @@ -52,7 +54,7 @@ SET (SQL_SOURCE log_event.cc rpl_record.cc rpl_reporting.cc log_event_old.cc rpl_record_old.cc message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c - mysqld.cc net_serv.cc + mysqld.cc net_serv.cc ../sql-common/client_plugin.c nt_servc.cc nt_servc.h opt_range.cc opt_range.h opt_sum.cc ../sql-common/pack.c parse_file.cc password.c procedure.cc protocol.cc records.cc repl_failsafe.cc rpl_filter.cc set_var.cc @@ -75,20 +77,23 @@ SET (SQL_SOURCE rpl_rli.cc rpl_mi.cc sql_servers.cc sql_connect.cc scheduler.cc sql_profile.cc event_parse_data.cc opt_table_elimination.cc - ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc - ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h - ${PROJECT_SOURCE_DIR}/include/mysqld_error.h - ${PROJECT_SOURCE_DIR}/include/mysqld_ername.h - ${PROJECT_SOURCE_DIR}/include/sql_state.h - ${PROJECT_SOURCE_DIR}/include/mysql_version.h - ${PROJECT_SOURCE_DIR}/sql/sql_builtin.cc - ${PROJECT_SOURCE_DIR}/sql/lex_hash.h) + create_options.cc + ${CMAKE_BINARY_DIR}/sql/sql_yacc.cc + ${CMAKE_BINARY_DIR}/sql/sql_yacc.h + ${CMAKE_BINARY_DIR}/include/mysqld_error.h + ${CMAKE_BINARY_DIR}/include/mysqld_ername.h + ${CMAKE_BINARY_DIR}/include/sql_state.h + ${CMAKE_BINARY_DIR}/include/mysql_version.h + ${CMAKE_BINARY_DIR}/sql/sql_builtin.cc + ${CMAKE_BINARY_DIR}/sql/lex_hash.h) ADD_LIBRARY(sql ${SQL_SOURCE}) -IF (NOT EXISTS cmake_dummy.cc) - FILE (WRITE cmake_dummy.cc "") -ENDIF (NOT EXISTS cmake_dummy.cc) -ADD_EXECUTABLE(mysqld cmake_dummy.cc message.rc) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/win/cmake/dummy.in cmake_dummy.cc COPYONLY) +MYSQL_ADD_EXECUTABLE(mysqld cmake_dummy.cc message.rc DESTINATION ${INSTALL_SBINDIR} COMPONENT Server) +INSTALL_DEBUG_TARGET(mysqld + DESTINATION ${INSTALL_SBINDIR} + PDB_DESTINATION ${INSTALL_SBINDIR}/debug + RENAME mysqld-debug) SET_TARGET_PROPERTIES(mysqld PROPERTIES OUTPUT_NAME mysqld${MYSQLD_EXE_SUFFIX}) SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE) @@ -112,17 +117,17 @@ IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS) ADD_CUSTOM_COMMAND(TARGET mysqld PRE_LINK COMMAND cscript ARGS //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js ${PLATFORM} ${LIB_LOCATIONS} > mysqld.def - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/sql) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) ENDIF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS) ADD_DEPENDENCIES(sql GenError) # Sql Parser custom command ADD_CUSTOM_COMMAND( - OUTPUT ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h - ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc + OUTPUT ${CMAKE_BINARY_DIR}/sql/sql_yacc.h + ${CMAKE_BINARY_DIR}/sql/sql_yacc.cc COMMAND bison ARGS -y -p MYSQL --defines=sql_yacc.h - --output=sql_yacc.cc sql_yacc.yy + --output=sql_yacc.cc "${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.yy" DEPENDS ${PROJECT_SOURCE_DIR}/sql/sql_yacc.yy) @@ -131,17 +136,15 @@ ADD_EXECUTABLE(gen_lex_hash gen_lex_hash.cc) TARGET_LINK_LIBRARIES(gen_lex_hash debug dbug mysqlclient strings wsock32) GET_TARGET_PROPERTY(GEN_LEX_HASH_EXE gen_lex_hash LOCATION) ADD_CUSTOM_COMMAND( - OUTPUT ${PROJECT_SOURCE_DIR}/sql/lex_hash.h + OUTPUT ${CMAKE_BINARY_DIR}/sql/lex_hash.h COMMAND ${GEN_LEX_HASH_EXE} ARGS > lex_hash.h DEPENDS ${GEN_LEX_HASH_EXE}) ADD_CUSTOM_TARGET( GenServerSource ALL - DEPENDS ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h - ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc - ${PROJECT_SOURCE_DIR}/sql/message.h - ${PROJECT_SOURCE_DIR}/sql/message.rc - ${PROJECT_SOURCE_DIR}/sql/lex_hash.h) + DEPENDS ${CMAKE_BINARY_DIR}/sql/sql_yacc.h + ${CMAKE_BINARY_DIR}/sql/sql_yacc.cc + ${CMAKE_BINARY_DIR}/sql/lex_hash.h) ADD_DEPENDENCIES(sql GenServerSource) @@ -153,7 +156,91 @@ ADD_LIBRARY(udf_example MODULE udf_example.c udf_example.def) ADD_DEPENDENCIES(udf_example strings GenError) TARGET_LINK_LIBRARIES(udf_example strings wsock32) -INSTALL(TARGETS mysqld - RUNTIME DESTINATION bin COMPONENT runtime - LIBRARY DESTINATION lib COMPONENT runtime - ARCHIVE DESTINATION lib COMPONENT runtime) +ADD_SUBDIRECTORY(share) + +IF(WIN32) + SET(my_bootstrap_sql ${CMAKE_CURRENT_BINARY_DIR}/my_bootstrap.sql) + FILE(TO_NATIVE_PATH ${my_bootstrap_sql} native_outfile) + + # Create bootstrapper SQL script + ADD_CUSTOM_COMMAND(OUTPUT + ${my_bootstrap_sql} + COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_SOURCE_DIR}/scripts + cmd /c copy mysql_system_tables.sql+mysql_system_tables_data.sql+fill_help_tables.sql ${native_outfile} + DEPENDS + ${CMAKE_SOURCE_DIR}/scripts/mysql_system_tables.sql + ${CMAKE_SOURCE_DIR}/scripts/mysql_system_tables_data.sql + ${CMAKE_SOURCE_DIR}/scripts/fill_help_tables.sql + ) + +ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mysql_bootstrap_sql.c + COMMAND comp_sql + mysql_bootstrap_sql + ${CMAKE_CURRENT_BINARY_DIR}/my_bootstrap.sql + mysql_bootstrap_sql.c + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS comp_sql ${my_bootstrap_sql}) + + MYSQL_ADD_EXECUTABLE(mysql_install_db + mysql_install_db.cc + ${CMAKE_CURRENT_BINARY_DIR}/mysql_bootstrap_sql.c + COMPONENT Server) + TARGET_LINK_LIBRARIES(mysql_install_db mysys strings dbug) + + ADD_LIBRARY(winservice STATIC winservice.c) + + MYSQL_ADD_EXECUTABLE(mysql_upgrade_service + mysql_upgrade_service.cc + COMPONENT Server) + + TARGET_LINK_LIBRARIES(mysql_upgrade_service mysys strings dbug winservice) + + # mysql_install_db should be in the same directory as mysqld + # to work correctly + GET_TARGET_PROPERTY(MYSQLD_EXECUTABLE mysqld LOCATION) + IF(NOT MYSQLD_EXECUTABLE) + MESSAGE(FATAL_ERROR "Unexpected") + ENDIF() +ENDIF() + +# We need to create empty directories (data/test) the installation. +# This does not work with current CPack due to http://www.cmake.org/Bug/view.php?id=8767 +# Avoid completely empty directories and install dummy file instead. +SET(DUMMY_FILE ${CMAKE_CURRENT_BINARY_DIR}/.empty ) +FILE(WRITE ${DUMMY_FILE} "") +INSTALL(FILES ${DUMMY_FILE} DESTINATION data/test COMPONENT DataFiles) + +# Install initial database on windows +IF(NOT CMAKE_CROSSCOMPILING) + GET_TARGET_PROPERTY(MYSQLD_EXECUTABLE mysqld LOCATION) +ENDIF() +IF(WIN32 AND MYSQLD_EXECUTABLE) + CONFIGURE_FILE( + ${CMAKE_SOURCE_DIR}/win/cmake/create_initial_db.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/create_initial_db.cmake + @ONLY + ) + + IF(MSVC_IDE OR CMAKE_GENERATOR MATCHES "Xcode") + SET (CONFIG_PARAM -DCONFIG=${CMAKE_CFG_INTDIR}) + ENDIF() + MAKE_DIRECTORY(${CMAKE_CURRENT_BINARY_DIR}/data) + ADD_CUSTOM_COMMAND( + OUTPUT initdb.dep + COMMAND ${CMAKE_COMMAND} + ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_initial_db.cmake + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep + DEPENDS mysqld + ) + ADD_CUSTOM_TARGET(initial_database + ALL + DEPENDS initdb.dep + ) + INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data DESTINATION . + COMPONENT DataFiles PATTERN "initdb.dep" EXCLUDE PATTERN "bootstrap.sql" EXCLUDE) +ELSE() + # Not windows or cross compiling, just install an empty directory + INSTALL(FILES ${DUMMY_FILE} DESTINATION data/mysql COMPONENT DataFiles) +ENDIF() diff --git a/sql/Makefile.am b/sql/Makefile.am index c413f8ce771..181924e9cec 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -49,7 +49,7 @@ mysqld_LDADD = libndb.la \ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ item_strfunc.h item_timefunc.h \ - item_xmlfunc.h \ + item_xmlfunc.h sql_plugin_services.h \ item_create.h item_subselect.h item_row.h \ mysql_priv.h item_geofunc.h sql_bitmap.h \ procedure.h sql_class.h sql_lex.h sql_list.h \ @@ -78,7 +78,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ sql_plugin.h authors.h event_parse_data.h \ event_data_objects.h event_scheduler.h \ sql_partition.h partition_info.h partition_element.h \ - contributors.h sql_servers.h + contributors.h sql_servers.h \ + create_options.h mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ @@ -124,9 +125,9 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ sql_plugin.cc sql_binlog.cc \ sql_builtin.cc sql_tablespace.cc partition_info.cc \ sql_servers.cc event_parse_data.cc \ - opt_table_elimination.cc + opt_table_elimination.cc create_options.cc -nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c +nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c client_plugin.c libndb_la_CPPFLAGS= @ndbcluster_includes@ libndb_la_SOURCES= ha_ndbcluster.cc \ @@ -140,18 +141,19 @@ mysql_tzinfo_to_sql_SOURCES = tztime.cc mysql_tzinfo_to_sql_CXXFLAGS= -DTZINFO2SQL DEFS = -DMYSQL_SERVER \ - -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ - -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ - -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ - -DPLUGINDIR="\"$(pkgplugindir)\"" \ + -DDEFAULT_MYSQL_HOME='"$(MYSQLBASEdir)"' \ + -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \ + -DSHAREDIR='"$(MYSQLSHAREdir)"' \ + -DPLUGINDIR='"$(pkgplugindir)"' \ -DHAVE_EVENT_SCHEDULER \ @DEFS@ BUILT_MAINT_SRC = sql_yacc.cc sql_yacc.h BUILT_SOURCES = $(BUILT_MAINT_SRC) lex_hash.h link_sources EXTRA_DIST = udf_example.c udf_example.def $(BUILT_MAINT_SRC) \ - nt_servc.cc nt_servc.h \ + nt_servc.cc nt_servc.h mysql_install_db.cc mysql_upgrade_service.cc \ message.mc message.h message.rc MSG00001.bin \ + winservice.c winservice.h \ CMakeLists.txt CLEANFILES = lex_hash.h sql_yacc.output link_sources @@ -167,6 +169,8 @@ link_sources: @LN_CP_F@ $(top_srcdir)/sql-common/pack.c pack.c rm -f client.c @LN_CP_F@ $(top_srcdir)/sql-common/client.c client.c + rm -f client_plugin.c + @LN_CP_F@ $(top_srcdir)/sql-common/client_plugin.c client_plugin.c rm -f my_time.c @LN_CP_F@ $(top_srcdir)/sql-common/my_time.c my_time.c rm -f my_user.c diff --git a/sql/authors.h b/sql/authors.h index 9f88b97c3ad..3925696d640 100644 --- a/sql/authors.h +++ b/sql/authors.h @@ -36,23 +36,35 @@ struct show_table_authors_st { */ struct show_table_authors_st show_table_authors[]= { + { "Michael (Monty) Widenius", "Tusby, Finland", + "Lead developer and main author" }, + { "David Axmark", "London, England", + "MySQL founder; Small stuff long time ago, Monty ripped it out!" }, + { "Sergei Golubchik", "Kerpen, Germany", + "Full-text search, precision math" }, + { "Igor Babaev", "Bellevue, USA", "Optimizer, keycache, core work"}, + { "Sergey Petrunia", "St. Petersburg, Russia", "Optimizer"}, + { "Oleksandr Byelkin", "Lugansk, Ukraine", + "Query Cache (4.0), Subqueries (4.1), Views (5.0)" }, { "Brian (Krow) Aker", "Seattle, WA, USA", "Architecture, archive, federated, bunch of little stuff :)" }, - { "Venu Anuganti", "", "Client/server protocol (4.1)" }, - { "David Axmark", "Uppsala, Sweden", - "Small stuff long time ago, Monty ripped it out!" }, + { "Kristian Nielsen", "Copenhagen, Denmark", + "General build stuff," }, { "Alexander (Bar) Barkov", "Izhevsk, Russia", "Unicode and character sets (4.1)" }, + { "Guilhem Bichot", "Bordeaux, France", "Replication (since 4.0)" }, + { "Venu Anuganti", "", "Client/server protocol (4.1)" }, + { "Konstantin Osipov", "Moscow, Russia", + "Prepared statements (4.1), Cursors (5.0)" }, + { "Dmitri Lenev", "Moscow, Russia", + "Time zones support (4.1), Triggers (5.0)" }, { "Omer BarNir", "Sunnyvale, CA, USA", "Testing (sometimes) and general QA stuff" }, - { "Guilhem Bichot", "Bordeaux, France", "Replication (since 4.0)" }, { "John Birrell", "", "Emulation of pthread_mutex() for OS/2" }, { "Andreas F. Bobak", "", "AGGREGATE extension to user-defined functions" }, { "Alexey Botchkov (Holyfoot)", "Izhevsk, Russia", "GIS extensions (4.1), embedded server (4.1), precision math (5.0)"}, { "Reggie Burnett", "Nashville, TN, USA", "Windows development, Connectors" }, - { "Oleksandr Byelkin", "Lugansk, Ukraine", - "Query Cache (4.0), Subqueries (4.1), Views (5.0)" }, { "Kent Boortz", "Orebro, Sweden", "Test platform, and general build stuff" }, { "Tim Bunce", "", "mysqlhotcopy" }, { "Yves Carlier", "", "mysqlaccess" }, @@ -69,8 +81,6 @@ struct show_table_authors_st show_table_authors[]= { { "Yuri Dario", "", "OS/2 port" }, { "Andrei Elkin", "Espoo, Finland", "Replication" }, { "Patrick Galbraith", "Sharon, NH", "Federated Engine, mysqlslap" }, - { "Sergei Golubchik", "Kerpen, Germany", - "Full-text search, precision math" }, { "Lenz Grimmer", "Hamburg, Germany", "Production (build and release) engineering" }, { "Nikolay Grishakin", "Austin, TX, USA", "Testing - Server" }, @@ -86,8 +96,6 @@ struct show_table_authors_st show_table_authors[]= { { "Hakan Küçükyılmaz", "Walldorf, Germany", "Testing - Server" }, { "Greg (Groggy) Lehey", "Uchunga, SA, Australia", "Backup" }, { "Matthias Leich", "Berlin, Germany", "Testing - Server" }, - { "Dmitri Lenev", "Moscow, Russia", - "Time zones support (4.1), Triggers (5.0)" }, { "Arjen Lentz", "Brisbane, Australia", "Documentation (2001-2004), Dutch error messages, LOG2()" }, { "Marc Liyanage", "", "Created Mac OS X packages" }, @@ -99,8 +107,6 @@ struct show_table_authors_st show_table_authors[]= { { "Jonathan (Jeb) Miller", "Kyle, TX, USA", "Testing - Cluster, Replication" }, { "Elliot Murphy", "Cocoa, FL, USA", "Replication and backup" }, - { "Kristian Nielsen", "Copenhagen, Denmark", - "General build stuff" }, { "Pekka Nouisiainen", "Stockholm, Sweden", "NDB Cluster: BLOB support, character set support, ordered indexes" }, { "Alexander Nozdrin", "Moscow, Russia", @@ -108,8 +114,6 @@ struct show_table_authors_st show_table_authors[]= { { "Per Eric Olsson", "", "Testing of dynamic record format" }, { "Jonas Oreland", "Stockholm, Sweden", "NDB Cluster, Online Backup, lots of other things" }, - { "Konstantin Osipov", "Moscow, Russia", - "Prepared statements (4.1), Cursors (5.0)" }, { "Alexander (Sasha) Pachev", "Provo, UT, USA", "Statement-based replication, SHOW CREATE TABLE, mysql-bench" }, { "Irena Pancirov", "", "Port to Windows with Borland compiler" }, @@ -147,9 +151,9 @@ struct show_table_authors_st show_table_authors[]= { { "Sergey Vojtovich", "Izhevsk, Russia", "Plugins infrastructure (5.1)" }, { "Matt Wagner", "Northfield, MN, USA", "Bug fixing" }, { "Jim Winstead Jr.", "Los Angeles, CA, USA", "Bug fixing" }, - { "Michael (Monty) Widenius", "Tusby, Finland", - "Lead developer and main author" }, { "Peter Zaitsev", "Tacoma, WA, USA", "SHA1(), AES_ENCRYPT(), AES_DECRYPT(), bug fixing" }, + {"Mark Mark Callaghan", "Texas, USA", "Statistics patches"}, + {"Percona", "CA, USA", "Microslow patches"}, {NULL, NULL, NULL} }; diff --git a/sql/client_settings.h b/sql/client_settings.h index a0bece9949f..a76955cd0f7 100644 --- a/sql/client_settings.h +++ b/sql/client_settings.h @@ -18,6 +18,7 @@ #include <thr_alarm.h> +#include <sql_common.h> #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \ CLIENT_SECURE_CONNECTION | CLIENT_TRANSACTIONS | \ @@ -31,10 +32,10 @@ #define mysql_master_send_query(A, B, C) 1 #define mysql_slave_send_query(A, B, C) 1 #define mysql_rpl_probe(mysql) 0 -#undef HAVE_SMEM #undef _CUSTOMCONFIG_ -#define mysql_server_init(a,b,c) 0 +#define mysql_server_init(a,b,c) mysql_client_plugin_init() +#define mysql_server_end() mysql_client_plugin_deinit() #ifdef HAVE_REPLICATION C_MODE_START diff --git a/sql/create_options.cc b/sql/create_options.cc new file mode 100644 index 00000000000..42c69436897 --- /dev/null +++ b/sql/create_options.cc @@ -0,0 +1,616 @@ +/* Copyright (C) 2010 Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + + Engine defined options of tables/fields/keys in CREATE/ALTER TABLE. +*/ + +#include "mysql_priv.h" +#include "create_options.h" +#include <my_getopt.h> + +#define FRM_QUOTED_VALUE 0x8000 + +/** + Links this item to the given list end + + @param start The list beginning or NULL + @param end The list last element or does not matter +*/ + +void engine_option_value::link(engine_option_value **start, + engine_option_value **end) +{ + DBUG_ENTER("engine_option_value::link"); + DBUG_PRINT("enter", ("name: '%s' (%u) value: '%s' (%u)", + name.str, (uint) name.length, + value.str, (uint) value.length)); + engine_option_value *opt; + /* check duplicates to avoid writing them to frm*/ + for(opt= *start; + opt && ((opt->parsed && !opt->value.str) || + my_strnncoll(system_charset_info, + (uchar *)name.str, name.length, + (uchar*)opt->name.str, opt->name.length)); + opt= opt->next) /* no-op */; + if (opt) + { + opt->value.str= NULL; /* remove previous value */ + opt->parsed= TRUE; /* and don't issue warnings for it anymore */ + } + /* + Add this option to the end of the list + + @note: We add even if it is opt->value.str == NULL because it can be + ALTER TABLE to remove the option. + */ + if (*start) + { + (*end)->next= this; + *end= this; + } + else + { + /* + note that is *start == 0, the value of *end does not matter, + it can be uninitialized. + */ + *start= *end= this; + } + DBUG_VOID_RETURN; +} + +static bool report_wrong_value(THD *thd, const char *name, const char *val, + my_bool suppress_warning) +{ + if (suppress_warning) + return 0; + + if (!(thd->variables.sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS) && + !thd->slave_thread) + { + my_error(ER_BAD_OPTION_VALUE, MYF(0), val, name); + return 1; + } + + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_OPTION_VALUE, + ER(ER_BAD_OPTION_VALUE), val, name); + return 0; +} + +static bool report_unknown_option(THD *thd, engine_option_value *val, + my_bool suppress_warning) +{ + DBUG_ENTER("report_unknown_option"); + + if (val->parsed || suppress_warning) + { + DBUG_PRINT("info", ("parsed => exiting")); + DBUG_RETURN(FALSE); + } + + if (!(thd->variables.sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS) && + !thd->slave_thread) + { + my_error(ER_UNKNOWN_OPTION, MYF(0), val->name.str); + DBUG_RETURN(TRUE); + } + + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_UNKNOWN_OPTION, ER(ER_UNKNOWN_OPTION), val->name.str); + DBUG_RETURN(FALSE); +} + +static bool set_one_value(ha_create_table_option *opt, + THD *thd, LEX_STRING *value, void *base, + my_bool suppress_warning, + MEM_ROOT *root) +{ + DBUG_ENTER("set_one_value"); + DBUG_PRINT("enter", ("opt: 0x%lx type: %u name '%s' value: '%s'", + (ulong) opt, + opt->type, opt->name, + (value->str ? value->str : "<DEFAULT>"))); + switch (opt->type) + { + case HA_OPTION_TYPE_ULL: + { + ulonglong *val= (ulonglong*)((char*)base + opt->offset); + if (!value->str) + { + *val= opt->def_value; + DBUG_RETURN(0); + } + + my_option optp= + { opt->name, 1, 0, (uchar **)val, 0, 0, GET_ULL, + REQUIRED_ARG, opt->def_value, opt->min_value, opt->max_value, + 0, (long) opt->block_size, 0}; + + ulonglong orig_val= strtoull(value->str, NULL, 10); + my_bool unused; + *val= orig_val; + *val= getopt_ull_limit_value(*val, &optp, &unused); + if (*val == orig_val) + DBUG_RETURN(0); + + DBUG_RETURN(report_wrong_value(thd, opt->name, value->str, + suppress_warning)); + } + case HA_OPTION_TYPE_STRING: + { + char **val= (char **)((char *)base + opt->offset); + if (!value->str) + { + *val= 0; + DBUG_RETURN(0); + } + + if (!(*val= strmake_root(root, value->str, value->length))) + DBUG_RETURN(1); + DBUG_RETURN(0); + } + case HA_OPTION_TYPE_ENUM: + { + uint *val= (uint *)((char *)base + opt->offset), num; + + *val= (uint) opt->def_value; + if (!value->str) + DBUG_RETURN(0); + + const char *start= opt->values, *end; + + num= 0; + while (*start) + { + for (end=start; + *end && *end != ','; + end+= my_mbcharlen(system_charset_info, *end)) /* no-op */; + if (!my_strnncoll(system_charset_info, + (uchar*)start, end-start, + (uchar*)value->str, value->length)) + { + *val= num; + DBUG_RETURN(0); + } + if (*end) + end++; + start= end; + num++; + } + + DBUG_RETURN(report_wrong_value(thd, opt->name, value->str, + suppress_warning)); + } + case HA_OPTION_TYPE_BOOL: + { + bool *val= (bool *)((char *)base + opt->offset); + *val= opt->def_value; + + if (!value->str) + DBUG_RETURN(0); + + if (!my_strnncoll(system_charset_info, + (const uchar*)"NO", 2, + (uchar *)value->str, value->length) || + !my_strnncoll(system_charset_info, + (const uchar*)"OFF", 3, + (uchar *)value->str, value->length) || + !my_strnncoll(system_charset_info, + (const uchar*)"0", 1, + (uchar *)value->str, value->length)) + { + *val= FALSE; + DBUG_RETURN(FALSE); + } + + if (!my_strnncoll(system_charset_info, + (const uchar*)"YES", 3, + (uchar *)value->str, value->length) || + !my_strnncoll(system_charset_info, + (const uchar*)"ON", 2, + (uchar *)value->str, value->length) || + !my_strnncoll(system_charset_info, + (const uchar*)"1", 1, + (uchar *)value->str, value->length)) + { + *val= TRUE; + DBUG_RETURN(FALSE); + } + + DBUG_RETURN(report_wrong_value(thd, opt->name, value->str, + suppress_warning)); + } + } + DBUG_ASSERT(0); + my_error(ER_UNKNOWN_ERROR, MYF(0)); + DBUG_RETURN(1); +} + +static const size_t ha_option_type_sizeof[]= +{ sizeof(ulonglong), sizeof(char *), sizeof(uint), sizeof(bool)}; + +/** + Creates option structure and parses list of options in it + + @param thd thread handler + @param option_struct where to store pointer on the option struct + @param option_list list of options given by user + @param rules list of option description by engine + @param suppress_warning second parse so we do not need warnings + @param root MEM_ROOT where allocate memory + + @retval TRUE Error + @retval FALSE OK +*/ + +my_bool parse_option_list(THD* thd, void *option_struct_arg, + engine_option_value *option_list, + ha_create_table_option *rules, + my_bool suppress_warning, + MEM_ROOT *root) +{ + ha_create_table_option *opt; + size_t option_struct_size= 0; + engine_option_value *val= option_list; + void **option_struct= (void**)option_struct_arg; + DBUG_ENTER("parse_option_list"); + DBUG_PRINT("enter", + ("struct: 0x%lx list: 0x%lx rules: 0x%lx suppres %u root 0x%lx", + (ulong) *option_struct, (ulong)option_list, (ulong)rules, + (uint) suppress_warning, (ulong) root)); + + if (rules) + { + LEX_STRING default_val= {NULL, 0}; + for (opt= rules; opt->name; opt++) + set_if_bigger(option_struct_size, opt->offset + + ha_option_type_sizeof[opt->type]); + + *option_struct= alloc_root(root, option_struct_size); + + /* set all values to default */ + for (opt= rules; opt->name; opt++) + set_one_value(opt, thd, &default_val, *option_struct, + suppress_warning, root); + } + + for (; val; val= val->next) + { + for (opt= rules; opt && opt->name; opt++) + { + if (my_strnncoll(system_charset_info, + (uchar*)opt->name, opt->name_length, + (uchar*)val->name.str, val->name.length)) + continue; + + if (set_one_value(opt, thd, &val->value, + *option_struct, suppress_warning || val->parsed, root)) + DBUG_RETURN(TRUE); + val->parsed= true; + break; + } + if (report_unknown_option(thd, val, suppress_warning)) + DBUG_RETURN(TRUE); + val->parsed= true; + } + + DBUG_RETURN(FALSE); +} + + +/** + Parses all table/fields/keys options + + @param thd thread handler + @param file handler of the table + @parem share descriptor of the table + + @retval TRUE Error + @retval FALSE OK +*/ + +my_bool parse_engine_table_options(THD *thd, handlerton *ht, + TABLE_SHARE *share) +{ + MEM_ROOT *root= &share->mem_root; + DBUG_ENTER("parse_engine_table_options"); + + if (parse_option_list(thd, &share->option_struct, share->option_list, + ht->table_options, TRUE, root)) + DBUG_RETURN(TRUE); + + for (Field **field= share->field; *field; field++) + { + if (parse_option_list(thd, &(*field)->option_struct, (*field)->option_list, + ht->field_options, TRUE, root)) + DBUG_RETURN(TRUE); + } + + for (uint index= 0; index < share->keys; index ++) + { + if (parse_option_list(thd, &share->key_info[index].option_struct, + share->key_info[index].option_list, + ht->index_options, TRUE, root)) + DBUG_RETURN(TRUE); + } + + DBUG_RETURN(FALSE); +} + + +/** + Returns representation length of key and value in the frm file +*/ + +uint engine_option_value::frm_length() +{ + /* + 1 byte - name length + 2 bytes - value length + + if value.str is NULL, this option is not written to frm (=DEFAULT) + */ + return value.str ? 1 + name.length + 2 + value.length : 0; +} + + +/** + Returns length of representation of option list in the frm file +*/ + +static uint option_list_frm_length(engine_option_value *opt) +{ + uint res= 0; + + for (; opt; opt= opt->next) + res+= opt->frm_length(); + + return res; +} + + +/** + Calculates length of options image in the .frm + + @param table_option_list list of table options + @param create_fields field descriptors list + @param keys number of keys + @param key_info array of key descriptors + + @returns length of image in frm +*/ + +uint engine_table_options_frm_length(engine_option_value *table_option_list, + List<Create_field> &create_fields, + uint keys, KEY *key_info) +{ + List_iterator<Create_field> it(create_fields); + Create_field *field; + uint res, index; + DBUG_ENTER("engine_table_options_frm_length"); + + res= option_list_frm_length(table_option_list); + + while ((field= it++)) + res+= option_list_frm_length(field->option_list); + + for (index= 0; index < keys; index++, key_info++) + res+= option_list_frm_length(key_info->option_list); + + /* + if there's at least one option somewhere (res > 0) + we write option lists for all fields and keys, zero-terminated. + If there're no options we write nothing at all (backward compatibility) + */ + DBUG_RETURN(res ? res + 1 + create_fields.elements + keys : 0); +} + + +/** + Writes image of the key and value to the frm image buffer + + @param buff pointer to the buffer free space beginning + + @returns pointer to byte after last recorded in the buffer +*/ + +uchar *engine_option_value::frm_image(uchar *buff) +{ + if (value.str) + { + *buff++= name.length; + memcpy(buff, name.str, name.length); + buff+= name.length; + int2store(buff, value.length | (quoted_value ? FRM_QUOTED_VALUE : 0)); + buff+= 2; + memcpy(buff, (const uchar *) value.str, value.length); + buff+= value.length; + } + return buff; +} + +/** + Writes image of the key and value to the frm image buffer + + @param buff pointer to the buffer to store the options in + @param opt list of options; + + @returns pointer to the end of the stored data in the buffer +*/ +static uchar *option_list_frm_image(uchar *buff, engine_option_value *opt) +{ + for (; opt; opt= opt->next) + buff= opt->frm_image(buff); + + *buff++= 0; + return buff; +} + + +/** + Writes options image in the .frm buffer + + @param buff pointer to the buffer + @param table_option_list list of table options + @param create_fields field descriptors list + @param keys number of keys + @param key_info array of key descriptors + + @returns pointer to byte after last recorded in the buffer +*/ + +uchar *engine_table_options_frm_image(uchar *buff, + engine_option_value *table_option_list, + List<Create_field> &create_fields, + uint keys, KEY *key_info) +{ + List_iterator<Create_field> it(create_fields); + Create_field *field; + KEY *key_info_end= key_info + keys; + DBUG_ENTER("engine_table_options_frm_image"); + + buff= option_list_frm_image(buff, table_option_list); + + while ((field= it++)) + buff= option_list_frm_image(buff, field->option_list); + + while (key_info < key_info_end) + buff= option_list_frm_image(buff, (key_info++)->option_list); + + DBUG_RETURN(buff); +} + +/** + Reads name and value from buffer, then link it in the list + + @param buff the buffer to read from + @param start The list beginning or NULL + @param end The list last element or does not matter + @param root MEM_ROOT for allocating + + @returns pointer to byte after last recorded in the buffer +*/ +uchar *engine_option_value::frm_read(const uchar *buff, engine_option_value **start, + engine_option_value **end, MEM_ROOT *root) +{ + LEX_STRING name, value; + uint len; + + name.length= buff[0]; + buff++; + if (!(name.str= strmake_root(root, (const char*)buff, name.length))) + return NULL; + buff+= name.length; + len= uint2korr(buff); + value.length= len & ~FRM_QUOTED_VALUE; + buff+= 2; + if (!(value.str= strmake_root(root, (const char*)buff, value.length))) + return NULL; + buff+= value.length; + + engine_option_value *ptr=new (root) + engine_option_value(name, value, len & FRM_QUOTED_VALUE, start, end); + if (!ptr) + return NULL; + + return (uchar *)buff; +} + + +/** + Reads options from this buffer + + @param buff the buffer to read from + @param length buffer length + @param share table descriptor + @param root MEM_ROOT for allocating + + @retval TRUE Error + @retval FALSE OK +*/ + +my_bool engine_table_options_frm_read(const uchar *buff, uint length, + TABLE_SHARE *share) +{ + const uchar *buff_end= buff + length; + engine_option_value *end; + MEM_ROOT *root= &share->mem_root; + uint count; + DBUG_ENTER("engine_table_options_frm_read"); + + while (buff < buff_end && *buff) + { + if (!(buff= engine_option_value::frm_read(buff, &share->option_list, &end, + root))) + DBUG_RETURN(TRUE); + } + buff++; + + for (count=0; count < share->fields; count++) + { + while (buff < buff_end && *buff) + { + if (!(buff= engine_option_value::frm_read(buff, + &share->field[count]->option_list, + &end, root))) + DBUG_RETURN(TRUE); + } + buff++; + } + + for (count=0; count < share->keys; count++) + { + while (buff < buff_end && *buff) + { + if (!(buff= engine_option_value::frm_read(buff, + &share->key_info[count].option_list, + &end, root))) + DBUG_RETURN(TRUE); + } + buff++; + } + + if (buff < buff_end) + sql_print_warning("Table '%s' was created in a later MariaDB version - " + "unknown table attributes were ignored", + share->table_name.str); + + DBUG_RETURN(buff > buff_end); +} + +/** + Merges two lists of engine_option_value's with duplicate removal. +*/ + +engine_option_value *merge_engine_table_options(engine_option_value *first, + engine_option_value *second, + MEM_ROOT *root) +{ + engine_option_value *end, *opt; + DBUG_ENTER("merge_engine_table_options"); + LINT_INIT(end); + + /* find last element */ + if (first && second) + for (end= first; end->next; end= end->next) /* no-op */; + + for (opt= second; opt; opt= opt->next) + new (root) engine_option_value(opt->name, opt->value, opt->quoted_value, + &first, &end); + DBUG_RETURN(first); +} diff --git a/sql/create_options.h b/sql/create_options.h new file mode 100644 index 00000000000..174abb1a59a --- /dev/null +++ b/sql/create_options.h @@ -0,0 +1,92 @@ +/* Copyright (C) 2010 Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + + Engine defined options of tables/fields/keys in CREATE/ALTER TABLE. +*/ + +#ifndef SQL_CREATE_OPTIONS_INCLUDED +#define SQL_CREATE_OPTIONS_INCLUDED + +#include "handler.h" + +class engine_option_value: public Sql_alloc +{ + public: + LEX_STRING name; + LEX_STRING value; + engine_option_value *next; ///< parser puts them in a FIFO linked list + bool parsed; ///< to detect unrecognized options + bool quoted_value; ///< option=VAL vs. option='VAL' + + engine_option_value(LEX_STRING &name_arg, LEX_STRING &value_arg, bool quoted, + engine_option_value **start, engine_option_value **end) : + name(name_arg), value(value_arg), + next(NULL), parsed(false), quoted_value(quoted) + { + link(start, end); + } + engine_option_value(LEX_STRING &name_arg, + engine_option_value **start, engine_option_value **end) : + name(name_arg), value(null_lex_str), + next(NULL), parsed(false), quoted_value(false) + { + link(start, end); + } + engine_option_value(LEX_STRING &name_arg, ulonglong value_arg, + engine_option_value **start, engine_option_value **end, + MEM_ROOT *root) : + name(name_arg), next(NULL), parsed(false), quoted_value(false) + { + if ((value.str= (char *)alloc_root(root, 22))) + { + value.length= longlong10_to_str(value_arg, value.str, 10) - value.str; + link(start, end); + } + } + static uchar *frm_read(const uchar *buff, engine_option_value **start, + engine_option_value **end, MEM_ROOT *root); + void link(engine_option_value **start, engine_option_value **end); + uint frm_length(); + uchar *frm_image(uchar *buff); +}; + +typedef struct st_key KEY; +class Create_field; + +my_bool parse_engine_table_options(THD *thd, handlerton *ht, + TABLE_SHARE *share); +my_bool parse_option_list(THD* thd, void *option_struct, + engine_option_value *option_list, + ha_create_table_option *rules, + my_bool suppress_warning, + MEM_ROOT *root); +my_bool engine_table_options_frm_read(const uchar *buff, + uint length, + TABLE_SHARE *share); +engine_option_value *merge_engine_table_options(engine_option_value *source, + engine_option_value *changes, + MEM_ROOT *root); + +uint engine_table_options_frm_length(engine_option_value *table_option_list, + List<Create_field> &create_fields, + uint keys, KEY *key_info); +uchar *engine_table_options_frm_image(uchar *buff, + engine_option_value *table_option_list, + List<Create_field> &create_fields, + uint keys, KEY *key_info); +#endif diff --git a/sql/derror.cc b/sql/derror.cc index 55e9b49dddc..9f05c95157b 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -1,4 +1,5 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (C) 2011 Monty Program Ab 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,6 +24,7 @@ #include "mysql_priv.h" #include "mysys_err.h" +static bool check_error_mesg(const char *file_name, const char **errmsg); static bool read_texts(const char *file_name,const char ***point, uint error_messages); static void init_myfunc_errs(void); @@ -31,9 +33,12 @@ static void init_myfunc_errs(void); Read messages from errorfile. This function can be called multiple times to reload the messages. - If it fails to load the messages, it will fail softly by initializing - the errmesg pointer to an array of empty strings or by keeping the - old array if it exists. + + If it fails to load the messages: + - If we already have error messages loaded, keep the old ones and + return FALSE(ok) + - Initializing the errmesg pointer to an array of empty strings + and return TRUE (error) @retval FALSE OK @@ -43,25 +48,44 @@ static void init_myfunc_errs(void); bool init_errmessage(void) { - const char **errmsgs, **ptr; + const char **errmsgs, **ptr, **org_errmsgs; + bool error= FALSE; DBUG_ENTER("init_errmessage"); /* Get a pointer to the old error messages pointer array. read_texts() tries to free it. */ - errmsgs= my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); + org_errmsgs= my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); /* Read messages from file. */ - if (read_texts(ERRMSG_FILE, &errmsgs, ER_ERROR_LAST - ER_ERROR_FIRST + 1) && - !errmsgs) + if (read_texts(ERRMSG_FILE, &errmsgs, ER_ERROR_LAST - ER_ERROR_FIRST + 1) || + check_error_mesg(ERRMSG_FILE, errmsgs)) { - if (!(errmsgs= (const char**) my_malloc((ER_ERROR_LAST-ER_ERROR_FIRST+1)* - sizeof(char*), MYF(0)))) - DBUG_RETURN(TRUE); - for (ptr= errmsgs; ptr < errmsgs + ER_ERROR_LAST - ER_ERROR_FIRST; ptr++) - *ptr= ""; + x_free(errmsgs); + + if (org_errmsgs) + { + /* Use old error messages */ + errmsgs= org_errmsgs; + } + else + { + /* + No error messages. Create a temporary empty error message so + that we don't get a crash if some code wrongly tries to access + a non existing error message. + */ + if (!(errmsgs= (const char**) my_malloc((ER_ERROR_LAST-ER_ERROR_FIRST+1)* + sizeof(char*), MYF(0)))) + DBUG_RETURN(TRUE); + for (ptr= errmsgs; ptr < errmsgs + ER_ERROR_LAST - ER_ERROR_FIRST; ptr++) + *ptr= ""; + error= TRUE; + } } + else + x_free(org_errmsgs); // Free old language /* Register messages for use with my_error(). */ if (my_error_register(errmsgs, ER_ERROR_FIRST, ER_ERROR_LAST)) @@ -72,7 +96,29 @@ bool init_errmessage(void) errmesg= errmsgs; /* Init global variabel */ init_myfunc_errs(); /* Init myfunc messages */ - DBUG_RETURN(FALSE); + DBUG_RETURN(error); +} + + +/** + Check the error messages array contains all relevant error messages +*/ + +static bool check_error_mesg(const char *file_name, const char **errmsg) +{ + /* + The last MySQL error message can't be an empty string; If it is, + it means that the error file doesn't contain all MySQL messages + and is probably from an older version of MySQL / MariaDB. + */ + if (errmsg[ER_ERROR_LAST - ER_ERROR_FIRST][0] == 0) + { + sql_print_error("Error message file '%s' is probably from and older " + "version of MariaDB / MYSQL as it doesn't contain all " + "error messages", file_name); + return 1; + } + return 0; } @@ -97,6 +143,8 @@ static bool read_texts(const char *file_name,const char ***point, uchar head[32],*pos; DBUG_ENTER("read_texts"); + *point= 0; + LINT_INIT(buff); funktpos=0; if ((file=my_open(fn_format(name,file_name,language,"",4), @@ -106,6 +154,7 @@ static bool read_texts(const char *file_name,const char ***point, funktpos=1; if (my_read(file,(uchar*) head,32,MYF(MY_NABP))) goto err; + funktpos=2; if (head[0] != (uchar) 254 || head[1] != (uchar) 254 || head[2] != 2 || head[3] != 1) goto err; /* purecov: inspected */ @@ -131,19 +180,16 @@ Please install the latest version of this file.",name); if (count < error_messages) { sql_print_error("\ -Error message file '%s' had only %d error messages,\n\ -but it should contain at least %d error messages.\n\ -Check that the above file is the right version for this program!", +Error message file '%s' had only %d error messages, but it should contain at least %d error messages.\nCheck that the above file is the right version for this program!", name,count,error_messages); VOID(my_close(file,MYF(MY_WME))); DBUG_RETURN(1); } - x_free((uchar*) *point); /* Free old language */ if (!(*point= (const char**) my_malloc((size_t) (length+count*sizeof(char*)),MYF(0)))) { - funktpos=2; /* purecov: inspected */ + funktpos=3; /* purecov: inspected */ goto err; /* purecov: inspected */ } buff= (uchar*) (*point + count); @@ -166,7 +212,8 @@ Check that the above file is the right version for this program!", DBUG_RETURN(0); err: - sql_print_error((funktpos == 2) ? "Not enough memory for messagefile '%s'" : + sql_print_error((funktpos == 3) ? "Not enough memory for messagefile '%s'" : + (funktpos == 2) ? "Incompatible header in messagefile '%s'. Probably from another version of MariaDB" : ((funktpos == 1) ? "Can't read from messagefile '%s'" : "Can't find messagefile '%s'"), name); err1: diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 5c4d9e94a6e..e4436afd057 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -1369,7 +1369,7 @@ Event_job_data::execute(THD *thd, bool drop) DBUG_ENTER("Event_job_data::execute"); - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, 0); /* MySQL parser currently assumes that current database is either diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h index e32077b9c97..1ca619b8ed6 100644 --- a/sql/event_data_objects.h +++ b/sql/event_data_objects.h @@ -89,9 +89,9 @@ public: my_time_t execute_at; my_time_t starts; my_time_t ends; - my_bool starts_null; - my_bool ends_null; - my_bool execute_at_null; + bool starts_null; + bool ends_null; + bool execute_at_null; longlong expression; interval_type interval; diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 7560d490641..960b5933a99 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -107,7 +107,8 @@ const TABLE_FIELD_TYPE event_table_fields[ET_FIELD_COUNT] = { { C_STRING_WITH_LEN("sql_mode") }, { C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES'," - "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION'," + "'IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY'," + "'NO_UNSIGNED_SUBTRACTION'," "'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB'," "'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40'," "'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES'," @@ -213,7 +214,7 @@ mysql_event_fill_row(THD *thd, Safety: this can only happen if someone started the server and then altered mysql.event. */ - my_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED, MYF(0), table->alias, + my_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED, MYF(0), table->alias.c_ptr(), (int) ET_FIELD_COUNT, table->s->fields); DBUG_RETURN(TRUE); } @@ -431,17 +432,18 @@ Event_db_repository::index_read_for_db_for_i_s(THD *thd, TABLE *schema_table, } key_copy(key_buf, event_table->record[0], key_info, key_len); - if (!(ret= event_table->file->index_read_map(event_table->record[0], key_buf, - (key_part_map)1, - HA_READ_KEY_EXACT))) + if (!(ret= event_table->file->ha_index_read_map(event_table->record[0], + key_buf, + (key_part_map) 1, + HA_READ_KEY_EXACT))) { DBUG_PRINT("info",("Found rows. Let's retrieve them. ret=%d", ret)); do { ret= copy_event_to_schema_table(thd, schema_table, event_table); if (ret == 0) - ret= event_table->file->index_next_same(event_table->record[0], - key_buf, key_len); + ret= event_table->file->ha_index_next_same(event_table->record[0], + key_buf, key_len); } while (ret == 0); } DBUG_PRINT("info", ("Scan finished. ret=%d", ret)); @@ -481,7 +483,8 @@ Event_db_repository::table_scan_all_for_i_s(THD *thd, TABLE *schema_table, READ_RECORD read_record_info; DBUG_ENTER("Event_db_repository::table_scan_all_for_i_s"); - init_read_record(&read_record_info, thd, event_table, NULL, 1, 0, FALSE); + if (init_read_record(&read_record_info, thd, event_table, NULL, 1, 0, FALSE)) + DBUG_RETURN(TRUE); /* rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE, @@ -922,8 +925,9 @@ Event_db_repository::find_named_event(LEX_STRING db, LEX_STRING name, key_copy(key, table->record[0], table->key_info, table->key_info->key_length); - if (table->file->index_read_idx_map(table->record[0], 0, key, HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_idx_map(table->record[0], 0, key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) { DBUG_PRINT("info", ("Row not found")); DBUG_RETURN(TRUE); @@ -978,7 +982,9 @@ Event_db_repository::drop_events_by_field(THD *thd, DBUG_VOID_RETURN; /* only enabled events are in memory, so we go now and delete the rest */ - init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE); + if (init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE)) + goto end; + while (!ret && !(read_record_info.read_record(&read_record_info)) ) { char *et_field= get_field(thd->mem_root, table->field[field]); @@ -1000,8 +1006,9 @@ Event_db_repository::drop_events_by_field(THD *thd, } } end_read_record(&read_record_info); - close_thread_tables(thd); +end: + close_thread_tables(thd); DBUG_VOID_RETURN; } diff --git a/sql/event_db_repository.h b/sql/event_db_repository.h index e25cb6b85a4..8c028f0717f 100644 --- a/sql/event_db_repository.h +++ b/sql/event_db_repository.h @@ -75,7 +75,6 @@ public: bool create_event(THD *thd, Event_parse_data *parse_data, bool create_if_not, bool *event_already_exists); - bool update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname, LEX_STRING *new_name); diff --git a/sql/event_parse_data.h b/sql/event_parse_data.h index 228ca1bb0c9..ae834cf9a9f 100644 --- a/sql/event_parse_data.h +++ b/sql/event_parse_data.h @@ -73,9 +73,9 @@ public: my_time_t starts; my_time_t ends; my_time_t execute_at; - my_bool starts_null; - my_bool ends_null; - my_bool execute_at_null; + bool starts_null; + bool ends_null; + bool execute_at_null; sp_name *identifier; Item* item_expression; diff --git a/sql/event_queue.cc b/sql/event_queue.cc index d68dc8ef479..b9585dc9c51 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -734,12 +734,14 @@ Event_queue::cond_wait(THD *thd, struct timespec *abstime, const char* msg, thd->enter_cond(&COND_queue_state, &LOCK_event_queue, msg); - DBUG_PRINT("info", ("pthread_cond_%swait", abstime? "timed":"")); - if (!abstime) - pthread_cond_wait(&COND_queue_state, &LOCK_event_queue); - else - pthread_cond_timedwait(&COND_queue_state, &LOCK_event_queue, abstime); - + if (!thd->killed) + { + DBUG_PRINT("info", ("pthread_cond_%swait", abstime ? "timed" : "")); + if (!abstime) + pthread_cond_wait(&COND_queue_state, &LOCK_event_queue); + else + pthread_cond_timedwait(&COND_queue_state, &LOCK_event_queue, abstime); + } mutex_last_locked_in_func= func; mutex_last_locked_at_line= line; mutex_queue_data_locked= TRUE; diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index fb66a50ee7f..7704ed3528d 100755 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -103,7 +103,7 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et) err_msg.append(err->msg, strlen(err->msg), system_charset_info); DBUG_ASSERT(err->level < 3); (sql_print_message_handlers[err->level])("%*s", err_msg.length(), - err_msg.c_ptr()); + err_msg.c_ptr_safe()); } DBUG_VOID_RETURN; } @@ -651,7 +651,14 @@ Event_scheduler::stop() /* thd could be 0x0, when shutting down */ sql_print_information("Event Scheduler: " "Waiting for the scheduler thread to reply"); - COND_STATE_WAIT(thd, NULL, "Waiting scheduler to stop"); + + /* + Wait only 2 seconds, as there is a small chance the thread missed the + above awake() call and we may have to do it again + */ + struct timespec top_time; + set_timespec(top_time, 2); + COND_STATE_WAIT(thd, &top_time, "Waiting scheduler to stop"); } while (state == STOPPING); DBUG_PRINT("info", ("Scheduler thread has cleaned up. Set state to INIT")); sql_print_information("Event Scheduler: Stopped"); diff --git a/sql/events.cc b/sql/events.cc index 6eaa27b3212..f0188bbb0ae 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -490,7 +490,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, of CURRENT_USER will be written into the binary log as the definer for the SQL thread. */ - ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); + ret= write_bin_log(thd, TRUE, log_query.ptr(), log_query.length()); } } } @@ -790,7 +790,7 @@ send_show_create_event(THD *thd, Event_timed *et, Protocol *protocol) protocol->store(et->name.str, et->name.length, system_charset_info); protocol->store(sql_mode.str, sql_mode.length, system_charset_info); protocol->store(tz_name->ptr(), tz_name->length(), system_charset_info); - protocol->store(show_str.c_ptr(), show_str.length(), + protocol->store(show_str.ptr(), show_str.length(), et->creation_ctx->get_client_cs()); protocol->store(et->creation_ctx->get_client_cs()->csname, strlen(et->creation_ctx->get_client_cs()->csname), @@ -928,7 +928,7 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */) */ bool -Events::init(my_bool opt_noacl_or_bootstrap) +Events::init(bool opt_noacl_or_bootstrap) { THD *thd; @@ -1225,7 +1225,12 @@ Events::load_events_from_db(THD *thd) DBUG_RETURN(TRUE); } - init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE); + if (init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE)) + { + close_thread_tables(thd); + DBUG_RETURN(TRUE); + } + while (!(read_record_info.read_record(&read_record_info))) { Event_queue_element *et; diff --git a/sql/events.h b/sql/events.h index 2bc87517748..a3c98d84f00 100644 --- a/sql/events.h +++ b/sql/events.h @@ -92,7 +92,7 @@ public: get_db_repository() { return db_repository; } static bool - init(my_bool opt_noacl); + init(bool opt_noacl); static void deinit(); diff --git a/sql/field.cc b/sql/field.cc index a8bb59ca417..2a52963afa9 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -59,7 +59,7 @@ const char field_separator=','; ((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1))) #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))) -#define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index))) +#define ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index) || bitmap_is_set(table->vcol_set, field_index))) /* Rules for merging different types of fields in UNION @@ -1286,7 +1286,7 @@ static bool test_if_real(const char *str,int length, CHARSET_INFO *cs) This is used for printing bit_fields as numbers while debugging. */ -String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val) +String *Field::val_int_as_str(String *val_buffer, bool unsigned_val) { ASSERT_COLUMN_MARKED_FOR_READ; CHARSET_INFO *cs= &my_charset_bin; @@ -1308,13 +1308,13 @@ String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val) Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg) - :ptr(ptr_arg), null_ptr(null_ptr_arg), - table(0), orig_table(0), table_name(0), - field_name(field_name_arg), - key_start(0), part_of_key(0), part_of_key_not_clustered(0), - part_of_sortkey(0), unireg_check(unireg_check_arg), - field_length(length_arg), null_bit(null_bit_arg), - is_created_from_null_item(FALSE) + :ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0), + table_name(0), field_name(field_name_arg), option_list(0), + option_struct(0), key_start(0), part_of_key(0), + part_of_key_not_clustered(0), part_of_sortkey(0), + unireg_check(unireg_check_arg), field_length(length_arg), + null_bit(null_bit_arg), is_created_from_null_item(FALSE), vcol_info(0), + stored_in_db(TRUE) { flags=null_ptr ? 0: NOT_NULL_FLAG; comment.str= (char*) ""; @@ -1538,9 +1538,9 @@ void Field::make_field(Send_field *field) } else field->org_table_name= field->db_name= ""; - if (orig_table && orig_table->alias) + if (orig_table && orig_table->alias.ptr()) { - field->table_name= orig_table->alias; + field->table_name= orig_table->alias.ptr(); field->org_col_name= field_name; } else @@ -1615,7 +1615,7 @@ longlong Field::convert_decimal2longlong(const my_decimal *val, int Field_num::store_decimal(const my_decimal *val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int err= 0; longlong i= convert_decimal2longlong(val, unsigned_flag, &err); return test(err | store(i, unsigned_flag)); @@ -1687,7 +1687,7 @@ void Field_num::make_field(Send_field *field) int Field_str::store_decimal(const my_decimal *d) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; double val; /* TODO: use decimal2string? */ int err= warn_if_overflow(my_decimal2double(E_DEC_FATAL_ERROR & @@ -1763,7 +1763,7 @@ bool Field::get_time(MYSQL_TIME *ltime) int Field::store_time(MYSQL_TIME *ltime, timestamp_type type_arg) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char buff[MAX_DATE_STRING_REP_LENGTH]; uint length= (uint) my_TIME_to_str(ltime, buff); return store(buff, length, &my_charset_bin); @@ -1890,7 +1890,7 @@ void Field_decimal::overflow(bool negative) int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char buff[STRING_BUFFER_USUAL_SIZE]; String tmp(buff,sizeof(buff), &my_charset_bin); const uchar *from= (uchar*) from_arg; @@ -2256,7 +2256,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs) int Field_decimal::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; if (unsigned_flag && nr < 0) { overflow(1); @@ -2301,7 +2301,7 @@ int Field_decimal::store(double nr) int Field_decimal::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char buff[22]; uint length, int_part; char fyllchar; @@ -2581,7 +2581,7 @@ void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value, bool Field_new_decimal::store_value(const my_decimal *decimal_value) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; DBUG_ENTER("Field_new_decimal::store_value"); #ifndef DBUG_OFF @@ -2626,7 +2626,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value) int Field_new_decimal::store(const char *from, uint length, CHARSET_INFO *charset_arg) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int err; my_decimal decimal_value; DBUG_ENTER("Field_new_decimal::store(char*)"); @@ -2693,7 +2693,7 @@ int Field_new_decimal::store(const char *from, uint length, int Field_new_decimal::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; my_decimal decimal_value; int err; DBUG_ENTER("Field_new_decimal::store(double)"); @@ -2728,7 +2728,7 @@ int Field_new_decimal::store(double nr) int Field_new_decimal::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; my_decimal decimal_value; int err; @@ -2750,7 +2750,7 @@ int Field_new_decimal::store(longlong nr, bool unsigned_val) int Field_new_decimal::store_decimal(const my_decimal *decimal_value) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; return store_value(decimal_value); } @@ -2972,7 +2972,7 @@ Field_new_decimal::unpack(uchar* to, int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error; longlong rnd; @@ -2984,7 +2984,7 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) int Field_tiny::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; nr=rint(nr); if (unsigned_flag) @@ -3027,7 +3027,7 @@ int Field_tiny::store(double nr) int Field_tiny::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; if (unsigned_flag) @@ -3147,7 +3147,7 @@ void Field_tiny::sql_type(String &res) const int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int store_tmp; int error; longlong rnd; @@ -3168,7 +3168,7 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) int Field_short::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; int16 res; nr=rint(nr); @@ -3220,7 +3220,7 @@ int Field_short::store(double nr) int Field_short::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; int16 res; @@ -3394,7 +3394,7 @@ void Field_short::sql_type(String &res) const int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int store_tmp; int error; longlong rnd; @@ -3408,7 +3408,7 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) int Field_medium::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; nr=rint(nr); if (unsigned_flag) @@ -3454,7 +3454,7 @@ int Field_medium::store(double nr) int Field_medium::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; if (unsigned_flag) @@ -3584,7 +3584,7 @@ void Field_medium::sql_type(String &res) const int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; long store_tmp; int error; longlong rnd; @@ -3605,7 +3605,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) int Field_long::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; int32 res; nr=rint(nr); @@ -3657,7 +3657,7 @@ int Field_long::store(double nr) int Field_long::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; int32 res; @@ -3831,7 +3831,7 @@ void Field_long::sql_type(String &res) const int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; char *end; ulonglong tmp; @@ -3861,7 +3861,7 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) int Field_longlong::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; longlong res; @@ -3913,7 +3913,7 @@ int Field_longlong::store(double nr) int Field_longlong::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; if (nr < 0) // Only possible error @@ -4139,7 +4139,7 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) int Field_float::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= truncate(&nr, FLT_MAX); float j= (float)nr; @@ -4401,7 +4401,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) int Field_double::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= truncate(&nr, DBL_MAX); #ifdef WORDS_BIGENDIAN @@ -4828,7 +4828,7 @@ timestamp_auto_set_type Field_timestamp::get_auto_set_type() const int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; MYSQL_TIME l_time; my_time_t tmp= 0; int error; @@ -4891,7 +4891,7 @@ int Field_timestamp::store(double nr) int Field_timestamp::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; MYSQL_TIME l_time; my_time_t timestamp= 0; int error; @@ -5190,7 +5190,7 @@ int Field_time::store_time(MYSQL_TIME *ltime, timestamp_type time_type) int Field_time::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; long tmp; int error= 0; if (nr > (double)TIME_MAX_VALUE) @@ -5228,7 +5228,7 @@ int Field_time::store(double nr) int Field_time::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; long tmp; int error= 0; if (nr < (longlong) -TIME_MAX_VALUE && !unsigned_val) @@ -5386,7 +5386,7 @@ void Field_time::sql_type(String &res) const int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char *end; int error; longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); @@ -5434,7 +5434,7 @@ int Field_year::store(double nr) int Field_year::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155) { *ptr= 0; @@ -5509,7 +5509,7 @@ void Field_year::sql_type(String &res) const int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; MYSQL_TIME l_time; uint32 tmp; int error; @@ -5564,7 +5564,7 @@ int Field_date::store(double nr) int Field_date::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; MYSQL_TIME not_used; int error; longlong initial_nr= nr; @@ -5743,7 +5743,7 @@ void Field_date::sql_type(String &res) const int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; long tmp; MYSQL_TIME l_time; int error; @@ -5793,7 +5793,7 @@ int Field_newdate::store(double nr) int Field_newdate::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; MYSQL_TIME l_time; longlong tmp; int error; @@ -5829,7 +5829,7 @@ int Field_newdate::store(longlong nr, bool unsigned_val) int Field_newdate::store_time(MYSQL_TIME *ltime,timestamp_type time_type) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; long tmp; int error= 0; if (time_type == MYSQL_TIMESTAMP_DATE || @@ -5976,7 +5976,7 @@ void Field_newdate::sql_type(String &res) const int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; MYSQL_TIME time_tmp; int error; ulonglong tmp= 0; @@ -6029,7 +6029,7 @@ int Field_datetime::store(double nr) int Field_datetime::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; MYSQL_TIME not_used; int error; longlong initial_nr= nr; @@ -6067,7 +6067,7 @@ int Field_datetime::store(longlong nr, bool unsigned_val) int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; longlong tmp; int error= 0; /* @@ -6370,7 +6370,7 @@ Field_longstr::report_if_important_data(const char *pstr, const char *end, int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint copy_length; const char *well_formed_error_pos; const char *cannot_convert_error_pos; @@ -6411,7 +6411,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) int Field_str::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; uint length; uint local_char_length= field_length / charset()->mbmaxlen; @@ -6707,8 +6707,7 @@ void Field_string::sql_type(String &res) const length= cs->cset->snprintf(cs,(char*) res.ptr(), res.alloced_length(), "%s(%d)", - ((type() == MYSQL_TYPE_VAR_STRING && - !thd->variables.new_mode) ? + (type() == MYSQL_TYPE_VAR_STRING ? (has_charset() ? "varchar" : "varbinary") : (has_charset() ? "char" : "binary")), (int) field_length / charset()->mbmaxlen); @@ -6860,7 +6859,7 @@ int Field_string::do_save_field_metadata(uchar *metadata_ptr) */ int Field_string::pack_cmp(const uchar *a, const uchar *b, uint length, - my_bool insert_or_update) + bool insert_or_update) { uint a_length, b_length; if (length > 255) @@ -6898,7 +6897,7 @@ int Field_string::pack_cmp(const uchar *a, const uchar *b, uint length, */ int Field_string::pack_cmp(const uchar *key, uint length, - my_bool insert_or_update) + bool insert_or_update) { uint row_length, local_key_length; uchar *end; @@ -7015,7 +7014,7 @@ int Field_varstring::do_save_field_metadata(uchar *metadata_ptr) int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint copy_length; const char *well_formed_error_pos; const char *cannot_convert_error_pos; @@ -7377,7 +7376,7 @@ Field_varstring::unpack(uchar *to, const uchar *from, int Field_varstring::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg, - my_bool insert_or_update) + bool insert_or_update) { uint a_length, b_length; if (key_length_arg > 255) @@ -7398,7 +7397,7 @@ int Field_varstring::pack_cmp(const uchar *a, const uchar *b, int Field_varstring::pack_cmp(const uchar *b, uint key_length_arg, - my_bool insert_or_update) + bool insert_or_update) { uchar *a= ptr+ length_bytes; uint a_length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr); @@ -7679,7 +7678,7 @@ void Field_blob::put_length(uchar *pos, uint32 length) int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint copy_length, new_length; const char *well_formed_error_pos; const char *cannot_convert_error_pos; @@ -8129,7 +8128,7 @@ const uchar *Field_blob::unpack(uchar *to, /* Keys for blobs are like keys on varchars */ int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg, - my_bool insert_or_update) + bool insert_or_update) { uint a_length, b_length; if (key_length_arg > 255) @@ -8150,7 +8149,7 @@ int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg, int Field_blob::pack_cmp(const uchar *b, uint key_length_arg, - my_bool insert_or_update) + bool insert_or_update) { uchar *a; uint a_length, b_length; @@ -8440,7 +8439,7 @@ void Field_enum::store_type(ulonglong value) int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int err= 0; uint32 not_used; char buff[STRING_BUFFER_USUAL_SIZE]; @@ -8489,7 +8488,7 @@ int Field_enum::store(double nr) int Field_enum::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; if ((ulonglong) nr > typelib->count || nr == 0) { @@ -8658,7 +8657,7 @@ Field *Field_enum::new_field(MEM_ROOT *root, struct st_table *new_table, int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; bool got_warning= 0; int err= 0; char *not_used; @@ -8698,7 +8697,7 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) int Field_set::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; ulonglong max_nr; @@ -9017,7 +9016,7 @@ uint Field_bit::is_equal(Create_field *new_field) int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int delta; for (; length && !*from; from++, length--) // skip left 0's @@ -9439,7 +9438,7 @@ Field_bit_as_char::Field_bit_as_char(uchar *ptr_arg, uint32 len_arg, int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int delta; uchar bits= (uchar) (field_length & 7); @@ -9548,6 +9547,8 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg, ((decimals_arg & FIELDFLAG_MAX_DEC) << FIELDFLAG_DEC_SHIFT) | (maybe_null ? FIELDFLAG_MAYBE_NULL : 0) | (is_unsigned ? 0 : FIELDFLAG_DECIMAL)); + vcol_info= 0; + stored_in_db= TRUE; } @@ -9567,6 +9568,7 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg, @param fld_interval_list Interval list (if any) @param fld_charset Field charset @param fld_geom_type Field geometry type (if any) + @param fld_vcol_info Virtual column data @retval FALSE on success @@ -9579,17 +9581,20 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, uint fld_type_modifier, Item *fld_default_value, Item *fld_on_update_value, LEX_STRING *fld_comment, char *fld_change, List<String> *fld_interval_list, - CHARSET_INFO *fld_charset, uint fld_geom_type) + CHARSET_INFO *fld_charset, uint fld_geom_type, + Virtual_column_info *fld_vcol_info, + engine_option_value *create_opt) { uint sign_len, allowed_type_modifier= 0; ulong max_field_charlength= MAX_FIELD_CHARLENGTH; DBUG_ENTER("Create_field::init()"); - + field= 0; field_name= fld_name; def= fld_default_value; flags= fld_type_modifier; + option_list= create_opt; unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ? Field::NEXT_NUMBER : Field::NONE); decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0; @@ -9610,6 +9615,33 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, interval_list.empty(); comment= *fld_comment; + vcol_info= fld_vcol_info; + stored_in_db= TRUE; + + /* Initialize data for a computed field */ + if ((uchar)fld_type == (uchar)MYSQL_TYPE_VIRTUAL) + { + DBUG_ASSERT(vcol_info && vcol_info->expr_item); + stored_in_db= vcol_info->is_stored(); + /* + Walk through the Item tree checking if all items are valid + to be part of the virtual column + */ + if (vcol_info->expr_item->walk(&Item::check_vcol_func_processor, 0, NULL)) + { + my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name); + DBUG_RETURN(TRUE); + } + + /* + Make a field created for the real type. + Note that regular and computed fields differ from each other only by + Field::vcol_info. It is is always NULL for a column that is not + computed. + */ + sql_type= fld_type= vcol_info->get_real_type(); + } + /* Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP. @@ -9899,7 +9931,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, } case MYSQL_TYPE_DECIMAL: DBUG_ASSERT(0); /* Was obsolete */ - } + } /* Remember the value of length */ char_length= length; @@ -10009,7 +10041,6 @@ uint pack_length_to_packflag(uint type) return 0; // This shouldn't happen } - Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length, uchar *null_pos, uchar null_bit, uint pack_flag, @@ -10201,6 +10232,10 @@ Create_field::Create_field(Field *old_field,Field *orig_field) charset= old_field->charset(); // May be NULL ptr comment= old_field->comment; decimals= old_field->decimals(); + vcol_info= old_field->vcol_info; + stored_in_db= old_field->stored_in_db; + option_list= old_field->option_list; + option_struct= old_field->option_struct; /* Fix if the original table had 4 byte pointer blobs */ if (flags & BLOB_FLAG) @@ -10275,6 +10310,19 @@ Create_field::Create_field(Field *old_field,Field *orig_field) /** + Makes a clone of this object for ALTER/CREATE TABLE + + @param mem_root MEM_ROOT where to clone the field +*/ + +Create_field *Create_field::clone(MEM_ROOT *mem_root) const +{ + Create_field *res= new (mem_root) Create_field(*this); + return res; +} + + +/** maximum possible display length for blob. @return diff --git a/sql/field.h b/sql/field.h index 9db4f47a0f3..3cfcf308282 100644 --- a/sql/field.h +++ b/sql/field.h @@ -34,6 +34,7 @@ class Send_field; class Protocol; class Create_field; class Relay_log_info; +struct ha_field_option_struct; struct st_cache_field; int field_conv(Field *to,Field *from); @@ -49,6 +50,71 @@ inline uint get_set_pack_length(int elements) return len > 4 ? 8 : len; } +/* + Virtual_column_info is the class to contain additional + characteristics that is specific for a virtual/computed + field such as: + - the defining expression that is evaluated to compute the value + of the field + - whether the field is to be stored in the database + - whether the field is used in a partitioning expression +*/ + +class Virtual_column_info: public Sql_alloc +{ +private: + /* + The following data is only updated by the parser and read + when a Create_field object is created/initialized. + */ + enum_field_types field_type; /* Real field type*/ + /* Flag indicating that the field is physically stored in the database */ + bool stored_in_db; + /* Flag indicating that the field used in a partitioning expression */ + bool in_partitioning_expr; + +public: + /* The expression to compute the value of the virtual column */ + Item *expr_item; + /* Text representation of the defining expression */ + LEX_STRING expr_str; + + Virtual_column_info() + : field_type((enum enum_field_types)MYSQL_TYPE_VIRTUAL), + stored_in_db(FALSE), in_partitioning_expr(FALSE), + expr_item(NULL) + { + expr_str.str= NULL; + expr_str.length= 0; + }; + ~Virtual_column_info() {} + enum_field_types get_real_type() + { + return field_type; + } + void set_field_type(enum_field_types fld_type) + { + /* Calling this function can only be done once. */ + field_type= fld_type; + } + bool is_stored() + { + return stored_in_db; + } + void set_stored_in_db_flag(bool stored) + { + stored_in_db= stored; + } + bool is_in_partitioning_expr() + { + return in_partitioning_expr; + } + void mark_as_in_partitioning_expr() + { + in_partitioning_expr= TRUE; + } +}; + class Field { Field(const Item &); /* Prevent use of these */ @@ -65,20 +131,24 @@ public: */ uchar *null_ptr; /* - Note that you can use table->in_use as replacement for current_thd member + Note that you can use table->in_use as replacement for current_thd member only inside of val_*() and store() members (e.g. you can't use it in cons) */ struct st_table *table; // Pointer for table struct st_table *orig_table; // Pointer to original table - const char **table_name, *field_name; + const char * const *table_name; + const char *field_name; + /** reference to the list of options or NULL */ + engine_option_value *option_list; + ha_field_option_struct *option_struct; /* structure with parsed options */ LEX_STRING comment; /* Field is part of the following keys */ key_map key_start, part_of_key, part_of_key_not_clustered; key_map part_of_sortkey; - /* - We use three additional unireg types for TIMESTAMP to overcome limitation - of current binary format of .frm file. We'd like to be able to support - NOW() as default and on update value for such fields but unable to hold + /* + We use three additional unireg types for TIMESTAMP to overcome limitation + of current binary format of .frm file. We'd like to be able to support + NOW() as default and on update value for such fields but unable to hold this info anywhere except unireg_check field. This issue will be resolved in more clean way with transition to new text based .frm format. See also comment for Field_timestamp::Field_timestamp(). @@ -111,6 +181,19 @@ public: */ bool is_created_from_null_item; + /* + This is additional data provided for any computed(virtual) field. + In particular it includes a pointer to the item by which this field + can be computed from other fields. + */ + Virtual_column_info *vcol_info; + /* + Flag indicating that the field is physically stored in tables + rather than just computed from other fields. + As of now, FALSE can be set only for computed virtual columns. + */ + bool stored_in_db; + Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg); @@ -140,7 +223,7 @@ public: This trickery is used to decrease a number of malloc calls. */ virtual String *val_str(String*,String *)=0; - String *val_int_as_str(String *val_buffer, my_bool unsigned_flag); + String *val_int_as_str(String *val_buffer, bool unsigned_flag); /* str_needs_quotes() returns TRUE if the value returned by val_str() needs to be quoted when used in constructing an SQL query. @@ -439,10 +522,10 @@ public: { return max_length;} virtual int pack_cmp(const uchar *a,const uchar *b, uint key_length_arg, - my_bool insert_or_update) + bool insert_or_update) { return cmp(a,b); } virtual int pack_cmp(const uchar *b, uint key_length_arg, - my_bool insert_or_update) + bool insert_or_update) { return cmp(ptr,b); } uint offset(uchar *record) { @@ -474,10 +557,14 @@ public: return (op_result == E_DEC_OVERFLOW); } int warn_if_overflow(int op_result); + void set_table_name(String *alias) + { + table_name= &alias->Ptr; + } void init(TABLE *table_arg) { orig_table= table= table_arg; - table_name= &table_arg->alias; + set_table_name(&table_arg->alias); } /* maximum possible display length */ @@ -708,7 +795,7 @@ public: /* base class for float and double and decimal (old one) */ class Field_real :public Field_num { public: - my_bool not_fixed; + bool not_fixed; Field_real(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, @@ -1135,7 +1222,7 @@ public: NONE, field_name_arg, dec_arg, 0, 0) {} Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg, - uint8 dec_arg, my_bool not_fixed_arg) + uint8 dec_arg, bool not_fixed_arg) :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0, NONE, field_name_arg, dec_arg, 0, 0) {not_fixed= not_fixed_arg; } @@ -1226,7 +1313,7 @@ public: Field::set_default(); } /* Get TIMESTAMP field value as seconds since begging of Unix Epoch */ - inline long get_timestamp(my_bool *null_value) + inline long get_timestamp(bool *null_value) { if ((*null_value= is_null())) return 0; @@ -1513,8 +1600,8 @@ public: const Relay_log_info *rli, uint16 mflags); uint row_pack_length() { return (field_length + 1); } int pack_cmp(const uchar *a,const uchar *b,uint key_length, - my_bool insert_or_update); - int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update); + bool insert_or_update); + int pack_cmp(const uchar *b,uint key_length,bool insert_or_update); uint packed_col_length(const uchar *to, uint length); uint max_packed_col_length(uint max_length); uint size_of() const { return sizeof(*this); } @@ -1596,8 +1683,8 @@ public: const uchar *unpack_key(uchar* to, const uchar *from, uint max_length, bool low_byte_first); int pack_cmp(const uchar *a, const uchar *b, uint key_length, - my_bool insert_or_update); - int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update); + bool insert_or_update); + int pack_cmp(const uchar *b, uint key_length,bool insert_or_update); int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L); int key_cmp(const uchar *,const uchar*); int key_cmp(const uchar *str, uint length); @@ -1782,8 +1869,8 @@ public: const uchar *unpack_key(uchar* to, const uchar *from, uint max_length, bool low_byte_first); int pack_cmp(const uchar *a, const uchar *b, uint key_length, - my_bool insert_or_update); - int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update); + bool insert_or_update); + int pack_cmp(const uchar *b, uint key_length,bool insert_or_update); uint packed_col_length(const uchar *col_ptr, uint length); uint max_packed_col_length(uint max_length); void free() { value.free(); } @@ -2069,14 +2156,31 @@ public: CHARSET_INFO *charset; Field::geometry_type geom_type; Field *field; // For alter table + engine_option_value *option_list; + /** structure with parsed options (for comparing fields in ALTER TABLE) */ + ha_field_option_struct *option_struct; uint8 row,col,sc_length,interval_id; // For rea_create_table uint offset,pack_flag; - Create_field() :after(0) {} + + /* + This is additinal data provided for any computed(virtual) field. + In particular it includes a pointer to the item by which this field + can be computed from other fields. + */ + Virtual_column_info *vcol_info; + /* + Flag indicating that the field is physically stored in tables + rather than just computed from other fields. + As of now, FALSE can be set only for computed virtual columns. + */ + bool stored_in_db; + + Create_field() :after(0), option_list(NULL), option_struct(NULL) + {} Create_field(Field *field, Field *orig_field); /* Used to make a clone of this object for ALTER/CREATE TABLE */ - Create_field *clone(MEM_ROOT *mem_root) const - { return new (mem_root) Create_field(*this); } + Create_field *clone(MEM_ROOT *mem_root) const; void create_length_to_internal_length(void); /* Init for a tmp table field. To be extended if need be. */ @@ -2088,7 +2192,8 @@ public: char *decimals, uint type_modifier, Item *default_value, Item *on_update_value, LEX_STRING *comment, char *change, List<String> *interval_list, CHARSET_INFO *cs, - uint uint_geom_type); + uint uint_geom_type, Virtual_column_info *vcol_info, + engine_option_value *option_list); bool field_flags_are_binary() { @@ -2127,7 +2232,7 @@ class Copy_field :public Sql_alloc { public: uchar *from_ptr,*to_ptr; uchar *from_null_ptr,*to_null_ptr; - my_bool *null_row; + bool *null_row; uint from_bit,to_bit; /** Number of bytes in the fields pointed to by 'from_ptr' and diff --git a/sql/filesort.cc b/sql/filesort.cc index e95ff08fcdd..ad891db3991 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -517,7 +517,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, THD *thd= current_thd; volatile THD::killed_state *killed= &thd->killed; handler *file; - MY_BITMAP *save_read_set, *save_write_set; + MY_BITMAP *save_read_set, *save_write_set, *save_vcol_set; DBUG_ENTER("find_all_keys"); DBUG_PRINT("info",("using: %s", (select ? select->quick ? "ranges" : "where": @@ -539,7 +539,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, if (! indexfile && ! quick_select) { next_pos=(uchar*) 0; /* Find records in sequence */ - file->ha_rnd_init(1); + if (file->ha_rnd_init_with_error(1)) + DBUG_RETURN(HA_POS_ERROR); file->extra_opt(HA_EXTRA_CACHE, current_thd->variables.read_buff_size); } @@ -553,6 +554,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, /* Remember original bitmaps */ save_read_set= sort_form->read_set; save_write_set= sort_form->write_set; + save_vcol_set= sort_form->vcol_set; /* Set up temporary column read map for columns used by sort */ bitmap_clear_all(&sort_form->tmp_set); /* Temporary set for register_used_fields and register_field_in_read_map */ @@ -561,7 +563,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, if (select && select->cond) select->cond->walk(&Item::register_field_in_read_map, 1, (uchar*) sort_form); - sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set); + sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set, + &sort_form->tmp_set); for (;;) { @@ -569,6 +572,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, { if ((error= select->quick->get_next())) break; + if (!error) + update_virtual_fields(thd, sort_form); file->position(sort_form->record[0]); DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE);); } @@ -581,11 +586,13 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, error= my_errno ? my_errno : -1; /* Abort */ break; } - error=file->rnd_pos(sort_form->record[0],next_pos); + error=file->ha_rnd_pos(sort_form->record[0],next_pos); } else { - error=file->rnd_next(sort_form->record[0]); + error=file->ha_rnd_next(sort_form->record[0]); + if (!error) + update_virtual_fields(thd, sort_form); if (!flag) { my_store_ptr(ref_pos,ref_length,record); // Position to row @@ -640,7 +647,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, DBUG_RETURN(HA_POS_ERROR); /* Signal we should use orignal column read and write maps */ - sort_form->column_bitmaps_set(save_read_set, save_write_set); + sort_form->column_bitmaps_set(save_read_set, save_write_set, save_vcol_set); DBUG_PRINT("test",("error: %d indexpos: %d",error,indexpos)); if (error != HA_ERR_END_OF_FILE) @@ -1007,7 +1014,14 @@ static void register_used_fields(SORTPARAM *param) if ((field= sort_field->field)) { if (field->table == table) - bitmap_set_bit(bitmap, field->field_index); + { + if (field->vcol_info) + { + Item *vcol_item= field->vcol_info->expr_item; + vcol_item->walk(&Item::register_field_in_read_map, 1, (uchar *) 0); + } + bitmap_set_bit(bitmap, field->field_index); + } } else { // Item diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 8e2cd207962..140931f94f1 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -9172,7 +9172,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) thd->client_capabilities = 0; my_net_init(&thd->net, 0); thd->main_security_ctx.master_access= ~0; - thd->main_security_ctx.priv_user = 0; + thd->main_security_ctx.priv_user[0] = 0; CHARSET_INFO *charset_connection; charset_connection= get_charset_by_csname("utf8", @@ -10549,6 +10549,23 @@ mysql_declare_plugin(ndbcluster) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(ndbcluster) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &ndbcluster_storage_engine, + ndbcluster_hton_name, + "MySQL AB", + "Clustered, fault-tolerant tables", + PLUGIN_LICENSE_GPL, + ndbcluster_init, /* Plugin Init */ + NULL, /* Plugin Deinit */ + 0x0100 /* 1.0 */, + ndb_status_variables_export,/* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ +} +maria_declare_plugin_end; #else int Sun_ar_require_a_symbol_here= 0; diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 31bede644d9..31afaebc8cc 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -3682,7 +3682,7 @@ pthread_handler_t ndb_binlog_thread_func(void *arg) thd->client_capabilities= 0; my_net_init(&thd->net, 0); thd->main_security_ctx.master_access= ~0; - thd->main_security_ctx.priv_user= 0; + thd->main_security_ctx.priv_user[0]= 0; /* Set up ndb binlog diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index e70eacfab5d..412734faf23 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -54,6 +54,7 @@ #endif #include "mysql_priv.h" +#include "create_options.h" #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" @@ -1153,7 +1154,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, error != HA_ADMIN_ALREADY_DONE && error != HA_ADMIN_TRY_ALTER) { - print_admin_msg(thd, "error", table_share->db.str, table->alias, + print_admin_msg(thd, "error", table_share->db.str, + table->alias.c_ptr(), opt_op_name[flag], "Subpartition %s returned error", sub_elem->partition_name); @@ -1180,7 +1182,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, error != HA_ADMIN_ALREADY_DONE && error != HA_ADMIN_TRY_ALTER) { - print_admin_msg(thd, "error", table_share->db.str, table->alias, + print_admin_msg(thd, "error", table_share->db.str, + table->alias.c_ptr(), opt_op_name[flag], "Partition %s returned error", part_elem->partition_name); } @@ -1723,11 +1726,11 @@ int ha_partition::copy_partitions(ulonglong * const copied, uint32 new_part; late_extra_cache(reorg_part); - if ((result= file->ha_rnd_init(1))) + if ((result= file->ha_rnd_init_with_error(1))) goto error; while (TRUE) { - if ((result= file->rnd_next(m_rec0))) + if ((result= file->ha_rnd_next(m_rec0))) { if (result == HA_ERR_RECORD_DELETED) continue; //Probably MyISAM @@ -1951,6 +1954,8 @@ uint ha_partition::del_ren_cre_table(const char *from, { if ((error= set_up_table_before_create(table_arg, from_buff, create_info, i, NULL)) || + parse_engine_table_options(ha_thd(), (*file)->ht, + (*file)->table_share) || ((error= (*file)->ha_create(from_buff, table_arg, create_info)))) goto create_error; } @@ -2457,7 +2462,7 @@ bool ha_partition::read_par_file(const char *name) fn_format(buff, name, "", ha_par_ext, MY_APPEND_EXT); /* Following could be done with my_stat to read in whole file */ - if ((file= my_open(buff, O_RDONLY | O_SHARE, MYF(0))) < 0) + if ((file= my_open(buff, O_RDONLY | O_SHARE, MYF(MY_WME))) < 0) DBUG_RETURN(true); if (my_read(file, (uchar *) & buff[0], PAR_WORD_SIZE, MYF(MY_NABP))) goto err1; @@ -2564,7 +2569,7 @@ bool ha_partition::setup_engine_array(MEM_ROOT *mem_root) for (i= 0; i < m_tot_parts; i++) m_engine_array[i]= ha_lock_engine(NULL, engine_array[i]); - my_afree((gptr) engine_array); + my_afree(engine_array); if (create_handlers(mem_root)) { @@ -2575,7 +2580,7 @@ bool ha_partition::setup_engine_array(MEM_ROOT *mem_root) DBUG_RETURN(false); err: - my_afree((gptr) engine_array); + my_afree(engine_array); DBUG_RETURN(true); } @@ -2676,7 +2681,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) name_buffer_ptr= m_name_buffer_ptr; m_start_key.length= 0; m_rec0= table->record[0]; - m_rec_length= table_share->reclength; + m_rec_length= table_share->stored_rec_length; alloc_len= m_tot_parts * (m_rec_length + PARTITION_BYTES_IN_POS); alloc_len+= table_share->max_key_length; if (!m_ordered_rec_buffer) @@ -3941,6 +3946,7 @@ int ha_partition::rnd_next(uchar *buf) int result= HA_ERR_END_OF_FILE; uint part_id= m_part_spec.start_part; DBUG_ENTER("ha_partition::rnd_next"); + decrement_statistics(&SSV::ha_read_rnd_next_count); if (NO_CURRENT_PART_ID == part_id) { @@ -3956,7 +3962,7 @@ int ha_partition::rnd_next(uchar *buf) while (TRUE) { - result= file->rnd_next(buf); + result= file->ha_rnd_next(buf); if (!result) { m_last_part= part_id; @@ -4088,6 +4094,7 @@ int ha_partition::rnd_pos(uchar * buf, uchar *pos) uint part_id; handler *file; DBUG_ENTER("ha_partition::rnd_pos"); + decrement_statistics(&SSV::ha_read_rnd_count); part_id= uint2korr((const uchar *) pos); DBUG_ASSERT(part_id < m_tot_parts); @@ -4300,6 +4307,7 @@ int ha_partition::index_read_map(uchar *buf, const uchar *key, enum ha_rkey_function find_flag) { DBUG_ENTER("ha_partition::index_read_map"); + decrement_statistics(&SSV::ha_read_key_count); end_range= 0; m_index_scan_type= partition_index_read; m_start_key.key= key; @@ -4428,6 +4436,7 @@ int ha_partition::common_index_read(uchar *buf, bool have_start_key) int ha_partition::index_first(uchar * buf) { DBUG_ENTER("ha_partition::index_first"); + decrement_statistics(&SSV::ha_read_first_count); end_range= 0; m_index_scan_type= partition_index_first; @@ -4459,6 +4468,7 @@ int ha_partition::index_first(uchar * buf) int ha_partition::index_last(uchar * buf) { DBUG_ENTER("ha_partition::index_last"); + decrement_statistics(&SSV::ha_read_last_count); m_index_scan_type= partition_index_last; DBUG_RETURN(common_first_last(buf)); @@ -4487,39 +4497,6 @@ int ha_partition::common_first_last(uchar *buf) /* - Read last using key - - SYNOPSIS - index_read_last_map() - buf Read row in MySQL Row Format - key Key - keypart_map Which part of key is used - - RETURN VALUE - >0 Error code - 0 Success - - DESCRIPTION - This is used in join_read_last_key to optimise away an ORDER BY. - Can only be used on indexes supporting HA_READ_ORDER -*/ - -int ha_partition::index_read_last_map(uchar *buf, const uchar *key, - key_part_map keypart_map) -{ - DBUG_ENTER("ha_partition::index_read_last"); - - m_ordered= TRUE; // Safety measure - end_range= 0; - m_index_scan_type= partition_index_read_last; - m_start_key.key= key; - m_start_key.keypart_map= keypart_map; - m_start_key.flag= HA_READ_PREFIX_LAST; - DBUG_RETURN(common_index_read(buf, TRUE)); -} - - -/* Optimization of the default implementation to take advantage of dynamic partition pruning. */ @@ -4595,6 +4572,7 @@ int ha_partition::index_read_idx_map(uchar *buf, uint index, int ha_partition::index_next(uchar * buf) { DBUG_ENTER("ha_partition::index_next"); + decrement_statistics(&SSV::ha_read_next_count); /* TODO(low priority): @@ -4631,6 +4609,7 @@ int ha_partition::index_next(uchar * buf) int ha_partition::index_next_same(uchar *buf, const uchar *key, uint keylen) { DBUG_ENTER("ha_partition::index_next_same"); + decrement_statistics(&SSV::ha_read_next_count); DBUG_ASSERT(keylen == m_start_key.length); DBUG_ASSERT(m_index_scan_type != partition_index_last); @@ -4658,6 +4637,7 @@ int ha_partition::index_next_same(uchar *buf, const uchar *key, uint keylen) int ha_partition::index_prev(uchar * buf) { DBUG_ENTER("ha_partition::index_prev"); + decrement_statistics(&SSV::ha_read_prev_count); /* TODO: read comment in index_next */ DBUG_ASSERT(m_index_scan_type != partition_index_first); @@ -4870,8 +4850,8 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same) } else if (is_next_same) { - if (!(error= file->index_next_same(buf, m_start_key.key, - m_start_key.length))) + if (!(error= file->ha_index_next_same(buf, m_start_key.key, + m_start_key.length))) { m_last_part= m_part_spec.start_part; DBUG_RETURN(0); @@ -4879,7 +4859,7 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same) } else { - if (!(error= file->index_next(buf))) + if (!(error= file->ha_index_next(buf))) { m_last_part= m_part_spec.start_part; DBUG_RETURN(0); // Row was in range @@ -4934,13 +4914,13 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf) break; case partition_index_read: DBUG_PRINT("info", ("index_read on partition %d", i)); - error= file->index_read_map(buf, m_start_key.key, - m_start_key.keypart_map, - m_start_key.flag); + error= file->ha_index_read_map(buf, m_start_key.key, + m_start_key.keypart_map, + m_start_key.flag); break; case partition_index_first: DBUG_PRINT("info", ("index_first on partition %d", i)); - error= file->index_first(buf); + error= file->ha_index_first(buf); break; case partition_index_first_unordered: /* @@ -5021,23 +5001,17 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) switch (m_index_scan_type) { case partition_index_read: - error= file->index_read_map(rec_buf_ptr, - m_start_key.key, - m_start_key.keypart_map, - m_start_key.flag); + error= file->ha_index_read_map(rec_buf_ptr, + m_start_key.key, + m_start_key.keypart_map, + m_start_key.flag); break; case partition_index_first: - error= file->index_first(rec_buf_ptr); + error= file->ha_index_first(rec_buf_ptr); reverse_order= FALSE; break; case partition_index_last: - error= file->index_last(rec_buf_ptr); - reverse_order= TRUE; - break; - case partition_index_read_last: - error= file->index_read_last_map(rec_buf_ptr, - m_start_key.key, - m_start_key.keypart_map); + error= file->ha_index_last(rec_buf_ptr); reverse_order= TRUE; break; case partition_read_range: @@ -5139,10 +5113,10 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) memcpy(rec_buf(part_id), table->record[0], m_rec_length); } else if (!is_next_same) - error= file->index_next(rec_buf(part_id)); + error= file->ha_index_next(rec_buf(part_id)); else - error= file->index_next_same(rec_buf(part_id), m_start_key.key, - m_start_key.length); + error= file->ha_index_next_same(rec_buf(part_id), m_start_key.key, + m_start_key.length); if (error) { if (error == HA_ERR_END_OF_FILE) @@ -5187,7 +5161,7 @@ int ha_partition::handle_ordered_prev(uchar *buf) handler *file= m_file[part_id]; DBUG_ENTER("ha_partition::handle_ordered_prev"); - if ((error= file->index_prev(rec_buf(part_id)))) + if ((error= file->ha_index_prev(rec_buf(part_id)))) { if (error == HA_ERR_END_OF_FILE) { @@ -7148,5 +7122,22 @@ mysql_declare_plugin(partition) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(partition) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &partition_storage_engine, + "partition", + "Mikael Ronstrom, MySQL AB", + "Partition Storage Engine Helper", + PLUGIN_LICENSE_GPL, + partition_initialize, /* Plugin Init */ + NULL, /* Plugin Deinit */ + 0x0100, /* 1.0 */ + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +} +maria_declare_plugin_end; #endif diff --git a/sql/ha_partition.h b/sql/ha_partition.h index adb8214aae4..73d1c25c0c4 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -76,9 +76,8 @@ private: partition_index_first= 1, partition_index_first_unordered= 2, partition_index_last= 3, - partition_index_read_last= 4, - partition_read_range = 5, - partition_no_index_scan= 6 + partition_read_range = 4, + partition_no_index_scan= 5 }; /* Data for the partition handler */ int m_mode; // Open mode @@ -493,8 +492,6 @@ public: virtual int index_first(uchar * buf); virtual int index_last(uchar * buf); virtual int index_next_same(uchar * buf, const uchar * key, uint keylen); - virtual int index_read_last_map(uchar * buf, const uchar * key, - key_part_map keypart_map); /* read_first_row is virtual method but is only implemented by @@ -1147,4 +1144,27 @@ public: ------------------------------------------------------------------------- virtual void append_create_info(String *packet) */ + + /* + the following heavily relies on the fact that all partitions + are in the same storage engine. + + When this limitation is lifted, the following hack should go away, + and a proper interface for engines needs to be introduced: + + an PARTITION_SHARE structure that has a pointer to the TABLE_SHARE. + is given to engines everywhere where TABLE_SHARE is used now + has members like option_struct, ha_data + perhaps TABLE needs to be split the same way too... + + this can also be done before partition will support a mix of engines, + but preferably together with other incompatible API changes. + */ + virtual handlerton *partition_ht() const + { + handlerton *h= m_file[0]->ht; + for (uint i=1; i < m_tot_parts; i++) + DBUG_ASSERT(h == m_file[i]->ht); + return h; + } }; diff --git a/sql/handler.cc b/sql/handler.cc index 3993fad1f9a..1f6a3b9f665 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -25,6 +25,7 @@ #endif #include "mysql_priv.h" +#include "create_options.h" #include "rpl_filter.h" #include <myisampack.h> #include "myisam.h" @@ -59,7 +60,7 @@ static const LEX_STRING sys_table_aliases[]= { C_STRING_WITH_LEN("NDB") }, { C_STRING_WITH_LEN("NDBCLUSTER") }, { C_STRING_WITH_LEN("HEAP") }, { C_STRING_WITH_LEN("MEMORY") }, { C_STRING_WITH_LEN("MERGE") }, { C_STRING_WITH_LEN("MRG_MYISAM") }, - { C_STRING_WITH_LEN("Aria") }, { C_STRING_WITH_LEN("Maria") }, + { C_STRING_WITH_LEN("Maria") }, { C_STRING_WITH_LEN("Aria") }, {NullS, 0} }; @@ -1247,6 +1248,7 @@ int ha_commit_one_phase(THD *thd, bool all) my_error(ER_ERROR_DURING_COMMIT, MYF(0), err); error=1; } + /* Should this be done only if is_real_trans is set ? */ status_var_increment(thd->status_var.ha_commit_count); ha_info_next= ha_info->next(); ha_info->reset(); /* keep it conveniently zero-filled */ @@ -1348,9 +1350,14 @@ int ha_rollback_trans(THD *thd, bool all) slave SQL thread, it would not stop the thread but just be printed in the error log; but we don't want users to wonder why they have this message in the error log, so we don't send it. + + We don't have to test for thd->killed == THD::KILL_SYSTEM_THREAD as + it doesn't matter if a warning is pushed to a system thread or not: + No one will see it... */ if (is_real_trans && thd->transaction.all.modified_non_trans_table && - !thd->slave_thread && thd->killed != THD::KILL_CONNECTION) + !thd->slave_thread && thd->killed != THD::KILL_CONNECTION && + thd->killed != THD::KILL_SERVER) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARNING_NOT_COMPLETE_ROLLBACK, ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)); @@ -2013,7 +2020,8 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, dummy_share.db.length= strlen(db); dummy_share.table_name.str= (char*) alias; dummy_share.table_name.length= strlen(alias); - dummy_table.alias= alias; + dummy_table.alias.set(alias, dummy_share.table_name.length, + table_alias_charset); file->change_table_ptr(&dummy_table, &dummy_share); @@ -2084,11 +2092,6 @@ double handler::keyread_time(uint index, uint ranges, ha_rows rows) return (rows + keys_per_block - 1)/ keys_per_block; } -void handler::ha_statistic_increment(ulong SSV::*offset) const -{ - status_var_increment(table->in_use->status_var.*offset); -} - void **handler::ha_data(THD *thd) const { return thd_ha_data(thd, ht); @@ -2153,10 +2156,24 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, dup_ref=ref+ALIGN_SIZE(ref_length); cached_table_flags= table_flags(); } + rows_read= rows_changed= 0; + memset(index_rows_read, 0, sizeof(index_rows_read)); DBUG_RETURN(error); } +/* Initialize handler for random reading, with error handling */ + +int handler::ha_rnd_init_with_error(bool scan) +{ + int error; + if (!(error= ha_rnd_init(scan))) + return 0; + table->file->print_error(error, MYF(0)); + return error; +} + + /** Read first row (only) from a table. @@ -2168,8 +2185,6 @@ int handler::read_first_row(uchar * buf, uint primary_key) register int error; DBUG_ENTER("handler::read_first_row"); - ha_statistic_increment(&SSV::ha_read_first_count); - /* If there is very few deleted rows in the table, find the first row by scanning the table. @@ -2178,15 +2193,17 @@ int handler::read_first_row(uchar * buf, uint primary_key) if (stats.deleted < 10 || primary_key >= MAX_KEY || !(index_flags(primary_key, 0, 0) & HA_READ_ORDER)) { - (void) ha_rnd_init(1); - while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ; - (void) ha_rnd_end(); + if ((!(error= ha_rnd_init(1)))) + { + while ((error= ha_rnd_next(buf)) == HA_ERR_RECORD_DELETED) ; + (void) ha_rnd_end(); + } } else { /* Find the first row through the primary key */ if (!(error = ha_index_init(primary_key, 0))) - error= index_first(buf); + error= ha_index_first(buf); (void) ha_index_end(); } DBUG_RETURN(error); @@ -2574,7 +2591,7 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, ha_index_init(table->s->next_number_index, 1); if (table->s->next_number_keypart == 0) { // Autoincrement at key-start - error=index_last(table->record[1]); + error=ha_index_last(table->record[1]); /* MySQL implicitely assumes such method does locking (as MySQL decides to use nr+increment without checking again with the handler, in @@ -2588,9 +2605,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, key_copy(key, table->record[0], table->key_info + table->s->next_number_index, table->s->next_number_key_offset); - error= index_read_map(table->record[1], key, - make_prev_keypart_map(table->s->next_number_keypart), - HA_READ_PREFIX_LAST); + error= ha_index_read_map(table->record[1], key, + make_prev_keypart_map(table->s-> + next_number_keypart), + HA_READ_PREFIX_LAST); /* MySQL needs to call us for next row: assume we are inserting ("a",null) here, we return 3, and next this statement will want to insert @@ -2882,11 +2900,12 @@ void handler::print_error(int error, myf errflag) { const char* engine= table_type(); if (temporary) - my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), engine); + my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.c_ptr(), + engine); else { SET_FATAL_ERROR; - my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine); + my_error(ER_GET_ERRMSG, MYF(0), error, str.c_ptr(), engine); } } else @@ -3213,11 +3232,14 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) if it is started. */ -inline void -handler::mark_trx_read_write() +handler::mark_trx_read_write_part2() { Ha_trx_info *ha_info= &ha_thd()->ha_data[ht->slot].ha_info[0]; + + /* Don't call this function again for this statement */ + mark_trx_done= TRUE; + /* When a storage engine method is called, the transaction must have been started, unless it's a DDL call, for which the @@ -3598,7 +3620,7 @@ int ha_enable_transaction(THD *thd, bool on) int handler::index_next_same(uchar *buf, const uchar *key, uint keylen) { int error; - DBUG_ENTER("index_next_same"); + DBUG_ENTER("handler::index_next_same"); if (!(error=index_next(buf))) { my_ptrdiff_t ptrdiff= buf - table->record[0]; @@ -3643,6 +3665,7 @@ int handler::index_next_same(uchar *buf, const uchar *key, uint keylen) key_part->field->move_field_offset(-ptrdiff); } } + DBUG_PRINT("return",("%i", error)); DBUG_RETURN(error); } @@ -3668,6 +3691,122 @@ void handler::get_dynamic_partition_info(PARTITION_INFO *stat_info, } +/* + Updates the global table stats with the TABLE this handler represents +*/ + +void handler::update_global_table_stats() +{ + TABLE_STATS * table_stats; + + status_var_add(table->in_use->status_var.rows_read, rows_read); + + if (!table->in_use->userstat_running) + { + rows_read= rows_changed= 0; + return; + } + + if (rows_read + rows_changed == 0) + return; // Nothing to update. + + DBUG_ASSERT(table->s && table->s->table_cache_key.str); + + pthread_mutex_lock(&LOCK_global_table_stats); + /* Gets the global table stats, creating one if necessary. */ + if (!(table_stats= (TABLE_STATS*) + hash_search(&global_table_stats, + (uchar*) table->s->table_cache_key.str, + table->s->table_cache_key.length))) + { + if (!(table_stats = ((TABLE_STATS*) + my_malloc(sizeof(TABLE_STATS), + MYF(MY_WME | MY_ZEROFILL))))) + { + /* Out of memory error already given */ + goto end; + } + memcpy(table_stats->table, table->s->table_cache_key.str, + table->s->table_cache_key.length); + table_stats->table_name_length= table->s->table_cache_key.length; + table_stats->engine_type= ht->db_type; + /* No need to set variables to 0, as we use MY_ZEROFILL above */ + + if (my_hash_insert(&global_table_stats, (uchar*) table_stats)) + { + /* Out of memory error is already given */ + my_free(table_stats, 0); + goto end; + } + } + // Updates the global table stats. + table_stats->rows_read+= rows_read; + table_stats->rows_changed+= rows_changed; + table_stats->rows_changed_x_indexes+= (rows_changed * + (table->s->keys ? table->s->keys : + 1)); + rows_read= rows_changed= 0; +end: + pthread_mutex_unlock(&LOCK_global_table_stats); +} + + +/* + Updates the global index stats with this handler's accumulated index reads. +*/ + +void handler::update_global_index_stats() +{ + DBUG_ASSERT(table->s); + + if (!table->in_use->userstat_running) + { + /* Reset all index read values */ + bzero(index_rows_read, sizeof(index_rows_read[0]) * table->s->keys); + return; + } + + for (uint index = 0; index < table->s->keys; index++) + { + if (index_rows_read[index]) + { + INDEX_STATS* index_stats; + uint key_length; + KEY *key_info = &table->key_info[index]; // Rows were read using this + + DBUG_ASSERT(key_info->cache_name); + if (!key_info->cache_name) + continue; + key_length= table->s->table_cache_key.length + key_info->name_length + 1; + pthread_mutex_lock(&LOCK_global_index_stats); + // Gets the global index stats, creating one if necessary. + if (!(index_stats= (INDEX_STATS*) hash_search(&global_index_stats, + key_info->cache_name, + key_length))) + { + if (!(index_stats = ((INDEX_STATS*) + my_malloc(sizeof(INDEX_STATS), + MYF(MY_WME | MY_ZEROFILL))))) + goto end; // Error is already given + + memcpy(index_stats->index, key_info->cache_name, key_length); + index_stats->index_name_length= key_length; + if (my_hash_insert(&global_index_stats, (uchar*) index_stats)) + { + my_free(index_stats, 0); + goto end; + } + } + /* Updates the global index stats. */ + index_stats->rows_read+= index_rows_read[index]; + index_rows_read[index]= 0; +end: + pthread_mutex_unlock(&LOCK_global_index_stats); + } + } +} + + /**************************************************************************** ** Some general functions that isn't in the handler class ****************************************************************************/ @@ -3704,6 +3843,7 @@ int ha_create_table(THD *thd, const char *path, name= get_canonical_filename(table.file, share.path.str, name_buff); error= table.file->ha_create(name, &table, create_info); + VOID(closefrm(&table, 0)); if (error) { @@ -3811,11 +3951,13 @@ int ha_init_key_cache(const char *name, KEY_CACHE *key_cache) uint tmp_block_size= (uint) key_cache->param_block_size; uint division_limit= key_cache->param_division_limit; uint age_threshold= key_cache->param_age_threshold; + uint partitions= key_cache->param_partitions; pthread_mutex_unlock(&LOCK_global_system_variables); DBUG_RETURN(!init_key_cache(key_cache, tmp_block_size, tmp_buff_size, - division_limit, age_threshold)); + division_limit, age_threshold, + partitions)); } DBUG_RETURN(0); } @@ -3845,10 +3987,12 @@ int ha_resize_key_cache(KEY_CACHE *key_cache) /** - Change parameters for key cache (like size) + Change parameters for key cache (like division_limit) */ int ha_change_key_cache_param(KEY_CACHE *key_cache) { + DBUG_ENTER("ha_change_key_cache_param"); + if (key_cache->key_cache_inited) { pthread_mutex_lock(&LOCK_global_system_variables); @@ -3857,9 +4001,35 @@ int ha_change_key_cache_param(KEY_CACHE *key_cache) pthread_mutex_unlock(&LOCK_global_system_variables); change_key_cache_param(key_cache, division_limit, age_threshold); } - return 0; + DBUG_RETURN(0); } + +/** + Repartition key cache +*/ +int ha_repartition_key_cache(KEY_CACHE *key_cache) +{ + DBUG_ENTER("ha_repartition_key_cache"); + + if (key_cache->key_cache_inited) + { + pthread_mutex_lock(&LOCK_global_system_variables); + size_t tmp_buff_size= (size_t) key_cache->param_buff_size; + long tmp_block_size= (long) key_cache->param_block_size; + uint division_limit= key_cache->param_division_limit; + uint age_threshold= key_cache->param_age_threshold; + uint partitions= key_cache->param_partitions; + pthread_mutex_unlock(&LOCK_global_system_variables); + DBUG_RETURN(!repartition_key_cache(key_cache, tmp_block_size, + tmp_buff_size, + division_limit, age_threshold, + partitions)); + } + DBUG_RETURN(0); +} + + /** Free memory allocated by a key cache. */ @@ -4328,17 +4498,16 @@ int handler::read_range_first(const key_range *start_key, range_key_part= table->key_info[active_index].key_part; if (!start_key) // Read first record - result= index_first(table->record[0]); + result= ha_index_first(table->record[0]); else - result= index_read_map(table->record[0], - start_key->key, - start_key->keypart_map, - start_key->flag); + result= ha_index_read_map(table->record[0], + start_key->key, + start_key->keypart_map, + start_key->flag); if (result) DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND) ? HA_ERR_END_OF_FILE : result); - DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE); } @@ -4364,11 +4533,11 @@ int handler::read_range_next() if (eq_range) { /* We trust that index_next_same always gives a row in range */ - DBUG_RETURN(index_next_same(table->record[0], - end_range->key, - end_range->length)); + DBUG_RETURN(ha_index_next_same(table->record[0], + end_range->key, + end_range->length)); } - result= index_next(table->record[0]); + result= ha_index_next(table->record[0]); if (result) DBUG_RETURN(result); DBUG_RETURN(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE); @@ -4549,6 +4718,8 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) if (!result) my_eof(thd); + else if (!thd->is_error()) + my_error(ER_GET_ERRNO, MYF(0), 0); return result; } @@ -4750,9 +4921,11 @@ int handler::ha_write_row(uchar *buf) DBUG_ENTER("handler::ha_write_row"); mark_trx_read_write(); + increment_statistics(&SSV::ha_write_count); if (unlikely(error= write_row(buf))) DBUG_RETURN(error); + rows_changed++; if (unlikely(error= binlog_log_row(table, 0, buf, log_func))) DBUG_RETURN(error); /* purecov: inspected */ DBUG_RETURN(0); @@ -4771,9 +4944,11 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data) DBUG_ASSERT(new_data == table->record[0]); mark_trx_read_write(); + increment_statistics(&SSV::ha_update_count); if (unlikely(error= update_row(old_data, new_data))) return error; + rows_changed++; if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func))) return error; return 0; @@ -4785,9 +4960,11 @@ int handler::ha_delete_row(const uchar *buf) Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function; mark_trx_read_write(); + increment_statistics(&SSV::ha_delete_count); if (unlikely(error= delete_row(buf))) return error; + rows_changed++; if (unlikely(error= binlog_log_row(table, buf, 0, log_func))) return error; return 0; diff --git a/sql/handler.h b/sql/handler.h index e8f6abdca65..79e838d2ca6 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -18,6 +18,9 @@ /* Definitions for parameters to do with handler-routines */ +#ifndef SQL_HANDLER_INCLUDED +#define SQL_HANDLER_INCLUDED + #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ #endif @@ -31,6 +34,10 @@ #define USING_TRANSACTIONS +#if MAX_KEY > 128 +#error MAX_KEY is too large. Values up to 128 are supported. +#endif + // the following is for checking tables #define HA_ADMIN_ALREADY_DONE 1 @@ -131,6 +138,7 @@ #define HA_BINLOG_STMT_CAPABLE (LL(1) << 35) /* Has automatic checksums and uses the new checksum format */ #define HA_HAS_NEW_CHECKSUM (LL(1) << 36) +#define HA_CAN_VIRTUAL_COLUMNS (LL(1) << 37) /* Set of all binlog flags. Currently only contain the capabilities @@ -549,6 +557,108 @@ struct handler_log_file_data { enum log_status status; }; +/* + Definitions for engine-specific table/field/index options in the CREATE TABLE. + + Options are declared with HA_*OPTION_* macros (HA_TOPTION_NUMBER, + HA_FOPTION_ENUM, HA_IOPTION_STRING, etc). + + Every macros takes the option name, and the name of the underlying field of + the appropriate C structure. The "appropriate C structure" is + ha_table_option_struct for table level options, + ha_field_option_struct for field level options, + ha_index_option_struct for key level options. The engine either + defines a structure of this name, or uses #define's to map + these "appropriate" names to the actual structure type name. + + ULL options use a ulonglong as the backing store. + HA_*OPTION_NUMBER() takes the option name, the structure field name, + the default value for the option, min, max, and blk_siz values. + + STRING options use a char* as a backing store. + HA_*OPTION_STRING takes the option name and the structure field name. + The default value will be 0. + + ENUM options use a uint as a backing store (not enum!!!). + HA_*OPTION_ENUM takes the option name, the structure field name, + the default value for the option as a number, and a string with the + permitted values for this enum - one string with comma separated values, + for example: "gzip,bzip2,lzma" + + BOOL options use a bool as a backing store. + HA_*OPTION_BOOL takes the option name, the structure field name, + and the default value for the option. + From the SQL, BOOL options accept YES/NO, ON/OFF, and 1/0. + + The name of the option is limited to 255 bytes, + the value (for string options) - to the 32767 bytes. + + See ha_example.cc for an example. +*/ + +struct ha_table_option_struct; +struct ha_field_option_struct; +struct ha_index_option_struct; + +enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */ + HA_OPTION_TYPE_STRING, /* char * */ + HA_OPTION_TYPE_ENUM, /* uint */ + HA_OPTION_TYPE_BOOL}; /* bool */ + +#define HA_xOPTION_NUMBER(name, struc, field, def, min, max, blk_siz) \ + { HA_OPTION_TYPE_ULL, name, sizeof(name)-1, \ + offsetof(struc, field), def, min, max, blk_siz, 0 } +#define HA_xOPTION_STRING(name, struc, field) \ + { HA_OPTION_TYPE_STRING, name, sizeof(name)-1, \ + offsetof(struc, field), 0, 0, 0, 0, 0 } +#define HA_xOPTION_ENUM(name, struc, field, values, def) \ + { HA_OPTION_TYPE_ENUM, name, sizeof(name)-1, \ + offsetof(struc, field), def, 0, \ + sizeof(values)-1, 0, values } +#define HA_xOPTION_BOOL(name, struc, field, def) \ + { HA_OPTION_TYPE_BOOL, name, sizeof(name)-1, \ + offsetof(struc, field), def, 0, 1, 0, 0 } +#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0 } + +#define HA_TOPTION_NUMBER(name, field, def, min, max, blk_siz) \ + HA_xOPTION_NUMBER(name, ha_table_option_struct, field, def, min, max, blk_siz) +#define HA_TOPTION_STRING(name, field) \ + HA_xOPTION_STRING(name, ha_table_option_struct, field) +#define HA_TOPTION_ENUM(name, field, values, def) \ + HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def) +#define HA_TOPTION_BOOL(name, field, def) \ + HA_xOPTION_BOOL(name, ha_table_option_struct, field, def) +#define HA_TOPTION_END HA_xOPTION_END + +#define HA_FOPTION_NUMBER(name, field, def, min, max, blk_siz) \ + HA_xOPTION_NUMBER(name, ha_field_option_struct, field, def, min, max, blk_siz) +#define HA_FOPTION_STRING(name, field) \ + HA_xOPTION_STRING(name, ha_field_option_struct, field) +#define HA_FOPTION_ENUM(name, field, values, def) \ + HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def) +#define HA_FOPTION_BOOL(name, field, def) \ + HA_xOPTION_BOOL(name, ha_field_option_struct, field, def) +#define HA_FOPTION_END HA_xOPTION_END + +#define HA_IOPTION_NUMBER(name, field, def, min, max, blk_siz) \ + HA_xOPTION_NUMBER(name, ha_index_option_struct, field, def, min, max, blk_siz) +#define HA_IOPTION_STRING(name, field) \ + HA_xOPTION_STRING(name, ha_index_option_struct, field) +#define HA_IOPTION_ENUM(name, field, values, def) \ + HA_xOPTION_ENUM(name, ha_index_option_struct, field, values, def) +#define HA_IOPTION_BOOL(name, field, values, def) \ + HA_xOPTION_BOOL(name, ha_index_option_struct, field, values, def) +#define HA_IOPTION_END HA_xOPTION_END + +typedef struct st_ha_create_table_option { + enum ha_option_type type; + const char *name; + size_t name_length; + ptrdiff_t offset; + ulonglong def_value; + ulonglong min_value, max_value, block_size; + const char *values; +} ha_create_table_option; enum handler_iterator_type { @@ -609,8 +719,9 @@ struct handlerton SHOW_COMP_OPTION state; /* - Historical number used for frm file to determine the correct storage engine. - This is going away and new engines will just use "name" for this. + Historical number used for frm file to determine the correct + storage engine. This is going away and new engines will just use + "name" for this. */ enum legacy_db_type db_type; /* @@ -720,7 +831,13 @@ struct handlerton int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db, const char *name); uint32 license; /* Flag for Engine License */ - void *data; /* Location for engines to keep personal structures */ + /* + Optional clauses in the CREATE/ALTER TABLE + */ + ha_create_table_option *table_options; // table level options + ha_create_table_option *field_options; // these are specified per field + ha_create_table_option *index_options; // these are specified per index + }; @@ -736,7 +853,6 @@ inline LEX_STRING *hton_name(const handlerton *hton) #define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter #define HTON_CAN_RECREATE (1 << 2) //Delete all is used fro truncate #define HTON_HIDDEN (1 << 3) //Engine does not appear in lists -#define HTON_FLUSH_AFTER_RENAME (1 << 4) #define HTON_NOT_USER_SELECTABLE (1 << 5) #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported #define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables @@ -944,11 +1060,16 @@ typedef struct st_ha_create_information uint extra_size; /* length of extra data segment */ /** Transactional or not. Unused; reserved for future versions. */ enum ha_choice transactional; - bool table_existed; /* 1 in create if table existed */ - bool frm_only; /* 1 if no ha_create_table() */ - bool varchar; /* 1 if table has a VARCHAR */ - enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */ - enum ha_choice page_checksum; /* If we have page_checksums */ + bool table_existed; ///< 1 in create if table existed + bool frm_only; ///< 1 if no ha_create_table() + bool varchar; ///< 1 if table has a VARCHAR + enum ha_storage_media storage_media; ///< DEFAULT, DISK or MEMORY + enum ha_choice page_checksum; ///< If we have page_checksums + engine_option_value *option_list; ///< list of table create options + /* the following three are only for ALTER TABLE, check_if_incompatible_data() */ + ha_table_option_struct *option_struct; ///< structure with parsed table options + ha_field_option_struct **fields_option_struct; ///< array of field option structures + ha_index_option_struct **indexes_option_struct; ///< array of index option structures } HA_CREATE_INFO; @@ -1134,6 +1255,7 @@ public: enum {NONE=0, INDEX, RND} inited; bool locked; bool implicit_emptied; /* Can be !=0 only if HEAP */ + bool mark_trx_done; bool cloned; /* 1 if this was created with clone */ const COND *pushed_cond; /** @@ -1157,6 +1279,12 @@ public: Interval returned by get_auto_increment() and being consumed by the inserter. */ + /* Statistics variables */ + ulonglong rows_read; + ulonglong rows_changed; + /* One bigger than needed to avoid to test if key == MAX_KEY */ + ulonglong index_rows_read[MAX_KEY+1]; + Discrete_interval auto_inc_interval_for_cur_row; /** Number of reserved auto-increment intervals. Serves as a heuristic @@ -1172,10 +1300,13 @@ public: ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY), ref_length(sizeof(my_off_t)), ft_handler(0), inited(NONE), - locked(FALSE), implicit_emptied(0), cloned(0), + locked(FALSE), implicit_emptied(FALSE), mark_trx_done(FALSE), cloned(0), pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0), auto_inc_intervals_count(0) - {} + { + reset_statistics(); + } + virtual ~handler(void) { DBUG_ASSERT(locked == FALSE); @@ -1212,7 +1343,7 @@ public: } /* This is called after index_init() if we need to do a index scan */ virtual int prepare_index_scan() { return 0; } - int ha_rnd_init(bool scan) + int ha_rnd_init(bool scan) __attribute__ ((warn_unused_result)) { int result; DBUG_ENTER("ha_rnd_init"); @@ -1227,7 +1358,15 @@ public: inited=NONE; DBUG_RETURN(rnd_end()); } + int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result)); int ha_reset(); + /* Tell handler (not storage engine) this is start of a new statement */ + void ha_start_of_new_statement() + { + ft_handler= 0; + mark_trx_done= FALSE; + } + /* this is necessary in many places, e.g. in HANDLER command */ int ha_index_or_rnd_end() { @@ -1301,10 +1440,16 @@ public: virtual void print_error(int error, myf errflag); virtual bool get_error_message(int error, String *buf); uint get_dup_key(int error); + void reset_statistics() + { + rows_read= rows_changed= 0; + bzero(index_rows_read, sizeof(index_rows_read)); + } virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) { table= table_arg; table_share= share; + reset_statistics(); } virtual double scan_time() { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; } @@ -1428,22 +1573,23 @@ public: } /** @brief - Positions an index cursor to the index specified in the handle. Fetches the - row if available. If the key value is null, begin at the first key of the - index. + Positions an index cursor to the index specified in the + handle. Fetches the row if available. If the key value is null, + begin at the first key of the index. */ +protected: virtual int index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) { uint key_len= calculate_key_len(table, active_index, key, keypart_map); - return index_read(buf, key, key_len, find_flag); + return index_read(buf, key, key_len, find_flag); } /** @brief - Positions an index cursor to the index specified in the handle. Fetches the - row if available. If the key value is null, begin at the first key of the - index. + Positions an index cursor to the index specified in the + handle. Fetches the row if available. If the key value is null, + begin at the first key of the index. */ virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key, key_part_map keypart_map, @@ -1457,17 +1603,26 @@ public: virtual int index_last(uchar * buf) { return HA_ERR_WRONG_COMMAND; } virtual int index_next_same(uchar *buf, const uchar *key, uint keylen); - /** - @brief - The following functions works like index_read, but it find the last - row with the current key value or prefix. - */ - virtual int index_read_last_map(uchar * buf, const uchar * key, - key_part_map keypart_map) + inline void update_index_statistics() { - uint key_len= calculate_key_len(table, active_index, key, keypart_map); - return index_read_last(buf, key, key_len); + index_rows_read[active_index]++; + rows_read++; } +public: + + /* Similar functions like the above, but does statistics counting */ + inline int ha_index_read_map(uchar * buf, const uchar * key, + key_part_map keypart_map, + enum ha_rkey_function find_flag); + inline int ha_index_read_idx_map(uchar * buf, uint index, const uchar * key, + key_part_map keypart_map, + enum ha_rkey_function find_flag); + inline int ha_index_next(uchar * buf); + inline int ha_index_prev(uchar * buf); + inline int ha_index_first(uchar * buf); + inline int ha_index_last(uchar * buf); + inline int ha_index_next_same(uchar *buf, const uchar *key, uint keylen); + virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p, KEY_MULTI_RANGE *ranges, uint range_count, bool sorted, HANDLER_BUFFER *buffer); @@ -1481,6 +1636,7 @@ public: void ft_end() { ft_handler=NULL; } virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key) { return NULL; } +private: virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; } virtual int rnd_next(uchar *buf)=0; virtual int rnd_pos(uchar * buf, uchar *pos)=0; @@ -1490,11 +1646,20 @@ public: It will return the row with the PK given in the record argument. */ virtual int rnd_pos_by_record(uchar *record) - { - position(record); - return rnd_pos(record, ref); - } + { + position(record); + return rnd_pos(record, ref); + } virtual int read_first_row(uchar *buf, uint primary_key); +public: + + /* Same as above, but with statistics */ + inline int ha_ft_read(uchar *buf); + inline int ha_rnd_next(uchar *buf); + inline int ha_rnd_pos(uchar *buf, uchar *pos); + inline int ha_rnd_pos_by_record(uchar *buf); + inline int ha_read_first_row(uchar *buf, uint primary_key); + /** The following 3 function is only needed for tables that may be internal temporary tables during joins. @@ -1670,6 +1835,9 @@ public: virtual bool is_crashed() const { return 0; } virtual bool auto_repair() const { return 0; } + void update_global_table_stats(); + void update_global_index_stats(); + #define CHF_CREATE_FLAG 0 #define CHF_DELETE_FLAG 1 #define CHF_RENAME_FLAG 2 @@ -1805,8 +1973,10 @@ public: LEX_STRING *engine_name() { return hton_name(ht); } protected: + /* deprecated, don't use in new engines */ + inline void ha_statistic_increment(ulong SSV::*offset) const { } + /* Service methods for use by storage engines. */ - void ha_statistic_increment(ulong SSV::*offset) const; void **ha_data(THD *) const; THD *ha_thd(void) const; @@ -1826,7 +1996,15 @@ protected: private: /* Private helpers */ - inline void mark_trx_read_write(); + void mark_trx_read_write_part2(); + inline void mark_trx_read_write() + { + if (!mark_trx_done) + mark_trx_read_write_part2(); + } + inline void increment_statistics(ulong SSV::*offset) const; + inline void decrement_statistics(ulong SSV::*offset) const; + /* Low-level primitives for storage engines. These should be overridden by the storage engine class. To call these methods, use @@ -1913,8 +2091,6 @@ private: virtual int index_read(uchar * buf, const uchar * key, uint key_len, enum ha_rkey_function find_flag) { return HA_ERR_WRONG_COMMAND; } - virtual int index_read_last(uchar * buf, const uchar * key, uint key_len) - { return (my_errno= HA_ERR_WRONG_COMMAND); } /** This method is similar to update_row, however the handler doesn't need to execute the updates at this point in time. The handler can be certain @@ -1987,6 +2163,11 @@ private: { return HA_ERR_WRONG_COMMAND; } virtual int rename_partitions(const char *path) { return HA_ERR_WRONG_COMMAND; } + friend class ha_partition; +public: + /* XXX to be removed, see ha_partition::partition_ht() */ + virtual handlerton *partition_ht() const + { return ht; } }; @@ -2069,6 +2250,7 @@ int ha_table_exists_in_engine(THD* thd, const char* db, const char* name); extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache); int ha_resize_key_cache(KEY_CACHE *key_cache); int ha_change_key_cache_param(KEY_CACHE *key_cache); +int ha_repartition_key_cache(KEY_CACHE *key_cache); int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache); int ha_end_key_cache(KEY_CACHE *key_cache); @@ -2122,3 +2304,5 @@ int ha_binlog_end(THD *thd); #define ha_binlog_wait(a) do {} while (0) #define ha_binlog_end(a) do {} while (0) #endif + +#endif diff --git a/sql/hash_filo.h b/sql/hash_filo.h index ab13d338695..8ddeeeb02fc 100644 --- a/sql/hash_filo.h +++ b/sql/hash_filo.h @@ -107,7 +107,7 @@ public: return entry; } - my_bool add(hash_filo_element *entry) + bool add(hash_filo_element *entry) { if (cache.records == size) { diff --git a/sql/item.cc b/sql/item.cc index 23294a6dbeb..c08333e4b80 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -429,8 +429,8 @@ Item::Item(THD *thd, Item *item): with_sum_func(item->with_sum_func), fixed(item->fixed), is_autogenerated_name(item->is_autogenerated_name), - collation(item->collation), with_subselect(item->with_subselect), + collation(item->collation), cmp_context(item->cmp_context) { next= thd->free_list; // Put in free list @@ -698,9 +698,24 @@ bool Item_field::register_field_in_read_map(uchar *arg) TABLE *table= (TABLE *) arg; if (field->table == table || !table) bitmap_set_bit(field->table->read_set, field->field_index); + if (field->vcol_info && field->vcol_info->expr_item) + return field->vcol_info->expr_item->walk(&Item::register_field_in_read_map, + 1, arg); return 0; } +/* + @brief + Mark field in bitmap supplied as *arg +*/ + +bool Item_field::register_field_in_bitmap(uchar *arg) +{ + MY_BITMAP *bitmap= (MY_BITMAP *) arg; + DBUG_ASSERT(bitmap); + bitmap_set_bit(bitmap, field->field_index); + return 0; +} bool Item::check_cols(uint c) { @@ -724,7 +739,8 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) } if (cs->ctype) { - uint orig_len= length; + const char *str_start= str; + /* This will probably need a better implementation in the future: a function in CHARSET_INFO structure. @@ -734,16 +750,20 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) length--; str++; } - if (orig_len != length && !is_autogenerated_name) + if (str != str_start && !is_autogenerated_name) { + char buff[SAFE_NAME_LEN]; + strmake(buff, str_start, + min(sizeof(buff)-1, length + (int) (str-str_start))); + if (length == 0) push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NAME_BECOMES_EMPTY, ER(ER_NAME_BECOMES_EMPTY), - str + length - orig_len); + buff); else push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_REMOVED_SPACES, ER(ER_REMOVED_SPACES), - str + length - orig_len); + buff); } } if (!my_charset_same(cs, system_charset_info)) @@ -2477,14 +2497,12 @@ double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end) tmp= my_strntod(cs, (char*) cptr, end - cptr, &end, &error); if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end))) { - /* - We can use str_value.ptr() here as Item_string is gurantee to put an - end \0 here. - */ + char buff[80]; + strmake(buff, cptr, min(sizeof(buff)-1, (size_t) (org_end-cptr))); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE, ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE", - cptr); + buff); } return tmp; } @@ -2493,8 +2511,10 @@ double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end) double Item_string::val_real() { DBUG_ASSERT(fixed == 1); - return double_from_string_with_check (str_value.charset(), str_value.ptr(), - (char *) str_value.ptr() + str_value.length()); + return double_from_string_with_check(str_value.charset(), + str_value.ptr(), + (char *) str_value.ptr() + + str_value.length()); } @@ -2801,7 +2821,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) unsigned_flag= entry->unsigned_flag; if (limit_clause_param) { - my_bool unused; + bool unused; set_int(entry->val_int(&unused), MY_INT64_NUM_DECIMAL_DIGITS); item_type= Item::INT_ITEM; DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0); @@ -4483,6 +4503,21 @@ error: return TRUE; } +/* + @brief + Mark virtual columns as used in a partitioning expression +*/ + +bool Item_field::vcol_in_partition_func_processor(uchar *int_arg) +{ + DBUG_ASSERT(fixed); + if (field->vcol_info) + { + field->vcol_info->mark_as_in_partitioning_expr(); + } + return FALSE; +} + Item *Item_field::safe_charset_converter(CHARSET_INFO *tocs) { diff --git a/sql/item.h b/sql/item.h index be2d340a4d3..0445cd4a9d5 100644 --- a/sql/item.h +++ b/sql/item.h @@ -18,6 +18,24 @@ #pragma interface /* gcc class implementation */ #endif +inline +bool trace_unsupported_func(const char *where, const char *processor_name) +{ + char buff[64]; + sprintf(buff, "%s::%s", where, processor_name); + DBUG_ENTER(buff); + sprintf(buff, "%s returns TRUE: unsupported function", processor_name); + DBUG_PRINT("info", ("%s", buff)); + DBUG_RETURN(TRUE); +} + +inline +bool trace_unsupported_by_check_vcol_func_processor(const char *where) +{ + return trace_unsupported_func(where, "check_vcol_func_processor"); +} + + class Protocol; struct TABLE_LIST; void item_init(void); /* Init item functions */ @@ -522,19 +540,19 @@ public: uint name_length; /* Length of name */ int8 marker; uint8 decimals; - my_bool maybe_null; /* If item may be null */ - my_bool in_rollup; /* If used in GROUP BY list + bool maybe_null; /* If item may be null */ + bool in_rollup; /* If used in GROUP BY list of a query with ROLLUP */ - my_bool null_value; /* if item is null */ - my_bool unsigned_flag; - my_bool with_sum_func; - my_bool fixed; /* If item fixed with fix_fields */ - my_bool is_autogenerated_name; /* indicate was name of this Item + bool null_value; /* if item is null */ + bool unsigned_flag; + bool with_sum_func; + bool fixed; /* If item fixed with fix_fields */ + bool is_autogenerated_name; /* indicate was name of this Item autogenerated or set by user */ - DTCollation collation; - my_bool with_subselect; /* If this item is a subselect or some + bool with_subselect; /* If this item is a subselect or some of its arguments is or contains a subselect */ + DTCollation collation; Item_result cmp_context; /* Comparison context */ // alloc & destruct is done as start of select using sql_alloc Item(); @@ -938,6 +956,11 @@ public: return FALSE; } /* + The next function differs from the previous one that a bitmap to be updated + is passed as uchar *arg. + */ + virtual bool register_field_in_bitmap(uchar *arg) { return 0; } + /* Check if a partition function is allowed SYNOPSIS check_partition_func_processor() @@ -989,11 +1012,43 @@ public: fields. */ virtual bool check_partition_func_processor(uchar *bool_arg) { return TRUE;} + /* + @brief + Processor used to mark virtual columns used in partitioning expression + + @param + arg always ignored + + @retval + FALSE always + */ + virtual bool vcol_in_partition_func_processor(uchar *arg) + { + return FALSE; + } + virtual bool subst_argument_checker(uchar **arg) - { + { if (*arg) - *arg= NULL; - return TRUE; + *arg= NULL; + return TRUE; + } + /* + @brief + Processor used to check acceptability of an item in the defining + expression for a virtual column + + @param + arg always ignored + + @retval + FALSE the item is accepted in the definition of a virtual column + @retval + TRUE otherwise + */ + virtual bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor(full_name()); } virtual Item *equal_fields_propagator(uchar * arg) { return this; } @@ -1402,6 +1457,10 @@ public: { return value_item->send(protocol, str); } + bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor("name_const"); + } }; bool agg_item_collations(DTCollation &c, const char *name, @@ -1421,6 +1480,7 @@ public: virtual Item_num *neg()= 0; Item *safe_charset_converter(CHARSET_INFO *tocs); bool check_partition_func_processor(uchar *int_arg) { return FALSE;} + bool check_vcol_func_processor(uchar *arg) { return FALSE;} }; #define NO_CACHED_FIELD_INDEX ((uint)(-1)) @@ -1581,7 +1641,10 @@ public: bool collect_item_field_processor(uchar * arg); bool find_item_in_field_list_processor(uchar *arg); bool register_field_in_read_map(uchar *arg); + bool register_field_in_bitmap(uchar *arg); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool vcol_in_partition_func_processor(uchar *bool_arg); + bool check_vcol_func_processor(uchar *arg) { return FALSE;} bool enumerate_field_refs_processor(uchar *arg); void cleanup(); bool result_as_longlong() @@ -1642,6 +1705,7 @@ public: Item *safe_charset_converter(CHARSET_INFO *tocs); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *arg) { return FALSE;} }; class Item_null_result :public Item_null @@ -1655,7 +1719,11 @@ public: save_in_field(result_field, no_conversions); } bool check_partition_func_processor(uchar *int_arg) {return TRUE;} -}; + bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor(full_name()); + } +}; /* Item represents one placeholder ('?') of prepared statement */ @@ -1796,6 +1864,7 @@ public: /** Item is a argument to a limit clause. */ bool limit_clause_param; void set_param_type_and_swap_value(Item_param *from); + }; @@ -1831,6 +1900,7 @@ public: { return (uint)(max_length - test(value < 0)); } bool eq(const Item *, bool binary_cmp) const; bool check_partition_func_processor(uchar *bool_arg) { return FALSE;} + bool check_vcol_func_processor(uchar *arg) { return FALSE;} }; @@ -1849,6 +1919,7 @@ public: Item_num *neg (); uint decimal_precision() const { return max_length; } bool check_partition_func_processor(uchar *bool_arg) { return FALSE;} + bool check_vcol_func_processor(uchar *arg) { return FALSE;} }; @@ -1890,6 +1961,7 @@ public: bool eq(const Item *, bool binary_cmp) const; void set_decimal_value(my_decimal *value_par); bool check_partition_func_processor(uchar *bool_arg) { return FALSE;} + bool check_vcol_func_processor(uchar *arg) { return FALSE;} }; @@ -2047,6 +2119,7 @@ public: } virtual void print(String *str, enum_query_type query_type); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *arg) { return FALSE;} /** Return TRUE if character-set-introducer was explicitly specified in the @@ -2100,7 +2173,7 @@ double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end); class Item_static_string_func :public Item_string { const char *func_name; -public: + public: Item_static_string_func(const char *name_par, const char *str, uint length, CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE) @@ -2114,6 +2187,10 @@ public: } bool check_partition_func_processor(uchar *int_arg) {return TRUE;} + bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name); + } }; @@ -2125,6 +2202,10 @@ public: CHARSET_INFO *cs= NULL): Item_string(name_arg, length, cs) {} + bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor("safe_string"); + } }; @@ -2204,6 +2285,7 @@ public: bool eq(const Item *item, bool binary_cmp) const; virtual Item *safe_charset_converter(CHARSET_INFO *tocs); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *arg) { return FALSE;} private: void hex_string_init(const char *str, uint str_length); }; @@ -2236,6 +2318,7 @@ public: save_in_field(result_field, no_conversions); } void cleanup(); + bool check_vcol_func_processor(uchar *arg) { return FALSE;} /* This method is used for debug purposes to print the name of an item to the debug log. The second use of this method is as @@ -2395,12 +2478,15 @@ public: if (ref && result_type() == ROW_RESULT) (*ref)->bring_value(); } + bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor("ref"); + } bool get_time(MYSQL_TIME *ltime) { DBUG_ASSERT(fixed); return (*ref)->get_time(ltime); } - }; @@ -2577,7 +2663,7 @@ class Item_int_with_ref :public Item_int { Item *ref; public: - Item_int_with_ref(longlong i, Item *ref_arg, my_bool unsigned_arg) : + Item_int_with_ref(longlong i, Item *ref_arg, bool unsigned_arg) : Item_int(i), ref(ref_arg) { unsigned_flag= unsigned_arg; @@ -2689,6 +2775,10 @@ public: table_map used_tables() const { return (table_map) 1L; } bool const_item() const { return 0; } bool is_null() { return null_value; } + bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor("copy"); + } /* Override the methods below as pure virtual to make sure all the @@ -2807,7 +2897,7 @@ public: class Cached_item :public Sql_alloc { public: - my_bool null_value; + bool null_value; Cached_item() :null_value(0) {} virtual bool cmp(void)=0; virtual ~Cached_item(); /*line -e1509 */ @@ -2933,6 +3023,10 @@ public: return arg->walk(processor, walk_subquery, args) || (this->*processor)(args); } + bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor("values"); + } }; @@ -3029,6 +3123,10 @@ private: BEFORE INSERT of BEFORE UPDATE trigger. */ bool read_only; + virtual bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor("trigger"); + } }; @@ -3097,6 +3195,10 @@ public: { return this == item; } + bool check_vcol_func_processor(uchar *arg) + { + return trace_unsupported_by_check_vcol_func_processor("cache"); + } /** If this item caches a field value, return pointer to underlying field. diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c6c09bf0cb5..c4d56a93af6 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -245,36 +245,61 @@ Item_bool_func2* Eq_creator::create(Item *a, Item *b) const return new Item_func_eq(a, b); } +Item_bool_func2* Eq_creator::create_swap(Item *a, Item *b) const +{ + return new Item_func_eq(b, a); +} Item_bool_func2* Ne_creator::create(Item *a, Item *b) const { return new Item_func_ne(a, b); } +Item_bool_func2* Ne_creator::create_swap(Item *a, Item *b) const +{ + return new Item_func_ne(b, a); +} Item_bool_func2* Gt_creator::create(Item *a, Item *b) const { return new Item_func_gt(a, b); } +Item_bool_func2* Gt_creator::create_swap(Item *a, Item *b) const +{ + return new Item_func_lt(b, a); +} Item_bool_func2* Lt_creator::create(Item *a, Item *b) const { return new Item_func_lt(a, b); } +Item_bool_func2* Lt_creator::create_swap(Item *a, Item *b) const +{ + return new Item_func_gt(b, a); +} Item_bool_func2* Ge_creator::create(Item *a, Item *b) const { return new Item_func_ge(a, b); } +Item_bool_func2* Ge_creator::create_swap(Item *a, Item *b) const +{ + return new Item_func_le(b, a); +} Item_bool_func2* Le_creator::create(Item *a, Item *b) const { return new Item_func_le(a, b); } +Item_bool_func2* Le_creator::create_swap(Item *a, Item *b) const +{ + return new Item_func_ge(b, a); +} + /* Test functions Most of these returns 0LL if false and 1LL if true and @@ -412,7 +437,8 @@ static bool convert_constant_item(THD *thd, Item_field *field_item, LINT_INIT(old_maps[0]); LINT_INIT(old_maps[1]); - if (table) + /* table->read_set may not be set if we come here from a CREATE TABLE */ + if (table && table->read_set) dbug_tmp_use_all_columns(table, old_maps, table->read_set, table->write_set); /* For comparison purposes allow invalid dates like 2000-01-32 */ @@ -448,7 +474,7 @@ static bool convert_constant_item(THD *thd, Item_field *field_item, } thd->variables.sql_mode= orig_sql_mode; thd->count_cuted_fields= orig_count_cuted_fields; - if (table) + if (table && table->read_set) dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_maps); } return result; @@ -825,7 +851,6 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value) return cmp_type; } - /* Retrieves correct TIME value from the given item. @@ -876,7 +901,12 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg, if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM || ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC)) { + Query_arena backup; + Query_arena *save_arena= thd->switch_to_arena_for_cached_items(&backup); Item_cache_int *cache= new Item_cache_int(); + if (save_arena) + thd->set_query_arena(save_arena); + /* Mark the cache as non-const to prevent re-caching. */ cache->set_used_tables(1); cache->store_longlong(item, value); @@ -912,7 +942,12 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg, cache_converted_constant can't be used here because it can't correctly convert a DATETIME value from string to int representation. */ + Query_arena backup; + Query_arena *save_arena= thd->switch_to_arena_for_cached_items(&backup); Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME); + if (save_arena) + thd->set_query_arena(save_arena); + /* Mark the cache as non-const to prevent re-caching. */ cache->set_used_tables(1); if (!(*a)->is_datetime()) @@ -1142,7 +1177,12 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM || ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC)) { + Query_arena backup; + Query_arena *save_arena= thd->switch_to_arena_for_cached_items(&backup); Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME); + if (save_arena) + thd->set_query_arena(save_arena); + /* Mark the cache as non-const to prevent re-caching. */ cache->set_used_tables(1); cache->store_longlong(item, value); @@ -4751,8 +4791,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref) We could also do boyer-more for non-const items, but as we would have to recompute the tables for each row it's not worth it. */ - if (args[1]->const_item() && !use_strnxfrm(collation.collation) && - !(specialflag & SPECIAL_NO_NEW_FUNC)) + if (args[1]->const_item() && !use_strnxfrm(collation.collation)) { String* res2 = args[1]->val_str(&cmp.value2); if (!res2) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index f612f944877..0278ad201af 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -220,7 +220,7 @@ public: class Item_cache; -#define UNKNOWN ((my_bool)-1) +#define UNKNOWN (-1) /* @@ -249,7 +249,7 @@ protected: FALSE - result is FALSE TRUE - result is NULL */ - my_bool result_for_null_param; + int result_for_null_param; public: Item_in_optimizer(Item *a, Item_in_subselect *b): Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), @@ -270,7 +270,14 @@ class Comp_creator public: Comp_creator() {} /* Remove gcc warning */ virtual ~Comp_creator() {} /* Remove gcc warning */ + /** + Create operation with given arguments. + */ virtual Item_bool_func2* create(Item *a, Item *b) const = 0; + /** + Create operation with given arguments in swap order. + */ + virtual Item_bool_func2* create_swap(Item *a, Item *b) const = 0; virtual const char* symbol(bool invert) const = 0; virtual bool eqne_op() const = 0; virtual bool l_op() const = 0; @@ -282,6 +289,7 @@ public: Eq_creator() {} /* Remove gcc warning */ virtual ~Eq_creator() {} /* Remove gcc warning */ virtual Item_bool_func2* create(Item *a, Item *b) const; + virtual Item_bool_func2* create_swap(Item *a, Item *b) const; virtual const char* symbol(bool invert) const { return invert? "<>" : "="; } virtual bool eqne_op() const { return 1; } virtual bool l_op() const { return 0; } @@ -293,6 +301,7 @@ public: Ne_creator() {} /* Remove gcc warning */ virtual ~Ne_creator() {} /* Remove gcc warning */ virtual Item_bool_func2* create(Item *a, Item *b) const; + virtual Item_bool_func2* create_swap(Item *a, Item *b) const; virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; } virtual bool eqne_op() const { return 1; } virtual bool l_op() const { return 0; } @@ -304,6 +313,7 @@ public: Gt_creator() {} /* Remove gcc warning */ virtual ~Gt_creator() {} /* Remove gcc warning */ virtual Item_bool_func2* create(Item *a, Item *b) const; + virtual Item_bool_func2* create_swap(Item *a, Item *b) const; virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; } virtual bool eqne_op() const { return 0; } virtual bool l_op() const { return 0; } @@ -315,6 +325,7 @@ public: Lt_creator() {} /* Remove gcc warning */ virtual ~Lt_creator() {} /* Remove gcc warning */ virtual Item_bool_func2* create(Item *a, Item *b) const; + virtual Item_bool_func2* create_swap(Item *a, Item *b) const; virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; } virtual bool eqne_op() const { return 0; } virtual bool l_op() const { return 1; } @@ -326,6 +337,7 @@ public: Ge_creator() {} /* Remove gcc warning */ virtual ~Ge_creator() {} /* Remove gcc warning */ virtual Item_bool_func2* create(Item *a, Item *b) const; + virtual Item_bool_func2* create_swap(Item *a, Item *b) const; virtual const char* symbol(bool invert) const { return invert? "<" : ">="; } virtual bool eqne_op() const { return 0; } virtual bool l_op() const { return 0; } @@ -337,6 +349,7 @@ public: Le_creator() {} /* Remove gcc warning */ virtual ~Le_creator() {} /* Remove gcc warning */ virtual Item_bool_func2* create(Item *a, Item *b) const; + virtual Item_bool_func2* create_swap(Item *a, Item *b) const; virtual const char* symbol(bool invert) const { return invert? ">" : "<="; } virtual bool eqne_op() const { return 0; } virtual bool l_op() const { return 1; } @@ -657,7 +670,7 @@ struct interval_range class Item_func_interval :public Item_int_func { Item_row *row; - my_bool use_decimal_comparison; + bool use_decimal_comparison; interval_range *intervals; public: Item_func_interval(Item_row *a) @@ -782,7 +795,7 @@ public: virtual uchar *get_value(Item *item)=0; void sort() { - my_qsort2(base,used_count,size,compare,collation); + my_qsort2(base,used_count,size,compare,(void*)collation); } int find(Item *item); @@ -865,7 +878,7 @@ public: void value_to_item(uint pos, Item *item) { ((Item_int*) item)->value= ((packed_longlong*) base)[pos].val; - ((Item_int*) item)->unsigned_flag= (my_bool) + ((Item_int*) item)->unsigned_flag= (bool) ((packed_longlong*) base)[pos].unsigned_flag; } Item_result result_type() { return INT_RESULT; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 2d1278e7ac3..ed771b60769 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2078,10 +2078,12 @@ double Item_func_round::real_op() { double value= args[0]->val_real(); - if (!(null_value= args[0]->null_value || args[1]->null_value)) - return my_double_round(value, args[1]->val_int(), args[1]->unsigned_flag, - truncate); - + if (!(null_value= args[0]->null_value)) + { + longlong dec= args[1]->val_int(); + if (!(null_value= args[1]->null_value)) + return my_double_round(value, dec, args[1]->unsigned_flag, truncate); + } return 0.0; } @@ -3169,11 +3171,15 @@ void Item_udf_func::print(String *str, enum_query_type query_type) double Item_func_udf_float::val_real() { + double res; + my_bool tmp_null_value; DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_udf_float::val"); DBUG_PRINT("info",("result_type: %d arg_count: %d", args[0]->result_type(), arg_count)); - DBUG_RETURN(udf.val(&null_value)); + res= udf.val(&tmp_null_value); + null_value= tmp_null_value; + DBUG_RETURN(res); } @@ -3190,9 +3196,13 @@ String *Item_func_udf_float::val_str(String *str) longlong Item_func_udf_int::val_int() { + longlong res; + my_bool tmp_null_value; DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_udf_int::val_int"); - DBUG_RETURN(udf.val_int(&null_value)); + res= udf.val_int(&tmp_null_value); + null_value= tmp_null_value; + DBUG_RETURN(res); } @@ -3209,8 +3219,10 @@ String *Item_func_udf_int::val_str(String *str) longlong Item_func_udf_decimal::val_int() { - my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf); + my_bool tmp_null_value; longlong result; + my_decimal dec_buf, *dec= udf.val_decimal(&tmp_null_value, &dec_buf); + null_value= tmp_null_value; if (null_value) return 0; my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result); @@ -3220,8 +3232,10 @@ longlong Item_func_udf_decimal::val_int() double Item_func_udf_decimal::val_real() { - my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf); + my_bool tmp_null_value; double result; + my_decimal dec_buf, *dec= udf.val_decimal(&tmp_null_value, &dec_buf); + null_value= tmp_null_value; if (null_value) return 0.0; my_decimal2double(E_DEC_FATAL_ERROR, dec, &result); @@ -3231,18 +3245,24 @@ double Item_func_udf_decimal::val_real() my_decimal *Item_func_udf_decimal::val_decimal(my_decimal *dec_buf) { + my_decimal *res; + my_bool tmp_null_value; DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_udf_decimal::val_decimal"); DBUG_PRINT("info",("result_type: %d arg_count: %d", args[0]->result_type(), arg_count)); - DBUG_RETURN(udf.val_decimal(&null_value, dec_buf)); + res= udf.val_decimal(&tmp_null_value, dec_buf); + null_value= tmp_null_value; + DBUG_RETURN(res); } String *Item_func_udf_decimal::val_str(String *str) { - my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf); + my_bool tmp_null_value; + my_decimal dec_buf, *dec= udf.val_decimal(&tmp_null_value, &dec_buf); + null_value= tmp_null_value; if (null_value) return 0; if (str->length() < DECIMAL_MAX_STR_LENGTH) @@ -3877,10 +3897,30 @@ bool Item_func_set_user_var::register_field_in_read_map(uchar *arg) TABLE *table= (TABLE *) arg; if (result_field->table == table || !table) bitmap_set_bit(result_field->table->read_set, result_field->field_index); + if (result_field->vcol_info) + return result_field->vcol_info-> + expr_item->walk(&Item::register_field_in_read_map, 1, arg); } return 0; } +/* + Mark field in bitmap supplied as *arg + +*/ + +bool Item_func_set_user_var::register_field_in_bitmap(uchar *arg) +{ + MY_BITMAP *bitmap = (MY_BITMAP *) arg; + DBUG_ASSERT(bitmap); + if (result_field) + { + if (!bitmap) + return 1; + bitmap_set_bit(bitmap, result_field->field_index); + } + return 0; +} /** Set value to user variable. @@ -3984,7 +4024,7 @@ Item_func_set_user_var::update_hash(void *ptr, uint length, /** Get the value of a variable as a double. */ -double user_var_entry::val_real(my_bool *null_value) +double user_var_entry::val_real(bool *null_value) { if ((*null_value= (value == 0))) return 0.0; @@ -4013,7 +4053,7 @@ double user_var_entry::val_real(my_bool *null_value) /** Get the value of a variable as an integer. */ -longlong user_var_entry::val_int(my_bool *null_value) const +longlong user_var_entry::val_int(bool *null_value) const { if ((*null_value= (value == 0))) return LL(0); @@ -4045,7 +4085,7 @@ longlong user_var_entry::val_int(my_bool *null_value) const /** Get the value of a variable as a string. */ -String *user_var_entry::val_str(my_bool *null_value, String *str, +String *user_var_entry::val_str(bool *null_value, String *str, uint decimals) { if ((*null_value= (value == 0))) @@ -4078,7 +4118,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str, /** Get the value of a variable as a decimal. */ -my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val) +my_decimal *user_var_entry::val_decimal(bool *null_value, my_decimal *val) { if ((*null_value= (value == 0))) return 0; @@ -5767,7 +5807,7 @@ Item_func_sp::cleanup() sp_result_field= NULL; } m_sp= NULL; - dummy_table->alias= NULL; + dummy_table->alias.free(); Item_func::cleanup(); } @@ -5793,7 +5833,7 @@ Item_func_sp::func_name() const qname.append('.'); } append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length); - return qname.ptr(); + return qname.c_ptr_safe(); } @@ -5849,7 +5889,7 @@ Item_func_sp::init_result_field(THD *thd) */ share= dummy_table->s; - dummy_table->alias = ""; + dummy_table->alias.set("", 0, table_alias_charset); dummy_table->maybe_null = maybe_null; dummy_table->in_use= thd; dummy_table->copy_blobs= TRUE; diff --git a/sql/item_func.h b/sql/item_func.h index ea9ed39159a..e750e372691 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -414,6 +414,7 @@ public: void fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } + bool check_vcol_func_processor(uchar *int_arg) { return TRUE;} }; @@ -474,6 +475,7 @@ public: Item_func_additive_op(Item *a,Item *b) :Item_num_op(a,b) {} void result_precision(); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} }; @@ -509,6 +511,7 @@ public: my_decimal *decimal_op(my_decimal *); void result_precision(); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} }; @@ -541,6 +544,7 @@ public: } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} }; @@ -555,6 +559,7 @@ public: void result_precision(); void fix_length_and_dec(); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} }; @@ -571,6 +576,7 @@ public: void fix_num_length_and_dec(); uint decimal_precision() const { return args[0]->decimal_precision(); } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} }; @@ -584,6 +590,7 @@ public: const char *func_name() const { return "abs"; } void fix_length_and_dec(); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} }; // A class to handle logarithmic and trigonometric functions @@ -739,6 +746,7 @@ public: double real_op(); my_decimal *decimal_op(my_decimal *); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} }; @@ -751,6 +759,7 @@ public: double real_op(); my_decimal *decimal_op(my_decimal *); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} }; /* This handles round and truncate */ @@ -782,6 +791,10 @@ public: void update_used_tables(); bool fix_fields(THD *thd, Item **ref); void cleanup() { first_eval= TRUE; Item_real_func::cleanup(); } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } private: void seed_random (Item * val); }; @@ -1064,6 +1077,10 @@ public: max_length= args[0]->max_length; } bool fix_fields(THD *thd, Item **ref); + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -1077,6 +1094,10 @@ public: const char *func_name() const { return "benchmark"; } void fix_length_and_dec() { max_length=1; maybe_null=0; } virtual void print(String *str, enum_query_type query_type); + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -1092,6 +1113,10 @@ public: used_tables_cache|= RAND_TABLE_BIT; } longlong val_int(); + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -1341,6 +1366,10 @@ class Item_func_get_lock :public Item_int_func longlong val_int(); const char *func_name() const { return "get_lock"; } void fix_length_and_dec() { max_length=1; maybe_null=1;} + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; class Item_func_release_lock :public Item_int_func @@ -1351,6 +1380,10 @@ public: longlong val_int(); const char *func_name() const { return "release_lock"; } void fix_length_and_dec() { max_length=1; maybe_null=1;} + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; /* replication functions */ @@ -1364,6 +1397,10 @@ public: longlong val_int(); const char *func_name() const { return "master_pos_wait"; } void fix_length_and_dec() { max_length=21; maybe_null=1;} + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -1436,6 +1473,7 @@ public: } void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); } bool register_field_in_read_map(uchar *arg); + bool register_field_in_bitmap(uchar *arg); bool set_entry(THD *thd, bool create_if_not_exists); void cleanup(); }; @@ -1523,7 +1561,7 @@ class Item_func_get_system_var :public Item_func longlong cached_llval; double cached_dval; String cached_strval; - my_bool cached_null_value; + bool cached_null_value; query_id_t used_query_id; uchar cache_present; @@ -1610,6 +1648,11 @@ public: bool fix_index(); void init_search(bool no_order); + bool check_vcol_func_processor(uchar *int_arg) + { + /* TODO: consider adding in support for the MATCH-based virtual columns */ + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -1629,6 +1672,17 @@ public: longlong val_int(); const char *func_name() const { return "is_free_lock"; } void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} + bool check_vcol_func_processor(uchar *int_arg) + { +#if 0 + DBUG_ENTER("Item_func_is_free_lock::check_vcol_func_processor"); + DBUG_PRINT("info", + ("check_vcol_func_processor returns TRUE: unsupported function")); + DBUG_RETURN(TRUE); +#else + return trace_unsupported_by_check_vcol_func_processor(func_name()); +#endif + } }; class Item_func_is_used_lock :public Item_int_func @@ -1639,6 +1693,10 @@ public: longlong val_int(); const char *func_name() const { return "is_used_lock"; } void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;} + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; /* For type casts */ @@ -1658,6 +1716,11 @@ public: longlong val_int(); const char *func_name() const { return "row_count"; } void fix_length_and_dec() { decimals= 0; maybe_null=0; } + bool check_vcol_func_processor(uchar *int_arg) + { + + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -1766,6 +1829,10 @@ public: { return sp_result_field; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -1776,6 +1843,10 @@ public: longlong val_int(); const char *func_name() const { return "found_rows"; } void fix_length_and_dec() { decimals= 0; maybe_null=0; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -1790,5 +1861,9 @@ public: void fix_length_and_dec() { max_length= 21; unsigned_flag=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; diff --git a/sql/item_row.h b/sql/item_row.h index 9838e360e5b..15dadb3d01c 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -80,4 +80,5 @@ public: bool check_cols(uint c); bool null_inside() { return with_null; }; void bring_value(); -}; + bool check_vcol_func_processor(uchar *int_arg) {return FALSE; } + }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 60d5d2f1341..1488fe25fd9 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2754,7 +2754,7 @@ String *Item_func_conv::val_str(String *str) from_base, &endptr, &err); } - ptr= longlong2str(dec, ans, to_base); + ptr= longlong2str(dec, ans, to_base, 1); if (str->copy(ans, (uint32) (ptr-ans), default_charset())) return make_empty_result(); return str; @@ -2915,7 +2915,7 @@ String *Item_func_hex::val_str(String *str) if ((null_value= args[0]->null_value)) return 0; - ptr= longlong2str(dec,ans,16); + ptr= longlong2str(dec,ans,16,1); if (str->copy(ans,(uint32) (ptr-ans),default_charset())) return make_empty_result(); // End of memory return str; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index e8fa041af4f..b731c13a871 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -363,6 +363,10 @@ public: String *val_str(String *); void fix_length_and_dec() { maybe_null=1; max_length = 13; } const char *func_name() const { return "encrypt"; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; #include "sql_crypt.h" @@ -411,6 +415,11 @@ public: call */ virtual const char *fully_qualified_func_name() const = 0; + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor( + fully_qualified_func_name()); + } }; @@ -674,6 +683,10 @@ public: maybe_null=1; max_length=MAX_BLOB_WIDTH; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -873,5 +886,9 @@ public: } const char *func_name() const{ return "uuid"; } String *val_str(String *); + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index b74ea0e804d..fa9eff0d95b 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -390,7 +390,10 @@ Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param, { DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect"); max= max_arg; - init(select_lex, new select_max_min_finder_subselect(this, max_arg)); + init(select_lex, + new select_max_min_finder_subselect(this, max_arg, + parent->substype() == + Item_subselect::ALL_SUBS)); max_columns= 1; maybe_null= 1; max_columns= 1; @@ -1008,11 +1011,20 @@ Item_in_subselect::single_value_transformer(JOIN *join, } Item *subs; - if (!select_lex->group_list.elements && - !select_lex->having && - !select_lex->with_sum_func && - !(select_lex->next_select()) && - select_lex->table_list.elements) + /* + Check if optimization with aggregate min/max possible + 1 There is no aggregate in the subquery + 2 It is not UNION + 3 There is tables + 4 It is not ALL subquery with possible NULLs in the SELECT list + */ + if (!select_lex->group_list.elements && /*1*/ + !select_lex->having && /*1*/ + !select_lex->with_sum_func && /*1*/ + !(select_lex->next_select()) && /*2*/ + select_lex->table_list.elements && /*3*/ + (!select_lex->ref_pointer_array[0]->maybe_null || /*4*/ + substype() != Item_subselect::ALL_SUBS)) /*4*/ { Item_sum_hybrid *item; nesting_map save_allow_sum_func; @@ -1072,8 +1084,11 @@ Item_in_subselect::single_value_transformer(JOIN *join, if (upper_item) upper_item->set_sub_test(item); } - /* fix fields is already called for left expression */ - substitution= func->create(left_expr, subs); + /* + The swap is needed for expressions of type 'f1 < ALL ( SELECT ....)' + where we want to evaluate the sub query even if f1 would be null. + */ + substitution= func->create_swap(left_expr, subs); DBUG_RETURN(RES_OK); } @@ -2075,13 +2090,14 @@ int subselect_uniquesubquery_engine::scan_table() if (table->file->inited) table->file->ha_index_end(); - table->file->ha_rnd_init(1); + if (table->file->ha_rnd_init_with_error(1)) + DBUG_RETURN(1); table->file->extra_opt(HA_EXTRA_CACHE, current_thd->variables.read_buff_size); table->null_row= 0; for (;;) { - error=table->file->rnd_next(table->record[0]); + error=table->file->ha_rnd_next(table->record[0]); if (error && error != HA_ERR_END_OF_FILE) { error= report_error(table, error); @@ -2255,10 +2271,11 @@ int subselect_uniquesubquery_engine::exec() if (!table->file->inited) table->file->ha_index_init(tab->ref.key, 0); - error= table->file->index_read_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_KEY_EXACT); + error= table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab-> + ref.key_parts), + HA_READ_KEY_EXACT); if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) error= report_error(table, error); @@ -2376,10 +2393,11 @@ int subselect_indexsubquery_engine::exec() if (!table->file->inited) table->file->ha_index_init(tab->ref.key, 1); - error= table->file->index_read_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_KEY_EXACT); + error= table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab-> + ref.key_parts), + HA_READ_KEY_EXACT); if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) error= report_error(table, error); @@ -2400,9 +2418,9 @@ int subselect_indexsubquery_engine::exec() ((Item_in_subselect *) item)->value= 1; break; } - error= table->file->index_next_same(table->record[0], - tab->ref.key_buff, - tab->ref.key_length); + error= table->file->ha_index_next_same(table->record[0], + tab->ref.key_buff, + tab->ref.key_length); if (error && error != HA_ERR_END_OF_FILE) { error= report_error(table, error); diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 775e4b4b317..9842641788b 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -32,7 +32,7 @@ class Item_bool_func2; class Item_subselect :public Item_result_field { - my_bool value_assigned; /* value already assigned to subselect */ + bool value_assigned; /* value already assigned to subselect */ protected: /* thread handler, will be assigned in fix_fields only */ THD *thd; @@ -139,6 +139,10 @@ public: bool walk(Item_processor processor, bool walk_subquery, uchar *arg); bool mark_as_eliminated_processor(uchar *arg); bool enumerate_field_refs_processor(uchar *arg); + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor("subselect"); + } /** Get the SELECT_LEX structure associated with this Item. @@ -429,10 +433,10 @@ protected: class subselect_single_select_engine: public subselect_engine { - my_bool prepared; /* simple subselect is prepared */ - my_bool optimized; /* simple subselect is optimized */ - my_bool executed; /* simple subselect is executed */ - my_bool optimize_error; ///< simple subselect optimization failed + bool prepared; /* simple subselect is prepared */ + bool optimized; /* simple subselect is optimized */ + bool executed; /* simple subselect is executed */ + bool optimize_error; /* simple subselect optimization failed */ st_select_lex *select_lex; /* corresponding select_lex */ JOIN * join; /* corresponding JOIN structure */ public: diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 92c2ba83f23..ce7602b7f03 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2617,8 +2617,10 @@ void Item_udf_sum::clear() bool Item_udf_sum::add() { + my_bool tmp_null_value; DBUG_ENTER("Item_udf_sum::add"); - udf.add(&null_value); + udf.add(&tmp_null_value); + null_value= tmp_null_value; DBUG_RETURN(0); } @@ -2654,11 +2656,15 @@ Item *Item_sum_udf_float::copy_or_same(THD* thd) double Item_sum_udf_float::val_real() { + my_bool tmp_null_value; + double res; DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_sum_udf_float::val"); DBUG_PRINT("info",("result_type: %d arg_count: %d", args[0]->result_type(), arg_count)); - DBUG_RETURN(udf.val(&null_value)); + res= udf.val(&tmp_null_value); + null_value= tmp_null_value; + DBUG_RETURN(res); } @@ -2694,12 +2700,16 @@ longlong Item_sum_udf_decimal::val_int() my_decimal *Item_sum_udf_decimal::val_decimal(my_decimal *dec_buf) { + my_decimal *res; + my_bool tmp_null_value; DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_udf_decimal::val_decimal"); DBUG_PRINT("info",("result_type: %d arg_count: %d", args[0]->result_type(), arg_count)); - DBUG_RETURN(udf.val_decimal(&null_value, dec_buf)); + res= udf.val_decimal(&tmp_null_value, dec_buf); + null_value= tmp_null_value; + DBUG_RETURN(res); } @@ -2716,11 +2726,15 @@ Item *Item_sum_udf_int::copy_or_same(THD* thd) longlong Item_sum_udf_int::val_int() { + my_bool tmp_null_value; + longlong res; DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_sum_udf_int::val_int"); DBUG_PRINT("info",("result_type: %d arg_count: %d", args[0]->result_type(), arg_count)); - DBUG_RETURN(udf.val_int(&null_value)); + res= udf.val_int(&tmp_null_value); + null_value= tmp_null_value; + DBUG_RETURN(res); } diff --git a/sql/item_sum.h b/sql/item_sum.h index 27dfb90ecf4..3d4b00e3b52 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -385,6 +385,10 @@ public: Item *get_arg(int i) { return args[i]; } Item *set_arg(int i, THD *thd, Item *new_val); uint get_arg_count() { return arg_count; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -665,6 +669,10 @@ public: } void fix_length_and_dec() {} enum Item_result result_type () const { return hybrid_type; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor("avg_field"); + } const char *func_name() const { DBUG_ASSERT(0); return "avg_field"; } }; @@ -734,6 +742,10 @@ public: } void fix_length_and_dec() {} enum Item_result result_type () const { return hybrid_type; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor("var_field"); + } const char *func_name() const { DBUG_ASSERT(0); return "variance_field"; } }; @@ -1265,8 +1277,13 @@ public: void make_unique(); double val_real() { - String *res; res=val_str(&str_value); - return res ? my_atof(res->c_ptr()) : 0.0; + int error; + const char *end; + String *res; + if (!(res= val_str(&str_value))) + return 0.0; + end= res->ptr() + res->length(); + return (my_strtod(res->ptr(), (char**) &end, &error)); } longlong val_int() { diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 4daef708fa3..963e28b80e8 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -72,6 +72,7 @@ public: enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_date_args(); @@ -92,6 +93,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_date_args(); @@ -124,6 +126,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_date_args(); @@ -141,6 +144,7 @@ public: enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); bool check_partition_func_processor(uchar *int_arg) {return TRUE;} + bool check_vcol_func_processor(uchar *int_arg) {return FALSE;} }; @@ -157,6 +161,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_date_args(); @@ -177,6 +182,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_time_args(); @@ -197,6 +203,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_time_args(); @@ -217,6 +224,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_date_args(); @@ -237,6 +245,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_time_args(); @@ -271,6 +280,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_date_args(); @@ -293,6 +303,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_date_args(); @@ -327,6 +338,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_date_args(); @@ -343,6 +355,7 @@ class Item_func_dayname :public Item_func_weekday enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); bool check_partition_func_processor(uchar *int_arg) {return TRUE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} }; @@ -369,6 +382,14 @@ public: decimals=0; max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } + bool check_vcol_func_processor(uchar *int_arg) + { + /* + TODO: Allow UNIX_TIMESTAMP called with an argument to be a part + of the expression for a virtual column + */ + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -385,6 +406,7 @@ public: max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_time_args(); @@ -509,6 +531,10 @@ public: */ virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; bool result_as_longlong() { return TRUE; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -545,6 +571,10 @@ public: void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -585,6 +615,10 @@ public: void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; @@ -642,6 +676,7 @@ public: const char *func_name() const { return "from_days"; } bool get_date(MYSQL_TIME *res, uint fuzzy_date); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return has_date_args() || has_time_args(); @@ -772,6 +807,7 @@ class Item_extract :public Item_int_func bool eq(const Item *item, bool binary_cmp) const; virtual void print(String *str, enum_query_type query_type); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { switch (int_type) { @@ -1058,6 +1094,7 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) { return !has_time_args(); diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 7464fbb440e..57995b2b643 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -222,6 +222,11 @@ public: collation.collation= pxml->charset(); } const char *func_name() const { return "nodeset"; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } + }; @@ -528,6 +533,10 @@ public: enum Type type() const { return XPATH_NODESET_CMP; }; const char *func_name() const { return "xpath_nodeset_to_const_comparator"; } bool is_bool_func() { return 1; } + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } longlong val_int() { diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index dadbb5ccf42..ce33d161c79 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -40,6 +40,10 @@ public: } void fix_length_and_dec(); String *parse_xml(String *raw_xml, String *parsed_xml_buf); + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor(func_name()); + } }; diff --git a/sql/key.cc b/sql/key.cc index 6336b0b8a5f..fec67b35ebc 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -281,8 +281,7 @@ bool key_cmp_if_same(TABLE *table,const uchar *key,uint idx,uint key_length) key++; store_length--; } - if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART | - HA_BIT_PART)) + if (!(key_part->key_part_flag & HA_CAN_MEMCMP)) { if (key_part->field->key_cmp(key, key_part->length)) return 1; diff --git a/sql/lex.h b/sql/lex.h index a22b491b739..f304e0412fa 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -65,6 +65,7 @@ static SYMBOL symbols[] = { { "ALL", SYM(ALL)}, { "ALGORITHM", SYM(ALGORITHM_SYM)}, { "ALTER", SYM(ALTER)}, + { "ALWAYS", SYM(ALWAYS_SYM)}, { "ANALYZE", SYM(ANALYZE_SYM)}, { "AND", SYM(AND_SYM)}, { "ANY", SYM(ANY_SYM)}, @@ -109,6 +110,7 @@ static SYMBOL symbols[] = { { "CHECKSUM", SYM(CHECKSUM_SYM)}, { "CIPHER", SYM(CIPHER_SYM)}, { "CLIENT", SYM(CLIENT_SYM)}, + { "CLIENT_STATISTICS", SYM(CLIENT_STATS_SYM)}, { "CLOSE", SYM(CLOSE_SYM)}, { "COALESCE", SYM(COALESCE)}, { "CODE", SYM(CODE_SYM)}, @@ -223,6 +225,7 @@ static SYMBOL symbols[] = { { "FULL", SYM(FULL)}, { "FULLTEXT", SYM(FULLTEXT_SYM)}, { "FUNCTION", SYM(FUNCTION_SYM)}, + { "GENERATED", SYM(GENERATED_SYM)}, { "GEOMETRY", SYM(GEOMETRY_SYM)}, { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)}, { "GET_FORMAT", SYM(GET_FORMAT)}, @@ -248,6 +251,7 @@ static SYMBOL symbols[] = { { "IN", SYM(IN_SYM)}, { "INDEX", SYM(INDEX_SYM)}, { "INDEXES", SYM(INDEXES)}, + { "INDEX_STATISTICS", SYM(INDEX_STATS_SYM)}, { "INFILE", SYM(INFILE)}, { "INITIAL_SIZE", SYM(INITIAL_SIZE_SYM)}, { "INNER", SYM(INNER_SYM)}, @@ -388,14 +392,16 @@ static SYMBOL symbols[] = { { "OUTFILE", SYM(OUTFILE)}, { "OWNER", SYM(OWNER_SYM)}, { "PACK_KEYS", SYM(PACK_KEYS_SYM)}, - { "PARSER", SYM(PARSER_SYM)}, { "PAGE", SYM(PAGE_SYM)}, { "PAGE_CHECKSUM", SYM(PAGE_CHECKSUM_SYM)}, + { "PARSER", SYM(PARSER_SYM)}, + { "PARSE_VCOL_EXPR", SYM(PARSE_VCOL_EXPR_SYM)}, { "PARTIAL", SYM(PARTIAL)}, { "PARTITION", SYM(PARTITION_SYM)}, { "PARTITIONING", SYM(PARTITIONING_SYM)}, { "PARTITIONS", SYM(PARTITIONS_SYM)}, { "PASSWORD", SYM(PASSWORD)}, + { "PERSISTENT", SYM(PERSISTENT_SYM)}, { "PHASE", SYM(PHASE_SYM)}, { "PLUGIN", SYM(PLUGIN_SYM)}, { "PLUGINS", SYM(PLUGINS_SYM)}, @@ -481,6 +487,7 @@ static SYMBOL symbols[] = { { "SIGNED", SYM(SIGNED_SYM)}, { "SIMPLE", SYM(SIMPLE_SYM)}, { "SLAVE", SYM(SLAVE)}, + { "SLOW", SYM(SLOW_SYM)}, { "SNAPSHOT", SYM(SNAPSHOT_SYM)}, { "SMALLINT", SYM(SMALLINT)}, { "SOCKET", SYM(SOCKET_SYM)}, @@ -529,6 +536,7 @@ static SYMBOL symbols[] = { { "TABLE", SYM(TABLE_SYM)}, { "TABLES", SYM(TABLES)}, { "TABLESPACE", SYM(TABLESPACE)}, + { "TABLE_STATISTICS", SYM(TABLE_STATS_SYM)}, { "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)}, { "TEMPORARY", SYM(TEMPORARY)}, { "TEMPTABLE", SYM(TEMPTABLE_SYM)}, @@ -572,6 +580,7 @@ static SYMBOL symbols[] = { { "USE", SYM(USE_SYM)}, { "USER", SYM(USER)}, { "USER_RESOURCES", SYM(RESOURCES)}, + { "USER_STATISTICS", SYM(USER_STATS_SYM)}, { "USE_FRM", SYM(USE_FRM)}, { "USING", SYM(USING)}, { "UTC_DATE", SYM(UTC_DATE_SYM)}, @@ -584,13 +593,15 @@ static SYMBOL symbols[] = { { "VARCHARACTER", SYM(VARCHAR)}, { "VARIABLES", SYM(VARIABLES)}, { "VARYING", SYM(VARYING)}, + { "VIA", SYM(VIA_SYM)}, + { "VIEW", SYM(VIEW_SYM)}, + { "VIRTUAL", SYM(VIRTUAL_SYM)}, { "WAIT", SYM(WAIT_SYM)}, { "WARNINGS", SYM(WARNINGS)}, { "WEEK", SYM(WEEK_SYM)}, { "WHEN", SYM(WHEN_SYM)}, { "WHERE", SYM(WHERE)}, { "WHILE", SYM(WHILE_SYM)}, - { "VIEW", SYM(VIEW_SYM)}, { "WITH", SYM(WITH)}, { "WORK", SYM(WORK_SYM)}, { "WRAPPER", SYM(WRAPPER_SYM)}, diff --git a/sql/lock.cc b/sql/lock.cc index 7fb725c9861..1b66fd3d33f 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -903,7 +903,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *write_lock_used=table; if (table->db_stat & HA_READ_ONLY) { - my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias); + my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias.c_ptr()); /* Clear the lock type of the lock data that are stored already. */ sql_lock->lock_count= (uint) (locks - sql_lock->locks); reset_lock_data(sql_lock); @@ -927,7 +927,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, for ( ; org_locks != locks ; org_locks++) { (*org_locks)->debug_print_param= (void *) table; - (*org_locks)->lock->name= table->alias; + (*org_locks)->lock->name= table->alias.c_ptr(); } } /* diff --git a/sql/log.cc b/sql/log.cc index 95f8e9e82ee..047439f6b73 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -112,6 +112,27 @@ char *make_default_log_name(char *buff,const char* log_ext) MYF(MY_UNPACK_FILENAME|MY_REPLACE_EXT)); } + +/* + Create a filename from a base with a given suffix. + The name is allocated trough my_once_alloc(), so one should only + use this for startup options that can all be freed at once. +*/ + +char *make_once_alloced_filename(const char *basename, const char *ext) +{ + char buff[FN_REFLEN+10], *end, *res; + size_t length; + strmake(buff, basename, sizeof(buff)-10); + end= strmov(fn_ext(buff), ext); + length= (size_t) (end - buff) + 1; + + if ((res= (char*) my_once_alloc(length, MYF(MY_WME)))) + memcpy(res, buff, length); + return res; +} + + /* Helper class to hold a mutex for the duration of the block. @@ -413,7 +434,7 @@ bool Log_to_csv_event_handler:: need_close= TRUE; if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || - table->file->ha_rnd_init(0)) + table->file->ha_rnd_init_with_error(0)) goto err; need_rnd_end= TRUE; @@ -564,7 +585,7 @@ bool Log_to_csv_event_handler:: need_close= TRUE; if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || - table->file->ha_rnd_init(0)) + table->file->ha_rnd_init_with_error(0)) goto err; need_rnd_end= TRUE; @@ -825,6 +846,13 @@ void Log_to_file_event_handler::flush() mysql_slow_log.reopen_file(); } +void Log_to_file_event_handler::flush_slow_log() +{ + /* reopen slow log file */ + if (opt_slow_log) + mysql_slow_log.reopen_file(); +} + /* Log error with all enabled log event handlers @@ -920,8 +948,6 @@ void LOGGER::init_log_tables() bool LOGGER::flush_logs(THD *thd) { - int rc= 0; - /* Now we lock logger, as nobody should be able to use logging routines while log tables are closed @@ -933,7 +959,24 @@ bool LOGGER::flush_logs(THD *thd) /* end of log flush */ logger.unlock(); - return rc; + return 0; +} + + +bool LOGGER::flush_slow_log(THD *thd) +{ + /* + Now we lock logger, as nobody should be able to use logging routines while + log tables are closed + */ + logger.lock_exclusive(); + + /* reopen log files */ + file_log_handler->flush_slow_log(); + + /* end of log flush */ + logger.unlock(); + return 0; } @@ -1731,7 +1774,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) log_query.append("`")) DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), + Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), TRUE, TRUE, errcode); DBUG_RETURN(mysql_bin_log.write(&qinfo)); } @@ -1755,7 +1798,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) log_query.append("`")) DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), + Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), TRUE, TRUE, errcode); DBUG_RETURN(mysql_bin_log.write(&qinfo)); } @@ -4424,6 +4467,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) if (likely(is_open())) { IO_CACHE *file= &log_file; + my_off_t my_org_b_tell; #ifdef HAVE_REPLICATION /* In the future we need to add to the following if tests like @@ -4441,6 +4485,8 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) } #endif /* HAVE_REPLICATION */ + my_org_b_tell= my_b_tell(file); + #if defined(USING_TRANSACTIONS) /* Should we write to the binlog cache or to the binlog on disk? @@ -4459,7 +4505,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) 2 - --binlog-direct-non-transactional-updates is set and we are about to use the statement format. When using the row format (cache_stmt == TRUE). */ - if (opt_using_transactions && thd) + if (opt_using_transactions) { if (thd->binlog_setup_trx_data()) goto err; @@ -4502,7 +4548,6 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) If row-based binlogging, Insert_id, Rand and other kind of "setting context" events are not needed. */ - if (thd) { if (!thd->current_stmt_binlog_row_based) { @@ -4549,16 +4594,16 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) } } - /* - Write the SQL command - */ - + /* Write the SQL command */ if (event_info->write(file) || DBUG_EVALUATE_IF("injecting_fault_writing", 1, 0)) goto err; if (file == &log_file) // we are writing to the real log (disk) { + ulonglong data_written= (my_b_tell(file) - my_org_b_tell); + status_var_add(thd->status_var.binlog_bytes_written, data_written); + if (flush_and_sync()) goto err; signal_update(); @@ -4717,6 +4762,7 @@ uint MYSQL_BIN_LOG::next_file_id() SYNOPSIS write_cache() + thd Current_thread cache Cache to write to the binary log lock_log True if the LOCK_log mutex should be aquired, false otherwise sync_log True if the log should be flushed and sync:ed @@ -4726,7 +4772,8 @@ uint MYSQL_BIN_LOG::next_file_id() be reset as a READ_CACHE to be able to read the contents from it. */ -int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) +int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log, + bool sync_log) { Mutex_sentry sentry(lock_log ? &LOCK_log : NULL); @@ -4774,6 +4821,7 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) /* write the first half of the split header */ if (my_b_write(&log_file, header, carry)) return ER_ERROR_ON_WRITE; + status_var_add(thd->status_var.binlog_bytes_written, carry); /* copy fixed second half of header to cache so the correct @@ -4842,6 +4890,8 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) /* Write data to the binary log file */ if (my_b_write(&log_file, cache->read_pos, length)) return ER_ERROR_ON_WRITE; + status_var_add(thd->status_var.binlog_bytes_written, length); + cache->read_pos=cache->read_end; // Mark buffer used up } while ((length= my_b_fill(cache))); @@ -4869,7 +4919,8 @@ int query_error_code(THD *thd, bool not_killed) is not set to these errors when specified not_killed by the caller. */ - if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED) + if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED || + error == ER_NEW_ABORTING_CONNECTION) error= 0; } else @@ -4897,6 +4948,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock) if (lock) pthread_mutex_lock(&LOCK_log); error= ev.write(&log_file); + status_var_add(thd->status_var.binlog_bytes_written, ev.data_written); if (lock) { if (!error && !(error= flush_and_sync())) @@ -4968,21 +5020,28 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, */ if (qinfo.write(&log_file)) goto err; + status_var_add(thd->status_var.binlog_bytes_written, qinfo.data_written); DBUG_EXECUTE_IF("crash_before_writing_xid", { - if ((write_error= write_cache(cache, false, true))) + if ((write_error= write_cache(thd, cache, FALSE, + TRUE))) DBUG_PRINT("info", ("error writing binlog cache: %d", write_error)); DBUG_PRINT("info", ("crashing before writing xid")); DBUG_SUICIDE(); }); - if ((write_error= write_cache(cache, false, false))) + if ((write_error= write_cache(thd, cache, FALSE, FALSE))) goto err; - if (commit_event && commit_event->write(&log_file)) - goto err; + if (commit_event) + { + if (commit_event->write(&log_file)) + goto err; + status_var_add(thd->status_var.binlog_bytes_written, + commit_event->data_written); + } if (incident && write_incident(thd, FALSE)) goto err; @@ -5203,9 +5262,23 @@ static bool test_if_number(register const char *str, void sql_perror(const char *message) { -#ifdef HAVE_STRERROR +#if defined(_WIN32) + char* buf; + DWORD dw= GetLastError(); + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL ) > 0) + { + sql_print_error("%s: %s",message, buf); + LocalFree((HLOCAL)buf); + } + else + { + sql_print_error("%s", message); + } +#elif defined(HAVE_STRERROR) sql_print_error("%s: %s",message, strerror(errno)); -#else +#else perror(message); #endif } @@ -6158,3 +6231,20 @@ mysql_declare_plugin(binlog) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(binlog) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &binlog_storage_engine, + "binlog", + "MySQL AB", + "This is a pseudo storage engine to represent the binlog in a transaction", + PLUGIN_LICENSE_GPL, + binlog_init, /* Plugin Init */ + NULL, /* Plugin Deinit */ + 0x0100 /* 1.0 */, + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +} +maria_declare_plugin_end; diff --git a/sql/log.h b/sql/log.h index 361ad0f2a91..4b32ecfdc02 100644 --- a/sql/log.h +++ b/sql/log.h @@ -361,9 +361,9 @@ public: void reset_gathered_updates(THD *thd); bool write(Log_event* event_info); // binary log write bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident); - bool write_incident(THD *thd, bool lock); - int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync); + int write_cache(THD *thd, IO_CACHE *cache, bool lock_log, + bool flush_and_sync); void set_write_error(THD *thd); bool check_write_error(THD *thd); @@ -501,6 +501,7 @@ public: const char *sql_text, uint sql_text_len, CHARSET_INFO *client_cs); void flush(); + void flush_slow_log(); void init_pthread_objects(); MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; } MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; } @@ -545,6 +546,7 @@ public: void init_base(); void init_log_tables(); bool flush_logs(THD *thd); + bool flush_slow_log(THD *thd); /* Perform basic logger cleanup. this will leave e.g. error log open. */ void cleanup_base(); /* Free memory. Nothing could be logged after this function is called */ diff --git a/sql/log_event.cc b/sql/log_event.cc index f56fa3c698a..927b61eb391 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -580,7 +580,7 @@ append_query_string(CHARSET_INFO *csinfo, if (to->reserve(orig_len + from->length()*2+3)) return 1; - beg= to->c_ptr_quick() + to->length(); + beg= (char*) to->ptr() + to->length(); ptr= beg; if (csinfo->escape_with_backslash_is_dangerous) ptr= str_to_hex(ptr, from->ptr(), from->length()); @@ -1133,7 +1133,7 @@ failed my_b_read")); goto err; } if ((res= read_log_event(buf, data_len, &error, description_event))) - res->register_temp_buf(buf); + res->register_temp_buf(buf, TRUE); err: UNLOCK_MUTEX; @@ -4691,7 +4691,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli, */ lex_start(thd); thd->lex->local_file= local_fname; - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, 0); if (!use_rli_only_for_errors) { @@ -6491,7 +6491,7 @@ int Append_block_log_event::do_apply_event(Relay_log_info const *rli) as the present method does not call mysql_parse(). */ lex_start(thd); - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, 0); my_delete(fname, MYF(0)); // old copy may exist already if ((fd= my_create(fname, CREATE_MODE, O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW, @@ -7431,7 +7431,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) we need to do any changes to that value after this function. */ lex_start(thd); - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, 0); /* The current statement is just about to begin and has not yet modified anything. Note, all.modified is reset @@ -8233,6 +8233,111 @@ Table_map_log_event::~Table_map_log_event() my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR)); } + +#ifdef MYSQL_CLIENT + +/* + Rewrite database name for the event to name specified by new_db + SYNOPSIS + new_db Database name to change to + new_len Length + desc Event describing binlog that we're writing to. + + DESCRIPTION + Reset db name. This function assumes that temp_buf member contains event + representation taken from a binary log. It resets m_dbnam and m_dblen and + rewrites temp_buf with new db name. + + RETURN + 0 - Success + other - Error +*/ + +int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len, + const Format_description_log_event* desc) +{ + DBUG_ENTER("Table_map_log_event::rewrite_db"); + DBUG_ASSERT(temp_buf); + + uint header_len= min(desc->common_header_len, + LOG_EVENT_MINIMAL_HEADER_LEN) + TABLE_MAP_HEADER_LEN; + int len_diff; + + if (!(len_diff= new_len - m_dblen)) + { + memcpy((void*) (temp_buf + header_len + 1), new_db, m_dblen + 1); + memcpy((void*) m_dbnam, new_db, m_dblen + 1); + DBUG_RETURN(0); + } + + // Create new temp_buf + ulong event_cur_len= uint4korr(temp_buf + EVENT_LEN_OFFSET); + ulong event_new_len= event_cur_len + len_diff; + char* new_temp_buf= (char*) my_malloc(event_new_len, MYF(MY_WME)); + + if (!new_temp_buf) + { + sql_print_error("Table_map_log_event::rewrite_db: " + "failed to allocate new temp_buf (%d bytes required)", + event_new_len); + DBUG_RETURN(-1); + } + + // Rewrite temp_buf + char* ptr= new_temp_buf; + ulong cnt= 0; + + // Copy header and change event length + memcpy(ptr, temp_buf, header_len); + int4store(ptr + EVENT_LEN_OFFSET, event_new_len); + ptr += header_len; + cnt += header_len; + + // Write new db name length and new name + *ptr++ = new_len; + memcpy(ptr, new_db, new_len + 1); + ptr += new_len + 1; + cnt += m_dblen + 2; + + // Copy rest part + memcpy(ptr, temp_buf + cnt, event_cur_len - cnt); + + // Reregister temp buf + free_temp_buf(); + register_temp_buf(new_temp_buf, TRUE); + + // Reset m_dbnam and m_dblen members + m_dblen= new_len; + + // m_dbnam resides in m_memory together with m_tblnam and m_coltype + uchar* memory= m_memory; + char const* tblnam= m_tblnam; + uchar* coltype= m_coltype; + + m_memory= (uchar*) my_multi_malloc(MYF(MY_WME), + &m_dbnam, (uint) m_dblen + 1, + &m_tblnam, (uint) m_tbllen + 1, + &m_coltype, (uint) m_colcnt, + NullS); + + if (!m_memory) + { + sql_print_error("Table_map_log_event::rewrite_db: " + "failed to allocate new m_memory (%d + %d + %d bytes required)", + m_dblen + 1, m_tbllen + 1, m_colcnt); + DBUG_RETURN(-1); + } + + memcpy((void*)m_dbnam, new_db, m_dblen + 1); + memcpy((void*)m_tblnam, tblnam, m_tbllen + 1); + memcpy(m_coltype, coltype, m_colcnt); + + my_free(memory, MYF(MY_WME)); + DBUG_RETURN(0); +} +#endif /* MYSQL_CLIENT */ + + /* Return value is an error code, one of: @@ -8830,7 +8935,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli, if (table->file->ha_table_flags() & HA_DUPLICATE_POS) { DBUG_PRINT("info",("Locating offending record using rnd_pos()")); - error= table->file->rnd_pos(table->record[1], table->file->dup_ref); + error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref); if (error) { DBUG_PRINT("info",("rnd_pos() returns error %d",error)); @@ -8862,10 +8967,10 @@ Rows_log_event::write_row(const Relay_log_info *const rli, key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum, 0); - error= table->file->index_read_idx_map(table->record[1], keynum, - (const uchar*)key.get(), - HA_WHOLE_KEY, - HA_READ_KEY_EXACT); + error= table->file->ha_index_read_idx_map(table->record[1], keynum, + (const uchar*)key.get(), + HA_WHOLE_KEY, + HA_READ_KEY_EXACT); if (error) { DBUG_PRINT("info",("index_read_idx() returns %s", HA_ERR(error))); @@ -9108,10 +9213,10 @@ record_compare_exit: /** Locate the current row in event's table. - The current row is pointed by @c m_curr_row. Member @c m_width tells how many - columns are there in the row (this can be differnet from the number of columns - in the table). It is assumed that event's table is already open and pointed - by @c m_table. + The current row is pointed by @c m_curr_row. Member @c m_width tells + how many columns are there in the row (this can be differnet from + the number of columns in the table). It is assumed that event's + table is already open and pointed by @c m_table. If a corresponding record is found in the table it is stored in @c m_table->record[0]. Note that when record is located based on a primary @@ -9172,13 +9277,14 @@ int Rows_log_event::find_row(const Relay_log_info *rli) length. Something along these lines should work: ADD>>> store_record(table,record[1]); - int error= table->file->rnd_pos(table->record[0], table->file->ref); + int error= table->file->ha_rnd_pos(table->record[0], + table->file->ref); ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0], table->s->reclength) == 0); */ DBUG_PRINT("info",("locating record using primary key (position)")); - int error= table->file->rnd_pos_by_record(table->record[0]); + int error= table->file->ha_rnd_pos_by_record(table->record[0]); if (error) { DBUG_PRINT("info",("rnd_pos returns error %d",error)); @@ -9238,9 +9344,9 @@ int Rows_log_event::find_row(const Relay_log_info *rli) table->record[0][table->s->null_bytes - 1]|= 256U - (1U << table->s->last_null_bit_pos); - if ((error= table->file->index_read_map(table->record[0], m_key, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if ((error= table->file->ha_index_read_map(table->record[0], m_key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT))) { DBUG_PRINT("info",("no record matching the key found in the table")); if (error == HA_ERR_RECORD_DELETED) @@ -9329,7 +9435,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli) 256U - (1U << table->s->last_null_bit_pos); } - while ((error= table->file->index_next(table->record[0]))) + while ((error= table->file->ha_index_next(table->record[0]))) { /* We just skip records that has already been deleted */ if (error == HA_ERR_RECORD_DELETED) @@ -9353,11 +9459,10 @@ int Rows_log_event::find_row(const Relay_log_info *rli) int restart_count= 0; // Number of times scanning has restarted from top /* We don't have a key: search the table using rnd_next() */ - if ((error= table->file->ha_rnd_init(1))) + if ((error= table->file->ha_rnd_init_with_error(1))) { DBUG_PRINT("info",("error initializing table scan" " (ha_rnd_init returns %d)",error)); - table->file->print_error(error, MYF(0)); goto err; } @@ -9365,7 +9470,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli) do { restart_rnd_next: - error= table->file->rnd_next(table->record[0]); + error= table->file->ha_rnd_next(table->record[0]); if (error) DBUG_PRINT("info", ("error: %s", HA_ERR(error))); @@ -9383,7 +9488,14 @@ int Rows_log_event::find_row(const Relay_log_info *rli) case HA_ERR_END_OF_FILE: if (++restart_count < 2) - table->file->ha_rnd_init(1); + { + int error2; + if ((error2= table->file->ha_rnd_init_with_error(1))) + { + error= error2; + goto err; + } + } break; default: diff --git a/sql/log_event.h b/sql/log_event.h index 645585c8ccb..a8b6e95ea2e 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -883,6 +883,13 @@ public: event's type, and its content is distributed in the event-specific fields. */ char *temp_buf; + + /* + TRUE <=> this event 'owns' temp_buf and should call my_free() when done + with it + */ + bool event_owns_temp_buf; + /* Timestamp on the master(for debugging and replication of NOW()/TIMESTAMP). It is important for queries and LOAD DATA @@ -1024,12 +1031,17 @@ public: Log_event(const char* buf, const Format_description_log_event *description_event); virtual ~Log_event() { free_temp_buf();} - void register_temp_buf(char* buf) { temp_buf = buf; } + void register_temp_buf(char* buf, bool must_free) + { + temp_buf= buf; + event_owns_temp_buf= must_free; + } void free_temp_buf() { if (temp_buf) { - my_free(temp_buf, MYF(0)); + if (event_owns_temp_buf) + my_free(temp_buf, MYF(0)); temp_buf = 0; } } @@ -1364,7 +1376,7 @@ protected: MODE_PIPES_AS_CONCAT==0x2 MODE_ANSI_QUOTES==0x4 MODE_IGNORE_SPACE==0x8 - MODE_NOT_USED==0x10 + MODE_IGNORE_BAD_TABLE_OPTIONS==0x10 MODE_ONLY_FULL_GROUP_BY==0x20 MODE_NO_UNSIGNED_SUBTRACTION==0x40 MODE_NO_DIR_IN_CREATE==0x80 @@ -3354,6 +3366,8 @@ public: ulong get_table_id() const { return m_table_id; } const char *get_table_name() const { return m_tblnam; } const char *get_db_name() const { return m_dbnam; } + int rewrite_db(const char* new_name, size_t new_name_len, + const Format_description_log_event*); #endif virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; } diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index cc9d712a834..94e45bc9ca6 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -77,7 +77,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info we need to do any changes to that value after this function. */ lex_start(ev_thd); - mysql_reset_thd_for_next_command(ev_thd); + mysql_reset_thd_for_next_command(ev_thd, 0); /* Check if the slave is set to use SBR. If so, it should switch @@ -582,7 +582,7 @@ replace_record(THD *thd, TABLE *table, */ if (table->file->ha_table_flags() & HA_DUPLICATE_POS) { - error= table->file->rnd_pos(table->record[1], table->file->dup_ref); + error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref); if (error) { DBUG_PRINT("info",("rnd_pos() returns error %d",error)); @@ -608,10 +608,10 @@ replace_record(THD *thd, TABLE *table, key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum, 0); - error= table->file->index_read_idx_map(table->record[1], keynum, - (const uchar*)key.get(), - HA_WHOLE_KEY, - HA_READ_KEY_EXACT); + error= table->file->ha_index_read_idx_map(table->record[1], keynum, + (const uchar*)key.get(), + HA_WHOLE_KEY, + HA_READ_KEY_EXACT); if (error) { DBUG_PRINT("info", ("index_read_idx() returns error %d", error)); @@ -723,13 +723,13 @@ static int find_and_fetch_row(TABLE *table, uchar *key) length. Something along these lines should work: ADD>>> store_record(table,record[1]); - int error= table->file->rnd_pos(table->record[0], table->file->ref); + int error= table->file->ha_rnd_pos(table->record[0], table->file->ref); ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0], table->s->reclength) == 0); */ table->file->position(table->record[0]); - int error= table->file->rnd_pos(table->record[0], table->file->ref); + int error= table->file->ha_rnd_pos(table->record[0], table->file->ref); /* rnd_pos() returns the record in table->record[0], so we have to move it to table->record[1]. @@ -767,8 +767,9 @@ static int find_and_fetch_row(TABLE *table, uchar *key) my_ptrdiff_t const pos= table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0; table->record[1][pos]= 0xFF; - if ((error= table->file->index_read_map(table->record[1], key, HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if ((error= table->file->ha_index_read_map(table->record[1], key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT))) { table->file->print_error(error, MYF(0)); table->file->ha_index_end(); @@ -822,7 +823,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key) 256U - (1U << table->s->last_null_bit_pos); } - while ((error= table->file->index_next(table->record[1]))) + while ((error= table->file->ha_index_next(table->record[1]))) { /* We just skip records that has already been deleted */ if (error == HA_ERR_RECORD_DELETED) @@ -844,14 +845,14 @@ static int find_and_fetch_row(TABLE *table, uchar *key) int error; /* We don't have a key: search the table using rnd_next() */ - if ((error= table->file->ha_rnd_init(1))) + if ((error= table->file->ha_rnd_init_with_error(1))) return error; /* Continue until we find the right record or have made a full loop */ do { restart_rnd_next: - error= table->file->rnd_next(table->record[1]); + error= table->file->ha_rnd_next(table->record[1]); DBUG_DUMP("record[0]", table->record[0], table->s->reclength); DBUG_DUMP("record[1]", table->record[1], table->s->reclength); @@ -868,15 +869,19 @@ static int find_and_fetch_row(TABLE *table, uchar *key) goto restart_rnd_next; case HA_ERR_END_OF_FILE: - if (++restart_count < 2) - table->file->ha_rnd_init(1); - break; + if (++restart_count < 2) + { + int error2; + if ((error2= table->file->ha_rnd_init_with_error(1))) + DBUG_RETURN(error2); + } + break; default: - table->file->print_error(error, MYF(0)); + table->file->print_error(error, MYF(0)); DBUG_PRINT("info", ("Record not found")); table->file->ha_rnd_end(); - DBUG_RETURN(error); + DBUG_RETURN(error); } } while (restart_count < 2 && record_compare(table)); @@ -2144,7 +2149,7 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, if (table->file->ha_table_flags() & HA_DUPLICATE_POS) { DBUG_PRINT("info",("Locating offending record using rnd_pos()")); - error= table->file->rnd_pos(table->record[1], table->file->dup_ref); + error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref); if (error) { DBUG_PRINT("info",("rnd_pos() returns error %d",error)); @@ -2176,10 +2181,10 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum, 0); - error= table->file->index_read_idx_map(table->record[1], keynum, - (const uchar*)key.get(), - HA_WHOLE_KEY, - HA_READ_KEY_EXACT); + error= table->file->ha_index_read_idx_map(table->record[1], keynum, + (const uchar*)key.get(), + HA_WHOLE_KEY, + HA_READ_KEY_EXACT); if (error) { DBUG_PRINT("info",("index_read_idx() returns error %d", error)); @@ -2330,13 +2335,13 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) length. Something along these lines should work: ADD>>> store_record(table,record[1]); - int error= table->file->rnd_pos(table->record[0], table->file->ref); + int error= table->file->ha_rnd_pos(table->record[0], table->file->ref); ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0], table->s->reclength) == 0); */ DBUG_PRINT("info",("locating record using primary key (position)")); - int error= table->file->rnd_pos_by_record(table->record[0]); + int error= table->file->ha_rnd_pos_by_record(table->record[0]); if (error) { DBUG_PRINT("info",("rnd_pos returns error %d",error)); @@ -2396,9 +2401,9 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0; table->record[0][pos]= 0xFF; - if ((error= table->file->index_read_map(table->record[0], m_key, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if ((error= table->file->ha_index_read_map(table->record[0], m_key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT))) { DBUG_PRINT("info",("no record matching the key found in the table")); if (error == HA_ERR_RECORD_DELETED) @@ -2487,7 +2492,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) 256U - (1U << table->s->last_null_bit_pos); } - while ((error= table->file->index_next(table->record[0]))) + while ((error= table->file->ha_index_next(table->record[0]))) { /* We just skip records that has already been deleted */ if (error == HA_ERR_RECORD_DELETED) @@ -2511,11 +2516,10 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) int restart_count= 0; // Number of times scanning has restarted from top /* We don't have a key: search the table using rnd_next() */ - if ((error= table->file->ha_rnd_init(1))) + if ((error= table->file->ha_rnd_init_with_error(1))) { DBUG_PRINT("info",("error initializing table scan" " (ha_rnd_init returns %d)",error)); - table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -2523,7 +2527,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) do { restart_rnd_next: - error= table->file->rnd_next(table->record[0]); + error= table->file->ha_rnd_next(table->record[0]); switch (error) { @@ -2535,7 +2539,11 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) case HA_ERR_END_OF_FILE: if (++restart_count < 2) - table->file->ha_rnd_init(1); + { + int error2; + if ((error2= table->file->ha_rnd_init_with_error(1))) + DBUG_RETURN(error2); + } break; default: diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc new file mode 100644 index 00000000000..086dc292dec --- /dev/null +++ b/sql/mysql_install_db.cc @@ -0,0 +1,637 @@ +/* Copyright (C) 2010-2011 Monty Program Ab & Vladislav Vaintroub + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + mysql_install_db creates a new database instance (optionally as service) + on Windows. +*/ +#define DONT_DEFINE_VOID +#include <my_global.h> +#include <my_getopt.h> +#include <my_sys.h> +#include <m_string.h> + +#include <windows.h> +#include <assert.h> +#include <shellapi.h> +#include <accctrl.h> +#include <aclapi.h> + +#define USAGETEXT \ +"mysql_install_db.exe Ver 1.00 for Windows\n" \ +"Copyright (C) 2010-2011 Monty Program Ab & Vladislav Vaintroub\n" \ +"This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n" \ +"and you are welcome to modify and redistribute it under the GPL v2 license\n" \ +"Usage: mysql_install_db.exe [OPTIONS]\n" \ +"OPTIONS:" + +extern "C" const char mysql_bootstrap_sql[]; + +char default_os_user[]= "NT AUTHORITY\\NetworkService"; +static int create_db_instance(); +static uint opt_silent; +static char datadir_buffer[FN_REFLEN]; +static char mysqld_path[FN_REFLEN]; +static char *opt_datadir; +static char *opt_service; +static char *opt_password; +static int opt_port; +static char *opt_socket; +static char *opt_os_user; +static char *opt_os_password; +static my_bool opt_default_user; +static my_bool opt_allow_remote_root_access; +static my_bool opt_skip_networking; +static my_bool verbose_errors; + + +static struct my_option my_long_options[]= +{ + {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"datadir", 'd', "Data directory of the new database", + &opt_datadir, &opt_datadir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"service", 'S', "Name of the Windows service", + &opt_service, &opt_service, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"password", 'p', "Root password", + &opt_password, &opt_password, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"port", 'P', "mysql port", + &opt_port, &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"socket", 'W', + "named pipe name (if missing, it will be set the same as service)", + &opt_socket, &opt_socket, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default-user", 'D', "Create default user", + &opt_default_user, &opt_default_user, 0 , GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"allow-remote-root-access", 'R', + "Allows remote access from network for user root", + &opt_allow_remote_root_access, &opt_allow_remote_root_access, 0 , GET_BOOL, + OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-networking", 'N', "Do not use TCP connections, use pipe instead", + &opt_skip_networking, &opt_skip_networking, 0 , GET_BOOL, OPT_ARG, 0, 0, 0, 0, + 0, 0}, + {"silent", 's', "Print less information", &opt_silent, + &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + + +static my_bool +get_one_option(int optid, + const struct my_option *opt __attribute__ ((unused)), + char *argument __attribute__ ((unused))) +{ + DBUG_ENTER("get_one_option"); + switch (optid) { + case '?': + printf("%s\n", USAGETEXT); + my_print_help(my_long_options); + exit(0); + break; + } + DBUG_RETURN(0); +} + + +static void die(const char *fmt, ...) +{ + va_list args; + DBUG_ENTER("die"); + + /* Print the error message */ + va_start(args, fmt); + fprintf(stderr, "FATAL ERROR: "); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + if (verbose_errors) + { + fprintf(stderr, + "http://kb.askmonty.org/v/installation-issues-on-windows contains some help\n" + "for solving the most common problems. If this doesn't help you, please\n" + "leave a comment in the knowledge base or file a bug report at\n" + "https://bugs.launchpad.net/maria"); + } + fflush(stderr); + va_end(args); + my_end(0); + exit(1); +} + + +static void verbose(const char *fmt, ...) +{ + va_list args; + + if (opt_silent) + return; + + /* Print the verbose message */ + va_start(args, fmt); + vfprintf(stdout, fmt, args); + fputc('\n', stdout); + fflush(stdout); + va_end(args); +} + + +int main(int argc, char **argv) +{ + int error; + char self_name[FN_REFLEN]; + char *p; + + MY_INIT(argv[0]); + GetModuleFileName(NULL, self_name, FN_REFLEN); + strcpy(mysqld_path,self_name); + p= strrchr(mysqld_path, FN_LIBCHAR); + if (p) + { + strcpy(p, "\\mysqld.exe"); + } + + if ((error= handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(error); + if (!opt_datadir) + { + my_print_help(my_long_options); + die("parameter --datadir=# is mandatory"); + } + + /* Print some help on errors */ + verbose_errors= TRUE; + + if (!opt_os_user) + { + opt_os_user= default_os_user; + opt_os_password= NULL; + } + /* Workaround WiX bug (strip possible quote character at the end of path) */ + size_t len= strlen(opt_datadir); + if (len > 0) + { + if (opt_datadir[len-1] == '"') + { + opt_datadir[len-1]= 0; + } + } + GetFullPathName(opt_datadir, FN_REFLEN, datadir_buffer, NULL); + opt_datadir= datadir_buffer; + + if (create_db_instance()) + { + die("database creation failed"); + } + + printf("Creation of the database was successfull"); + return 0; +} + + + +/** + Convert slashes in paths into MySQL-compatible form +*/ + +static void convert_slashes(char *s) +{ + for (; *s ; s++) + if (*s == '\\') + *s= '/'; +} + + +/** + Calculate basedir from mysqld.exe path. + Basedir assumed to be is one level up from the mysqld.exe directory location. + E.g basedir for C:\my\bin\mysqld.exe would be C:\my +*/ + +static void get_basedir(char *basedir, int size, const char *mysqld_path) +{ + strcpy_s(basedir, size, mysqld_path); + convert_slashes(basedir); + char *p= strrchr(basedir,'/'); + if (p) + { + *p = 0; + p= strrchr(basedir, '/'); + if (p) + *p= 0; + } +} + + +/** + Allocate and initialize command line for mysqld --bootstrap. + The resulting string is passed to popen, so it has a lot of quoting + quoting around the full string plus quoting around parameters with spaces. +*/ + +static char *init_bootstrap_command_line(char *cmdline, size_t size) +{ + char basedir[MAX_PATH]; + get_basedir(basedir, sizeof(basedir), mysqld_path); + + my_snprintf(cmdline, size-1, + "\"\"%s\" --no-defaults --bootstrap" + " \"--language=%s\\share\\english\"" + " --basedir=. --datadir=. --default-storage-engine=myisam" + " --max_allowed_packet=9M --loose-skip-innodb --loose-skip-pbxt" + " --net-buffer-length=16k\"", mysqld_path, basedir); + return cmdline; +} + + +/** + Create my.ini in current directory (this is assumed to be + data directory as well). +*/ + +static int create_myini() +{ + my_bool enable_named_pipe= FALSE; + printf("Creating my.ini file\n"); + + char path_buf[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, path_buf); + + /* Create ini file. */ + FILE *myini= fopen("my.ini","wt"); + if (!myini) + { + die("Cannot create my.ini in data directory"); + } + + /* Write out server settings. */ + fprintf(myini, "[mysqld]\n"); + convert_slashes(path_buf); + fprintf(myini, "datadir=%s\n", path_buf); + if (opt_skip_networking) + { + fprintf(myini,"skip-networking\n"); + if (!opt_socket) + opt_socket= opt_service; + } + enable_named_pipe= (my_bool) + ((opt_socket && opt_socket[0]) || opt_skip_networking); + + if (enable_named_pipe) + { + fprintf(myini,"enable-named-pipe\n"); + } + + if (opt_socket && opt_socket[0]) + { + fprintf(myini, "socket=%s\n", opt_socket); + } + if (opt_port) + { + fprintf(myini,"port=%d\n", opt_port); + } + + /* Write out client settings. */ + fprintf(myini, "[client]\n"); + + /* Used for named pipes */ + if (opt_socket && opt_socket[0]) + fprintf(myini,"socket=%s\n",opt_socket); + if (opt_skip_networking) + fprintf(myini,"protocol=pipe\n"); + else if (opt_port) + fprintf(myini,"port=%d\n",opt_port); + fclose(myini); + return 0; +} + + +static const char update_root_passwd_part1[]= + "UPDATE mysql.user SET Password = PASSWORD('"; +static const char update_root_passwd_part2[]= + "') where User='root';\n"; +static const char remove_default_user_cmd[]= + "DELETE FROM mysql.user where User='';\n"; +static const char allow_remote_root_access_cmd[]= + "CREATE TEMPORARY TABLE tmp_user LIKE user;\n" + "INSERT INTO tmp_user SELECT * from user where user='root' " + " AND host='localhost';\n" + "UPDATE tmp_user SET host='%';\n" + "INSERT INTO user SELECT * FROM tmp_user;\n" + "DROP TABLE tmp_user;\n"; +static const char end_of_script[]="-- end."; + +/* Register service. Assume my.ini is in datadir */ + +static int register_service() +{ + char buf[3*MAX_PATH +32]; /* path to mysqld.exe, to my.ini, service name */ + SC_HANDLE sc_manager, sc_service; + + size_t datadir_len= strlen(opt_datadir); + const char *backslash_after_datadir= "\\"; + + if (datadir_len && opt_datadir[datadir_len-1] == '\\') + backslash_after_datadir= ""; + + verbose("Registering service '%s'", opt_service); + my_snprintf(buf, sizeof(buf)-1, + "\"%s\" \"--defaults-file=%s%smy.ini\" \"%s\"" , mysqld_path, opt_datadir, + backslash_after_datadir, opt_service); + + /* Get a handle to the SCM database. */ + sc_manager= OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (!sc_manager) + { + die("OpenSCManager failed (%u)\n", GetLastError()); + } + + /* Create the service. */ + sc_service= CreateService(sc_manager, opt_service, opt_service, + SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, buf, NULL, NULL, NULL, opt_os_user, opt_os_password); + + if (!sc_service) + { + CloseServiceHandle(sc_manager); + die("CreateService failed (%u)", GetLastError()); + } + + SERVICE_DESCRIPTION sd= { "MariaDB database server" }; + ChangeServiceConfig2(sc_service, SERVICE_CONFIG_DESCRIPTION, &sd); + CloseServiceHandle(sc_service); + CloseServiceHandle(sc_manager); + return 0; +} + + +static void clean_directory(const char *dir) +{ + char dir2[MAX_PATH+2]; + *(strmake(dir2, dir, MAX_PATH+1)+1)= 0; + + SHFILEOPSTRUCT fileop; + fileop.hwnd= NULL; /* no status display */ + fileop.wFunc= FO_DELETE; /* delete operation */ + fileop.pFrom= dir2; /* source file name as double null terminated string */ + fileop.pTo= NULL; /* no destination needed */ + fileop.fFlags= FOF_NOCONFIRMATION|FOF_SILENT; /* do not prompt the user */ + + + fileop.fAnyOperationsAborted= FALSE; + fileop.lpszProgressTitle= NULL; + fileop.hNameMappings= NULL; + + SHFileOperation(&fileop); +} + + +/* + Define directory permission to have inheritable all access for a user + (defined as username or group string or as SID) +*/ + +static int set_directory_permissions(const char *dir, const char *os_user) +{ + + struct{ + TOKEN_USER tokenUser; + BYTE buffer[SECURITY_MAX_SID_SIZE]; + } tokenInfoBuffer; + + HANDLE hDir= CreateFile(dir,READ_CONTROL|WRITE_DAC,0,NULL,OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS,NULL); + if (hDir == INVALID_HANDLE_VALUE) + return -1; + ACL* pOldDACL; + SECURITY_DESCRIPTOR* pSD= NULL; + EXPLICIT_ACCESS ea={0}; + BOOL isWellKnownSID= FALSE; + WELL_KNOWN_SID_TYPE wellKnownSidType = WinNullSid; + PSID pSid= NULL; + + GetSecurityInfo(hDir, SE_FILE_OBJECT , DACL_SECURITY_INFORMATION,NULL, NULL, + &pOldDACL, NULL, (void**)&pSD); + + if (os_user) + { + /* Check for 3 predefined service users + They might have localized names in non-English Windows, thus they need + to be handled using well-known SIDs. + */ + if (stricmp(os_user, "NT AUTHORITY\\NetworkService") == 0) + { + wellKnownSidType= WinNetworkServiceSid; + } + else if (stricmp(os_user, "NT AUTHORITY\\LocalService") == 0) + { + wellKnownSidType= WinLocalServiceSid; + } + else if (stricmp(os_user, "NT AUTHORITY\\LocalSystem") == 0) + { + wellKnownSidType= WinLocalSystemSid; + } + + if (wellKnownSidType != WinNullSid) + { + DWORD size= SECURITY_MAX_SID_SIZE; + pSid= (PSID)tokenInfoBuffer.buffer; + if (!CreateWellKnownSid(wellKnownSidType, NULL, pSid, + &size)) + { + return 1; + } + ea.Trustee.TrusteeForm= TRUSTEE_IS_SID; + ea.Trustee.ptstrName= (LPTSTR)pSid; + } + else + { + ea.Trustee.TrusteeForm= TRUSTEE_IS_NAME; + ea.Trustee.ptstrName= (LPSTR)os_user; + } + } + else + { + HANDLE token; + if (OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY, &token)) + { + + DWORD length= (DWORD) sizeof(tokenInfoBuffer); + if (GetTokenInformation(token, TokenUser, &tokenInfoBuffer, + length, &length)) + { + pSid= tokenInfoBuffer.tokenUser.User.Sid; + } + } + if (!pSid) + return 0; + ea.Trustee.TrusteeForm= TRUSTEE_IS_SID; + ea.Trustee.ptstrName= (LPTSTR)pSid; + } + ea.grfAccessMode= GRANT_ACCESS; + ea.grfAccessPermissions= GENERIC_ALL; + ea.grfInheritance= CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE; + ea.Trustee.TrusteeType= TRUSTEE_IS_UNKNOWN; + ACL* pNewDACL= 0; + DWORD err= SetEntriesInAcl(1,&ea,pOldDACL,&pNewDACL); + if (pNewDACL) + { + SetSecurityInfo(hDir,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL, + pNewDACL, NULL); + } + if (pSD != NULL) + LocalFree((HLOCAL) pSD); + if (pNewDACL != NULL) + LocalFree((HLOCAL) pNewDACL); + CloseHandle(hDir); + return 0; +} + + +/* + Give directory permissions for special service user NT SERVICE\servicename + this user is available only on Win7 and later. +*/ + +void grant_directory_permissions_to_service() +{ + char service_user[MAX_PATH+ 12]; + OSVERSIONINFO info; + info.dwOSVersionInfoSize= sizeof(info); + GetVersionEx(&info); + if (info.dwMajorVersion >6 || + (info.dwMajorVersion== 6 && info.dwMinorVersion > 0) + && opt_service) + { + my_snprintf(service_user,sizeof(service_user), "NT SERVICE\\%s", + opt_service); + set_directory_permissions(opt_datadir, service_user); + } +} + + +/* Create database instance (including registering as service etc) .*/ + +static int create_db_instance() +{ + int ret= 0; + char cwd[MAX_PATH]; + DWORD cwd_len= MAX_PATH; + char cmdline[3*MAX_PATH]; + FILE *in; + + verbose("Running bootstrap"); + + GetCurrentDirectory(cwd_len, cwd); + CreateDirectory(opt_datadir, NULL); /*ignore error, it might already exist */ + + if (!SetCurrentDirectory(opt_datadir)) + { + die("Cannot set current directory to '%s'\n",opt_datadir); + return -1; + } + + CreateDirectory("mysql",NULL); + CreateDirectory("test", NULL); + + /* + Set data directory permissions for both current user and + default_os_user (the one who runs services). + */ + set_directory_permissions(opt_datadir, NULL); + set_directory_permissions(opt_datadir, default_os_user); + + /* Do mysqld --bootstrap. */ + init_bootstrap_command_line(cmdline, sizeof(cmdline)); + /* verbose("Executing %s", cmdline); */ + + in= popen(cmdline, "wt"); + if (!in) + goto end; + + if (fwrite("use mysql;\n",11,1, in) != 1) + { + verbose("ERROR: Cannot write to mysqld's stdin"); + ret= 1; + goto end; + } + + /* Write the bootstrap script to stdin. */ + if (fwrite(mysql_bootstrap_sql, strlen(mysql_bootstrap_sql), 1, in) != 1) + { + verbose("ERROR: Cannot write to mysqld's stdin"); + ret= 1; + goto end; + } + + /* Remove default user, if requested. */ + if (!opt_default_user) + { + verbose("Removing default user",remove_default_user_cmd); + fputs(remove_default_user_cmd, in); + fflush(in); + } + + if (opt_allow_remote_root_access) + { + verbose("Allowing remote access for user root",remove_default_user_cmd); + fputs(allow_remote_root_access_cmd,in); + fflush(in); + } + + /* Change root password if requested. */ + if (opt_password) + { + verbose("Changing root password",remove_default_user_cmd); + fputs(update_root_passwd_part1, in); + fputs(opt_password, in); + fputs(update_root_passwd_part2, in); + fflush(in); + } + + /* + On some reason, bootstrap chokes if last command sent via stdin ends with + newline, so we supply a dummy comment, that does not end with newline. + */ + fputs(end_of_script, in); + fflush(in); + + /* Check if bootstrap has completed successfully. */ + ret= pclose(in); + if (ret) + { + verbose("mysqld returned error %d in pclose",ret); + goto end; + } + + /* Create my.ini file in data directory.*/ + ret= create_myini(); + if (ret) + goto end; + + /* Register service if requested. */ + if (opt_service && opt_service[0]) + { + ret= register_service(); + grant_directory_permissions_to_service(); + if (ret) + goto end; + } + +end: + if (ret) + { + SetCurrentDirectory(cwd); + clean_directory(opt_datadir); + } + return ret; +} diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 7b3c264c896..065425c4c96 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -30,6 +30,15 @@ #ifndef MYSQL_CLIENT +/* + the following #define adds server-only members to enum_mysql_show_type, + that is defined in mysql/plugin.h + it has to be before mysql/plugin.h is included. +*/ +#define SHOW_always_last SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, \ + SHOW_HAVE, SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, \ + SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS + #include <my_global.h> #include <mysql_version.h> #include <mysql_embed.h> @@ -94,12 +103,16 @@ extern MYSQL_PLUGIN_IMPORT const char *primary_key_name; #include "unireg.h" void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size); +#endif // MYSQL_CLIENT + void *sql_alloc(size_t); void *sql_calloc(size_t); char *sql_strdup(const char *str); char *sql_strmake(const char *str, size_t len); void *sql_memdup(const void * ptr, size_t size); void sql_element_free(void *ptr); + +#ifndef MYSQL_CLIENT char *sql_strmake_with_convert(const char *str, size_t arg_length, CHARSET_INFO *from_cs, size_t max_res_length, @@ -510,7 +523,7 @@ protected: #define MODE_PIPES_AS_CONCAT 2 #define MODE_ANSI_QUOTES 4 #define MODE_IGNORE_SPACE 8 -#define MODE_NOT_USED 16 +#define MODE_IGNORE_BAD_TABLE_OPTIONS 16 #define MODE_ONLY_FULL_GROUP_BY 32 #define MODE_NO_UNSIGNED_SUBTRACTION 64 #define MODE_NO_DIR_IN_CREATE 128 @@ -802,6 +815,7 @@ inline bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list) inline bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc) { return false; } +#define decrease_user_connections(X) do { } while(0) /* nothing */ #endif /*NO_EMBEDDED_ACCESS_CHECKS*/ bool multi_update_precheck(THD *thd, TABLE_LIST *tables); @@ -1030,15 +1044,14 @@ int write_bin_log(THD *thd, bool clear_error, char const *query, ulong query_length); /* sql_connect.cc */ -int check_user(THD *thd, enum enum_server_command command, - const char *passwd, uint passwd_len, const char *db, - bool check_count); pthread_handler_t handle_one_connection(void *arg); bool init_new_connection_handler_thread(); void reset_mqh(LEX_USER *lu, bool get_them); bool check_mqh(THD *thd, uint check_command); void time_out_user_resource_limits(THD *thd, USER_CONN *uc); +#ifndef NO_EMBEDDED_ACCESS_CHECKS void decrease_user_connections(USER_CONN *uc); +#endif bool thd_init_client_charset(THD *thd, uint cs_number); inline bool is_supported_parser_charset(CHARSET_INFO *cs) { @@ -1048,6 +1061,10 @@ bool setup_connection_thread_globals(THD *thd); bool login_connection(THD *thd); void end_connection(THD *thd); void prepare_new_connection_state(THD* thd); +void update_global_user_stats(THD* thd, bool create_user, time_t now); +int get_or_create_user_conn(THD *thd, const char *user, + const char *host, USER_RESOURCES *mqh); +int check_for_max_user_connections(THD *thd, USER_CONN *uc); int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); @@ -1084,14 +1101,22 @@ bool is_update_query(enum enum_sql_command command); bool is_log_table_write_query(enum enum_sql_command command); bool alloc_query(THD *thd, const char *packet, uint packet_length); void mysql_init_select(LEX *lex); -void mysql_reset_thd_for_next_command(THD *thd); +void mysql_reset_thd_for_next_command(THD *thd, my_bool calculate_userstat); bool mysql_new_select(LEX *lex, bool move_down); void create_select_for_variable(const char *var_name); void mysql_init_multi_delete(LEX *lex); bool multi_delete_set_locks_and_link_aux_tables(LEX *lex); void init_max_user_conn(void); void init_update_queries(void); +void init_global_user_stats(void); +void init_global_table_stats(void); +void init_global_index_stats(void); +void init_global_client_stats(void); void free_max_user_conn(void); +void free_global_user_stats(void); +void free_global_table_stats(void); +void free_global_index_stats(void); +void free_global_client_stats(void); pthread_handler_t handle_bootstrap(void *arg); int mysql_execute_command(THD *thd); bool do_command(THD *thd); @@ -1341,6 +1366,7 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length, bool allow_rowid, uint *cached_field_index_ptr); Field * find_field_in_table_sef(TABLE *table, const char *name); +int update_virtual_fields(THD *thd, TABLE *table, bool ignore_stored= FALSE); #endif /* MYSQL_SERVER */ @@ -1471,14 +1497,17 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum enum_field_types t LEX_STRING *comment, char *change, List<String> *interval_list, CHARSET_INFO *cs, - uint uint_geom_type); + uint uint_geom_type, + Virtual_column_info *vcol_info, + engine_option_value *create_options); Create_field * new_create_field(THD *thd, char *field_name, enum_field_types type, char *length, char *decimals, uint type_modifier, Item *default_value, Item *on_update_value, LEX_STRING *comment, char *change, List<String> *interval_list, CHARSET_INFO *cs, - uint uint_geom_type); + uint uint_geom_type, + Virtual_column_info *vcol_info); void store_position_for_column(const char *name); bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *group,bool asc); bool push_new_name_resolution_context(THD *thd, @@ -1608,6 +1637,7 @@ void remove_db_from_cache(const char *db); void flush_tables(); bool is_equal(const LEX_STRING *a, const LEX_STRING *b); char *make_default_log_name(char *buff,const char* log_ext); +char *make_once_alloced_filename(const char *basename, const char *ext); #ifdef WITH_PARTITION_STORAGE_ENGINE uint fast_alter_partition_table(THD *thd, TABLE *table, @@ -1949,7 +1979,7 @@ extern MYSQL_PLUGIN_IMPORT uint reg_ext_length; #ifdef MYSQL_SERVER extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN]; extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file; -extern char log_error_file[FN_REFLEN], *opt_tc_log_file; +extern char log_error_file[FN_REFLEN], *opt_tc_log_file, *opt_log_basename; extern ulonglong log_10_int[20]; extern ulonglong keybuff_size; extern ulonglong thd_startup_options; @@ -1969,6 +1999,7 @@ extern ulong max_connect_errors, connect_timeout; extern ulong extra_max_connections; extern ulong slave_net_timeout, slave_trans_retries; extern uint max_user_connections; +extern ulonglong denied_connections; extern ulong what_to_log,flush_time; extern ulong query_buff_size; extern ulong max_prepared_stmt_count, prepared_stmt_count; @@ -2018,12 +2049,14 @@ extern bool volatile abort_loop, shutdown_in_progress; extern bool in_bootstrap; extern uint volatile thread_count, thread_running, global_read_lock; extern ulong thread_created; +extern uint thread_handling; extern uint connection_count, extra_connection_count; extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern ulong slave_exec_mode_options; extern my_bool opt_readonly, lower_case_file_system; +extern my_bool opt_userstat_running; extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; extern my_bool opt_secure_auth, debug_assert_if_crashed_table; extern char* opt_secure_file_priv; @@ -2068,6 +2101,11 @@ extern pthread_mutex_t LOCK_des_key_file; #endif extern pthread_mutex_t LOCK_server_started; extern pthread_cond_t COND_server_started; +extern pthread_mutex_t LOCK_global_user_client_stats; +extern pthread_mutex_t LOCK_global_table_stats; +extern pthread_mutex_t LOCK_global_index_stats; +extern pthread_mutex_t LOCK_stats; + extern int mysqld_server_started; extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; extern rw_lock_t LOCK_system_variables_hash; @@ -2094,6 +2132,11 @@ extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[]; extern String null_string; extern HASH open_cache, lock_db_cache; +extern HASH global_user_stats; +extern HASH global_client_stats; +extern HASH global_table_stats; +extern HASH global_index_stats; + extern TABLE *unused_tables; extern const char* any_db; extern struct my_option my_long_options[]; @@ -2261,7 +2304,7 @@ longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(uchar *,uint,char,char); -void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, +bool init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, SQL_SELECT *select, int use_record_cache, bool print_errors, bool disable_rr_cache); void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, @@ -2302,6 +2345,7 @@ char *fn_rext(char *name); /* Conversion functions */ #endif /* MYSQL_SERVER */ + #if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS uint strconvert(CHARSET_INFO *from_cs, const char *from, CHARSET_INFO *to_cs, char *to, uint to_length, uint *errors); @@ -2326,10 +2370,6 @@ uint build_table_filename(char *buff, size_t bufflen, const char *db, const char *get_canonical_filename(handler *file, const char *path, char *tmp_path); -#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" -#define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9 -#define SAFE_NAME_LEN (NAME_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH) - uint build_table_shadow_filename(char *buff, size_t bufflen, ALTER_PARTITION_PARAM_TYPE *lpt); /* Flags for conversion functions. */ diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc new file mode 100644 index 00000000000..db916101eb1 --- /dev/null +++ b/sql/mysql_upgrade_service.cc @@ -0,0 +1,522 @@ +/* Copyright (C) 2010-2011 Monty Program Ab & Vladislav Vaintroub + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + mysql_upgrade_service upgrades mysql service on Windows. + It changes service definition to point to the new mysqld.exe, restarts the + server and runs mysql_upgrade +*/ + +#define DONT_DEFINE_VOID +#include <process.h> +#include <my_global.h> +#include <my_getopt.h> +#include <my_sys.h> +#include <m_string.h> +#include <mysql_version.h> +#include <winservice.h> + +#include <windows.h> + +/* We're using version APIs */ +#pragma comment(lib, "version") + +#define USAGETEXT \ +"mysql_upgrade_service.exe Ver 1.00 for Windows\n" \ +"Copyright (C) 2010-2011 Monty Program Ab & Vladislav Vaintroub" \ +"This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n" \ +"and you are welcome to modify and redistribute it under the GPL v2 license\n" \ +"Usage: mysql_upgrade_service.exe [OPTIONS]\n" \ +"OPTIONS:" + +static char mysqld_path[MAX_PATH]; +static char mysqladmin_path[MAX_PATH]; +static char mysqlupgrade_path[MAX_PATH]; + +static char defaults_file_param[MAX_PATH + 16]; /*--defaults-file=<path> */ +static char logfile_path[MAX_PATH]; +static char *opt_service; +static SC_HANDLE service; +static SC_HANDLE scm; +HANDLE mysqld_process; // mysqld.exe started for upgrade +DWORD initial_service_state= -1; // initial state of the service +HANDLE logfile_handle; + +/* + Startup and shutdown timeouts, in seconds. + Maybe,they can be made parameters +*/ +static unsigned int startup_timeout= 60; +static unsigned int shutdown_timeout= 60; + +static struct my_option my_long_options[]= +{ + {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"service", 'S', "Name of the existing Windows service", + &opt_service, &opt_service, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + + + +static my_bool +get_one_option(int optid, + const struct my_option *opt __attribute__ ((unused)), + char *argument __attribute__ ((unused))) +{ + DBUG_ENTER("get_one_option"); + switch (optid) { + case '?': + printf("%s\n", USAGETEXT); + my_print_help(my_long_options); + exit(0); + break; + } + DBUG_RETURN(0); +} + + + +static void log(const char *fmt, ...) +{ + va_list args; + /* Print the error message */ + va_start(args, fmt); + vfprintf(stdout,fmt, args); + va_end(args); + fputc('\n', stdout); + fflush(stdout); +} + + +static void die(const char *fmt, ...) +{ + va_list args; + DBUG_ENTER("die"); + + /* Print the error message */ + va_start(args, fmt); + + fprintf(stderr, "FATAL ERROR: "); + vfprintf(stderr, fmt, args); + if (logfile_path[0]) + { + fprintf(stderr, "Additional information can be found in the log file %s", + logfile_path); + } + va_end(args); + fputc('\n', stderr); + fflush(stdout); + /* Cleanup */ + + /* + Stop service that we started, if it was not initally running at + program start. + */ + if (initial_service_state != -1 && initial_service_state != SERVICE_RUNNING) + { + SERVICE_STATUS service_status; + ControlService(service, SERVICE_CONTROL_STOP, &service_status); + } + + if (scm) + CloseServiceHandle(scm); + if (service) + CloseServiceHandle(service); + /* Stop mysqld.exe, if it was started for upgrade */ + if (mysqld_process) + TerminateProcess(mysqld_process, 3); + if (logfile_handle) + CloseHandle(logfile_handle); + my_end(0); + + exit(1); +} + + +/* + spawn-like function to run subprocesses. + We also redirect the full output to the log file. + + Typical usage could be something like + run_tool(P_NOWAIT, "cmd.exe", "/c" , "echo", "foo", NULL) + + @param wait_flag (P_WAIT or P_NOWAIT) + @program program to run + + Rest of the parameters is NULL terminated strings building command line. + + @return intptr containing either process handle, if P_NOWAIT is used + or return code of the process (if P_WAIT is used) +*/ + +static intptr_t run_tool(int wait_flag, const char *program,...) +{ + static char cmdline[32*1024]; + char *end; + va_list args; + va_start(args, program); + if (!program) + die("Invalid call to run_tool"); + end= strxmov(cmdline, "\"", program, "\"", NullS); + + for(;;) + { + char *param= va_arg(args,char *); + if(!param) + break; + end= strxmov(end, " \"", param, "\"", NullS); + } + va_end(args); + + /* Create output file if not alredy done */ + if (!logfile_handle) + { + char tmpdir[FN_REFLEN]; + GetTempPath(FN_REFLEN, tmpdir); + sprintf_s(logfile_path, "%s\\mysql_upgrade_service.%s.log", tmpdir, + opt_service); + logfile_handle= CreateFile(logfile_path, GENERIC_WRITE, FILE_SHARE_READ, + NULL, TRUNCATE_EXISTING, 0, NULL); + if (!logfile_handle) + { + die("Cannot open log file %s, windows error %u", + logfile_path, GetLastError()); + } + } + + /* Start child process */ + STARTUPINFO si= {0}; + si.cb= sizeof(si); + si.hStdInput= GetStdHandle(STD_INPUT_HANDLE); + si.hStdError= logfile_handle; + si.hStdOutput= logfile_handle; + si.dwFlags= STARTF_USESTDHANDLES; + PROCESS_INFORMATION pi; + if (!CreateProcess(NULL, cmdline, NULL, + NULL, TRUE, NULL, NULL, NULL, &si, &pi)) + { + die("CreateProcess failed (commandline %s)", cmdline); + } + CloseHandle(pi.hThread); + + if (wait_flag == P_NOWAIT) + { + /* Do not wait for process to complete, return handle. */ + return (intptr_t)pi.hProcess; + } + + /* Wait for process to complete. */ + if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0) + { + die("WaitForSingleObject() failed"); + } + DWORD exit_code; + if (!GetExitCodeProcess(pi.hProcess, &exit_code)) + { + die("GetExitCodeProcess() failed"); + } + return (intptr_t)exit_code; +} + + +void stop_mysqld_service() +{ + DWORD needed; + SERVICE_STATUS_PROCESS ssp; + int timeout= shutdown_timeout*1000; + for(;;) + { + if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, + (LPBYTE)&ssp, + sizeof(SERVICE_STATUS_PROCESS), + &needed)) + { + die("QueryServiceStatusEx failed (%u)\n", GetLastError()); + } + + /* + Remeber initial state of the service, we will restore it on + exit. + */ + if(initial_service_state == -1) + initial_service_state= ssp.dwCurrentState; + + switch(ssp.dwCurrentState) + { + case SERVICE_STOPPED: + return; + case SERVICE_RUNNING: + if(!ControlService(service, SERVICE_CONTROL_STOP, + (SERVICE_STATUS *)&ssp)) + die("ControlService failed, error %u\n", GetLastError()); + case SERVICE_START_PENDING: + case SERVICE_STOP_PENDING: + if(timeout < 0) + die("Service does not stop after %d seconds timeout",shutdown_timeout); + Sleep(100); + timeout -= 100; + break; + default: + die("Unexpected service state %d",ssp.dwCurrentState); + } + } +} + + +/* + Shutdown mysql server. Not using mysqladmin, since + our --skip-grant-tables do not work anymore after mysql_upgrade + that does "flush privileges". Instead, the shutdown event is set. +*/ +void initiate_mysqld_shutdown() +{ + char event_name[32]; + DWORD pid= GetProcessId(mysqld_process); + sprintf_s(event_name, "MySQLShutdown%d", pid); + HANDLE shutdown_handle= OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name); + if(!shutdown_handle) + { + die("OpenEvent() failed for shutdown event"); + } + + if(!SetEvent(shutdown_handle)) + { + die("SetEvent() failed"); + } +} + + +/* + Change service configuration (binPath) to point to mysqld from + this installation. +*/ +static void change_service_config() +{ + + char defaults_file[MAX_PATH]; + char default_character_set[64]; + char buf[MAX_PATH]; + char commandline[3*MAX_PATH + 19]; + int i; + + scm= OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if(!scm) + die("OpenSCManager failed with %u", GetLastError()); + service= OpenService(scm, opt_service, SERVICE_ALL_ACCESS); + if (!service) + die("OpenService failed with %u", GetLastError()); + + BYTE config_buffer[8*1024]; + LPQUERY_SERVICE_CONFIGW config= (LPQUERY_SERVICE_CONFIGW)config_buffer; + DWORD size= sizeof(config_buffer); + DWORD needed; + if (!QueryServiceConfigW(service, config, size, &needed)) + die("QueryServiceConfig failed with %u", GetLastError()); + + mysqld_service_properties props; + if (get_mysql_service_properties(config->lpBinaryPathName, &props)) + { + die("Not a valid MySQL service"); + } + + int my_major= MYSQL_VERSION_ID/10000; + int my_minor= (MYSQL_VERSION_ID %10000)/100; + int my_patch= MYSQL_VERSION_ID%100; + + if(my_major < props.version_major || + (my_major == props.version_major && my_minor < props.version_minor)) + { + die("Can not downgrade, the service is currently running as version %d.%d.%d" + ", my version is %d.%d.%d", props.version_major, props.version_minor, + props.version_patch, my_major, my_minor, my_patch); + } + + if(props.inifile[0] == 0) + { + /* + Weird case, no --defaults-file in service definition, need to create one. + */ + sprintf_s(props.inifile, MAX_PATH, "%s\\my.ini", props.datadir); + } + + /* + Write datadir to my.ini, after converting backslashes to + unix style slashes. + */ + strcpy_s(buf, MAX_PATH, props.datadir); + for(i= 0; buf[i]; i++) + { + if (buf[i] == '\\') + buf[i]= '/'; + } + WritePrivateProfileString("mysqld", "datadir",buf, props.inifile); + + /* + Remove basedir from defaults file, otherwise the service wont come up in + the new version, and will complain about mismatched message file. + */ + WritePrivateProfileString("mysqld", "basedir",NULL, props.inifile); + + /* + Replace default-character-set with character-set-server, to avoid + "default-character-set is deprecated and will be replaced ..." + message. + */ + default_character_set[0]= 0; + GetPrivateProfileString("mysqld", "default-character-set", NULL, + default_character_set, sizeof(default_character_set), defaults_file); + if (default_character_set[0]) + { + WritePrivateProfileString("mysqld", "default-character-set", NULL, + defaults_file); + WritePrivateProfileString("mysqld", "character-set-server", + default_character_set, defaults_file); + } + + sprintf(defaults_file_param,"--defaults-file=%s", props.inifile); + sprintf_s(commandline, "\"%s\" \"%s\" \"%s\"", mysqld_path, + defaults_file_param, opt_service); + if (!ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, + SERVICE_NO_CHANGE, commandline, NULL, NULL, NULL, NULL, NULL, NULL)) + { + die("ChangeServiceConfig failed with %u", GetLastError()); + } + +} + + +int main(int argc, char **argv) +{ + int error; + MY_INIT(argv[0]); + char bindir[FN_REFLEN]; + char *p; + + /* Parse options */ + if ((error= handle_options(&argc, &argv, my_long_options, get_one_option))) + die(""); + if (!opt_service) + die("--service=# parameter is mandatory"); + + /* + Get full path to mysqld, we need it when changing service configuration. + Assume installation layout, i.e mysqld.exe, mysqladmin.exe, mysqlupgrade.exe + and mysql_upgrade_service.exe are in the same directory. + */ + GetModuleFileName(NULL, bindir, FN_REFLEN); + p= strrchr(bindir, FN_LIBCHAR); + if(p) + { + *p= 0; + } + sprintf_s(mysqld_path, "%s\\mysqld.exe", bindir); + sprintf_s(mysqladmin_path, "%s\\mysqladmin.exe", bindir); + sprintf_s(mysqlupgrade_path, "%s\\mysql_upgrade.exe", bindir); + + char *paths[]= {mysqld_path, mysqladmin_path, mysqlupgrade_path}; + for(int i= 0; i< 3;i++) + { + if(GetFileAttributes(paths[i]) == INVALID_FILE_ATTRIBUTES) + die("File %s does not exist", paths[i]); + } + + /* + Messages written on stdout should not be buffered, GUI upgrade program + reads them from pipe and uses as progress indicator. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + log("Phase 1/8: Changing service configuration"); + change_service_config(); + + log("Phase 2/8: Stopping service"); + stop_mysqld_service(); + + /* + Start mysqld.exe as non-service skipping privileges (so we do not + care about the password). But disable networking and enable pipe + for communication, for security reasons. + */ + char socket_param[FN_REFLEN]; + sprintf_s(socket_param,"--socket=mysql_upgrade_service_%d", + GetCurrentProcessId()); + + log("Phase 3/8: Starting mysqld for upgrade"); + mysqld_process= (HANDLE)run_tool(P_NOWAIT, mysqld_path, + defaults_file_param, "--skip-networking", "--skip-grant-tables", + "--enable-named-pipe", socket_param, NULL); + + if (mysqld_process == INVALID_HANDLE_VALUE) + { + die("Cannot start mysqld.exe process, errno=%d", errno); + } + + log("Phase 4/8: Waiting for startup to complete"); + DWORD start_duration_ms= 0; + for(;;) + { + if (WaitForSingleObject(mysqld_process, 0) != WAIT_TIMEOUT) + die("mysqld.exe did not start"); + + if (run_tool(P_WAIT, mysqladmin_path, "--protocol=pipe", + socket_param, "ping", NULL) == 0) + { + break; + } + if (start_duration_ms > startup_timeout*1000) + die("Server did not come up in %d seconds",startup_timeout); + Sleep(500); + start_duration_ms+= 500; + } + + log("Phase 5/8: Running mysql_upgrade"); + int upgrade_err= (int) run_tool(P_WAIT, mysqlupgrade_path, + "--protocol=pipe", "--force", socket_param, + NULL); + + if (upgrade_err) + die("mysql_upgrade failed with error code %d\n", upgrade_err); + + log("Phase 6/8: Initiating server shutdown"); + initiate_mysqld_shutdown(); + + log("Phase 7/8: Waiting for shutdown to complete"); + if (WaitForSingleObject(mysqld_process, shutdown_timeout*1000) + != WAIT_OBJECT_0) + { + /* Shutdown takes too long */ + die("mysqld does not shutdown."); + } + CloseHandle(mysqld_process); + mysqld_process= NULL; + + log("Phase 8/8: Starting service%s", + (initial_service_state == SERVICE_RUNNING)?"":" (skipped)"); + if (initial_service_state == SERVICE_RUNNING) + { + StartService(service, NULL, NULL); + } + + log("Service '%s' successfully upgraded.\nLog file is written to %s", + opt_service, logfile_path); + CloseServiceHandle(service); + CloseServiceHandle(scm); + if (logfile_handle) + CloseHandle(logfile_handle); + my_end(0); + exit(0); +}
\ No newline at end of file diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c4ec0b741f0..0d0ad919515 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -24,6 +24,7 @@ #include "rpl_mi.h" #include "sql_repl.h" #include "rpl_filter.h" +#include "client_settings.h" #include "repl_failsafe.h" #include <my_stacktrace.h> #include "mysqld_suffix.h" @@ -280,7 +281,7 @@ const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; static const char *sql_mode_names[]= { "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", - "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION", + "IGNORE_BAD_TABLE_OPTIONS", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION", "NO_DIR_IN_CREATE", "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI", @@ -300,7 +301,7 @@ static const unsigned int sql_mode_names_len[]= /*PIPES_AS_CONCAT*/ 15, /*ANSI_QUOTES*/ 11, /*IGNORE_SPACE*/ 12, - /*?*/ 1, + /*IGNORE_BAD_TABLE_OPTIONS*/ 24, /*ONLY_FULL_GROUP_BY*/ 18, /*NO_UNSIGNED_SUBTRACTION*/ 23, /*NO_DIR_IN_CREATE*/ 16, @@ -383,6 +384,16 @@ TYPELIB thread_handling_typelib= thread_handling_names, NULL }; +const char *plugin_maturity_names[]= +{ "unknown", "experimental", "alpha", "beta", "gamma", "stable", 0 }; + +TYPELIB plugin_maturity_values= +{ + array_elements(plugin_maturity_names) - 1, "", plugin_maturity_names, 0 +}; + +const int server_maturity= MariaDB_PLUGIN_MATURITY_UNKNOWN; + const char *first_keyword= "first", *binary_keyword= "BINARY"; const char *my_localhost= "localhost", *delayed_user= "DELAYED"; #if SIZEOF_OFF_T > 4 && defined(BIG_TABLES) @@ -424,6 +435,7 @@ static my_bool opt_ignore_wrong_options= 0, opt_expect_abort= 0; static my_bool opt_sync= 0; static uint kill_cached_threads, wake_thread; ulong thread_created; +uint thread_handling; static ulong max_used_connections; static ulong my_bind_addr; /**< the address we bind to */ static volatile ulong cached_thread_count= 0; @@ -437,6 +449,9 @@ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on," #else ; #endif +#ifdef SAFEMALLOC +my_bool sf_malloc_trough_check= 0; +#endif static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr; static char *opt_init_slave, *language_ptr, *opt_init_connect; static char *default_character_set_name; @@ -456,6 +471,7 @@ static pthread_cond_t COND_thread_cache, COND_flush_thread_cache; bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0; my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table; +my_bool opt_userstat_running; ulong log_output_options; my_bool opt_log_queries_not_using_indexes= 0; bool opt_error_log= IF_WIN(1,0); @@ -598,6 +614,7 @@ ulong extra_max_connections; ulong max_long_data_size; uint max_user_connections= 0; +ulonglong denied_connections; /** Limit of the total number of prepared statements in the server. Is necessary to protect the server against out-of-memory attacks. @@ -624,7 +641,7 @@ time_t server_start_time, flush_status_time; char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30]; char *default_tz_name; -char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN]; +char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN], *opt_log_basename; char mysql_real_data_home[FN_REFLEN], language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN], *opt_init_file, *opt_tc_log_file, @@ -700,6 +717,9 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, LOCK_global_system_variables, LOCK_user_conn, LOCK_slave_list, LOCK_active_mi, LOCK_connection_count, LOCK_short_uuid_generator; +pthread_mutex_t LOCK_stats, LOCK_global_user_client_stats; +pthread_mutex_t LOCK_global_table_stats, LOCK_global_index_stats; + /** The below lock protects access to two global server variables: max_prepared_stmt_count and prepared_stmt_count. These variables @@ -1064,7 +1084,7 @@ static void close_connections(void) tmp->thread_id, (tmp->main_security_ctx.user ? tmp->main_security_ctx.user : "")); - close_connection(tmp,0,0); + close_connection(tmp,ER_SERVER_SHUTDOWN,0); } #endif DBUG_PRINT("quit",("Unlocking LOCK_thread_count")); @@ -1402,11 +1422,13 @@ void clean_up(bool print_message) #ifdef HAVE_REPLICATION my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); #endif - x_free(opt_bin_logname); - x_free(opt_relay_logname); x_free(opt_secure_file_priv); bitmap_free(&temp_pool); free_max_user_conn(); + free_global_user_stats(); + free_global_client_stats(); + free_global_table_stats(); + free_global_index_stats(); #ifdef HAVE_REPLICATION end_slave_list(); #endif @@ -1432,6 +1454,7 @@ void clean_up(bool print_message) if (print_message && errmesg && server_start_time) sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname); thread_scheduler.end(); + mysql_library_end(); finish_client_errs(); my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST), MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); @@ -1499,21 +1522,26 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_bytes_received); (void) pthread_mutex_destroy(&LOCK_user_conn); (void) pthread_mutex_destroy(&LOCK_connection_count); + (void) pthread_mutex_destroy(&LOCK_stats); + (void) pthread_mutex_destroy(&LOCK_global_user_client_stats); + (void) pthread_mutex_destroy(&LOCK_global_table_stats); + (void) pthread_mutex_destroy(&LOCK_global_index_stats); + #ifndef EMBEDDED_LIBRARY Events::destroy_mutexes(); -#endif +#endif /* !EMBEDDED_LIBRARY */ #ifdef HAVE_OPENSSL (void) pthread_mutex_destroy(&LOCK_des_key_file); #ifndef HAVE_YASSL for (int i= 0; i < CRYPTO_num_locks(); ++i) (void) rwlock_destroy(&openssl_stdlocks[i].lock); OPENSSL_free(openssl_stdlocks); -#endif -#endif +#endif /* HAVE_YASSL */ +#endif /* HAVE_OPENSSL */ #ifdef HAVE_REPLICATION (void) pthread_mutex_destroy(&LOCK_rpl_status); (void) pthread_cond_destroy(&COND_rpl_status); -#endif +#endif /* HAVE_REPLICATION */ (void) pthread_mutex_destroy(&LOCK_server_started); (void) pthread_cond_destroy(&COND_server_started); (void) pthread_mutex_destroy(&LOCK_active_mi); @@ -1541,20 +1569,23 @@ static void clean_up_mutexes() mysys/thr_mutex.c, will give a warning on first wrong mutex usage! */ +#ifdef SAFE_MUTEX +#define always_in_that_order(A,B) \ + pthread_mutex_lock(A); pthread_mutex_lock(B); \ + pthread_mutex_unlock(B); pthread_mutex_unlock(A) +#else +#define always_in_that_order(A,B) +#endif + static void register_mutex_order() { -#ifdef SAFE_MUTEX /* We must have LOCK_open before LOCK_global_system_variables because LOCK_open is hold while sql_plugin.c::intern_sys_var_ptr() is called. */ - pthread_mutex_lock(&LOCK_open); - pthread_mutex_lock(&LOCK_global_system_variables); - - pthread_mutex_unlock(&LOCK_global_system_variables); - pthread_mutex_unlock(&LOCK_open); -#endif + always_in_that_order(&LOCK_open, &LOCK_global_system_variables); } +#undef always_in_that_order /**************************************************************************** @@ -1942,6 +1973,17 @@ void close_connection(THD *thd, uint errcode, bool lock) if (lock) (void) pthread_mutex_lock(&LOCK_thread_count); thd->killed= THD::KILL_CONNECTION; + + if (global_system_variables.log_warnings > 3) + { + Security_context *sctx= &thd->main_security_ctx; + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), + thd->thread_id,(thd->db ? thd->db : "unconnected"), + sctx->user ? sctx->user : "unauthenticated", + sctx->host_or_ip, + (errcode ? ER(errcode) : "CLOSE_CONNECTION")); + } + if ((vio= thd->net.vio) != 0) { if (errcode) @@ -2109,24 +2151,6 @@ void flush_thread_cache() } -#ifdef THREAD_SPECIFIC_SIGPIPE -/** - Aborts a thread nicely. Comes here on SIGPIPE. - - @todo - One should have to fix that thr_alarm know about this thread too. -*/ -extern "C" sig_handler abort_thread(int sig __attribute__((unused))) -{ - THD *thd=current_thd; - DBUG_ENTER("abort_thread"); - if (thd) - thd->killed= THD::KILL_CONNECTION; - DBUG_VOID_RETURN; -} -#endif - - /****************************************************************************** Setup a signal thread with handles all signals. Because Linux doesn't support schemas use a mutex to check that @@ -2661,6 +2685,12 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", case THD::KILL_QUERY: kreason= "KILL_QUERY"; break; + case THD::KILL_SYSTEM_THREAD: + kreason= "KILL_SYSTEM_THREAD"; + break; + case THD::KILL_SERVER: + kreason= "KILL_SERVER"; + break; case THD::KILLED_NO_VALUE: kreason= "KILLED_NO_VALUE"; break; @@ -3012,7 +3042,7 @@ int my_message_sql(uint error, const char *str, myf MyFlags) MYSQL_ERROR::enum_warning_level level; sql_print_message_func func; DBUG_ENTER("my_message_sql"); - DBUG_PRINT("error", ("error: %u message: '%s'", error, str)); + DBUG_PRINT("error", ("error: %u message: '%s' Flag: %d", error, str, MyFlags)); DBUG_ASSERT(str != NULL); /* @@ -3028,7 +3058,8 @@ int my_message_sql(uint error, const char *str, myf MyFlags) { /* At least, prevent new abuse ... */ DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0 || - strncmp(str, "MARIA table", 11) == 0); + strncmp(str, "Aria table", 11) == 0 || + (MyFlags & ME_JUST_INFO)); error= ER_UNKNOWN_ERROR; } @@ -3055,7 +3086,10 @@ int my_message_sql(uint error, const char *str, myf MyFlags) this could be improved by having a common stack of handlers. */ if (thd->handle_error(error, str, level)) + { + DBUG_PRINT("info", ("error handled by handle_error()")); DBUG_RETURN(0); + } if (level == MYSQL_ERROR::WARN_LEVEL_WARN) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, error, str); @@ -3134,7 +3168,7 @@ to_error_log: /* When simulating OOM, skip writing to error log to avoid mtr errors */ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0);); - if (!thd || (MyFlags & ME_NOREFRESH)) + if (!thd || thd->log_all_errors || (MyFlags & ME_NOREFRESH)) (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */ DBUG_RETURN(0); } @@ -3325,6 +3359,7 @@ SHOW_VAR com_status_vars[]= { {"show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS}, {"show_binlogs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS}, {"show_charsets", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS}, + {"show_client_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CLIENT_STATS]), SHOW_LONG_STATUS}, {"show_collations", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS}, {"show_column_types", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS}, {"show_contributors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS}, @@ -3347,6 +3382,7 @@ SHOW_VAR com_status_vars[]= { {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS}, {"show_grants", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS}, {"show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS}, + {"show_index_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_INDEX_STATS]), SHOW_LONG_STATUS}, {"show_master_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS}, {"show_new_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS}, {"show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS}, @@ -3363,9 +3399,11 @@ SHOW_VAR com_status_vars[]= { {"show_slave_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS}, {"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS}, {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS}, + {"show_table_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS}, {"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS}, {"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS}, {"show_triggers", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS}, + {"show_user_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS}, {"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS}, {"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS}, {"slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS}, @@ -3395,6 +3433,7 @@ static int init_common_variables(const char *conf_file_name, int argc, char **argv, const char **groups) { char buff[FN_REFLEN], *s; + const char *basename; umask(((~my_umask) & 0666)); my_decimal_set_zero(&decimal_zero); // set decimal_zero constant; tzset(); // Set tzname @@ -3448,13 +3487,20 @@ static int init_common_variables(const char *conf_file_name, int argc, if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0) { + /* + Get hostname of computer (used by 'show variables') and as default + basename for the pid file if --log-basename is not given. + */ strmake(glob_hostname, STRING_WITH_LEN("localhost")); sql_print_warning("gethostname failed, using '%s' as hostname", - glob_hostname); - strmake(pidfile_name, STRING_WITH_LEN("mysql")); + glob_hostname); + basename= "mysql"; } else - strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5); + { + basename= glob_hostname; + } + strmake(pidfile_name, basename, sizeof(pidfile_name)-5); strmov(fn_ext(pidfile_name),".pid"); // Add proper extension /* @@ -3570,6 +3616,7 @@ static int init_common_variables(const char *conf_file_name, int argc, if (init_errmessage()) /* Read error messages from file */ return 1; init_client_errs(); + mysql_library_init(never,never,never); /* for replication */ lex_init(); if (item_create_init()) return 1; @@ -3782,6 +3829,12 @@ static int init_thread_environment() (void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_short_uuid_generator, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST); + (void) pthread_mutex_init(&LOCK_stats, MY_MUTEX_INIT_FAST); + (void) pthread_mutex_init(&LOCK_global_user_client_stats, + MY_MUTEX_INIT_FAST); + (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST); + (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST); + #ifdef HAVE_OPENSSL (void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST); #ifndef HAVE_YASSL @@ -3948,6 +4001,32 @@ static void end_ssl() #endif /* EMBEDDED_LIBRARY */ +#ifdef _WIN32 +/** + Registers a file to be collected when Windows Error Reporting creates a crash + report. + + @note only works on Vista and later, since WerRegisterFile() is not available + on earlier Windows. +*/ +#include <werapi.h> +static void add_file_to_crash_report(char *file) +{ + /* Load WerRegisterFile function dynamically.*/ + HRESULT (WINAPI *pWerRegisterFile)(PCWSTR, WER_REGISTER_FILE_TYPE, DWORD) + =(HRESULT (WINAPI *) (PCWSTR, WER_REGISTER_FILE_TYPE, DWORD)) + GetProcAddress(GetModuleHandle("kernel32"),"WerRegisterFile"); + + if (pWerRegisterFile) + { + wchar_t wfile[MAX_PATH+1]= {0}; + if (mbstowcs(wfile, file, MAX_PATH) != (size_t)-1) + { + pWerRegisterFile(wfile, WerRegFileTypeOther, WER_FILE_ANONYMOUS_DATA); + } + } +} +#endif static int init_server_components() { @@ -4000,6 +4079,11 @@ static int init_server_components() if (!res) setbuf(stderr, NULL); + +#ifdef _WIN32 + /* Add error log to windows crash reporting. */ + add_file_to_crash_report(log_error_file); +#endif } } @@ -4056,7 +4140,7 @@ version 5.0 and above. It is replaced by the binary log."); if (opt_update_logname) { /* as opt_bin_log==0, no need to free opt_bin_logname */ - if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME)))) + if (!(opt_bin_logname= my_once_strdup(opt_update_logname, MYF(MY_WME)))) { sql_print_error("Out of memory"); return EXIT_OUT_OF_MEMORY; @@ -4156,8 +4240,7 @@ a file name for --log-bin-index option", opt_binlog_index_name); } if (ln == buf) { - my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR)); - opt_bin_logname=my_strdup(buf, MYF(0)); + opt_bin_logname= my_once_strdup(buf, MYF(MY_WME)); } if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE)) { @@ -4168,6 +4251,9 @@ a file name for --log-bin-index option", opt_binlog_index_name); /* call ha_init_key_cache() on all key caches to init them */ process_key_caches(&ha_init_key_cache); + init_global_table_stats(); + init_global_index_stats(); + /* Allow storage engine to give real error messages */ if (ha_init_errors()) DBUG_RETURN(1); @@ -4301,10 +4387,10 @@ a file name for --log-bin-index option", opt_binlog_index_name); pthread_mutex_unlock(&LOCK_global_system_variables); } } -#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES) +#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES) if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap) { - sql_print_error("Maria engine is not enabled or did not start. The Maria engine must be enabled to continue as mysqld was configured with --with-maria-tmp-tables"); + sql_print_error("Aria engine is not enabled or did not start. The Aria engine must be enabled to continue as mysqld was configured with --with-aria-tmp-tables"); unireg_abort(1); } #endif @@ -4370,6 +4456,8 @@ a file name for --log-bin-index option", opt_binlog_index_name); init_max_user_conn(); init_update_queries(); + init_global_user_stats(); + init_global_client_stats(); DBUG_RETURN(0); } @@ -5138,7 +5226,7 @@ void create_thread_to_handle_connection(THD *thd) ER(ER_CANT_CREATE_THREAD), error); net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff); (void) pthread_mutex_lock(&LOCK_thread_count); - close_connection(thd,0,0); + close_connection(thd,ER_OUT_OF_RESOURCES,0); delete thd; (void) pthread_mutex_unlock(&LOCK_thread_count); return; @@ -5185,6 +5273,7 @@ static void create_new_thread(THD *thd) DBUG_PRINT("error",("Too many connections")); close_connection(thd, ER_CON_COUNT_ERROR, 1); + statistic_increment(denied_connections, &LOCK_status); delete thd; DBUG_VOID_RETURN; } @@ -5818,7 +5907,7 @@ error: enum options_mysqld { - OPT_ISAM_LOG=256, OPT_SKIP_NEW, + OPT_ISAM_LOG=256, OPT_SKIP_GRANT, OPT_SKIP_LOCK, OPT_ENABLE_LOCK, OPT_USE_LOCKING, OPT_SOCKET, OPT_UPDATE_LOG, @@ -5872,7 +5961,7 @@ enum options_mysqld OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP, OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE, OPT_NDB_USE_COPYING_ALTER_TABLE, - OPT_SKIP_SAFEMALLOC, OPT_MUTEX_DEADLOCK_DETECTOR, + OPT_SAFEMALLOC, OPT_MUTEX_DEADLOCK_DETECTOR, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE, OPT_SKIP_SYMLINKS, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, @@ -5895,6 +5984,7 @@ enum options_mysqld OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE, OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE, OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD, + OPT_KEY_CACHE_PARTITIONS, OPT_LONG_QUERY_TIME, OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET, OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE, @@ -5973,6 +6063,7 @@ enum options_mysqld OPT_TABLE_LOCK_WAIT_TIMEOUT, OPT_PLUGIN_LOAD, OPT_PLUGIN_DIR, + OPT_PLUGIN_MATURITY, OPT_SYMBOLIC_LINKS, OPT_WARNINGS, OPT_RECORD_BUFFER_OLD, @@ -5981,13 +6072,15 @@ enum options_mysqld OPT_PROFILING, OPT_KEEP_FILES_ON_CREATE, OPT_GENERAL_LOG, - OPT_SLOW_LOG, + OPT_SLOW_LOG, OPT_LOG_BASENAME, OPT_THREAD_HANDLING, OPT_INNODB_ROLLBACK_ON_TIMEOUT, OPT_SECURE_FILE_PRIV, OPT_MIN_EXAMINED_ROW_LIMIT, OPT_LOG_SLOW_SLAVE_STATEMENTS, - OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_DEBUG_ASSERT_IF_CRASHED_TABLE, OPT_OLD_MODE, + OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_DEBUG_ASSERT_IF_CRASHED_TABLE, + OPT_DEBUG_ASSERT_ON_ERROR, + OPT_OLD_MODE, OPT_TEST_IGNORE_WRONG_OPTIONS, OPT_TEST_RESTART, #if defined(ENABLED_DEBUG_SYNC) OPT_DEBUG_SYNC_TIMEOUT, @@ -6001,6 +6094,7 @@ enum options_mysqld OPT_LOG_SLOW_RATE_LIMIT, OPT_LOG_SLOW_VERBOSITY, OPT_LOG_SLOW_FILTER, + OPT_USERSTAT, OPT_GENERAL_LOG_FILE, OPT_SLOW_QUERY_LOG_FILE, OPT_IGNORE_BUILTIN_INNODB, @@ -6161,6 +6255,10 @@ struct my_option my_long_options[] = "Do an assert in handler::print_error() if we get a crashed table", &debug_assert_if_crashed_table, &debug_assert_if_crashed_table, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-assert-on-error", OPT_DEBUG_ASSERT_ON_ERROR, + "Do an assert in various functions if we get a fatal error", + &my_assert_on_error, &my_assert_on_error, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD, "Set the default character set (deprecated option, use --character-set-server instead).", @@ -6248,8 +6346,8 @@ struct my_option my_long_options[] = &opt_debugging, &opt_debugging, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"general_log", OPT_GENERAL_LOG, - "Enable/disable general log.", &opt_log, - &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, + "Enable/disable general log. Filename can be specified with --general-log-file or --log-basename. Is 'hostname.log' by default.", + &opt_log, &opt_log, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_LARGE_PAGES {"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. " "Disable with --skip-large-pages.", &opt_large_pages, &opt_large_pages, @@ -6289,16 +6387,32 @@ each time the SQL thread starts.", "--general_log/--general_log_file instead).", &opt_logname, &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"general_log_file", OPT_GENERAL_LOG_FILE, - "Log connections and queries to given file.", &opt_logname, - &opt_logname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Log connections and queries to given file. Defaults to " + "'datadir'/'log-basename'.log or 'datadir'/'hostname'.log if not " + "specified.", + &opt_logname, &opt_logname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"log-basename", OPT_LOG_BASENAME, + "Basename for all log files and the .pid file. This sets all log file " + "names at once (in 'datadir') and is normally the only option you need " + "for specifying log files. This is especially recommend to be set if you " + "are using replication as it ensures that your log file names are not " + "depending on your host name. Sets names for --log-bin, --log-bin-index, " + "--relay-log, --relay-log-index, --general-log-file, " + "--log-slow-query-log-file, --log-error-file and --pid-file", + &opt_log_basename, &opt_log_basename, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, {"log-bin", OPT_BIN_LOG, - "Log update queries in binary format. Optional (but strongly recommended " - "to avoid replication problems if server's hostname changes) argument " - "should be the chosen location for the binary log files.", - &opt_bin_logname, &opt_bin_logname, 0, GET_STR_ALLOC, + "Log update queries in binary format. Optional argument should be name for " + "binary log. If not given " + "datadir/'log-basename'-bin or 'datadir'/mysql-bin will be used (the later if " + "--log-basename is not specified). We strongly recommend you to use either " + "--log-basename or specify a filename to ensure that replication doesn't " + "stop if the real hostname of the computer changes'.", + &opt_bin_logname, &opt_bin_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-bin-index", OPT_BIN_LOG_INDEX, - "File that holds the names for last binary log files.", + "File that holds the names for last binary log files. If not specified, " + "defaults to 'datadir/log-basename'-bin.index or 'datadir/mysql-bin.index'", &opt_binlog_index_name, &opt_binlog_index_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifndef TO_BE_REMOVED_IN_5_1_OR_6_0 @@ -6327,7 +6441,10 @@ each time the SQL thread starts.", "break, so you can safely set this to 1." ,&trust_function_creators, &trust_function_creators, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"log-error", OPT_ERROR_LOG_FILE, "Error log file.", + {"log-error", OPT_ERROR_LOG_FILE, + "Log errors to file (instead of stdout). If file name is not specified " + "then 'datadir'/'log-basename'.err or the pid-file path with extension " + ".err is used.", &log_error_file_ptr, &log_error_file_ptr, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.", @@ -6365,15 +6482,20 @@ each time the SQL thread starts.", &opt_log_slow_slave_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"log-slow-queries", OPT_SLOW_QUERY_LOG, - "Log slow queries to a table or log file. Defaults logging to table " - "mysql.slow_log or hostname-slow.log if --log-output=file is used. " - "Must be enabled to activate other slow log options. " - "(deprecated option, use --slow_query_log/--slow_query_log_file instead)", + "Enable logging of slow queries (longer than --log-slow-time) to log file " + "or table. Optional argument is file name for slow log. If not given, " + "'log-basename'-slow.log will be used. Use --log-output=TABLE if you want " + "to have the log in the table 'mysql.slow_log'", &opt_slow_logname, &opt_slow_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"slow_query_log_file", OPT_SLOW_QUERY_LOG_FILE, - "Log slow queries to given log file. Defaults logging to hostname-slow.log. " - "Must be enabled to activate other slow log options.", + "Specify name for slow query log. Defaults to 'log-basename'-slow.log if " + "not given", + &opt_slow_logname, &opt_slow_logname, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"log-slow-file", OPT_SLOW_QUERY_LOG_FILE, + "Specify name for slow query log. Defaults to 'log-basename'-slow.log if " + "not given", &opt_slow_logname, &opt_slow_logname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"log-tc", OPT_LOG_TC, @@ -6392,7 +6514,7 @@ each time the SQL thread starts.", "log and this option just turns on --log-bin instead.", &opt_update_logname, &opt_update_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"log-warnings", 'W', "Log some not critical warnings to the log file.", + {"log-warnings", 'W', "Log some not critical warnings to the general log file. Value can be between 0-11; The higher value, the more warnings", &global_system_variables.log_warnings, &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, 0, 0, 0}, @@ -6415,7 +6537,8 @@ each time the SQL thread starts.", 0, 0, 0, 0}, {"master-info-file", OPT_MASTER_INFO_FILE, "The location and name of the file that remembers the master and where " - "the I/O replication thread is in the master's binlogs.", + "the I/O replication thread is in the master's binlogs. Defaults to " + "master.info. Is not affected by --log-basename.", &master_info_file, &master_info_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"master-password", OPT_MASTER_PASSWORD, @@ -6617,7 +6740,9 @@ each time the SQL thread starts.", "per each user+host vs. per account).", &opt_old_style_user_limits, &opt_old_style_user_limits, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld.", + {"pid-file", OPT_PID_FILE, + "Pid file used by safe_mysqld. If not set, defaults to " + "'datadir'/'log-basename'.pid or 'datadir'/'hostname'.pid'.", &pidfile_name_ptr, &pidfile_name_ptr, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection or 0 for default to, in " @@ -6639,17 +6764,19 @@ each time the SQL thread starts.", 0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0}, #endif {"relay-log", OPT_RELAY_LOG, - "The location and name to use for relay logs.", + "The location and name to use for relay logs. If not specified " + "'datadir'/'log-basename' will be used.", &opt_relay_logname, &opt_relay_logname, 0, - GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"relay-log-index", OPT_RELAY_LOG_INDEX, - "The location and name to use for the file that keeps a list of the last \ -relay logs.", + "The location and name to use for the file that keeps a list of the last " + "relay logs. If not specified 'datadir'/'log-basename' will be used.", &opt_relaylog_index_name, &opt_relaylog_index_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE, - "The location and name of the file that remembers where the SQL replication \ -thread is in the relay logs.", + "The location and name of the file that remembers where the SQL " + "replication thread is in the relay logs. Defaults to relay-log.info. " + "Is not affected by '--log-basename'.", &relay_log_info_file, &relay_log_info_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"replicate-do-db", OPT_REPLICATE_DO_DB, @@ -6765,8 +6892,6 @@ thread is in the relay logs.", {"shared-memory", OPT_ENABLE_SHARED_MEMORY, "Enable the shared memory.",&opt_enable_shared_memory, &opt_enable_shared_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#endif -#ifdef HAVE_SMEM {"shared-memory-base-name",OPT_SHARED_MEMORY_BASE_NAME, "Base name of shared memory.", &shared_memory_base_name, &shared_memory_base_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -6795,14 +6920,11 @@ thread is in the relay logs.", {"skip-networking", OPT_SKIP_NETWORKING, "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"skip-new", OPT_SKIP_NEW, "Don't use new, possibly wrong routines.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifndef DBUG_OFF #ifdef SAFEMALLOC - {"skip-safemalloc", OPT_SKIP_SAFEMALLOC, - "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG, - 0, 0, 0, 0, 0, 0}, -#endif + {"safemalloc", OPT_SAFEMALLOC, + "Check all memory allocation for every malloc/free call.", + &sf_malloc_trough_check, &sf_malloc_trough_check, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, #endif {"skip-show-database", OPT_SKIP_SHOW_DB, "Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, @@ -6833,7 +6955,8 @@ thread is in the relay logs.", &slave_exec_mode_str, &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif {"slow-query-log", OPT_SLOW_LOG, - "Enable/disable slow query log.", &opt_slow_log, + "Enable/disable slow query log. See also '--log-slow-queries'", + &opt_slow_log, &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"socket", OPT_SOCKET, "Socket file to use for connection.", &mysqld_unix_port, &mysqld_unix_port, 0, GET_STR, @@ -7070,6 +7193,11 @@ thread is in the relay logs.", "The minimum percentage of warm blocks in key cache.", &dflt_key_cache_var.param_division_limit, 0, 0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0}, + {"key_cache_segments", OPT_KEY_CACHE_PARTITIONS, + "The number of segments in a key cache", + &dflt_key_cache_var.param_partitions, 0, + 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, DEFAULT_KEY_CACHE_PARTITIONS, + 0, MAX_KEY_CACHE_PARTITIONS, 0, 1, 0}, {"log-slow-filter", OPT_LOG_SLOW_FILTER, "Log only the queries that followed certain execution plan. Multiple flags " "allowed in a comma-separated string. [admin, filesort, filesort_on_disk, " @@ -7086,19 +7214,16 @@ thread is in the relay logs.", "Choose how verbose the messages to your slow log will be. Multiple flags " "allowed in a comma-separated string. [query_plan, innodb]", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - {"log-slow-file", OPT_SLOW_QUERY_LOG_FILE, - "Log slow queries to given log file. Defaults logging to hostname-slow.log", - &opt_slow_logname, &opt_slow_logname, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"long_query_time", OPT_LONG_QUERY_TIME, - "Log all queries that have taken more than long_query_time seconds to " - "execute. The argument will be treated as a decimal value with " - "microsecond precision.", + {"log-slow-time", OPT_LONG_QUERY_TIME, + "Log all queries that have taken more than log-slow-time seconds to " + "execute to file. The argument will be treated as a decimal value with " + "microsecond precission. Same as --log-query-time.", &long_query_time, &long_query_time, 0, GET_DOUBLE, REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0}, - {"log-slow-time", OPT_LONG_QUERY_TIME, - "Log all queries that have taken more than long_query_time seconds to execute to file. " - "The argument will be treated as a decimal value with microsecond precission.", + {"long_query_time", OPT_LONG_QUERY_TIME, + "Log all queries that have taken more than long-query-time seconds to " + "execute to file. The argument will be treated as a decimal value with " + "microsecond precission. Same as --log-slow-time.", &long_query_time, &long_query_time, 0, GET_DOUBLE, REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0}, {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES, @@ -7341,6 +7466,10 @@ thread is in the relay logs.", "is the plugin library in plugin_dir.", &opt_plugin_load, &opt_plugin_load, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"plugin-maturity", OPT_PLUGIN_MATURITY, + "The lowest desirable plugin maturity. Plugins less mature than that will not be installed or loaded.", + (uchar**) &plugin_maturity, (uchar**) &plugin_maturity, &plugin_maturity_values, + GET_ENUM, REQUIRED_ARG, server_maturity, 0, 0, 0, 0, 0}, {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE, "The size of the buffer that is allocated when preloading indexes.", &global_system_variables.preload_buff_size, @@ -7514,7 +7643,7 @@ thread is in the relay logs.", 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"tmp_table_size", OPT_TMP_TABLE_SIZE, "If an internal in-memory temporary table exceeds this size, MySQL will " - "automatically convert it to an on-disk MyISAM/Maria table.", + "automatically convert it to an on-disk MyISAM/Aria table.", &global_system_variables.tmp_table_size, &max_system_variables.tmp_table_size, 0, GET_ULL, REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0}, @@ -7554,6 +7683,10 @@ thread is in the relay logs.", &max_system_variables.net_wait_timeout, 0, GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT), 0, 1, 0}, + {"userstat", OPT_USERSTAT, + "Control USER_STATISTICS, CLIENT_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS running", + (uchar**) &opt_userstat_running, (uchar**) &opt_userstat_running, + 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0}, {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE, "Causes updates to non-transactional engines using statement format to be " "written directly to binary log. Before using this option, make sure that " @@ -7926,6 +8059,46 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff) #endif /* HAVE_OPENSSL */ +static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff) +{ + struct st_data { + KEY_CACHE_STATISTICS stats; + SHOW_VAR var[8]; + } *data; + SHOW_VAR *v; + + data=(st_data *)buff; + v= data->var; + + var->type= SHOW_ARRAY; + var->value= (char*)v; + + get_key_cache_statistics(dflt_key_cache, 0, &data->stats); + +#define set_one_keycache_var(X,Y) \ + v->name= X; \ + v->type= SHOW_LONGLONG; \ + v->value= (char*)&data->stats.Y; \ + v++; + + set_one_keycache_var("blocks_not_flushed", blocks_changed); + set_one_keycache_var("blocks_unused", blocks_unused); + set_one_keycache_var("blocks_used", blocks_used); + set_one_keycache_var("blocks_warm", blocks_warm); + set_one_keycache_var("read_requests", read_requests); + set_one_keycache_var("reads", reads); + set_one_keycache_var("write_requests", write_requests); + set_one_keycache_var("writes", writes); + + v->name= 0; + + DBUG_ASSERT((char*)(v+1) <= buff + SHOW_VAR_FUNC_BUFF_SIZE); + +#undef set_one_keycache_var + + return 0; +} + /* Variables shown by SHOW STATUS in alphabetical order @@ -7934,19 +8107,24 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff) SHOW_VAR status_vars[]= { {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, + {"Access_denied_errors", (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS}, {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG}, {"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG}, + {"Busy_time", (char*) offsetof(STATUS_VAR, busy_time), SHOW_DOUBLE_STATUS}, {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS}, {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS}, + {"Binlog_bytes_written", (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS}, {"Com", (char*) com_status_vars, SHOW_ARRAY}, {"Compression", (char*) &show_net_compression, SHOW_FUNC}, {"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH}, + {"Cpu_time", (char*) offsetof(STATUS_VAR, cpu_time), SHOW_DOUBLE_STATUS}, {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS}, {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG}, {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS}, {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG}, {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH}, {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG}, + {"Empty_queries", (char*) offsetof(STATUS_VAR, empty_queries), SHOW_LONG_STATUS}, {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH}, {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, @@ -7963,14 +8141,7 @@ SHOW_VAR status_vars[]= { {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS}, {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, - {"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG}, - {"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG}, - {"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG}, - {"Key_blocks_warm", (char*) offsetof(KEY_CACHE, warm_blocks), SHOW_KEY_CACHE_LONG}, - {"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG}, - {"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG}, - {"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG}, - {"Key_writes", (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG}, + {"Key", (char*) &show_default_keycache, SHOW_FUNC}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH}, @@ -7982,6 +8153,8 @@ SHOW_VAR status_vars[]= { {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS}, {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC}, + {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS}, + {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS}, #ifdef HAVE_QUERY_CACHE {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH}, {"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH}, @@ -8160,6 +8333,7 @@ static int mysql_init_variables(void) opt_skip_name_resolve= 0; opt_ignore_builtin_innodb= 0; opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0; + opt_log_basename= 0; opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name ! opt_secure_auth= 0; opt_secure_file_priv= 0; @@ -8568,8 +8742,44 @@ mysqld_get_one_option(int optid, case (int) OPT_BIN_LOG: opt_bin_log= test(argument != disabled_my_option); break; + case (int) OPT_LOG_BASENAME: + { + if (opt_log_basename[0] == 0 || strchr(opt_log_basename, FN_EXTCHAR) || + strchr(opt_log_basename,FN_LIBCHAR)) + { + sql_print_error("Wrong argument for --log-basename. It can't be empty or contain '.' or '" FN_DIRSEP "'"); + return 1; + } + log_error_file_ptr= argument; + + /* + The following file named needs explicite extensions (should be fixed in + future by having the creating code do this). + */ + opt_logname= make_once_alloced_filename(argument, ".log"); + opt_slow_logname= make_once_alloced_filename(argument, "-slow.log"); + opt_bin_logname= make_once_alloced_filename(argument, "-bin"); + opt_binlog_index_name= make_once_alloced_filename(argument, "-bin.index"); + opt_relay_logname= make_once_alloced_filename(argument, "-relay-bin"); + opt_relaylog_index_name=make_once_alloced_filename(argument, + "-relay-bin.index"); + + pidfile_name_ptr= pidfile_name; + strmake(pidfile_name, argument, sizeof(pidfile_name)-5); + strmov(fn_ext(pidfile_name),".pid"); + + /* The following is depricated so don't set it by default */ + if (opt_update_logname) + opt_update_logname= argument; + + /* check for errors */ + if (!opt_bin_logname || !opt_relaylog_index_name || ! opt_logname || + ! opt_slow_logname) + return 1; // out of memory error + break; + } case (int) OPT_ERROR_LOG_FILE: - opt_error_log= 1; + opt_error_log= (argument != disabled_my_option); break; #ifdef HAVE_REPLICATION case (int) OPT_INIT_RPL_ROLE: @@ -8595,6 +8805,7 @@ mysqld_get_one_option(int optid, } case (int)OPT_REPLICATE_REWRITE_DB: { + /* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */ char* key = argument,*p, *val; if (!(p= strstr(argument, "->"))) @@ -8683,7 +8894,6 @@ mysqld_get_one_option(int optid, } #endif /* HAVE_REPLICATION */ case (int) OPT_SLOW_QUERY_LOG: - WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--log-slow-file'"); opt_slow_log= 1; break; case OPT_LOG_OUTPUT: @@ -8705,29 +8915,20 @@ mysqld_get_one_option(int optid, } case OPT_EVENT_SCHEDULER: #ifndef HAVE_EVENT_SCHEDULER - sql_perror("Event scheduler is not supported in embedded build."); + sql_print_error("Event scheduler is not supported in embedded build."); #else if (Events::set_opt_event_scheduler(argument)) return 1; #endif break; - case (int) OPT_SKIP_NEW: - opt_specialflag|= SPECIAL_NO_NEW_FUNC; - delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE; - myisam_concurrent_insert=0; - myisam_recover_options= HA_RECOVER_NONE; - sp_automatic_privileges=0; - my_use_symdir=0; - ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE); -#ifdef HAVE_QUERY_CACHE - query_cache_size=0; -#endif - break; case (int) OPT_SAFE: - opt_specialflag|= SPECIAL_SAFE_MODE; + opt_specialflag|= SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC; delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE; myisam_recover_options= HA_RECOVER_DEFAULT; ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE); +#ifdef HAVE_QUERY_CACHE + query_cache_size=0; +#endif break; case (int) OPT_SKIP_PRIOR: opt_specialflag|= SPECIAL_NO_PRIOR; @@ -9038,16 +9239,16 @@ mysqld_get_one_option(int optid, break; } case OPT_ONE_THREAD: - global_system_variables.thread_handling= SCHEDULER_NO_THREADS; - opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling]; + thread_handling= SCHEDULER_NO_THREADS; + opt_thread_handling= thread_handling_typelib.type_names[thread_handling]; break; case OPT_THREAD_HANDLING: { int id; LINT_INIT(id); if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id)) - global_system_variables.thread_handling= id - 1; - opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling]; + thread_handling= id - 1; + opt_thread_handling= thread_handling_typelib.type_names[thread_handling]; break; } case OPT_FT_BOOLEAN_SYNTAX: @@ -9058,11 +9259,6 @@ mysqld_get_one_option(int optid, } strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1); break; - case OPT_SKIP_SAFEMALLOC: -#ifdef SAFEMALLOC - sf_malloc_quick=1; -#endif - break; case OPT_LOWER_CASE_TABLE_NAMES: lower_case_table_names= argument ? atoi(argument) : 1; lower_case_table_names_used= 1; @@ -9112,6 +9308,7 @@ mysql_getopt_value(const char *keyname, uint key_length, case OPT_KEY_CACHE_BLOCK_SIZE: case OPT_KEY_CACHE_DIVISION_LIMIT: case OPT_KEY_CACHE_AGE_THRESHOLD: + case OPT_KEY_CACHE_PARTITIONS: { KEY_CACHE *key_cache; if (!(key_cache= get_or_create_key_cache(keyname, key_length))) @@ -9129,6 +9326,8 @@ mysql_getopt_value(const char *keyname, uint key_length, return &key_cache->param_division_limit; case OPT_KEY_CACHE_AGE_THRESHOLD: return &key_cache->param_age_threshold; + case OPT_KEY_CACHE_PARTITIONS: + return (uchar**) &key_cache->param_partitions; } } } @@ -9217,7 +9416,7 @@ static int get_options(int *argc,char **argv) if (mysqld_chroot) set_root(mysqld_chroot); #else - global_system_variables.thread_handling = SCHEDULER_NO_THREADS; + thread_handling = SCHEDULER_NO_THREADS; max_allowed_packet= global_system_variables.max_allowed_packet; net_buffer_length= global_system_variables.net_buffer_length; #endif @@ -9238,6 +9437,19 @@ static int get_options(int *argc,char **argv) myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size); my_crc_dbug_check= opt_my_crc_dbug_check; + /* + Log mysys errors when we don't have a thd or thd->log_all_errors is set + (recovery) to the log. This is mainly useful for debugging strange system + errors. + */ + if (global_system_variables.log_warnings >= 10) + my_global_flags= MY_WME | ME_JUST_INFO; + /* Log all errors not handled by thd->handle_error() to my_message_sql() */ + if (global_system_variables.log_warnings >= 11) + my_global_flags|= ME_NOREFRESH; + if (my_assert_on_error) + debug_assert_if_crashed_table= 1; + /* long_query_time is in microseconds */ global_system_variables.long_query_time= max_system_variables.long_query_time= (longlong) (long_query_time * 1000000.0); @@ -9253,15 +9465,17 @@ static int get_options(int *argc,char **argv) &global_system_variables.datetime_format)) return 1; +#ifdef SAFEMALLOC + sf_malloc_quick= !sf_malloc_trough_check; +#endif #ifdef EMBEDDED_LIBRARY one_thread_scheduler(&thread_scheduler); one_thread_scheduler(&extra_thread_scheduler); #else - if (global_system_variables.thread_handling <= - SCHEDULER_ONE_THREAD_PER_CONNECTION) + if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION) one_thread_per_connection_scheduler(&thread_scheduler, &max_connections, &connection_count); - else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS) + else if (thread_handling == SCHEDULER_NO_THREADS) one_thread_scheduler(&thread_scheduler); else pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */ @@ -9649,6 +9863,8 @@ void refresh_status(THD *thd) /* Reset thread's status variables */ bzero((uchar*) &thd->status_var, sizeof(thd->status_var)); + bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var)); + thd->start_bytes_received= 0; /* Reset some global variables */ reset_status_vars(); diff --git a/sql/net_serv.cc b/sql/net_serv.cc index eb5f45bbced..272b1759151 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -116,7 +116,7 @@ my_bool my_net_init(NET *net, Vio* vio) net->vio = vio; my_net_local_init(net); /* Set some limits */ if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+ - NET_HEADER_SIZE + COMP_HEADER_SIZE, + NET_HEADER_SIZE + COMP_HEADER_SIZE +1, MYF(MY_WME)))) DBUG_RETURN(1); net->buff_end=net->buff+net->max_packet; @@ -580,7 +580,7 @@ net_real_write(NET *net,const uchar *packet, size_t len) uchar *b; uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE; if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE + - COMP_HEADER_SIZE, MYF(MY_WME)))) + COMP_HEADER_SIZE + 1, MYF(MY_WME)))) { net->error= 2; net->last_errno= ER_OUT_OF_RESOURCES; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index a42a03f4c86..3821665fb22 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -708,8 +708,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, static TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, double read_time); -static -TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree); +static TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree); #ifndef DBUG_OFF static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map, @@ -1437,7 +1436,7 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler) quick->record= head->record[0]; } - if (need_to_fetch_row && head->file->ha_rnd_init(1)) + if (need_to_fetch_row && head->file->ha_rnd_init_with_error(1)) { DBUG_PRINT("error", ("ROR index_merge rnd_init call failed")); DBUG_RETURN(1); @@ -1615,7 +1614,7 @@ int QUICK_ROR_UNION_SELECT::reset() queue_insert(&queue, (uchar*)quick); } - if (head->file->ha_rnd_init(1)) + if (head->file->ha_rnd_init_with_error(1)) { DBUG_PRINT("error", ("ROR index_merge rnd_init call failed")); DBUG_RETURN(1); @@ -7607,8 +7606,8 @@ check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree, param->range_count++; if (!tmp_min_flag && ! tmp_max_flag && (uint) key_tree->part+1 == param->table->key_info[keynr].key_parts && - (param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) == - HA_NOSAME && min_key_length == max_key_length && + (param->table->key_info[keynr].flags & HA_NOSAME) && + min_key_length == max_key_length && !memcmp(param->min_key, param->max_key, min_key_length) && !param->first_null_comp) { @@ -7897,7 +7896,7 @@ get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key, { KEY *table_key=quick->head->key_info+quick->index; flag=EQ_RANGE; - if ((table_key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME && + if ((table_key->flags & HA_NOSAME) && key->part == table_key->key_parts-1) { if (!(table_key->flags & HA_NULL_PART_KEY) || @@ -7947,7 +7946,7 @@ bool QUICK_RANGE_SELECT::unique_key_range() if ((tmp->flag & (EQ_RANGE | NULL_RANGE)) == EQ_RANGE) { KEY *key=head->key_info+index; - return ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME && + return ((key->flags & HA_NOSAME) && key->key_length == tmp->min_length); } } @@ -8066,8 +8065,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, range->min_length= range->max_length= ref->key_length; range->min_keypart_map= range->max_keypart_map= make_prev_keypart_map(ref->key_parts); - range->flag= ((ref->key_length == key_info->key_length && - (key_info->flags & HA_END_SPACE_KEY) == 0) ? EQ_RANGE : 0); + range->flag= (ref->key_length == key_info->key_length ? EQ_RANGE : 0); if (!(quick->key_parts=key_part=(KEY_PART *) alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts))) @@ -8224,7 +8222,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() index_merge currently doesn't support "using index" at all */ head->disable_keyread(); - init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE); + if (init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE)) + result= 1; DBUG_RETURN(result); err: @@ -8370,7 +8369,7 @@ int QUICK_ROR_INTERSECT_SELECT::get_next() /* We get here if we got the same row ref in all scans. */ if (need_to_fetch_row) - error= head->file->rnd_pos(head->record[0], last_rowid); + error= head->file->ha_rnd_pos(head->record[0], last_rowid); } while (error == HA_ERR_RECORD_DELETED); if (!need_to_fetch_row) @@ -8451,7 +8450,7 @@ int QUICK_ROR_UNION_SELECT::get_next() cur_rowid= prev_rowid; prev_rowid= tmp; - error= head->file->rnd_pos(quick->record, prev_rowid); + error= head->file->ha_rnd_pos(quick->record, prev_rowid); } while (error == HA_ERR_RECORD_DELETED); DBUG_RETURN(error); } @@ -8660,10 +8659,12 @@ int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length, int result; if (last_range) { - /* Read the next record in the same range with prefix after cur_prefix. */ + /* + Read the next record in the same range with prefix after cur_prefix. + */ DBUG_ASSERT(cur_prefix != NULL); - result= file->index_read_map(record, cur_prefix, keypart_map, - HA_READ_AFTER_KEY); + result= file->ha_index_read_map(record, cur_prefix, keypart_map, + HA_READ_AFTER_KEY); if (result || last_range->max_keypart_map == 0) DBUG_RETURN(result); @@ -8712,8 +8713,8 @@ int QUICK_RANGE_SELECT_GEOM::get_next() if (last_range) { // Already read through key - result= file->index_next_same(record, last_range->min_key, - last_range->min_length); + result= file->ha_index_next_same(record, last_range->min_key, + last_range->min_length); if (result != HA_ERR_END_OF_FILE) DBUG_RETURN(result); } @@ -8727,10 +8728,10 @@ int QUICK_RANGE_SELECT_GEOM::get_next() } last_range= *(cur_range++); - result= file->index_read_map(record, last_range->min_key, - last_range->min_keypart_map, - (ha_rkey_function)(last_range->flag ^ - GEOM_FLAG)); + result= file->ha_index_read_map(record, last_range->min_key, + last_range->min_keypart_map, + (ha_rkey_function)(last_range->flag ^ + GEOM_FLAG)); if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE) DBUG_RETURN(result); last_range= 0; // Not found, to next range @@ -8842,9 +8843,9 @@ int QUICK_SELECT_DESC::get_next() { // Already read through key result = ((last_range->flag & EQ_RANGE && used_key_parts <= head->key_info[index].key_parts) ? - file->index_next_same(record, last_range->min_key, + file->ha_index_next_same(record, last_range->min_key, last_range->min_length) : - file->index_prev(record)); + file->ha_index_prev(record)); if (!result) { if (cmp_prev(*rev_it.ref()) == 0) @@ -8860,7 +8861,7 @@ int QUICK_SELECT_DESC::get_next() if (last_range->flag & NO_MAX_RANGE) // Read last record { int local_error; - if ((local_error=file->index_last(record))) + if ((local_error= file->ha_index_last(record))) DBUG_RETURN(local_error); // Empty table if (cmp_prev(last_range) == 0) DBUG_RETURN(0); @@ -8872,9 +8873,9 @@ int QUICK_SELECT_DESC::get_next() used_key_parts <= head->key_info[index].key_parts) { - result = file->index_read_map(record, last_range->max_key, - last_range->max_keypart_map, - HA_READ_KEY_EXACT); + result= file->ha_index_read_map(record, last_range->max_key, + last_range->max_keypart_map, + HA_READ_KEY_EXACT); } else { @@ -8882,11 +8883,11 @@ int QUICK_SELECT_DESC::get_next() (last_range->flag & EQ_RANGE && used_key_parts > head->key_info[index].key_parts) || range_reads_after_key(last_range)); - result=file->index_read_map(record, last_range->max_key, - last_range->max_keypart_map, - ((last_range->flag & NEAR_MAX) ? - HA_READ_BEFORE_KEY : - HA_READ_PREFIX_LAST_OR_PREV)); + result= file->ha_index_read_map(record, last_range->max_key, + last_range->max_keypart_map, + ((last_range->flag & NEAR_MAX) ? + HA_READ_BEFORE_KEY : + HA_READ_PREFIX_LAST_OR_PREV)); } if (result) { @@ -9055,7 +9056,7 @@ void QUICK_RANGE_SELECT::add_keys_and_lengths(String *key_names, uint length; KEY *key_info= head->key_info + index; key_names->append(key_info->name); - length= longlong2str(max_used_key_length, buf, 10) - buf; + length= longlong10_to_str(max_used_key_length, buf, 10) - buf; used_lengths->append(buf, length); } @@ -9080,7 +9081,7 @@ void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names, KEY *key_info= head->key_info + quick->index; key_names->append(key_info->name); - length= longlong2str(quick->max_used_key_length, buf, 10) - buf; + length= longlong10_to_str(quick->max_used_key_length, buf, 10) - buf; used_lengths->append(buf, length); } if (pk_quick_select) @@ -9088,7 +9089,8 @@ void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names, KEY *key_info= head->key_info + pk_quick_select->index; key_names->append(','); key_names->append(key_info->name); - length= longlong2str(pk_quick_select->max_used_key_length, buf, 10) - buf; + length= (longlong10_to_str(pk_quick_select->max_used_key_length, buf, 10) + - buf); used_lengths->append(','); used_lengths->append(buf, length); } @@ -9113,7 +9115,7 @@ void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names, used_lengths->append(','); } key_names->append(key_info->name); - length= longlong2str(qr->quick->max_used_key_length, buf, 10) - buf; + length= longlong10_to_str(qr->quick->max_used_key_length, buf, 10) - buf; used_lengths->append(buf, length); } @@ -9122,7 +9124,7 @@ void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names, KEY *key_info= head->key_info + cpk_quick->index; key_names->append(','); key_names->append(key_info->name); - length= longlong2str(cpk_quick->max_used_key_length, buf, 10) - buf; + length= longlong10_to_str(cpk_quick->max_used_key_length, buf, 10) - buf; used_lengths->append(','); used_lengths->append(buf, length); } @@ -10634,7 +10636,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void) DBUG_RETURN(result); if (quick_prefix_select && quick_prefix_select->reset()) DBUG_RETURN(1); - result= file->index_last(record); + result= file->ha_index_last(record); if (result == HA_ERR_END_OF_FILE) DBUG_RETURN(0); /* Save the prefix of the last group. */ @@ -10736,9 +10738,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next() first sub-group with the extended prefix. */ if (!have_min && !have_max && key_infix_len > 0) - result= file->index_read_map(record, group_prefix, - make_prev_keypart_map(real_key_parts), - HA_READ_KEY_EXACT); + result= file->ha_index_read_map(record, group_prefix, + make_prev_keypart_map(real_key_parts), + HA_READ_KEY_EXACT); result= have_min ? min_res : have_max ? max_res : result; } while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) && @@ -10800,9 +10802,10 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min() /* Apply the constant equality conditions to the non-group select fields */ if (key_infix_len > 0) { - if ((result= file->index_read_map(record, group_prefix, - make_prev_keypart_map(real_key_parts), - HA_READ_KEY_EXACT))) + if ((result= + file->ha_index_read_map(record, group_prefix, + make_prev_keypart_map(real_key_parts), + HA_READ_KEY_EXACT))) DBUG_RETURN(result); } @@ -10817,9 +10820,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min() { /* Find the first subsequent record without NULL in the MIN/MAX field. */ key_copy(tmp_record, record, index_info, 0); - result= file->index_read_map(record, tmp_record, - make_keypart_map(real_key_parts), - HA_READ_AFTER_KEY); + result= file->ha_index_read_map(record, tmp_record, + make_keypart_map(real_key_parts), + HA_READ_AFTER_KEY); /* Check if the new record belongs to the current group by comparing its prefix with the group's prefix. If it is from the next group, then the @@ -10874,9 +10877,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max() if (min_max_ranges.elements > 0) result= next_max_in_range(); else - result= file->index_read_map(record, group_prefix, - make_prev_keypart_map(real_key_parts), - HA_READ_PREFIX_LAST); + result= file->ha_index_read_map(record, group_prefix, + make_prev_keypart_map(real_key_parts), + HA_READ_PREFIX_LAST); DBUG_RETURN(result); } @@ -10920,7 +10923,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_prefix() { if (!seen_first_key) { - result= file->index_first(record); + result= file->ha_index_first(record); if (result) DBUG_RETURN(result); seen_first_key= TRUE; @@ -10928,9 +10931,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_prefix() else { /* Load the first key in this group into record. */ - result= file->index_read_map(record, group_prefix, - make_prev_keypart_map(group_key_parts), - HA_READ_AFTER_KEY); + result= file->ha_index_read_map(record, group_prefix, + make_prev_keypart_map(group_key_parts), + HA_READ_AFTER_KEY); if (result) DBUG_RETURN(result); } @@ -11007,7 +11010,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range() HA_READ_AFTER_KEY : HA_READ_KEY_OR_NEXT; } - result= file->index_read_map(record, group_prefix, keypart_map, find_flag); + result= file->ha_index_read_map(record, group_prefix, keypart_map, + find_flag); if (result) { if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) && @@ -11055,6 +11059,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range() /* Compare the found key with max_key. */ int cmp_res= key_cmp(index_info->key_part, max_key, real_prefix_len + min_max_arg_len); + my_afree(max_key); /* The key is outside of the range if: the interval is open and the key is equal to the maximum boundry @@ -11146,7 +11151,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range() HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV; } - result= file->index_read_map(record, group_prefix, keypart_map, find_flag); + result= file->ha_index_read_map(record, group_prefix, keypart_map, + find_flag); if (result) { @@ -11179,6 +11185,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range() /* Compare the found key with min_key. */ int cmp_res= key_cmp(index_info->key_part, min_key, real_prefix_len + min_max_arg_len); + my_afree(min_key); /* The key is outside of the range if: the interval is open and the key is equal to the minimum boundry @@ -11282,7 +11289,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths(String *key_names, char buf[64]; uint length; key_names->append(index_info->name); - length= longlong2str(max_used_key_length, buf, 10) - buf; + length= longlong10_to_str(max_used_key_length, buf, 10) - buf; used_lengths->append(buf, length); } @@ -11314,7 +11321,8 @@ static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map, if (!tmp.length()) tmp.append(STRING_WITH_LEN("(empty)")); - DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s) scans: %s", (long) tree, msg, tmp.ptr())); + DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s) scans: %s", (long) tree, msg, + tmp.c_ptr())); DBUG_VOID_RETURN; } @@ -11337,7 +11345,7 @@ static void print_ror_scans_arr(TABLE *table, const char *msg, } if (!tmp.length()) tmp.append(STRING_WITH_LEN("(empty)")); - DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.ptr())); + DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.c_ptr())); DBUG_VOID_RETURN; } diff --git a/sql/opt_range.h b/sql/opt_range.h index d4852671717..eaaf4a2a2a8 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -833,7 +833,7 @@ public: ~FT_SELECT() { file->ft_end(); } int init() { return error=file->ft_init(); } int reset() { return 0; } - int get_next() { return error=file->ft_read(record); } + int get_next() { return error= file->ha_ft_read(record); } int get_type() { return QS_TYPE_FULLTEXT; } }; diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 7bb75c3175d..f8a81eac380 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -111,7 +111,7 @@ static int get_index_min_value(TABLE *table, TABLE_REF *ref, int error; if (!ref->key_length) - error= table->file->index_first(table->record[0]); + error= table->file->ha_index_first(table->record[0]); else { /* @@ -133,10 +133,10 @@ static int get_index_min_value(TABLE *table, TABLE_REF *ref, Closed interval: Either The MIN argument is non-nullable, or we have a >= predicate for the MIN argument. */ - error= table->file->index_read_map(table->record[0], - ref->key_buff, - make_prev_keypart_map(ref->key_parts), - HA_READ_KEY_OR_NEXT); + error= table->file->ha_index_read_map(table->record[0], + ref->key_buff, + make_prev_keypart_map(ref->key_parts), + HA_READ_KEY_OR_NEXT); else { /* @@ -148,10 +148,10 @@ static int get_index_min_value(TABLE *table, TABLE_REF *ref, and it would not work. */ DBUG_ASSERT(prefix_len < ref->key_length); - error= table->file->index_read_map(table->record[0], - ref->key_buff, - make_prev_keypart_map(ref->key_parts), - HA_READ_AFTER_KEY); + error= table->file->ha_index_read_map(table->record[0], + ref->key_buff, + make_prev_keypart_map(ref->key_parts), + HA_READ_AFTER_KEY); /* If the found record is outside the group formed by the search prefix, or there is no such record at all, check if all @@ -174,10 +174,10 @@ static int get_index_min_value(TABLE *table, TABLE_REF *ref, key_cmp_if_same(table, ref->key_buff, ref->key, prefix_len))) { DBUG_ASSERT(item_field->field->real_maybe_null()); - error= table->file->index_read_map(table->record[0], - ref->key_buff, - make_prev_keypart_map(ref->key_parts), - HA_READ_KEY_EXACT); + error= table->file->ha_index_read_map(table->record[0], + ref->key_buff, + make_prev_keypart_map(ref->key_parts), + HA_READ_KEY_EXACT); } } } @@ -200,12 +200,12 @@ static int get_index_min_value(TABLE *table, TABLE_REF *ref, static int get_index_max_value(TABLE *table, TABLE_REF *ref, uint range_fl) { return (ref->key_length ? - table->file->index_read_map(table->record[0], ref->key_buff, - make_prev_keypart_map(ref->key_parts), - range_fl & NEAR_MAX ? - HA_READ_BEFORE_KEY : - HA_READ_PREFIX_LAST_OR_PREV) : - table->file->index_last(table->record[0])); + table->file->ha_index_read_map(table->record[0], ref->key_buff, + make_prev_keypart_map(ref->key_parts), + range_fl & NEAR_MAX ? + HA_READ_BEFORE_KEY : + HA_READ_PREFIX_LAST_OR_PREV) : + table->file->ha_index_last(table->record[0])); } @@ -381,12 +381,11 @@ int opt_sum_query(THD *thd, const_result= 0; break; } - table->file->ha_index_init((uint) ref.key, 1); - - error= is_max ? - get_index_max_value(table, &ref, range_fl) : - get_index_min_value(table, &ref, item_field, range_fl, - prefix_len); + if (!(error= table->file->ha_index_init((uint) ref.key, 1))) + error= (is_max ? + get_index_max_value(table, &ref, range_fl) : + get_index_min_value(table, &ref, item_field, range_fl, + prefix_len)); /* Verify that the read tuple indeed matches the search key */ if (!error && reckey_in_range(is_max, &ref, item_field->field, @@ -660,6 +659,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, case Item_func::GE_FUNC: break; case Item_func::BETWEEN: + if (((Item_func_between*) cond)->negated) + DBUG_RETURN(FALSE); between= 1; break; case Item_func::MULT_EQUAL_FUNC: diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc index 5d952021365..fdf818abb8e 100644 --- a/sql/opt_table_elimination.cc +++ b/sql/opt_table_elimination.cc @@ -1539,7 +1539,7 @@ Dep_value_table *Dep_analysis_context::create_table_value(TABLE *table) for (uint i=0; i < table->s->keys; i++) { KEY *key= table->key_info + i; - if ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME) + if (key->flags & HA_NOSAME) { Dep_module_key *key_dep; if (!(key_dep= new Dep_module_key(tbl_dep, i, key->key_parts))) @@ -1778,7 +1778,7 @@ static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl) JOIN_TAB *tab= tbl->table->reginfo.join_tab; if (!(join->const_table_map & tab->table->map)) { - DBUG_PRINT("info", ("Eliminated table %s", table->alias)); + DBUG_PRINT("info", ("Eliminated table %s", table->alias.c_ptr())); tab->type= JT_CONST; join->eliminated_tables |= table->map; join->const_table_map|= table->map; @@ -1813,7 +1813,7 @@ void Dep_analysis_context::dbug_print_deps() fprintf(DBUG_FILE, " equality%ld: %s -> %s.%s\n", (long)(eq_mod - equality_mods), str.c_ptr(), - eq_mod->field->table->table->alias, + eq_mod->field->table->table->alias.c_ptr(), eq_mod->field->field->field_name); } else @@ -1831,12 +1831,13 @@ void Dep_analysis_context::dbug_print_deps() if ((table_dep= table_deps[i])) { /* Print table */ - fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias); + fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias.c_ptr()); /* Print fields */ for (Dep_value_field *field_dep= table_dep->fields; field_dep; field_dep= field_dep->next_table_field) { - fprintf(DBUG_FILE, " field %s.%s ->", table_dep->table->alias, + fprintf(DBUG_FILE, " field %s.%s ->", + table_dep->table->alias.c_ptr(), field_dep->field->field_name); uint ofs= field_dep->bitmap_offset; for (uint bit= ofs; bit < ofs + n_equality_mods; bit++) diff --git a/sql/parse_file.h b/sql/parse_file.h index 247cb147389..2ebcd2ec987 100644 --- a/sql/parse_file.h +++ b/sql/parse_file.h @@ -92,12 +92,12 @@ class File_parser: public Sql_alloc { char *buff, *start, *end; LEX_STRING file_type; - my_bool content_ok; + bool content_ok; public: File_parser() :buff(0), start(0), end(0), content_ok(0) { file_type.str= 0; file_type.length= 0; } - my_bool ok() { return content_ok; } + bool ok() { return content_ok; } LEX_STRING *type() { return &file_type; } my_bool parse(uchar* base, MEM_ROOT *mem_root, struct File_option *parameters, uint required, diff --git a/sql/partition_info.cc b/sql/partition_info.cc index f51d3fdf641..ac3042fd815 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1106,8 +1106,8 @@ void partition_info::print_no_partition_found(TABLE *table) if (part_expr->null_value) buf_ptr= (char*)"NULL"; else - longlong2str(err_value, buf, - part_expr->unsigned_flag ? 10 : -10); + longlong10_to_str(err_value, buf, + part_expr->unsigned_flag ? 10 : -10); my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr); dbug_tmp_restore_column_map(table->read_set, old_map); } diff --git a/sql/password.c b/sql/password.c index c8aa90aa56d..27fbb07b6e3 100644 --- a/sql/password.c +++ b/sql/password.c @@ -190,7 +190,7 @@ void scramble_323(char *to, const char *message, const char *password) */ my_bool -check_scramble_323(const char *scrambled, const char *message, +check_scramble_323(const unsigned char *scrambled, const char *message, ulong *hash_pass) { struct my_rnd_struct rand_st; @@ -198,7 +198,7 @@ check_scramble_323(const char *scrambled, const char *message, /* Big enough for checks. */ char buff[16], scrambled_buff[SCRAMBLE_LENGTH_323 + 1]; char *to, extra; - const char *pos; + const uchar *pos; /* Ensure that the scrambled message is null-terminated. */ memcpy(scrambled_buff, scrambled, SCRAMBLE_LENGTH_323); @@ -218,7 +218,7 @@ check_scramble_323(const char *scrambled, const char *message, to=buff; while (*scrambled) { - if (*scrambled++ != (char) (*to++ ^ extra)) + if (*scrambled++ != (uchar) (*to++ ^ extra)) return 1; /* Wrong password */ } return 0; @@ -485,7 +485,7 @@ scramble(char *to, const char *message, const char *password) */ my_bool -check_scramble(const char *scramble_arg, const char *message, +check_scramble(const uchar *scramble_arg, const char *message, const uint8 *hash_stage2) { SHA1_CONTEXT sha1_context; @@ -498,7 +498,7 @@ check_scramble(const char *scramble_arg, const char *message, mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); mysql_sha1_result(&sha1_context, buf); /* encrypt scramble */ - my_crypt((char *) buf, buf, (const uchar *) scramble_arg, SCRAMBLE_LENGTH); + my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH); /* now buf supposedly contains hash_stage1: so we can get hash_stage2 */ mysql_sha1_reset(&sha1_context); mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE); diff --git a/sql/procedure.h b/sql/procedure.h index ceb586766b1..30a8a0efccb 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -42,7 +42,11 @@ public: { init_make_field(tmp_field,field_type()); } - unsigned int size_of() { return sizeof(*this);} + unsigned int size_of() { return sizeof(*this);} + bool check_vcol_func_processor(uchar *int_arg) + { + return trace_unsupported_by_check_vcol_func_processor("proc"); + } }; class Item_proc_real :public Item_proc diff --git a/sql/protocol.cc b/sql/protocol.cc index 055c166f5a5..3381cf2f1bb 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -343,24 +343,6 @@ static bool write_eof_packet(THD *thd, NET *net, } /** - Please client to send scrambled_password in old format. - - @param thd thread handle - - @retval - 0 ok - @retval - !0 error -*/ - -bool send_old_password_request(THD *thd) -{ - NET *net= &thd->net; - return my_net_write(net, eof_buff, 1) || net_flush(net); -} - - -/** @param thd Thread handler @param sql_errno The error code to send @param err A pointer to the error message @@ -652,6 +634,9 @@ bool Protocol::send_fields(List<Item> *list, uint flags) uint count= 0; #endif + /* We have to reallocate it here as a stored procedure may have reset it */ + (void) local_packet->alloc(thd->variables.net_buffer_length); + while ((item=it++)) { char *pos; diff --git a/sql/protocol.h b/sql/protocol.h index 5d49aa28112..1560f7272b5 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -180,7 +180,6 @@ public: void send_warning(THD *thd, uint sql_errno, const char *err=0); bool net_send_error(THD *thd, uint sql_errno=0, const char *err=0); void net_end_statement(THD *thd); -bool send_old_password_request(THD *thd); uchar *net_store_data(uchar *to,const uchar *from, size_t length); uchar *net_store_data(uchar *to,int32 from); uchar *net_store_data(uchar *to,longlong from); diff --git a/sql/records.cc b/sql/records.cc index 181afbad400..208405b0657 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -159,7 +159,8 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, This is the most basic access method of a table using rnd_init, rnd_next and rnd_end. No indexes are used. */ -void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, + +bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, SQL_SELECT *select, int use_record_cache, bool print_error, bool disable_rr_cache) @@ -208,7 +209,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0); info->ref_pos=table->file->ref; if (!table->file->inited) - table->file->ha_rnd_init(0); + if (table->file->ha_rnd_init_with_error(0)) + DBUG_RETURN(1); /* table->sort.addon_field is checked because if we use addon fields, @@ -217,7 +219,6 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, */ if (!disable_rr_cache && !table->sort.addon_field && - ! (specialflag & SPECIAL_SAFE_MODE) && thd->variables.read_rnd_buff_size && !(table->file->ha_table_flags() & HA_FAST_KEY_READ) && (table->db_stat & HA_READ_ONLY || @@ -245,7 +246,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, else if (table->sort.record_pointers) { DBUG_PRINT("info",("using record_pointers")); - table->file->ha_rnd_init(0); + if (table->file->ha_rnd_init_with_error(0)) + DBUG_RETURN(1); info->cache_pos=table->sort.record_pointers; info->cache_end=info->cache_pos+ table->sort.found_records*info->ref_length; @@ -256,7 +258,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, { DBUG_PRINT("info",("using rr_sequential")); info->read_record=rr_sequential; - table->file->ha_rnd_init(1); + if (table->file->ha_rnd_init_with_error(1)) + DBUG_RETURN(1); /* We can use record cache if we don't update dynamic length tables */ if (!table->no_cache && (use_record_cache > 0 || @@ -274,7 +277,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, !table->file->pushed_cond) table->file->cond_push(select->cond); - DBUG_VOID_RETURN; + DBUG_RETURN(0); } /* init_read_record */ @@ -330,6 +333,7 @@ static int rr_quick(READ_RECORD *info) break; } } + update_virtual_fields(info->thd, info->table); return tmp; } @@ -349,7 +353,7 @@ static int rr_quick(READ_RECORD *info) static int rr_index_first(READ_RECORD *info) { - int tmp= info->file->index_first(info->record); + int tmp= info->file->ha_index_first(info->record); info->read_record= rr_index; if (tmp) tmp= rr_handle_error(info, tmp); @@ -375,7 +379,7 @@ static int rr_index_first(READ_RECORD *info) static int rr_index(READ_RECORD *info) { - int tmp= info->file->index_next(info->record); + int tmp= info->file->ha_index_next(info->record); if (tmp) tmp= rr_handle_error(info, tmp); return tmp; @@ -385,7 +389,7 @@ static int rr_index(READ_RECORD *info) int rr_sequential(READ_RECORD *info) { int tmp; - while ((tmp=info->file->rnd_next(info->record))) + while ((tmp= info->file->ha_rnd_next(info->record))) { /* rnd_next can return RECORD_DELETED for MyISAM when one thread is @@ -397,6 +401,8 @@ int rr_sequential(READ_RECORD *info) break; } } + if (!tmp) + update_virtual_fields(info->thd, info->table); return tmp; } @@ -408,7 +414,7 @@ static int rr_from_tempfile(READ_RECORD *info) { if (my_b_read(info->io_cache,info->ref_pos,info->ref_length)) return -1; /* End of file */ - if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos))) + if (!(tmp= info->file->ha_rnd_pos(info->record,info->ref_pos))) break; /* The following is extremely unlikely to happen */ if (tmp == HA_ERR_RECORD_DELETED || @@ -459,7 +465,7 @@ static int rr_from_pointers(READ_RECORD *info) cache_pos= info->cache_pos; info->cache_pos+= info->ref_length; - if (!(tmp=info->file->rnd_pos(info->record,cache_pos))) + if (!(tmp= info->file->ha_rnd_pos(info->record,cache_pos))) break; /* The following is extremely unlikely to happen */ @@ -592,7 +598,7 @@ static int rr_from_cache(READ_RECORD *info) record=uint3korr(position); position+=3; record_pos=info->cache+record*info->reclength; - if ((error=(int16) info->file->rnd_pos(record_pos,info->ref_pos))) + if ((error=(int16) info->file->ha_rnd_pos(record_pos,info->ref_pos))) { record_pos[info->error_offset]=1; shortstore(record_pos,error); diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc index 585334433df..1ccd3ccc0fe 100644 --- a/sql/rpl_filter.cc +++ b/sql/rpl_filter.cc @@ -48,6 +48,7 @@ Rpl_filter::~Rpl_filter() } +#ifndef MYSQL_CLIENT /* Returns true if table should be logged/replicated @@ -132,6 +133,7 @@ Rpl_filter::tables_ok(const char* db, TABLE_LIST* tables) !do_table_inited && !wild_do_table_inited); } +#endif /* Checks whether a db matches some do_db and ignore_db rules @@ -523,6 +525,13 @@ Rpl_filter::get_wild_ignore_table(String* str) } +bool +Rpl_filter::rewrite_db_is_empty() +{ + return rewrite_db.is_empty(); +} + + const char* Rpl_filter::get_rewrite_db(const char* db, size_t *new_len) { diff --git a/sql/rpl_filter.h b/sql/rpl_filter.h index ff7e4081bb1..88951600e56 100644 --- a/sql/rpl_filter.h +++ b/sql/rpl_filter.h @@ -42,7 +42,9 @@ public: /* Checks - returns true if ok to replicate/log */ - bool tables_ok(const char* db, TABLE_LIST* tables); +#ifndef MYSQL_CLIENT + bool tables_ok(const char* db, TABLE_LIST *tables); +#endif bool db_ok(const char* db); bool db_ok_with_wild_table(const char *db); @@ -69,6 +71,7 @@ public: void get_wild_do_table(String* str); void get_wild_ignore_table(String* str); + bool rewrite_db_is_empty(); const char* get_rewrite_db(const char* db, size_t *new_len); I_List<i_string>* get_do_db(); diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 47b528001dc..8bb1757d917 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -68,10 +68,10 @@ class Master_info : public Slave_reporting_capability char host[HOSTNAME_LENGTH+1]; char user[USERNAME_LENGTH+1]; char password[MAX_PASSWORD_LENGTH+1]; - my_bool ssl; // enables use of SSL connection if true + bool ssl; // enables use of SSL connection if true char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN]; char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN]; - my_bool ssl_verify_server_cert; + bool ssl_verify_server_cert; my_off_t master_log_pos; File fd; // we keep the file open, so we need to remember the file pointer diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index b56cef3913f..3a9990bb20f 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -172,7 +172,8 @@ a file name for --relay-log-index option", opt_relaylog_index_name); " so replication " "may break when this MySQL server acts as a " "slave and has his hostname changed!! Please " - "use '--relay-log=%s' to avoid this problem.", ln); + "use '--log-basename=#' or '--relay-log=%s' to avoid " + "this problem.", ln); name_warning_sent= 1; } /* diff --git a/sql/scheduler.cc b/sql/scheduler.cc index 5b8f834aecc..6dd93640dc5 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -376,7 +376,9 @@ void libevent_kill_thd_callback(int Fd, short, void*) { THD *thd= (THD*)list->data; list= list_rest(list); - if (thd->killed == THD::KILL_CONNECTION) + if (thd->killed == THD::KILL_CONNECTION || + thd->killed == THD::KILL_SYSTEM_THREAD || + thd->killed == THD::KILL_SERVER) { /* Delete from libevent and add to the processing queue. @@ -531,9 +533,10 @@ static void libevent_connection_close(THD *thd) static bool libevent_should_close_connection(THD* thd) { - return thd->net.error || - thd->net.vio == 0 || - thd->killed == THD::KILL_CONNECTION; + return (thd->net.error || + thd->net.vio == 0 || + thd->killed == THD::KILL_CONNECTION || + thd->killed == THD::KILL_SERVER); } diff --git a/sql/set_var.cc b/sql/set_var.cc index 40e26ea4930..b5b19f52c9e 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -61,7 +61,7 @@ #include <my_getopt.h> #include <thr_alarm.h> #include <myisam.h> -#ifdef WITH_MARIA_STORAGE_ENGINE +#ifdef WITH_ARIA_STORAGE_ENGINE #include <maria.h> #endif #include <my_dir.h> @@ -326,15 +326,18 @@ static sys_var_thd_ulong sys_interactive_timeout(&vars, "interactive_timeout", static sys_var_thd_ulong sys_join_buffer_size(&vars, "join_buffer_size", &SV::join_buff_size); static sys_var_key_buffer_size sys_key_buffer_size(&vars, "key_buffer_size"); -static sys_var_key_cache_long sys_key_cache_block_size(&vars, "key_cache_block_size", - offsetof(KEY_CACHE, - param_block_size)); -static sys_var_key_cache_long sys_key_cache_division_limit(&vars, "key_cache_division_limit", - offsetof(KEY_CACHE, - param_division_limit)); -static sys_var_key_cache_long sys_key_cache_age_threshold(&vars, "key_cache_age_threshold", - offsetof(KEY_CACHE, - param_age_threshold)); +static sys_var_key_cache_long sys_key_cache_block_size(&vars, + "key_cache_block_size", + offsetof(KEY_CACHE,param_block_size)); +static sys_var_key_cache_long sys_key_cache_division_limit(&vars, + "key_cache_division_limit", + offsetof(KEY_CACHE, param_division_limit)); +static sys_var_key_cache_long sys_key_cache_age_threshold(&vars, + "key_cache_age_threshold", + offsetof(KEY_CACHE, param_age_threshold)); +static sys_var_key_cache_long sys_key_cache_partitions(&vars, + "key_cache_segments", + offsetof(KEY_CACHE, param_partitions)); static sys_var_const sys_language(&vars, "language", OPT_GLOBAL, SHOW_CHAR, (uchar*) language); @@ -477,6 +480,10 @@ static sys_var_thd_enum sys_myisam_stats_method(&vars, "myisam_stats_met &myisam_stats_method_typelib, NULL); +static sys_var_const sys_myisam_block_size(&vars, "myisam_block_size", + OPT_GLOBAL, SHOW_LONG, + (uchar*) &myisam_block_size); + #ifdef __NT__ /* purecov: begin inspected */ static sys_var_const sys_named_pipe(&vars, "named_pipe", @@ -531,6 +538,9 @@ static sys_var_const sys_protocol_version(&vars, "protocol_version", static sys_var_thd_ulong sys_read_buff_size(&vars, "read_buffer_size", &SV::read_buff_size); static sys_var_opt_readonly sys_readonly(&vars, "read_only", &opt_readonly); +static sys_var_bool_ptr sys_userstat(&vars, "userstat", + &opt_userstat_running); + static sys_var_thd_ulong sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size", &SV::read_rnd_buff_size); static sys_var_thd_ulong sys_div_precincrement(&vars, "div_precision_increment", @@ -600,9 +610,8 @@ static sys_var_thd_ulong sys_trans_prealloc_size(&vars, "transaction_prealloc_si &SV::trans_prealloc_size, 0, fix_trans_mem_root); sys_var_enum_const sys_thread_handling(&vars, "thread_handling", - &SV::thread_handling, - &thread_handling_typelib, - NULL); + &thread_handling, + &thread_handling_typelib); #ifdef HAVE_QUERY_CACHE static sys_var_long_ptr sys_query_cache_limit(&vars, "query_cache_limit", @@ -902,6 +911,8 @@ static sys_var_thd_set sys_log_slow_verbosity(&vars, /* Global read-only variable containing hostname */ static sys_var_const_str sys_hostname(&vars, "hostname", glob_hostname); +static sys_var_const_str_ptr sys_log_basename(&vars, "log_basename", + &opt_log_basename); #ifndef EMBEDDED_LIBRARY static sys_var_const_str_ptr sys_repl_report_host(&vars, "report_host", &report_host); @@ -965,6 +976,9 @@ static sys_var_readonly sys_myisam_mmap_size(&vars, "myisam_mmap_size", SHOW_LONGLONG, get_myisam_mmap_size); +static sys_var_enum_const sys_plugin_maturity(&vars, "plugin_maturity", + &plugin_maturity, + &plugin_maturity_values); bool sys_var::check(THD *thd, set_var *var) { @@ -980,7 +994,7 @@ bool sys_var_str::check(THD *thd, set_var *var) if ((res=(*check_func)(thd, var)) < 0) my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), - name, var->value->str_value.ptr()); + name, var->value->str_value.c_ptr()); return res; } @@ -1227,21 +1241,21 @@ extern void fix_delay_key_write(THD *thd, enum_var_type type) switch ((enum_delay_key_write) delay_key_write_options) { case DELAY_KEY_WRITE_NONE: myisam_delay_key_write=0; -#ifdef WITH_MARIA_STORAGE_ENGINE +#ifdef WITH_ARIA_STORAGE_ENGINE maria_delay_key_write= 0; #endif ha_open_options&= ~HA_OPEN_DELAY_KEY_WRITE; break; case DELAY_KEY_WRITE_ON: myisam_delay_key_write=1; -#ifdef WITH_MARIA_STORAGE_ENGINE +#ifdef WITH_ARIA_STORAGE_ENGINE maria_delay_key_write= 1; #endif ha_open_options&= ~HA_OPEN_DELAY_KEY_WRITE; break; case DELAY_KEY_WRITE_ALL: myisam_delay_key_write=1; -#ifdef WITH_MARIA_STORAGE_ENGINE +#ifdef WITH_ARIA_STORAGE_ENGINE maria_delay_key_write= 1; #endif ha_open_options|= HA_OPEN_DELAY_KEY_WRITE; @@ -1660,12 +1674,6 @@ uchar *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) return (uchar*) enum_names->type_names[*value]; } -uchar *sys_var_enum_const::value_ptr(THD *thd, enum_var_type type, - LEX_STRING *base) -{ - return (uchar*) enum_names->type_names[global_system_variables.*offset]; -} - bool sys_var_thd_ulong::check(THD *thd, set_var *var) { if (get_unsigned(thd, var, max_system_variables.*offset, GET_ULONG)) @@ -2249,11 +2257,15 @@ bool sys_var_character_set::check(THD *thd, set_var *var) } tmp= NULL; } - else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) && - !(tmp=get_old_charset_by_name(res->c_ptr()))) + else { - my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr()); - return 1; + const char *name= res->c_ptr_safe(); + if (!(tmp=get_charset_by_csname(name,MY_CS_PRIMARY,MYF(0))) && + !(tmp=get_old_charset_by_name(name))) + { + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), name); + return 1; + } } } else // INT_RESULT @@ -2543,7 +2555,15 @@ bool sys_var_key_cache_long::update(THD *thd, set_var *var) pthread_mutex_unlock(&LOCK_global_system_variables); - error= (bool) (ha_resize_key_cache(key_cache)); + if (offset == offsetof(KEY_CACHE, param_block_size)) + error= (bool) (ha_resize_key_cache(key_cache)); + else + if (offset == offsetof(KEY_CACHE, param_division_limit) || + offset == offsetof(KEY_CACHE, param_age_threshold)) + error= (bool) (ha_change_key_cache_param(key_cache)); + else + if (offset == offsetof(KEY_CACHE, param_partitions)) + error= (bool) (ha_repartition_key_cache(key_cache)); pthread_mutex_lock(&LOCK_global_system_variables); key_cache->in_init= 0; @@ -2594,7 +2614,7 @@ static int sys_check_log_path(THD *thd, set_var *var) if (!(res= var->value->val_str(&str))) goto err; - log_file_str= res->c_ptr(); + log_file_str= res->c_ptr_safe(); bzero(&f_stat, sizeof(MY_STAT)); path_length= unpack_filename(path, log_file_str); @@ -4089,7 +4109,7 @@ bool sys_var_thd_optimizer_switch::check(THD *thd, set_var *var) optimizer_switch_typelib.count, thd->variables.optimizer_switch, global_system_variables.optimizer_switch, - res->c_ptr_safe(), res->length(), NULL, + res->ptr(), res->length(), NULL, &error, &error_len, ¬_used); if (error_len) { @@ -4174,6 +4194,7 @@ static KEY_CACHE *create_key_cache(const char *name, uint length) key_cache->param_block_size= dflt_key_cache_var.param_block_size; key_cache->param_division_limit= dflt_key_cache_var.param_division_limit; key_cache->param_age_threshold= dflt_key_cache_var.param_age_threshold; + key_cache->param_partitions= dflt_key_cache_var.param_partitions; } } DBUG_RETURN(key_cache); diff --git a/sql/set_var.h b/sql/set_var.h index 2e9812eca3b..95885357b83 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -377,21 +377,14 @@ public: }; -class sys_var_enum_const :public sys_var +class sys_var_enum_const :public sys_var_enum { - ulong SV::*offset; - TYPELIB *enum_names; public: - sys_var_enum_const(sys_var_chain *chain, const char *name_arg, ulong SV::*offset_arg, - TYPELIB *typelib, sys_after_update_func func) - :sys_var(name_arg,func), offset(offset_arg), enum_names(typelib) - { chain_sys_var(chain); } - bool check(THD *thd, set_var *var) { return 1; } - bool update(THD *thd, set_var *var) { return 1; } - SHOW_TYPE show_type() { return SHOW_CHAR; } - bool check_update_type(Item_result type) { return 1; } + sys_var_enum_const(sys_var_chain *chain, const char *name_arg, + uint *value_arg, TYPELIB *typelib) + :sys_var_enum(chain, name_arg, value_arg, typelib, 0) + { } bool is_readonly() const { return 1; } - uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); }; @@ -1432,6 +1425,7 @@ public: my_free((uchar*) name, MYF(0)); } friend bool process_key_caches(process_key_cache_t func); + friend int fill_key_cache_tables(THD *thd, TABLE_LIST *tables, COND *cond); friend void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(const char*, uchar*)); }; diff --git a/sql/share/CMakeLists.txt b/sql/share/CMakeLists.txt new file mode 100644 index 00000000000..0c8ddf402d2 --- /dev/null +++ b/sql/share/CMakeLists.txt @@ -0,0 +1,54 @@ +# Copyright (c) 2006, 2010, 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 + +SET (dirs +danish +german +slovak +dutch +greek +norwegian +spanish +english +hungarian +norwegian-ny +swedish +italian +polish +ukrainian +japanese +portuguese +romanian +estonian +korean +russian +czech +french +serbian +) + +SET(files + errmsg.txt +) + +FOREACH (dir ${dirs}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir} + DESTINATION share COMPONENT Server) +ENDFOREACH() +INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/charsets DESTINATION share COMPONENT Server + PATTERN "languages.html" EXCLUDE +) + +INSTALL(FILES ${files} DESTINATION share COMPONENT Server) diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am index 4a9123d6d25..892a720900e 100644 --- a/sql/share/Makefile.am +++ b/sql/share/Makefile.am @@ -15,7 +15,7 @@ ## Process this file with automake to create Makefile.in -EXTRA_DIST= errmsg.txt +EXTRA_DIST= errmsg.txt CMakeLists.txt dist-hook: for dir in charsets @AVAILABLE_LANGUAGES@; do \ diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 001bea9de88..d3d038e9b82 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6017,7 +6017,7 @@ ER_ONLY_INTEGERS_ALLOWED eng "Only integers allowed as number here" ger "An dieser Stelle sind nur Ganzzahlen zulässig" ER_UNSUPORTED_LOG_ENGINE - eng "This storage engine cannot be used for log tables"" + eng "This storage engine cannot be used for log tables" ger "Diese Speicher-Engine kann für Logtabellen nicht verwendet werden" ER_BAD_LOG_STATEMENT eng "You cannot '%s' a log table if logging is enabled" @@ -6213,3 +6213,39 @@ ER_DEBUG_SYNC_TIMEOUT ER_DEBUG_SYNC_HIT_LIMIT eng "debug sync point hit limit reached" ger "Debug Sync Point Hit Limit erreicht" + +ER_VCOL_BASED_ON_VCOL + eng "A computed column cannot be based on a computed column" + +ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED + eng "Function or expression is not allowed for column '%s'" + +ER_DATA_CONVERSION_ERROR_FOR_VIRTUAL_COLUMN + eng "Generated value for computed column '%s' cannot be converted to type '%s'" + +ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN + eng "Primary key cannot be defined upon a computed column" + +ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN + eng "Key/Index cannot be defined on a non-stored computed column" + +ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN + eng "Cannot define foreign key with %s clause on a computed column" + +ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN + eng "The value specified for computed column '%s' in table '%s' ignored" + +ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN + eng "This is not yet supported for computed columns" + +ER_CONST_EXPR_IN_VCOL + eng "Constant expression in computed column function is not allowed" + +ER_ROW_EXPR_FOR_VCOL + eng "Expression for computed column cannot return a row" +ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS + eng "%s storage engine does not support computed columns" +ER_UNKNOWN_OPTION + eng "Unknown option '%-.64s'" +ER_BAD_OPTION_VALUE + eng "Incorrect value '%-.64s' for option '%-.64s'" diff --git a/sql/slave.cc b/sql/slave.cc index d779d8cdc9e..813cf20464e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -843,6 +843,7 @@ bool is_network_error(uint errorno) errorno == CR_SERVER_GONE_ERROR || errorno == CR_SERVER_LOST || errorno == ER_CON_COUNT_ERROR || + errorno == ER_NEW_ABORTING_CONNECTION || errorno == ER_SERVER_SHUTDOWN) return TRUE; @@ -3986,11 +3987,11 @@ bool flush_relay_log_info(Relay_log_info* rli) my_b_seek(file, 0L); pos=strmov(buff, rli->group_relay_log_name); *pos++='\n'; - pos=longlong2str(rli->group_relay_log_pos, pos, 10); + pos= longlong10_to_str(rli->group_relay_log_pos, pos, 10); *pos++='\n'; pos=strmov(pos, rli->group_master_log_name); *pos++='\n'; - pos=longlong2str(rli->group_master_log_pos, pos, 10); + pos=longlong10_to_str(rli->group_master_log_pos, pos, 10); *pos='\n'; if (my_b_write(file, (uchar*) buff, (size_t) (pos-buff)+1)) error=1; diff --git a/sql/sp.cc b/sql/sp.cc index 6f8c351f637..efa5526fed9 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -16,8 +16,8 @@ */ #include "mysql_priv.h" -#include "sp.h" #include "sp_head.h" +#include "sp.h" #include "sp_cache.h" #include "sql_trigger.h" @@ -25,7 +25,7 @@ static bool create_string(THD *thd, String *buf, - int sp_type, + stored_procedure_type sp_type, const char *db, ulong dblen, const char *name, ulong namelen, const char *params, ulong paramslen, @@ -35,7 +35,8 @@ create_string(THD *thd, String *buf, const LEX_STRING *definer_user, const LEX_STRING *definer_host); static int -db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, +db_load_routine(THD *thd, stored_procedure_type type, sp_name *name, + sp_head **sphp, ulong sql_mode, const char *params, const char *returns, const char *body, st_sp_chistics &chistics, const char *definer, longlong created, longlong modified, @@ -149,7 +150,8 @@ TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] = { { C_STRING_WITH_LEN("sql_mode") }, { C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES'," - "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION'," + "'IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY'," + "'NO_UNSIGNED_SUBTRACTION'," "'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB'," "'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40'," "'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES'," @@ -491,7 +493,8 @@ static TABLE *open_proc_table_for_update(THD *thd) */ static int -db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table) +db_find_routine_aux(THD *thd, stored_procedure_type type, sp_name *name, + TABLE *table) { uchar key[MAX_KEY_LENGTH]; // db, name, optional key length type DBUG_ENTER("db_find_routine_aux"); @@ -514,8 +517,9 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table) key_copy(key, table->record[0], table->key_info, table->key_info->key_length); - if (table->file->index_read_idx_map(table->record[0], 0, key, HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_idx_map(table->record[0], 0, key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) DBUG_RETURN(SP_KEY_NOT_FOUND); DBUG_RETURN(SP_OK); @@ -543,7 +547,8 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table) */ static int -db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) +db_find_routine(THD *thd, stored_procedure_type type, sp_name *name, + sp_head **sphp) { TABLE *table; const char *params, *returns, *body; @@ -742,7 +747,8 @@ Bad_db_error_handler::handle_error(uint sql_errno, const char *message, static int -db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, +db_load_routine(THD *thd, stored_procedure_type type, + sp_name *name, sp_head **sphp, ulong sql_mode, const char *params, const char *returns, const char *body, st_sp_chistics &chistics, const char *definer, longlong created, longlong modified, @@ -930,7 +936,7 @@ sp_returns_type(THD *thd, String &result, sp_head *sp) */ int -sp_create_routine(THD *thd, int type, sp_head *sp) +sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) { int ret; TABLE *table; @@ -946,7 +952,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp) bool save_binlog_row_based; DBUG_ENTER("sp_create_routine"); - DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length, + DBUG_PRINT("enter", ("type: %d name: %.*s", (int) type, + (int) sp->m_name.length, sp->m_name.str)); String retstr(64); retstr.set_charset(system_charset_info); @@ -1144,7 +1151,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) (sp->m_explicit_name ? sp->m_db.length : 0), sp->m_name.str, sp->m_name.length, sp->m_params.str, sp->m_params.length, - retstr.c_ptr(), retstr.length(), + retstr.ptr(), retstr.length(), sp->m_body.str, sp->m_body.length, sp->m_chistics, &(thd->lex->definer->user), &(thd->lex->definer->host))) @@ -1156,7 +1163,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) thd->variables.sql_mode= saved_mode; /* Such a statement can always go directly to binlog, no trans cache */ if (thd->binlog_query(THD::MYSQL_QUERY_TYPE, - log_query.c_ptr(), log_query.length(), + log_query.ptr(), log_query.length(), FALSE, FALSE, 0)) ret= SP_INTERNAL_ERROR; thd->variables.sql_mode= 0; @@ -1191,7 +1198,7 @@ done: */ int -sp_drop_routine(THD *thd, int type, sp_name *name) +sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name) { TABLE *table; int ret; @@ -1251,14 +1258,16 @@ sp_drop_routine(THD *thd, int type, sp_name *name) */ int -sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) +sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, + st_sp_chistics *chistics) { TABLE *table; int ret; bool save_binlog_row_based; DBUG_ENTER("sp_update_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", - type, (int) name->m_name.length, name->m_name.str)); + (int) type, + (int) name->m_name.length, name->m_name.str)); DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || type == TYPE_ENUM_FUNCTION); @@ -1321,6 +1330,7 @@ sp_drop_db_routines(THD *thd, char *db) TABLE *table; int ret; uint key_len; + uchar keybuf[MAX_KEY_LENGTH]; DBUG_ENTER("sp_drop_db_routines"); DBUG_PRINT("enter", ("db: %s", db)); @@ -1330,12 +1340,14 @@ sp_drop_db_routines(THD *thd, char *db) table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info); key_len= table->key_info->key_part[0].store_length; + table->field[MYSQL_PROC_FIELD_DB]->get_key_image(keybuf, key_len, Field::itRAW); + + ret= SP_OK; table->file->ha_index_init(0, 1); - if (! table->file->index_read_map(table->record[0], - (uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr, - (key_part_map)1, HA_READ_KEY_EXACT)) + if (!table->file->ha_index_read_map(table->record[0], keybuf, (key_part_map)1, + HA_READ_KEY_EXACT)) { int nxtres; bool deleted= FALSE; @@ -1350,9 +1362,8 @@ sp_drop_db_routines(THD *thd, char *db) nxtres= 0; break; } - } while (! (nxtres= table->file->index_next_same(table->record[0], - (uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr, - key_len))); + } while (!(nxtres= table->file->ha_index_next_same(table->record[0], + keybuf, key_len))); if (nxtres != HA_ERR_END_OF_FILE) ret= SP_KEY_NOT_FOUND; if (deleted) @@ -1384,7 +1395,7 @@ err: */ bool -sp_show_create_routine(THD *thd, int type, sp_name *name) +sp_show_create_routine(THD *thd, stored_procedure_type type, sp_name *name) { bool err_status= TRUE; sp_head *sp; @@ -1442,8 +1453,8 @@ sp_show_create_routine(THD *thd, int type, sp_name *name) */ sp_head * -sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, - bool cache_only) +sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name, + sp_cache **cp, bool cache_only) { sp_head *sp; ulong depth= (type == TYPE_ENUM_PROCEDURE ? @@ -1600,7 +1611,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any) */ int -sp_routine_exists_in_table(THD *thd, int type, sp_name *name) +sp_routine_exists_in_table(THD *thd, stored_procedure_type type, sp_name *name) { TABLE *table; int ret; @@ -1767,7 +1778,7 @@ static bool add_used_routine(LEX *lex, Query_arena *arena, */ void sp_add_used_routine(LEX *lex, Query_arena *arena, - sp_name *rt, char rt_type) + sp_name *rt, enum stored_procedure_type rt_type) { rt->set_routine_type(rt_type); (void)add_used_routine(lex, arena, &rt->m_sroutines_key, 0); @@ -1923,9 +1934,11 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, for (Sroutine_hash_entry *rt= start; rt; rt= rt->next) { sp_name name(thd, rt->key.str, rt->key.length); - int type= rt->key.str[0]; + stored_procedure_type type= (stored_procedure_type) rt->key.str[0]; sp_head *sp; + if (type == TYPE_ENUM_TRIGGER) + continue; if (!(sp= sp_cache_lookup((type == TYPE_ENUM_FUNCTION ? &thd->sp_func_cache : &thd->sp_proc_cache), &name))) @@ -2114,7 +2127,7 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex, */ static bool create_string(THD *thd, String *buf, - int type, + stored_procedure_type type, const char *db, ulong dblen, const char *name, ulong namelen, const char *params, ulong paramslen, @@ -42,26 +42,28 @@ int sp_drop_db_routines(THD *thd, char *db); sp_head * -sp_find_routine(THD *thd, int type, sp_name *name, +sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name, sp_cache **cp, bool cache_only); bool sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any); int -sp_routine_exists_in_table(THD *thd, int type, sp_name *name); +sp_routine_exists_in_table(THD *thd, stored_procedure_type type, + sp_name *name); bool -sp_show_create_routine(THD *thd, int type, sp_name *name); +sp_show_create_routine(THD *thd, stored_procedure_type type, sp_name *name); int -sp_create_routine(THD *thd, int type, sp_head *sp); +sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp); int -sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics); +sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, + st_sp_chistics *chistics); int -sp_drop_routine(THD *thd, int type, sp_name *name); +sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name); /* Procedures for pre-caching of stored routines and building table list @@ -70,7 +72,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name); void sp_get_prelocking_info(THD *thd, bool *need_prelocking, bool *first_no_prelocking); void sp_add_used_routine(LEX *lex, Query_arena *arena, - sp_name *rt, char rt_type); + sp_name *rt, stored_procedure_type rt_type); void sp_remove_not_own_routines(LEX *lex); bool sp_update_sp_used_routines(HASH *dst, HASH *src); int sp_cache_routines_and_add_tables(THD *thd, LEX *lex, diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 67ec830d902..f1f453bada5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -388,8 +388,8 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr) thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; thd->abort_on_warning= - thd->variables.sql_mode & - (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES); + test(thd->variables.sql_mode & + (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)); thd->transaction.stmt.modified_non_trans_table= FALSE; /* Save the value in the field. Convert the value if needed. */ @@ -843,6 +843,8 @@ sp_head::create_result_field(uint field_max_length, const char *field_name, m_return_field_def.interval, field_name ? field_name : (const char *) m_name.str); + field->vcol_info= m_return_field_def.vcol_info; + field->stored_in_db= m_return_field_def.stored_in_db; if (field) field->init(table); @@ -1384,7 +1386,10 @@ sp_head::execute(THD *thd) If the DB has changed, the pointer has changed too, but the original thd->db will then have been freed */ - if (cur_db_changed && thd->killed != THD::KILL_CONNECTION) + if (cur_db_changed && + thd->killed != THD::KILL_CONNECTION && + thd->killed != THD::KILL_SERVER && + thd->killed != THD::KILL_SYSTEM_THREAD) { /* Force switching back to the saved current database, because it may be @@ -2123,6 +2128,8 @@ sp_head::reset_lex(THD *thd) sublex->dec= NULL; sublex->interval_list.empty(); sublex->type= 0; + sublex->uint_geom_type= 0; + sublex->vcol_info= 0; DBUG_RETURN(FALSE); } @@ -2249,7 +2256,8 @@ sp_head::fill_field_definition(THD *thd, LEX *lex, &lex->interval_list, lex->charset ? lex->charset : thd->variables.collation_database, - lex->uint_geom_type)) + lex->uint_geom_type, + lex->vcol_info, NULL)) return TRUE; if (field_def->interval_list.elements) diff --git a/sql/sp_head.h b/sql/sp_head.h index cdf1786f2d5..29fa2ff1de2 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -30,11 +30,16 @@ @ingroup Runtime_Environment @{ */ -// Values for the type enum. This reflects the order of the enum declaration -// in the CREATE TABLE command. -#define TYPE_ENUM_FUNCTION 1 -#define TYPE_ENUM_PROCEDURE 2 -#define TYPE_ENUM_TRIGGER 3 +/* + Values for the type enum. This reflects the order of the enum declaration + in the CREATE TABLE command. +*/ +enum stored_procedure_type +{ + TYPE_ENUM_FUNCTION=1, + TYPE_ENUM_PROCEDURE=2, + TYPE_ENUM_TRIGGER=3 +}; Item_result sp_map_result_type(enum enum_field_types type); @@ -136,9 +141,9 @@ public: // Init. the qualified name from the db and name. void init_qname(THD *thd); // thd for memroot allocation - void set_routine_type(char type) + void set_routine_type(stored_procedure_type type) { - m_sroutines_key.str[0]= type; + m_sroutines_key.str[0]= (char) type; } ~sp_name() @@ -172,8 +177,7 @@ public: HAS_SQLCOM_FLUSH= 4096 }; - /** TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */ - int m_type; + stored_procedure_type m_type; uint m_flags; // Boolean attributes of a stored routine Create_field m_return_field_def; /**< This is used for FUNCTIONs only. */ diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index ee33b6f5325..2558055eda3 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -121,7 +121,7 @@ sp_rcontext::init_var_table(THD *thd) return TRUE; m_var_table->copy_blobs= TRUE; - m_var_table->alias= ""; + m_var_table->alias.set("", 0, table_alias_charset); return FALSE; } diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 8da0a4bee82..15815e496dd 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -281,7 +281,7 @@ public: int close(THD *thd); - inline my_bool + inline bool is_open() { return test(server_side_cursor); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 89b70032642..0953af75b9c 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -31,6 +31,8 @@ #include <stdarg.h> #include "sp_head.h" #include "sp.h" +#include <sql_common.h> +#include <mysql/plugin_auth.h> static const TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = { @@ -149,6 +151,87 @@ TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = { const TABLE_FIELD_DEF mysql_db_table_def= {MYSQL_DB_FIELD_COUNT, mysql_db_table_fields}; +static LEX_STRING native_password_plugin_name= { + C_STRING_WITH_LEN("mysql_native_password") +}; + +static LEX_STRING old_password_plugin_name= { + C_STRING_WITH_LEN("mysql_old_password") +}; + +/// @todo make it configurable +LEX_STRING *default_auth_plugin_name= &native_password_plugin_name; + +static plugin_ref native_password_plugin; +#ifndef NO_EMBEDDED_ACCESS_CHECKS +static plugin_ref old_password_plugin; +#endif + +/* Classes */ + +struct acl_host_and_ip +{ + char *hostname; + long ip,ip_mask; // Used with masked ip:s +}; + +class ACL_ACCESS { +public: + ulong sort; + ulong access; +}; + +/* ACL_HOST is used if no host is specified */ + +class ACL_HOST :public ACL_ACCESS +{ +public: + acl_host_and_ip host; + char *db; +}; + +class ACL_USER :public ACL_ACCESS +{ +public: + acl_host_and_ip host; + uint hostname_length; + USER_RESOURCES user_resource; + char *user; + uint8 salt[SCRAMBLE_LENGTH+1]; // scrambled password in binary form + uint8 salt_len; // 0 - no password, 4 - 3.20, 8 - 4.0, 20 - 4.1.1 + enum SSL_type ssl_type; + const char *ssl_cipher, *x509_issuer, *x509_subject; + LEX_STRING plugin; + LEX_STRING auth_string; + + ACL_USER *copy(MEM_ROOT *root) + { + ACL_USER *dst= (ACL_USER *)alloc_root(root, sizeof(ACL_USER)); + if (!dst) + return 0; + *dst= *this; + dst->user= safe_strdup_root(root, user); + dst->ssl_cipher= safe_strdup_root(root, ssl_cipher); + dst->x509_issuer= safe_strdup_root(root, x509_issuer); + dst->x509_subject= safe_strdup_root(root, x509_subject); + if (plugin.str == native_password_plugin_name.str || + plugin.str == old_password_plugin_name.str) + dst->plugin= plugin; + else + dst->plugin.str= strmake_root(root, plugin.str, plugin.length); + dst->auth_string.str = safe_strdup_root(root, auth_string.str); + dst->host.hostname= safe_strdup_root(root, host.hostname); + return dst; + } +}; + +class ACL_DB :public ACL_ACCESS +{ +public: + acl_host_and_ip host; + char *user,*db; +}; + #ifndef NO_EMBEDDED_ACCESS_CHECKS #define FIRST_NON_YN_FIELD 26 @@ -172,6 +255,24 @@ static uchar* acl_entry_get_key(acl_entry *entry, size_t *length, #define IP_ADDR_STRLEN (3+1+3+1+3+1+3) #define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1) +#if defined(HAVE_OPENSSL) +/* + Without SSL the handshake consists of one packet. This packet + has both client capabilites and scrambled password. + With SSL the handshake might consist of two packets. If the first + packet (client capabilities) has CLIENT_SSL flag set, we have to + switch to SSL and read the second packet. The scrambled password + is in the second packet and client_capabilites field will be ignored. + Maybe it is better to accept flags other than CLIENT_SSL from the + second packet? +*/ +#define SSL_HANDSHAKE_SIZE 2 +#define NORMAL_HANDSHAKE_SIZE 6 +#define MIN_HANDSHAKE_SIZE 2 +#else +#define MIN_HANDSHAKE_SIZE 6 +#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ + static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs; static MEM_ROOT mem, memex; static bool initialized=0; @@ -187,9 +288,8 @@ static void init_check_host(void); static void rebuild_check_host(void); static ACL_USER *find_acl_user(const char *host, const char *user, my_bool exact); -static bool update_user_table(THD *thd, TABLE *table, - const char *host, const char *user, - const char *new_password, uint new_password_len); +static bool update_user_table(THD *, TABLE *, const char *, const char *, + const char *, uint); static void update_hostname(acl_host_and_ip *host, const char *hostname); static bool compare_hostname(const acl_host_and_ip *host,const char *hostname, const char *ip); @@ -220,6 +320,48 @@ set_user_salt(ACL_USER *acl_user, const char *password, uint password_len) acl_user->salt_len= 0; } +static char *fix_plugin_ptr(char *name) +{ + if (my_strcasecmp(system_charset_info, name, + native_password_plugin_name.str) == 0) + return native_password_plugin_name.str; + else + if (my_strcasecmp(system_charset_info, name, + old_password_plugin_name.str) == 0) + return old_password_plugin_name.str; + else + return name; +} + +/** + Fix ACL::plugin pointer to point to a hard-coded string, if appropriate + + Make sure that if ACL_USER's plugin is a built-in, then it points + to a hard coded string, not to an allocated copy. Run-time, for + authentication, we want to be able to detect built-ins by comparing + pointers, not strings. + + Additionally - update the salt if the plugin is built-in. + + @retval 0 the pointers were fixed + @retval 1 this ACL_USER uses a not built-in plugin +*/ +static bool fix_user_plugin_ptr(ACL_USER *user) +{ + if (my_strcasecmp(system_charset_info, user->plugin.str, + native_password_plugin_name.str) == 0) + user->plugin= native_password_plugin_name; + else + if (my_strcasecmp(system_charset_info, user->plugin.str, + old_password_plugin_name.str) == 0) + user->plugin= old_password_plugin_name; + else + return true; + + set_user_salt(user, user->auth_string.str, user->auth_string.length); + return false; +} + /* This after_update function is used when user.password is less than SCRAMBLE_LENGTH bytes. @@ -267,6 +409,19 @@ my_bool acl_init(bool dont_read_acl_tables) (hash_get_key) acl_entry_get_key, (hash_free_key) free, &my_charset_utf8_bin); + + /* + cache built-in native authentication plugins, + to avoid hash searches and a global mutex lock on every connect + */ + native_password_plugin= my_plugin_lock_by_name(0, + &native_password_plugin_name, MYSQL_AUTHENTICATION_PLUGIN); + old_password_plugin= my_plugin_lock_by_name(0, + &old_password_plugin_name, MYSQL_AUTHENTICATION_PLUGIN); + + if (!native_password_plugin || !old_password_plugin) + DBUG_RETURN(1); + if (dont_read_acl_tables) { DBUG_RETURN(0); /* purecov: tested */ @@ -326,8 +481,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) acl_cache->clear(1); // Clear locked hostname cache init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0); - init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0, - FALSE); + if (init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0, + FALSE)) + goto end; + table->use_all_columns(); VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); while (!(read_record_info.read_record(&read_record_info))) @@ -376,7 +533,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) end_read_record(&read_record_info); freeze_size(&acl_hosts); - init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0,FALSE); + if (init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0, + FALSE)) + goto end; + table->use_all_columns(); VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100)); password_length= table->field[2]->field_length / @@ -424,6 +584,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) while (!(read_record_info.read_record(&read_record_info))) { ACL_USER user; + char *password; + uint password_len; + + bzero(&user, sizeof(user)); update_hostname(&user.host, get_field(&mem, table->field[0])); user.user= get_field(&mem, table->field[1]); if (check_no_resolve && hostname_requires_resolving(user.host.hostname)) @@ -435,27 +599,34 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) continue; } - const char *password= get_field(thd->mem_root, table->field[2]); - uint password_len= password ? strlen(password) : 0; + password= get_field(&mem, table->field[2]); + password_len= password ? strlen(password) : 0; + user.auth_string.str= password ? password : const_cast<char*>(""); + user.auth_string.length= password_len; set_user_salt(&user, password, password_len); - if (user.salt_len == 0 && password_len != 0) - { - switch (password_len) { - case 45: /* 4.1: to be removed */ - sql_print_warning("Found 4.1 style password for user '%s@%s'. " - "Ignoring user. " - "You should change password for this user.", - user.user ? user.user : "", - user.host.hostname ? user.host.hostname : ""); - break; - default: - sql_print_warning("Found invalid password for user: '%s@%s'; " - "Ignoring user", user.user ? user.user : "", - user.host.hostname ? user.host.hostname : ""); - break; - } + + switch (password_len) { + case 0: /* no password */ + case SCRAMBLED_PASSWORD_CHAR_LENGTH: + user.plugin= native_password_plugin_name; + break; + case SCRAMBLED_PASSWORD_CHAR_LENGTH_323: + user.plugin= old_password_plugin_name; + break; + case 45: /* 4.1: to be removed */ + sql_print_warning("Found 4.1.0 style password for user '%s@%s'. " + "Ignoring user. " + "You should change password for this user.", + user.user ? user.user : "", + user.host.hostname ? user.host.hostname : ""); + continue; + default: + sql_print_warning("Found invalid password for user: '%s@%s'; " + "Ignoring user", user.user ? user.user : "", + user.host.hostname ? user.host.hostname : ""); + continue; } - else // password is correct + { uint next_field; user.access= get_access(table,3,&next_field) & GLOBAL_ACLS; @@ -532,13 +703,35 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ptr= get_field(thd->mem_root, table->field[next_field++]); user.user_resource.user_conn= ptr ? atoi(ptr) : 0; } - else - user.user_resource.user_conn= 0; + + if (table->s->fields >= 41) + { + /* We may have plugin & auth_String fields */ + char *tmpstr= get_field(&mem, table->field[next_field++]); + if (tmpstr) + { + user.plugin.str= tmpstr; + user.plugin.length= strlen(user.plugin.str); + if (user.auth_string.length) + { + sql_print_warning("'user' entry '%s@%s' has both a password " + "and an authentication plugin specified. The " + "password will be ignored.", + user.user ? user.user : "", + user.host.hostname ? user.host.hostname : ""); + } + user.auth_string.str= get_field(&mem, table->field[next_field++]); + if (!user.auth_string.str) + user.auth_string.str= const_cast<char*>(""); + user.auth_string.length= strlen(user.auth_string.str); + + fix_user_plugin_ptr(&user); + } + } } else { user.ssl_type=SSL_TYPE_NONE; - bzero((char *)&(user.user_resource),sizeof(user.user_resource)); #ifndef TO_BE_REMOVED if (table->s->fields <= 13) { // Without grant @@ -564,7 +757,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) end_read_record(&read_record_info); freeze_size(&acl_users); - init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0,FALSE); + if (init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0, + FALSE)) + goto end; + table->use_all_columns(); VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100)); while (!(read_record_info.read_record(&read_record_info))) @@ -641,6 +837,8 @@ void acl_free(bool end) delete_dynamic(&acl_dbs); delete_dynamic(&acl_wild_hosts); hash_free(&acl_check_hosts); + plugin_unlock(0, native_password_plugin); + plugin_unlock(0, old_password_plugin); if (!end) acl_cache->clear(1); /* purecov: inspected */ else @@ -843,246 +1041,10 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) /* - Seek ACL entry for a user, check password, SSL cypher, and if - everything is OK, update THD user data and USER_RESOURCES struct. - - IMPLEMENTATION - This function does not check if the user has any sensible privileges: - only user's existence and validity is checked. - Note, that entire operation is protected by acl_cache_lock. + Gets user credentials without authentication and resource limit checks. SYNOPSIS acl_getroot() - thd thread handle. If all checks are OK, - thd->security_ctx->priv_user/master_access are updated. - thd->security_ctx->host/ip/user are used for checks. - mqh user resources; on success mqh is reset, else - unchanged - passwd scrambled & crypted password, received from client - (to check): thd->scramble or thd->scramble_323 is - used to decrypt passwd, so they must contain - original random string, - passwd_len length of passwd, must be one of 0, 8, - SCRAMBLE_LENGTH_323, SCRAMBLE_LENGTH - 'thd' and 'mqh' are updated on success; other params are IN. - - RETURN VALUE - 0 success: thd->priv_user, thd->priv_host, thd->master_access, mqh are - updated - 1 user not found or authentication failure - 2 user found, has long (4.1.1) salt, but passwd is in old (3.23) format. - -1 user found, has short (3.23) salt, but passwd is in new (4.1.1) format. -*/ - -int acl_getroot(THD *thd, USER_RESOURCES *mqh, - const char *passwd, uint passwd_len) -{ - ulong user_access= NO_ACCESS; - int res= 1; - ACL_USER *acl_user= 0; - Security_context *sctx= thd->security_ctx; - DBUG_ENTER("acl_getroot"); - - if (!initialized) - { - /* - here if mysqld's been started with --skip-grant-tables option. - */ - sctx->skip_grants(); - bzero((char*) mqh, sizeof(*mqh)); - DBUG_RETURN(0); - } - - VOID(pthread_mutex_lock(&acl_cache->lock)); - - /* - Find acl entry in user database. Note, that find_acl_user is not the same, - because it doesn't take into account the case when user is not empty, - but acl_user->user is empty - */ - - for (uint i=0 ; i < acl_users.elements ; i++) - { - ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*); - if (!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user)) - { - if (compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip)) - { - /* check password: it should be empty or valid */ - if (passwd_len == acl_user_tmp->salt_len) - { - if (acl_user_tmp->salt_len == 0 || - (acl_user_tmp->salt_len == SCRAMBLE_LENGTH ? - check_scramble(passwd, thd->scramble, acl_user_tmp->salt) : - check_scramble_323(passwd, thd->scramble, - (ulong *) acl_user_tmp->salt)) == 0) - { - acl_user= acl_user_tmp; - res= 0; - } - } - else if (passwd_len == SCRAMBLE_LENGTH && - acl_user_tmp->salt_len == SCRAMBLE_LENGTH_323) - res= -1; - else if (passwd_len == SCRAMBLE_LENGTH_323 && - acl_user_tmp->salt_len == SCRAMBLE_LENGTH) - res= 2; - /* linear search complete: */ - break; - } - } - } - /* - This was moved to separate tree because of heavy HAVE_OPENSSL case. - If acl_user is not null, res is 0. - */ - - if (acl_user) - { - /* OK. User found and password checked continue validation */ -#ifdef HAVE_OPENSSL - Vio *vio=thd->net.vio; - SSL *ssl= (SSL*) vio->ssl_arg; - X509 *cert; -#endif - - /* - At this point we know that user is allowed to connect - from given host by given username/password pair. Now - we check if SSL is required, if user is using SSL and - if X509 certificate attributes are OK - */ - switch (acl_user->ssl_type) { - case SSL_TYPE_NOT_SPECIFIED: // Impossible - case SSL_TYPE_NONE: // SSL is not required - user_access= acl_user->access; - break; -#ifdef HAVE_OPENSSL - case SSL_TYPE_ANY: // Any kind of SSL is ok - if (vio_type(vio) == VIO_TYPE_SSL) - user_access= acl_user->access; - break; - case SSL_TYPE_X509: /* Client should have any valid certificate. */ - /* - Connections with non-valid certificates are dropped already - in sslaccept() anyway, so we do not check validity here. - - We need to check for absence of SSL because without SSL - we should reject connection. - */ - if (vio_type(vio) == VIO_TYPE_SSL && - SSL_get_verify_result(ssl) == X509_V_OK && - (cert= SSL_get_peer_certificate(ssl))) - { - user_access= acl_user->access; - X509_free(cert); - } - break; - case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */ - /* - We do not check for absence of SSL because without SSL it does - not pass all checks here anyway. - If cipher name is specified, we compare it to actual cipher in - use. - */ - if (vio_type(vio) != VIO_TYPE_SSL || - SSL_get_verify_result(ssl) != X509_V_OK) - break; - if (acl_user->ssl_cipher) - { - DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'", - acl_user->ssl_cipher,SSL_get_cipher(ssl))); - if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(ssl))) - user_access= acl_user->access; - else - { - if (global_system_variables.log_warnings) - sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'", - acl_user->ssl_cipher, - SSL_get_cipher(ssl)); - break; - } - } - /* Prepare certificate (if exists) */ - DBUG_PRINT("info",("checkpoint 1")); - if (!(cert= SSL_get_peer_certificate(ssl))) - { - user_access=NO_ACCESS; - break; - } - DBUG_PRINT("info",("checkpoint 2")); - /* If X509 issuer is specified, we check it... */ - if (acl_user->x509_issuer) - { - DBUG_PRINT("info",("checkpoint 3")); - char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); - DBUG_PRINT("info",("comparing issuers: '%s' and '%s'", - acl_user->x509_issuer, ptr)); - if (strcmp(acl_user->x509_issuer, ptr)) - { - if (global_system_variables.log_warnings) - sql_print_information("X509 issuer mismatch: should be '%s' " - "but is '%s'", acl_user->x509_issuer, ptr); - free(ptr); - X509_free(cert); - user_access=NO_ACCESS; - break; - } - user_access= acl_user->access; - free(ptr); - } - DBUG_PRINT("info",("checkpoint 4")); - /* X509 subject is specified, we check it .. */ - if (acl_user->x509_subject) - { - char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); - DBUG_PRINT("info",("comparing subjects: '%s' and '%s'", - acl_user->x509_subject, ptr)); - if (strcmp(acl_user->x509_subject,ptr)) - { - if (global_system_variables.log_warnings) - sql_print_information("X509 subject mismatch: should be '%s' but is '%s'", - acl_user->x509_subject, ptr); - free(ptr); - X509_free(cert); - user_access=NO_ACCESS; - break; - } - user_access= acl_user->access; - free(ptr); - } - /* Deallocate the X509 certificate. */ - X509_free(cert); - break; -#else /* HAVE_OPENSSL */ - default: - /* - If we don't have SSL but SSL is required for this user the - authentication should fail. - */ - break; -#endif /* HAVE_OPENSSL */ - } - sctx->master_access= user_access; - sctx->priv_user= acl_user->user ? sctx->user : (char *) ""; - *mqh= acl_user->user_resource; - - if (acl_user->host.hostname) - strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1); - else - *sctx->priv_host= 0; - } - VOID(pthread_mutex_unlock(&acl_cache->lock)); - DBUG_RETURN(res); -} - - -/* - This is like acl_getroot() above, but it doesn't check password, - and we don't care about the user resources. - - SYNOPSIS - acl_getroot_no_password() sctx Context which should be initialized user user name host host name @@ -1094,13 +1056,13 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, TRUE Error */ -bool acl_getroot_no_password(Security_context *sctx, char *user, char *host, - char *ip, char *db) +bool acl_getroot(Security_context *sctx, char *user, char *host, + char *ip, char *db) { int res= 1; uint i; ACL_USER *acl_user= 0; - DBUG_ENTER("acl_getroot_no_password"); + DBUG_ENTER("acl_getroot"); DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', db: '%s'", (host ? host : "(NULL)"), (ip ? ip : "(NULL)"), @@ -1123,8 +1085,7 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host, sctx->master_access= 0; sctx->db_access= 0; - sctx->priv_user= (char *) ""; - *sctx->priv_host= 0; + *sctx->priv_user= *sctx->priv_host= 0; /* Find acl entry in user database. @@ -1166,7 +1127,11 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host, } } sctx->master_access= acl_user->access; - sctx->priv_user= acl_user->user ? user : (char *) ""; + + if (acl_user->user) + strmake(sctx->priv_user, user, USERNAME_LENGTH); + else + *sctx->priv_user= 0; if (acl_user->host.hostname) strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1); @@ -1192,7 +1157,9 @@ static void acl_update_user(const char *user, const char *host, const char *x509_issuer, const char *x509_subject, USER_RESOURCES *mqh, - ulong privileges) + ulong privileges, + const LEX_STRING *plugin, + const LEX_STRING *auth) { safe_mutex_assert_owner(&acl_cache->lock); @@ -1206,6 +1173,22 @@ static void acl_update_user(const char *user, const char *host, (acl_user->host.hostname && !my_strcasecmp(system_charset_info, host, acl_user->host.hostname))) { + if (plugin->str[0]) + { + acl_user->plugin= *plugin; + acl_user->auth_string.str= auth->str ? + strmake_root(&mem, auth->str, auth->length) : const_cast<char*>(""); + acl_user->auth_string.length= auth->length; + if (fix_user_plugin_ptr(acl_user)) + acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length); + } + else + if (password) + { + acl_user->auth_string.str= strmake_root(&mem, password, password_len); + acl_user->auth_string.length= password_len; + set_user_salt(acl_user, password, password_len); + } acl_user->access=privileges; if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR) acl_user->user_resource.questions=mqh->questions; @@ -1225,8 +1208,6 @@ static void acl_update_user(const char *user, const char *host, acl_user->x509_subject= (x509_subject ? strdup_root(&mem,x509_subject) : 0); } - if (password) - set_user_salt(acl_user, password, password_len); /* search complete: */ break; } @@ -1242,7 +1223,9 @@ static void acl_insert_user(const char *user, const char *host, const char *x509_issuer, const char *x509_subject, USER_RESOURCES *mqh, - ulong privileges) + ulong privileges, + const LEX_STRING *plugin, + const LEX_STRING *auth) { ACL_USER acl_user; @@ -1250,6 +1233,24 @@ static void acl_insert_user(const char *user, const char *host, acl_user.user=*user ? strdup_root(&mem,user) : 0; update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0); + if (plugin->str[0]) + { + acl_user.plugin= *plugin; + acl_user.auth_string.str= auth->str ? + strmake_root(&mem, auth->str, auth->length) : const_cast<char*>(""); + acl_user.auth_string.length= auth->length; + if (fix_user_plugin_ptr(&acl_user)) + acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length); + } + else + { + acl_user.plugin= password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 ? + old_password_plugin_name : native_password_plugin_name; + acl_user.auth_string.str= strmake_root(&mem, password, password_len); + acl_user.auth_string.length= password_len; + set_user_salt(&acl_user, password, password_len); + } + acl_user.access=privileges; acl_user.user_resource = *mqh; acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user); @@ -1260,8 +1261,6 @@ static void acl_insert_user(const char *user, const char *host, acl_user.x509_issuer= x509_issuer ? strdup_root(&mem,x509_issuer) : 0; acl_user.x509_subject=x509_subject ? strdup_root(&mem,x509_subject) : 0; - set_user_salt(&acl_user, password, password_len); - VOID(push_dynamic(&acl_users,(uchar*) &acl_user)); if (!acl_user.host.hostname || (acl_user.host.hostname[0] == wild_many && !acl_user.host.hostname[1])) @@ -1648,7 +1647,13 @@ bool change_password(THD *thd, const char *host, const char *user, goto end; } /* update loaded acl entry: */ - set_user_salt(acl_user, new_password, new_password_len); + if (acl_user->plugin.str == native_password_plugin_name.str || + acl_user->plugin.str == old_password_plugin_name.str) + { + acl_user->auth_string.str= strmake_root(&mem, new_password, new_password_len); + acl_user->auth_string.length= new_password_len; + set_user_salt(acl_user, new_password, new_password_len); + } if (update_user_table(thd, table, acl_user->host.hostname ? acl_user->host.hostname : "", @@ -1856,9 +1861,9 @@ static bool update_user_table(THD *thd, TABLE *table, key_copy((uchar *) user_key, table->record[0], table->key_info, table->key_info->key_length); - if (table->file->index_read_idx_map(table->record[0], 0, - (uchar *) user_key, HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar *) user_key, HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) { my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0)); /* purecov: deadcode */ @@ -1949,9 +1954,9 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, key_copy(user_key, table->record[0], table->key_info, table->key_info->key_length); - if (table->file->index_read_idx_map(table->record[0], 0, user_key, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_idx_map(table->record[0], 0, user_key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) { /* what == 'N' means revoke */ if (what == 'N') @@ -1982,6 +1987,15 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0)); goto end; } + else if (combo.plugin.str[0]) + { + if (!plugin_is_ready(&combo.plugin, MYSQL_AUTHENTICATION_PLUGIN)) + { + my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), combo.plugin.str); + goto end; + } + } + old_row_exists = 0; restore_record(table,s->default_values); table->field[0]->store(combo.host.str,combo.host.length, @@ -1995,7 +2009,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, { old_row_exists = 1; store_record(table,record[1]); // Save copy for update - if (combo.password.str) // If password given + if (combo.password.str) // If password given table->field[2]->store(password, password_len, system_charset_info); else if (!rights && !revoke_grant && lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && @@ -2076,7 +2090,17 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, (mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS)) table->field[next_field+3]->store((longlong) mqh.user_conn, TRUE); mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour; + + next_field+=4; + if (table->s->fields >= 41 && combo.plugin.str[0]) + { + table->field[next_field]->store(combo.plugin.str, combo.plugin.length, + system_charset_info); + table->field[next_field+1]->store(combo.auth.str, combo.auth.length, + system_charset_info); + } } + if (old_row_exists) { /* @@ -2120,7 +2144,9 @@ end: lex->x509_issuer, lex->x509_subject, &lex->mqh, - rights); + rights, + &combo.plugin, + &combo.auth); else acl_insert_user(combo.user.str, combo.host.str, password, password_len, lex->ssl_type, @@ -2128,7 +2154,9 @@ end: lex->x509_issuer, lex->x509_subject, &lex->mqh, - rights); + rights, + &combo.plugin, + &combo.auth); } DBUG_RETURN(error); } @@ -2172,9 +2200,9 @@ static int replace_db_table(TABLE *table, const char *db, key_copy(user_key, table->record[0], table->key_info, table->key_info->key_length); - if (table->file->index_read_idx_map(table->record[0],0, user_key, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_idx_map(table->record[0],0, user_key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) { if (what == 'N') { // no row, no revoke @@ -2406,8 +2434,9 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) col_privs->field[4]->store("",0, &my_charset_latin1); col_privs->file->ha_index_init(0, 1); - if (col_privs->file->index_read_map(col_privs->record[0], (uchar*) key, - (key_part_map)15, HA_READ_KEY_EXACT)) + if (col_privs->file->ha_index_read_map(col_privs->record[0], (uchar*) key, + (key_part_map)15, + HA_READ_KEY_EXACT)) { cols = 0; /* purecov: deadcode */ col_privs->file->ha_index_end(); @@ -2433,7 +2462,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) privs= cols= 0; return; } - } while (!col_privs->file->index_next(col_privs->record[0]) && + } while (!col_privs->file->ha_index_next(col_privs->record[0]) && !key_cmp_if_same(col_privs,key,0,key_prefix_len)); col_privs->file->ha_index_end(); } @@ -2577,8 +2606,8 @@ static int replace_column_table(GRANT_TABLE *g_t, key_copy(user_key, table->record[0], table->key_info, table->key_info->key_length); - if (table->file->index_read_map(table->record[0], user_key, HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_map(table->record[0], user_key, + HA_WHOLE_KEY, HA_READ_KEY_EXACT)) { if (revoke_grant) { @@ -2659,9 +2688,9 @@ static int replace_column_table(GRANT_TABLE *g_t, key_copy(user_key, table->record[0], table->key_info, key_prefix_length); - if (table->file->index_read_map(table->record[0], user_key, - (key_part_map)15, - HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_map(table->record[0], user_key, + (key_part_map)15, + HA_READ_KEY_EXACT)) goto end; /* Scan through all rows with the same host,db,user and table */ @@ -2712,7 +2741,7 @@ static int replace_column_table(GRANT_TABLE *g_t, hash_delete(&g_t->hash_columns,(uchar*) grant_column); } } - } while (!table->file->index_next(table->record[0]) && + } while (!table->file->ha_index_next(table->record[0]) && !key_cmp_if_same(table, key, 0, key_prefix_length)); } @@ -2774,9 +2803,9 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, key_copy(user_key, table->record[0], table->key_info, table->key_info->key_length); - if (table->file->index_read_idx_map(table->record[0], 0, user_key, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_idx_map(table->record[0], 0, user_key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) { /* The following should never happen as we first check the in memory @@ -2899,10 +2928,10 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, TRUE); store_record(table,record[1]); // store at pos 1 - if (table->file->index_read_idx_map(table->record[0], 0, - (uchar*) table->field[0]->ptr, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar*) table->field[0]->ptr, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) { /* The following should never happen as we first check the in memory @@ -3646,7 +3675,7 @@ static my_bool grant_load_procs_priv(TABLE *p_table) p_table->file->ha_index_init(0, 1); p_table->use_all_columns(); - if (!p_table->file->index_first(p_table->record[0])) + if (!p_table->file->ha_index_first(p_table->record[0])) { memex_ptr= &memex; my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr); @@ -3698,7 +3727,7 @@ static my_bool grant_load_procs_priv(TABLE *p_table) goto end_unlock; } } - while (!p_table->file->index_next(p_table->record[0])); + while (!p_table->file->ha_index_next(p_table->record[0])); } /* Return ok */ return_val= 0; @@ -3748,7 +3777,7 @@ static my_bool grant_load(THD *thd, TABLE_LIST *tables) t_table->use_all_columns(); c_table->use_all_columns(); - if (!t_table->file->index_first(t_table->record[0])) + if (!t_table->file->ha_index_first(t_table->record[0])) { memex_ptr= &memex; my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr); @@ -3783,7 +3812,7 @@ static my_bool grant_load(THD *thd, TABLE_LIST *tables) goto end_unlock; } } - while (!t_table->file->index_next(t_table->record[0])); + while (!t_table->file->ha_index_next(t_table->record[0])); } return_val=0; // Return ok @@ -4055,6 +4084,8 @@ err: { char command[128]; get_privilege_desc(command, sizeof(command), want_access); + status_var_increment(thd->status_var.access_denied_errors); + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), command, sctx->priv_user, @@ -4468,16 +4499,14 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name, ulong get_table_grant(THD *thd, TABLE_LIST *table) { ulong privilege; -#ifndef EMBEDDED_LIBRARY - Security_context *sctx= thd->security_ctx; - const char *db = table->db ? table->db : thd->db; -#endif GRANT_TABLE *grant_table; rw_rdlock(&LOCK_grant); #ifdef EMBEDDED_LIBRARY grant_table= NULL; #else + Security_context *sctx= thd->security_ctx; + const char *db = table->db ? table->db : thd->db; grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user, table->table_name, 0); #endif @@ -4670,16 +4699,27 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append(lex_user->host.str,lex_user->host.length, system_charset_info); global.append ('\''); - if (acl_user->salt_len) + if (acl_user->plugin.str == native_password_plugin_name.str || + acl_user->plugin.str == old_password_plugin_name.str) { - char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1]; - if (acl_user->salt_len == SCRAMBLE_LENGTH) - make_password_from_salt(passwd_buff, acl_user->salt); - else - make_password_from_salt_323(passwd_buff, (ulong *) acl_user->salt); - global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '")); - global.append(passwd_buff); - global.append('\''); + if (acl_user->auth_string.length) + { + DBUG_ASSERT(acl_user->salt_len); + global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '")); + global.append(acl_user->auth_string.str, acl_user->auth_string.length); + global.append('\''); + } + } + else + { + global.append(STRING_WITH_LEN(" IDENTIFIED VIA ")); + global.append(acl_user->plugin.str, acl_user->plugin.length); + if (acl_user->auth_string.length) + { + global.append(STRING_WITH_LEN(" USING '")); + global.append(acl_user->auth_string.str, acl_user->auth_string.length); + global.append('\''); + } } /* "show grants" SSL related stuff */ if (acl_user->ssl_type == SSL_TYPE_ANY) @@ -5302,9 +5342,9 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop, table->key_info->key_part[1].store_length); key_copy(user_key, table->record[0], table->key_info, key_prefix_length); - if ((error= table->file->index_read_idx_map(table->record[0], 0, - user_key, (key_part_map)3, - HA_READ_KEY_EXACT))) + if ((error= table->file->ha_index_read_idx_map(table->record[0], 0, + user_key, (key_part_map)3, + HA_READ_KEY_EXACT))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) { @@ -5339,7 +5379,7 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop, DBUG_PRINT("info",("scan table: '%s' search: '%s'@'%s'", table->s->table_name.str, user_str, host_str)); #endif - while ((error= table->file->rnd_next(table->record[0])) != + while ((error= table->file->ha_rnd_next(table->record[0])) != HA_ERR_END_OF_FILE) { if (error) @@ -6392,38 +6432,44 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, tables->db= (char*)sp_db; tables->table_name= tables->alias= (char*)sp_name; - combo->host.length= strlen(combo->host.str); - combo->user.length= strlen(combo->user.str); - combo->host.str= thd->strmake(combo->host.str,combo->host.length); - combo->user.str= thd->strmake(combo->user.str,combo->user.length); + thd->make_lex_string(&combo->user, + combo->user.str, strlen(combo->user.str), 0); + thd->make_lex_string(&combo->host, + combo->host.str, strlen(combo->host.str), 0); + combo->password= empty_lex_str; + combo->plugin= empty_lex_str; + combo->auth= empty_lex_str; - if(au && au->salt_len) + if(au) { - if (au->salt_len == SCRAMBLE_LENGTH) - { - make_password_from_salt(passwd_buff, au->salt); - combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH; - } - else if (au->salt_len == SCRAMBLE_LENGTH_323) + if (au->salt_len) { - make_password_from_salt_323(passwd_buff, (ulong *) au->salt); - combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; + if (au->salt_len == SCRAMBLE_LENGTH) + { + make_password_from_salt(passwd_buff, au->salt); + combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH; + } + else if (au->salt_len == SCRAMBLE_LENGTH_323) + { + make_password_from_salt_323(passwd_buff, (ulong *) au->salt); + combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; + } + else + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_PASSWD_LENGTH, + ER(ER_PASSWD_LENGTH), SCRAMBLED_PASSWORD_CHAR_LENGTH); + return TRUE; + } + combo->password.str= passwd_buff; } - else + + if (au->plugin.str != native_password_plugin_name.str && + au->plugin.str != old_password_plugin_name.str) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_PASSWD_LENGTH, - ER(ER_PASSWD_LENGTH), - SCRAMBLED_PASSWORD_CHAR_LENGTH); - return TRUE; + combo->plugin= au->plugin; + combo->auth= au->auth_string; } - combo->password.str= passwd_buff; - } - else - { - combo->password.str= (char*)""; - combo->password.length= 0; } if (user_list.push_back(combo)) @@ -6917,3 +6963,1487 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name, } #endif + +/**************************************************************************** + AUTHENTICATION CODE + including initial connect handshake, invoking appropriate plugins, + client-server plugin negotiation, COM_CHANGE_USER, and native + MySQL authentication plugins. +****************************************************************************/ + +/* few defines to have less ifdef's in the code below */ +#ifdef EMBEDDED_LIBRARY +#undef HAVE_OPENSSL +#ifdef NO_EMBEDDED_ACCESS_CHECKS +#define initialized 0 +#define check_for_max_user_connections(X,Y) 0 +#define get_or_create_user_conn(A,B,C,D) 0 +#endif +#endif +#ifndef HAVE_OPENSSL +#define ssl_acceptor_fd 0 +#define sslaccept(A,B,C,D) 1 +#define NORMAL_HANDSHAKE_SIZE 6 +#endif + +/** + The internal version of what plugins know as MYSQL_PLUGIN_VIO, + basically the context of the authentication session +*/ +struct MPVIO_EXT : public MYSQL_PLUGIN_VIO +{ + MYSQL_SERVER_AUTH_INFO auth_info; + THD *thd; + ACL_USER *acl_user; ///< a copy, independent from acl_users array + plugin_ref plugin; ///< what plugin we're under + LEX_STRING db; ///< db name from the handshake packet + /** when restarting a plugin this caches the last client reply */ + struct { + char *plugin, *pkt; ///< pointers into NET::buff + uint pkt_len; + } cached_client_reply; + /** this caches the first plugin packet for restart request on the client */ + struct { + char *pkt; + uint pkt_len; + } cached_server_packet; + int packets_read, packets_written; ///< counters for send/received packets + uint connect_errors; ///< if there were connect errors for this host + /** when plugin returns a failure this tells us what really happened */ + enum { SUCCESS, FAILURE, RESTART } status; +}; + + +/** + a helper function to report an access denied error in all the proper places +*/ + +static void login_failed_error(THD *thd) +{ + my_error(ER_ACCESS_DENIED_ERROR, MYF(0), + thd->main_security_ctx.user, + thd->main_security_ctx.host_or_ip, + thd->password ? ER(ER_YES) : ER(ER_NO)); + general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR), + thd->main_security_ctx.user, + thd->main_security_ctx.host_or_ip, + thd->password ? ER(ER_YES) : ER(ER_NO)); + status_var_increment(thd->status_var.access_denied_errors); + /* + Log access denied messages to the error log when log-warnings = 2 + so that the overhead of the general query log is not required to track + failed connections. + */ + if (global_system_variables.log_warnings > 1) + { + sql_print_warning(ER(ER_ACCESS_DENIED_ERROR), + thd->main_security_ctx.user, + thd->main_security_ctx.host_or_ip, + thd->password ? ER(ER_YES) : ER(ER_NO)); + } +} + + +/** + sends a server handshake initialization packet, the very first packet + after the connection was established + + Packet format: + + Bytes Content + ----- ---- + 1 protocol version (always 10) + n server version string, \0-terminated + 4 thread id + 8 first 8 bytes of the plugin provided data (scramble) + 1 \0 byte, terminating the first part of a scramble + 2 server capabilities (two lower bytes) + 1 server character set + 2 server status + 2 server capabilities (two upper bytes) + 1 length of the scramble + 10 reserved, always 0 + n rest of the plugin provided data (at least 12 bytes) + 1 \0 byte, terminating the second part of a scramble + + @retval 0 ok + @retval 1 error +*/ + +static bool send_server_handshake_packet(MPVIO_EXT *mpvio, + const char *data, uint data_len) +{ + DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE); + DBUG_ASSERT(data_len <= 255); + + THD *thd= mpvio->thd; + char *buff= (char *)my_alloca(1 + SERVER_VERSION_LENGTH + 1 + data_len + 64); + char scramble_buf[SCRAMBLE_LENGTH]; + char *end= buff; + + *end++= protocol_version; + + thd->client_capabilities= CLIENT_BASIC_FLAGS; + + if (data_len) + { + mpvio->cached_server_packet.pkt= (char*)thd->memdup(data, data_len); + mpvio->cached_server_packet.pkt_len= data_len; + } + + if (data_len < SCRAMBLE_LENGTH) + { + if (data_len) + { /* + the first packet *must* have at least 20 bytes of a scramble. + if a plugin provided less, we pad it to 20 with zeros + */ + memcpy(scramble_buf, data, data_len); + bzero(scramble_buf+data_len, SCRAMBLE_LENGTH-data_len); + data= scramble_buf; + } + else + { + /* + if the default plugin does not provide the data for the scramble at + all, we generate a scramble internally anyway, just in case the + user account (that will be known only later) uses a + native_password_plugin (which needs a scramble). If we don't send a + scramble now - wasting 20 bytes in the packet - + native_password_plugin will have to send it in a separate packet, + adding one more round trip. + */ + create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); + data= thd->scramble; + } + data_len= SCRAMBLE_LENGTH; + } + + if (opt_using_transactions) + thd->client_capabilities|= CLIENT_TRANSACTIONS; + + thd->client_capabilities|= CAN_CLIENT_COMPRESS; + + if (ssl_acceptor_fd) + { + thd->client_capabilities |= CLIENT_SSL; + thd->client_capabilities |= CLIENT_SSL_VERIFY_SERVER_CERT; + } + + end= strnmov(end, server_version, SERVER_VERSION_LENGTH) + 1; + int4store((uchar*) end, mpvio->thd->thread_id); + end+= 4; + + /* + Old clients does not understand long scrambles, but can ignore packet + tail: that's why first part of the scramble is placed here, and second + part at the end of packet. + */ + end= (char*)memcpy(end, data, SCRAMBLE_LENGTH_323); + end+= SCRAMBLE_LENGTH_323; + *end++= 0; + + int2store(end, thd->client_capabilities); + /* write server characteristics: up to 16 bytes allowed */ + end[2]=(char) default_charset_info->number; + int2store(end+3, mpvio->thd->server_status); + int2store(end+5, thd->client_capabilities >> 16); + end[7]= data_len; + bzero(end+8, 10); + end+= 18; + /* write scramble tail */ + end= (char*)memcpy(end, data + SCRAMBLE_LENGTH_323, + data_len - SCRAMBLE_LENGTH_323); + end+= data_len - SCRAMBLE_LENGTH_323; + end= strmake(end, plugin_name(mpvio->plugin)->str, + plugin_name(mpvio->plugin)->length); + + int res= my_net_write(&mpvio->thd->net, (uchar*) buff, (size_t) (end-buff)) || + net_flush(&mpvio->thd->net); + my_afree(buff); + return res; +} + +static bool secure_auth(THD *thd) +{ + if (!opt_secure_auth) + return 0; + + /* + If the server is running in secure auth mode, short scrambles are + forbidden. Extra juggling to report the same error as the old code. + */ + if (thd->client_capabilities & CLIENT_PROTOCOL_41) + { + my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0), + thd->security_ctx->user, + thd->security_ctx->host_or_ip); + general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE), + thd->security_ctx->user, + thd->security_ctx->host_or_ip); + } + else + { + my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); + general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); + } + return 1; +} + +/** + sends a "change plugin" packet, requesting a client to restart authentication + using a different authentication plugin + + Packet format: + + Bytes Content + ----- ---- + 1 byte with the value 254 + n client plugin to use, \0-terminated + n plugin provided data + + In a special case of switching from native_password_plugin to + old_password_plugin, the packet contains only one - the first - byte, + plugin name is omitted, plugin data aren't needed as the scramble was + already sent. This one-byte packet is identical to the "use the short + scramble" packet in the protocol before plugins were introduced. + + @retval 0 ok + @retval 1 error +*/ + +static bool send_plugin_request_packet(MPVIO_EXT *mpvio, + const uchar *data, uint data_len) +{ + DBUG_ASSERT(mpvio->packets_written == 1); + DBUG_ASSERT(mpvio->packets_read == 1); + NET *net= &mpvio->thd->net; + static uchar switch_plugin_request_buf[]= { 254 }; + + + mpvio->status= MPVIO_EXT::FAILURE; // the status is no longer RESTART + + const char *client_auth_plugin= + ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin; + + DBUG_ASSERT(client_auth_plugin); + DBUG_ASSERT(my_strcasecmp(system_charset_info, client_auth_plugin, + mpvio->cached_client_reply.plugin)); + + /* + we send an old "short 4.0 scramble request", if we need to request a + client to use 4.0 auth plugin (short scramble) and the scramble was + already sent to the client + + below, cached_client_reply.plugin is the plugin name that client has used, + client_auth_plugin is derived from mysql.user table, for the given + user account, it's the plugin that the client need to use to login. + */ + bool switch_from_long_to_short_scramble= + native_password_plugin_name.str == mpvio->cached_client_reply.plugin && + client_auth_plugin == old_password_plugin_name.str; + + if (switch_from_long_to_short_scramble) + return secure_auth(mpvio->thd) || + my_net_write(net, switch_plugin_request_buf, 1) || + net_flush(net); + + /* + We never request a client to switch from a short to long scramble. + Plugin-aware clients can do that, but traditionally it meant to + ask an old 4.0 client to use the new 4.1 authentication protocol. + */ + bool switch_from_short_to_long_scramble= + old_password_plugin_name.str == mpvio->cached_client_reply.plugin && + client_auth_plugin == native_password_plugin_name.str; + + if (switch_from_short_to_long_scramble) + { + my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); + general_log_print(mpvio->thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); + return 1; + } + + return net_write_command(net, switch_plugin_request_buf[0], + (uchar*)client_auth_plugin, + strlen(client_auth_plugin)+1, + (uchar*)data, data_len); +} + + +#ifndef NO_EMBEDDED_ACCESS_CHECKS +/** + Finds acl entry in user database for authentication purposes. + + Finds a user and copies it into mpvio. Reports an authentication + failure if a user is not found. + + @note find_acl_user is not the same, because it doesn't take into + account the case when user is not empty, but acl_user->user is empty + + @retval 0 found + @retval 1 not found +*/ + +static bool find_mpvio_user(MPVIO_EXT *mpvio, Security_context *sctx) +{ + DBUG_ASSERT(mpvio->acl_user == 0); + + pthread_mutex_lock(&acl_cache->lock); + for (uint i=0 ; i < acl_users.elements ; i++) + { + ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*); + if ((!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user)) && + compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip)) + { + mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root); + break; + } + } + pthread_mutex_unlock(&acl_cache->lock); + + if (!mpvio->acl_user) + { + login_failed_error(mpvio->thd); + return 1; + } + + /* user account requires non-default plugin and the client is too old */ + if (mpvio->acl_user->plugin.str != native_password_plugin_name.str && + mpvio->acl_user->plugin.str != old_password_plugin_name.str && + !(mpvio->thd->client_capabilities & CLIENT_PLUGIN_AUTH)) + { + DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, + native_password_plugin_name.str)); + DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, + old_password_plugin_name.str)); + my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); + general_log_print(mpvio->thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); + return 1; + } + + mpvio->auth_info.user_name= sctx->user; + mpvio->auth_info.auth_string= mpvio->acl_user->auth_string.str; + strmake(mpvio->auth_info.authenticated_as, mpvio->acl_user->user ? + mpvio->acl_user->user : "", USERNAME_LENGTH); + + return 0; +} +#endif + + +/* the packet format is described in send_change_user_packet() */ +static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) +{ + THD *thd= mpvio->thd; + NET *net= &thd->net; + Security_context *sctx= thd->security_ctx; + + char *user= (char*) net->read_pos; + char *end= user + packet_length; + /* Safe because there is always a trailing \0 at the end of the packet */ + char *passwd= strend(user)+1; + uint user_len= passwd - user - 1; + char *db= passwd; + char db_buff[SAFE_NAME_LEN + 1]; // buffer to store db in utf8 + char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8 + uint dummy_errors; + + if (passwd >= end) + { + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); + return 1; + } + + /* + Old clients send null-terminated string as password; new clients send + the size (1 byte) + string (not null-terminated). Hence in case of empty + password both send '\0'. + + This strlen() can't be easily deleted without changing protocol. + + Cast *passwd to an unsigned char, so that it doesn't extend the sign for + *passwd > 127 and become 2**32-127+ after casting to uint. + */ + uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ? + (uchar)(*passwd++) : strlen(passwd)); + + db+= passwd_len + 1; + /* + Database name is always NUL-terminated, so in case of empty database + the packet must contain at least the trailing '\0'. + */ + if (db >= end) + { + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); + return 1; + } + + uint db_len= strlen(db); + + char *ptr= db + db_len + 1; + + if (ptr+1 < end) + { + uint cs_number= uint2korr(ptr); + if (thd_init_client_charset(thd, cs_number)) + return 1; + thd->update_charset(); + } + + /* Convert database and user names to utf8 */ + db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info, + db, db_len, thd->charset(), &dummy_errors); + + user_len= copy_and_convert(user_buff, sizeof(user_buff)-1, + system_charset_info, user, user_len, + thd->charset(), &dummy_errors); + + if (!(sctx->user= my_strndup(user_buff, user_len, MYF(MY_WME)))) + return 1; + + /* Clear variables that are allocated */ + thd->user_connect= 0; + strmake(sctx->priv_user, sctx->user, USERNAME_LENGTH); + + if (thd->make_lex_string(&mpvio->db, db_buff, db_len, 0) == 0) + return 1; /* The error is set by make_lex_string(). */ + + /* + Clear thd->db as it points to something, that will be freed when + connection is closed. We don't want to accidentally free a wrong + pointer if connect failed. + */ + thd->reset_db(NULL, 0); + + if (!initialized) + { + // if mysqld's been started with --skip-grant-tables option + mpvio->status= MPVIO_EXT::SUCCESS; + return 0; + } + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (find_mpvio_user(mpvio, sctx)) + return 1; + + char *client_plugin; + if (thd->client_capabilities & CLIENT_PLUGIN_AUTH) + { + client_plugin= ptr + 2; + if (client_plugin >= end) + { + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); + return 1; + } + client_plugin= fix_plugin_ptr(client_plugin); + } + else + { + if (thd->client_capabilities & CLIENT_SECURE_CONNECTION) + client_plugin= native_password_plugin_name.str; + else + { + client_plugin= old_password_plugin_name.str; + /* + For a passwordless accounts we use native_password_plugin. + But when an old 4.0 client connects to it, we change it to + old_password_plugin, otherwise MySQL will think that server + and client plugins don't match. + */ + if (mpvio->acl_user->auth_string.length == 0) + mpvio->acl_user->plugin= old_password_plugin_name; + } + } + + /* remember the data part of the packet, to present it to plugin in read_packet() */ + mpvio->cached_client_reply.pkt= passwd; + mpvio->cached_client_reply.pkt_len= passwd_len; + mpvio->cached_client_reply.plugin= client_plugin; + mpvio->status= MPVIO_EXT::RESTART; +#endif + + return 0; +} + + +/* the packet format is described in send_client_reply_packet() */ +static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, + uchar **buff, ulong pkt_len) +{ +#ifndef EMBEDDED_LIBRARY + THD *thd= mpvio->thd; + NET *net= &thd->net; + char *end; + + DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE); + + if (pkt_len < MIN_HANDSHAKE_SIZE) + return packet_error; + + /* + Protocol buffer is guaranteed to always end with \0. (see my_net_read()) + As the code below depends on this, lets check that. + */ + DBUG_ASSERT(net->read_pos[pkt_len] == 0); + + if (mpvio->connect_errors) + reset_host_errors(&net->vio->remote.sin_addr); + + ulong client_capabilities= uint2korr(net->read_pos); + if (client_capabilities & CLIENT_PROTOCOL_41) + { + if (pkt_len < 32) + return packet_error; + client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16; + thd->max_client_packet_length= uint4korr(net->read_pos+4); + DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8])); + if (thd_init_client_charset(thd, (uint) net->read_pos[8])) + return packet_error; + thd->update_charset(); + end= (char*) net->read_pos+32; + } + else + { + if (pkt_len < 5) + return packet_error; + thd->max_client_packet_length= uint3korr(net->read_pos+2); + end= (char*) net->read_pos+5; + } + + /* Disable those bits which are not supported by the client. */ + thd->client_capabilities&= client_capabilities; + + if (thd->client_capabilities & CLIENT_IGNORE_SPACE) + thd->variables.sql_mode|= MODE_IGNORE_SPACE; + + DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities)); + if (thd->client_capabilities & CLIENT_SSL) + { + char error_string[1024] __attribute__((unused)); + + /* Do the SSL layering. */ + if (!ssl_acceptor_fd) + return packet_error; + + DBUG_PRINT("info", ("IO layer change in progress...")); + if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, error_string)) + { + DBUG_PRINT("error", ("Failed to accept new SSL connection")); + return packet_error; + } + + DBUG_PRINT("info", ("Reading user information over SSL layer")); + pkt_len= my_net_read(net); + if (pkt_len == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE) + { + DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)", + pkt_len)); + return packet_error; + } + } + + if (end >= (char*) net->read_pos+ pkt_len +2) + return packet_error; + + if (thd->client_capabilities & CLIENT_INTERACTIVE) + thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout; + if ((thd->client_capabilities & CLIENT_TRANSACTIONS) && + opt_using_transactions) + net->return_status= &thd->server_status; + + char *user= end; + char *passwd= strend(user)+1; + uint user_len= passwd - user - 1, db_len; + char *db= passwd; + char db_buff[SAFE_NAME_LEN + 1]; // buffer to store db in utf8 + char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8 + uint dummy_errors; + + /* + Old clients send null-terminated string as password; new clients send + the size (1 byte) + string (not null-terminated). Hence in case of empty + password both send '\0'. + + This strlen() can't be easily deleted without changing protocol. + + Cast *passwd to an unsigned char, so that it doesn't extend the sign for + *passwd > 127 and become 2**32-127+ after casting to uint. + */ + uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ? + (uchar)(*passwd++) : strlen(passwd); + + db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ? + db + passwd_len + 1 : 0; + + if (passwd + passwd_len + test(db) > (char *)net->read_pos + pkt_len) + return packet_error; + + /* strlen() can't be easily deleted without changing protocol */ + db_len= db ? strlen(db) : 0; + + char *client_plugin= passwd + passwd_len + (db ? db_len + 1 : 0); + + /* Since 4.1 all database names are stored in utf8 */ + if (db) + { + db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info, + db, db_len, thd->charset(), &dummy_errors); + db= db_buff; + } + + user_len= copy_and_convert(user_buff, sizeof(user_buff)-1, + system_charset_info, user, user_len, + thd->charset(), &dummy_errors); + user= user_buff; + + /* If username starts and ends in "'", chop them off */ + if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'') + { + user++; + user_len-= 2; + } + + /* + Clip username to allowed length in characters (not bytes). This is + mostly for backward compatibility. + */ + { + CHARSET_INFO *cs= system_charset_info; + int err; + + user_len= (uint) cs->cset->well_formed_len(cs, user, user + user_len, + USERNAME_CHAR_LENGTH, &err); + user[user_len]= '\0'; + } + + Security_context *sctx= thd->security_ctx; + + if (thd->make_lex_string(&mpvio->db, db, db_len, 0) == 0) + return packet_error; /* The error is set by make_lex_string(). */ + if (sctx->user) + x_free(sctx->user); + if (!(sctx->user= my_strndup(user, user_len, MYF(MY_WME)))) + return packet_error; /* The error is set by my_strdup(). */ + + /* + Clear thd->db as it points to something, that will be freed when + connection is closed. We don't want to accidentally free a wrong + pointer if connect failed. + */ + thd->reset_db(NULL, 0); + + if (!initialized) + { + // if mysqld's been started with --skip-grant-tables option + mpvio->status= MPVIO_EXT::SUCCESS; + return packet_error; + } + + thd->password= passwd_len > 0; + if (find_mpvio_user(mpvio, sctx)) + { + return packet_error; + } + + if (thd->client_capabilities & CLIENT_PLUGIN_AUTH) + { + if (client_plugin >= (char *)net->read_pos + pkt_len) + return packet_error; + client_plugin= fix_plugin_ptr(client_plugin); + } + else + { + if (thd->client_capabilities & CLIENT_SECURE_CONNECTION) + client_plugin= native_password_plugin_name.str; + else + { + client_plugin= old_password_plugin_name.str; + /* + For a passwordless accounts we use native_password_plugin. + But when an old 4.0 client connects to it, we change it to + old_password_plugin, otherwise MySQL will think that server + and client plugins don't match. + */ + if (mpvio->acl_user->auth_string.length == 0) + mpvio->acl_user->plugin= old_password_plugin_name; + } + } + + /* + if the acl_user needs a different plugin to authenticate + (specified in GRANT ... AUTHENTICATED VIA plugin_name ..) + we need to restart the authentication in the server. + But perhaps the client has already used the correct plugin - + in that case the authentication on the client may not need to be + restarted and a server auth plugin will read the data that the client + has just send. Cache them to return in the next server_mpvio_read_packet(). + */ + if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, + plugin_name(mpvio->plugin)->str) != 0) + { + mpvio->cached_client_reply.pkt= passwd; + mpvio->cached_client_reply.pkt_len= passwd_len; + mpvio->cached_client_reply.plugin= client_plugin; + mpvio->status= MPVIO_EXT::RESTART; + return packet_error; + } + + /* + ok, we don't need to restart the authentication on the server. + but if the client used the wrong plugin, we need to restart + the authentication on the client. Do it here, the server plugin + doesn't need to know. + */ + const char *client_auth_plugin= + ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin; + + if (client_auth_plugin && + my_strcasecmp(system_charset_info, client_plugin, client_auth_plugin)) + { + mpvio->cached_client_reply.plugin= client_plugin; + if (send_plugin_request_packet(mpvio, + (uchar*)mpvio->cached_server_packet.pkt, + mpvio->cached_server_packet.pkt_len)) + return packet_error; + + passwd_len= my_net_read(&mpvio->thd->net); + passwd = (char*)mpvio->thd->net.read_pos; + } + + *buff= (uchar*)passwd; + return passwd_len; +#else + return 0; +#endif +} + + +/** + vio->write_packet() callback method for server authentication plugins + + This function is called by a server authentication plugin, when it wants + to send data to the client. + + It transparently wraps the data into a handshake packet, + and handles plugin negotiation with the client. If necessary, + it escapes the plugin data, if it starts with a mysql protocol packet byte. +*/ + +static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param, + const uchar *packet, int packet_len) +{ + MPVIO_EXT *mpvio= (MPVIO_EXT*)param; + int res; + + /* reset cached_client_reply */ + mpvio->cached_client_reply.pkt= 0; + /* for the 1st packet we wrap plugin data into the handshake packet */ + if (mpvio->packets_written == 0) + res= send_server_handshake_packet(mpvio, (char*)packet, packet_len); + else if (mpvio->status == MPVIO_EXT::RESTART) + res= send_plugin_request_packet(mpvio, packet, packet_len); + else if (packet_len > 0 && (*packet == 1 || *packet == 255 || *packet == 254)) + { + /* + we cannot allow plugin data packet to start from 255 or 254 - + as the client will treat it as an error or "change plugin" packet. + We'll escape these bytes with \1. Consequently, we + have to escape \1 byte too. + */ + res= net_write_command(&mpvio->thd->net, 1, (uchar*)"", 0, + packet, packet_len); + } + else + { + res= my_net_write(&mpvio->thd->net, packet, packet_len) || + net_flush(&mpvio->thd->net); + } + mpvio->packets_written++; + return res; +} + + +/** + vio->read_packet() callback method for server authentication plugins + + This function is called by a server authentication plugin, when it wants + to read data from the client. + + It transparently extracts the client plugin data, if embedded into + a client authentication handshake packet, and handles plugin negotiation + with the client, if necessary. +*/ + +static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) +{ + MPVIO_EXT *mpvio= (MPVIO_EXT*)param; + ulong pkt_len; + + if (mpvio->packets_written == 0) + { + /* + plugin wants to read the data without sending anything first. + send an empty packet to force a server handshake packet to be sent + */ + if (server_mpvio_write_packet(mpvio, 0, 0)) + pkt_len= packet_error; + else + pkt_len= my_net_read(&mpvio->thd->net); + } + else + if (mpvio->cached_client_reply.pkt) + { + DBUG_ASSERT(mpvio->status == MPVIO_EXT::RESTART); + DBUG_ASSERT(mpvio->packets_read > 0); + /* + if the have the data cached from the last server_mpvio_read_packet + (which can be the case if it's a restarted authentication) + and a client has used the correct plugin, then we can return the + cached data straight away and avoid one round trip. + */ + const char *client_auth_plugin= + ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin; + if (client_auth_plugin == 0 || + my_strcasecmp(system_charset_info, mpvio->cached_client_reply.plugin, + client_auth_plugin) == 0) + { + mpvio->status= MPVIO_EXT::FAILURE; + *buf= (uchar*)mpvio->cached_client_reply.pkt; + mpvio->cached_client_reply.pkt= 0; + mpvio->packets_read++; + return (int)mpvio->cached_client_reply.pkt_len; + } + /* + But if the client has used the wrong plugin, the cached data are + useless. Furthermore, we have to send a "change plugin" request + to the client. + */ + if (server_mpvio_write_packet(mpvio, 0, 0)) + pkt_len= packet_error; + else + pkt_len= my_net_read(&mpvio->thd->net); + } + else + pkt_len= my_net_read(&mpvio->thd->net); + + if (pkt_len == packet_error) + goto err; + + mpvio->packets_read++; + + /* + the 1st packet has the plugin data wrapped into the client authentication + handshake packet + */ + if (mpvio->packets_read == 1) + { + pkt_len= parse_client_handshake_packet(mpvio, buf, pkt_len); + if (pkt_len == packet_error) + goto err; + } + else + *buf = mpvio->thd->net.read_pos; + + return (int)pkt_len; + +err: + if (mpvio->status == MPVIO_EXT::FAILURE && !mpvio->thd->is_error()) + { + inc_host_errors(&mpvio->thd->net.vio->remote.sin_addr); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); + } + return -1; +} + + +/** + fills MYSQL_PLUGIN_VIO_INFO structure with the information about the + connection +*/ + +static void server_mpvio_info(MYSQL_PLUGIN_VIO *vio, + MYSQL_PLUGIN_VIO_INFO *info) +{ + MPVIO_EXT *mpvio= (MPVIO_EXT*)vio; + mpvio_info(mpvio->thd->net.vio, info); +} + + +static bool acl_check_ssl(THD *thd, ACL_USER *acl_user) +{ +#if defined(HAVE_OPENSSL) + Vio *vio=thd->net.vio; + SSL *ssl= (SSL*) vio->ssl_arg; + X509 *cert; +#endif + + /* + At this point we know that user is allowed to connect + from given host by given username/password pair. Now + we check if SSL is required, if user is using SSL and + if X509 certificate attributes are OK + */ + switch (acl_user->ssl_type) { + case SSL_TYPE_NOT_SPECIFIED: // Impossible + case SSL_TYPE_NONE: // SSL is not required + return 0; +#if defined(HAVE_OPENSSL) + case SSL_TYPE_ANY: // Any kind of SSL is ok + return vio_type(vio) != VIO_TYPE_SSL; + case SSL_TYPE_X509: /* Client should have any valid certificate. */ + /* + Connections with non-valid certificates are dropped already + in sslaccept() anyway, so we do not check validity here. + + We need to check for absence of SSL because without SSL + we should reject connection. + */ + if (vio_type(vio) == VIO_TYPE_SSL && + SSL_get_verify_result(ssl) == X509_V_OK && + (cert= SSL_get_peer_certificate(ssl))) + { + X509_free(cert); + return 0; + } + return 1; + case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */ + /* If a cipher name is specified, we compare it to actual cipher in use. */ + if (vio_type(vio) != VIO_TYPE_SSL || + SSL_get_verify_result(ssl) != X509_V_OK) + return 1; + if (acl_user->ssl_cipher) + { + DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'", + acl_user->ssl_cipher,SSL_get_cipher(ssl))); + if (strcmp(acl_user->ssl_cipher,SSL_get_cipher(ssl))) + { + if (global_system_variables.log_warnings) + sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'", + acl_user->ssl_cipher, SSL_get_cipher(ssl)); + return 1; + } + } + /* Prepare certificate (if exists) */ + if (!(cert= SSL_get_peer_certificate(ssl))) + return 1; + /* If X509 issuer is specified, we check it... */ + if (acl_user->x509_issuer) + { + char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); + DBUG_PRINT("info",("comparing issuers: '%s' and '%s'", + acl_user->x509_issuer, ptr)); + if (strcmp(acl_user->x509_issuer, ptr)) + { + if (global_system_variables.log_warnings) + sql_print_information("X509 issuer mismatch: should be '%s' " + "but is '%s'", acl_user->x509_issuer, ptr); + free(ptr); + X509_free(cert); + return 1; + } + free(ptr); + } + /* X509 subject is specified, we check it .. */ + if (acl_user->x509_subject) + { + char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); + DBUG_PRINT("info",("comparing subjects: '%s' and '%s'", + acl_user->x509_subject, ptr)); + if (strcmp(acl_user->x509_subject,ptr)) + { + if (global_system_variables.log_warnings) + sql_print_information("X509 subject mismatch: should be '%s' but is '%s'", + acl_user->x509_subject, ptr); + free(ptr); + X509_free(cert); + return 1; + } + free(ptr); + } + X509_free(cert); + return 0; +#else /* HAVE_OPENSSL */ + default: + /* + If we don't have SSL but SSL is required for this user the + authentication should fail. + */ + return 1; +#endif /* HAVE_OPENSSL */ + } + return 1; +} + +static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name, + MPVIO_EXT *mpvio) +{ + int res= CR_OK, old_status= MPVIO_EXT::FAILURE; + bool unlock_plugin= false; + plugin_ref plugin; + +#ifdef EMBEDDED_LIBRARY + plugin= native_password_plugin; +#else + if (auth_plugin_name->str == native_password_plugin_name.str) + plugin= native_password_plugin; + else if (auth_plugin_name->str == old_password_plugin_name.str) + plugin= old_password_plugin; + else if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name, + MYSQL_AUTHENTICATION_PLUGIN))) + unlock_plugin= true; +#endif + + mpvio->plugin= plugin; + old_status= mpvio->status; + + if (plugin) + { + st_mysql_auth *auth= (st_mysql_auth*)plugin_decl(plugin)->info; + res= auth->authenticate_user(mpvio, &mpvio->auth_info); + + if (unlock_plugin) + plugin_unlock(thd, plugin); + } + else + { + /* Server cannot load the required plugin. */ + my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name->str); + res= CR_ERROR; + } + + /* + If the status was MPVIO_EXT::RESTART before the authenticate_user() call + it can never be MPVIO_EXT::RESTART after the call, because any call + to write_packet() or read_packet() will reset the status. + + But (!) if a plugin never called a read_packet() or write_packet(), the + status will stay unchanged. We'll fix it, by resetting the status here. + */ + if (old_status == MPVIO_EXT::RESTART && mpvio->status == MPVIO_EXT::RESTART) + mpvio->status= MPVIO_EXT::FAILURE; // reset to the default + + return res; +} + +/** + Perform the handshake, authorize the client and update thd sctx variables. + + @param thd thread handle + @param connect_errors number of previous failed connect attemps + from this host + @param com_change_user_pkt_len size of the COM_CHANGE_USER packet + (without the first, command, byte) or 0 + if it's not a COM_CHANGE_USER (that is, if + it's a new connection) + + @retval 0 success, thd is updated. + @retval 1 error +*/ + +bool acl_authenticate(THD *thd, uint connect_errors, + uint com_change_user_pkt_len) +{ + int res= CR_OK; + MPVIO_EXT mpvio; + LEX_STRING *auth_plugin_name= default_auth_plugin_name; + enum enum_server_command command= com_change_user_pkt_len ? COM_CHANGE_USER + : COM_CONNECT; + DBUG_ENTER("acl_authenticate"); + + compile_time_assert(MYSQL_USERNAME_LENGTH == USERNAME_LENGTH); + + bzero(&mpvio, sizeof(mpvio)); + mpvio.read_packet= server_mpvio_read_packet; + mpvio.write_packet= server_mpvio_write_packet; + mpvio.info= server_mpvio_info; + mpvio.thd= thd; + mpvio.connect_errors= connect_errors; + mpvio.status= MPVIO_EXT::FAILURE; + + if (command == COM_CHANGE_USER) + { + mpvio.packets_written++; // pretend that a server handshake packet was sent + mpvio.packets_read++; // take COM_CHANGE_USER packet into account + + if (parse_com_change_user_packet(&mpvio, com_change_user_pkt_len)) + DBUG_RETURN(1); + + DBUG_ASSERT(mpvio.status == MPVIO_EXT::RESTART || + mpvio.status == MPVIO_EXT::SUCCESS); + } + else + { + /* mark the thd as having no scramble yet */ + thd->scramble[SCRAMBLE_LENGTH]= 1; + + /* + perform the first authentication attempt, with the default plugin. + This sends the server handshake packet, reads the client reply + with a user name, and performs the authentication if everyone has used + the correct plugin. + */ + res= do_auth_once(thd, auth_plugin_name, &mpvio); + } + + /* + retry the authentication, if - after receiving the user name - + we found that we need to switch to a non-default plugin + */ + if (mpvio.status == MPVIO_EXT::RESTART) + { + DBUG_ASSERT(mpvio.acl_user); + DBUG_ASSERT(command == COM_CHANGE_USER || + my_strcasecmp(system_charset_info, auth_plugin_name->str, + mpvio.acl_user->plugin.str)); + auth_plugin_name= &mpvio.acl_user->plugin; + res= do_auth_once(thd, auth_plugin_name, &mpvio); + } + + Security_context *sctx= thd->security_ctx; + ACL_USER *acl_user= mpvio.acl_user; + + thd->password= mpvio.auth_info.password_used; // remember for error messages + + /* + Log the command here so that the user can check the log + for the tried logins and also to detect break-in attempts. + + if sctx->user is unset it's protocol failure, bad packet. + */ + if (sctx->user) + { + if (strcmp(sctx->priv_user, sctx->user)) + { + general_log_print(thd, command, "%s@%s as %s on %s", + sctx->user, sctx->host_or_ip, + sctx->priv_user[0] ? sctx->priv_user : "anonymous", + mpvio.db.str ? mpvio.db.str : (char*) ""); + } + else + general_log_print(thd, command, (char*) "%s@%s on %s", + sctx->user, sctx->host_or_ip, + mpvio.db.str ? mpvio.db.str : (char*) ""); + } + + if (res > CR_OK && mpvio.status != MPVIO_EXT::SUCCESS) + { + DBUG_ASSERT(mpvio.status == MPVIO_EXT::FAILURE); + + if (!thd->is_error()) + login_failed_error(thd); + DBUG_RETURN(1); + } + + if (initialized) // if not --skip-grant-tables + { + sctx->master_access= acl_user->access; + strmake(sctx->priv_user, mpvio.auth_info.authenticated_as, USERNAME_LENGTH); + if (acl_user->host.hostname) + strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME); + else + *sctx->priv_host= 0; + + /* + OK. Let's check the SSL. Historically it was checked after the password, + as an additional layer, not instead of the password + (in which case it would've been a plugin too). + */ + if (acl_check_ssl(thd, acl_user)) + { + login_failed_error(thd); + DBUG_RETURN(1); + } + + /* Don't allow the user to connect if he has done too many queries */ + if ((acl_user->user_resource.questions || acl_user->user_resource.updates || + acl_user->user_resource.conn_per_hour || + acl_user->user_resource.user_conn || max_user_connections) && + get_or_create_user_conn(thd, + (opt_old_style_user_limits ? sctx->user : sctx->priv_user), + (opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host), + &acl_user->user_resource)) + DBUG_RETURN(1); // The error is set by get_or_create_user_conn() + } + else + sctx->skip_grants(); + + if (thd->user_connect && + (thd->user_connect->user_resources.conn_per_hour || + thd->user_connect->user_resources.user_conn || + max_user_connections) && + check_for_max_user_connections(thd, thd->user_connect)) + { + /* Ensure we don't decrement thd->user_connections->connections twice */ + thd->user_connect= 0; + status_var_increment(denied_connections); + DBUG_RETURN(1); // The error is set in check_for_max_user_connections() + } + + DBUG_PRINT("info", + ("Capabilities: %lu packet_length: %ld Host: '%s' " + "Login user: '%s' Priv_user: '%s' Using password: %s " + "Access: %lu db: '%s'", + thd->client_capabilities, thd->max_client_packet_length, + sctx->host_or_ip, sctx->user, sctx->priv_user, + thd->password ? "yes": "no", + sctx->master_access, mpvio.db.str)); + + if (command == COM_CONNECT && + !(thd->main_security_ctx.master_access & SUPER_ACL)) + { + pthread_mutex_lock(&LOCK_connection_count); + bool count_ok= (*thd->scheduler->connection_count <= + *thd->scheduler->max_connections); + VOID(pthread_mutex_unlock(&LOCK_connection_count)); + if (!count_ok) + { // too many connections + my_error(ER_CON_COUNT_ERROR, MYF(0)); + DBUG_RETURN(1); + } + } + + /* + This is the default access rights for the current database. It's + set to 0 here because we don't have an active database yet (and we + may not have an active database to set. + */ + sctx->db_access=0; + + /* Change a database if necessary */ + if (mpvio.db.length) + { + if (mysql_change_db(thd, &mpvio.db, FALSE)) + { + /* mysql_change_db() has pushed the error message. */ + status_var_increment(thd->status_var.access_denied_errors); + DBUG_RETURN(1); + } + } + + thd->net.net_skip_rest_factor= 2; // skip at most 2*max_packet_size + + if (res == CR_OK_HANDSHAKE_COMPLETE) + thd->main_da.disable_status(); + else + my_ok(thd); + + /* Ready to handle queries */ + DBUG_RETURN(0); +} + + +/** + MySQL Server Password Authentication Plugin + + In the MySQL authentication protocol: + 1. the server sends the random scramble to the client + 2. client sends the encrypted password back to the server + 3. the server checks the password. +*/ + +static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio, + MYSQL_SERVER_AUTH_INFO *info) +{ + uchar *pkt; + int pkt_len; + MPVIO_EXT *mpvio=(MPVIO_EXT*)vio; + THD *thd=mpvio->thd; + + /* generate the scramble, or reuse the old one */ + if (thd->scramble[SCRAMBLE_LENGTH]) + { + create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); + /* and send it to the client */ + if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) + return CR_ERROR; + } + + /* reply and authenticate */ + + /* + <digression> + This is more complex than it looks. + + The plugin (we) may be called right after the client was connected - + and will need to send a scramble, read reply, authenticate. + + Or the plugin may be called after another plugin has sent a scramble, + and read the reply. If the client has used the correct client-plugin, + we won't need to read anything here from the client, the client + has already sent a reply with everything we need for authentication. + + Or the plugin may be called after another plugin has sent a scramble, + and read the reply, but the client has used the wrong client-plugin. + We'll need to sent a "switch to another plugin" packet to the + client and read the reply. "Use the short scramble" packet is a special + case of "switch to another plugin" packet. + + Or, perhaps, the plugin may be called after another plugin has + done the handshake but did not send a useful scramble. We'll need + to send a scramble (and perhaps a "switch to another plugin" packet) + and read the reply. + + Besides, a client may be an old one, that doesn't understand plugins. + Or doesn't even understand 4.0 scramble. + + And we want to keep the same protocol on the wire unless non-native + plugins are involved. + + Anyway, it still looks simple from a plugin point of view: + "send the scramble, read the reply and authenticate". + All the magic is transparently handled by the server. + </digression> + */ + + /* read the reply with the encrypted password */ + if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0) + return CR_ERROR; + +#ifdef NO_EMBEDDED_ACCESS_CHECKS + return CR_OK; +#endif + + if (pkt_len == 0) /* no password */ + return info->auth_string[0] ? CR_ERROR : CR_OK; + + info->password_used = 1; + if (pkt_len == SCRAMBLE_LENGTH) + return info->auth_string[0] == 0 || + check_scramble(pkt, thd->scramble, mpvio->acl_user->salt) ? + CR_ERROR : CR_OK; + + inc_host_errors(&mpvio->thd->net.vio->remote.sin_addr); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); + return CR_ERROR; +} + + +static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio, + MYSQL_SERVER_AUTH_INFO *info) +{ + uchar *pkt; + int pkt_len; + MPVIO_EXT *mpvio=(MPVIO_EXT*)vio; + THD *thd=mpvio->thd; + + /* generate the scramble, or reuse the old one */ + if (thd->scramble[SCRAMBLE_LENGTH]) + { + create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); + /* and send it to the client */ + if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) + return CR_ERROR; + } + + /* read the reply and authenticate */ + if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0) + return CR_ERROR; + +#ifdef NO_EMBEDDED_ACCESS_CHECKS + return CR_OK; +#endif + + /* + legacy: if switch_from_long_to_short_scramble, + the password is sent \0-terminated, the pkt_len is always 9 bytes. + We need to figure out the correct scramble length here. + */ + if (pkt_len == SCRAMBLE_LENGTH_323+1) + pkt_len= strnlen((char*)pkt, pkt_len); + + if (pkt_len == 0) /* no password */ + return info->auth_string[0] ? CR_ERROR : CR_OK; + + if (secure_auth(thd)) + return CR_ERROR; + + info->password_used = 1; + + if (pkt_len == SCRAMBLE_LENGTH_323) + return info->auth_string[0] == 0 || + check_scramble_323(pkt, thd->scramble, + (ulong *)mpvio->acl_user->salt) ? CR_ERROR : CR_OK; + + inc_host_errors(&mpvio->thd->net.vio->remote.sin_addr); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); + return CR_ERROR; +} + +static struct st_mysql_auth native_password_handler= +{ + MYSQL_AUTHENTICATION_INTERFACE_VERSION, + native_password_plugin_name.str, + native_password_authenticate +}; + +static struct st_mysql_auth old_password_handler= +{ + MYSQL_AUTHENTICATION_INTERFACE_VERSION, + old_password_plugin_name.str, + old_password_authenticate +}; + +mysql_declare_plugin(mysql_password) +{ + MYSQL_AUTHENTICATION_PLUGIN, /* type constant */ + &native_password_handler, /* type descriptor */ + native_password_plugin_name.str, /* Name */ + "R.J.Silk, Sergei Golubchik", /* Author */ + "Native MySQL authentication", /* Description */ + PLUGIN_LICENSE_GPL, /* License */ + NULL, /* Init function */ + NULL, /* Deinit function */ + 0x0100, /* Version (1.0) */ + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ +}, +{ + MYSQL_AUTHENTICATION_PLUGIN, /* type constant */ + &old_password_handler, /* type descriptor */ + old_password_plugin_name.str, /* Name */ + "R.J.Silk, Sergei Golubchik", /* Author */ + "Old MySQL-4.0 authentication", /* Description */ + PLUGIN_LICENSE_GPL, /* License */ + NULL, /* Init function */ + NULL, /* Deinit function */ + 0x0100, /* Version (1.0) */ + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ +} +mysql_declare_plugin_end; + +maria_declare_plugin(mysql_password) +{ + MYSQL_AUTHENTICATION_PLUGIN, /* type constant */ + &native_password_handler, /* type descriptor */ + native_password_plugin_name.str, /* Name */ + "R.J.Silk, Sergei Golubchik", /* Author */ + "Native MySQL authentication", /* Description */ + PLUGIN_LICENSE_GPL, /* License */ + NULL, /* Init function */ + NULL, /* Deinit function */ + 0x0100, /* Version (1.0) */ + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* String version */ + MariaDB_PLUGIN_MATURITY_BETA /* Maturity */ +}, +{ + MYSQL_AUTHENTICATION_PLUGIN, /* type constant */ + &old_password_handler, /* type descriptor */ + old_password_plugin_name.str, /* Name */ + "R.J.Silk, Sergei Golubchik", /* Author */ + "Old MySQL-4.0 authentication", /* Description */ + PLUGIN_LICENSE_GPL, /* License */ + NULL, /* Init function */ + NULL, /* Deinit function */ + 0x0100, /* Version (1.0) */ + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* String version */ + MariaDB_PLUGIN_MATURITY_BETA /* Maturity */ +} +maria_declare_plugin_end; diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 29676b71c90..1be2ecd2ef0 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -164,53 +164,6 @@ enum mysql_db_table_field extern const TABLE_FIELD_DEF mysql_db_table_def; -/* Classes */ - -struct acl_host_and_ip -{ - char *hostname; - long ip,ip_mask; // Used with masked ip:s -}; - - -class ACL_ACCESS { -public: - ulong sort; - ulong access; -}; - - -/* ACL_HOST is used if no host is specified */ - -class ACL_HOST :public ACL_ACCESS -{ -public: - acl_host_and_ip host; - char *db; -}; - - -class ACL_USER :public ACL_ACCESS -{ -public: - acl_host_and_ip host; - uint hostname_length; - USER_RESOURCES user_resource; - char *user; - uint8 salt[SCRAMBLE_LENGTH+1]; // scrambled password in binary form - uint8 salt_len; // 0 - no password, 4 - 3.20, 8 - 3.23, 20 - 4.1.1 - enum SSL_type ssl_type; - const char *ssl_cipher, *x509_issuer, *x509_subject; -}; - - -class ACL_DB :public ACL_ACCESS -{ -public: - acl_host_and_ip host; - char *user,*db; -}; - /* prototypes */ bool hostname_requires_resolving(const char *hostname); @@ -219,10 +172,9 @@ my_bool acl_reload(THD *thd); void acl_free(bool end=0); ulong acl_get(const char *host, const char *ip, const char *user, const char *db, my_bool db_is_pattern); -int acl_getroot(THD *thd, USER_RESOURCES *mqh, const char *passwd, - uint passwd_len); -bool acl_getroot_no_password(Security_context *sctx, char *user, char *host, - char *ip, char *db); +bool acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len); +bool acl_getroot(Security_context *sctx, char *user, char *host, + char *ip, char *db); bool acl_check_host(const char *host, const char *ip); int check_change_password(THD *thd, const char *host, const char *user, char *password, uint password_len); diff --git a/sql/sql_analyse.h b/sql/sql_analyse.h index 8807b40857e..b72ff62d592 100644 --- a/sql/sql_analyse.h +++ b/sql/sql_analyse.h @@ -71,7 +71,7 @@ class field_info :public Sql_alloc protected: ulong treemem, tree_elements, empty, nulls, min_length, max_length; uint room_in_tree; - my_bool found; + bool found; TREE tree; Item *item; analyse *pc; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 54921500e93..c8b1067425b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -61,7 +61,7 @@ private: bool Prelock_error_handler::handle_error(uint sql_errno, const char * /* message */, - MYSQL_ERROR::enum_warning_level /* level */, + MYSQL_ERROR::enum_warning_level level, THD * /* thd */) { if (sql_errno == ER_NO_SUCH_TABLE) @@ -70,7 +70,8 @@ Prelock_error_handler::handle_error(uint sql_errno, return TRUE; } - m_unhandled_errors++; + if (level == MYSQL_ERROR::WARN_LEVEL_ERROR) + m_unhandled_errors++; return FALSE; } @@ -1393,6 +1394,12 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str, table->s->table_name.str, (long) table)); + if (table->file) + { + table->file->update_global_table_stats(); + table->file->update_global_index_stats(); + } + *table_ptr=table->next; /* When closing a MERGE parent or child table, detach the children first. @@ -1475,12 +1482,11 @@ void close_temporary_tables(THD *thd) /* Better add "if exists", in case a RESET MASTER has been done */ const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS "; - uint stub_len= sizeof(stub) - 1; - char buf[256]; - String s_query= String(buf, sizeof(buf), system_charset_info); + char buf[FN_REFLEN]; + String s_query(buf, sizeof(buf), system_charset_info); bool found_user_tables= FALSE; - memcpy(buf, stub, stub_len); + s_query.copy(stub, sizeof(stub)-1, system_charset_info); /* Insertion sort of temp tables by pseudo_thread_id to build ordered list @@ -1534,19 +1540,25 @@ void close_temporary_tables(THD *thd) { bool save_thread_specific_used= thd->thread_specific_used; my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id; + char db_buf[FN_REFLEN]; + String db(db_buf, sizeof(db_buf), system_charset_info); + /* Set pseudo_thread_id to be that of the processed table */ thd->variables.pseudo_thread_id= tmpkeyval(thd, table); - String db; - db.append(table->s->db.str); + + db.copy(table->s->db.str, table->s->db.length, system_charset_info); + /* Reset s_query() if changed by previous loop */ + s_query.length(sizeof(stub)-1); + /* Loop forward through all tables that belong to a common database within the sublist of common pseudo_thread_id to create single DROP query */ - for (s_query.length(stub_len); + for (; table && is_user_table(table) && tmpkeyval(thd, table) == thd->variables.pseudo_thread_id && table->s->db.length == db.length() && - strcmp(table->s->db.str, db.ptr()) == 0; + memcmp(table->s->db.str, db.ptr(), db.length()) == 0; table= next) { /* @@ -1850,7 +1862,7 @@ int drop_temporary_table(THD *thd, TABLE_LIST *table_list) /* Table might be in use by some outer statement. */ if (table->query_id && table->query_id != thd->query_id) { - my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr()); DBUG_RETURN(-1); } @@ -1873,7 +1885,7 @@ void close_temporary_table(THD *thd, TABLE *table, DBUG_ENTER("close_temporary_table"); DBUG_PRINT("tmptable", ("closing table: '%s'.'%s' 0x%lx alias: '%s'", table->s->db.str, table->s->table_name.str, - (long) table, table->alias)); + (long) table, table->alias.c_ptr())); /* When closing a MERGE parent or child table, detach the children @@ -1933,6 +1945,13 @@ void close_temporary(TABLE *table, bool free_share, bool delete_table) DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", table->s->db.str, table->s->table_name.str)); + /* in_use is not set for replication temporary tables during shutdown */ + if (table->in_use) + { + table->file->update_global_table_stats(); + table->file->update_global_index_stats(); + } + free_io_cache(table); closefrm(table, 0); if (delete_table) @@ -2337,7 +2356,8 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in) table->tablenr=thd->current_tablenr++; table->used_fields=0; table->const_table=0; - table->null_row= table->maybe_null= 0; + table->null_row= 0; + table->maybe_null= 0; table->force_index= table->force_index_order= table->force_index_group= 0; table->status=STATUS_NO_RECORD; DBUG_RETURN(FALSE); @@ -2599,7 +2619,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ("query_id: %lu server_id: %u pseudo_thread_id: %lu", (ulong) table->query_id, (uint) thd->server_id, (ulong) thd->variables.pseudo_thread_id)); - my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr()); DBUG_RETURN(0); } table->query_id= thd->query_id; @@ -2636,7 +2656,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, When looking for a usable TABLE, ignore MERGE children, as they belong to their parent and cannot be used explicitly. */ - if (!my_strcasecmp(system_charset_info, table->alias, alias) && + if (!my_strcasecmp(system_charset_info, table->alias.c_ptr(), alias) && table->query_id != thd->query_id && /* skip tables already used */ !(thd->prelocked_mode && table->query_id) && !table->parent) @@ -2991,25 +3011,23 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table->alias_name_used= my_strcasecmp(table_alias_charset, table->s->table_name.str, alias); /* Fix alias if table name changes */ - if (strcmp(table->alias, alias)) - { - uint length=(uint) strlen(alias)+1; - table->alias= (char*) my_realloc((char*) table->alias, length, - MYF(MY_WME)); - memcpy((char*) table->alias, alias, length); - } + if (strcmp(table->alias.c_ptr(), alias)) + table->alias.copy(alias, strlen(alias), table->alias.charset()); + /* These variables are also set in reopen_table() */ table->tablenr=thd->current_tablenr++; table->used_fields=0; table->const_table=0; - table->null_row= table->maybe_null= 0; + table->null_row= 0; + table->maybe_null= 0; table->force_index= table->force_index_order= table->force_index_group= 0; table->status=STATUS_NO_RECORD; table->insert_values= 0; table->fulltext_searched= 0; + table->file->ha_start_of_new_statement(); table->file->ft_handler= 0; /* - Check that there is no reference to a condtion from an earlier query + Check that there is no reference to a condition from an earlier query (cf. Bug#58553). */ DBUG_ASSERT(table->file->pushed_cond == NULL); @@ -3085,7 +3103,7 @@ bool reopen_table(TABLE *table) #ifdef EXTRA_DEBUG if (table->db_stat) sql_print_error("Table %s had a open data handler in reopen_table", - table->alias); + table->alias.c_ptr()); #endif bzero((char*) &table_list, sizeof(TABLE_LIST)); table_list.db= table->s->db.str; @@ -3096,7 +3114,7 @@ bool reopen_table(TABLE *table) DBUG_RETURN(1); // Thread was killed if (open_unireg_entry(thd, &tmp, &table_list, - table->alias, + table->alias.c_ptr(), table->s->table_cache_key.str, table->s->table_cache_key.length, thd->mem_root, 0)) @@ -3135,14 +3153,14 @@ bool reopen_table(TABLE *table) VOID(closefrm(table, 1)); // close file, free everything *table= tmp; + table->alias.move(tmp.alias); table->default_column_bitmaps(); table->file->change_table_ptr(table, table->s); - DBUG_ASSERT(table->alias != 0); + DBUG_ASSERT(table->alias.ptr() != 0); for (field=table->field ; *field ; field++) { - (*field)->table= (*field)->orig_table= table; - (*field)->table_name= &table->alias; + (*field)->init(table); } for (key=0 ; key < table->s->keys ; key++) { @@ -3295,7 +3313,7 @@ static bool reattach_merge(THD *thd) DBUG_PRINT("tcache", ("MERGE parent, attach children")); if (table->file->extra(HA_EXTRA_ATTACH_CHILDREN)) { - my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr()); error= TRUE; mark_merge_parent_and_children_as_bad(table); } @@ -3388,7 +3406,6 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old) */ if (table->child_l && !table->children_attached) merge_table_found= TRUE; - if (!tables) { /* @@ -3448,8 +3465,7 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old) } continue; } - my_error(ER_CANT_REOPEN_TABLE, MYF(0), - table->alias ? table->alias : table->s->table_name.str); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr()); unlink_open_table(thd, table, 0); /* Restart loop, as one of the used tables may now be closed */ prev= &thd->open_tables; @@ -3652,7 +3668,7 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock) char *key= table->s->table_cache_key.str; uint key_length= table->s->table_cache_key.length; - DBUG_PRINT("loop", ("table_name: %s", table->alias ? table->alias : "")); + DBUG_PRINT("loop", ("table_name: %s", table->alias.c_ptr())); HASH_SEARCH_STATE state; for (TABLE *search= (TABLE*) hash_first(&open_cache, (uchar*) key, key_length, &state); @@ -4446,7 +4462,7 @@ void detach_merge_children(TABLE *table, bool clear_refs) Set alias to "" to ensure that table is not used if we are in LOCK TABLES */ - ((char*) child_l->table->alias)[0]= 0; + child_l->table->alias.length(0); /* Clear the table reference to force new assignment at next open. */ child_l->table= NULL; @@ -4999,7 +5015,7 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table, if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ && (int) table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ) { - my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias); + my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias.c_ptr()); DBUG_RETURN(1); } if ((error=table->file->start_stmt(thd, lock_type))) @@ -5830,6 +5846,9 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table) table->covering_keys.intersect(field->part_of_key); table->merge_keys.merge(field->part_of_key); + if (field->vcol_info) + table->mark_virtual_col(field); + if (thd->mark_used_columns == MARK_COLUMNS_READ) bitmap= table->read_set; else @@ -6110,7 +6129,8 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length, Field **field_ptr, *field; uint cached_field_index= *cached_field_index_ptr; DBUG_ENTER("find_field_in_table"); - DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias, name)); + DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias.c_ptr(), + name)); /* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */ if (cached_field_index < table->s->fields && @@ -8138,6 +8158,12 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, { /* Mark fields as used to allow storage engine to optimze access */ bitmap_set_bit(field->table->read_set, field->field_index); + /* + Mark virtual fields for write and others that the virtual fields + depend on for read. + */ + if (field->vcol_info) + field->table->mark_virtual_col(field); if (table) { table->covering_keys.intersect(field->part_of_key); @@ -8348,7 +8374,8 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values, List_iterator_fast<Item> f(fields),v(values); Item *value, *fld; Item_field *field; - TABLE *table= 0; + TABLE *table= 0, *vcol_table= 0; + bool abort_on_warning_saved= thd->abort_on_warning; DBUG_ENTER("fill_record"); /* @@ -8371,6 +8398,8 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values, table->auto_increment_field_not_null= FALSE; f.rewind(); } + else if (thd->lex->unit.insert_table_with_stored_vcol) + vcol_table= thd->lex->unit.insert_table_with_stored_vcol; while ((fld= f++)) { if (!(field= fld->filed_for_view_update())) @@ -8383,14 +8412,40 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values, table= rfield->table; if (rfield == table->next_number_field) table->auto_increment_field_not_null= TRUE; + if (rfield->vcol_info && + value->type() != Item::DEFAULT_VALUE_ITEM && + value->type() != Item::NULL_ITEM && + table->s->table_category != TABLE_CATEGORY_TEMPORARY) + { + thd->abort_on_warning= FALSE; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN, + ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN), + rfield->field_name, table->s->table_name.str); + thd->abort_on_warning= abort_on_warning_saved; + } if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors) { my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0)); goto err; } + DBUG_ASSERT(vcol_table == 0 || vcol_table == table); + vcol_table= table; } + /* Update virtual fields*/ + thd->abort_on_warning= FALSE; + if (vcol_table) + { + if (vcol_table->vfield) + { + if (update_virtual_fields(thd, vcol_table, TRUE)) + goto err; + } + } + thd->abort_on_warning= abort_on_warning_saved; DBUG_RETURN(thd->is_error()); err: + thd->abort_on_warning= abort_on_warning_saved; if (table) table->auto_increment_field_not_null= FALSE; DBUG_RETURN(TRUE); @@ -8426,9 +8481,31 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields, Table_triggers_list *triggers, enum trg_event_type event) { - return (fill_record(thd, fields, values, ignore_errors) || - (triggers && triggers->process_triggers(thd, event, - TRG_ACTION_BEFORE, TRUE))); + bool result; + result= (fill_record(thd, fields, values, ignore_errors) || + (triggers && triggers->process_triggers(thd, event, + TRG_ACTION_BEFORE, TRUE))); + /* + Re-calculate virtual fields to cater for cases when base columns are + updated by the triggers. + */ + if (!result && triggers) + { + TABLE *table= 0; + List_iterator_fast<Item> f(fields); + Item *fld; + Item_field *item_field; + if (fields.elements) + { + fld= (Item_field*)f++; + item_field= fld->filed_for_view_update(); + if (item_field && item_field->field && + (table= item_field->field->table) && + table->vfield) + result= update_virtual_fields(thd, table, TRUE); + } + } + return result; } @@ -8456,38 +8533,63 @@ bool fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors) { List_iterator_fast<Item> v(values); + List<TABLE> tbl_list; Item *value; TABLE *table= 0; + Field *field; + bool abort_on_warning_saved= thd->abort_on_warning; DBUG_ENTER("fill_record"); - Field *field; + if (!*ptr) + { + /* No fields to update, quite strange!*/ + DBUG_RETURN(0); + } + + /* + On INSERT or UPDATE fields are checked to be from the same table, + thus we safely can take table from the first field. + */ + table= (*ptr)->table; + /* Reset the table->auto_increment_field_not_null as it is valid for only one row. */ - if (*ptr) - { - /* - On INSERT or UPDATE fields are checked to be from the same table, - thus we safely can take table from the first field. - */ - table= (*ptr)->table; - table->auto_increment_field_not_null= FALSE; - } + table->auto_increment_field_not_null= FALSE; while ((field = *ptr++) && ! thd->is_error()) { + /* Ensure that all fields are from the same table */ + DBUG_ASSERT(field->table == table); + value=v++; - table= field->table; if (field == table->next_number_field) table->auto_increment_field_not_null= TRUE; + if (field->vcol_info && + value->type() != Item::DEFAULT_VALUE_ITEM && + value->type() != Item::NULL_ITEM && + table->s->table_category != TABLE_CATEGORY_TEMPORARY) + { + thd->abort_on_warning= FALSE; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN, + ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN), + field->field_name, table->s->table_name.str); + thd->abort_on_warning= abort_on_warning_saved; + } if (value->save_in_field(field, 0) < 0) goto err; } + /* Update virtual fields*/ + thd->abort_on_warning= FALSE; + if (table->vfield && update_virtual_fields(thd, table, TRUE)) + goto err; + thd->abort_on_warning= abort_on_warning_saved; DBUG_RETURN(thd->is_error()); err: - if (table) - table->auto_increment_field_not_null= FALSE; + thd->abort_on_warning= abort_on_warning_saved; + table->auto_increment_field_not_null= FALSE; DBUG_RETURN(TRUE); } @@ -8521,9 +8623,22 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr, Table_triggers_list *triggers, enum trg_event_type event) { - return (fill_record(thd, ptr, values, ignore_errors) || - (triggers && triggers->process_triggers(thd, event, - TRG_ACTION_BEFORE, TRUE))); + bool result; + result= (fill_record(thd, ptr, values, ignore_errors) || + (triggers && triggers->process_triggers(thd, event, + TRG_ACTION_BEFORE, TRUE))); + /* + Re-calculate virtual fields to cater for cases when base columns are + updated by the triggers. + */ + if (!result && triggers && *ptr) + { + TABLE *table= (*ptr)->table; + if (table->vfield) + result= update_virtual_fields(thd, table, TRUE); + } + return result; + } @@ -8724,7 +8839,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, { if (!in_use->killed) { - in_use->killed= THD::KILL_CONNECTION; + in_use->killed= THD::KILL_SYSTEM_THREAD; pthread_mutex_lock(&in_use->mysys_var->mutex); if (in_use->mysys_var->current_cond) { @@ -9058,7 +9173,7 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) && ! in_use->killed) { - in_use->killed= THD::KILL_CONNECTION; + in_use->killed= THD::KILL_SYSTEM_THREAD; pthread_mutex_lock(&in_use->mysys_var->mutex); if (in_use->mysys_var->current_cond) { diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index e07806a56ab..5385acc934f 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -60,13 +60,13 @@ public: } void subtract(Bitmap& map2) { bitmap_subtract(&map, &map2.map); } void merge(Bitmap& map2) { bitmap_union(&map, &map2.map); } - my_bool is_set(uint n) const { return bitmap_is_set(&map, n); } - my_bool is_prefix(uint n) const { return bitmap_is_prefix(&map, n); } - my_bool is_clear_all() const { return bitmap_is_clear_all(&map); } - my_bool is_set_all() const { return bitmap_is_set_all(&map); } - my_bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); } - my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, &map2.map); } - my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); } + bool is_set(uint n) const { return bitmap_is_set(&map, n); } + bool is_prefix(uint n) const { return bitmap_is_prefix(&map, n); } + bool is_clear_all() const { return bitmap_is_clear_all(&map); } + bool is_set_all() const { return bitmap_is_set_all(&map); } + bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); } + bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, &map2.map); } + bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); } char *print(char *buf) const { char *s=buf; @@ -155,14 +155,14 @@ public: void intersect_extended(ulonglong map2) { map&= map2; } void subtract(Bitmap<64>& map2) { map&= ~map2.map; } void merge(Bitmap<64>& map2) { map|= map2.map; } - my_bool is_set(uint n) const { return test(map & (((ulonglong)1) << n)); } - my_bool is_prefix(uint n) const { return map == (((ulonglong)1) << n)-1; } - my_bool is_clear_all() const { return map == (ulonglong)0; } - my_bool is_set_all() const { return map == ~(ulonglong)0; } - my_bool is_subset(const Bitmap<64>& map2) const { return !(map & ~map2.map); } - my_bool is_overlapping(const Bitmap<64>& map2) const { return (map & map2.map)!= 0; } - my_bool operator==(const Bitmap<64>& map2) const { return map == map2.map; } - char *print(char *buf) const { longlong2str(map,buf,16); return buf; } + bool is_set(uint n) const { return test(map & (((ulonglong)1) << n)); } + bool is_prefix(uint n) const { return map == (((ulonglong)1) << n)-1; } + bool is_clear_all() const { return map == (ulonglong)0; } + bool is_set_all() const { return map == ~(ulonglong)0; } + bool is_subset(const Bitmap<64>& map2) const { return !(map & ~map2.map); } + bool is_overlapping(const Bitmap<64>& map2) const { return (map & map2.map)!= 0; } + bool operator==(const Bitmap<64>& map2) const { return map == map2.map; } + char *print(char *buf) const { longlong2str(map,buf,16,1); return buf; } ulonglong to_ulonglong() const { return map; } class Iterator : public Table_map_iterator { diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in index 7ecd4918d7b..3ba47e3a14e 100644 --- a/sql/sql_builtin.cc.in +++ b/sql/sql_builtin.cc.in @@ -16,13 +16,12 @@ #include <my_global.h> #include <mysql/plugin.h> -typedef struct st_mysql_plugin builtin_plugin[]; +typedef struct st_maria_plugin builtin_maria_plugin[]; -extern builtin_plugin - builtin_binlog_plugin@mysql_plugin_defs@; +extern builtin_maria_plugin + builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@; -struct st_mysql_plugin *mysqld_builtins[]= +struct st_maria_plugin *mariadb_builtins[]= { - builtin_binlog_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0 + builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@,(struct st_maria_plugin *)0 }; - diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 4a073aa0485..de9447fa356 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -742,7 +742,7 @@ inline void Query_cache_query::lock_writing() remove it. */ -my_bool Query_cache_query::try_lock_writing() +bool Query_cache_query::try_lock_writing() { DBUG_ENTER("Query_cache_block::try_lock_writing"); if (rw_trywrlock(&lock)!=0) @@ -2279,6 +2279,18 @@ void Query_cache::free_cache() { DBUG_ENTER("Query_cache::free_cache"); + /* Destroy locks */ + Query_cache_block *block= queries_blocks; + if (block) + { + do + { + Query_cache_query *query= block->query(); + rwlock_destroy(&query->lock); + block= block->next; + } while (block != queries_blocks); + } + my_free((uchar*) cache, MYF(MY_ALLOW_ZERO_PTR)); make_disabled(); hash_free(&queries); diff --git a/sql/sql_cache.h b/sql/sql_cache.h index 1d98ae2e094..a3a91127129 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -124,7 +124,7 @@ struct Query_cache_block block_type type; TABLE_COUNTER_TYPE n_tables; // number of tables in query - inline my_bool is_free(void) { return type == FREE; } + inline bool is_free(void) { return type == FREE; } void init(ulong length); void destroy(); inline uint headers_len(); @@ -165,7 +165,7 @@ struct Query_cache_query } void lock_writing(); void lock_reading(); - my_bool try_lock_writing(); + bool try_lock_writing(); void unlock_writing(); void unlock_reading(); }; @@ -315,7 +315,7 @@ protected: uint mem_bin_num, mem_bin_steps; // See at init_cache & find_bin - my_bool initialized; + bool initialized; /* Exclude/include from cyclic double linked list */ static void double_linked_list_exclude(Query_cache_block *point, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 49710d5dbcc..a31c4728720 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -110,6 +110,7 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_root) key_create_info(rhs.key_create_info), columns(rhs.columns, mem_root), name(rhs.name), + option_list(rhs.option_list), generated(rhs.generated) { list_copy_and_replace_each_value(columns, mem_root); @@ -199,6 +200,59 @@ bool foreign_key_prefix(Key *a, Key *b) #endif } +/* + @brief + Check if the foreign key options are compatible with the specification + of the columns on which the key is created + + @retval + FALSE The foreign key options are compatible with key columns + @retval + TRUE Otherwise +*/ +bool Foreign_key::validate(List<Create_field> &table_fields) +{ + Create_field *sql_field; + Key_part_spec *column; + List_iterator<Key_part_spec> cols(columns); + List_iterator<Create_field> it(table_fields); + DBUG_ENTER("Foreign_key::validate"); + while ((column= cols++)) + { + it.rewind(); + while ((sql_field= it++) && + my_strcasecmp(system_charset_info, + column->field_name, + sql_field->field_name)) {} + if (!sql_field) + { + my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name); + DBUG_RETURN(TRUE); + } + if (type == Key::FOREIGN_KEY && sql_field->vcol_info) + { + if (delete_opt == FK_OPTION_SET_NULL) + { + my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0), + "ON DELETE SET NULL"); + DBUG_RETURN(TRUE); + } + if (update_opt == FK_OPTION_SET_NULL) + { + my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0), + "ON UPDATE SET NULL"); + DBUG_RETURN(TRUE); + } + if (update_opt == FK_OPTION_CASCADE) + { + my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0), + "ON UPDATE CASCADE"); + DBUG_RETURN(TRUE); + } + } + } + DBUG_RETURN(FALSE); +} /**************************************************************************** ** Thread specific functions @@ -610,7 +664,7 @@ THD::THD() Open_tables_state(refresh_version), rli_fake(0), lock_id(&main_lock_id), user_time(0), in_sub_stmt(0), - sql_log_bin_toplevel(false), + sql_log_bin_toplevel(false), log_all_errors(0), binlog_table_maps(0), binlog_flags(0UL), table_map_for_update(0), arg_of_last_insert_id_function(FALSE), @@ -683,6 +737,7 @@ THD::THD() mysys_var=0; binlog_evt_union.do_union= FALSE; enable_slow_log= 0; + #ifndef DBUG_OFF dbug_sentry=THD_SENTRY_MAGIC; #endif @@ -750,6 +805,7 @@ THD::THD() thr_lock_owner_init(&main_lock_id, &lock_info); m_internal_handler= NULL; + arena_for_cached_items= 0; m_binlog_invoker= FALSE; memset(&invoker_user, 0, sizeof(invoker_user)); memset(&invoker_host, 0, sizeof(invoker_host)); @@ -758,6 +814,7 @@ THD::THD() void THD::push_internal_handler(Internal_error_handler *handler) { + DBUG_ENTER("THD::push_internal_handler"); if (m_internal_handler) { handler->m_prev_internal_handler= m_internal_handler; @@ -767,6 +824,7 @@ void THD::push_internal_handler(Internal_error_handler *handler) { m_internal_handler= handler; } + DBUG_VOID_RETURN; } @@ -786,10 +844,11 @@ bool THD::handle_error(uint sql_errno, const char *message, Internal_error_handler *THD::pop_internal_handler() { + DBUG_ENTER("THD::pop_internal_handler"); DBUG_ASSERT(m_internal_handler != NULL); Internal_error_handler *popped_handler= m_internal_handler; m_internal_handler= m_internal_handler->m_prev_internal_handler; - return popped_handler; + DBUG_RETURN(popped_handler); } extern "C" @@ -886,14 +945,65 @@ void THD::init(void) update_charset(); reset_current_stmt_binlog_row_based(); bzero((char *) &status_var, sizeof(status_var)); + bzero((char *) &org_status_var, sizeof(org_status_var)); sql_log_bin_toplevel= options & OPTION_BIN_LOG; - + select_commands= update_commands= other_commands= 0; + /* Set to handle counting of aborted connections */ + userstat_running= opt_userstat_running; + last_global_update_time= current_connect_time= time(NULL); #if defined(ENABLED_DEBUG_SYNC) /* Initialize the Debug Sync Facility. See debug_sync.cc. */ debug_sync_init_thread(this); #endif /* defined(ENABLED_DEBUG_SYNC) */ } + +/* Updates some status variables to be used by update_global_user_stats */ + +void THD::update_stats(void) +{ + /* sql_command == SQLCOM_END in case of parse errors or quit */ + if (lex->sql_command != SQLCOM_END) + { + /* A SQL query. */ + if (lex->sql_command == SQLCOM_SELECT) + select_commands++; + else if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) + { + /* Ignore 'SHOW ' commands */ + } + else if (is_update_query(lex->sql_command)) + update_commands++; + else + other_commands++; + } +} + + +void THD::update_all_stats() +{ + time_t save_time; + ulonglong end_cpu_time, end_utime; + double busy_time, cpu_time; + + /* This is set at start of query if opt_userstat_running was set */ + if (!userstat_running) + return; + + end_cpu_time= my_getcputime(); + end_utime= my_micro_time_and_time(&save_time); + busy_time= (end_utime - start_utime) / 1000000.0; + cpu_time= (end_cpu_time - start_cpu_time) / 10000000.0; + /* In case there are bad values, 2629743 is the #seconds in a month. */ + if (cpu_time > 2629743.0) + cpu_time= 0; + status_var_add(status_var.cpu_time, cpu_time); + status_var_add(status_var.busy_time, busy_time); + + update_global_user_stats(this, TRUE, save_time); + userstat_running= 0; +} + /* Init THD for query processing. @@ -971,6 +1081,11 @@ void THD::cleanup(void) lock=locked_tables; locked_tables=0; close_thread_tables(this); } + if (user_connect) + { + decrease_user_connections(user_connect); + user_connect= 0; // Safety + } wt_thd_destroy(&transaction.wt); #if defined(ENABLED_DEBUG_SYNC) @@ -1064,9 +1179,8 @@ THD::~THD() from_var from this array NOTES - This function assumes that all variables are long/ulong. - If this assumption will change, then we have to explictely add - the other variables after the while loop + This function assumes that all variables at start are long/ulong and + other types are handled explicitely */ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var) @@ -1079,8 +1193,14 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var) while (to != end) *(to++)+= *(from++); - to_var->bytes_received+= from_var->bytes_received; - to_var->bytes_sent+= from_var->bytes_sent; + /* Handle the not ulong variables. See end of system_status_var */ + to_var->bytes_received+= from_var->bytes_received; + to_var->bytes_sent+= from_var->bytes_sent; + to_var->rows_read+= from_var->rows_read; + to_var->rows_sent+= from_var->rows_sent; + to_var->binlog_bytes_written+= from_var->binlog_bytes_written; + to_var->cpu_time+= from_var->cpu_time; + to_var->busy_time+= from_var->busy_time; } /* @@ -1093,7 +1213,8 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var) dec_var minus this array NOTE - This function assumes that all variables are long/ulong. + This function assumes that all variables at start are long/ulong and + other types are handled explicitely */ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, @@ -1107,8 +1228,15 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, while (to != end) *(to++)+= *(from++) - *(dec++); - to_var->bytes_received+= from_var->bytes_received - dec_var->bytes_received;; - to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent; + to_var->bytes_received+= from_var->bytes_received - + dec_var->bytes_received; + to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent; + to_var->rows_read+= from_var->rows_read - dec_var->rows_read; + to_var->rows_sent+= from_var->rows_sent - dec_var->rows_sent; + to_var->binlog_bytes_written+= from_var->binlog_bytes_written - + dec_var->binlog_bytes_written; + to_var->cpu_time+= from_var->cpu_time - dec_var->cpu_time; + to_var->busy_time+= from_var->busy_time - dec_var->busy_time; } #define SECONDS_TO_WAIT_FOR_KILL 2 @@ -1127,6 +1255,15 @@ void THD::awake(THD::killed_state state_to_set) THD_CHECK_SENTRY(this); safe_mutex_assert_owner(&LOCK_thd_data); + if (global_system_variables.log_warnings > 3) + { + Security_context *sctx= security_ctx; + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), + thread_id,(db ? db : "unconnected"), + sctx->user ? sctx->user : "unauthenticated", + sctx->host_or_ip, + "KILLED"); + } killed= state_to_set; if (state_to_set != THD::KILL_QUERY) { @@ -2472,26 +2609,32 @@ bool select_max_min_finder_subselect::cmp_real() { Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0); double val1= cache->val_real(), val2= maxmin->val_real(); + + /* Ignore NULLs for ANY and keep them for ALL subqueries */ + if (cache->null_value) + return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value); + if (maxmin->null_value) + return !is_all; + if (fmax) - return (cache->null_value && !maxmin->null_value) || - (!cache->null_value && !maxmin->null_value && - val1 > val2); - return (maxmin->null_value && !cache->null_value) || - (!cache->null_value && !maxmin->null_value && - val1 < val2); + return(val1 > val2); + return (val1 < val2); } bool select_max_min_finder_subselect::cmp_int() { Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0); longlong val1= cache->val_int(), val2= maxmin->val_int(); + + /* Ignore NULLs for ANY and keep them for ALL subqueries */ + if (cache->null_value) + return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value); + if (maxmin->null_value) + return !is_all; + if (fmax) - return (cache->null_value && !maxmin->null_value) || - (!cache->null_value && !maxmin->null_value && - val1 > val2); - return (maxmin->null_value && !cache->null_value) || - (!cache->null_value && !maxmin->null_value && - val1 < val2); + return(val1 > val2); + return (val1 < val2); } bool select_max_min_finder_subselect::cmp_decimal() @@ -2499,13 +2642,16 @@ bool select_max_min_finder_subselect::cmp_decimal() Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0); my_decimal cval, *cvalue= cache->val_decimal(&cval); my_decimal mval, *mvalue= maxmin->val_decimal(&mval); + + /* Ignore NULLs for ANY and keep them for ALL subqueries */ + if (cache->null_value) + return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value); + if (maxmin->null_value) + return !is_all; + if (fmax) - return (cache->null_value && !maxmin->null_value) || - (!cache->null_value && !maxmin->null_value && - my_decimal_cmp(cvalue, mvalue) > 0) ; - return (maxmin->null_value && !cache->null_value) || - (!cache->null_value && !maxmin->null_value && - my_decimal_cmp(cvalue,mvalue) < 0); + return (my_decimal_cmp(cvalue, mvalue) > 0) ; + return (my_decimal_cmp(cvalue,mvalue) < 0); } bool select_max_min_finder_subselect::cmp_str() @@ -2518,13 +2664,16 @@ bool select_max_min_finder_subselect::cmp_str() */ val1= cache->val_str(&buf1); val2= maxmin->val_str(&buf1); + + /* Ignore NULLs for ANY and keep them for ALL subqueries */ + if (cache->null_value) + return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value); + if (maxmin->null_value) + return !is_all; + if (fmax) - return (cache->null_value && !maxmin->null_value) || - (!cache->null_value && !maxmin->null_value && - sortcmp(val1, val2, cache->collation.collation) > 0) ; - return (maxmin->null_value && !cache->null_value) || - (!cache->null_value && !maxmin->null_value && - sortcmp(val1, val2, cache->collation.collation) < 0); + return (sortcmp(val1, val2, cache->collation.collation) > 0) ; + return (sortcmp(val1, val2, cache->collation.collation) < 0); } int select_exists_subselect::send_data(List<Item> &items) @@ -2952,7 +3101,8 @@ void thd_increment_bytes_sent(ulong length) { THD *thd=current_thd; if (likely(thd != 0)) - { /* current_thd==0 when close_connection() calls net_send_error() */ + { + /* current_thd == 0 when close_connection() calls net_send_error() */ thd->status_var.bytes_sent+= length; } } @@ -2978,9 +3128,9 @@ void THD::set_status_var_init() void Security_context::init() { - host= user= priv_user= ip= 0; + host= user= ip= 0; host_or_ip= "connecting host"; - priv_host[0]= '\0'; + priv_user[0]= priv_host[0]= '\0'; master_access= 0; #ifndef NO_EMBEDDED_ACCESS_CHECKS db_access= NO_ACCESS; @@ -3004,8 +3154,7 @@ void Security_context::skip_grants() /* privileges for the user are unknown everything is allowed */ host_or_ip= (char *)""; master_access= ~NO_ACCESS; - priv_user= (char *)""; - *priv_host= '\0'; + *priv_user= *priv_host= '\0'; } @@ -3047,7 +3196,7 @@ bool Security_context::set_user(char *user_arg) of a statement under credentials of a different user, e.g. definer of a procedure, we authenticate this user in a local instance of Security_context by means of this method (and - ultimately by means of acl_getroot_no_password), and make the + ultimately by means of acl_getroot), and make the local instance active in the thread by re-setting thd->security_ctx pointer. @@ -3081,19 +3230,12 @@ change_security_context(THD *thd, DBUG_ASSERT(definer_user->str && definer_host->str); *backup= NULL; - /* - The current security context may have NULL members - if we have just started the thread and not authenticated - any user. This use case is currently in events worker thread. - */ - needs_change= (thd->security_ctx->priv_user == NULL || - strcmp(definer_user->str, thd->security_ctx->priv_user) || - thd->security_ctx->priv_host == NULL || + needs_change= (strcmp(definer_user->str, thd->security_ctx->priv_user) || my_strcasecmp(system_charset_info, definer_host->str, thd->security_ctx->priv_host)); if (needs_change) { - if (acl_getroot_no_password(this, definer_user->str, definer_host->str, + if (acl_getroot(this, definer_user->str, definer_host->str, definer_host->str, db->str)) { my_error(ER_NO_SUCH_USER, MYF(0), definer_user->str, @@ -3167,7 +3309,10 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) */ extern "C" int thd_killed(const MYSQL_THD thd) { - return(thd->killed); + if (thd->killed == THD::NOT_KILLED || thd->killed == THD::KILL_BAD_DATA || + thd->killed == THD::KILL_SYSTEM_THREAD) + return 0; + return thd->killed; } /** @@ -3182,7 +3327,7 @@ extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd) #ifdef INNODB_COMPATIBILITY_HOOKS -extern "C" struct charset_info_st *thd_charset(MYSQL_THD thd) +extern "C" const struct charset_info_st *thd_charset(MYSQL_THD thd) { return(thd->charset()); } @@ -3406,8 +3551,9 @@ void THD::get_definer(LEX_USER *definer) { definer->user = invoker_user; definer->host= invoker_host; - definer->password.str= NULL; - definer->password.length= 0; + definer->password= null_lex_str; + definer->plugin= empty_lex_str; + definer->auth= empty_lex_str; } else #endif @@ -3973,8 +4119,8 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, int errcode) { DBUG_ENTER("THD::binlog_query"); - DBUG_PRINT("enter", ("qtype: %s query: '%s'", - show_query_type(qtype), query_arg)); + DBUG_PRINT("enter", ("qtype: %s query: '%-.*s'", + show_query_type(qtype), (int) query_len, query_arg)); DBUG_ASSERT(query_arg && mysql_bin_log.is_open()); /* @@ -4010,7 +4156,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, { sql_print_warning("%s Statement: %.*s", ER(ER_BINLOG_UNSAFE_STATEMENT), - MYSQL_ERRMSG_SIZE, query_arg); + (int) min(MYSQL_ERRMSG_SIZE, query_len), query_arg); binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED; } } diff --git a/sql/sql_class.h b/sql/sql_class.h index 40a5d61e433..4bf1bc3964c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -209,13 +209,15 @@ public: KEY_CREATE_INFO key_create_info; List<Key_part_spec> columns; const char *name; + engine_option_value *option_list; bool generated; Key(enum Keytype type_par, const char *name_arg, KEY_CREATE_INFO *key_info_arg, - bool generated_arg, List<Key_part_spec> &cols) + bool generated_arg, List<Key_part_spec> &cols, + engine_option_value *create_opt) :type(type_par), key_create_info(*key_info_arg), columns(cols), - name(name_arg), generated(generated_arg) + name(name_arg), option_list(create_opt), generated(generated_arg) {} Key(const Key &rhs, MEM_ROOT *mem_root); virtual ~Key() {} @@ -244,7 +246,7 @@ public: Foreign_key(const char *name_arg, List<Key_part_spec> &cols, Table_ident *table, List<Key_part_spec> &ref_cols, uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) - :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols), + :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL), ref_table(table), ref_columns(ref_cols), delete_opt(delete_opt_arg), update_opt(update_opt_arg), match_opt(match_opt_arg) @@ -256,6 +258,8 @@ public: */ virtual Key *clone(MEM_ROOT *mem_root) const { return new (mem_root) Foreign_key(*this, mem_root); } + /* Used to validate foreign key options */ + bool validate(List<Create_field> &table_fields); }; typedef struct st_mysql_lock @@ -295,6 +299,9 @@ struct system_variables When attempting to access a dynamic variable, if the session version is out of date, then the session version is updated and realloced if neccessary and bytes copied from global to make up for missing data. + + Note that one should use my_bool instead of bool here, as the variables + are used with my_getopt.c */ ulong dynamic_variables_version; char* dynamic_variables_ptr; @@ -339,7 +346,6 @@ struct system_variables ulong read_rnd_buff_size; ulong div_precincrement; ulong sortbuff_size; - ulong thread_handling; ulong tx_isolation; ulong completion_type; /* Determines which non-standard SQL behaviour should be enabled */ @@ -478,25 +484,31 @@ typedef struct system_status_var ulong com_stmt_fetch; ulong com_stmt_reset; ulong com_stmt_close; + ulong empty_queries; + ulong access_denied_errors; + ulong lost_connections; /* Number of statements sent from the client */ ulong questions; - - ulonglong bytes_received; - ulonglong bytes_sent; /* IMPORTANT! SEE last_system_status_var DEFINITION BELOW. Below 'last_system_status_var' are all variables that cannot be handled automatically by add_to_status()/add_diff_to_status(). */ + ulonglong bytes_received; + ulonglong bytes_sent; + ulonglong rows_read; + ulonglong rows_sent; + ulonglong binlog_bytes_written; double last_query_cost; + double cpu_time, busy_time; } STATUS_VAR; /* This is used for 'SHOW STATUS'. It must be updated to the last ulong - variable in system_status_var which is makes sens to add to the global + variable in system_status_var which is makes sense to add to the global counter */ @@ -669,7 +681,7 @@ public: Server_side_cursor *cursor; inline char *query() { return query_string.str; } - inline uint32 query_length() { return query_string.length; } + inline uint32 query_length() { return (uint32)query_string.length; } void set_query_inner(char *query_arg, uint32 query_length_arg); /** @@ -804,7 +816,8 @@ public: priv_user - The user privilege we are using. May be "" for anonymous user. ip - client IP */ - char *host, *user, *priv_user, *ip; + char *host, *user, *ip; + char priv_user[USERNAME_LENGTH]; /* The host privilege we are using */ char priv_host[MAX_HOSTNAME]; /* points to host if host is available, otherwise points to ip */ @@ -1353,6 +1366,7 @@ public: struct my_rnd_struct rand; // used for authentication struct system_variables variables; // Changeable local variables struct system_status_var status_var; // Per thread statistic vars + struct system_status_var org_status_var; // For user statistics struct system_status_var *initial_status_var; /* used by show status */ THR_LOCK_INFO lock_info; // Locking info of this thread THR_LOCK_OWNER main_lock_id; // To use for conventional queries @@ -1453,6 +1467,10 @@ public: uint in_sub_stmt; /* TRUE when the current top has SQL_LOG_BIN ON */ bool sql_log_bin_toplevel; + /* True when opt_userstat_running is set at start of query */ + bool userstat_running; + /* True if we want to log all errors */ + bool log_all_errors; /* container for handler's private per-connection data */ Ha_data ha_data[MAX_HA]; @@ -1815,7 +1833,9 @@ public: NOT_KILLED=0, KILL_BAD_DATA=1, KILL_CONNECTION=ER_SERVER_SHUTDOWN, + KILL_SYSTEM_THREAD=ER_NEW_ABORTING_CONNECTION, /* Kill connection nicely */ KILL_QUERY=ER_QUERY_INTERRUPTED, + KILL_SERVER, /* Placeholder for shortdown */ KILLED_NO_VALUE /* means neither of the states */ }; killed_state volatile killed; @@ -1880,7 +1900,7 @@ public: bool no_warnings_for_error; /* no warnings on call to my_error() */ /* set during loop of derived table processing */ bool derived_tables_processing; - my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ + bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ sp_rcontext *spcont; // SP runtime context sp_cache *sp_proc_cache; @@ -1896,6 +1916,21 @@ public: */ LOG_INFO* current_linfo; NET* slave_net; // network connection from slave -> m. + + /* + Used to update global user stats. The global user stats are updated + occasionally with the 'diff' variables. After the update, the 'diff' + variables are reset to 0. + */ + /* Time when the current thread connected to MySQL. */ + time_t current_connect_time; + /* Last time when THD stats were updated in global_user_stats. */ + time_t last_global_update_time; + /* Number of commands not reflected in global_user_stats yet. */ + uint select_commands, update_commands, other_commands; + ulonglong start_cpu_time; + ulonglong start_bytes_received; + /* Used by the sys_var class to store temporary values */ union { @@ -1961,6 +1996,8 @@ public: alloc_root. */ void init_for_queries(); + void update_all_stats(); + void update_stats(void); void change_user(void); void cleanup(void); void cleanup_after_query(); @@ -2395,6 +2432,27 @@ public: LEX_STRING get_invoker_user() { return invoker_user; } LEX_STRING get_invoker_host() { return invoker_host; } bool has_invoker() { return invoker_user.length > 0; } + +private: + /* + This reference points to the table arena when the expression + for a virtual column is being evaluated + */ + Query_arena *arena_for_cached_items; + +public: + void reset_arena_for_cached_items(Query_arena *new_arena) + { + arena_for_cached_items= new_arena; + } + Query_arena *switch_to_arena_for_cached_items(Query_arena *backup) + { + if (!arena_for_cached_items) + return 0; + set_n_backup_active_arena(arena_for_cached_items, backup); + return backup; + } + private: /** The current internal error handler for this thread, or NULL. */ Internal_error_handler *m_internal_handler; @@ -2435,7 +2493,6 @@ private: LEX_STRING invoker_host; }; - /** A short cut for thd->main_da.set_ok_status(). */ inline void @@ -2734,7 +2791,7 @@ public: }; -#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES) +#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES) #include <maria.h> #define ENGINE_COLUMNDEF MARIA_COLUMNDEF #else @@ -2872,9 +2929,11 @@ class select_max_min_finder_subselect :public select_subselect Item_cache *cache; bool (select_max_min_finder_subselect::*op)(); bool fmax; + bool is_all; public: - select_max_min_finder_subselect(Item_subselect *item_arg, bool mx) - :select_subselect(item_arg), cache(0), fmax(mx) + select_max_min_finder_subselect(Item_subselect *item_arg, bool mx, + bool all) + :select_subselect(item_arg), cache(0), fmax(mx), is_all(all) {} void cleanup(); int send_data(List<Item> &items); @@ -2969,10 +3028,10 @@ class user_var_entry Item_result type; bool unsigned_flag; - double val_real(my_bool *null_value); - longlong val_int(my_bool *null_value) const; - String *val_str(my_bool *null_value, String *str, uint decimals); - my_decimal *val_decimal(my_bool *null_value, my_decimal *result); + double val_real(bool *null_value); + longlong val_int(bool *null_value) const; + String *val_str(bool *null_value, String *str, uint decimals); + my_decimal *val_decimal(bool *null_value, my_decimal *result); DTCollation collation; }; @@ -3179,4 +3238,150 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, STATUS_VAR *dec_var); void mark_transaction_to_rollback(THD *thd, bool all); +/* + inline handler methods that need to know TABLE and THD structures +*/ +inline void handler::increment_statistics(ulong SSV::*offset) const +{ + status_var_increment(table->in_use->status_var.*offset); +} + +inline void handler::decrement_statistics(ulong SSV::*offset) const +{ + status_var_decrement(table->in_use->status_var.*offset); +} + +inline int handler::ha_index_read_map(uchar * buf, const uchar * key, + key_part_map keypart_map, + enum ha_rkey_function find_flag) +{ + DBUG_ASSERT(inited==INDEX); + increment_statistics(&SSV::ha_read_key_count); + int error= index_read_map(buf, key, keypart_map, find_flag); + if (!error) + update_index_statistics(); + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_index_read_idx_map(uchar * buf, uint index, + const uchar * key, + key_part_map keypart_map, + enum ha_rkey_function find_flag) +{ + increment_statistics(&SSV::ha_read_key_count); + int error= index_read_idx_map(buf, index, key, keypart_map, find_flag); + if (!error) + { + rows_read++; + index_rows_read[index]++; + } + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_index_next(uchar * buf) +{ + DBUG_ASSERT(inited==INDEX); + increment_statistics(&SSV::ha_read_next_count); + int error= index_next(buf); + if (!error) + update_index_statistics(); + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_index_prev(uchar * buf) +{ + DBUG_ASSERT(inited==INDEX); + increment_statistics(&SSV::ha_read_prev_count); + int error= index_prev(buf); + if (!error) + update_index_statistics(); + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_index_first(uchar * buf) +{ + DBUG_ASSERT(inited==INDEX); + increment_statistics(&SSV::ha_read_first_count); + int error= index_first(buf); + if (!error) + update_index_statistics(); + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_index_last(uchar * buf) +{ + DBUG_ASSERT(inited==INDEX); + increment_statistics(&SSV::ha_read_last_count); + int error= index_last(buf); + if (!error) + update_index_statistics(); + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_index_next_same(uchar *buf, const uchar *key, + uint keylen) +{ + DBUG_ASSERT(inited==INDEX); + increment_statistics(&SSV::ha_read_next_count); + int error= index_next_same(buf, key, keylen); + if (!error) + update_index_statistics(); + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_ft_read(uchar *buf) +{ + int error= ft_read(buf); + if (!error) + rows_read++; + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_rnd_next(uchar *buf) +{ + increment_statistics(&SSV::ha_read_rnd_next_count); + int error= rnd_next(buf); + if (!error) + rows_read++; + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_rnd_pos(uchar *buf, uchar *pos) +{ + increment_statistics(&SSV::ha_read_rnd_count); + int error= rnd_pos(buf, pos); + if (!error) + rows_read++; + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_rnd_pos_by_record(uchar *buf) +{ + int error= rnd_pos_by_record(buf); + if (!error) + rows_read++; + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + +inline int handler::ha_read_first_row(uchar *buf, uint primary_key) +{ + int error= read_first_row(buf, primary_key); + if (!error) + rows_read++; + table->status=error ? STATUS_NOT_FOUND: 0; + return error; +} + + #endif /* MYSQL_SERVER */ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 7dd15ea731f..e32dde04de0 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -22,23 +22,12 @@ #include "mysql_priv.h" -#ifdef HAVE_OPENSSL -/* - Without SSL the handshake consists of one packet. This packet - has both client capabilites and scrambled password. - With SSL the handshake might consist of two packets. If the first - packet (client capabilities) has CLIENT_SSL flag set, we have to - switch to SSL and read the second packet. The scrambled password - is in the second packet and client_capabilites field will be ignored. - Maybe it is better to accept flags other than CLIENT_SSL from the - second packet? -*/ -#define SSL_HANDSHAKE_SIZE 2 -#define NORMAL_HANDSHAKE_SIZE 6 -#define MIN_HANDSHAKE_SIZE 2 -#else -#define MIN_HANDSHAKE_SIZE 6 -#endif /* HAVE_OPENSSL */ +HASH global_user_stats, global_client_stats, global_table_stats; +HASH global_index_stats; +/* Protects the above global stats */ +extern pthread_mutex_t LOCK_global_user_client_stats; +extern pthread_mutex_t LOCK_global_table_stats; +extern pthread_mutex_t LOCK_global_index_stats; #ifdef __WIN__ extern void win_install_sigabrt_handler(); @@ -51,9 +40,9 @@ extern void win_install_sigabrt_handler(); #ifndef NO_EMBEDDED_ACCESS_CHECKS static HASH hash_user_connections; -static int get_or_create_user_conn(THD *thd, const char *user, - const char *host, - USER_RESOURCES *mqh) +int get_or_create_user_conn(THD *thd, const char *user, + const char *host, + USER_RESOURCES *mqh) { int return_val= 0; size_t temp_len, user_len; @@ -62,6 +51,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, DBUG_ASSERT(user != 0); DBUG_ASSERT(host != 0); + DBUG_ASSERT(thd->user_connect == 0); user_len= strlen(user); temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1; @@ -119,10 +109,9 @@ end: 1 error */ -static int check_for_max_user_connections(THD *thd, USER_CONN *uc) { - int error=0; + int error= 1; DBUG_ENTER("check_for_max_user_connections"); (void) pthread_mutex_lock(&LOCK_user_conn); @@ -130,7 +119,6 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc) max_user_connections < (uint) uc->connections) { my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user); - error=1; goto end; } time_out_user_resource_limits(thd, uc); @@ -140,7 +128,6 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc) my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_user_connections", (long) uc->user_resources.user_conn); - error= 1; goto end; } if (uc->user_resources.conn_per_hour && @@ -149,10 +136,10 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc) my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_connections_per_hour", (long) uc->user_resources.conn_per_hour); - error=1; goto end; } uc->conn_per_hour++; + error= 0; end: if (error) @@ -272,241 +259,6 @@ end: #endif /* NO_EMBEDDED_ACCESS_CHECKS */ -/** - Check if user exist and password supplied is correct. - - @param thd thread handle, thd->security_ctx->{host,user,ip} are used - @param command originator of the check: now check_user is called - during connect and change user procedures; used for - logging. - @param passwd scrambled password received from client - @param passwd_len length of scrambled password - @param db database name to connect to, may be NULL - @param check_count TRUE if establishing a new connection. In this case - check that we have not exceeded the global - max_connections limist - - @note Host, user and passwd may point to communication buffer. - Current implementation does not depend on that, but future changes - should be done with this in mind; 'thd' is INOUT, all other params - are 'IN'. - - @retval 0 OK; thd->security_ctx->user/master_access/priv_user/db_access and - thd->db are updated; OK is sent to the client. - @retval 1 error, e.g. access denied or handshake error, not sent to - the client. A message is pushed into the error stack. -*/ - -int -check_user(THD *thd, enum enum_server_command command, - const char *passwd, uint passwd_len, const char *db, - bool check_count) -{ - DBUG_ENTER("check_user"); - LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 }; - - /* - Clear thd->db as it points to something, that will be freed when - connection is closed. We don't want to accidentally free a wrong - pointer if connect failed. Also in case of 'CHANGE USER' failure, - current database will be switched to 'no database selected'. - */ - thd->reset_db(NULL, 0); - -#ifdef NO_EMBEDDED_ACCESS_CHECKS - thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights - /* Change database if necessary */ - if (db && db[0]) - { - if (mysql_change_db(thd, &db_str, FALSE)) - DBUG_RETURN(1); - } - my_ok(thd); - DBUG_RETURN(0); -#else - - my_bool opt_secure_auth_local; - pthread_mutex_lock(&LOCK_global_system_variables); - opt_secure_auth_local= opt_secure_auth; - pthread_mutex_unlock(&LOCK_global_system_variables); - - /* - If the server is running in secure auth mode, short scrambles are - forbidden. - */ - if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323) - { - my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); - general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); - DBUG_RETURN(1); - } - if (passwd_len != 0 && - passwd_len != SCRAMBLE_LENGTH && - passwd_len != SCRAMBLE_LENGTH_323) - { - my_error(ER_HANDSHAKE_ERROR, MYF(0)); - DBUG_RETURN(1); - } - - USER_RESOURCES ur; - int res= acl_getroot(thd, &ur, passwd, passwd_len); -#ifndef EMBEDDED_LIBRARY - if (res == -1) - { - /* - This happens when client (new) sends password scrambled with - scramble(), but database holds old value (scrambled with - scramble_323()). Here we please client to send scrambled_password - in old format. - */ - NET *net= &thd->net; - if (opt_secure_auth_local) - { - my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0), - thd->main_security_ctx.user, - thd->main_security_ctx.host_or_ip); - general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE), - thd->main_security_ctx.user, - thd->main_security_ctx.host_or_ip); - DBUG_RETURN(1); - } - /* We have to read very specific packet size */ - if (send_old_password_request(thd) || - my_net_read(net) != SCRAMBLE_LENGTH_323 + 1) - { - inc_host_errors(&thd->remote.sin_addr); - my_error(ER_HANDSHAKE_ERROR, MYF(0)); - DBUG_RETURN(1); - } - /* Final attempt to check the user based on reply */ - /* So as passwd is short, errcode is always >= 0 */ - res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323); - } -#endif /*EMBEDDED_LIBRARY*/ - /* here res is always >= 0 */ - if (res == 0) - { - if (!(thd->main_security_ctx.master_access & - NO_ACCESS)) // authentication is OK - { - DBUG_PRINT("info", - ("Capabilities: %lu packet_length: %ld Host: '%s' " - "Login user: '%s' Priv_user: '%s' Using password: %s " - "Access: %lu db: '%s'", - thd->client_capabilities, - thd->max_client_packet_length, - thd->main_security_ctx.host_or_ip, - thd->main_security_ctx.user, - thd->main_security_ctx.priv_user, - passwd_len ? "yes": "no", - thd->main_security_ctx.master_access, - (thd->db ? thd->db : "*none*"))); - - if (check_count) - { - bool count_ok= 1; - - if (!(thd->main_security_ctx.master_access & SUPER_ACL)) - { - pthread_mutex_lock(&LOCK_connection_count); - count_ok= (*thd->scheduler->connection_count <= - *thd->scheduler->max_connections); - VOID(pthread_mutex_unlock(&LOCK_connection_count)); - } - if (!count_ok) - { // too many connections - my_error(ER_CON_COUNT_ERROR, MYF(0)); - DBUG_RETURN(1); - } - } - - /* - Log the command before authentication checks, so that the user can - check the log for the tried login tried and also to detect - break-in attempts. - */ - general_log_print(thd, command, - (thd->main_security_ctx.priv_user == - thd->main_security_ctx.user ? - (char*) "%s@%s on %s" : - (char*) "%s@%s as anonymous on %s"), - thd->main_security_ctx.user, - thd->main_security_ctx.host_or_ip, - db ? db : (char*) ""); - - /* - This is the default access rights for the current database. It's - set to 0 here because we don't have an active database yet (and we - may not have an active database to set. - */ - thd->main_security_ctx.db_access=0; - - /* Don't allow user to connect if he has done too many queries */ - if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn || - max_user_connections) && - get_or_create_user_conn(thd, - (opt_old_style_user_limits ? thd->main_security_ctx.user : - thd->main_security_ctx.priv_user), - (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip : - thd->main_security_ctx.priv_host), - &ur)) - { - /* The error is set by get_or_create_user_conn(). */ - DBUG_RETURN(1); - } - if (thd->user_connect && - (thd->user_connect->user_resources.conn_per_hour || - thd->user_connect->user_resources.user_conn || - max_user_connections) && - check_for_max_user_connections(thd, thd->user_connect)) - { - /* The error is set in check_for_max_user_connections(). */ - DBUG_RETURN(1); - } - - /* Change database if necessary */ - if (db && db[0]) - { - if (mysql_change_db(thd, &db_str, FALSE)) - { - /* mysql_change_db() has pushed the error message. */ - if (thd->user_connect) - decrease_user_connections(thd->user_connect); - DBUG_RETURN(1); - } - } - my_ok(thd); - /* - Allow the network layer to skip big packets. Although a malicious - authenticated session might use this to trick the server to read - big packets indefinitely, this is a previously established behavior - that needs to be preserved as to not break backwards compatibility. - */ - thd->net.net_skip_rest_factor= 2; // skip at most 2*max_packet_size - thd->password= test(passwd_len); // remember for error messages - /* Ready to handle queries */ - DBUG_RETURN(0); - } - } - else if (res == 2) // client gave short hash, server has long hash - { - my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); - general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); - DBUG_RETURN(1); - } - my_error(ER_ACCESS_DENIED_ERROR, MYF(0), - thd->main_security_ctx.user, - thd->main_security_ctx.host_or_ip, - passwd_len ? ER(ER_YES) : ER(ER_NO)); - general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR), - thd->main_security_ctx.user, - thd->main_security_ctx.host_or_ip, - passwd_len ? ER(ER_YES) : ER(ER_NO)); - DBUG_RETURN(1); -#endif /* NO_EMBEDDED_ACCESS_CHECKS */ -} - - /* Check for maximum allowable user connections, if the mysqld server is started with corresponding variable that is greater then 0. @@ -529,10 +281,14 @@ extern "C" void free_user(struct user_conn *uc) void init_max_user_conn(void) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - (void) hash_init(&hash_user_connections,system_charset_info,max_connections, - 0,0, - (hash_get_key) get_key_conn, (hash_free_key) free_user, - 0); + if (hash_init(&hash_user_connections,system_charset_info,max_connections, + 0,0, + (hash_get_key) get_key_conn, (hash_free_key) free_user, + 0)) + { + sql_print_error("Initializing hash_user_connections failed."); + exit(1); + } #endif } @@ -585,6 +341,445 @@ void reset_mqh(LEX_USER *lu, bool get_them= 0) #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } +/***************************************************************************** + Handle users statistics +*****************************************************************************/ + +/* 'mysql_system_user' is used for when the user is not defined for a THD. */ +static const char mysql_system_user[]= "#mysql_system#"; + +// Returns 'user' if it's not NULL. Returns 'mysql_system_user' otherwise. +static const char * get_valid_user_string(char* user) +{ + return user ? user : mysql_system_user; +} + +/* + Returns string as 'IP' for the client-side of the connection represented by + 'client'. Does not allocate memory. May return "". +*/ + +static const char *get_client_host(THD *client) +{ + return client->security_ctx->host_or_ip[0] ? + client->security_ctx->host_or_ip : + client->security_ctx->host ? client->security_ctx->host : ""; +} + +extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length, + my_bool not_used __attribute__((unused))) +{ + *length= user_stats->user_name_length; + return (uchar*) user_stats->user; +} + +void free_user_stats(USER_STATS* user_stats) +{ + my_free(user_stats, MYF(0)); +} + +void init_user_stats(USER_STATS *user_stats, + const char *user, + size_t user_length, + const char *priv_user, + uint total_connections, + uint concurrent_connections, + time_t connected_time, + double busy_time, + double cpu_time, + ulonglong bytes_received, + ulonglong bytes_sent, + ulonglong binlog_bytes_written, + ha_rows rows_sent, + ha_rows rows_read, + ha_rows rows_inserted, + ha_rows rows_deleted, + ha_rows rows_updated, + ulonglong select_commands, + ulonglong update_commands, + ulonglong other_commands, + ulonglong commit_trans, + ulonglong rollback_trans, + ulonglong denied_connections, + ulonglong lost_connections, + ulonglong access_denied_errors, + ulonglong empty_queries) +{ + DBUG_ENTER("init_user_stats"); + DBUG_PRINT("enter", ("user: %s priv_user: %s", user, priv_user)); + + user_length= min(user_length, sizeof(user_stats->user)-1); + memcpy(user_stats->user, user, user_length); + user_stats->user[user_length]= 0; + user_stats->user_name_length= user_length; + strmake(user_stats->priv_user, priv_user, sizeof(user_stats->priv_user)-1); + + user_stats->total_connections= total_connections; + user_stats->concurrent_connections= concurrent_connections; + user_stats->connected_time= connected_time; + user_stats->busy_time= busy_time; + user_stats->cpu_time= cpu_time; + user_stats->bytes_received= bytes_received; + user_stats->bytes_sent= bytes_sent; + user_stats->binlog_bytes_written= binlog_bytes_written; + user_stats->rows_sent= rows_sent; + user_stats->rows_updated= rows_updated; + user_stats->rows_read= rows_read; + user_stats->select_commands= select_commands; + user_stats->update_commands= update_commands; + user_stats->other_commands= other_commands; + user_stats->commit_trans= commit_trans; + user_stats->rollback_trans= rollback_trans; + user_stats->denied_connections= denied_connections; + user_stats->lost_connections= lost_connections; + user_stats->access_denied_errors= access_denied_errors; + user_stats->empty_queries= empty_queries; + DBUG_VOID_RETURN; +} + + +#ifdef COMPLEAT_PATCH_NOT_ADDED_YET + +void add_user_stats(USER_STATS *user_stats, + uint total_connections, + uint concurrent_connections, + time_t connected_time, + double busy_time, + double cpu_time, + ulonglong bytes_received, + ulonglong bytes_sent, + ulonglong binlog_bytes_written, + ha_rows rows_sent, + ha_rows rows_read, + ha_rows rows_inserted, + ha_rows rows_deleted, + ha_rows rows_updated, + ulonglong select_commands, + ulonglong update_commands, + ulonglong other_commands, + ulonglong commit_trans, + ulonglong rollback_trans, + ulonglong denied_connections, + ulonglong lost_connections, + ulonglong access_denied_errors, + ulonglong empty_queries) +{ + user_stats->total_connections+= total_connections; + user_stats->concurrent_connections+= concurrent_connections; + user_stats->connected_time+= connected_time; + user_stats->busy_time+= busy_time; + user_stats->cpu_time+= cpu_time; + user_stats->bytes_received+= bytes_received; + user_stats->bytes_sent+= bytes_sent; + user_stats->binlog_bytes_written+= binlog_bytes_written; + user_stats->rows_sent+= rows_sent; + user_stats->rows_inserted+= rows_inserted; + user_stats->rows_deleted+= rows_deleted; + user_stats->rows_updated+= rows_updated; + user_stats->rows_read+= rows_read; + user_stats->select_commands+= select_commands; + user_stats->update_commands+= update_commands; + user_stats->other_commands+= other_commands; + user_stats->commit_trans+= commit_trans; + user_stats->rollback_trans+= rollback_trans; + user_stats->denied_connections+= denied_connections; + user_stats->lost_connections+= lost_connections; + user_stats->access_denied_errors+= access_denied_errors; + user_stats->empty_queries+= empty_queries; +} +#endif + + +void init_global_user_stats(void) +{ + if (hash_init(&global_user_stats, system_charset_info, max_connections, + 0, 0, (hash_get_key) get_key_user_stats, + (hash_free_key)free_user_stats, 0)) + { + sql_print_error("Initializing global_user_stats failed."); + exit(1); + } +} + +void init_global_client_stats(void) +{ + if (hash_init(&global_client_stats, system_charset_info, max_connections, + 0, 0, (hash_get_key) get_key_user_stats, + (hash_free_key)free_user_stats, 0)) + { + sql_print_error("Initializing global_client_stats failed."); + exit(1); + } +} + +extern "C" uchar *get_key_table_stats(TABLE_STATS *table_stats, size_t *length, + my_bool not_used __attribute__((unused))) +{ + *length= table_stats->table_name_length; + return (uchar*) table_stats->table; +} + +extern "C" void free_table_stats(TABLE_STATS* table_stats) +{ + my_free(table_stats, MYF(0)); +} + +void init_global_table_stats(void) +{ + if (hash_init(&global_table_stats, system_charset_info, max_connections, + 0, 0, (hash_get_key) get_key_table_stats, + (hash_free_key)free_table_stats, 0)) { + sql_print_error("Initializing global_table_stats failed."); + exit(1); + } +} + +extern "C" uchar *get_key_index_stats(INDEX_STATS *index_stats, size_t *length, + my_bool not_used __attribute__((unused))) +{ + *length= index_stats->index_name_length; + return (uchar*) index_stats->index; +} + +extern "C" void free_index_stats(INDEX_STATS* index_stats) +{ + my_free(index_stats, MYF(0)); +} + +void init_global_index_stats(void) +{ + if (hash_init(&global_index_stats, system_charset_info, max_connections, + 0, 0, (hash_get_key) get_key_index_stats, + (hash_free_key)free_index_stats, 0)) + { + sql_print_error("Initializing global_index_stats failed."); + exit(1); + } +} + + +void free_global_user_stats(void) +{ + hash_free(&global_user_stats); +} + +void free_global_table_stats(void) +{ + hash_free(&global_table_stats); +} + +void free_global_index_stats(void) +{ + hash_free(&global_index_stats); +} + +void free_global_client_stats(void) +{ + hash_free(&global_client_stats); +} + +/* + Increments the global stats connection count for an entry from + global_client_stats or global_user_stats. Returns 0 on success + and 1 on error. +*/ + +static bool increment_count_by_name(const char *name, size_t name_length, + const char *role_name, + HASH *users_or_clients, THD *thd) +{ + USER_STATS *user_stats; + + if (!(user_stats= (USER_STATS*) hash_search(users_or_clients, (uchar*) name, + name_length))) + { + /* First connection for this user or client */ + if (!(user_stats= ((USER_STATS*) + my_malloc(sizeof(USER_STATS), + MYF(MY_WME | MY_ZEROFILL))))) + return TRUE; // Out of memory + + init_user_stats(user_stats, name, name_length, role_name, + 0, 0, // connections + 0, 0, 0, // time + 0, 0, 0, // bytes sent, received and written + 0, 0, // Rows sent and read + 0, 0, 0, // rows inserted, deleted and updated + 0, 0, 0, // select, update and other commands + 0, 0, // commit and rollback trans + thd->status_var.access_denied_errors, + 0, // lost connections + 0, // access denied errors + 0); // empty queries + + if (my_hash_insert(users_or_clients, (uchar*)user_stats)) + { + my_free(user_stats, 0); + return TRUE; // Out of memory + } + } + user_stats->total_connections++; + return FALSE; +} + + +/* + Increments the global user and client stats connection count. + + @param use_lock if true, LOCK_global_user_client_stats will be locked + + @retval 0 ok + @retval 1 error. +*/ + +#ifndef EMBEDDED_LIBRARY +static bool increment_connection_count(THD* thd, bool use_lock) +{ + const char *user_string= get_valid_user_string(thd->main_security_ctx.user); + const char *client_string= get_client_host(thd); + bool return_value= FALSE; + + if (!thd->userstat_running) + return FALSE; + + if (use_lock) + pthread_mutex_lock(&LOCK_global_user_client_stats); + + if (increment_count_by_name(user_string, strlen(user_string), user_string, + &global_user_stats, thd)) + { + return_value= TRUE; + goto end; + } + if (increment_count_by_name(client_string, strlen(client_string), + user_string, &global_client_stats, thd)) + { + return_value= TRUE; + goto end; + } + +end: + if (use_lock) + pthread_mutex_unlock(&LOCK_global_user_client_stats); + return return_value; +} +#endif + +/* + Used to update the global user and client stats +*/ + +static void update_global_user_stats_with_user(THD *thd, + USER_STATS *user_stats, + time_t now) +{ + DBUG_ASSERT(thd->userstat_running); + + user_stats->connected_time+= now - thd->last_global_update_time; + user_stats->busy_time+= (thd->status_var.busy_time - + thd->org_status_var.busy_time); + user_stats->cpu_time+= (thd->status_var.cpu_time - + thd->org_status_var.cpu_time); + /* + This is handle specially as bytes_recieved is incremented BEFORE + org_status_var is copied. + */ + user_stats->bytes_received+= (thd->org_status_var.bytes_received- + thd->start_bytes_received); + user_stats->bytes_sent+= (thd->status_var.bytes_sent - + thd->org_status_var.bytes_sent); + user_stats->binlog_bytes_written+= + (thd->status_var.binlog_bytes_written - + thd->org_status_var.binlog_bytes_written); + user_stats->rows_read+= (thd->status_var.rows_read - + thd->org_status_var.rows_read); + user_stats->rows_sent+= (thd->status_var.rows_sent - + thd->org_status_var.rows_sent); + user_stats->rows_inserted+= (thd->status_var.ha_write_count - + thd->org_status_var.ha_write_count); + user_stats->rows_deleted+= (thd->status_var.ha_delete_count - + thd->org_status_var.ha_delete_count); + user_stats->rows_updated+= (thd->status_var.ha_update_count - + thd->org_status_var.ha_update_count); + user_stats->select_commands+= thd->select_commands; + user_stats->update_commands+= thd->update_commands; + user_stats->other_commands+= thd->other_commands; + user_stats->commit_trans+= (thd->status_var.ha_commit_count - + thd->org_status_var.ha_commit_count); + user_stats->rollback_trans+= (thd->status_var.ha_rollback_count + + thd->status_var.ha_savepoint_rollback_count - + thd->org_status_var.ha_rollback_count - + thd->org_status_var. + ha_savepoint_rollback_count); + user_stats->access_denied_errors+= + (thd->status_var.access_denied_errors - + thd->org_status_var.access_denied_errors); + user_stats->empty_queries+= (thd->status_var.empty_queries - + thd->org_status_var.empty_queries); + + /* The following can only contain 0 or 1 and then connection ends */ + user_stats->denied_connections+= thd->status_var.access_denied_errors; + user_stats->lost_connections+= thd->status_var.lost_connections; +} + + +/* Updates the global stats of a user or client */ +void update_global_user_stats(THD *thd, bool create_user, time_t now) +{ + const char *user_string, *client_string; + USER_STATS *user_stats; + size_t user_string_length, client_string_length; + DBUG_ASSERT(thd->userstat_running); + + user_string= get_valid_user_string(thd->main_security_ctx.user); + user_string_length= strlen(user_string); + client_string= get_client_host(thd); + client_string_length= strlen(client_string); + + pthread_mutex_lock(&LOCK_global_user_client_stats); + + // Update by user name + if ((user_stats= (USER_STATS*) hash_search(&global_user_stats, + (uchar*) user_string, + user_string_length))) + { + /* Found user. */ + update_global_user_stats_with_user(thd, user_stats, now); + } + else + { + /* Create the entry */ + if (create_user) + { + increment_count_by_name(user_string, user_string_length, user_string, + &global_user_stats, thd); + } + } + + /* Update by client IP */ + if ((user_stats= (USER_STATS*)hash_search(&global_client_stats, + (uchar*) client_string, + client_string_length))) + { + // Found by client IP + update_global_user_stats_with_user(thd, user_stats, now); + } + else + { + // Create the entry + if (create_user) + { + increment_count_by_name(client_string, client_string_length, + user_string, &global_client_stats, thd); + } + } + /* Reset variables only used for counting */ + thd->select_commands= thd->update_commands= thd->other_commands= 0; + thd->last_global_update_time= now; + + pthread_mutex_unlock(&LOCK_global_user_client_stats); +} + /** Set thread character set variables from the given ID @@ -665,9 +860,8 @@ bool init_new_connection_handler_thread() thd thread handle RETURN - 0 success, OK is sent to user, thd is updated. - -1 error, which is sent to user - > 0 error code (not sent to user) + 0 success, thd is updated. + 1 error */ #ifndef EMBEDDED_LIBRARY @@ -675,11 +869,6 @@ static int check_connection(THD *thd) { uint connect_errors= 0; NET *net= &thd->net; - ulong pkt_len= 0; - char *end, *user, *passwd, *db; - uint user_len, dummy_errors, passwd_len, db_len; - char db_buff[SAFE_NAME_LEN*2 + 1]; // buffer to store db in utf8 - char user_buff[USERNAME_LENGTH*2 + 1]; // buffer to store user in utf8 DBUG_PRINT("info", ("New connection received on %s", vio_description(net->vio))); @@ -741,210 +930,10 @@ static int check_connection(THD *thd) } vio_keepalive(net->vio, TRUE); - ulong server_capabilites; - { - /* buff[] needs to big enough to hold the server_version variable */ - char buff[SERVER_VERSION_LENGTH + 1 + SCRAMBLE_LENGTH + 1 + 64]; - server_capabilites= CLIENT_BASIC_FLAGS; - - if (opt_using_transactions) - server_capabilites|= CLIENT_TRANSACTIONS; -#ifdef HAVE_COMPRESS - server_capabilites|= CLIENT_COMPRESS; -#endif /* HAVE_COMPRESS */ -#ifdef HAVE_OPENSSL - if (ssl_acceptor_fd) - { - server_capabilites |= CLIENT_SSL; /* Wow, SSL is available! */ - server_capabilites |= CLIENT_SSL_VERIFY_SERVER_CERT; - } -#endif /* HAVE_OPENSSL */ - - end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1; - int4store((uchar*) end, thd->thread_id); - end+= 4; - /* - So as check_connection is the only entry point to authorization - procedure, scramble is set here. This gives us new scramble for - each handshake. - */ - create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); - /* - Old clients does not understand long scrambles, but can ignore packet - tail: that's why first part of the scramble is placed here, and second - part at the end of packet. - */ - end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1; - - int2store(end, server_capabilites); - /* write server characteristics: up to 16 bytes allowed */ - end[2]=(char) default_charset_info->number; - int2store(end+3, thd->server_status); - bzero(end+5, 13); - end+= 18; - /* write scramble tail */ - end= strmake(end, thd->scramble + SCRAMBLE_LENGTH_323, - SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323) + 1; - - /* At this point we write connection message and read reply */ - if (net_write_command(net, (uchar) protocol_version, (uchar*) "", 0, - (uchar*) buff, (size_t) (end-buff)) || - (pkt_len= my_net_read(net)) == packet_error || - pkt_len < MIN_HANDSHAKE_SIZE) - goto error; - } -#ifdef _CUSTOMCONFIG_ -#include "_cust_sql_parse.h" -#endif - if (connect_errors) - reset_host_errors(&thd->remote.sin_addr); if (thd->packet.alloc(thd->variables.net_buffer_length)) return 1; /* The error is set by alloc(). */ - /* - Protocol buffer is guaranteed to always end with \0. (see my_net_read()) - As the code below depends on this, lets check that. - */ - DBUG_ASSERT(net->read_pos[pkt_len] == 0); - - thd->client_capabilities= uint2korr(net->read_pos); - if (thd->client_capabilities & CLIENT_PROTOCOL_41) - { - if (pkt_len < 32) - goto error; - - thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16; - thd->max_client_packet_length= uint4korr(net->read_pos+4); - DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8])); - if (thd_init_client_charset(thd, (uint) net->read_pos[8])) - return 1; - thd->update_charset(); - end= (char*) net->read_pos+32; - } - else - { - if (pkt_len < 5) - goto error; - - thd->max_client_packet_length= uint3korr(net->read_pos+2); - end= (char*) net->read_pos+5; - } - /* - Disable those bits which are not supported by the server. - This is a precautionary measure, if the client lies. See Bug#27944. - */ - thd->client_capabilities&= server_capabilites; - - if (thd->client_capabilities & CLIENT_IGNORE_SPACE) - thd->variables.sql_mode|= MODE_IGNORE_SPACE; -#ifdef HAVE_OPENSSL - DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities)); - if (thd->client_capabilities & CLIENT_SSL) - { - char error_string[1024]; - /* Do the SSL layering. */ - if (!ssl_acceptor_fd) - goto error; - DBUG_PRINT("info", ("IO layer change in progress...")); - if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, error_string)) - { - DBUG_PRINT("error", ("Failed to accept new SSL connection")); - goto error; - } - DBUG_PRINT("info", ("Reading user information over SSL layer")); - if ((pkt_len= my_net_read(net)) == packet_error || - pkt_len < NORMAL_HANDSHAKE_SIZE) - { - DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)", - pkt_len)); - goto error; - } - } -#endif /* HAVE_OPENSSL */ - - if (end >= (char*) net->read_pos+ pkt_len +2) - goto error; - - if (thd->client_capabilities & CLIENT_INTERACTIVE) - thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout; - if ((thd->client_capabilities & CLIENT_TRANSACTIONS) && - opt_using_transactions) - net->return_status= &thd->server_status; - - user= end; - passwd= strend(user)+1; - user_len= passwd - user - 1; - db= passwd; - - /* - Old clients send null-terminated string as password; new clients send - the size (1 byte) + string (not null-terminated). Hence in case of empty - password both send '\0'. - - This strlen() can't be easily deleted without changing protocol. - - Cast *passwd to an unsigned char, so that it doesn't extend the sign for - *passwd > 127 and become 2**32-127+ after casting to uint. - - strlen() is safe as packet[pkt_len] is guranteed to be 0 - */ - passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ? - (uchar)(*passwd++) : strlen(passwd); - db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ? - db + passwd_len + 1 : 0; - - if (passwd + passwd_len + test(db) > (char *)net->read_pos + pkt_len) - goto error; - - /* strlen() can't be easily deleted without changing protocol */ - db_len= db ? strlen(db) : 0; - - /* Since 4.1 all database names are stored in utf8 */ - if (db) - { - db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1, - system_charset_info, - db, db_len, - thd->charset(), &dummy_errors)]= 0; - db= db_buff; - } - - user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1, - system_charset_info, user, user_len, - thd->charset(), &dummy_errors)]= '\0'; - user= user_buff; - - /* If username starts and ends in "'", chop them off */ - if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'') - { - user[user_len-1]= 0; - user++; - user_len-= 2; - } - - /* - Clip username to allowed length in characters (not bytes). This is - mostly for backward compatibility. - */ - { - CHARSET_INFO *cs= system_charset_info; - int err; - - user_len= (uint) cs->cset->well_formed_len(cs, user, user + user_len, - USERNAME_CHAR_LENGTH, &err); - user[user_len]= '\0'; - } - - if (thd->main_security_ctx.user) - x_free(thd->main_security_ctx.user); - if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME)))) - return 1; /* The error is set by my_strdup(). */ - return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE); - -error: - inc_host_errors(&thd->remote.sin_addr); - my_error(ER_HANDSHAKE_ERROR, MYF(0)); - return 1; + return acl_authenticate(thd, connect_errors, 0); } @@ -1016,6 +1005,14 @@ bool login_connection(THD *thd) /* Connect completed, set read/write timeouts back to default */ my_net_set_read_timeout(net, thd->variables.net_read_timeout); my_net_set_write_timeout(net, thd->variables.net_write_timeout); + + /* Updates global user connection stats. */ + if (increment_connection_count(thd, TRUE)) + { + net_send_error(thd, ER_OUTOFMEMORY); // Out of memory + DBUG_RETURN(1); + } + DBUG_RETURN(0); } @@ -1031,12 +1028,22 @@ void end_connection(THD *thd) { NET *net= &thd->net; plugin_thdvar_cleanup(thd); + if (thd->user_connect) + { + /* + We decrease this variable early to make it easy to log again quickly. + This code is not critical as we will in any case do this test + again in thd->cleanup() + */ decrease_user_connections(thd->user_connect); + thd->user_connect= 0; + } if (thd->killed || (net->error && net->vio != 0)) { statistic_increment(aborted_threads,&LOCK_status); + status_var_increment(thd->status_var.lost_connections); } if (net->error && net->vio != 0) @@ -1163,15 +1170,20 @@ pthread_handler_t handle_one_connection(void *arg) for (;;) { NET *net= &thd->net; + bool create_user= TRUE; lex_start(thd); if (login_connection(thd)) + { + create_user= FALSE; goto end_thread; + } prepare_new_connection_state(thd); while (!net->error && net->vio != 0 && - !(thd->killed == THD::KILL_CONNECTION)) + thd->killed != THD::KILL_CONNECTION && + thd->killed != THD::KILL_SERVER) { if (do_command(thd)) break; @@ -1180,12 +1192,14 @@ pthread_handler_t handle_one_connection(void *arg) end_thread: close_connection(thd, 0, 1); + if (thd->userstat_running) + update_global_user_stats(thd, create_user, time(NULL)); + if (thd->scheduler->end_thread(thd,1)) return 0; // Probably no-threads /* - If end_thread() returns, we are either running with - thread-handler=no-threads or this thread has been schedule to + If end_thread() returns, this thread has been schedule to handle the next connection. */ thd= current_thd; diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index eca507a5d50..630ba787c72 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -610,7 +610,7 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused))) thd->set_n_backup_active_arena(this, &backup_arena); /* Create a list of fields and start sequential scan */ rc= result->prepare(item_list, &fake_unit); - if (!rc && !(rc= table->file->ha_rnd_init(TRUE))) + if (!rc && !(rc= table->file->ha_rnd_init_with_error(TRUE))) is_rnd_inited= 1; thd->restore_active_arena(this, &backup_arena); @@ -657,7 +657,7 @@ void Materialized_cursor::fetch(ulong num_rows) result->begin_dataset(); for (fetch_limit+= num_rows; fetch_count < fetch_limit; fetch_count++) { - if ((res= table->file->rnd_next(table->record[0]))) + if ((res= table->file->ha_rnd_next(table->record[0]))) break; /* Send data only if the read was successful. */ /* diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 460b41349b3..2a2efe27952 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -20,6 +20,7 @@ #include "mysql_priv.h" #include <mysys_err.h> +#include "sp_head.h" #include "sp.h" #include "events.h" #include <my_dir.h> diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index f6a1654ec74..29cd3262a72 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -132,7 +132,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, - there should be no delete triggers associated with the table. */ if (!using_limit && const_cond_result && - !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && (thd->lex->sql_command == SQLCOM_TRUNCATE || (!thd->current_stmt_binlog_row_based && !(table->triggers && table->triggers->has_delete_triggers())))) @@ -268,8 +267,15 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, free_underlaid_joins(thd, select_lex); DBUG_RETURN(TRUE); } - if (usable_index==MAX_KEY || (select && select->quick)) - init_read_record(&info, thd, table, select, 1, 1, FALSE); + if (usable_index == MAX_KEY || (select && select->quick)) + { + if (init_read_record(&info, thd, table, select, 1, 1, FALSE)) + { + delete select; + free_underlaid_joins(thd, select_lex); + DBUG_RETURN(TRUE); + } + } else init_read_record_idx(&info, thd, table, 1, usable_index); @@ -307,6 +313,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, while (!(error=info.read_record(&info)) && !thd->killed && ! thd->is_error()) { + update_virtual_fields(thd, table); thd->examined_row_count++; // thd->is_error() is tested to disallow delete row on error if (!select || select->skip_record(thd) > 0) @@ -947,7 +954,10 @@ int multi_delete::do_table_deletes(TABLE *table, bool ignore) READ_RECORD info; ha_rows last_deleted= deleted; DBUG_ENTER("do_deletes_for_table"); - init_read_record(&info, thd, table, NULL, 0, 1, FALSE); + + if (init_read_record(&info, thd, table, NULL, 0, 1, FALSE)) + DBUG_RETURN(1); + /* Ignore any rows not found in reference tables as they may already have been deleted by foreign key handling diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 15a2a1298f0..60d3740931e 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -583,11 +583,11 @@ retry: { /* Check if we read from the same index. */ DBUG_ASSERT((uint) keyno == table->file->get_index()); - error= table->file->index_next(table->record[0]); + error= table->file->ha_index_next(table->record[0]); } else { - error= table->file->rnd_next(table->record[0]); + error= table->file->ha_rnd_next(table->record[0]); } break; } @@ -597,13 +597,13 @@ retry: { table->file->ha_index_or_rnd_end(); table->file->ha_index_init(keyno, 1); - error= table->file->index_first(table->record[0]); + error= table->file->ha_index_first(table->record[0]); } else { table->file->ha_index_or_rnd_end(); if (!(error= table->file->ha_rnd_init(1))) - error= table->file->rnd_next(table->record[0]); + error= table->file->ha_rnd_next(table->record[0]); } mode=RNEXT; break; @@ -615,7 +615,7 @@ retry: { if ((error= table->file->can_continue_handler_scan())) break; - error=table->file->index_prev(table->record[0]); + error= table->file->ha_index_prev(table->record[0]); break; } /* else fall through */ @@ -623,13 +623,13 @@ retry: DBUG_ASSERT(keyname != 0); table->file->ha_index_or_rnd_end(); table->file->ha_index_init(keyno, 1); - error= table->file->index_last(table->record[0]); + error= table->file->ha_index_last(table->record[0]); mode=RPREV; break; case RNEXT_SAME: /* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */ DBUG_ASSERT(keyname != 0); - error= table->file->index_next_same(table->record[0], key, key_len); + error= table->file->ha_index_next_same(table->record[0], key, key_len); break; case RKEY: { @@ -669,8 +669,8 @@ retry: table->file->ha_index_or_rnd_end(); table->file->ha_index_init(keyno, 1); key_copy(key, table->record[0], table->key_info + keyno, key_len); - error= table->file->index_read_map(table->record[0], - key, keypart_map, ha_rkey_mode); + error= table->file->ha_index_read_map(table->record[0], + key, keypart_map, ha_rkey_mode); mode=rkey_to_rnext[(int)ha_rkey_mode]; break; } @@ -695,6 +695,8 @@ retry: } goto ok; } + /* Generate values for virtual fields */ + update_virtual_fields(thd, table); if (cond && !cond->val_int()) continue; if (num_rows >= offset_limit_cnt) diff --git a/sql/sql_help.cc b/sql/sql_help.cc index a00fc1003c2..a93fd23a57f 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -184,11 +184,14 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields, SQL_SELECT *select, List<String> *names, String *name, String *description, String *example) { - DBUG_ENTER("search_topics"); int count= 0; - READ_RECORD read_record_info; - init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE); + DBUG_ENTER("search_topics"); + + /* Should never happen. As this is part of help, we can ignore this */ + if (init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE)) + DBUG_RETURN(0); + while (!read_record_info.read_record(&read_record_info)) { if (!select->cond->val_int()) // Doesn't match like @@ -224,11 +227,13 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields, int search_keyword(THD *thd, TABLE *keywords, struct st_find_field *find_fields, SQL_SELECT *select, int *key_id) { - DBUG_ENTER("search_keyword"); int count= 0; - READ_RECORD read_record_info; - init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE); + DBUG_ENTER("search_keyword"); + /* Should never happen. As this is part of help, we can ignore this */ + if (init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE)) + DBUG_RETURN(0); + while (!read_record_info.read_record(&read_record_info) && count<2) { if (!select->cond->val_int()) // Dosn't match like @@ -296,13 +301,13 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, rkey_id->store((longlong) key_id, TRUE); rkey_id->get_key_image(buff, rkey_id->pack_length(), Field::itRAW); - int key_res= relations->file->index_read_map(relations->record[0], - buff, (key_part_map) 1, - HA_READ_KEY_EXACT); + int key_res= relations->file->ha_index_read_map(relations->record[0], + buff, (key_part_map) 1, + HA_READ_KEY_EXACT); for ( ; !key_res && key_id == (int16) rkey_id->val_int() ; - key_res= relations->file->index_next(relations->record[0])) + key_res= relations->file->ha_index_next(relations->record[0])) { uchar topic_id_buff[8]; longlong topic_id= rtopic_id->val_int(); @@ -310,8 +315,8 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, field->store((longlong) topic_id, TRUE); field->get_key_image(topic_id_buff, field->pack_length(), Field::itRAW); - if (!topics->file->index_read_map(topics->record[0], topic_id_buff, - (key_part_map)1, HA_READ_KEY_EXACT)) + if (!topics->file->ha_index_read_map(topics->record[0], topic_id_buff, + (key_part_map)1, HA_READ_KEY_EXACT)) { memorize_variant_topic(thd,topics,count,find_fields, names,name,description,example); @@ -349,10 +354,11 @@ int search_categories(THD *thd, TABLE *categories, Field *pcat_id= find_fields[help_category_help_category_id].field; int count= 0; READ_RECORD read_record_info; - DBUG_ENTER("search_categories"); - init_read_record(&read_record_info, thd, categories, select,1,0,FALSE); + /* Should never happen. As this is part of help, we can ignore this */ + if (init_read_record(&read_record_info, thd, categories, select,1,0,FALSE)) + DBUG_RETURN(0); while (!read_record_info.read_record(&read_record_info)) { if (select && !select->cond->val_int()) @@ -383,10 +389,13 @@ int search_categories(THD *thd, TABLE *categories, void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname, SQL_SELECT *select, List<String> *res) { + READ_RECORD read_record_info; DBUG_ENTER("get_all_items_for_category"); - READ_RECORD read_record_info; - init_read_record(&read_record_info, thd, items, select,1,0,FALSE); + /* Should never happen. As this is part of help, we can ignore this */ + if (init_read_record(&read_record_info, thd, items, select,1,0,FALSE)) + DBUG_VOID_RETURN; + while (!read_record_info.read_record(&read_record_info)) { if (!select->cond->val_int()) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 171e49aa7d6..99bebe827a4 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -75,15 +75,6 @@ static void unlink_blobs(register TABLE *table); #endif static bool check_view_insertability(THD *thd, TABLE_LIST *view); -/* Define to force use of my_malloc() if the allocated memory block is big */ - -#ifndef HAVE_ALLOCA -#define my_safe_alloca(size, min_length) my_alloca(size) -#define my_safe_afree(ptr, size, min_length) my_afree(ptr) -#else -#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(0))) -#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0)) -#endif /* Check that insert/update fields are from the same single table of a view. @@ -283,6 +274,9 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, } } } + /* Mark virtual columns used in the insert statement */ + if (table->vfield) + table->mark_virtual_columns_for_write(TRUE); // For the values we need select_priv #ifndef NO_EMBEDDED_ACCESS_CHECKS table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege); @@ -1276,7 +1270,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, if (mysql_prepare_insert_check_table(thd, table_list, fields, select_insert)) DBUG_RETURN(TRUE); - /* Prepare the fields in the statement. */ if (values) { @@ -1329,6 +1322,18 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, if (!table) table= table_list->table; + if (!fields.elements && table->vfield) + { + for (Field **vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++) + { + if ((*vfield_ptr)->stored_in_db) + { + thd->lex->unit.insert_table_with_stored_vcol= table; + break; + } + } + } + if (!select_insert) { Item *fake_conds= 0; @@ -1455,7 +1460,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) goto err; if (table->file->ha_table_flags() & HA_DUPLICATE_POS) { - if (table->file->rnd_pos(table->record[1],table->file->dup_ref)) + if (table->file->ha_rnd_pos(table->record[1],table->file->dup_ref)) goto err; } else @@ -1476,9 +1481,10 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) } } key_copy((uchar*) key,table->record[0],table->key_info+key_nr,0); - if ((error=(table->file->index_read_idx_map(table->record[1],key_nr, - (uchar*) key, HA_WHOLE_KEY, - HA_READ_KEY_EXACT)))) + if ((error= (table->file->ha_index_read_idx_map(table->record[1], + key_nr, (uchar*) key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)))) goto err; } if (info->handle_duplicates == DUP_UPDATE) @@ -1778,8 +1784,10 @@ public: table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0), group_count(0) { - thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user; + thd.security_ctx->user=(char*) delayed_user; thd.security_ctx->host=(char*) my_localhost; + strmake(thd.security_ctx->priv_user, thd.security_ctx->user, + USERNAME_LENGTH); thd.current_tablenr=0; thd.version=refresh_version; thd.command=COM_DELAYED_INSERT; @@ -2070,6 +2078,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) TABLE *copy; TABLE_SHARE *share; uchar *bitmap; + char *copy_tmp; DBUG_ENTER("Delayed_insert::get_local_table"); /* First request insert thread to get a lock */ @@ -2102,20 +2111,21 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) the other record buffers and alignment are unnecessary. */ thd_proc_info(client_thd, "allocating local table"); - copy= (TABLE*) client_thd->alloc(sizeof(*copy)+ - (share->fields+1)*sizeof(Field**)+ - share->reclength + - share->column_bitmap_size*2); - if (!copy) + copy_tmp= (char*) client_thd->alloc(sizeof(*copy)+ + (share->fields+1)*sizeof(Field**)+ + share->reclength + + share->column_bitmap_size*3); + if (!copy_tmp) goto error; /* Copy the TABLE object. */ + copy= new (copy_tmp) TABLE; *copy= *table; /* We don't need to change the file handler here */ /* Assign the pointers for the field pointers array and the record. */ field= copy->field= (Field**) (copy + 1); bitmap= (uchar*) (field + share->fields + 1); - copy->record[0]= (bitmap + share->column_bitmap_size * 2); + copy->record[0]= (bitmap + share->column_bitmap_size*3); memcpy((char*) copy->record[0], (char*) table->record[0], share->reclength); /* Make a copy of all fields. @@ -2157,10 +2167,13 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) copy->def_read_set.bitmap= (my_bitmap_map*) bitmap; copy->def_write_set.bitmap= ((my_bitmap_map*) (bitmap + share->column_bitmap_size)); + copy->def_vcol_set.bitmap= ((my_bitmap_map*) + (bitmap + 2*share->column_bitmap_size)); copy->tmp_set.bitmap= 0; // To catch errors - bzero((char*) bitmap, share->column_bitmap_size*2); + bzero((char*) bitmap, share->column_bitmap_size*3); copy->read_set= ©->def_read_set; copy->write_set= ©->def_write_set; + copy->vcol_set= ©->def_vcol_set; DBUG_RETURN(copy); @@ -2307,7 +2320,7 @@ void kill_delayed_threads(void) Delayed_insert *di; while ((di= it++)) { - di->thd.killed= THD::KILL_CONNECTION; + di->thd.killed= THD::KILL_SYSTEM_THREAD; pthread_mutex_lock(&di->thd.LOCK_thd_data); if (di->thd.mysys_var) { @@ -2392,7 +2405,8 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) for (;;) { - if (thd->killed == THD::KILL_CONNECTION) + if (thd->killed == THD::KILL_CONNECTION || + thd->killed == THD::KILL_SYSTEM_THREAD || thd->killed == THD::KILL_SERVER) { uint lock_count; /* @@ -2440,7 +2454,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) break; if (error == ETIMEDOUT || error == ETIME) { - thd->killed= THD::KILL_CONNECTION; + thd->killed= THD::KILL_SYSTEM_THREAD; break; } } @@ -2473,7 +2487,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) { /* Fatal error */ di->dead= 1; - thd->killed= THD::KILL_CONNECTION; + thd->killed= THD::KILL_SYSTEM_THREAD; } pthread_cond_broadcast(&di->cond_client); } @@ -2483,7 +2497,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) { /* Some fatal error */ di->dead= 1; - thd->killed= THD::KILL_CONNECTION; + thd->killed= THD::KILL_SYSTEM_THREAD; } } di->status=0; @@ -2543,7 +2557,7 @@ pthread_handler_t handle_delayed_insert(void *arg) thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; thd->set_current_time(); threads.append(thd); - thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED; + thd->killed=abort_loop ? THD::KILL_SYSTEM_THREAD : THD::NOT_KILLED; pthread_mutex_unlock(&LOCK_thread_count); /* @@ -2577,7 +2591,7 @@ end: di->table=0; di->dead= 1; // If error - thd->killed= THD::KILL_CONNECTION; // If error + thd->killed= THD::KILL_SYSTEM_THREAD; // If error pthread_mutex_unlock(&di->mutex); close_thread_tables(thd); // Free the table @@ -2656,7 +2670,7 @@ bool Delayed_insert::handle_inserts(void) max_rows= delayed_insert_limit; if (thd.killed || table->needs_reopen_or_name_lock()) { - thd.killed= THD::KILL_CONNECTION; + thd.killed= THD::KILL_SYSTEM_THREAD; max_rows= ULONG_MAX; // Do as much as possible } @@ -3495,7 +3509,7 @@ int select_create::write_to_binlog(bool is_trans, int errcode) Avoid to use thd->binlog_query() twice, otherwise it will print the unsafe warning twice. */ - Query_log_event ev(thd, query.c_ptr_safe(), query.length(), is_trans, + Query_log_event ev(thd, query.ptr(), query.length(), is_trans, FALSE, errcode); return mysql_bin_log.write(&ev); } @@ -3577,7 +3591,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, tmp_table.s->db_low_byte_first= test(create_info->db_type == myisam_hton || create_info->db_type == heap_hton); - tmp_table.null_row=tmp_table.maybe_null=0; + tmp_table.null_row= 0; + tmp_table.maybe_null= 0; while ((item=it++)) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index cbb3782114a..30b53f49b5a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -23,8 +23,8 @@ #include "item_create.h" #include <m_ctype.h> #include <hash.h> -#include "sp.h" #include "sp_head.h" +#include "sp.h" /* We are using pointer to this variable for distinguishing between assignment @@ -334,6 +334,7 @@ void lex_start(THD *thd) lex->reset_query_tables_list(FALSE); lex->expr_allows_subselect= TRUE; lex->use_only_table_context= FALSE; + lex->parse_vcol_expr= FALSE; lex->name.str= 0; lex->name.length= 0; @@ -784,9 +785,9 @@ int MYSQLlex(void *arg, void *yythd) Lex_input_stream *lip= & thd->m_parser_state->m_lip; LEX *lex= thd->lex; YYSTYPE *yylval=(YYSTYPE*) arg; - CHARSET_INFO *cs= thd->charset(); - uchar *state_map= cs->state_map; - uchar *ident_map= cs->ident_map; + CHARSET_INFO *const cs= thd->charset(); + const uchar *const state_map= cs->state_map; + const uchar *const ident_map= cs->ident_map; LINT_INIT(c); lip->yylval=yylval; // The global state @@ -1592,6 +1593,7 @@ void st_select_lex_unit::init_query() item_list.empty(); describe= 0; found_rows_for_union= 0; + insert_table_with_stored_vcol= 0; } void st_select_lex::init_query() diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 3706d4c30ae..acdbab62076 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -120,6 +120,8 @@ enum enum_sql_command { SQLCOM_SHOW_CREATE_TRIGGER, SQLCOM_ALTER_DB_UPGRADE, SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES, + SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, + SQLCOM_SHOW_CLIENT_STATS, /* When a command is added here, be sure it's also added in mysqld.cc @@ -532,6 +534,13 @@ public: bool describe; /* union exec() called for EXPLAIN */ Procedure *last_procedure; /* Pointer to procedure, if such exists */ + /* + Insert table with stored virtual columns. + This is used only in those rare cases + when the list of inserted values is empty. + */ + TABLE *insert_table_with_stored_vcol; + void init_query(); st_select_lex_unit* master_unit(); st_select_lex* outer_select(); @@ -959,6 +968,8 @@ extern sys_var *trg_new_row_fake_var; enum xa_option_words {XA_NONE, XA_JOIN, XA_RESUME, XA_ONE_PHASE, XA_SUSPEND, XA_FOR_MIGRATE}; +extern const LEX_STRING null_lex_str; +extern const LEX_STRING empty_lex_str; struct Sroutine_hash_entry; @@ -1598,6 +1609,7 @@ typedef struct st_lex : public Query_tables_list LEX_USER *grant_user; XID *xid; THD *thd; + Virtual_column_info *vcol_info; /* maintain a list of used plugins for this LEX */ DYNAMIC_ARRAY plugins; @@ -1681,6 +1693,14 @@ typedef struct st_lex : public Query_tables_list syntax error back. */ bool expr_allows_subselect; + /* + A special command "PARSE_VCOL_EXPR" is defined for the parser + to translate a defining expression of a virtual column into an + Item object. + The following flag is used to prevent other applications to use + this command. + */ + bool parse_vcol_expr; thr_lock_type lock_option; enum SSL_type ssl_type; /* defined in violite.h */ @@ -1786,6 +1806,11 @@ typedef struct st_lex : public Query_tables_list const char *stmt_definition_end; /** + Collects create options for Field and KEY + */ + engine_option_value *option_list, *option_list_last; + + /** During name resolution search only in the table list given by Name_resolution_context::first_name_resolution_table and Name_resolution_context::last_name_resolution_table diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 23105d84a9d..3a1dbef4f3f 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -614,11 +614,15 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, size_t pl= 0; List<Item> fv; Item *item, *val; - String pfield, pfields; int n; const char *tbl= table_name_arg; const char *tdb= (thd->db != NULL ? thd->db : db_arg); - String string_buf; + char name_buffer[SAFE_NAME_LEN*2]; + char command_buffer[1024]; + String string_buf(name_buffer, sizeof(name_buffer), + system_charset_info); + String pfields(command_buffer, sizeof(command_buffer), + system_charset_info); if (!thd->db || strcmp(db_arg, thd->db)) { @@ -627,7 +631,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, prefix table name with database name so that it becomes a FQ name. */ - string_buf.set_charset(system_charset_info); + string_buf.length(0); string_buf.append(db_arg); string_buf.append("`"); string_buf.append("."); @@ -648,6 +652,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, /* prepare fields-list and SET if needed; print_query won't do that for us. */ + pfields.length(0); if (!thd->lex->field_list.is_empty()) { List_iterator<Item> li(thd->lex->field_list); @@ -692,8 +697,8 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, } } - p= pfields.c_ptr_safe(); - pl= strlen(p); + p= pfields.c_ptr_safe(); + pl= pfields.length(); if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl))) return TRUE; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 41f308a2ce4..5e45c06996e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -33,7 +33,7 @@ #include "debug_sync.h" #include <rpl_mi.h> -#ifdef WITH_MARIA_STORAGE_ENGINE +#ifdef WITH_ARIA_STORAGE_ENGINE #include "../storage/maria/ha_maria.h" #endif @@ -189,7 +189,7 @@ bool end_active_trans(THD *thd) thd->server_status&= ~SERVER_STATUS_IN_TRANS; if (ha_commit(thd)) error=1; -#ifdef WITH_MARIA_STORAGE_ENGINE +#ifdef WITH_ARIA_STORAGE_ENGINE ha_maria::implicit_commit(thd, TRUE); #endif } @@ -346,10 +346,14 @@ void init_update_queries(void) sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CLIENT_STATS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_USER_STATS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_TABLE_STATS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_INDEX_STATS]= CF_STATUS_COMMAND; - sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND | - CF_SHOW_TABLE_COMMAND | - CF_REEXECUTION_FRAGILE); + sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND | + CF_SHOW_TABLE_COMMAND | + CF_REEXECUTION_FRAGILE); sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND | CF_SHOW_TABLE_COMMAND | CF_REEXECUTION_FRAGILE); @@ -448,9 +452,8 @@ static void handle_bootstrap_impl(THD *thd) thd_proc_info(thd, 0); thd->version=refresh_version; - thd->security_ctx->priv_user= - thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME)); - thd->security_ctx->priv_host[0]=0; + thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME)); + thd->security_ctx->priv_user[0]= thd->security_ctx->priv_host[0]=0; /* Make the "client" handle multiple results. This is necessary to enable stored procedures with SELECTs and Dynamic SQL @@ -582,7 +585,6 @@ end: return 0; } - /** @brief Check access privs for a MERGE table and fix children lock types. @@ -793,7 +795,17 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion) if (res < 0) my_error(thd->killed_errno(), MYF(0)); else if ((res == 0) && do_release) + { thd->killed= THD::KILL_CONNECTION; + if (global_system_variables.log_warnings > 3) + { + Security_context *sctx= &thd->main_security_ctx; + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), + thd->thread_id,(thd->db ? thd->db : "unconnected"), + sctx->user ? sctx->user : "unauthenticated", + sctx->host_or_ip, "RELEASE"); + } + } DBUG_RETURN(res); } @@ -844,6 +856,8 @@ bool do_command(THD *thd) net_new_transaction(net); + /* Save for user statistics */ + thd->start_bytes_received= thd->status_var.bytes_received; packet_length= my_net_read(net); #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) thd->profiling.start_new_query(); @@ -1120,105 +1134,41 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_CHANGE_USER: { status_var_increment(thd->status_var.com_other); - char *user= (char*) packet, *packet_end= packet + packet_length; - /* Safe because there is always a trailing \0 at the end of the packet */ - char *passwd= strend(user)+1; thd->change_user(); thd->clear_error(); // if errors from rollback - /* - Old clients send null-terminated string ('\0' for empty string) for - password. New clients send the size (1 byte) + string (not null - terminated, so also '\0' for empty string). + /* acl_authenticate() takes the data from net->read_pos */ + net->read_pos= (uchar*)packet; - Cast *passwd to an unsigned char, so that it doesn't extend the sign - for *passwd > 127 and become 2**32-127 after casting to uint. - */ - char db_buff[SAFE_NAME_LEN+1]; // buffer to store db in utf8 - char *db= passwd; - char *save_db; - /* - If there is no password supplied, the packet must contain '\0', - in any type of handshake (4.1 or pre-4.1). - */ - if (passwd >= packet_end) - { - my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); - break; - } - uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ? - (uchar)(*passwd++) : strlen(passwd)); - uint dummy_errors, save_db_length, db_length; - int res; + uint save_db_length= thd->db_length; + char *save_db= thd->db; + USER_CONN *save_user_connect= thd->user_connect; Security_context save_security_ctx= *thd->security_ctx; - USER_CONN *save_user_connect; - - db+= passwd_len + 1; - /* - Database name is always NUL-terminated, so in case of empty database - the packet must contain at least the trailing '\0'. - */ - if (db >= packet_end) - { - my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); - break; - } - db_length= strlen(db); - - char *ptr= db + db_length + 1; - uint cs_number= 0; - - if (ptr < packet_end) - { - CHARSET_INFO *cs; - if (ptr + 2 > packet_end) - { - my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); - break; - } - - if ((cs_number= uint2korr(ptr)) && - (cs= get_charset(cs_number, MYF(0))) && - !is_supported_parser_charset(cs)) - { - /* Disallow non-supported parser character sets: UCS2, UTF16, UTF32 */ - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client", - cs->csname); - break; - } - } - - /* Convert database name to utf8 */ - db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1, - system_charset_info, db, db_length, - thd->charset(), &dummy_errors)]= 0; - db= db_buff; - - /* Save user and privileges */ - save_db_length= thd->db_length; - save_db= thd->db; - save_user_connect= thd->user_connect; - - if (!(thd->security_ctx->user= my_strdup(user, MYF(0)))) - { - thd->security_ctx->user= save_security_ctx.user; - my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); - break; - } - - /* Clear variables that are allocated */ + CHARSET_INFO *save_character_set_client= + thd->variables.character_set_client; + CHARSET_INFO *save_collation_connection= + thd->variables.collation_connection; + CHARSET_INFO *save_character_set_results= + thd->variables.character_set_results; + + /* Ensure we don't free security_ctx->user in case we have to revert */ + thd->security_ctx->user= 0; thd->user_connect= 0; - thd->security_ctx->priv_user= thd->security_ctx->user; - res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE); - if (res) + if (acl_authenticate(thd, 0, packet_length)) { + /* Free user if allocated by acl_authenticate */ x_free(thd->security_ctx->user); *thd->security_ctx= save_security_ctx; + if (thd->user_connect) + decrease_user_connections(thd->user_connect); thd->user_connect= save_user_connect; - thd->db= save_db; - thd->db_length= save_db_length; + thd->reset_db(save_db, save_db_length); + thd->variables.character_set_client= save_character_set_client; + thd->variables.collation_connection= save_collation_connection; + thd->variables.character_set_results= save_character_set_results; + thd->update_charset(); } else { @@ -1229,17 +1179,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif /* NO_EMBEDDED_ACCESS_CHECKS */ x_free(save_db); x_free(save_security_ctx.user); - - if (cs_number) - { - /* - We have checked charset earlier, - so thd_init_client_charset cannot fail. - */ - if (thd_init_client_charset(thd, cs_number)) - DBUG_ASSERT(0); - thd->update_charset(); - } } break; } @@ -1296,7 +1235,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { char *beginning_of_next_stmt= (char*) end_of_stmt; -#ifdef WITH_MARIA_STORAGE_ENGINE +#ifdef WITH_ARIA_STORAGE_ENGINE ha_maria::implicit_commit(thd, FALSE); #endif @@ -1411,7 +1350,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, table_list.select_lex= &(thd->lex->select_lex); lex_start(thd); - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, opt_userstat_running); thd->lex-> select_lex.table_list.link_in_list(&table_list, @@ -1628,7 +1567,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { char *end= buff + length; length+= my_snprintf(end, buff_len - length - 1, - end," Memory in use: %ldK Max memory used: %ldK", + " Memory in use: %ldK Max memory used: %ldK", (sf_malloc_cur_memory+1023L)/1024L, (sf_malloc_max_memory+1023L)/1024L); } @@ -1721,7 +1660,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->transaction.stmt.reset(); -#ifdef WITH_MARIA_STORAGE_ENGINE +#ifdef WITH_ARIA_STORAGE_ENGINE ha_maria::implicit_commit(thd, FALSE); #endif @@ -1735,6 +1674,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* Free tables */ close_thread_tables(thd); + /* Update status; Must be done after close_thread_tables */ + thd->update_all_stats(); + if (sql_command_flags[thd->lex->sql_command] & CF_CHANGES_DATA) { net_end_statement(thd); @@ -1752,6 +1694,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd_proc_info(thd, 0); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); + + /* Check that some variables are reset properly */ + DBUG_ASSERT(thd->abort_on_warning == 0); DBUG_RETURN(error); } @@ -1910,6 +1855,12 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, thd->profiling.discard_current_query(); #endif break; + case SCH_USER_STATS: + case SCH_CLIENT_STATS: + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) + DBUG_RETURN(1); + case SCH_TABLE_STATS: + case SCH_INDEX_STATS: case SCH_OPEN_TABLES: case SCH_VARIABLES: case SCH_STATUS: @@ -2353,6 +2304,10 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_COLLATIONS: case SQLCOM_SHOW_STORAGE_ENGINES: case SQLCOM_SHOW_PROFILE: + case SQLCOM_SHOW_CLIENT_STATS: + case SQLCOM_SHOW_USER_STATS: + case SQLCOM_SHOW_TABLE_STATS: + case SQLCOM_SHOW_INDEX_STATS: case SQLCOM_SELECT: thd->status_var.last_query_cost= 0.0; if (all_tables) @@ -3176,9 +3131,7 @@ end_with_restore_list: goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; thd->query_plan_flags|= QPLAN_ADMIN; - res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ? - mysql_recreate_table(thd, first_table) : - mysql_optimize_table(thd, first_table, &lex->check_opt); + res= mysql_optimize_table(thd, first_table, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { @@ -4445,8 +4398,8 @@ end_with_restore_list: if (sp_grant_privileges(thd, lex->sphead->m_db.str, name, lex->sql_command == SQLCOM_CREATE_PROCEDURE)) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_PROC_AUTO_GRANT_FAIL, - ER(ER_PROC_AUTO_GRANT_FAIL)); + ER_PROC_AUTO_GRANT_FAIL, ER(ER_PROC_AUTO_GRANT_FAIL)); + thd->clear_error(); } /* @@ -4643,9 +4596,10 @@ create_sp_error: */ /* Conditionally writes to binlog */ - int type= lex->sql_command == SQLCOM_ALTER_PROCEDURE ? - TYPE_ENUM_PROCEDURE : - TYPE_ENUM_FUNCTION; + stored_procedure_type type; + type= (lex->sql_command == SQLCOM_ALTER_PROCEDURE ? + TYPE_ENUM_PROCEDURE : + TYPE_ENUM_FUNCTION); sp_result= sp_update_routine(thd, type, @@ -4673,8 +4627,8 @@ create_sp_error: case SQLCOM_DROP_FUNCTION: { int sp_result; - int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ? - TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION); + stored_procedure_type type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ? + TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION); sp_result= sp_routine_exists_in_table(thd, type, lex->spname); mysql_reset_errors(thd, 0); @@ -4701,9 +4655,10 @@ create_sp_error: #endif /* Conditionally writes to binlog */ - int type= lex->sql_command == SQLCOM_DROP_PROCEDURE ? - TYPE_ENUM_PROCEDURE : - TYPE_ENUM_FUNCTION; + stored_procedure_type type; + type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ? + TYPE_ENUM_PROCEDURE : + TYPE_ENUM_FUNCTION); sp_result= sp_drop_routine(thd, type, lex->spname); } @@ -5147,6 +5102,7 @@ create_sp_error: break; } thd_proc_info(thd, "query end"); + thd->update_stats(); /* Binlog-related cleanup: @@ -5220,9 +5176,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) String str(buff,(uint32) sizeof(buff), system_charset_info); str.length(0); thd->lex->unit.print(&str, QT_ORDINARY); - str.append('\0'); push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_YES, str.ptr()); + ER_YES, str.c_ptr_safe()); } if (res) result->abort(); @@ -5240,6 +5195,10 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) delete result; } } + /* Count number of empty select queries */ + if (!thd->sent_row_count) + status_var_increment(thd->status_var.empty_queries); + status_var_add(thd->status_var.rows_sent, thd->sent_row_count); return res; } @@ -5455,6 +5414,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (!no_errors) { const char *db_name= db ? db : thd->db; + status_var_increment(thd->status_var.access_denied_errors); my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->priv_host, db_name); } @@ -5487,12 +5447,15 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, { // We can never grant this DBUG_PRINT("error",("No possible access")); if (!no_errors) + { + status_var_increment(thd->status_var.access_denied_errors); my_error(ER_ACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->priv_host, (thd->password ? ER(ER_YES) : ER(ER_NO))); /* purecov: tested */ + } DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -5518,11 +5481,14 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_PRINT("error",("Access denied")); if (!no_errors) + { + status_var_increment(thd->status_var.access_denied_errors); my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->priv_host, (db ? db : (thd->db ? thd->db : "unknown"))); /* purecov: tested */ + } DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -5551,6 +5517,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) if (!thd->col_access && check_grant_db(thd, dst_db_name)) { + status_var_increment(thd->status_var.access_denied_errors); my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), thd->security_ctx->priv_user, thd->security_ctx->priv_host, @@ -5613,14 +5580,14 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, { TABLE_LIST *org_tables= tables; TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); - uint i= 0; Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx; + uint i; /* The check that first_not_own_table is not reached is for the case when the given table list refers to the list for prelocking (contains tables of other queries). For simple queries first_not_own_table is 0. */ - for (; i < number && tables != first_not_own_table; + for (i=0; i < number && tables != first_not_own_table; tables= tables->next_global, i++) { if (tables->security_ctx) @@ -5632,9 +5599,12 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL))) { if (!no_errors) + { + status_var_increment(thd->status_var.access_denied_errors); my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->priv_host, INFORMATION_SCHEMA_NAME.str); + } return TRUE; } /* @@ -5798,6 +5768,7 @@ bool check_global_access(THD *thd, ulong want_access) return 0; get_privilege_desc(command, sizeof(command), want_access); my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); + status_var_increment(thd->status_var.access_denied_errors); return 1; #else return 0; @@ -5901,7 +5872,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize) Call it after we use THD for queries, not before. */ -void mysql_reset_thd_for_next_command(THD *thd) +void mysql_reset_thd_for_next_command(THD *thd, my_bool calculate_userstat) { DBUG_ENTER("mysql_reset_thd_for_next_command"); DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */ @@ -5946,6 +5917,15 @@ void mysql_reset_thd_for_next_command(THD *thd) thd->total_warn_count=0; // Warnings for this query thd->rand_used= 0; thd->sent_row_count= thd->examined_row_count= 0; + + /* Copy data for user stats */ + if ((thd->userstat_running= calculate_userstat)) + { + thd->start_cpu_time= my_getcputime(); + memcpy(&thd->org_status_var, &thd->status_var, sizeof(thd->status_var)); + thd->select_commands= thd->update_commands= thd->other_commands= 0; + } + thd->query_plan_flags= QPLAN_INIT; thd->query_plan_fsort_passes= 0; @@ -6137,7 +6117,6 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, const char ** found_semicolon) { DBUG_ENTER("mysql_parse"); - DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on();); /* @@ -6157,7 +6136,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, FIXME: cleanup the dependencies in the code to simplify this. */ lex_start(thd); - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, opt_userstat_running); if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0) { @@ -6235,10 +6214,11 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, } else { + /* Update statistics for getting the query from the cache */ + thd->lex->sql_command= SQLCOM_SELECT; /* There are no multi queries in the cache. */ *found_semicolon= NULL; } - DBUG_VOID_RETURN; } @@ -6264,7 +6244,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length) if (!(error= parser_state.init(thd, rawbuf, length))) { lex_start(thd); - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, opt_userstat_running); if (!parse_sql(thd, & parser_state, NULL) && all_tables_not_ok(thd, lex->select_lex.table_list.first)) @@ -6292,7 +6272,9 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, LEX_STRING *comment, char *change, List<String> *interval_list, CHARSET_INFO *cs, - uint uint_geom_type) + uint uint_geom_type, + Virtual_column_info *vcol_info, + engine_option_value *create_options) { register Create_field *new_field; LEX *lex= thd->lex; @@ -6310,7 +6292,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, lex->col_list.push_back(new Key_part_spec(field_name->str, 0)); key= new Key(Key::PRIMARY, NullS, &default_key_create_info, - 0, lex->col_list); + 0, lex->col_list, NULL); lex->alter_info.key_list.push_back(key); lex->col_list.empty(); } @@ -6320,7 +6302,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, lex->col_list.push_back(new Key_part_spec(field_name->str, 0)); key= new Key(Key::UNIQUE, NullS, &default_key_create_info, 0, - lex->col_list); + lex->col_list, NULL); lex->alter_info.key_list.push_back(key); lex->col_list.empty(); } @@ -6378,7 +6360,8 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, if (!(new_field= new Create_field()) || new_field->init(thd, field_name->str, type, length, decimals, type_modifier, default_value, on_update_value, comment, change, - interval_list, cs, uint_geom_type)) + interval_list, cs, uint_geom_type, vcol_info, + create_options)) DBUG_RETURN(1); lex->alter_info.create_list.push_back(new_field); @@ -7141,6 +7124,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, result= 1; } } + if (((options & (REFRESH_SLOW_QUERY_LOG | REFRESH_LOG)) == + REFRESH_SLOW_QUERY_LOG)) + { + /* We are only flushing slow query log */ + logger.flush_slow_log(thd); + } + #ifdef HAVE_QUERY_CACHE if (options & REFRESH_QUERY_CACHE_FREE) { @@ -7258,14 +7248,43 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, pthread_mutex_unlock(&LOCK_active_mi); } #endif - if (options & REFRESH_USER_RESOURCES) - reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */ - if (*write_to_binlog != -1) - *write_to_binlog= tmp_write_to_binlog; - /* - If the query was killed then this function must fail. - */ - return result || (thd ? thd->killed : 0); + if (options & REFRESH_USER_RESOURCES) + reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */ + if (options & REFRESH_TABLE_STATS) + { + pthread_mutex_lock(&LOCK_global_table_stats); + free_global_table_stats(); + init_global_table_stats(); + pthread_mutex_unlock(&LOCK_global_table_stats); + } + if (options & REFRESH_INDEX_STATS) + { + pthread_mutex_lock(&LOCK_global_index_stats); + free_global_index_stats(); + init_global_index_stats(); + pthread_mutex_unlock(&LOCK_global_index_stats); + } + if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS)) + { + pthread_mutex_lock(&LOCK_global_user_client_stats); + if (options & REFRESH_USER_STATS) + { + free_global_user_stats(); + init_global_user_stats(); + } + if (options & REFRESH_CLIENT_STATS) + { + free_global_client_stats(); + init_global_client_stats(); + } + pthread_mutex_unlock(&LOCK_global_user_client_stats); + } + if (*write_to_binlog != -1) + *write_to_binlog= tmp_write_to_binlog; + /* + If the query was killed then this function must fail. + */ + return result || (thd ? thd->killed : 0); } @@ -7301,7 +7320,6 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query) VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (tmp) { - /* If we're SUPER, we can KILL anything, including system-threads. No further checks. @@ -7317,6 +7335,10 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query) If user of both killer and killee are non-NULL, proceed with slayage if both are string-equal. + + It's ok to also kill DELAYED threads with KILL_CONNECTION instead of + KILL_SYSTEM_THREAD; The difference is that KILL_CONNECTION may be + faster and do a harder kill than KILL_SYSTEM_THREAD; */ if ((thd->security_ctx->master_access & SUPER_ACL) || @@ -7884,8 +7906,9 @@ void get_default_definer(THD *thd, LEX_USER *definer) definer->host.str= (char *) sctx->priv_host; definer->host.length= strlen(definer->host.str); - definer->password.str= NULL; - definer->password.length= 0; + definer->password= null_lex_str; + definer->plugin= empty_lex_str; + definer->auth= empty_lex_str; } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index c810963b701..9b6bc0cd4b0 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1006,7 +1006,8 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func; thd->lex->allow_sum_func= 0; - error= func_expr->fix_fields(thd, (Item**)&func_expr); + if (!(error= func_expr->fix_fields(thd, (Item**)&func_expr))) + func_expr->walk(&Item::vcol_in_partition_func_processor, 0, NULL); /* Restore agg_field/agg_func and allow_sum_func, @@ -1928,7 +1929,7 @@ static int add_int(File fptr, longlong number) static int add_uint(File fptr, ulonglong number) { char buff[32]; - longlong2str(number, buff, 10); + longlong2str(number, buff, 10, 1); return add_string(fptr, buff); } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index f44813f3224..67c59322a55 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -18,10 +18,11 @@ #include "mysql_priv.h" #include <my_pthread.h> #include <my_getopt.h> +#include <mysql/plugin_auth.h> #define REPORT_TO_LOG 1 #define REPORT_TO_USER 2 -extern struct st_mysql_plugin *mysqld_builtins[]; +extern struct st_maria_plugin *mariadb_builtins[]; /** @note The order of the enumeration is critical. @@ -38,6 +39,18 @@ static TYPELIB global_plugin_typelib= char *opt_plugin_load= NULL; char *opt_plugin_dir_ptr; char opt_plugin_dir[FN_REFLEN]; +uint plugin_maturity; + +/* + not really needed now, this map will become essential when we add more + maturity levels. We cannot change existing maturity constants, + so the next value - even if it will be MariaDB_PLUGIN_MATURITY_VERY_BUGGY - + will inevitably be larger than MariaDB_PLUGIN_MATURITY_STABLE. + To be able to compare them we use this mapping array +*/ +uint plugin_maturity_map[]= +{ 0, 1, 2, 3, 4, 5, 6 }; + /* When you ad a new plugin type, add both a string and make sure that the init and deinit array are correctly updated. @@ -48,7 +61,10 @@ const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]= { C_STRING_WITH_LEN("STORAGE ENGINE") }, { C_STRING_WITH_LEN("FTPARSER") }, { C_STRING_WITH_LEN("DAEMON") }, - { C_STRING_WITH_LEN("INFORMATION SCHEMA") } + { C_STRING_WITH_LEN("INFORMATION SCHEMA") }, + { C_STRING_WITH_LEN("AUDIT") }, + { C_STRING_WITH_LEN("REPLICATION") }, + { C_STRING_WITH_LEN("AUTHENTICATION") } }; extern int initialize_schema_table(st_plugin_int *plugin); @@ -61,12 +77,12 @@ extern int finalize_schema_table(st_plugin_int *plugin); */ plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]= { - 0,ha_initialize_handlerton,0,0,initialize_schema_table + 0,ha_initialize_handlerton,0,0,initialize_schema_table, 0, 0, 0 }; plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]= { - 0,ha_finalize_handlerton,0,0,finalize_schema_table + 0,ha_finalize_handlerton,0,0,finalize_schema_table, 0, 0, 0 }; #ifdef HAVE_DLOPEN @@ -76,6 +92,14 @@ static const char *sizeof_st_plugin_sym= "_mysql_sizeof_struct_st_plugin_"; static const char *plugin_declarations_sym= "_mysql_plugin_declarations_"; static int min_plugin_interface_version= MYSQL_PLUGIN_INTERFACE_VERSION & ~0xFF; +static const char *maria_plugin_interface_version_sym= + "_maria_plugin_interface_version_"; +static const char *maria_sizeof_st_plugin_sym= + "_maria_sizeof_struct_st_plugin_"; +static const char *maria_plugin_declarations_sym= + "_maria_plugin_declarations_"; +static int min_maria_plugin_interface_version= + MARIA_PLUGIN_INTERFACE_VERSION & ~0xFF; #endif /* Note that 'int version' must be the first field of every plugin @@ -87,7 +111,10 @@ static int min_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]= MYSQL_HANDLERTON_INTERFACE_VERSION, MYSQL_FTPARSER_INTERFACE_VERSION, MYSQL_DAEMON_INTERFACE_VERSION, - MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION + MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION, + 0xff00, /* audit plugins are supported in a later versions */ + 0xff00, /* replication plugins are supported in a later versions */ + MYSQL_AUTHENTICATION_INTERFACE_VERSION }; static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]= { @@ -95,10 +122,15 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]= MYSQL_HANDLERTON_INTERFACE_VERSION, MYSQL_FTPARSER_INTERFACE_VERSION, MYSQL_DAEMON_INTERFACE_VERSION, - MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION + MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION, + 0x0000, /* audit plugins are supported in a later versions */ + 0x0000, /* replication plugins are supported in a later versions */ + MYSQL_AUTHENTICATION_INTERFACE_VERSION }; -static bool initialized= 0; +/* support for Services */ + +#include "sql_plugin_services.h" /* A mutex LOCK_plugin must be acquired before accessing the @@ -112,6 +144,8 @@ static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM]; static bool reap_needed= false; static int plugin_array_version=0; +static bool initialized= 0; + /* write-lock on LOCK_system_variables_hash is required before modifying the following variables/structures @@ -199,7 +233,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, const char *list); static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *, int *, char **); -static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *, +static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *, struct st_plugin_int **); static void unlock_variables(THD *thd, struct system_variables *vars); static void cleanup_variables(THD *thd, struct system_variables *vars); @@ -224,6 +258,22 @@ extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd, extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists); #endif /* EMBEDDED_LIBRARY */ +static void report_error(int where_to, uint error, ...) +{ + va_list args; + if (where_to & REPORT_TO_USER) + { + va_start(args, error); + my_printv_error(error, ER(error), MYF(0), args); + va_end(args); + } + if (where_to & REPORT_TO_LOG) + { + va_start(args, error); + error_log_print(ERROR_LEVEL, ER(error), args); + va_end(args); + } +} /** Check if the provided path is valid in the sense that it does cause @@ -275,7 +325,7 @@ static const char *item_val_str(struct st_mysql_value *value, Lets be nice and create a temporary string since the buffer was too small */ - return current_thd->strmake(res->c_ptr_quick(), res->length()); + return current_thd->strmake(res->ptr(), res->length()); } @@ -360,11 +410,230 @@ static inline void free_plugin_mem(struct st_plugin_dl *p) } +/** + Reads data from mysql plugin interface + + @param plugin_dl Structure where the data should be put + @param sym Reverence on version info + @param dlpath Path to the module + @param report What errors should be reported + + @retval FALSE OK + @retval TRUE ERROR +*/ + +#ifdef HAVE_DLOPEN +static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, + void *sym, char *dlpath, + int report) +{ + DBUG_ENTER("read_maria_plugin_info"); + /* Determine interface version */ + if (!sym) + { + free_plugin_mem(plugin_dl); + report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym); + DBUG_RETURN(TRUE); + } + plugin_dl->mariaversion= 0; + plugin_dl->mysqlversion= *(int *)sym; + /* Versioning */ + if (plugin_dl->mysqlversion < min_plugin_interface_version || + (plugin_dl->mysqlversion >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8)) + { + free_plugin_mem(plugin_dl); + report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, + "plugin interface version mismatch"); + DBUG_RETURN(TRUE); + } + /* Find plugin declarations */ + if (!(sym= dlsym(plugin_dl->handle, plugin_declarations_sym))) + { + free_plugin_mem(plugin_dl); + report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym); + DBUG_RETURN(TRUE); + } + + /* convert mysql declaration to maria one */ + { + int i; + uint sizeof_st_plugin; + struct st_mysql_plugin *old; + struct st_maria_plugin *cur; + char *ptr= (char *)sym; + + if ((sym= dlsym(plugin_dl->handle, sizeof_st_plugin_sym))) + sizeof_st_plugin= *(int *)sym; + else + { + DBUG_ASSERT(min_plugin_interface_version == 0); + sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version); + } + + for (i= 0; + ((struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info; + i++) + /* no op */; + + cur= (struct st_maria_plugin*) + my_malloc((i + 1) * sizeof(struct st_maria_plugin), + MYF(MY_ZEROFILL|MY_WME)); + if (!cur) + { + free_plugin_mem(plugin_dl); + report_error(report, ER_OUTOFMEMORY, (int) plugin_dl->dl.length); + DBUG_RETURN(TRUE); + } + /* + All st_plugin fields not initialized in the plugin explicitly, are + set to 0. It matches C standard behaviour for struct initializers that + have less values than the struct definition. + */ + for (i=0; + (old= (struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info; + i++) + { + + cur[i].type= old->type; + cur[i].info= old->info; + cur[i].name= old->name; + cur[i].author= old->author; + cur[i].descr= old->descr; + cur[i].license= old->license; + cur[i].init= old->init; + cur[i].deinit= old->deinit; + cur[i].version= old->version; + cur[i].status_vars= old->status_vars; + cur[i].system_vars= old->system_vars; + /* + Something like this should be added to process + new mysql plugin versions: + if (plugin_dl->mysqlversion > 0x0101) + { + cur[i].newfield= CONSTANT_MEANS_UNKNOWN; + } + else + { + cur[i].newfield= old->newfield; + } + */ + /* Maria only fields */ + cur[i].version_info= "Unknown"; + cur[i].maturity= MariaDB_PLUGIN_MATURITY_UNKNOWN; + } + plugin_dl->allocated= true; + plugin_dl->plugins= (struct st_maria_plugin *)cur; + } + + DBUG_RETURN(FALSE); +} + + +/** + Reads data from maria plugin interface + + @param plugin_dl Structure where the data should be put + @param sym Reverence on version info + @param dlpath Path to the module + @param report what errors should be reported + + @retval FALSE OK + @retval TRUE ERROR +*/ + +static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, + void *sym, char *dlpath, + int report) +{ + DBUG_ENTER("read_maria_plugin_info"); + + /* Determine interface version */ + if (!(sym)) + { + /* + Actually this branch impossible because in case of absence of maria + version we try mysql version. + */ + free_plugin_mem(plugin_dl); + report_error(report, ER_CANT_FIND_DL_ENTRY, + maria_plugin_interface_version_sym); + DBUG_RETURN(TRUE); + } + plugin_dl->mariaversion= *(int *)sym; + plugin_dl->mysqlversion= 0; + /* Versioning */ + if (plugin_dl->mariaversion < min_maria_plugin_interface_version || + (plugin_dl->mariaversion >> 8) > (MARIA_PLUGIN_INTERFACE_VERSION >> 8)) + { + free_plugin_mem(plugin_dl); + report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, + "plugin interface version mismatch"); + DBUG_RETURN(TRUE); + } + /* Find plugin declarations */ + if (!(sym= dlsym(plugin_dl->handle, maria_plugin_declarations_sym))) + { + free_plugin_mem(plugin_dl); + report_error(report, ER_CANT_FIND_DL_ENTRY, maria_plugin_declarations_sym); + DBUG_RETURN(TRUE); + } + if (plugin_dl->mariaversion != MARIA_PLUGIN_INTERFACE_VERSION) + { + uint sizeof_st_plugin; + struct st_maria_plugin *old, *cur; + char *ptr= (char *)sym; + + if ((sym= dlsym(plugin_dl->handle, maria_sizeof_st_plugin_sym))) + sizeof_st_plugin= *(int *)sym; + else + { + free_plugin_mem(plugin_dl); + report_error(report, ER_CANT_FIND_DL_ENTRY, maria_sizeof_st_plugin_sym); + DBUG_RETURN(TRUE); + } + + if (sizeof_st_plugin != sizeof(st_mysql_plugin)) + { + int i; + for (i= 0; + ((struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info; + i++) + /* no op */; + + cur= (struct st_maria_plugin*) + my_malloc((i + 1) * sizeof(struct st_maria_plugin), + MYF(MY_ZEROFILL|MY_WME)); + if (!cur) + { + free_plugin_mem(plugin_dl); + report_error(report, ER_OUTOFMEMORY, (int) plugin_dl->dl.length); + DBUG_RETURN(TRUE); + } + /* + All st_plugin fields not initialized in the plugin explicitly, are + set to 0. It matches C standard behaviour for struct initializers that + have less values than the struct definition. + */ + for (i=0; + (old= (struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info; + i++) + memcpy(cur + i, old, min(sizeof(cur[i]), sizeof_st_plugin)); + + sym= cur; + plugin_dl->allocated= true; + } + } + plugin_dl->plugins= (struct st_maria_plugin *)sym; + + DBUG_RETURN(FALSE); +} +#endif /* HAVE_DLOPEN */ + static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) { #ifdef HAVE_DLOPEN char dlpath[FN_REFLEN]; - uint plugin_dir_len, dummy_errors, dlpathlen; + uint plugin_dir_len, dummy_errors, dlpathlen, i; struct st_plugin_dl *tmp, plugin_dl; void *sym; DBUG_ENTER("plugin_dl_add"); @@ -381,10 +650,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) system_charset_info, 1) || plugin_dir_len + dl->length + 1 >= FN_REFLEN) { - if (report & REPORT_TO_USER) - my_error(ER_UDF_NO_PATHS, MYF(0)); - if ((report & (REPORT_TO_LOG | REPORT_TO_USER)) == REPORT_TO_LOG) - sql_print_error("%s", ER(ER_UDF_NO_PATHS)); + report_error(report, ER_UDF_NO_PATHS); DBUG_RETURN(0); } /* If this dll is already loaded just increase ref_count. */ @@ -409,119 +675,52 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) if (*errmsg == ':') errmsg++; if (*errmsg == ' ') errmsg++; } - if (report & REPORT_TO_USER) - my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, errno, errmsg); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, errno, errmsg); - DBUG_RETURN(0); - } - /* Determine interface version */ - if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym))) - { - free_plugin_mem(&plugin_dl); - if (report & REPORT_TO_USER) - my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_interface_version_sym); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_interface_version_sym); + report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg); DBUG_RETURN(0); } - plugin_dl.version= *(int *)sym; - /* Versioning */ - if (plugin_dl.version < min_plugin_interface_version || - (plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8)) + + /* Checks which plugin interface present and reads info */ + if (!(sym= dlsym(plugin_dl.handle, maria_plugin_interface_version_sym))) { - free_plugin_mem(&plugin_dl); - if (report & REPORT_TO_USER) - my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0, - "plugin interface version mismatch"); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, 0, - "plugin interface version mismatch"); - DBUG_RETURN(0); + if (read_mysql_plugin_info(&plugin_dl, + dlsym(plugin_dl.handle, + plugin_interface_version_sym), + dlpath, + report)) + DBUG_RETURN(0); } - /* Find plugin declarations */ - if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym))) + else { - free_plugin_mem(&plugin_dl); - if (report & REPORT_TO_USER) - my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym); - DBUG_RETURN(0); + if (read_maria_plugin_info(&plugin_dl, sym, dlpath, report)) + DBUG_RETURN(0); } - if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION) + /* link the services in */ + for (i= 0; i < array_elements(list_of_services); i++) { - int i; - uint sizeof_st_plugin; - struct st_mysql_plugin *old, *cur; - char *ptr= (char *)sym; - - if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym))) - sizeof_st_plugin= *(int *)sym; - else - { -#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL - free_plugin_mem(&plugin_dl); - if (report & REPORT_TO_USER) - my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), sizeof_st_plugin_sym); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym); - DBUG_RETURN(0); -#else - /* - When the following assert starts failing, we'll have to switch - to the upper branch of the #ifdef - */ - DBUG_ASSERT(min_plugin_interface_version == 0); - sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version); -#endif - } - - if (sizeof_st_plugin != sizeof(st_mysql_plugin)) + if ((sym= dlsym(plugin_dl.handle, list_of_services[i].name))) { - for (i= 0; - ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info; - i++) - /* no op */; - - cur= (struct st_mysql_plugin*) - my_malloc((i+1)*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME)); - if (!cur) + uint ver= (uint)(intptr) *(void **)sym; + if (ver > list_of_services[i].version || + (ver >> 8) < (list_of_services[i].version >> 8)) { - free_plugin_mem(&plugin_dl); - if (report & REPORT_TO_USER) - my_error(ER_OUTOFMEMORY, MYF(0), (int) plugin_dl.dl.length); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_OUTOFMEMORY), (int) plugin_dl.dl.length); + char buf[MYSQL_ERRMSG_SIZE]; + my_snprintf(buf, sizeof(buf), + "service '%s' interface version mismatch", + list_of_services[i].name); + report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, buf); DBUG_RETURN(0); } - /* - All st_plugin fields not initialized in the plugin explicitly, are - set to 0. It matches C standard behaviour for struct initializers that - have less values than the struct definition. - */ - for (i=0; - (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info; - i++) - memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin)); - - sym= cur; - plugin_dl.allocated= true; + *(void **)sym= list_of_services[i].service; } } - plugin_dl.plugins= (struct st_mysql_plugin *)sym; /* Duplicate and convert dll name */ plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1; if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0)))) { free_plugin_mem(&plugin_dl); - if (report & REPORT_TO_USER) - my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(plugin_dl.dl.length)); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_OUTOFMEMORY), - static_cast<int>(plugin_dl.dl.length)); + report_error(report, ER_OUTOFMEMORY, (int) plugin_dl.dl.length); DBUG_RETURN(0); } plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length, @@ -532,21 +731,13 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl))) { free_plugin_mem(&plugin_dl); - if (report & REPORT_TO_USER) - my_error(ER_OUTOFMEMORY, MYF(0), - static_cast<int>(sizeof(struct st_plugin_dl))); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_OUTOFMEMORY), - static_cast<int>(sizeof(struct st_plugin_dl))); + report_error(report, ER_OUTOFMEMORY, (int) sizeof(struct st_plugin_dl)); DBUG_RETURN(0); } DBUG_RETURN(tmp); #else DBUG_ENTER("plugin_dl_add"); - if (report & REPORT_TO_USER) - my_error(ER_FEATURE_DISABLED, MYF(0), "plugin", "HAVE_DLOPEN"); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_FEATURE_DISABLED), "plugin", "HAVE_DLOPEN"); + report_error(report, ER_FEATURE_DISABLED, "plugin", "HAVE_DLOPEN"); DBUG_RETURN(0); #endif } @@ -665,7 +856,7 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO) /* For debugging, we do an additional malloc which allows the memory manager and/or valgrind to track locked references and - double unlocks to aid resolving reference counting.problems. + double unlocks to aid resolving reference counting problems. */ if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME)))) DBUG_RETURN(NULL); @@ -673,7 +864,7 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO) *plugin= pi; #endif pi->ref_count++; - DBUG_PRINT("info",("thd: 0x%lx plugin: \"%s\" ref_count: %d", + DBUG_PRINT("lock",("thd: 0x%lx plugin: \"%s\" LOCK ref_count: %d", (long) current_thd, pi->name.str, pi->ref_count)); if (lex) @@ -764,14 +955,11 @@ static bool plugin_add(MEM_ROOT *tmp_root, int *argc, char **argv, int report) { struct st_plugin_int tmp; - struct st_mysql_plugin *plugin; + struct st_maria_plugin *plugin; DBUG_ENTER("plugin_add"); if (plugin_find_internal(name, MYSQL_ANY_PLUGIN)) { - if (report & REPORT_TO_USER) - my_error(ER_UDF_EXISTS, MYF(0), name->str); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_UDF_EXISTS), name->str); + report_error(report, ER_UDF_EXISTS, name->str); DBUG_RETURN(TRUE); } /* Clear the whole struct to catch future extensions. */ @@ -798,10 +986,18 @@ static bool plugin_add(MEM_ROOT *tmp_root, strxnmov(buf, sizeof(buf) - 1, "API version for ", plugin_type_names[plugin->type].str, " plugin is too different", NullS); - if (report & REPORT_TO_USER) - my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dl->str, 0, buf); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dl->str, 0, buf); + report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, 0, buf); + goto err; + } + if (plugin_maturity_map[plugin->maturity] < plugin_maturity) + { + char buf[256]; + strxnmov(buf, sizeof(buf) - 1, "Loading of ", + plugin_maturity_names[plugin->maturity], + " plugins is prohibited by --plugin-maturity=", + plugin_maturity_names[plugin_maturity], + NullS); + report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, 0, buf); goto err; } tmp.plugin= plugin; @@ -830,10 +1026,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, DBUG_RETURN(FALSE); } } - if (report & REPORT_TO_USER) - my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), name->str); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name->str); + report_error(report, ER_CANT_FIND_DL_ENTRY, name->str); err: plugin_dl_del(dl); DBUG_RETURN(TRUE); @@ -989,8 +1182,6 @@ static void intern_plugin_unlock(LEX *lex, plugin_ref plugin) my_free((uchar*) plugin, MYF(MY_WME)); #endif - DBUG_PRINT("info",("unlocking plugin, name= %s, ref_count= %d", - pi->name.str, pi->ref_count)); if (lex) { /* @@ -1010,6 +1201,9 @@ static void intern_plugin_unlock(LEX *lex, plugin_ref plugin) DBUG_ASSERT(pi->ref_count); pi->ref_count--; + DBUG_PRINT("lock",("thd: 0x%lx plugin: \"%s\" UNLOCK ref_count: %d", + (long) current_thd, pi->name.str, pi->ref_count)); + if (pi->state == PLUGIN_IS_DELETED && !pi->ref_count) reap_needed= true; @@ -1040,6 +1234,9 @@ void plugin_unlock_list(THD *thd, plugin_ref *list, uint count) { LEX *lex= thd ? thd->lex : 0; DBUG_ENTER("plugin_unlock_list"); + if (count == 0) + DBUG_VOID_RETURN; + DBUG_ASSERT(list); pthread_mutex_lock(&LOCK_plugin); while (count--) @@ -1175,8 +1372,8 @@ int plugin_init(int *argc, char **argv, int flags) { uint i; bool is_myisam; - struct st_mysql_plugin **builtins; - struct st_mysql_plugin *plugin; + struct st_maria_plugin **builtins; + struct st_maria_plugin *plugin; struct st_plugin_int tmp, *plugin_ptr, **reap; MEM_ROOT tmp_root; bool reaped_mandatory_plugin= FALSE; @@ -1215,7 +1412,7 @@ int plugin_init(int *argc, char **argv, int flags) /* First we register builtin plugins */ - for (builtins= mysqld_builtins; *builtins; builtins++) + for (builtins= mariadb_builtins; *builtins; builtins++) { for (plugin= *builtins; plugin->info; plugin++) { @@ -1338,7 +1535,7 @@ err: } -static bool register_builtin(struct st_mysql_plugin *plugin, +static bool register_builtin(struct st_maria_plugin *plugin, struct st_plugin_int *tmp, struct st_plugin_int **ptr) { @@ -1374,7 +1571,7 @@ static bool register_builtin(struct st_mysql_plugin *plugin, RETURN false - plugin registered successfully */ -bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin) +bool plugin_register_builtin(THD *thd, struct st_maria_plugin *plugin) { struct st_plugin_int tmp, *ptr; bool result= true; @@ -1456,7 +1653,12 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) goto end; } table= tables.table; - init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE); + if (init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE)) + { + sql_print_error("Could not initialize init_read_record; Plugins not " + "loaded"); + goto end; + } table->use_all_columns(); while (!(error= read_record_info.read_record(&read_record_info))) { @@ -1503,7 +1705,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, char buffer[FN_REFLEN]; LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name; struct st_plugin_dl *plugin_dl; - struct st_mysql_plugin *plugin; + struct st_maria_plugin *plugin; char *p= buffer; DBUG_ENTER("plugin_load_list"); while (list) @@ -1845,10 +2047,10 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name) table->use_all_columns(); table->field[0]->store(name->str, name->length, system_charset_info); - if (! table->file->index_read_idx_map(table->record[0], 0, - (uchar *)table->field[0]->ptr, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (! table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar *)table->field[0]->ptr, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) { int error; /* diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index c63e1d4acff..936c27a2290 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -29,16 +29,6 @@ class sys_var; #define INITIAL_LEX_PLUGIN_LIST_SIZE 16 -/* - the following #define adds server-only members to enum_mysql_show_type, - that is defined in plugin.h -*/ -#define SHOW_FUNC SHOW_FUNC, SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_LONGLONG, \ - SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, SHOW_HAVE, \ - SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, SHOW_LONG_NOFLUSH, \ - SHOW_LONGLONG_STATUS -#include <mysql/plugin.h> -#undef SHOW_FUNC typedef enum enum_mysql_show_type SHOW_TYPE; typedef struct st_mysql_show_var SHOW_VAR; @@ -64,8 +54,9 @@ struct st_plugin_dl { LEX_STRING dl; void *handle; - struct st_mysql_plugin *plugins; - int version; + struct st_maria_plugin *plugins; + int mysqlversion; + int mariaversion; bool allocated; uint ref_count; /* number of plugins loaded from the library */ }; @@ -75,7 +66,7 @@ struct st_plugin_dl struct st_plugin_int { LEX_STRING name; - struct st_mysql_plugin *plugin; + struct st_maria_plugin *plugin; struct st_plugin_dl *plugin_dl; uint state; uint ref_count; /* number of threads using the plugin */ @@ -118,6 +109,9 @@ extern char *opt_plugin_load; extern char *opt_plugin_dir_ptr; extern char opt_plugin_dir[FN_REFLEN]; extern const LEX_STRING plugin_type_names[]; +extern uint plugin_maturity; +extern TYPELIB plugin_maturity_values; +extern const char *plugin_maturity_names[]; extern int plugin_init(int *argc, char **argv, int init_flags); extern void plugin_shutdown(void); diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h new file mode 100644 index 00000000000..14a2a16561a --- /dev/null +++ b/sql/sql_plugin_services.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* support for Services */ +#include <service_versions.h> + +struct st_service_ref { + const char *name; + uint version; + void *service; +}; + +static struct my_snprintf_service_st my_snprintf_handler = { + my_snprintf, + my_vsnprintf +}; + +static struct thd_alloc_service_st thd_alloc_handler= { + thd_alloc, + thd_calloc, + thd_strdup, + thd_strmake, + thd_memdup, + thd_make_lex_string +}; + +static struct st_service_ref list_of_services[] __attribute__((unused)) = +{ + { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler }, + { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler } +}; + diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1c0ee55b79d..2c062deacd0 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2101,14 +2101,13 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) Prepared_statement *stmt; bool error; DBUG_ENTER("mysqld_stmt_prepare"); - DBUG_PRINT("prep_query", ("%s", packet)); /* First of all clear possible warnings from the previous command */ - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, opt_userstat_running); if (! (stmt= new Prepared_statement(thd))) - DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */ + goto end; /* out of memory: error is set in Sql_alloc */ if (thd->stmt_map.insert(thd, stmt)) { @@ -2116,7 +2115,7 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) The error is set in the insert. The statement itself will be also deleted there (this is how the hash works). */ - DBUG_VOID_RETURN; + goto end; } /* Reset warnings from previous command */ @@ -2143,6 +2142,7 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) thd->protocol= save_protocol; /* check_prepared_statemnt sends the metadata packet in case of success */ +end: DBUG_VOID_RETURN; } @@ -2189,7 +2189,7 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len) lex->prepared_stmt_code.length)) && entry->value) { - my_bool is_var_null; + bool is_var_null; var_value= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC); /* NULL value of variable checked early as entry->value so here @@ -2478,7 +2478,7 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) packet+= 9; /* stmt_id + 5 bytes of flags */ /* First of all clear possible warnings from the previous command */ - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, opt_userstat_running); if (!(stmt= find_prepared_statement(thd, stmt_id))) { @@ -2577,7 +2577,8 @@ void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length) DBUG_ENTER("mysqld_stmt_fetch"); /* First of all clear possible warnings from the previous command */ - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, opt_userstat_running); + status_var_increment(thd->status_var.com_stmt_fetch); if (!(stmt= find_prepared_statement(thd, stmt_id))) { @@ -2643,7 +2644,7 @@ void mysqld_stmt_reset(THD *thd, char *packet) DBUG_ENTER("mysqld_stmt_reset"); /* First of all clear possible warnings from the previous command */ - mysql_reset_thd_for_next_command(thd); + mysql_reset_thd_for_next_command(thd, opt_userstat_running); status_var_increment(thd->status_var.com_stmt_reset); if (!(stmt= find_prepared_statement(thd, stmt_id))) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8b7261a8712..ebb31290c96 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -37,7 +37,7 @@ #include <my_bit.h> #include <hash.h> #include <ft_global.h> -#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES) +#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES) #include "../storage/maria/ha_maria.h" #define TMP_ENGINE_HTON maria_hton #else @@ -2960,8 +2960,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, !table->fulltext_searched && !table->pos_in_table_list->embedding) { - if ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) - == HA_NOSAME) + if (table->key_info[key].flags & HA_NOSAME) { if (const_ref == eq_part) { // Found everything for ref. @@ -5124,7 +5123,7 @@ optimize_straight_join(JOIN *join, table_map join_tables) All other cases are in-between these two extremes. Thus the parameter 'search_depth' controlls the exhaustiveness of the search. The higher the - value, the longer the optimizaton time and possibly the better the + value, the longer the optimization time and possibly the better the resulting plan. The lower the value, the fewer alternative plans are estimated, but the more likely to get a bad QEP. @@ -5618,7 +5617,7 @@ static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab) { uint null_fields,blobs,fields,rec_length; Field **f_ptr,*field; - MY_BITMAP *read_set= join_tab->table->read_set;; + MY_BITMAP *read_set= join_tab->table->read_set; null_fields= blobs= fields= rec_length=0; for (f_ptr=join_tab->table->field ; (field= *f_ptr) ; f_ptr++) @@ -5941,8 +5940,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, DBUG_RETURN(0); if (j->type == JT_CONST) j->table->const_table= 1; - else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY | - HA_END_SPACE_KEY)) != HA_NOSAME) || + else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) != HA_NOSAME) || keyparts != keyinfo->key_parts || null_ref_key) { /* Must read with repeat */ @@ -6204,9 +6202,10 @@ static void add_not_null_conds(JOIN *join) */ if (notnull->fix_fields(join->thd, ¬null)) DBUG_VOID_RETURN; - DBUG_EXECUTE("where",print_where(notnull, - referred_tab->table->alias, - QT_ORDINARY);); + DBUG_EXECUTE("where", + print_where(notnull, + referred_tab->table->alias.c_ptr(), + QT_ORDINARY);); add_cond_and_fix(&referred_tab->select_cond, notnull); } } @@ -6465,7 +6464,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } if (tmp || !cond || tab->type == JT_REF) { - DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY);); + DBUG_EXECUTE("where", + print_where(tmp,tab->table->alias.c_ptr(), + QT_ORDINARY);); SQL_SELECT *sel= tab->select= ((SQL_SELECT*) thd->memdup((uchar*) select, sizeof(*select))); @@ -6504,7 +6505,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) tab->select_cond= sel->cond= NULL; sel->head=tab->table; - DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY);); + DBUG_EXECUTE("where", + print_where(tmp,tab->table->alias.c_ptr(), + QT_ORDINARY);); if (tab->quick) { /* Use quick key read if it's a constant and it's not used @@ -7266,8 +7269,6 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab) static bool only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables) { - if (specialflag & SPECIAL_SAFE_MODE) - return 0; // skip this optimize /* purecov: inspected */ tables&= ~PSEUDO_TABLE_BITS; for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1) { @@ -9723,6 +9724,8 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field, table->s->db_create_options|= HA_OPTION_PACK_RECORD; else if (org_field->type() == FIELD_TYPE_DOUBLE) ((Field_double *) new_field)->not_fixed= TRUE; + new_field->vcol_info= 0; + new_field->stored_in_db= TRUE; } return new_field; } @@ -10041,9 +10044,13 @@ void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps) uint field_count= table->s->fields; bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count, FALSE); - bitmap_init(&table->tmp_set, + bitmap_init(&table->def_vcol_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count, FALSE); + bitmap_init(&table->tmp_set, + (my_bitmap_map*) (bitmaps+ 2*bitmap_buffer_size(field_count)), + field_count, FALSE); + /* write_set and all_set are copies of read_set */ table->def_write_set= table->def_read_set; table->s->all_set= table->def_read_set; @@ -10144,7 +10151,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, /* No need to change table name to lower case as we are only creating - MyISAM, Maria or HEAP tables here + MyISAM, Aria or HEAP tables here */ fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME); @@ -10196,7 +10203,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, &tmpname, (uint) strlen(path)+1, &group_buff, (group && ! using_unique_constraint ? param->group_length : 0), - &bitmaps, bitmap_buffer_size(field_count)*2, + &bitmaps, bitmap_buffer_size(field_count)*3, NullS)) { if (temp_pool_slot != MY_BIT_NONE) @@ -10225,7 +10232,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, thd->mem_root= &table->mem_root; table->field=reg_field; - table->alias= table_alias; + table->alias.set(table_alias, strlen(table_alias), table_alias_charset); + table->reginfo.lock_type=TL_WRITE; /* Will be updated */ table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE; table->map=1; @@ -10591,7 +10599,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, null_count=(null_count+7) & ~7; // move to next byte // fix table name in field entry - field->table_name= &table->alias; + field->set_table_name(&table->alias); } param->copy_field_end=copy; @@ -10835,7 +10843,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list) &share, sizeof(*share), &field, (field_count + 1) * sizeof(Field*), &blob_field, (field_count+1) *sizeof(uint), - &bitmaps, bitmap_buffer_size(field_count)*2, + &bitmaps, bitmap_buffer_size(field_count)*3, NullS)) return 0; @@ -10926,8 +10934,9 @@ error: static bool open_tmp_table(TABLE *table) { int error; - if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR, - HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE))) + if ((error= table->file->ha_open(table, table->s->table_name.str, O_RDWR, + HA_OPEN_TMP_TABLE | + HA_OPEN_INTERNAL_TABLE))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->db_stat=0; @@ -10938,9 +10947,9 @@ static bool open_tmp_table(TABLE *table) } -#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES) +#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES) -/* Create internal Maria temporary table */ +/* Create internal Aria temporary table */ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, ulonglong options) @@ -11020,7 +11029,7 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]); /* We are using a GROUP BY on something that contains NULL - In this case we have to tell Maria that two NULL should + In this case we have to tell Aria that two NULL should on INSERT be regarded at the same value */ if (!using_unique_constraint) @@ -11034,10 +11043,22 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, OPTION_BIG_TABLES) create_info.data_file_length= ~(ulonglong) 0; + /* + The logic for choosing the record format: + The STATIC_RECORD format is the fastest one, because it's so simple, + so we use this by default for short rows. + BLOCK_RECORD caches both row and data, so this is generally faster than + DYNAMIC_RECORD. The one exception is when we write to tmp table and + want to use keys for duplicate elimination as with BLOCK RECORD + we first write the row, then check for key conflicts and then we have to + delete the row. The cases when this can happen is when there is + a group by and no sum functions or if distinct is used. + */ if ((error= maria_create(share->table_name.str, - share->reclength < 64 && - !share->blob_fields ? STATIC_RECORD : - BLOCK_RECORD, + (share->reclength < 64 && + !share->blob_fields ? STATIC_RECORD : + ((!param->sum_func_count && table->group) || + table->distinct) ? DYNAMIC_RECORD : BLOCK_RECORD), share->keys, &keydef, (uint) (param->recinfo-param->start_recinfo), param->start_recinfo, @@ -11066,7 +11087,7 @@ bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table, return create_internal_tmp_table_from_heap2(thd, table, param, error, ignore_last_dupp_key_error, maria_hton, - "converting HEAP to Maria"); + "converting HEAP to Aria"); } #else @@ -11253,7 +11274,8 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table, if (table->file->indexes_are_disabled()) new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL); table->file->ha_index_or_rnd_end(); - table->file->ha_rnd_init(1); + if (table->file->ha_rnd_init_with_error(1)) + DBUG_RETURN(1); if (table->no_rows) { new_table.file->extra(HA_EXTRA_NO_ROWS); @@ -11278,7 +11300,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table, is safe as this is a temporary MyISAM table without timestamp/autoincrement or partitioning. */ - while (!table->file->rnd_next(new_table.record[1])) + while (!table->file->ha_rnd_next(new_table.record[1])) { write_err= new_table.file->ha_write_row(new_table.record[1]); DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;); @@ -11338,7 +11360,7 @@ free_tmp_table(THD *thd, TABLE *entry) MEM_ROOT own_root= entry->mem_root; const char *save_proc_info; DBUG_ENTER("free_tmp_table"); - DBUG_PRINT("enter",("table: %s",entry->alias)); + DBUG_PRINT("enter",("table: %s",entry->alias.c_ptr())); save_proc_info=thd->proc_info; thd_proc_info(thd, "removing tmp table"); @@ -11823,6 +11845,8 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, } DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond)); + update_virtual_fields(join->thd, join_tab->table); + if (select_cond) { select_cond_result= test(select_cond->val_int()); @@ -12049,6 +12073,8 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last) join->thd->send_kill_message(); return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */ } + if (rc == NESTED_LOOP_OK) + update_virtual_fields(join->thd, join_tab->table); if (rc == NESTED_LOOP_OK && (!join_tab->cache.select || (err= join_tab->cache.select->skip_record(join->thd)) != 0 )) @@ -12127,10 +12153,10 @@ int safe_index_read(JOIN_TAB *tab) { int error; TABLE *table= tab->table; - if ((error=table->file->index_read_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_KEY_EXACT))) + if ((error= table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_KEY_EXACT))) return report_error(table, error); return 0; } @@ -12234,8 +12260,8 @@ join_read_system(JOIN_TAB *tab) int error; if (table->status & STATUS_GARBAGE) // If first read { - if ((error=table->file->read_first_row(table->record[0], - table->s->primary_key))) + if ((error= table->file->ha_read_first_row(table->record[0], + table->s->primary_key))) { if (error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -12243,6 +12269,7 @@ join_read_system(JOIN_TAB *tab) empty_record(table); // Make empty record return -1; } + update_virtual_fields(tab->join->thd, table); store_record(table,record[1]); } else if (!table->status) // Only happens with left join @@ -12277,10 +12304,10 @@ join_read_const(JOIN_TAB *tab) error=HA_ERR_KEY_NOT_FOUND; else { - error=table->file->index_read_idx_map(table->record[0],tab->ref.key, - (uchar*) tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_KEY_EXACT); + error= table->file->ha_index_read_idx_map(table->record[0],tab->ref.key, + (uchar*) tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_KEY_EXACT); } if (error) { @@ -12291,6 +12318,7 @@ join_read_const(JOIN_TAB *tab) return report_error(table, error); return -1; } + update_virtual_fields(tab->join->thd, table); store_record(table,record[1]); } else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join @@ -12334,10 +12362,10 @@ join_read_key(JOIN_TAB *tab) tab->read_record.file->unlock_row(); tab->ref.has_record= FALSE; } - error=table->file->index_read_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_KEY_EXACT); + error= table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_KEY_EXACT); if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -12418,10 +12446,10 @@ join_read_always_key(JOIN_TAB *tab) if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref)) return -1; - if ((error=table->file->index_read_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_KEY_EXACT))) + if ((error= table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_KEY_EXACT))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -12452,9 +12480,10 @@ join_read_last_key(JOIN_TAB *tab) } if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref)) return -1; - if ((error=table->file->index_read_last_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts)))) + if ((error= table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_PREFIX_LAST))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -12479,9 +12508,9 @@ join_read_next_same(READ_RECORD *info) TABLE *table= info->table; JOIN_TAB *tab=table->reginfo.join_tab; - if ((error=table->file->index_next_same(table->record[0], - tab->ref.key_buff, - tab->ref.key_length))) + if ((error= table->file->ha_index_next_same(table->record[0], + tab->ref.key_buff, + tab->ref.key_length))) { if (error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -12499,7 +12528,7 @@ join_read_prev_same(READ_RECORD *info) TABLE *table= info->table; JOIN_TAB *tab=table->reginfo.join_tab; - if ((error=table->file->index_prev(table->record[0]))) + if ((error= table->file->ha_index_prev(table->record[0]))) return report_error(table, error); if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key, tab->ref.key_length)) @@ -12524,7 +12553,7 @@ int rr_sequential(READ_RECORD *info); int init_read_record_seq(JOIN_TAB *tab) { tab->read_record.read_record= rr_sequential; - if (tab->read_record.file->ha_rnd_init(1)) + if (tab->read_record.file->ha_rnd_init_with_error(1)) return 1; return (*tab->read_record.read_record)(&tab->read_record); } @@ -12544,8 +12573,9 @@ join_init_read_record(JOIN_TAB *tab) { if (tab->select && tab->select->quick && tab->select->quick->reset()) return 1; - init_read_record(&tab->read_record, tab->join->thd, tab->table, - tab->select,1,1, FALSE); + if (init_read_record(&tab->read_record, tab->join->thd, tab->table, + tab->select,1,1, FALSE)) + return 1; return (*tab->read_record.read_record)(&tab->read_record); } @@ -12568,7 +12598,7 @@ join_read_first(JOIN_TAB *tab) error= table->file->ha_index_init(tab->index, tab->sorted); if (!error) error= table->file->prepare_index_scan(); - if (error || (error=tab->table->file->index_first(tab->table->record[0]))) + if (error || (error=tab->table->file->ha_index_first(tab->table->record[0]))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) report_error(table, error); @@ -12582,8 +12612,9 @@ static int join_read_next(READ_RECORD *info) { int error; - if ((error=info->file->index_next(info->record))) + if ((error= info->file->ha_index_next(info->record))) return report_error(info->table, error); + return 0; } @@ -12606,8 +12637,9 @@ join_read_last(JOIN_TAB *tab) error= table->file->ha_index_init(tab->index, 1); if (!error) error= table->file->prepare_index_scan(); - if (error || (error= tab->table->file->index_last(tab->table->record[0]))) + if (error || (error= tab->table->file->ha_index_last(tab->table->record[0]))) return report_error(table, error); + return 0; } @@ -12616,7 +12648,7 @@ static int join_read_prev(READ_RECORD *info) { int error; - if ((error= info->file->index_prev(info->record))) + if ((error= info->file->ha_index_prev(info->record))) return report_error(info->table, error); return 0; } @@ -12641,7 +12673,7 @@ join_ft_read_first(JOIN_TAB *tab) #endif table->file->ft_init(); - if ((error= table->file->ft_read(table->record[0]))) + if ((error= table->file->ha_ft_read(table->record[0]))) return report_error(table, error); return 0; } @@ -12650,7 +12682,7 @@ static int join_ft_read_next(READ_RECORD *info) { int error; - if ((error= info->file->ft_read(info->table->record[0]))) + if ((error= info->file->ha_ft_read(info->table->record[0]))) return report_error(info->table, error); return 0; } @@ -12960,7 +12992,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { int error; join->found_records++; - if ((error=table->file->ha_write_row(table->record[0]))) + if ((error= table->file->ha_write_row(table->record[0]))) { if (!table->file->is_fatal_error(error, HA_CHECK_DUP)) goto end; @@ -13015,15 +13047,15 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (item->maybe_null) group->buff[-1]= (char) group->field->is_null(); } - if (!table->file->index_read_map(table->record[1], - join->tmp_table_param.group_buff, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (!table->file->ha_index_read_map(table->record[1], + join->tmp_table_param.group_buff, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) { /* Update old record */ restore_record(table,record[1]); update_tmptable_sum_func(join->sum_funcs,table); - if ((error=table->file->ha_update_row(table->record[1], - table->record[0]))) + if ((error= table->file->ha_update_row(table->record[1], + table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ @@ -13047,7 +13079,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), init_tmptable_sum_functions(join->sum_funcs); if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if ((error=table->file->ha_write_row(table->record[0]))) + if ((error= table->file->ha_write_row(table->record[0]))) { if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param, @@ -13089,7 +13121,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if (!(error=table->file->ha_write_row(table->record[0]))) + if (!(error= table->file->ha_write_row(table->record[0]))) join->send_records++; // New group else { @@ -13098,15 +13130,15 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } - if (table->file->rnd_pos(table->record[1],table->file->dup_ref)) + if (table->file->ha_rnd_pos(table->record[1],table->file->dup_ref)) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } restore_record(table,record[1]); update_tmptable_sum_func(join->sum_funcs,table); - if ((error=table->file->ha_update_row(table->record[1], - table->record[0]))) + if ((error= table->file->ha_update_row(table->record[1], + table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ @@ -14587,8 +14619,10 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, org_record=(char*) (record=table->record[0])+offset; new_record=(char*) table->record[1]+offset; - file->ha_rnd_init(1); - error=file->rnd_next(record); + if (file->ha_rnd_init_with_error(1)) + DBUG_RETURN(1); + + error= file->ha_rnd_next(record); for (;;) { if (thd->killed) @@ -14601,7 +14635,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, { if (error == HA_ERR_RECORD_DELETED) { - error= file->rnd_next(record); + error= file->ha_rnd_next(record); continue; } if (error == HA_ERR_END_OF_FILE) @@ -14610,9 +14644,9 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, } if (having && !having->val_int()) { - if ((error=file->ha_delete_row(record))) + if ((error= file->ha_delete_row(record))) goto err; - error=file->rnd_next(record); + error= file->ha_rnd_next(record); continue; } if (copy_blobs(first_field)) @@ -14627,7 +14661,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, bool found=0; for (;;) { - if ((error=file->rnd_next(record))) + if ((error= file->ha_rnd_next(record))) { if (error == HA_ERR_RECORD_DELETED) continue; @@ -14637,7 +14671,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, } if (compare_record(table, first_field) == 0) { - if ((error=file->ha_delete_row(record))) + if ((error= file->ha_delete_row(record))) goto err; } else if (!found) @@ -14716,7 +14750,9 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, DBUG_RETURN(1); } - file->ha_rnd_init(1); + if ((error= file->ha_rnd_init(1))) + goto err; + key_pos=key_buffer; for (;;) { @@ -14727,7 +14763,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, error=0; goto err; } - if ((error=file->rnd_next(record))) + if ((error= file->ha_rnd_next(record))) { if (error == HA_ERR_RECORD_DELETED) continue; @@ -14737,7 +14773,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, } if (having && !having->val_int()) { - if ((error=file->ha_delete_row(record))) + if ((error= file->ha_delete_row(record))) goto err; continue; } @@ -14754,7 +14790,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, if (hash_search(&hash, org_key_pos, key_length)) { /* Duplicated found ; Remove the row */ - if ((error=file->ha_delete_row(record))) + if ((error= file->ha_delete_row(record))) goto err; } else @@ -16180,6 +16216,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, char buff[256]; String str(buff,sizeof(buff),&my_charset_bin); str.length(0); + str.extra_allocation(1024); item->print(&str, QT_ORDINARY); item_field->name= sql_strmake(str.ptr(),str.length()); } @@ -17133,8 +17170,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(new Item_string(key_info->name, strlen(key_info->name), system_charset_info)); - length= longlong2str(tab->ref.key_length, keylen_str_buf, 10) - - keylen_str_buf; + length= (longlong10_to_str(tab->ref.key_length, keylen_str_buf, 10) - + keylen_str_buf); item_list.push_back(new Item_string(keylen_str_buf, length, system_charset_info)); for (store_key **ref=tab->ref.key_copy ; *ref ; ref++) @@ -17152,8 +17189,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, register uint length; item_list.push_back(new Item_string(key_info->name, strlen(key_info->name),cs)); - length= longlong2str(key_info->key_length, keylen_str_buf, 10) - - keylen_str_buf; + length= (longlong10_to_str(key_info->key_length, keylen_str_buf, 10) - + keylen_str_buf); item_list.push_back(new Item_string(keylen_str_buf, length, system_charset_info)); diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 2dd27c2b217..61a36d1bbea 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -185,8 +185,9 @@ static bool servers_load(THD *thd, TABLE_LIST *tables) free_root(&mem, MYF(0)); init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0); - init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, - FALSE); + if (init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, + FALSE)) + DBUG_RETURN(1); while (!(read_record_info.read_record(&read_record_info))) { /* return_val is already TRUE, so no need to set */ @@ -529,10 +530,10 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server) system_charset_info); /* read index until record is that specified in server_name */ - if ((error= table->file->index_read_idx_map(table->record[0], 0, - (uchar *)table->field[0]->ptr, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if ((error= table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar *)table->field[0]->ptr, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT))) { /* if not found, err */ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) @@ -872,10 +873,10 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server) server->server_name_length, system_charset_info); - if ((error= table->file->index_read_idx_map(table->record[0], 0, - (uchar *)table->field[0]->ptr, - ~(longlong)0, - HA_READ_KEY_EXACT))) + if ((error= table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar *)table->field[0]->ptr, + ~(longlong)0, + HA_READ_KEY_EXACT))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) table->file->print_error(error, MYF(0)); @@ -929,10 +930,10 @@ delete_server_record(TABLE *table, /* set the field that's the PK to the value we're looking for */ table->field[0]->store(server_name, server_name_length, system_charset_info); - if ((error= table->file->index_read_idx_map(table->record[0], 0, - (uchar *)table->field[0]->ptr, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if ((error= table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar *)table->field[0]->ptr, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) table->file->print_error(error, MYF(0)); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index bb9a4a1e062..1d5d53114a3 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -19,10 +19,11 @@ #include "mysql_priv.h" #include "sql_select.h" // For select_describe +#include "create_options.h" #include "sql_show.h" #include "repl_failsafe.h" -#include "sp.h" #include "sp_head.h" +#include "sp.h" #include "sql_trigger.h" #include "authors.h" #include "contributors.h" @@ -96,11 +97,21 @@ static int make_version_string(char *buf, int buf_length, uint version) return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff); } + +static const LEX_STRING maturity_name[]={ + { C_STRING_WITH_LEN("Unknown") }, + { C_STRING_WITH_LEN("Experimental") }, + { C_STRING_WITH_LEN("Alpha") }, + { C_STRING_WITH_LEN("Beta") }, + { C_STRING_WITH_LEN("Gamma") }, + { C_STRING_WITH_LEN("Stable") }}; + + static my_bool show_plugins(THD *thd, plugin_ref plugin, void *arg) { TABLE *table= (TABLE*) arg; - struct st_mysql_plugin *plug= plugin_decl(plugin); + struct st_maria_plugin *plug= plugin_decl(plugin); struct st_plugin_dl *plugin_dl= plugin_dlib(plugin); CHARSET_INFO *cs= system_charset_info; char version_buf[20]; @@ -145,7 +156,7 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, table->field[5]->set_notnull(); table->field[6]->store(version_buf, make_version_string(version_buf, sizeof(version_buf), - plugin_dl->version), + plugin_dl->mariaversion), cs); table->field[6]->set_notnull(); } @@ -188,6 +199,26 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, } table->field[9]->set_notnull(); + if ((uint) plug->maturity <= MariaDB_PLUGIN_MATURITY_STABLE) + table->field[10]->store(maturity_name[plug->maturity].str, + maturity_name[plug->maturity].length, + cs); + else + { + DBUG_ASSERT(0); + table->field[10]->store("Unknown", 7, cs); + } + table->field[10]->set_notnull(); + + if (plug->version_info) + { + table->field[11]->store(plug->version_info, + strlen(plug->version_info), cs); + table->field[11]->set_notnull(); + } + else + table->field[11]->set_null(); + return schema_table_store_record(thd, table); } @@ -780,7 +811,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) protocol->store(table_list->schema_table->table_name, system_charset_info); else - protocol->store(table_list->table->alias, system_charset_info); + protocol->store(table_list->table->alias.c_ptr(), system_charset_info); } if (table_list->view) @@ -826,6 +857,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname, sctx->master_access); if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname)) { + status_var_increment(thd->status_var.access_denied_errors); my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->host_or_ip, dbname); general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), @@ -1017,7 +1049,7 @@ append_identifier(THD *thd, String *packet, const char *name, uint length) /* The identifier must be quoted as it includes a quote character or - it's a keyword + it's a keyword */ VOID(packet->reserve(length*2 + 2)); @@ -1143,7 +1175,7 @@ static bool get_field_default_value(THD *thd, TABLE *table, if (field_type == MYSQL_TYPE_BIT) { longlong dec= field->val_int(); - char *ptr= longlong2str(dec, tmp + 2, 2); + char *ptr= longlong2str(dec, tmp + 2, 2, 1); uint32 length= (uint32) (ptr - tmp); tmp[0]= 'b'; tmp[1]= '\''; @@ -1177,6 +1209,31 @@ static bool get_field_default_value(THD *thd, TABLE *table, return has_default; } + +/** + Appends list of options to string + + @param thd thread handler + @param packet string to append + @param opt list of options +*/ + +static void append_create_options(THD *thd, String *packet, + engine_option_value *opt) +{ + for(; opt; opt= opt->next) + { + DBUG_ASSERT(opt->value.str); + packet->append(' '); + append_identifier(thd, packet, opt->name.str, opt->name.length); + packet->append('='); + if (opt->quoted_value) + append_unescaped(packet, opt->value.str, opt->value.length); + else + packet->append(opt->value.str, opt->value.length); + } +} + /* Build a CREATE TABLE statement for a table. @@ -1243,7 +1300,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, else { if (lower_case_table_names == 2) - alias= table->alias; + alias= table->alias.c_ptr(); else { alias= share->table_name.str; @@ -1315,6 +1372,19 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, } } + if (field->vcol_info) + { + packet->append(STRING_WITH_LEN(" AS (")); + packet->append(field->vcol_info->expr_str.str, + field->vcol_info->expr_str.length, + system_charset_info); + packet->append(STRING_WITH_LEN(")")); + if (field->stored_in_db) + packet->append(STRING_WITH_LEN(" PERSISTENT")); + else + packet->append(STRING_WITH_LEN(" VIRTUAL")); + } + if (flags & NOT_NULL_FLAG) packet->append(STRING_WITH_LEN(" NOT NULL")); else if (field->type() == MYSQL_TYPE_TIMESTAMP) @@ -1326,7 +1396,8 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, packet->append(STRING_WITH_LEN(" NULL")); } - if (get_field_default_value(thd, table, field, &def_value, 1)) + if (!field->vcol_info && + get_field_default_value(thd, table, field, &def_value, 1)) { packet->append(STRING_WITH_LEN(" DEFAULT ")); packet->append(def_value.ptr(), def_value.length(), system_charset_info); @@ -1345,6 +1416,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, packet->append(STRING_WITH_LEN(" COMMENT ")); append_unescaped(packet, field->comment.str, field->comment.length); } + append_create_options(thd, packet, field->option_list); } key_info= table->key_info; @@ -1416,6 +1488,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, append_identifier(thd, packet, parser_name->str, parser_name->length); packet->append(STRING_WITH_LEN(" */ ")); } + append_create_options(thd, packet, key_info->option_list); } /* @@ -1577,6 +1650,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, packet->append(STRING_WITH_LEN(" CONNECTION=")); append_unescaped(packet, share->connect_string.str, share->connect_string.length); } + append_create_options(thd, packet, share->option_list); append_directory(thd, packet, "DATA", create_info.data_file_name); append_directory(thd, packet, "INDEX", create_info.index_file_name); } @@ -1863,7 +1937,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) pthread_mutex_lock(&tmp->LOCK_thd_data); if ((mysys_var= tmp->mysys_var)) pthread_mutex_lock(&mysys_var->mutex); - thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0); + thd_info->proc_info= (char*) (tmp->killed != THD::NOT_KILLED && + tmp->killed != THD::KILL_BAD_DATA ? + "Killed" : 0); #ifndef EMBEDDED_LIBRARY thd_info->state_info= (char*) (tmp->locked ? "Locked" : tmp->net.reading_or_writing ? @@ -1981,7 +2057,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) if ((mysys_var= tmp->mysys_var)) pthread_mutex_lock(&mysys_var->mutex); /* COMMAND */ - if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0))) + if ((val= (char *) ((tmp->killed != THD::NOT_KILLED && + tmp->killed != THD::KILL_BAD_DATA ? + "Killed" : 0)))) table->field[4]->store(val, strlen(val), cs); else table->field[4]->store(command_name[tmp->command].str, @@ -2213,11 +2291,7 @@ void remove_status_vars(SHOW_VAR *list) } } -inline void make_upper(char *buf) -{ - for (; *buf; buf++) - *buf= my_toupper(system_charset_info, *buf); -} + static bool show_status_array(THD *thd, const char *wild, SHOW_VAR *variables, @@ -2256,7 +2330,7 @@ static bool show_status_array(THD *thd, const char *wild, strnmov(prefix_end, variables->name, len); name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ if (ucase_names) - make_upper(name_buffer); + my_caseup_str(system_charset_info, name_buffer); restore_record(table, s->default_values); table->field[0]->store(name_buffer, strlen(name_buffer), @@ -2350,14 +2424,6 @@ static bool show_status_array(THD *thd, const char *wild, end= strend(pos); break; } - case SHOW_KEY_CACHE_LONG: - value= (char*) dflt_key_cache + (ulong)value; - end= int10_to_str(*(long*) value, buff, 10); - break; - case SHOW_KEY_CACHE_LONGLONG: - value= (char*) dflt_key_cache + (ulong)value; - end= longlong10_to_str(*(longlong*) value, buff, 10); - break; case SHOW_UNDEF: break; // Return empty string case SHOW_SYS: // Cannot happen @@ -2383,6 +2449,323 @@ end: DBUG_RETURN(res); } +#ifdef COMPLEAT_PATCH_NOT_ADDED_YET +/* + Aggregate values for mapped_user entries by their role. + + SYNOPSIS + aggregate_user_stats + all_user_stats - input to aggregate + agg_user_stats - returns aggregated values + + RETURN + 0 - OK + 1 - error +*/ + +static int aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats) +{ + DBUG_ENTER("aggregate_user_stats"); + if (hash_init(agg_user_stats, system_charset_info, + max(all_user_stats->records, 1), + 0, 0, (hash_get_key)get_key_user_stats, + (hash_free_key)free_user_stats, 0)) + { + sql_print_error("Malloc in aggregate_user_stats failed"); + DBUG_RETURN(1); + } + + for (uint i= 0; i < all_user_stats->records; i++) + { + USER_STATS *user= (USER_STATS*)hash_element(all_user_stats, i); + USER_STATS *agg_user; + uint name_length= strlen(user->priv_user); + + if (!(agg_user= (USER_STATS*) hash_search(agg_user_stats, + (uchar*)user->priv_user, + name_length))) + { + // First entry for this role. + if (!(agg_user= (USER_STATS*) my_malloc(sizeof(USER_STATS), + MYF(MY_WME | MY_ZEROFILL)))) + { + sql_print_error("Malloc in aggregate_user_stats failed"); + DBUG_RETURN(1); + } + + init_user_stats(agg_user, user->priv_user, name_length, + user->priv_user, + user->total_connections, user->concurrent_connections, + user->connected_time, user->busy_time, user->cpu_time, + user->bytes_received, user->bytes_sent, + user->binlog_bytes_written, + user->rows_sent, user->rows_read, + user->rows_inserted, user->rows_deleted, + user->rows_updated, + user->select_commands, user->update_commands, + user->other_commands, + user->commit_trans, user->rollback_trans, + user->denied_connections, user->lost_connections, + user->access_denied_errors, user->empty_queries); + + if (my_hash_insert(agg_user_stats, (uchar*) agg_user)) + { + /* Out of memory */ + my_free(agg_user, 0); + sql_print_error("Malloc in aggregate_user_stats failed"); + DBUG_RETURN(1); + } + } + else + { + /* Aggregate with existing values for this role. */ + add_user_stats(agg_user, + user->total_connections, user->concurrent_connections, + user->connected_time, user->busy_time, user->cpu_time, + user->bytes_received, user->bytes_sent, + user->binlog_bytes_written, + user->rows_sent, user->rows_read, + user->rows_inserted, user->rows_deleted, + user->rows_updated, + user->select_commands, user->update_commands, + user->other_commands, + user->commit_trans, user->rollback_trans, + user->denied_connections, user->lost_connections, + user->access_denied_errors, user->empty_queries); + } + } + DBUG_PRINT("exit", ("aggregated %lu input into %lu output entries", + all_user_stats->records, agg_user_stats->records)); + DBUG_RETURN(0); +} +#endif + +/* + Write result to network for SHOW USER_STATISTICS + + SYNOPSIS + send_user_stats + all_user_stats - values to return + table - I_S table + + RETURN + 0 - OK + 1 - error +*/ + +int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table) +{ + DBUG_ENTER("send_user_stats"); + + for (uint i= 0; i < all_user_stats->records; i++) + { + uint j= 0; + USER_STATS *user_stats= (USER_STATS*) hash_element(all_user_stats, i); + + table->field[j++]->store(user_stats->user, user_stats->user_name_length, + system_charset_info); + table->field[j++]->store((longlong)user_stats->total_connections,TRUE); + table->field[j++]->store((longlong)user_stats->concurrent_connections, TRUE); + table->field[j++]->store((longlong)user_stats->connected_time, TRUE); + table->field[j++]->store((double)user_stats->busy_time); + table->field[j++]->store((double)user_stats->cpu_time); + table->field[j++]->store((longlong)user_stats->bytes_received, TRUE); + table->field[j++]->store((longlong)user_stats->bytes_sent, TRUE); + table->field[j++]->store((longlong)user_stats->binlog_bytes_written, TRUE); + table->field[j++]->store((longlong)user_stats->rows_read, TRUE); + table->field[j++]->store((longlong)user_stats->rows_sent, TRUE); + table->field[j++]->store((longlong)user_stats->rows_deleted, TRUE); + table->field[j++]->store((longlong)user_stats->rows_inserted, TRUE); + table->field[j++]->store((longlong)user_stats->rows_updated, TRUE); + table->field[j++]->store((longlong)user_stats->select_commands, TRUE); + table->field[j++]->store((longlong)user_stats->update_commands, TRUE); + table->field[j++]->store((longlong)user_stats->other_commands, TRUE); + table->field[j++]->store((longlong)user_stats->commit_trans, TRUE); + table->field[j++]->store((longlong)user_stats->rollback_trans, TRUE); + table->field[j++]->store((longlong)user_stats->denied_connections, TRUE); + table->field[j++]->store((longlong)user_stats->lost_connections, TRUE); + table->field[j++]->store((longlong)user_stats->access_denied_errors, TRUE); + table->field[j++]->store((longlong)user_stats->empty_queries, TRUE); + if (schema_table_store_record(thd, table)) + { + DBUG_PRINT("error", ("store record error")); + DBUG_RETURN(1); + } + } + DBUG_RETURN(0); +} + +/* + Process SHOW USER_STATISTICS + + SYNOPSIS + mysqld_show_user_stats + thd - current thread + wild - limit results to the entry for this user + with_roles - when true, display role for mapped users + + RETURN + 0 - OK + 1 - error +*/ + +int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond) +{ + TABLE *table= tables->table; + int result; + DBUG_ENTER("fill_schema_user_stats"); + + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) + DBUG_RETURN(1); + + /* + Iterates through all the global stats and sends them to the client. + Pattern matching on the client IP is supported. + */ + + pthread_mutex_lock(&LOCK_global_user_client_stats); + result= send_user_stats(thd, &global_user_stats, table) != 0; + pthread_mutex_unlock(&LOCK_global_user_client_stats); + + DBUG_PRINT("exit", ("result: %d", result)); + DBUG_RETURN(result); +} + +/* + Process SHOW CLIENT_STATISTICS + + SYNOPSIS + mysqld_show_client_stats + thd - current thread + wild - limit results to the entry for this client + + RETURN + 0 - OK + 1 - error +*/ + +int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond) +{ + TABLE *table= tables->table; + int result; + DBUG_ENTER("fill_schema_client_stats"); + + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) + DBUG_RETURN(1); + + /* + Iterates through all the global stats and sends them to the client. + Pattern matching on the client IP is supported. + */ + + pthread_mutex_lock(&LOCK_global_user_client_stats); + result= send_user_stats(thd, &global_client_stats, table) != 0; + pthread_mutex_unlock(&LOCK_global_user_client_stats); + + DBUG_PRINT("exit", ("result: %d", result)); + DBUG_RETURN(result); +} + + +/* Fill information schema table with table statistics */ + +int fill_schema_table_stats(THD *thd, TABLE_LIST *tables, COND *cond) +{ + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_table_stats"); + + pthread_mutex_lock(&LOCK_global_table_stats); + for (uint i= 0; i < global_table_stats.records; i++) + { + char *end_of_schema; + TABLE_STATS *table_stats= + (TABLE_STATS*)hash_element(&global_table_stats, i); + TABLE_LIST tmp_table; + size_t schema_length, table_name_length; + + end_of_schema= strend(table_stats->table); + schema_length= (size_t) (end_of_schema - table_stats->table); + table_name_length= strlen(table_stats->table + schema_length + 1); + + bzero((char*) &tmp_table,sizeof(tmp_table)); + tmp_table.db= table_stats->table; + tmp_table.table_name= end_of_schema+1; + tmp_table.grant.privilege= 0; + if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db, + &tmp_table.grant.privilege, 0, 0, + is_schema_db(tmp_table.db)) || + check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, + 1)) + continue; + + table->field[0]->store(table_stats->table, schema_length, + system_charset_info); + table->field[1]->store(table_stats->table + schema_length+1, + table_name_length, system_charset_info); + table->field[2]->store((longlong)table_stats->rows_read, TRUE); + table->field[3]->store((longlong)table_stats->rows_changed, TRUE); + table->field[4]->store((longlong)table_stats->rows_changed_x_indexes, + TRUE); + if (schema_table_store_record(thd, table)) + { + VOID(pthread_mutex_unlock(&LOCK_global_table_stats)); + DBUG_RETURN(1); + } + } + pthread_mutex_unlock(&LOCK_global_table_stats); + DBUG_RETURN(0); +} + + +/* Fill information schema table with index statistics */ + +int fill_schema_index_stats(THD *thd, TABLE_LIST *tables, COND *cond) +{ + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_index_stats"); + + pthread_mutex_lock(&LOCK_global_index_stats); + for (uint i= 0; i < global_index_stats.records; i++) + { + INDEX_STATS *index_stats = + (INDEX_STATS*) hash_element(&global_index_stats, i); + TABLE_LIST tmp_table; + char *index_name; + size_t schema_name_length, table_name_length, index_name_length; + + bzero((char*) &tmp_table,sizeof(tmp_table)); + tmp_table.db= index_stats->index; + tmp_table.table_name= strend(index_stats->index)+1; + tmp_table.grant.privilege= 0; + if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db, + &tmp_table.grant.privilege, 0, 0, + is_schema_db(tmp_table.db)) || + check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1)) + continue; + + index_name= strend(tmp_table.table_name)+1; + schema_name_length= (tmp_table.table_name - index_stats->index) -1; + table_name_length= (index_name - tmp_table.table_name)-1; + index_name_length= (index_stats->index_name_length - schema_name_length - + table_name_length - 3); + + table->field[0]->store(tmp_table.db, schema_name_length, + system_charset_info); + table->field[1]->store(tmp_table.table_name, table_name_length, + system_charset_info); + table->field[2]->store(index_name, index_name_length, system_charset_info); + table->field[3]->store((longlong)index_stats->rows_read, TRUE); + + if (schema_table_store_record(thd, table)) + { + VOID(pthread_mutex_unlock(&LOCK_global_index_stats)); + DBUG_RETURN(1); + } + } + pthread_mutex_unlock(&LOCK_global_index_stats); + DBUG_RETURN(0); +} + /* collect status for all running threads */ @@ -3722,7 +4105,8 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, } else { - char option_buff[350],*ptr; + char option_buff[350]; + String str(option_buff,sizeof(option_buff), system_charset_info); TABLE *show_table= tables->table; TABLE_SHARE *share= show_table->s; handler *file= show_table->file; @@ -3755,53 +4139,58 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, table->field[4]->store(tmp_buff, strlen(tmp_buff), cs); table->field[5]->store((longlong) share->frm_version, TRUE); - ptr=option_buff; + str.length(0); if (share->min_rows) { - ptr=strmov(ptr," min_rows="); - ptr=longlong10_to_str(share->min_rows,ptr,10); + str.qs_append(STRING_WITH_LEN(" min_rows=")); + str.qs_append(share->min_rows); } if (share->max_rows) { - ptr=strmov(ptr," max_rows="); - ptr=longlong10_to_str(share->max_rows,ptr,10); + str.qs_append(STRING_WITH_LEN(" max_rows=")); + str.qs_append(share->max_rows); } if (share->avg_row_length) { - ptr=strmov(ptr," avg_row_length="); - ptr=longlong10_to_str(share->avg_row_length,ptr,10); + str.qs_append(STRING_WITH_LEN(" avg_row_length=")); + str.qs_append(share->avg_row_length); } if (share->db_create_options & HA_OPTION_PACK_KEYS) - ptr=strmov(ptr," pack_keys=1"); + str.qs_append(STRING_WITH_LEN(" pack_keys=1")); if (share->db_create_options & HA_OPTION_NO_PACK_KEYS) - ptr=strmov(ptr," pack_keys=0"); + str.qs_append(STRING_WITH_LEN(" pack_keys=0")); /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */ if (share->db_create_options & HA_OPTION_CHECKSUM) - ptr=strmov(ptr," checksum=1"); + str.qs_append(STRING_WITH_LEN(" checksum=1")); if (share->page_checksum != HA_CHOICE_UNDEF) - ptr= strxmov(ptr, " page_checksum=", - ha_choice_values[(uint) share->page_checksum], NullS); + { + str.qs_append(STRING_WITH_LEN(" page_checksum=")); + str.qs_append(ha_choice_values[(uint) share->page_checksum]); + } if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE) - ptr=strmov(ptr," delay_key_write=1"); + str.qs_append(STRING_WITH_LEN(" delay_key_write=1")); if (share->row_type != ROW_TYPE_DEFAULT) - ptr=strxmov(ptr, " row_format=", - ha_row_type[(uint) share->row_type], - NullS); + { + str.qs_append(STRING_WITH_LEN(" row_format=")); + str.qs_append(ha_row_type[(uint) share->row_type]); + } if (share->key_block_size) { - ptr= strmov(ptr, " key_block_size="); - ptr= longlong10_to_str(share->key_block_size, ptr, 10); + str.qs_append(STRING_WITH_LEN(" key_block_size=")); + str.qs_append(share->key_block_size); } #ifdef WITH_PARTITION_STORAGE_ENGINE if (is_partitioned) - ptr= strmov(ptr, " partitioned"); + str.qs_append(STRING_WITH_LEN(" partitioned")); #endif if (share->transactional != HA_CHOICE_UNDEF) - ptr= strxmov(ptr, " transactional=", - ha_choice_values[(uint) share->transactional], NullS); - table->field[19]->store(option_buff+1, - (ptr == option_buff ? 0 : - (uint) (ptr-option_buff)-1), cs); + { + str.qs_append(STRING_WITH_LEN(" transactional=")); + str.qs_append(ha_choice_values[(uint) share->transactional]); + } + append_create_options(thd, &str, share->option_list); + if (str.length()) + table->field[19]->store(str.ptr()+1, str.length()-1, cs); tmp_buff= (share->table_charset ? share->table_charset->name : "default"); @@ -4114,6 +4503,8 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, field->unireg_check != Field::TIMESTAMP_DN_FIELD) table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"), cs); + if (field->vcol_info) + table->field[16]->store(STRING_WITH_LEN("VIRTUAL"), cs); table->field[18]->store(field->comment.str, field->comment.length, cs); if (schema_table_store_record(thd, table)) @@ -4170,7 +4561,7 @@ static my_bool iter_schema_engines(THD *thd, plugin_ref plugin, if (plugin_state(plugin) != PLUGIN_IS_READY) { - struct st_mysql_plugin *plug= plugin_decl(plugin); + struct st_maria_plugin *plug= plugin_decl(plugin); if (!(wild && wild[0] && wild_case_compare(scs, plug->name,wild))) { @@ -4412,7 +4803,7 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_RETURN(1); } proc_table->file->ha_index_init(0, 1); - if ((res= proc_table->file->index_first(proc_table->record[0]))) + if ((res= proc_table->file->ha_index_first(proc_table->record[0]))) { res= (res == HA_ERR_END_OF_FILE) ? 0 : 1; goto err; @@ -4422,7 +4813,7 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) res= 1; goto err; } - while (!proc_table->file->index_next(proc_table->record[0])) + while (!proc_table->file->ha_index_next(proc_table->record[0])) { if (store_schema_proc(thd, table, proc_table, wild, full_access, definer)) { @@ -5330,7 +5721,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) if (et.load_from_row(thd, event_table)) { - my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias); + my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias.c_ptr()); DBUG_RETURN(1); } @@ -5659,6 +6050,81 @@ struct schema_table_ref ST_SCHEMA_TABLE *schema_table; }; +ST_FIELD_INFO user_stats_fields_info[]= +{ + {"USER", USERNAME_LENGTH, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE}, + {"TOTAL_CONNECTIONS", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections",SKIP_OPEN_TABLE}, + {"CONCURRENT_CONNECTIONS", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections",SKIP_OPEN_TABLE}, + {"CONNECTED_TIME", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time",SKIP_OPEN_TABLE}, + {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_DOUBLE, 0, 0, "Busy_time",SKIP_OPEN_TABLE}, + {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_DOUBLE, 0, 0, "Cpu_time",SKIP_OPEN_TABLE}, + {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Bytes_received",SKIP_OPEN_TABLE}, + {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Bytes_sent",SKIP_OPEN_TABLE}, + {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Binlog_bytes_written",SKIP_OPEN_TABLE}, + {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_read",SKIP_OPEN_TABLE}, + {"ROWS_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_sent",SKIP_OPEN_TABLE}, + {"ROWS_DELETED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_deleted",SKIP_OPEN_TABLE}, + {"ROWS_INSERTED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_inserted",SKIP_OPEN_TABLE}, + {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_updated",SKIP_OPEN_TABLE}, + {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Select_commands",SKIP_OPEN_TABLE}, + {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Update_commands",SKIP_OPEN_TABLE}, + {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Other_commands",SKIP_OPEN_TABLE}, + {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Commit_transactions",SKIP_OPEN_TABLE}, + {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rollback_transactions",SKIP_OPEN_TABLE}, + {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Denied_connections",SKIP_OPEN_TABLE}, + {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Lost_connections",SKIP_OPEN_TABLE}, + {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Access_denied",SKIP_OPEN_TABLE}, + {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Empty_queries",SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + +ST_FIELD_INFO client_stats_fields_info[]= +{ + {"CLIENT", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Client",SKIP_OPEN_TABLE}, + {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Total_connections",SKIP_OPEN_TABLE}, + {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Concurrent_connections",SKIP_OPEN_TABLE}, + {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Connected_time",SKIP_OPEN_TABLE}, + {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_DOUBLE, 0, 0, "Busy_time",SKIP_OPEN_TABLE}, + {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_DOUBLE, 0, 0, "Cpu_time",SKIP_OPEN_TABLE}, + {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Bytes_received",SKIP_OPEN_TABLE}, + {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Bytes_sent",SKIP_OPEN_TABLE}, + {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Binlog_bytes_written",SKIP_OPEN_TABLE}, + {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_read",SKIP_OPEN_TABLE}, + {"ROWS_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_sent",SKIP_OPEN_TABLE}, + {"ROWS_DELETED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_deleted",SKIP_OPEN_TABLE}, + {"ROWS_INSERTED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_inserted",SKIP_OPEN_TABLE}, + {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_updated",SKIP_OPEN_TABLE}, + {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Select_commands",SKIP_OPEN_TABLE}, + {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Update_commands",SKIP_OPEN_TABLE}, + {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Other_commands",SKIP_OPEN_TABLE}, + {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Commit_transactions",SKIP_OPEN_TABLE}, + {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rollback_transactions",SKIP_OPEN_TABLE}, + {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Denied_connections",SKIP_OPEN_TABLE}, + {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Lost_connections",SKIP_OPEN_TABLE}, + {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Access_denied",SKIP_OPEN_TABLE}, + {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Empty_queries",SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO table_stats_fields_info[]= +{ + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema",SKIP_OPEN_TABLE}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name",SKIP_OPEN_TABLE}, + {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_read",SKIP_OPEN_TABLE}, + {"ROWS_CHANGED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_changed",SKIP_OPEN_TABLE}, + {"ROWS_CHANGED_X_INDEXES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_changed_x_#indexes",SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + +ST_FIELD_INFO index_stats_fields_info[]= +{ + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema",SKIP_OPEN_TABLE}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name",SKIP_OPEN_TABLE}, + {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name",SKIP_OPEN_TABLE}, + {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_read",SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0,0} +}; /* Find schema_tables elment by name @@ -6298,6 +6764,90 @@ int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond) } +static +int store_key_cache_table_record(THD *thd, TABLE *table, + const char *name, uint name_length, + KEY_CACHE *key_cache, + uint partitions, uint partition_no) +{ + KEY_CACHE_STATISTICS keycache_stats; + uint err; + DBUG_ENTER("store_key_cache_table_record"); + + get_key_cache_statistics(key_cache, partition_no, &keycache_stats); + + if (!key_cache->key_cache_inited || keycache_stats.mem_size == 0) + DBUG_RETURN(0); + + restore_record(table, s->default_values); + table->field[0]->store(name, name_length, system_charset_info); + if (partitions == 0) + table->field[1]->set_null(); + else + { + table->field[1]->set_notnull(); + table->field[1]->store((long) partitions, TRUE); + } + + if (partition_no == 0) + table->field[2]->set_null(); + else + { + table->field[2]->set_notnull(); + table->field[2]->store((long) partition_no, TRUE); + } + table->field[3]->store(keycache_stats.mem_size, TRUE); + table->field[4]->store(keycache_stats.block_size, TRUE); + table->field[5]->store(keycache_stats.blocks_used, TRUE); + table->field[6]->store(keycache_stats.blocks_unused, TRUE); + table->field[7]->store(keycache_stats.blocks_changed, TRUE); + table->field[8]->store(keycache_stats.read_requests, TRUE); + table->field[9]->store(keycache_stats.reads, TRUE); + table->field[10]->store(keycache_stats.write_requests, TRUE); + table->field[11]->store(keycache_stats.writes, TRUE); + + err= schema_table_store_record(thd, table); + DBUG_RETURN(err); +} + + +int fill_key_cache_tables(THD *thd, TABLE_LIST *tables, COND *cond) +{ + TABLE *table= tables->table; + I_List_iterator<NAMED_LIST> it(key_caches); + NAMED_LIST *element; + DBUG_ENTER("fill_key_cache_tables"); + + while ((element= it++)) + { + KEY_CACHE *key_cache= (KEY_CACHE *) element->data; + + if (!key_cache->key_cache_inited) + continue; + + uint partitions= key_cache->partitions; + DBUG_ASSERT(partitions <= MAX_KEY_CACHE_PARTITIONS); + + if (partitions) + { + for (uint i= 0; i < partitions; i++) + { + if (store_key_cache_table_record(thd, table, + element->name, element->name_length, + key_cache, partitions, i+1)) + DBUG_RETURN(1); + } + } + + if (store_key_cache_table_record(thd, table, + element->name, element->name_length, + key_cache, partitions, 0)) + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + + ST_FIELD_INFO schema_fields_info[]= { {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, @@ -6783,6 +7333,8 @@ ST_FIELD_INFO plugin_fields_info[]= {"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE}, + {"PLUGIN_MATURITY", 12, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"PLUGIN_AUTH_VERSION", 80, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -6875,6 +7427,35 @@ ST_FIELD_INFO referential_constraints_fields_info[]= }; +ST_FIELD_INFO keycache_fields_info[]= +{ + {"KEY_CACHE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"SEGMENTS", 3, MYSQL_TYPE_LONG, 0, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED) , 0, SKIP_OPEN_TABLE}, + {"SEGMENT_NUMBER", 3, MYSQL_TYPE_LONG, 0, + (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE}, + {"FULL_SIZE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, + (MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE}, + {"BLOCK_SIZE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, + (MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE }, + {"USED_BLOCKS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, + (MY_I_S_UNSIGNED), "Key_blocks_used", SKIP_OPEN_TABLE}, + {"UNUSED_BLOCKS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, + (MY_I_S_UNSIGNED), "Key_blocks_unused", SKIP_OPEN_TABLE}, + {"DIRTY_BLOCKS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, + (MY_I_S_UNSIGNED), "Key_blocks_not_flushed", SKIP_OPEN_TABLE}, + {"READ_REQUESTS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, + (MY_I_S_UNSIGNED), "Key_read_requests", SKIP_OPEN_TABLE}, + {"READS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, + (MY_I_S_UNSIGNED), "Key_reads", SKIP_OPEN_TABLE}, + {"WRITE_REQUESTS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, + (MY_I_S_UNSIGNED), "Key_write_requests", SKIP_OPEN_TABLE}, + {"WRITES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, + (MY_I_S_UNSIGNED), "Key_writes", SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} +}; + + /* Description of ST_FIELD_INFO in table.h @@ -6886,6 +7467,8 @@ ST_SCHEMA_TABLE schema_tables[]= { {"CHARACTER_SETS", charsets_fields_info, create_schema_table, fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0}, + {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table, + fill_schema_client_stats, make_old_format, 0, -1, -1, 0, 0}, {"COLLATIONS", collation_fields_info, create_schema_table, fill_schema_collation, make_old_format, 0, -1, -1, 0, 0}, {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info, @@ -6910,6 +7493,10 @@ ST_SCHEMA_TABLE schema_tables[]= fill_status, make_old_format, 0, 0, -1, 0, 0}, {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table, fill_variables, make_old_format, 0, 0, -1, 0, 0}, + {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table, + fill_schema_index_stats, make_old_format, 0, -1, -1, 0, 0}, + {"KEY_CACHES", keycache_fields_info, create_schema_table, + fill_key_cache_tables, make_old_format, 0, -1,-1, 0, 0}, {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table, get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0, OPEN_TABLE_ONLY}, @@ -6951,11 +7538,15 @@ ST_SCHEMA_TABLE schema_tables[]= get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0}, {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table, fill_schema_table_privileges, 0, 0, -1, -1, 0, 0}, + {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table, + fill_schema_table_stats, make_old_format, 0, -1, -1, 0, 0}, {"TRIGGERS", triggers_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0, OPEN_TABLE_ONLY}, {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, fill_schema_user_privileges, 0, 0, -1, -1, 0, 0}, + {"USER_STATISTICS", user_stats_fields_info, create_schema_table, + fill_schema_user_stats, make_old_format, 0, -1, -1, 0, 0}, {"VARIABLES", variables_fields_info, create_schema_table, fill_variables, make_old_format, 0, 0, -1, 1, 0}, {"VIEWS", view_fields_info, create_schema_table, diff --git a/sql/sql_string.cc b/sql/sql_string.cc index d56766f8994..c14dee91c73 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -28,9 +28,11 @@ #ifdef HAVE_FCONVERT #include <floatingpoint.h> #endif - #include "sql_string.h" +#ifdef MYSQL_CLIENT +#error Attempt to use server-side sql_string on client. Use client/sql_string.cc +#endif /***************************************************************************** ** String functions *****************************************************************************/ @@ -447,7 +449,7 @@ bool String::append(const String &s) { if (s.length()) { - if (realloc(str_length+s.length())) + if (realloc_with_extra_if_needed(str_length+s.length())) return TRUE; memcpy(Ptr+str_length,s.ptr(),s.length()); str_length+=s.length(); @@ -472,7 +474,7 @@ bool String::append(const char *s,uint32 arg_length) { uint32 add_length=arg_length * str_charset->mbmaxlen; uint dummy_errors; - if (realloc(str_length+ add_length)) + if (realloc_with_extra_if_needed(str_length+ add_length)) return TRUE; str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset, s, arg_length, &my_charset_latin1, @@ -483,7 +485,7 @@ bool String::append(const char *s,uint32 arg_length) /* For an ASCII compatinble string we can just append. */ - if (realloc(str_length+arg_length)) + if (realloc_with_extra_if_needed(str_length+arg_length)) return TRUE; memcpy(Ptr+str_length,s,arg_length); str_length+=arg_length; @@ -514,14 +516,14 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) { uint32 add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen; uint dummy_errors; - if (realloc(str_length + add_length)) + if (realloc_with_extra_if_needed(str_length + add_length)) return TRUE; str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset, s, arg_length, cs, &dummy_errors); } else { - if (realloc(str_length + arg_length)) + if (realloc_with_extra_if_needed(str_length + arg_length)) return TRUE; memcpy(Ptr + str_length, s, arg_length); str_length+= arg_length; @@ -533,7 +535,7 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) #ifdef TO_BE_REMOVED bool String::append(FILE* file, uint32 arg_length, myf my_flags) { - if (realloc(str_length+arg_length)) + if (realloc_with_extra_if_needed(str_length+arg_length)) return TRUE; if (my_fread(file, (uchar*) Ptr + str_length, arg_length, my_flags)) { @@ -547,7 +549,7 @@ bool String::append(FILE* file, uint32 arg_length, myf my_flags) bool String::append(IO_CACHE* file, uint32 arg_length) { - if (realloc(str_length+arg_length)) + if (realloc_with_extra_if_needed(str_length+arg_length)) return TRUE; if (my_b_read(file, (uchar*) Ptr + str_length, arg_length)) { @@ -563,7 +565,7 @@ bool String::append_with_prefill(const char *s,uint32 arg_length, { int t_length= arg_length > full_length ? arg_length : full_length; - if (realloc(str_length + t_length)) + if (realloc_with_extra_if_needed(str_length + t_length)) return TRUE; t_length= full_length - arg_length; if (t_length > 0) @@ -672,7 +674,7 @@ bool String::replace(uint32 offset,uint32 arg_length, { if (diff) { - if (realloc(str_length+(uint32) diff)) + if (realloc_with_extra_if_needed(str_length+(uint32) diff)) return TRUE; bmove_upp((uchar*) Ptr+str_length+diff, (uchar*) Ptr+str_length, str_length-offset-arg_length); @@ -723,10 +725,10 @@ void String::qs_append(int i) str_length+= (int) (end-buff); } -void String::qs_append(uint i) +void String::qs_append(ulonglong i) { char *buff= Ptr + str_length; - char *end= int10_to_str(i, buff, 10); + char *end= longlong10_to_str(i, buff,10); str_length+= (int) (end-buff); } diff --git a/sql/sql_string.h b/sql/sql_string.h index 44e7c1894bb..a4bc2f53f3a 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -1,5 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2008-2011 Monty Program Ab 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,6 +18,9 @@ /* This file is originally from the mysql distribution. Coded by monty */ +#ifndef MYSQL_SQL_STRING_H_INCLUDED +#define MYSQL_SQL_STRING_H_INCLUDED + #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ #endif @@ -25,6 +29,10 @@ #define NOT_FIXED_DEC 31 #endif +#ifdef MYSQL_CLIENT +#error Attempt to use server-side sql_string on client. Use client/sql_string.h +#endif + class String; int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); @@ -49,23 +57,24 @@ uint convert_to_printable(char *to, size_t to_len, class String { char *Ptr; - uint32 str_length,Alloced_length; + uint32 str_length,Alloced_length, extra_alloc; bool alloced; CHARSET_INFO *str_charset; public: String() { - Ptr=0; str_length=Alloced_length=0; alloced=0; + Ptr=0; str_length=Alloced_length=extra_alloc=0; alloced=0; str_charset= &my_charset_bin; } String(uint32 length_arg) { - alloced=0; Alloced_length=0; (void) real_alloc(length_arg); + alloced=0; Alloced_length= extra_alloc= 0; (void) real_alloc(length_arg); str_charset= &my_charset_bin; } String(const char *str, CHARSET_INFO *cs) { - Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0; + Ptr=(char*) str; str_length= (uint32) strlen(str); + Alloced_length= extra_alloc= 0; alloced=0; str_charset=cs; } /* @@ -75,18 +84,18 @@ public: */ String(const char *str,uint32 len, CHARSET_INFO *cs) { - Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0; + Ptr=(char*) str; str_length=len; Alloced_length= extra_alloc=0; alloced=0; str_charset=cs; } String(char *str,uint32 len, CHARSET_INFO *cs) { - Ptr=(char*) str; Alloced_length=str_length=len; alloced=0; + Ptr=(char*) str; Alloced_length=str_length=len; extra_alloc= 0; alloced=0; str_charset=cs; } String(const String &str) { Ptr=str.Ptr ; str_length=str.str_length ; - Alloced_length=str.Alloced_length; alloced=0; + Alloced_length=str.Alloced_length; extra_alloc= 0; alloced=0; str_charset=str.str_charset; } static void *operator new(size_t size, MEM_ROOT *mem_root) throw () @@ -106,8 +115,10 @@ public: inline CHARSET_INFO *charset() const { return str_charset; } inline uint32 length() const { return str_length;} inline uint32 alloced_length() const { return Alloced_length;} + inline uint32 extra_allocation() const { return extra_alloc;} inline char& operator [] (uint32 i) const { return Ptr[i]; } inline void length(uint32 len) { str_length=len ; } + inline void extra_allocation(uint32 len) { extra_alloc= len; } inline bool is_empty() const { return (str_length == 0); } inline void mark_as_const() { Alloced_length= 0;} inline const char *ptr() const { return Ptr; } @@ -139,11 +150,9 @@ public: { DBUG_ASSERT(&str != this); free(); - Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0; + Ptr=(char*) str.ptr()+offset; str_length=arg_length; if (str.Alloced_length) Alloced_length=str.Alloced_length-offset; - else - Alloced_length=0; str_charset=str.str_charset; } @@ -159,13 +168,13 @@ public: inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); - Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0; + Ptr=(char*) str; str_length=Alloced_length=arg_length; str_charset=cs; } inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); - Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0; + Ptr=(char*) str; str_length=arg_length; str_charset=cs; } bool set_ascii(const char *str, uint32 arg_length); @@ -216,11 +225,11 @@ public: if (alloced) { alloced=0; - Alloced_length=0; my_free(Ptr,MYF(0)); - Ptr=0; - str_length=0; /* Safety */ } + Alloced_length= extra_alloc= 0; + Ptr=0; + str_length=0; /* Safety */ } inline bool alloc(uint32 arg_length) { @@ -230,9 +239,21 @@ public: } bool real_alloc(uint32 arg_length); // Empties old string bool realloc(uint32 arg_length); - inline void shrink(uint32 arg_length) // Shrink buffer + bool realloc_with_extra(uint32 arg_length) + { + if (extra_alloc < 4096) + extra_alloc= extra_alloc*2+128; + return realloc(arg_length + extra_alloc); + } + bool realloc_with_extra_if_needed(uint32 arg_length) { if (arg_length < Alloced_length) + return 0; + return realloc_with_extra(arg_length); + } + inline void shrink(uint32 arg_length) // Shrink buffer + { + if (ALIGN_SIZE(arg_length+1) < Alloced_length) { char *new_ptr; if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0)))) @@ -259,7 +280,6 @@ public: DBUG_ASSERT(!s.uses_buffer_owned_by(this)); free(); Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length; - alloced=0; } return *this; } @@ -275,6 +295,14 @@ public: bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs); bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, CHARSET_INFO *csto, uint *errors); + void move(String &s) + { + free(); + Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length; + extra_alloc= s.extra_alloc; + alloced= s.alloced; + s.alloced= 0; + } bool append(const String &s); bool append(const char *s); bool append(const char *s,uint32 arg_length); @@ -294,7 +322,7 @@ public: } else { - if (realloc(str_length+1)) + if (realloc_with_extra(str_length + 1)) return 1; Ptr[str_length++]=chr; } @@ -305,6 +333,7 @@ public: friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); + friend class Field; uint32 numchars(); int charpos(int i,uint32 offset=0); @@ -349,6 +378,10 @@ public: int4store(Ptr + position,value); } + void qs_append(const char *str) + { + qs_append(str, (uint32)strlen(str)); + } void qs_append(const char *str, uint32 len); void qs_append(double d); void qs_append(double *d); @@ -358,7 +391,15 @@ public: str_length++; } void qs_append(int i); - void qs_append(uint i); + void qs_append(uint i) + { + qs_append((ulonglong)i); + } + void qs_append(ulong i) + { + qs_append((ulonglong)i); + } + void qs_append(ulonglong i); /* Inline (general) functions used by the protocol functions */ @@ -413,3 +454,5 @@ static inline bool check_if_only_end_space(CHARSET_INFO *cs, char *str, { return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end; } + +#endif // MYSQL_SQL_STRING_H_INCLUDED diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7328157182d..bb062615966 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -21,6 +21,7 @@ #include <hash.h> #include <myisam.h> #include <my_dir.h> +#include "create_options.h" #include "sp_head.h" #include "sql_trigger.h" #include "sql_show.h" @@ -45,17 +46,10 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, static bool prepare_blob_field(THD *thd, Create_field *sql_field); static bool check_engine(THD *, const char *, HA_CREATE_INFO *); -static int -mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, - Alter_info *alter_info, - bool tmp_table, - uint *db_options, - handler *file, KEY **key_info_buffer, - uint *key_count, int select_field_count); -static bool -mysql_prepare_alter_table(THD *thd, TABLE *table, - HA_CREATE_INFO *create_info, - Alter_info *alter_info); +static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *, + bool, uint *, handler *, KEY **, uint *, int); +static bool mysql_prepare_alter_table(THD *, TABLE *, HA_CREATE_INFO *, + Alter_info *); static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list); #ifndef DBUG_OFF @@ -2121,7 +2115,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, { if (!foreign_key_error) my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), - wrong_tables.c_ptr()); + wrong_tables.c_ptr_safe()); else my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0)); error= 1; @@ -2258,10 +2252,10 @@ static int sort_keys(KEY *a, KEY *b) { if (!(b_flags & HA_NOSAME)) return -1; - if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) + if ((a_flags ^ b_flags) & HA_NULL_PART_KEY) { /* Sort NOT NULL keys before other keys */ - return (a_flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1; + return (a_flags & HA_NULL_PART_KEY) ? 1 : -1; } if (a->name == primary_key_name) return -1; @@ -2543,7 +2537,12 @@ int prepare_create_field(Create_field *sql_field, (sql_field->decimals << FIELDFLAG_DEC_SHIFT)); break; } - if (!(sql_field->flags & NOT_NULL_FLAG)) + if (sql_field->flags & NOT_NULL_FLAG) + DBUG_PRINT("info", ("1")); + if (sql_field->vcol_info) + DBUG_PRINT("info", ("2")); + if (!(sql_field->flags & NOT_NULL_FLAG) || + (sql_field->vcol_info)) /* Make virtual columns allow NULL values */ sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL; if (sql_field->flags & NO_DEFAULT_VALUE_FLAG) sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT; @@ -2857,6 +2856,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, null_fields--; sql_field->flags= dup_field->flags; sql_field->interval= dup_field->interval; + sql_field->vcol_info= dup_field->vcol_info; + sql_field->stored_in_db= dup_field->stored_in_db; it2.remove(); // Remove first (create) definition select_field_pos--; break; @@ -2889,7 +2890,28 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->offset= record_offset; if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) auto_increment++; - record_offset+= sql_field->pack_length; + if (parse_option_list(thd, &sql_field->option_struct, + sql_field->option_list, + create_info->db_type->field_options, FALSE, + thd->mem_root)) + DBUG_RETURN(TRUE); + /* + For now skip fields that are not physically stored in the database + (virtual fields) and update their offset later + (see the next loop). + */ + if (sql_field->stored_in_db) + record_offset+= sql_field->pack_length; + } + /* Update virtual fields' offset*/ + it.rewind(); + while ((sql_field=it++)) + { + if (!sql_field->stored_in_db) + { + sql_field->offset= record_offset; + record_offset+= sql_field->pack_length; + } } if (timestamps_with_niladic > 1) { @@ -2939,6 +2961,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, if (key->type == Key::FOREIGN_KEY) { fk_key_count++; + if (((Foreign_key *)key)->validate(alter_info->create_list)) + DBUG_RETURN(TRUE); Foreign_key *fk_key= (Foreign_key*) key; if (fk_key->ref_columns.elements && fk_key->ref_columns.elements != fk_key->columns.elements) @@ -3069,6 +3093,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_info->key_part=key_part_info; key_info->usable_key_parts= key_number; key_info->algorithm= key->key_create_info.algorithm; + key_info->option_list= key->option_list; + if (parse_option_list(thd, &key_info->option_struct, + key_info->option_list, + create_info->db_type->index_options, FALSE, + thd->mem_root)) + DBUG_RETURN(TRUE); if (key->type == Key::FULLTEXT) { @@ -3234,6 +3264,17 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } } #endif + if (!sql_field->stored_in_db) + { + /* Key fields must always be physically stored. */ + my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0)); + DBUG_RETURN(TRUE); + } + if (key->type == Key::PRIMARY && sql_field->vcol_info) + { + my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0)); + DBUG_RETURN(TRUE); + } if (!(sql_field->flags & NOT_NULL_FLAG)) { if (key->type == Key::PRIMARY) @@ -3445,6 +3486,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } } + if (parse_option_list(thd, &create_info->option_struct, + create_info->option_list, + file->partition_ht()->table_options, FALSE, + thd->mem_root)) + DBUG_RETURN(TRUE); + DBUG_RETURN(FALSE); } @@ -3957,12 +4004,16 @@ bool mysql_create_table_no_lock(THD *thd, } /* Give warnings for not supported table options */ - if (create_info->transactional && !file->ht->commit) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_ILLEGAL_HA_CREATE_OPTION, - ER(ER_ILLEGAL_HA_CREATE_OPTION), - file->engine_name()->str, - "TRANSACTIONAL=1"); +#if defined(WITH_ARIA_STORAGE_ENGINE) + extern handlerton *maria_hton; + if (file->ht != maria_hton) +#endif + if (create_info->transactional) + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_ILLEGAL_HA_CREATE_OPTION, + ER(ER_ILLEGAL_HA_CREATE_OPTION), + file->engine_name()->str, + "TRANSACTIONAL=1"); VOID(pthread_mutex_lock(&LOCK_open)); if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) @@ -5789,6 +5840,7 @@ compare_tables(TABLE *table, KEY_PART_INFO *key_part; KEY_PART_INFO *end; THD *thd= table->in_use; + uint i; /* Remember if the new definition has new VARCHAR column; create_info->varchar will be reset in mysql_prepare_create_table. @@ -5879,6 +5931,12 @@ compare_tables(TABLE *table, DBUG_RETURN(0); } + if ((create_info->fields_option_struct= (ha_field_option_struct**) + thd->calloc(sizeof(void*) * table->s->fields)) == NULL || + (create_info->indexes_option_struct= (ha_index_option_struct**) + thd->calloc(sizeof(void*) * table->s->keys)) == NULL) + DBUG_RETURN(1); + /* Use transformed info to evaluate possibility of fast ALTER TABLE but use the preserved field to persist modifications. @@ -5886,15 +5944,19 @@ compare_tables(TABLE *table, new_field_it.init(alter_info->create_list); tmp_new_field_it.init(tmp_alter_info.create_list); - /* Go through fields and check if the original ones are compatible + /* + Go through fields and check if the original ones are compatible with new table. */ - for (f_ptr= table->field, new_field= new_field_it++, + for (i= 0, f_ptr= table->field, new_field= new_field_it++, tmp_new_field= tmp_new_field_it++; (field= *f_ptr); - f_ptr++, new_field= new_field_it++, + i++, f_ptr++, new_field= new_field_it++, tmp_new_field= tmp_new_field_it++) { + DBUG_ASSERT(i < table->s->fields); + create_info->fields_option_struct[i]= tmp_new_field->option_struct; + /* Make sure we have at least the default charset in use. */ if (!new_field->charset) new_field->charset= create_info->default_table_charset; @@ -5908,6 +5970,19 @@ compare_tables(TABLE *table, DBUG_RETURN(0); } + /* + Check if the altered column is computed and either + is stored or is used in the partitioning expression. + TODO: Mark such a column with an alter flag only if + the defining expression has changed. + */ + if (field->vcol_info && + (field->stored_in_db || field->vcol_info->is_in_partitioning_expr())) + { + *need_copy_table= ALTER_TABLE_DATA_CHANGED; + DBUG_RETURN(0); + } + /* Don't pack rows in old tables if the user has requested this. */ if (create_info->row_type == ROW_TYPE_DYNAMIC || (tmp_new_field->flags & BLOB_FLAG) || @@ -6035,7 +6110,9 @@ compare_tables(TABLE *table, for (new_key= *key_info_buffer; new_key < new_key_end; new_key++) { /* Search an old key with the same name. */ - for (table_key= table->key_info; table_key < table_key_end; table_key++) + for (i= 0, table_key= table->key_info; + table_key < table_key_end; + i++, table_key++) { if (! strcmp(table_key->name, new_key->name)) break; @@ -6054,6 +6131,11 @@ compare_tables(TABLE *table, } DBUG_PRINT("info", ("index added: '%s'", new_key->name)); } + else + { + DBUG_ASSERT(i < table->s->keys); + create_info->indexes_option_struct[i]= new_key->option_struct; + } } /* Check if changes are compatible with current handler without a copy */ @@ -6229,6 +6311,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } restore_record(table, s->default_values); // Empty record for DEFAULT + create_info->option_list= merge_engine_table_options(table->s->option_list, + create_info->option_list, thd->mem_root); /* First collect all fields from table which isn't in drop_list */ @@ -6276,6 +6360,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (def) { // Field is changed def->field=field; + if (field->stored_in_db != def->stored_in_db) + { + my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN, MYF(0)); + goto err; + } if (!def->after) { new_create_list.push_back(def); @@ -6491,7 +6580,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, key= new Key(key_type, key_name, &key_create_info, test(key_info->flags & HA_GENERATED_KEY), - key_parts); + key_parts, key_info->option_list); new_key_list.push_back(key); } } @@ -6499,6 +6588,9 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Key *key; while ((key=key_it++)) // Add new keys { + if (key->type == Key::FOREIGN_KEY && + ((Foreign_key *)key)->validate(new_create_list)) + goto err; if (key->type != Key::FOREIGN_KEY) new_key_list.push_back(key); if (key->name && @@ -6959,7 +7051,7 @@ view_err: error= 0; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->alias); + table->alias.c_ptr()); } /* @@ -7023,7 +7115,7 @@ view_err: error= 0; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->alias); + table->alias.c_ptr()); } if (!error) @@ -7723,27 +7815,6 @@ view_err: if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) DBUG_RETURN(TRUE); - if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME)) - { - /* - For the alter table to be properly flushed to the logs, we - have to open the new table. If not, we get a problem on server - shutdown. But we do not need to attach MERGE children. - */ - char path[FN_REFLEN]; - TABLE *t_table; - build_table_filename(path + 1, sizeof(path) - 1, new_db, table_name, "", 0); - t_table= open_temporary_table(thd, path, new_db, tmp_name, 0); - if (t_table) - { - intern_close_table(t_table); - my_free(t_table, MYF(0)); - } - else - sql_print_warning("Could not open table %s.%s after rename\n", - new_db,table_name); - ha_flush_logs(old_db_type); - } table_list->table=0; // For query cache query_cache_invalidate3(thd, table_list, 0); @@ -7952,7 +8023,9 @@ copy_data_between_tables(TABLE *from,TABLE *to, /* Tell handler that we have values for all columns in the to table */ to->use_all_columns(); - init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE); + to->mark_virtual_columns_for_write(TRUE); + if (init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE)) + goto err; errpos= 4; if (ignore) to->file->extra(HA_EXTRA_IGNORE_DUP_KEY); @@ -7966,6 +8039,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, error= 1; break; } + update_virtual_fields(thd, from); thd->row_count++; /* Return error if source table isn't empty. */ if (error_if_not_empty) @@ -7986,6 +8060,12 @@ copy_data_between_tables(TABLE *from,TABLE *to, copy_ptr->do_copy(copy_ptr); } prev_insert_id= to->file->next_insert_id; + update_virtual_fields(thd, to, TRUE); + if (thd->is_error()) + { + error= 1; + break; + } error=to->file->ha_write_row(to->record[0]); to->auto_increment_field_not_null= FALSE; if (error) @@ -8191,7 +8271,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, goto err; } ha_checksum row_crc= 0; - int error= t->file->rnd_next(t->record[0]); + int error= t->file->ha_rnd_next(t->record[0]); if (unlikely(error)) { if (error == HA_ERR_RECORD_DELETED) diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 887f746251b..04adf6dcadc 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -60,14 +60,15 @@ print_where(COND *cond,const char *info, enum_query_type query_type) { if (cond) { - char buff[256]; + char buff[1024]; String str(buff,(uint32) sizeof(buff), system_charset_info); str.length(0); + str.extra_allocation(1024); cond->print(&str, query_type); str.append('\0'); DBUG_LOCK_FILE; (void) fprintf(DBUG_FILE,"\nWHERE:(%s) ",info); - (void) fputs(str.ptr(),DBUG_FILE); + (void) fputs(str.c_ptr_safe(),DBUG_FILE); (void) fputc('\n',DBUG_FILE); DBUG_UNLOCK_FILE; } @@ -159,7 +160,7 @@ void TEST_filesort(SORT_FIELD *sortorder,uint s_length) out.append('\0'); // Purify doesn't like c_ptr() DBUG_LOCK_FILE; VOID(fputs("\nInfo about FILESORT\n",DBUG_FILE)); - fprintf(DBUG_FILE,"Sortorder: %s\n",out.ptr()); + fprintf(DBUG_FILE,"Sortorder: %s\n",out.c_ptr_safe()); DBUG_UNLOCK_FILE; DBUG_VOID_RETURN; } @@ -194,7 +195,7 @@ TEST_join(JOIN *join) TABLE *form=tab->table; char key_map_buff[128]; fprintf(DBUG_FILE,"%-16.16s type: %-7s q_keys: %s refs: %d key: %d len: %d\n", - form->alias, + form->alias.c_ptr(), join_type_str[tab->type], tab->keys.print(key_map_buff), tab->ref.key_parts, @@ -218,7 +219,7 @@ TEST_join(JOIN *join) if (tab->ref.key_parts) { fprintf(DBUG_FILE, - " refs: %s\n", ref_key_parts[i].ptr()); + " refs: %s\n", ref_key_parts[i].c_ptr_safe()); } } DBUG_UNLOCK_FILE; @@ -444,11 +445,15 @@ static int print_key_cache_status(const char *name, KEY_CACHE *key_cache) } else { + KEY_CACHE_STATISTICS stats; + get_key_cache_statistics(key_cache, 0, &stats); + printf("%s\n\ Buffer_size: %10lu\n\ Block_size: %10lu\n\ Division_limit: %10lu\n\ -Age_limit: %10lu\n\ +Age_threshold: %10lu\n\ +Partitions: %10lu\n\ blocks used: %10lu\n\ not flushed: %10lu\n\ w_requests: %10s\n\ @@ -458,11 +463,13 @@ reads: %10s\n\n", name, (ulong) key_cache->param_buff_size, key_cache->param_block_size, key_cache->param_division_limit, key_cache->param_age_threshold, - key_cache->blocks_used,key_cache->global_blocks_changed, - llstr(key_cache->global_cache_w_requests,llbuff1), - llstr(key_cache->global_cache_write,llbuff2), - llstr(key_cache->global_cache_r_requests,llbuff3), - llstr(key_cache->global_cache_read,llbuff4)); + key_cache->param_partitions, + (ulong)stats.blocks_used, + (ulong)stats.blocks_changed, + llstr(stats.write_requests,llbuff1), + llstr(stats.writes,llbuff2), + llstr(stats.read_requests,llbuff3), + llstr(stats.reads,llbuff4)); } return 0; } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 3de7aded51e..fb9abc06f6b 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -853,7 +853,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, stmt_query->append(stmt_definition.str, stmt_definition.length); - trg_def->str= stmt_query->c_ptr(); + trg_def->str= stmt_query->c_ptr_safe(); trg_def->length= stmt_query->length(); /* Create trigger definition file. */ @@ -1090,10 +1090,7 @@ void Table_triggers_list::set_table(TABLE *new_table) { trigger_table= new_table; for (Field **field= new_table->triggers->record1_field ; *field ; field++) - { - (*field)->table= (*field)->orig_table= new_table; - (*field)->table_name= &new_table->alias; - } + (*field)->init(new_table); } diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 063321f9902..2906e69fc75 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -154,7 +154,13 @@ void udf_init() } table= tables.table; - init_read_record(&read_record_info, new_thd, table, NULL,1,0,FALSE); + if (init_read_record(&read_record_info, new_thd, table, NULL,1,0,FALSE)) + { + sql_print_error("Could not initialize init_read_record; udf's not " + "loaded"); + goto end; + } + table->use_all_columns(); while (!(error= read_record_info.read_record(&read_record_info))) { @@ -571,10 +577,10 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) goto err; table->use_all_columns(); table->field[0]->store(exact_name_str, exact_name_len, &my_charset_bin); - if (!table->file->index_read_idx_map(table->record[0], 0, - (uchar*) table->field[0]->ptr, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT)) + if (!table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar*) table->field[0]->ptr, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)) { int error; if ((error = table->file->ha_delete_row(table->record[0]))) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 8041de66ade..70572b406e5 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -160,7 +160,7 @@ static void prepare_record_for_error_message(int error, TABLE *table) /* Tell the engine about the new set. */ table->file->column_bitmaps_signal(); /* Read record that is identified by table->file->ref. */ - (void) table->file->rnd_pos(table->record[1], table->file->ref); + (void) table->file->ha_rnd_pos(table->record[1], table->file->ref); /* Copy the newly read columns into the new record. */ for (field_p= table->field; (field= *field_p); field_p++) if (bitmap_is_set(&unique_map, field->field_index)) @@ -477,7 +477,10 @@ int mysql_update(THD *thd, */ if (used_index == MAX_KEY || (select && select->quick)) - init_read_record(&info, thd, table, select, 0, 1, FALSE); + { + if (init_read_record(&info, thd, table, select, 0, 1, FALSE)) + goto err; + } else init_read_record_idx(&info, thd, table, 1, used_index); @@ -486,6 +489,7 @@ int mysql_update(THD *thd, while (!(error=info.read_record(&info)) && !thd->killed) { + update_virtual_fields(thd, table); thd->examined_row_count++; if (!select || (error= select->skip_record(thd)) > 0) { @@ -552,7 +556,8 @@ int mysql_update(THD *thd, if (select && select->quick && select->quick->reset()) goto err; table->file->try_semi_consistent_read(1); - init_read_record(&info, thd, table, select, 0, 1, FALSE); + if (init_read_record(&info, thd, table, select, 0, 1, FALSE)) + goto err; updated= found= 0; /* @@ -599,6 +604,7 @@ int mysql_update(THD *thd, while (!(error=info.read_record(&info)) && !thd->killed) { + update_virtual_fields(thd, table); thd->examined_row_count++; if (!select || select->skip_record(thd) > 0) { @@ -1611,7 +1617,8 @@ loop_end: do { Field_string *field= new Field_string(tbl->file->ref_length, 0, - tbl->alias, &my_charset_bin); + tbl->alias.c_ptr(), + &my_charset_bin); if (!field) DBUG_RETURN(1); field->init(tbl); @@ -1908,7 +1915,7 @@ int multi_update::do_updates() TABLE_LIST *cur_table; int local_error= 0; ha_rows org_updated; - TABLE *table, *tmp_table; + TABLE *table, *tmp_table, *err_table; List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables); DBUG_ENTER("multi_update::do_updates"); @@ -1926,14 +1933,21 @@ int multi_update::do_updates() org_updated= updated; tmp_table= tmp_tables[cur_table->shared]; tmp_table->file->extra(HA_EXTRA_CACHE); // Change to read cache - (void) table->file->ha_rnd_init(0); + if ((local_error= table->file->ha_rnd_init(0))) + { + err_table= table; + goto err; + } table->file->extra(HA_EXTRA_NO_CACHE); check_opt_it.rewind(); while(TABLE *tbl= check_opt_it++) { - if (tbl->file->ha_rnd_init(1)) + if ((local_error= tbl->file->ha_rnd_init(1))) + { + err_table= tbl; goto err; + } tbl->file->extra(HA_EXTRA_CACHE); } @@ -1953,21 +1967,28 @@ int multi_update::do_updates() } copy_field_end=copy_field_ptr; - if ((local_error = tmp_table->file->ha_rnd_init(1))) + if ((local_error= tmp_table->file->ha_rnd_init(1))) + { + err_table= tmp_table; goto err; + } can_compare_record= records_are_comparable(table); for (;;) { if (thd->killed && trans_safe) - goto err; - if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0]))) + { + thd->fatal_error(); + goto err2; + } + if ((local_error= tmp_table->file->ha_rnd_next(tmp_table->record[0]))) { if (local_error == HA_ERR_END_OF_FILE) break; if (local_error == HA_ERR_RECORD_DELETED) continue; // May happen on dup key + err_table= tmp_table; goto err; } @@ -1977,12 +1998,15 @@ int multi_update::do_updates() uint field_num= 0; do { - if((local_error= - tbl->file->rnd_pos(tbl->record[0], - (uchar *) tmp_table->field[field_num]->ptr))) + if ((local_error= + tbl->file->ha_rnd_pos(tbl->record[0], + (uchar*) tmp_table->field[field_num]->ptr))) + { + err_table= tbl; goto err; + } field_num++; - } while((tbl= check_opt_it++)); + } while ((tbl= check_opt_it++)); table->status|= STATUS_UPDATED; store_record(table,record[1]); @@ -2007,7 +2031,10 @@ int multi_update::do_updates() if (error == VIEW_CHECK_SKIP) continue; else if (error == VIEW_CHECK_ERROR) - goto err; + { + thd->fatal_error(); + goto err2; + } } if ((local_error=table->file->ha_update_row(table->record[1], table->record[0])) && @@ -2015,7 +2042,10 @@ int multi_update::do_updates() { if (!ignore || table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY)) + { + err_table= table; goto err; + } } if (local_error != HA_ERR_RECORD_IS_THE_SAME) updated++; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index df9df89f972..2fc6918e49f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -18,8 +18,8 @@ #include "mysql_priv.h" #include "sql_select.h" #include "parse_file.h" -#include "sp.h" #include "sp_head.h" +#include "sp.h" #include "sp_cache.h" #define MD5_BUFF_LENGTH 33 @@ -848,7 +848,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, thd->variables.sql_mode|= sql_mode; } - DBUG_PRINT("info", ("View: %s", view_query.ptr())); + DBUG_PRINT("info", ("View: %s", view_query.c_ptr_safe())); /* fill structure */ view->source= thd->lex->create_view_select; @@ -1215,7 +1215,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, + MODE_PIPES_AS_CONCAT affect expression parsing + MODE_ANSI_QUOTES affect expression parsing + MODE_IGNORE_SPACE affect expression parsing - - MODE_NOT_USED not used :) + - MODE_IGNORE_BAD_TABLE_OPTIONS affect only CREATE/ALTER TABLE parsing * MODE_ONLY_FULL_GROUP_BY affect execution * MODE_NO_UNSIGNED_SUBTRACTION affect execution - MODE_NO_DIR_IN_CREATE affect table creation only @@ -1720,7 +1720,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) } if (non_existant_views.length()) { - my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr()); + my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr_safe()); } something_wrong= error || wrong_object_name || non_existant_views.length(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 29fc39f9cc6..5f94bcd8bf3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -46,6 +46,7 @@ #include "sp_rcontext.h" #include "sp.h" #include "event_parse_data.h" +#include "create_options.h" #include <myisam.h> #include <myisammrg.h> @@ -58,6 +59,7 @@ int yylex(void *yylval, void *yythd); const LEX_STRING null_lex_str= {0,0}; +const LEX_STRING empty_lex_str= { (char*) "", 0 }; #define yyoverflow(A,B,C,D,E,F) \ { \ @@ -608,6 +610,7 @@ static bool add_create_index_prepare (LEX *lex, Table_ident *table) lex->alter_info.flags= ALTER_ADD_INDEX; lex->col_list.empty(); lex->change= NullS; + lex->option_list= NULL; return FALSE; } @@ -617,7 +620,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type, const char *name, { Key *key; key= new Key(type, name, info ? info : &lex->key_create_info, generated, - lex->col_list); + lex->col_list, lex->option_list); if (key == NULL) return TRUE; @@ -711,6 +714,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token ALGORITHM_SYM %token ALL /* SQL-2003-R */ %token ALTER /* SQL-2003-R */ +%token ALWAYS_SYM %token ANALYZE_SYM %token AND_AND_SYM /* OPERATOR */ %token AND_SYM /* SQL-2003-R */ @@ -760,6 +764,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CHECK_SYM /* SQL-2003-R */ %token CIPHER_SYM %token CLIENT_SYM +%token CLIENT_STATS_SYM %token CLOSE_SYM /* SQL-2003-R */ %token COALESCE /* SQL-2003-N */ %token CODE_SYM @@ -877,6 +882,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token FULLTEXT_SYM %token FUNCTION_SYM /* SQL-2003-R */ %token GE +%token GENERATED_SYM %token GEOMETRYCOLLECTION %token GEOMETRY_SYM %token GET_FORMAT /* MYSQL-FUNC */ @@ -906,6 +912,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token IMPORT %token INDEXES %token INDEX_SYM +%token INDEX_STATS_SYM %token INFILE %token INITIAL_SIZE_SYM %token INNER_SYM /* SQL-2003-R */ @@ -1054,11 +1061,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token PAGE_CHECKSUM_SYM %token PARAM_MARKER %token PARSER_SYM +%token PARSE_VCOL_EXPR_SYM %token PARTIAL /* SQL-2003-N */ %token PARTITIONING_SYM %token PARTITIONS_SYM %token PARTITION_SYM /* SQL-2003-R */ %token PASSWORD +%token PERSISTENT_SYM %token PHASE_SYM %token PLUGINS_SYM %token PLUGIN_SYM @@ -1147,6 +1156,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SIGNED_SYM %token SIMPLE_SYM /* SQL-2003-N */ %token SLAVE +%token SLOW_SYM %token SMALLINT /* SQL-2003-R */ %token SNAPSHOT_SYM %token SOCKET_SYM @@ -1191,6 +1201,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token TABLES %token TABLESPACE %token TABLE_REF_PRIORITY +%token TABLE_STATS_SYM %token TABLE_SYM /* SQL-2003-R */ %token TABLE_CHECKSUM_SYM %token TEMPORARY /* SQL-2003-N */ @@ -1238,6 +1249,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token UPGRADE_SYM %token USAGE /* SQL-2003-N */ %token USER /* SQL-2003-R */ +%token USER_STATS_SYM %token USE_FRM %token USE_SYM %token USING /* SQL-2003-R */ @@ -1252,7 +1264,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token VARIANCE_SYM %token VARYING /* SQL-2003-R */ %token VAR_SAMP_SYM +%token VIA_SYM %token VIEW_SYM /* SQL-2003-N */ +%token VIRTUAL_SYM %token WAIT_SYM %token WARNINGS %token WEEK_SYM @@ -1314,7 +1328,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); text_string opt_gconcat_separator %type <num> - type int_type real_type order_dir lock_option + type int_type real_type order_dir lock_option field_def udf_type if_exists opt_local opt_table_options table_options table_option opt_if_not_exists opt_no_write_to_binlog delete_option opt_temporary all_or_any opt_distinct @@ -1474,6 +1488,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); key_using_alg server_def server_options_list server_option definer_opt no_definer definer + parse_vcol_expr vcol_opt_specifier vcol_opt_attribute + vcol_opt_attribute_list vcol_attribute END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt @@ -1606,6 +1622,7 @@ statement: | load | lock | optimize + | parse_vcol_expr | partition_entry | preload | prepare @@ -2336,6 +2353,7 @@ sp_init_param: lex->interval_list.empty(); lex->uint_geom_type= 0; + lex->vcol_info= 0; } ; @@ -3891,7 +3909,11 @@ create2: ; create2a: - field_list ')' opt_create_table_options + field_list ')' + { + Lex->create_info.option_list= NULL; + } + opt_create_table_options opt_partitioning create3 {} | opt_partitioning @@ -4770,6 +4792,30 @@ create_table_option: Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL; Lex->create_info.transactional= $3; } + | IDENT_sys equal TEXT_STRING_sys + { + new (YYTHD->mem_root) + engine_option_value($1, $3, true, &Lex->create_info.option_list, + &Lex->option_list_last); + } + | IDENT_sys equal ident + { + new (YYTHD->mem_root) + engine_option_value($1, $3, false, &Lex->create_info.option_list, + &Lex->option_list_last); + } + | IDENT_sys equal real_ulonglong_num + { + new (YYTHD->mem_root) + engine_option_value($1, $3, &Lex->create_info.option_list, + &Lex->option_list_last, YYTHD->mem_root); + } + | IDENT_sys equal DEFAULT + { + new (YYTHD->mem_root) + engine_option_value($1, &Lex->create_info.option_list, + &Lex->option_list_last); + } ; default_charset: @@ -4891,25 +4937,33 @@ column_def: ; key_def: - normal_key_type opt_ident key_alg '(' key_list ')' normal_key_options + normal_key_type opt_ident key_alg '(' key_list ')' + { Lex->option_list= NULL; } + normal_key_options { if (add_create_index (Lex, $1, $2)) MYSQL_YYABORT; } | fulltext opt_key_or_index opt_ident init_key_options - '(' key_list ')' fulltext_key_options + '(' key_list ')' + { Lex->option_list= NULL; } + fulltext_key_options { if (add_create_index (Lex, $1, $3)) MYSQL_YYABORT; } | spatial opt_key_or_index opt_ident init_key_options - '(' key_list ')' spatial_key_options + '(' key_list ')' + { Lex->option_list= NULL; } + spatial_key_options { if (add_create_index (Lex, $1, $3)) MYSQL_YYABORT; } | opt_constraint constraint_key_type opt_ident key_alg - '(' key_list ')' normal_key_options + '(' key_list ')' + { Lex->option_list= NULL; } + normal_key_options { if (add_create_index (Lex, $2, $3 ? $3 : $1)) MYSQL_YYABORT; @@ -4928,6 +4982,7 @@ key_def: if (key == NULL) MYSQL_YYABORT; lex->alter_info.key_list.push_back(key); + lex->option_list= NULL; if (add_create_index (lex, Key::MULTIPLE, key_name, &default_key_create_info, 1)) MYSQL_YYABORT; @@ -4971,8 +5026,10 @@ field_spec: lex->default_value= lex->on_update_value= 0; lex->comment=null_lex_str; lex->charset=NULL; + lex->vcol_info= 0; + lex->option_list= NULL; } - type opt_attribute + field_def { LEX *lex=Lex; if (add_field_to_list(lex->thd, &$1, (enum enum_field_types) $3, @@ -4980,8 +5037,98 @@ field_spec: lex->default_value, lex->on_update_value, &lex->comment, lex->change,&lex->interval_list,lex->charset, - lex->uint_geom_type)) + lex->uint_geom_type, + lex->vcol_info, lex->option_list)) + MYSQL_YYABORT; + } + ; + +field_def: + type opt_attribute {} + | type opt_generated_always AS '(' virtual_column_func ')' + vcol_opt_specifier + vcol_opt_attribute + { + $$= (enum enum_field_types)MYSQL_TYPE_VIRTUAL; + Lex->vcol_info->set_field_type((enum enum_field_types) $1); + } + ; + +opt_generated_always: + /* empty */ + | GENERATED_SYM ALWAYS_SYM {} + ; + +vcol_opt_specifier: + /* empty */ + { + Lex->vcol_info->set_stored_in_db_flag(FALSE); + } + | VIRTUAL_SYM + { + Lex->vcol_info->set_stored_in_db_flag(FALSE); + } + | PERSISTENT_SYM + { + Lex->vcol_info->set_stored_in_db_flag(TRUE); + } + ; + +vcol_opt_attribute: + /* empty */ {} + | vcol_opt_attribute_list {} + ; + +vcol_opt_attribute_list: + vcol_opt_attribute_list vcol_attribute {} + | vcol_attribute + ; + +vcol_attribute: + UNIQUE_SYM + { + LEX *lex=Lex; + lex->type|= UNIQUE_FLAG; + lex->alter_info.flags|= ALTER_ADD_INDEX; + } + | UNIQUE_SYM KEY_SYM + { + LEX *lex=Lex; + lex->type|= UNIQUE_KEY_FLAG; + lex->alter_info.flags|= ALTER_ADD_INDEX; + } + | COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; } + ; + +parse_vcol_expr: + PARSE_VCOL_EXPR_SYM '(' virtual_column_func ')' + { + /* + "PARSE_VCOL_EXPR" can only be used by the SQL server + when reading a '*.frm' file. + Prevent the end user from invoking this command. + */ + if (!Lex->parse_vcol_expr) + { + my_message(ER_SYNTAX_ERROR, ER(ER_SYNTAX_ERROR), MYF(0)); MYSQL_YYABORT; + } + } + ; + +virtual_column_func: + remember_name expr remember_end + { + Lex->vcol_info= new Virtual_column_info(); + if (!Lex->vcol_info) + { + mem_alloc_error(sizeof(Virtual_column_info)); + MYSQL_YYABORT; + } + uint expr_len= (uint)($3 - $1) - 1; + Lex->vcol_info->expr_str.str= (char* ) sql_memdup($1 + 1, expr_len); + Lex->vcol_info->expr_str.length= expr_len; + Lex->vcol_info->expr_item= $2; } ; @@ -5311,6 +5458,29 @@ attribute: Lex->charset=$2; } } + | IDENT_sys equal TEXT_STRING_sys + { + new (YYTHD->mem_root) + engine_option_value($1, $3, true, &Lex->option_list, + &Lex->option_list_last); + } + | IDENT_sys equal ident + { + new (YYTHD->mem_root) + engine_option_value($1, $3, false, &Lex->option_list, + &Lex->option_list_last); + } + | IDENT_sys equal real_ulonglong_num + { + new (YYTHD->mem_root) + engine_option_value($1, $3, &Lex->option_list, + &Lex->option_list_last, YYTHD->mem_root); + } + | IDENT_sys equal DEFAULT + { + new (YYTHD->mem_root) + engine_option_value($1, &Lex->option_list, &Lex->option_list_last); + } ; now_or_signed_literal: @@ -5600,6 +5770,29 @@ key_using_alg: all_key_opt: KEY_BLOCK_SIZE opt_equal ulong_num { Lex->key_create_info.block_size= $3; } + | IDENT_sys equal TEXT_STRING_sys + { + new (YYTHD->mem_root) + engine_option_value($1, $3, true, &Lex->option_list, + &Lex->option_list_last); + } + | IDENT_sys equal ident + { + new (YYTHD->mem_root) + engine_option_value($1, $3, false, &Lex->option_list, + &Lex->option_list_last); + } + | IDENT_sys equal real_ulonglong_num + { + new (YYTHD->mem_root) + engine_option_value($1, $3, &Lex->option_list, + &Lex->option_list_last, YYTHD->mem_root); + } + | IDENT_sys equal DEFAULT + { + new (YYTHD->mem_root) + engine_option_value($1, &Lex->option_list, &Lex->option_list_last); + } ; normal_key_opt: @@ -6088,6 +6281,7 @@ alter_list_item: LEX *lex=Lex; lex->change= $3.str; lex->alter_info.flags|= ALTER_CHANGE_COLUMN; + lex->option_list= NULL; } field_spec opt_place | MODIFY_SYM opt_column field_ident @@ -6098,8 +6292,10 @@ alter_list_item: lex->comment=null_lex_str; lex->charset= NULL; lex->alter_info.flags|= ALTER_CHANGE_COLUMN; + lex->vcol_info= 0; + lex->option_list= NULL; } - type opt_attribute + field_def { LEX *lex=Lex; if (add_field_to_list(lex->thd,&$3, @@ -6108,7 +6304,8 @@ alter_list_item: lex->default_value, lex->on_update_value, &lex->comment, $3.str, &lex->interval_list, lex->charset, - lex->uint_geom_type)) + lex->uint_geom_type, + lex->vcol_info, lex->option_list)) MYSQL_YYABORT; } opt_place @@ -6215,8 +6412,7 @@ alter_list_item: } | create_table_options_space_separated { - LEX *lex=Lex; - lex->alter_info.flags|= ALTER_OPTIONS; + Lex->alter_info.flags|= ALTER_OPTIONS; } | FORCE_SYM { @@ -6599,8 +6795,6 @@ cache_keys_spec: { Lex->select_lex.alloc_index_hints(YYTHD); Select->set_index_hint_type(INDEX_HINT_USE, - global_system_variables.old_mode ? - INDEX_HINT_MASK_JOIN : INDEX_HINT_MASK_ALL); } cache_key_list_or_empty @@ -9325,6 +9519,7 @@ ulonglong_num: real_ulonglong_num: NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + | HEX_NUM { $$= strtoull($1.str, (char**) 0, 16); } | LONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } | dec_num_error { MYSQL_YYABORT; } ; @@ -10387,6 +10582,34 @@ show_param: { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; } + | CLIENT_STATS_SYM + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_CLIENT_STATS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS)) + MYSQL_YYABORT; + } + | USER_STATS_SYM + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_USER_STATS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS)) + MYSQL_YYABORT; + } + | TABLE_STATS_SYM + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_TABLE_STATS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS)) + MYSQL_YYABORT; + } + | INDEX_STATS_SYM + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_INDEX_STATS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS)) + MYSQL_YYABORT; + } | CREATE PROCEDURE sp_name { LEX *lex= Lex; @@ -10595,6 +10818,16 @@ flush_option: { Lex->type|= REFRESH_STATUS; } | SLAVE { Lex->type|= REFRESH_SLAVE; } + | SLOW_SYM QUERY_SYM LOGS_SYM + { Lex->type |= REFRESH_SLOW_QUERY_LOG; } + | CLIENT_STATS_SYM + { Lex->type|= REFRESH_CLIENT_STATS; } + | USER_STATS_SYM + { Lex->type|= REFRESH_USER_STATS; } + | TABLE_STATS_SYM + { Lex->type|= REFRESH_TABLE_STATS; } + | INDEX_STATS_SYM + { Lex->type|= REFRESH_INDEX_STATS; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | DES_KEY_FILE @@ -11592,6 +11825,9 @@ user: $$->user = $1; $$->host.str= (char *) "%"; $$->host.length= 1; + $$->password= null_lex_str; + $$->plugin= empty_lex_str; + $$->auth= empty_lex_str; if (check_string_char_length(&$$->user, ER(ER_USERNAME), USERNAME_CHAR_LENGTH, @@ -11604,6 +11840,9 @@ user: if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) MYSQL_YYABORT; $$->user = $1; $$->host=$3; + $$->password= null_lex_str; + $$->plugin= empty_lex_str; + $$->auth= empty_lex_str; if (check_string_char_length(&$$->user, ER(ER_USERNAME), USERNAME_CHAR_LENGTH, @@ -11697,6 +11936,7 @@ keyword_sp: | AGAINST {} | AGGREGATE_SYM {} | ALGORITHM_SYM {} + | ALWAYS_SYM {} | ANY_SYM {} | AT_SYM {} | AUTHORS_SYM {} @@ -11714,6 +11954,7 @@ keyword_sp: | CHAIN_SYM {} | CHANGED {} | CIPHER_SYM {} + | CLIENT_STATS_SYM {} | CLIENT_SYM {} | COALESCE {} | CODE_SYM {} @@ -11766,6 +12007,7 @@ keyword_sp: | FIRST_SYM {} | FIXED_SYM {} | FRAC_SECOND_SYM {} + | GENERATED_SYM {} | GEOMETRY_SYM {} | GEOMETRYCOLLECTION {} | GET_FORMAT {} @@ -11775,6 +12017,7 @@ keyword_sp: | HOSTS_SYM {} | HOUR_SYM {} | IDENTIFIED_SYM {} + | INDEX_STATS_SYM {} | INVOKER_SYM {} | IMPORT {} | INDEXES {} @@ -11853,6 +12096,7 @@ keyword_sp: | PARTITIONING_SYM {} | PARTITIONS_SYM {} | PASSWORD {} + | PERSISTENT_SYM {} | PHASE_SYM {} | PLUGIN_SYM {} | PLUGINS_SYM {} @@ -11898,6 +12142,7 @@ keyword_sp: | SIMPLE_SYM {} | SHARE_SYM {} | SHUTDOWN {} + | SLOW_SYM {} | SNAPSHOT_SYM {} | SOUNDS_SYM {} | SOURCE_SYM {} @@ -11917,6 +12162,7 @@ keyword_sp: | SUSPEND_SYM {} | SWAPS_SYM {} | SWITCHES_SYM {} + | TABLE_STATS_SYM {} | TABLES {} | TABLE_CHECKSUM_SYM {} | TABLESPACE {} @@ -11942,9 +12188,11 @@ keyword_sp: | UNKNOWN_SYM {} | UNTIL_SYM {} | USER {} + | USER_STATS_SYM {} | USE_FRM {} | VARIABLES {} | VIEW_SYM {} + | VIRTUAL_SYM {} | VALUE_SYM {} | WARNINGS {} | WAIT_SYM {} @@ -12857,6 +13105,18 @@ grant_user: } | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING { $$= $1; $1->password= $5; } + | user IDENTIFIED_SYM VIA_SYM ident_or_text + { + $$= $1; + $1->plugin= $4; + $1->auth= empty_lex_str; + } + | user IDENTIFIED_SYM VIA_SYM ident_or_text USING TEXT_STRING_sys + { + $$= $1; + $1->plugin= $4; + $1->auth= $6; + } | user { $$= $1; $1->password= null_lex_str; } ; @@ -12887,7 +13147,7 @@ column_list_id: while ((point=iter++)) { if (!my_strcasecmp(system_charset_info, - point->column.ptr(), new_str->ptr())) + point->column.c_ptr(), new_str->c_ptr())) break; } lex->grant_tot_col|= lex->which_columns; @@ -13545,6 +13805,7 @@ sf_tail: lex->length= lex->dec= NULL; lex->interval_list.empty(); lex->type= 0; + lex->vcol_info= 0; } type /* $11 */ { /* $12 */ diff --git a/sql/structs.h b/sql/structs.h index f3642852c4a..ee6a2ffdcfd 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -71,6 +71,8 @@ typedef struct st_key_part_info { /* Info about a key part */ uint8 null_bit; /* Position to null_bit */ } KEY_PART_INFO ; +class engine_option_value; +struct ha_index_option_struct; typedef struct st_key { uint key_length; /* Tot length of key */ @@ -79,6 +81,7 @@ typedef struct st_key { uint extra_length; uint usable_key_parts; /* Should normally be = key_parts */ uint block_size; + uint name_length; enum ha_key_alg algorithm; /* Note that parser is used when the table is opened for use, and @@ -91,6 +94,8 @@ typedef struct st_key { }; KEY_PART_INFO *key_part; char *name; /* Name of key */ + /* Unique name for cache; db + \0 + table_name + \0 + key_name + \0 */ + uchar *cache_name; /* Array of AVG(#records with the same field value) for 1st ... Nth key part. 0 means 'not known'. @@ -101,6 +106,9 @@ typedef struct st_key { int bdb_return_if_eq; } handler; struct st_table *table; + /** reference to the list of options or NULL */ + engine_option_value *option_list; + ha_index_option_struct *option_struct; /* structure with parsed options */ } KEY; @@ -178,7 +186,7 @@ extern const char *show_comp_option_name[]; typedef int *(*update_var)(THD *, struct st_mysql_show_var *); typedef struct st_lex_user { - LEX_STRING user, host, password; + LEX_STRING user, host, password, plugin, auth; } LEX_USER; /* @@ -240,6 +248,111 @@ typedef struct user_conn { USER_RESOURCES user_resources; } USER_CONN; +typedef struct st_user_stats +{ + char user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1]; + // Account name the user is mapped to when this is a user from mapped_user. + // Otherwise, the same value as user. + char priv_user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1]; + uint user_name_length; + uint total_connections; + uint concurrent_connections; + time_t connected_time; // in seconds + double busy_time; // in seconds + double cpu_time; // in seconds + ulonglong bytes_received; + ulonglong bytes_sent; + ulonglong binlog_bytes_written; + ha_rows rows_read, rows_sent; + ha_rows rows_updated, rows_deleted, rows_inserted; + ulonglong select_commands, update_commands, other_commands; + ulonglong commit_trans, rollback_trans; + ulonglong denied_connections, lost_connections; + ulonglong access_denied_errors; + ulonglong empty_queries; +} USER_STATS; + +/* Lookup function for hash tables with USER_STATS entries */ +extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length, + my_bool not_used __attribute__((unused))); + +/* Free all memory for a hash table with USER_STATS entries */ +extern void free_user_stats(USER_STATS* user_stats); + +/* Intialize an instance of USER_STATS */ +extern void +init_user_stats(USER_STATS *user_stats, + const char *user, + size_t user_length, + const char *priv_user, + uint total_connections, + uint concurrent_connections, + time_t connected_time, + double busy_time, + double cpu_time, + ulonglong bytes_received, + ulonglong bytes_sent, + ulonglong binlog_bytes_written, + ha_rows rows_sent, + ha_rows rows_read, + ha_rows rows_inserted, + ha_rows rows_deleted, + ha_rows rows_updated, + ulonglong select_commands, + ulonglong update_commands, + ulonglong other_commands, + ulonglong commit_trans, + ulonglong rollback_trans, + ulonglong denied_connections, + ulonglong lost_connections, + ulonglong access_denied_errors, + ulonglong empty_queries); + +/* Increment values of an instance of USER_STATS */ +extern void +add_user_stats(USER_STATS *user_stats, + uint total_connections, + uint concurrent_connections, + time_t connected_time, + double busy_time, + double cpu_time, + ulonglong bytes_received, + ulonglong bytes_sent, + ulonglong binlog_bytes_written, + ha_rows rows_sent, + ha_rows rows_read, + ha_rows rows_inserted, + ha_rows rows_deleted, + ha_rows rows_updated, + ulonglong select_commands, + ulonglong update_commands, + ulonglong other_commands, + ulonglong commit_trans, + ulonglong rollback_trans, + ulonglong denied_connections, + ulonglong lost_connections, + ulonglong access_denied_errors, + ulonglong empty_queries); + +typedef struct st_table_stats +{ + char table[NAME_LEN * 2 + 2]; // [db] + '\0' + [table] + '\0' + uint table_name_length; + ulonglong rows_read, rows_changed; + ulonglong rows_changed_x_indexes; + /* Stores enum db_type, but forward declarations cannot be done */ + int engine_type; +} TABLE_STATS; + +typedef struct st_index_stats +{ + // [db] + '\0' + [table] + '\0' + [index] + '\0' + char index[NAME_LEN * 3 + 3]; + uint index_name_length; /* Length of 'index' */ + ulonglong rows_read; +} INDEX_STATS; + + /* Bits in form->update */ #define REG_MAKE_DUPP 1 /* Make a copy of record when read */ #define REG_NEW_RECORD 2 /* Write a new record if not found */ diff --git a/sql/table.cc b/sql/table.cc index 0bfa74dba75..554e1a6e55e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -21,6 +21,7 @@ #include "mysql_priv.h" #include "sql_trigger.h" +#include "create_options.h" #include <m_ctype.h> #include "my_md5.h" @@ -36,6 +37,12 @@ LEX_STRING GENERAL_LOG_NAME= {C_STRING_WITH_LEN("general_log")}; /* SLOW_LOG name */ LEX_STRING SLOW_LOG_NAME= {C_STRING_WITH_LEN("slow_log")}; +/* + Keyword added as a prefix when parsing the defining expression for a + virtual column read from the column definition saved in the frm file +*/ +LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") }; + /* Functions defined in this file */ void open_table_error(TABLE_SHARE *share, int error, int db_errno, @@ -680,12 +687,14 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, uint interval_count, interval_parts, read_length, int_length; uint db_create_options, keys, key_parts, n_length; uint key_info_length, com_length, null_bit_pos; - uint extra_rec_buf_length; + uint vcol_screen_length; + uint extra_rec_buf_length, options_len; uint i,j; bool use_hash; - char *keynames, *names, *comment_pos; + char *keynames, *names, *comment_pos, *vcol_screen_pos; uchar *record; - uchar *disk_buff, *strpos, *null_flags, *null_pos; + uchar *disk_buff, *strpos, *null_flags, *null_pos, *options; + uchar *buff= 0; ulong pos, record_offset, *rec_per_key, rec_buff_length; handler *handler_file= 0; KEY *keyinfo; @@ -698,6 +707,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, bool null_bits_are_used; DBUG_ENTER("open_binary_frm"); + LINT_INIT(options); + LINT_INIT(options_len); + new_field_pack_flag= head[27]; new_frm_ver= (head[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; @@ -803,7 +815,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, for (i=0 ; i < keys ; i++, keyinfo++) { - keyinfo->table= 0; // Updated in open_frm if (new_frm_ver >= 3) { keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; @@ -855,6 +866,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; share->reclength = uint2korr((head+16)); + share->stored_rec_length= share->reclength; if (*(head+26) == 1) share->system= 1; /* one-record-database */ #ifdef HAVE_CRYPTED_FRM @@ -872,15 +884,14 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if ((n_length= uint4korr(head+55))) { /* Read extra data segment */ - uchar *buff, *next_chunk, *buff_end; + uchar *next_chunk, *buff_end; DBUG_PRINT("info", ("extra segment size is %u bytes", n_length)); if (!(next_chunk= buff= (uchar*) my_malloc(n_length+1, MYF(MY_WME)))) goto err; if (my_pread(file, buff, n_length, record_offset + share->reclength, MYF(MY_NABP))) { - my_free(buff, MYF(0)); - goto err; + goto free_and_err; } share->connect_string.length= uint2korr(buff); if (!(share->connect_string.str= strmake_root(&share->mem_root, @@ -888,8 +899,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, share->connect_string. length))) { - my_free(buff, MYF(0)); - goto err; + goto free_and_err; } next_chunk+= share->connect_string.length + 2; buff_end= buff + n_length; @@ -909,8 +919,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, plugin_data(tmp_plugin, handlerton *))) { /* bad file, legacy_db_type did not match the name */ - my_free(buff, MYF(0)); - goto err; + goto free_and_err; } /* tmp_plugin is locked with a local lock. @@ -939,8 +948,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, error= 8; my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-partition"); - my_free(buff, MYF(0)); - goto err; + goto free_and_err; } plugin_unlock(NULL, share->db_plugin); share->db_plugin= ha_lock_engine(NULL, partition_hton); @@ -955,8 +963,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, error= 8; name.str[name.length]= 0; my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str); - my_free(buff, MYF(0)); - goto err; + goto free_and_err; /* purecov: end */ } next_chunk+= str_db_type_length + 2; @@ -972,34 +979,19 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, memdup_root(&share->mem_root, next_chunk + 4, partition_info_len + 1))) { - my_free(buff, MYF(0)); - goto err; + goto free_and_err; } } #else if (partition_info_len) { DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined")); - my_free(buff, MYF(0)); - goto err; + goto free_and_err; } #endif next_chunk+= 5 + partition_info_len; } -#if MYSQL_VERSION_ID < 50200 - if (share->mysql_version >= 50106 && share->mysql_version <= 50109) - { - /* - Partition state array was here in version 5.1.6 to 5.1.9, this code - makes it possible to load a 5.1.6 table in later versions. Can most - likely be removed at some point in time. Will only be used for - upgrades within 5.1 series of versions. Upgrade to 5.2 can only be - done from newer 5.1 versions. - */ - next_chunk+= 4; - } - else if (share->mysql_version >= 50110) -#endif + if (share->mysql_version >= 50110 && next_chunk < buff_end) { /* New auto_partitioned indicator introduced in 5.1.11 */ #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -1017,8 +1009,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, { DBUG_PRINT("error", ("fulltext key uses parser that is not defined in .frm")); - my_free(buff, MYF(0)); - goto err; + goto free_and_err; } parser_name.str= (char*) next_chunk; parser_name.length= strlen((char*) next_chunk); @@ -1028,12 +1019,22 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if (! keyinfo->parser) { my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str); - my_free(buff, MYF(0)); - goto err; + goto free_and_err; } } } - my_free(buff, MYF(0)); + DBUG_ASSERT(next_chunk <= buff_end); + if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS) + { + /* + store options position, but skip till the time we will + know number of fields + */ + options_len= uint4korr(next_chunk); + options= next_chunk + 4; + next_chunk+= options_len + 4; + } + DBUG_ASSERT(next_chunk <= buff_end); } share->key_block_size= uint2korr(head+62); @@ -1043,21 +1044,21 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, share->rec_buff_length= rec_buff_length; if (!(record= (uchar *) alloc_root(&share->mem_root, rec_buff_length))) - goto err; /* purecov: inspected */ + goto free_and_err; /* purecov: inspected */ share->default_values= record; if (my_pread(file, record, (size_t) share->reclength, record_offset, MYF(MY_NABP))) - goto err; /* purecov: inspected */ + goto free_and_err; /* purecov: inspected */ VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0))); if (my_read(file, head,288,MYF(MY_NABP))) - goto err; + goto free_and_err; #ifdef HAVE_CRYPTED_FRM if (crypted) { crypted->decode((char*) head+256,288-256); if (sint2korr(head+284) != 0) // Should be 0 - goto err; // Wrong password + goto free_and_err; // Wrong password } #endif @@ -1069,11 +1070,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, int_length= uint2korr(head+274); share->null_fields= uint2korr(head+282); com_length= uint2korr(head+284); + vcol_screen_length= uint2korr(head+286); + share->vfields= 0; + share->stored_fields= share->fields; share->comment.length= (int) (head[46]); share->comment.str= strmake_root(&share->mem_root, (char*) head+47, share->comment.length); - DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length)); + DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length, vcol_screen_length)); + if (!(field_ptr = (Field **) alloc_root(&share->mem_root, @@ -1081,14 +1086,16 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, interval_count*sizeof(TYPELIB)+ (share->fields+interval_parts+ keys+3)*sizeof(char *)+ - (n_length+int_length+com_length))))) - goto err; /* purecov: inspected */ + (n_length+int_length+com_length+ + vcol_screen_length))))) + goto free_and_err; /* purecov: inspected */ share->field= field_ptr; read_length=(uint) (share->fields * field_pack_length + - pos+ (uint) (n_length+int_length+com_length)); + pos+ (uint) (n_length+int_length+com_length+ + vcol_screen_length)); if (read_string(file,(uchar**) &disk_buff,read_length)) - goto err; /* purecov: inspected */ + goto free_and_err; /* purecov: inspected */ #ifdef HAVE_CRYPTED_FRM if (crypted) { @@ -1107,11 +1114,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, memcpy((char*) names, strpos+(share->fields*field_pack_length), (uint) (n_length+int_length)); comment_pos= names+(n_length+int_length); - memcpy(comment_pos, disk_buff+read_length-com_length, com_length); + memcpy(comment_pos, disk_buff+read_length-com_length-vcol_screen_length, + com_length); + vcol_screen_pos= names+(n_length+int_length+com_length); + memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length, + vcol_screen_length); fix_type_pointers(&interval_array, &share->fieldnames, 1, &names); if (share->fieldnames.count != share->fields) - goto err; + goto free_and_err; fix_type_pointers(&interval_array, share->intervals, interval_count, &names); @@ -1125,7 +1136,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, uint count= (uint) (interval->count + 1) * sizeof(uint); if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root, count))) - goto err; + goto free_and_err; for (count= 0; count < interval->count; count++) { char *val= (char*) interval->type_names[count]; @@ -1141,7 +1152,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, /* Allocate handler */ if (!(handler_file= get_new_handler(share, thd->mem_root, share->db_type()))) - goto err; + goto free_and_err; record= share->default_values-1; /* Fieldstart = 1 */ null_bits_are_used= share->null_fields != 0; @@ -1176,10 +1187,14 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++) { uint pack_flag, interval_nr, unireg_type, recpos, field_length; + uint vcol_info_length=0; + uint vcol_expr_length=0; enum_field_types field_type; CHARSET_INFO *charset=NULL; Field::geometry_type geom_type= Field::GEOM_GEOMETRY; LEX_STRING comment; + Virtual_column_info *vcol_info= 0; + bool fld_stored_in_db= TRUE; if (new_frm_ver >= 3) { @@ -1200,7 +1215,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, charset= &my_charset_bin; #else error= 4; // unsupported field type - goto err; + goto free_and_err; #endif } else @@ -1211,9 +1226,21 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, { error= 5; // Unknown or unavailable charset errarg= (int) strpos[14]; - goto err; + goto free_and_err; } } + + if ((uchar)field_type == (uchar)MYSQL_TYPE_VIRTUAL) + { + DBUG_ASSERT(interval_nr); // Expect non-null expression + /* + The interval_id byte in the .frm file stores the length of the + expression statement for a virtual column. + */ + vcol_info_length= interval_nr; + interval_nr= 0; + } + if (!comment_length) { comment.str= (char*) ""; @@ -1225,6 +1252,34 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, comment.length= comment_length; comment_pos+= comment_length; } + + if (vcol_info_length) + { + /* + Get virtual column data stored in the .frm file as follows: + byte 1 = 1 (always 1 to allow for future extensions) + byte 2 = sql_type + byte 3 = flags (as of now, 0 - no flags, 1 - field is physically stored) + byte 4-... = virtual column expression (text data) + */ + vcol_info= new Virtual_column_info(); + if ((uint)vcol_screen_pos[0] != 1) + { + error= 4; + goto free_and_err; + } + field_type= (enum_field_types) (uchar) vcol_screen_pos[1]; + fld_stored_in_db= (bool) (uint) vcol_screen_pos[2]; + vcol_expr_length= vcol_info_length-(uint)FRM_VCOL_HEADER_SIZE; + if (!(vcol_info->expr_str.str= + (char *)memdup_root(&share->mem_root, + vcol_screen_pos+(uint)FRM_VCOL_HEADER_SIZE, + vcol_expr_length))) + goto free_and_err; + vcol_info->expr_str.length= vcol_expr_length; + vcol_screen_pos+= vcol_info_length; + share->vfields++; + } } else { @@ -1310,11 +1365,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if (!reg_field) // Not supported field type { error= 4; - goto err; /* purecov: inspected */ + goto free_and_err; /* purecov: inspected */ } reg_field->field_index= i; reg_field->comment=comment; + reg_field->vcol_info= vcol_info; + reg_field->stored_in_db= fld_stored_in_db; if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag)) { null_bits_are_used= 1; @@ -1338,7 +1395,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, share->timestamp_field_offset= i; if (use_hash) - if (my_hash_insert(&share->name_hash, (uchar*) field_ptr) ) + { + if (my_hash_insert(&share->name_hash, + (uchar*) field_ptr)) { /* Set return code 8 here to indicate that an error has @@ -1346,10 +1405,20 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, sent (OOM). */ error= 8; - goto err; + goto free_and_err; } + } + if (!reg_field->stored_in_db) + { + share->stored_fields--; + if (share->stored_rec_length>=recpos) + share->stored_rec_length= recpos-1; + } } *field_ptr=0; // End marker + /* Sanity checks: */ + DBUG_ASSERT(share->fields>=share->stored_fields); + DBUG_ASSERT(share->reclength>=share->stored_rec_length); /* Fix key->name and key_part->field */ if (key_parts) @@ -1364,6 +1433,19 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, { uint usable_parts= 0; keyinfo->name=(char*) share->keynames.type_names[key]; + keyinfo->name_length= strlen(keyinfo->name); + keyinfo->cache_name= + (uchar*) alloc_root(&share->mem_root, + share->table_cache_key.length+ + keyinfo->name_length + 1); + if (keyinfo->cache_name) // If not out of memory + { + uchar *pos= keyinfo->cache_name; + memcpy(pos, share->table_cache_key.str, share->table_cache_key.length); + memcpy(pos + share->table_cache_key.length, keyinfo->name, + keyinfo->name_length+1); + } + /* Fix fulltext keys for old .frm files */ if (share->key_info[key].flags & HA_FULLTEXT) share->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT; @@ -1400,7 +1482,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if (!key_part->fieldnr) { error= 4; // Wrong file - goto err; + goto free_and_err; } field= key_part->field= share->field[key_part->fieldnr-1]; key_part->type= field->key_type(); @@ -1426,12 +1508,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, keyinfo->extra_length+=HA_KEY_BLOB_LENGTH; key_part->store_length+=HA_KEY_BLOB_LENGTH; keyinfo->key_length+= HA_KEY_BLOB_LENGTH; - /* - Mark that there may be many matching values for one key - combination ('a', 'a ', 'a '...) - */ - if (!(field->flags & BINARY_FLAG)) - keyinfo->flags|= HA_END_SPACE_KEY; } if (field->type() == MYSQL_TYPE_BIT) key_part->key_part_flag|= HA_BIT_PART; @@ -1517,6 +1593,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, */ if (field->real_maybe_null()) key_part->key_part_flag|= HA_NULL_PART; + /* + Sometimes we can compare key parts for equality with memcmp. + But not always. + */ + if (!(key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART | + HA_BIT_PART)) && + key_part->type != HA_KEYTYPE_FLOAT && + key_part->type == HA_KEYTYPE_DOUBLE) + key_part->key_part_flag|= HA_CAN_MEMCMP; } keyinfo->usable_key_parts= usable_parts; // Filesort @@ -1565,6 +1650,16 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, null_length, 255); } + if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS) + { + DBUG_ASSERT(options_len); + if (engine_table_options_frm_read(options, options_len, share)) + goto free_and_err; + } + if (parse_engine_table_options(thd, handler_file->partition_ht(), share)) + goto free_and_err; + my_free(buff, MYF(MY_ALLOW_ZERO_PTR)); + if (share->found_next_number_field) { reg_field= *share->found_next_number_field; @@ -1626,6 +1721,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, #endif DBUG_RETURN (0); + free_and_err: + my_free(buff, MYF(MY_ALLOW_ZERO_PTR)); err: share->error= error; share->open_errno= my_errno; @@ -1644,6 +1741,316 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, DBUG_RETURN(error); } /* open_binary_frm */ +/* + @brief + Clear GET_FIXED_FIELDS_FLAG in all fields of a table + + @param + table The table for whose fields the flags are to be cleared + + @note + This routine is used for error handling purposes. + + @return + none +*/ + +static void clear_field_flag(TABLE *table) +{ + Field **ptr; + DBUG_ENTER("clear_field_flag"); + + for (ptr= table->field; *ptr; ptr++) + (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG); + DBUG_VOID_RETURN; +} + + +/* + @brief + Perform semantic analysis of the defining expression for a virtual column + + @param + thd The thread object + @param + table The table containing the virtual column + @param + vcol_field The virtual field whose defining expression is to be analyzed + + @details + The function performs semantic analysis of the defining expression for + the virtual column vcol_field. The expression is used to compute the + values of this column. + + @note + The function exploits the fact that the fix_fields method sets the flag + GET_FIXED_FIELDS_FLAG for all fields in the item tree. + This flag must always be unset before returning from this function + since it is used for other purposes as well. + + @retval + TRUE An error occurred, something was wrong with the function + @retval + FALSE Otherwise +*/ + +bool fix_vcol_expr(THD *thd, + TABLE *table, + Field *vcol_field) +{ + Virtual_column_info *vcol_info= vcol_field->vcol_info; + Item* func_expr= vcol_info->expr_item; + uint dir_length, home_dir_length; + bool result= TRUE; + TABLE_LIST tables; + TABLE_LIST *save_table_list, *save_first_table, *save_last_table; + int error; + Name_resolution_context *context; + const char *save_where; + char* db_name; + char db_name_string[FN_REFLEN]; + bool save_use_only_table_context; + Field **ptr, *field; + enum_mark_columns save_mark_used_columns= thd->mark_used_columns; + DBUG_ASSERT(func_expr); + DBUG_ENTER("fix_vcol_expr"); + + /* + Set-up the TABLE_LIST object to be a list with a single table + Set the object to zero to create NULL pointers and set alias + and real name to table name and get database name from file name. + */ + + bzero((void*)&tables, sizeof(TABLE_LIST)); + tables.alias= tables.table_name= (char*) table->s->table_name.str; + tables.table= table; + tables.next_local= 0; + tables.next_name_resolution_table= 0; + strmov(db_name_string, table->s->normalized_path.str); + dir_length= dirname_length(db_name_string); + db_name_string[dir_length - 1]= 0; + home_dir_length= dirname_length(db_name_string); + db_name= &db_name_string[home_dir_length]; + tables.db= db_name; + + thd->mark_used_columns= MARK_COLUMNS_NONE; + + context= thd->lex->current_context(); + table->map= 1; //To ensure correct calculation of const item + table->get_fields_in_item_tree= TRUE; + save_table_list= context->table_list; + save_first_table= context->first_name_resolution_table; + save_last_table= context->last_name_resolution_table; + context->table_list= &tables; + context->first_name_resolution_table= &tables; + context->last_name_resolution_table= NULL; + func_expr->walk(&Item::change_context_processor, 0, (uchar*) context); + save_where= thd->where; + thd->where= "virtual column function"; + + /* Save the context before fixing the fields*/ + save_use_only_table_context= thd->lex->use_only_table_context; + thd->lex->use_only_table_context= TRUE; + /* Fix fields referenced to by the virtual column function */ + error= func_expr->fix_fields(thd, (Item**)0); + /* Restore the original context*/ + thd->lex->use_only_table_context= save_use_only_table_context; + context->table_list= save_table_list; + context->first_name_resolution_table= save_first_table; + context->last_name_resolution_table= save_last_table; + + if (unlikely(error)) + { + DBUG_PRINT("info", + ("Field in virtual column expression does not belong to the table")); + goto end; + } + thd->where= save_where; + if (unlikely(func_expr->result_type() == ROW_RESULT)) + { + my_error(ER_ROW_EXPR_FOR_VCOL, MYF(0)); + goto end; + } +#ifdef PARANOID + /* + Walk through the Item tree checking if all items are valid + to be part of the virtual column + */ + error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL); + if (error) + { + my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name); + goto end; + } +#endif + if (unlikely(func_expr->const_item())) + { + my_error(ER_CONST_EXPR_IN_VCOL, MYF(0)); + goto end; + } + /* Ensure that this virtual column is not based on another virtual field. */ + ptr= table->field; + while ((field= *(ptr++))) + { + if ((field->flags & GET_FIXED_FIELDS_FLAG) && + (field->vcol_info)) + { + my_error(ER_VCOL_BASED_ON_VCOL, MYF(0)); + goto end; + } + } + result= FALSE; + +end: + + /* Clear GET_FIXED_FIELDS_FLAG for the fields of the table */ + clear_field_flag(table); + + table->get_fields_in_item_tree= FALSE; + thd->mark_used_columns= save_mark_used_columns; + table->map= 0; //Restore old value + + DBUG_RETURN(result); +} + +/* + @brief + Unpack the definition of a virtual column from its linear representation + + @parm + thd The thread object + @param + table The table containing the virtual column + @param + field The field for the virtual + @param + vcol_expr The string representation of the defining expression + @param[out] + error_reported The flag to inform the caller that no other error + messages are to be generated + + @details + The function takes string representation 'vcol_expr' of the defining + expression for the virtual field 'field' of the table 'table' and + parses it, building an item object for it. The pointer to this item is + placed into in field->vcol_info.expr_item. After this the function performs + semantic analysis of the item by calling the the function fix_vcol_expr. + Since the defining expression is part of the table definition the item for + it is created in table->memroot within the special arena TABLE::expr_arena. + + @note + Before passing 'vcol_expr" to the parser the function embraces it in + parenthesis and prepands it a special keyword. + + @retval + FALSE If a success + @retval + TRUE Otherwise +*/ +bool unpack_vcol_info_from_frm(THD *thd, + TABLE *table, + Field *field, + LEX_STRING *vcol_expr, + bool *error_reported) +{ + bool rc; + char *vcol_expr_str; + int str_len; + CHARSET_INFO *old_character_set_client; + Query_arena *backup_stmt_arena_ptr; + Query_arena backup_arena; + Query_arena *vcol_arena= 0; + Parser_state parser_state; + DBUG_ENTER("unpack_vcol_info_from_frm"); + DBUG_ASSERT(vcol_expr); + + old_character_set_client= thd->variables.character_set_client; + backup_stmt_arena_ptr= thd->stmt_arena; + + /* + Step 1: Construct the input string for the parser. + The string to be parsed has to be of the following format: + "PARSE_VCOL_EXPR (<expr_string_from_frm>)". + */ + + if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root, + vcol_expr->length + + parse_vcol_keyword.length + 3))) + { + DBUG_RETURN(TRUE); + } + memcpy(vcol_expr_str, + (char*) parse_vcol_keyword.str, + parse_vcol_keyword.length); + str_len= parse_vcol_keyword.length; + memcpy(vcol_expr_str + str_len, "(", 1); + str_len++; + memcpy(vcol_expr_str + str_len, + (char*) vcol_expr->str, + vcol_expr->length); + str_len+= vcol_expr->length; + memcpy(vcol_expr_str + str_len, ")", 1); + str_len++; + memcpy(vcol_expr_str + str_len, "\0", 1); + str_len++; + + if (parser_state.init(thd, vcol_expr_str, str_len)) + goto err; + + /* + Step 2: Setup thd for parsing. + */ + vcol_arena= table->expr_arena; + if (!vcol_arena) + { + Query_arena expr_arena(&table->mem_root, Query_arena::INITIALIZED); + if (!(vcol_arena= (Query_arena *) alloc_root(&table->mem_root, + sizeof(Query_arena)))) + goto err; + *vcol_arena= expr_arena; + table->expr_arena= vcol_arena; + } + thd->set_n_backup_active_arena(vcol_arena, &backup_arena); + thd->stmt_arena= vcol_arena; + + thd->lex->parse_vcol_expr= TRUE; + + /* + Step 3: Use the parser to build an Item object from vcol_expr_str. + */ + if (parse_sql(thd, &parser_state, NULL)) + { + goto err; + } + /* From now on use vcol_info generated by the parser. */ + field->vcol_info= thd->lex->vcol_info; + + /* Validate the Item tree. */ + if (fix_vcol_expr(thd, table, field)) + { + *error_reported= TRUE; + field->vcol_info= 0; + goto err; + } + rc= FALSE; + goto end; + +err: + rc= TRUE; + thd->lex->parse_vcol_expr= FALSE; + thd->free_items(); +end: + thd->stmt_arena= backup_stmt_arena_ptr; + if (vcol_arena) + thd->restore_active_arena(vcol_arena, &backup_arena); + thd->variables.character_set_client= old_character_set_client; + + DBUG_RETURN(rc); +} + +/* + Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE +*/ /* Open a table based on a TABLE_SHARE @@ -1678,7 +2085,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, uint records, i, bitmap_size; bool error_reported= FALSE; uchar *record, *bitmaps; - Field **field_ptr; + Field **field_ptr, **vfield_ptr; + uint8 save_context_analysis_only= thd->lex->context_analysis_only; DBUG_ENTER("open_table_from_share"); DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str, share->table_name.str, (long) outparam)); @@ -1686,6 +2094,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, /* Parsing of partitioning information from .frm needs thd->lex set up. */ DBUG_ASSERT(thd->lex->is_lex_started); + thd->lex->context_analysis_only= 0; // not a view + error= 1; bzero((char*) outparam, sizeof(*outparam)); outparam->in_use= thd; @@ -1695,7 +2105,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); - if (!(outparam->alias= my_strdup(alias, MYF(MY_WME)))) + if (outparam->alias.copy(alias, strlen(alias), table_alias_charset)) goto err; outparam->quick_keys.init(); outparam->covering_keys.init(); @@ -1832,6 +2242,34 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, } } + /* + Process virtual columns, if any. + */ + if (!(vfield_ptr = (Field **) alloc_root(&outparam->mem_root, + (uint) ((share->vfields+1)* + sizeof(Field*))))) + goto err; + + outparam->vfield= vfield_ptr; + + for (field_ptr= outparam->field; *field_ptr; field_ptr++) + { + if ((*field_ptr)->vcol_info) + { + if (unpack_vcol_info_from_frm(thd, + outparam, + *field_ptr, + &(*field_ptr)->vcol_info->expr_str, + &error_reported)) + { + error= 4; // in case no error is reported + goto err; + } + *(vfield_ptr++)= *field_ptr; + } + } + *vfield_ptr= 0; // End marker + #ifdef WITH_PARTITION_STORAGE_ENGINE if (share->partition_info_len && outparam->file) { @@ -1899,17 +2337,30 @@ partititon_err: } #endif + /* Check virtual columns against table's storage engine. */ + if (share->vfields && + !(outparam->file && + (outparam->file->ha_table_flags() & HA_CAN_VIRTUAL_COLUMNS))) + { + my_error(ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS, MYF(0), + plugin_name(share->db_plugin)->str); + error_reported= TRUE; + goto err; + } + /* Allocate bitmaps */ bitmap_size= share->column_bitmap_size; - if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*3))) + if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*4))) goto err; bitmap_init(&outparam->def_read_set, (my_bitmap_map*) bitmaps, share->fields, FALSE); bitmap_init(&outparam->def_write_set, (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, FALSE); - bitmap_init(&outparam->tmp_set, + bitmap_init(&outparam->def_vcol_set, (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE); + bitmap_init(&outparam->tmp_set, + (my_bitmap_map*) (bitmaps+bitmap_size*3), share->fields, FALSE); outparam->default_column_bitmaps(); /* The table struct is now initialized; Open the table */ @@ -1973,6 +2424,7 @@ partititon_err: HA_HAS_OWN_BINLOGGING); thd->status_var.opened_tables++; + thd->lex->context_analysis_only= save_context_analysis_only; DBUG_RETURN (0); err: @@ -1985,8 +2437,9 @@ partititon_err: #endif outparam->file= 0; // For easier error checking outparam->db_stat=0; + thd->lex->context_analysis_only= save_context_analysis_only; free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root - my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR)); + outparam->alias.free(); DBUG_RETURN (error); } @@ -2012,12 +2465,15 @@ int closefrm(register TABLE *table, bool free_share) table->file->extra(HA_EXTRA_PREPARE_FOR_DROP); error=table->file->close(); } - my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR)); - table->alias= 0; + table->alias.free(); + if (table->expr_arena) + table->expr_arena->free_items(); if (table->field) { for (Field **ptr=table->field ; *ptr ; ptr++) + { delete *ptr; + } table->field= 0; } delete table->file; @@ -2485,6 +2941,7 @@ File create_frm(THD *thd, const char *name, const char *db, ulong length; uchar fill[IO_SIZE]; int create_flags= O_RDWR | O_TRUNC; + DBUG_ENTER("create_frm"); if (create_info->options & HA_LEX_CREATE_TMP_TABLE) create_flags|= O_EXCL | O_NOFOLLOW; @@ -2566,7 +3023,7 @@ File create_frm(THD *thd, const char *name, const char *db, { VOID(my_close(file,MYF(0))); VOID(my_delete(name,MYF(0))); - return(-1); + DBUG_RETURN(-1); } } } @@ -2577,7 +3034,7 @@ File create_frm(THD *thd, const char *name, const char *db, else my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno); } - return (file); + DBUG_RETURN(file); } /* create_frm */ @@ -2596,6 +3053,7 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) create_info->comment= share->comment; create_info->transactional= share->transactional; create_info->page_checksum= share->page_checksum; + create_info->option_list= share->option_list; DBUG_VOID_RETURN; } @@ -2848,7 +3306,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) const TABLE_FIELD_TYPE *field_def= table_def->field; DBUG_ENTER("table_check_intact"); DBUG_PRINT("info",("table: %s expected_count: %d", - table->alias, table_def->count)); + table->alias.c_ptr(), table_def->count)); /* Whether the table definition has already been validated. */ if (table->s->table_field_def_cache == table_def) @@ -2863,15 +3321,15 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) { report_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE), - table->alias, table_def->count, table->s->fields, - static_cast<int>(table->s->mysql_version), - MYSQL_VERSION_ID); + table->alias.c_ptr(), table_def->count, table->s->fields, + (int) table->s->mysql_version, MYSQL_VERSION_ID); DBUG_RETURN(TRUE); } else if (MYSQL_VERSION_ID == table->s->mysql_version) { report_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED, - ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias, + ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), + table->alias.c_ptr(), table_def->count, table->s->fields); DBUG_RETURN(TRUE); } @@ -2883,11 +3341,13 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) is backward compatible. */ } - char buffer[STRING_BUFFER_USUAL_SIZE]; + char buffer[1024]; for (i=0 ; i < table_def->count; i++, field_def++) { String sql_type(buffer, sizeof(buffer), system_charset_info); sql_type.length(0); + /* Allocate min 256 characters at once */ + sql_type.extra_allocation(256); if (i < table->s->fields) { Field *field= table->field[i]; @@ -2902,7 +3362,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) */ report_error(0, "Incorrect definition of table %s.%s: " "expected column '%s' at position %d, found '%s'.", - table->s->db.str, table->alias, field_def->name.str, i, + table->s->db.str, table->alias.c_ptr(), + field_def->name.str, i, field->field_name); } field->sql_type(sql_type); @@ -2928,7 +3389,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) { report_error(0, "Incorrect definition of table %s.%s: " "expected column '%s' at position %d to have type " - "%s, found type %s.", table->s->db.str, table->alias, + "%s, found type %s.", table->s->db.str, + table->alias.c_ptr(), field_def->name.str, i, field_def->type.str, sql_type.c_ptr_safe()); error= TRUE; @@ -2938,7 +3400,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) report_error(0, "Incorrect definition of table %s.%s: " "expected the type of column '%s' at position %d " "to have character set '%s' but the type has no " - "character set.", table->s->db.str, table->alias, + "character set.", table->s->db.str, + table->alias.c_ptr(), field_def->name.str, i, field_def->cset.str); error= TRUE; } @@ -2948,7 +3411,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) report_error(0, "Incorrect definition of table %s.%s: " "expected the type of column '%s' at position %d " "to have character set '%s' but found " - "character set '%s'.", table->s->db.str, table->alias, + "character set '%s'.", table->s->db.str, + table->alias.c_ptr(), field_def->name.str, i, field_def->cset.str, field->charset()->csname); error= TRUE; @@ -2959,7 +3423,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) report_error(0, "Incorrect definition of table %s.%s: " "expected column '%s' at position %d to have type %s " " but the column is not found.", - table->s->db.str, table->alias, + table->s->db.str, table->alias.c_ptr(), field_def->name.str, i, field_def->type.str); error= TRUE; } @@ -3763,11 +4227,8 @@ bool TABLE_LIST::prepare_view_securety_context(THD *thd) { DBUG_PRINT("info", ("This table is suid view => load contest")); DBUG_ASSERT(view && view_sctx); - if (acl_getroot_no_password(view_sctx, - definer.user.str, - definer.host.str, - definer.host.str, - thd->db)) + if (acl_getroot(view_sctx, definer.user.str, definer.host.str, + definer.host.str, thd->db)) { if ((thd->lex->sql_command == SQLCOM_SHOW_CREATE) || (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) @@ -4360,9 +4821,10 @@ void st_table::clear_column_bitmaps() Reset column read/write usage. It's identical to: bitmap_clear_all(&table->def_read_set); bitmap_clear_all(&table->def_write_set); + bitmap_clear_all(&table->def_vcol_set); */ - bzero((char*) def_read_set.bitmap, s->column_bitmap_size*2); - column_bitmaps_set(&def_read_set, &def_write_set); + bzero((char*) def_read_set.bitmap, s->column_bitmap_size*3); + column_bitmaps_set(&def_read_set, &def_write_set, &def_vcol_set); } @@ -4467,7 +4929,14 @@ void st_table::mark_columns_used_by_index_no_reset(uint index, KEY_PART_INFO *key_part_end= (key_part + key_info[index].key_parts); for (;key_part != key_part_end; key_part++) + { bitmap_set_bit(bitmap, key_part->fieldnr-1); + if (key_part->field->vcol_info && + key_part->field->vcol_info->expr_item) + key_part->field->vcol_info-> + expr_item->walk(&Item::register_field_in_bitmap, + 1, (uchar *) bitmap); + } } @@ -4594,6 +5063,8 @@ void st_table::mark_columns_needed_for_update() file->column_bitmaps_signal(); } } + /* Mark all virtual columns needed for update */ + mark_virtual_columns_for_write(FALSE); DBUG_VOID_RETURN; } @@ -4620,9 +5091,109 @@ void st_table::mark_columns_needed_for_insert() } if (found_next_number_field) mark_auto_increment_column(); + /* Mark virtual columns for insert */ + mark_virtual_columns_for_write(TRUE); } +/* + @brief Mark a column as virtual used by the query + + @param field the field for the column to be marked + + @details + The function marks the column for 'field' as virtual (computed) + in the bitmap vcol_set. + If the column is marked for the first time the expression to compute + the column is traversed and all columns that are occurred there are + marked in the read_set of the table. + + @retval + TRUE if column is marked for the first time + @retval + FALSE otherwise +*/ + +bool st_table::mark_virtual_col(Field *field) +{ + bool res; + DBUG_ASSERT(field->vcol_info); + if (!(res= bitmap_fast_test_and_set(vcol_set, field->field_index))) + { + Item *vcol_item= field->vcol_info->expr_item; + DBUG_ASSERT(vcol_item); + vcol_item->walk(&Item::register_field_in_read_map, 1, (uchar *) 0); + } + return res; +} + + +/* + @brief Mark virtual columns for update/insert commands + + @param insert_fl <-> virtual columns are marked for insert command + + @details + The function marks virtual columns used in a update/insert commands + in the vcol_set bitmap. + For an insert command a virtual column is always marked in write_set if + it is a stored column. + If a virtual column is from write_set it is always marked in vcol_set. + If a stored virtual column is not from write_set but it is computed + through columns from write_set it is also marked in vcol_set, and, + besides, it is added to write_set. + + @return void + + @note + Let table t1 have columns a,b,c and let column c be a stored virtual + column computed through columns a and b. Then for the query + UPDATE t1 SET a=1 + column c will be placed into vcol_set and into write_set while + column b will be placed into read_set. + If column c was a virtual column, but not a stored virtual column + then it would not be added to any of the sets. Column b would not + be added to read_set either. +*/ + +void st_table::mark_virtual_columns_for_write(bool insert_fl) +{ + Field **vfield_ptr, *tmp_vfield; + bool bitmap_updated= FALSE; + + for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) + { + tmp_vfield= *vfield_ptr; + if (bitmap_is_set(write_set, tmp_vfield->field_index)) + bitmap_updated= mark_virtual_col(tmp_vfield); + else if (tmp_vfield->stored_in_db) + { + bool mark_fl= insert_fl; + if (!mark_fl) + { + MY_BITMAP *save_read_set; + Item *vcol_item= tmp_vfield->vcol_info->expr_item; + DBUG_ASSERT(vcol_item); + bitmap_clear_all(&tmp_set); + save_read_set= read_set; + read_set= &tmp_set; + vcol_item->walk(&Item::register_field_in_read_map, 1, (uchar *) 0); + read_set= save_read_set; + bitmap_intersect(&tmp_set, write_set); + mark_fl= !bitmap_is_clear_all(&tmp_set); + } + if (mark_fl) + { + bitmap_set_bit(write_set, tmp_vfield->field_index); + mark_virtual_col(tmp_vfield); + bitmap_updated= TRUE; + } + } + } + if (bitmap_updated) + file->column_bitmaps_signal(); +} + /** @brief Check if this is part of a MERGE table with attached children. @@ -4630,7 +5201,7 @@ void st_table::mark_columns_needed_for_insert() @retval TRUE children are attached @retval FALSE no MERGE part or children not attached - @detail + @details A MERGE table consists of a parent TABLE and zero or more child TABLEs. Each of these TABLEs is called a part of a MERGE table. */ @@ -4891,6 +5462,57 @@ size_t max_row_length(TABLE *table, const uchar *data) return length; } +/* + @brief Compute values for virtual columns used in query + + @param thd Thread handle + @param table The TABLE object + @param for_write Requests to compute only fields needed for write + + @details + The function computes the values of the virtual columns of the table and + stores them in the table record buffer. + Only fields from vcol_set are computed, and, when the flag for_write is not + set to TRUE, a virtual field is computed only if it's not stored. + The flag for_write is set to TRUE for row insert/update operations. + + @retval + 0 Success + @retval + >0 Error occurred when storing a virtual field value +*/ + +int update_virtual_fields(THD *thd, TABLE *table, bool for_write) +{ + DBUG_ENTER("update_virtual_fields"); + Field **vfield_ptr, *vfield; + int error= 0; + if (!table || !table->vfield) + DBUG_RETURN(0); + + thd->reset_arena_for_cached_items(table->expr_arena); + /* Iterate over virtual fields in the table */ + for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++) + { + vfield= (*vfield_ptr); + DBUG_ASSERT(vfield->vcol_info && vfield->vcol_info->expr_item); + /* Only update those fields that are marked in the vcol_set bitmap */ + if (bitmap_is_set(table->vcol_set, vfield->field_index) && + (for_write || !vfield->stored_in_db)) + { + /* Compute the actual value of the virtual fields */ + error= vfield->vcol_info->expr_item->save_in_field(vfield, 0); + DBUG_PRINT("info", ("field '%s' - updated", vfield->field_name)); + } + else + { + DBUG_PRINT("info", ("field '%s' - skipped", vfield->field_name)); + } + } + thd->reset_arena_for_cached_items(0); + DBUG_RETURN(0); +} + /***************************************************************************** ** Instansiate templates *****************************************************************************/ diff --git a/sql/table.h b/sql/table.h index 687d0296e1e..1b7713022ce 100644 --- a/sql/table.h +++ b/sql/table.h @@ -13,6 +13,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef SQL_TABLE_INCLUDED +#define SQL_TABLE_INCLUDED /* Structs that defines the TABLE */ @@ -25,6 +27,7 @@ class st_select_lex; class partition_info; class COND_EQUAL; class Security_context; +class Query_arena; /*************************************************************************/ @@ -339,6 +342,8 @@ typedef struct st_table_share #ifdef NOT_YET struct st_table *open_tables; /* link to open tables */ #endif + engine_option_value *option_list; /* text options for table */ + ha_table_option_struct *option_struct; /* structure with parsed options */ /* The following is copied to each TABLE on OPEN */ Field **field; @@ -381,6 +386,8 @@ typedef struct st_table_share ulong version, mysql_version; ulong timestamp_offset; /* Set to offset+1 of record */ ulong reclength; /* Recordlength */ + /* Stored record length. No generated-only virtual fields are included */ + ulong stored_rec_length; plugin_ref db_plugin; /* storage engine plugin */ inline handlerton *db_type() const /* table_type for handler */ @@ -406,6 +413,8 @@ typedef struct st_table_share */ uint null_bytes_for_compare; uint fields; /* Number of fields */ + /* Number of stored fields, generated-only virtual fields are not included */ + uint stored_fields; uint rec_buff_length; /* Size of table->record[] buffer */ uint keys, key_parts; uint max_key_length, max_unique_length, total_key_length; @@ -427,6 +436,7 @@ typedef struct st_table_share uint error, open_errno, errarg; /* error from open_table_def() */ uint column_bitmap_size; uchar frm_version; + uint vfields; /* Number of computed (virtual) fields */ bool null_field_first; bool system; /* Set if system table (one record) */ bool crypted; /* If .frm file is crypted */ @@ -705,16 +715,17 @@ struct st_table { Field *next_number_field; /* Set if next_number is activated */ Field *found_next_number_field; /* Set on open */ Field_timestamp *timestamp_field; + Field **vfield; /* Pointer to virtual fields*/ /* Table's triggers, 0 if there are no of them */ Table_triggers_list *triggers; TABLE_LIST *pos_in_table_list;/* Element referring to this table */ ORDER *group; - const char *alias; /* alias or table name */ + String alias; /* alias or table name */ uchar *null_flags; my_bitmap_map *bitmap_init_value; - MY_BITMAP def_read_set, def_write_set, tmp_set; /* containers */ - MY_BITMAP *read_set, *write_set; /* Active column sets */ + MY_BITMAP def_read_set, def_write_set, def_vcol_set, tmp_set; + MY_BITMAP *read_set, *write_set, *vcol_set; /* Active column sets */ /* The ID of the query that opened and is using this table. Has different meanings depending on the table type. @@ -782,7 +793,7 @@ struct st_table { /* number of select if it is derived table */ uint derived_select_number; int current_lock; /* Type of lock on table */ - my_bool copy_blobs; /* copy_blobs when storing */ + bool copy_blobs; /* copy_blobs when storing */ /* 0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0. @@ -794,34 +805,34 @@ struct st_table { If true, the current table row is considered to have all columns set to NULL, including columns declared as "not null" (see maybe_null). */ - my_bool null_row; + bool null_row; /* TODO: Each of the following flags take up 8 bits. They can just as easily be put into one single unsigned long and instead of taking up 18 bytes, it would take up 4. */ - my_bool force_index; + bool force_index; /** Flag set when the statement contains FORCE INDEX FOR ORDER BY See TABLE_LIST::process_index_hints(). */ - my_bool force_index_order; + bool force_index_order; /** Flag set when the statement contains FORCE INDEX FOR GROUP BY See TABLE_LIST::process_index_hints(). */ - my_bool force_index_group; - my_bool distinct,const_table,no_rows; + bool force_index_group; + bool distinct,const_table,no_rows; /** If set, the optimizer has found that row retrieval should access index tree only. */ - my_bool key_read; - my_bool no_keyread; + bool key_read; + bool no_keyread; /* Placeholder for an open table which prevents other connections from taking name-locks on this table. Typically used with @@ -839,30 +850,38 @@ struct st_table { object associated with it (db_stat is always 0), but please do not rely on that. */ - my_bool open_placeholder; - my_bool locked_by_logger; - my_bool no_replicate; - my_bool locked_by_name; - my_bool fulltext_searched; - my_bool no_cache; + bool open_placeholder; + bool locked_by_logger; + bool no_replicate; + bool locked_by_name; + bool fulltext_searched; + bool no_cache; /* To signal that the table is associated with a HANDLER statement */ - my_bool open_by_handler; + bool open_by_handler; /* To indicate that a non-null value of the auto_increment field was provided by the user or retrieved from the current record. Used only in the MODE_NO_AUTO_VALUE_ON_ZERO mode. */ - my_bool auto_increment_field_not_null; - my_bool insert_or_update; /* Can be used by the handler */ - my_bool alias_name_used; /* true if table_name is alias */ - my_bool get_fields_in_item_tree; /* Signal to fix_field */ + bool auto_increment_field_not_null; + bool insert_or_update; /* Can be used by the handler */ + bool alias_name_used; /* true if table_name is alias */ + bool get_fields_in_item_tree; /* Signal to fix_field */ /* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */ - my_bool children_attached; + bool children_attached; REGINFO reginfo; /* field connections */ MEM_ROOT mem_root; GRANT_INFO grant; FILESORT_INFO sort; + /* + The arena which the items for expressions from the table definition + are associated with. + Currently only the items of the expressions for virtual columns are + associated with this arena. + TODO: To attach the partitioning expressions to this arena. + */ + Query_arena *expr_arena; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_info *part_info; /* Partition related information */ bool no_partitions_used; /* If true, all partitions have been pruned away */ @@ -880,6 +899,8 @@ struct st_table { void mark_columns_needed_for_update(void); void mark_columns_needed_for_delete(void); void mark_columns_needed_for_insert(void); + bool mark_virtual_col(Field *field); + void mark_virtual_columns_for_write(bool insert_fl); inline void column_bitmaps_set(MY_BITMAP *read_set_arg, MY_BITMAP *write_set_arg) { @@ -888,12 +909,30 @@ struct st_table { if (file) file->column_bitmaps_signal(); } + inline void column_bitmaps_set(MY_BITMAP *read_set_arg, + MY_BITMAP *write_set_arg, + MY_BITMAP *vcol_set_arg) + { + read_set= read_set_arg; + write_set= write_set_arg; + vcol_set= vcol_set_arg; + if (file) + file->column_bitmaps_signal(); + } inline void column_bitmaps_set_no_signal(MY_BITMAP *read_set_arg, MY_BITMAP *write_set_arg) { read_set= read_set_arg; write_set= write_set_arg; } + inline void column_bitmaps_set_no_signal(MY_BITMAP *read_set_arg, + MY_BITMAP *write_set_arg, + MY_BITMAP *vcol_set_arg) + { + read_set= read_set_arg; + write_set= write_set_arg; + vcol_set= vcol_set_arg; + } inline void use_all_columns() { column_bitmaps_set(&s->all_set, &s->all_set); @@ -902,6 +941,7 @@ struct st_table { { read_set= &def_read_set; write_set= &def_write_set; + vcol_set= &def_vcol_set; } /* Is table open or should be treated as such by name-locking? */ inline bool is_name_opened() { return db_stat || open_placeholder; } @@ -957,6 +997,7 @@ typedef struct st_foreign_key_info enum enum_schema_tables { SCH_CHARSETS= 0, + SCH_CLIENT_STATS, SCH_COLLATIONS, SCH_COLLATION_CHARACTER_SET_APPLICABILITY, SCH_COLUMNS, @@ -966,6 +1007,8 @@ enum enum_schema_tables SCH_FILES, SCH_GLOBAL_STATUS, SCH_GLOBAL_VARIABLES, + SCH_INDEX_STATS, + SCH_KEY_CACHES, SCH_KEY_COLUMN_USAGE, SCH_OPEN_TABLES, SCH_PARTITIONS, @@ -984,8 +1027,10 @@ enum enum_schema_tables SCH_TABLE_CONSTRAINTS, SCH_TABLE_NAMES, SCH_TABLE_PRIVILEGES, + SCH_TABLE_STATS, SCH_TRIGGERS, SCH_USER_PRIVILEGES, + SCH_USER_STATS, SCH_VARIABLES, SCH_VIEWS }; @@ -1822,3 +1867,4 @@ static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set, size_t max_row_length(TABLE *table, const uchar *data); +#endif diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index c96171c4e74..7afb8027a2c 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -65,11 +65,13 @@ void init_sql_alloc(MEM_ROOT *mem_root, uint block_size, uint pre_alloc) } +#ifndef MYSQL_CLIENT void *sql_alloc(size_t Size) { MEM_ROOT *root= *my_pthread_getspecific_ptr(MEM_ROOT**,THR_MALLOC); return alloc_root(root,Size); } +#endif void *sql_calloc(size_t size) diff --git a/sql/tztime.cc b/sql/tztime.cc index 3cdc1853c14..6bb295b98c6 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -216,7 +216,7 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) ALIGN_SIZE(sp->typecnt * sizeof(TRAN_TYPE_INFO)) + #ifdef ABBR_ARE_USED - ALIGN_SIZE(sp->charcnt) + + ALIGN_SIZE(sp->charcnt+1) + #endif sp->leapcnt * sizeof(LS_INFO)))) return 1; @@ -229,7 +229,7 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) tzinfo_buf+= ALIGN_SIZE(sp->typecnt * sizeof(TRAN_TYPE_INFO)); #ifdef ABBR_ARE_USED sp->chars= tzinfo_buf; - tzinfo_buf+= ALIGN_SIZE(sp->charcnt); + tzinfo_buf+= ALIGN_SIZE(sp->charcnt+1); #endif sp->lsis= (LS_INFO *)tzinfo_buf; @@ -1678,7 +1678,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) tz_leapcnt= 0; - res= table->file->index_first(table->record[0]); + res= table->file->ha_index_first(table->record[0]); while (!res) { @@ -1700,7 +1700,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) tz_leapcnt, (ulong) tz_lsis[tz_leapcnt-1].ls_trans, tz_lsis[tz_leapcnt-1].ls_corr)); - res= table->file->index_next(table->record[0]); + res= table->file->ha_index_next(table->record[0]); } (void)table->file->ha_index_end(); @@ -1815,6 +1815,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) uint tzid, ttid; my_time_t ttime; char buff[MAX_FIELD_WIDTH]; + uchar keybuff[32]; + Field *field; String abbr(buff, sizeof(buff), &my_charset_latin1); char *alloc_buff, *tz_name_buff; /* @@ -1867,8 +1869,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ (void)table->file->ha_index_init(0, 1); - if (table->file->index_read_map(table->record[0], table->field[0]->ptr, - HA_WHOLE_KEY, HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_map(table->record[0], table->field[0]->ptr, + HA_WHOLE_KEY, HA_READ_KEY_EXACT)) { #ifdef EXTRA_DEBUG /* @@ -1892,11 +1894,16 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ table= tz_tables->table; tz_tables= tz_tables->next_local; - table->field[0]->store((longlong) tzid, TRUE); + field= table->field[0]; + field->store((longlong) tzid, TRUE); + DBUG_ASSERT(field->key_length() <= sizeof(keybuff)); + field->get_key_image(keybuff, + min(field->key_length(), sizeof(keybuff)), + Field::itRAW); (void)table->file->ha_index_init(0, 1); - if (table->file->index_read_map(table->record[0], table->field[0]->ptr, - HA_WHOLE_KEY, HA_READ_KEY_EXACT)) + if (table->file->ha_index_read_map(table->record[0], keybuff, + HA_WHOLE_KEY, HA_READ_KEY_EXACT)) { sql_print_error("Can't find description of time zone '%u'", tzid); goto end; @@ -1919,11 +1926,16 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ table= tz_tables->table; tz_tables= tz_tables->next_local; - table->field[0]->store((longlong) tzid, TRUE); + field= table->field[0]; + field->store((longlong) tzid, TRUE); + DBUG_ASSERT(field->key_length() <= sizeof(keybuff)); + field->get_key_image(keybuff, + min(field->key_length(), sizeof(keybuff)), + Field::itRAW); (void)table->file->ha_index_init(0, 1); - res= table->file->index_read_map(table->record[0], table->field[0]->ptr, - (key_part_map)1, HA_READ_KEY_EXACT); + res= table->file->ha_index_read_map(table->record[0], keybuff, + (key_part_map)1, HA_READ_KEY_EXACT); while (!res) { ttid= (uint)table->field[1]->val_int(); @@ -1970,8 +1982,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) tmp_tz_info.typecnt= ttid + 1; - res= table->file->index_next_same(table->record[0], - table->field[0]->ptr, 4); + res= table->file->ha_index_next_same(table->record[0], keybuff, 4); } if (res != HA_ERR_END_OF_FILE) @@ -1993,8 +2004,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) table->field[0]->store((longlong) tzid, TRUE); (void)table->file->ha_index_init(0, 1); - res= table->file->index_read_map(table->record[0], table->field[0]->ptr, - (key_part_map)1, HA_READ_KEY_EXACT); + res= table->file->ha_index_read_map(table->record[0], keybuff, + (key_part_map)1, HA_READ_KEY_EXACT); while (!res) { ttime= (my_time_t)table->field[1]->val_int(); @@ -2023,8 +2034,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u", tzid, (ulong) ttime, ttid)); - res= table->file->index_next_same(table->record[0], - table->field[0]->ptr, 4); + res= table->file->ha_index_next_same(table->record[0], keybuff, 4); } /* diff --git a/sql/unireg.cc b/sql/unireg.cc index a5d9edbf181..dde755462dd 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -25,11 +25,15 @@ */ #include "mysql_priv.h" +#include "create_options.h" #include <m_ctype.h> #include <assert.h> #define FCOMP 17 /* Bytes for a packed field */ +/* threshold for safe_alloca */ +#define ALLOCA_THRESHOLD 2048 + static uchar * pack_screens(List<Create_field> &create_fields, uint *info_length, uint *screens, bool small_file); static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info, @@ -108,6 +112,7 @@ bool mysql_create_frm(THD *thd, const char *file_name, ulong key_buff_length; File file; ulong filepos, data_offset; + uint options_len; uchar fileinfo[64],forminfo[288],*keybuff; uchar *screen_buff; char buff[128]; @@ -183,6 +188,18 @@ bool mysql_create_frm(THD *thd, const char *file_name, create_info->extra_size+= key_info[i].parser_name->length + 1; } + options_len= engine_table_options_frm_length(create_info->option_list, + create_fields, + keys, key_info); + DBUG_PRINT("info", ("Options length: %u", options_len)); + if (options_len) + { + create_info->table_options|= HA_OPTION_TEXT_CREATE_OPTIONS; + create_info->extra_size+= (options_len + 4); + } + else + create_info->table_options&= ~HA_OPTION_TEXT_CREATE_OPTIONS; + if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo, create_info, keys)) < 0) { @@ -302,6 +319,7 @@ bool mysql_create_frm(THD *thd, const char *file_name, if (my_write(file, (uchar*) buff, 6, MYF_RW)) goto err; } + for (i= 0; i < keys; i++) { if (key_info[i].parser_name) @@ -312,6 +330,24 @@ bool mysql_create_frm(THD *thd, const char *file_name, } } + if (options_len) + { + uchar *optbuff= (uchar *)my_safe_alloca(options_len + 4, ALLOCA_THRESHOLD); + my_bool error; + DBUG_PRINT("info", ("Create options length: %u", options_len)); + if (!optbuff) + goto err; + int4store(optbuff, options_len); + engine_table_options_frm_image(optbuff + 4, + create_info->option_list, + create_fields, + keys, key_info); + error= my_write(file, optbuff, options_len + 4, MYF_RW); + my_safe_afree(optbuff, options_len + 4, ALLOCA_THRESHOLD); + if (error) + goto err; + } + VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0))); if (my_write(file, forminfo, 288, MYF_RW) || my_write(file, screen_buff, info_length, MYF_RW) || @@ -591,7 +627,7 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, { uint length,int_count,int_length,no_empty, int_parts; uint time_stamp_pos,null_fields; - ulong reclength, totlength, n_length, com_length; + ulong reclength, totlength, n_length, com_length, vcol_info_length; DBUG_ENTER("pack_header"); if (create_fields.elements > MAX_FIELDS) @@ -602,8 +638,8 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, totlength= 0L; reclength= data_offset; - no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields= - com_length=0; + no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields=0; + com_length=vcol_info_length=0; n_length=2L; /* Check fields */ @@ -632,6 +668,30 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, field->field_name, static_cast<ulong>(tmp_len)); field->comment.length= tmp_len; } + if (field->vcol_info) + { + tmp_len= + system_charset_info->cset->charpos(system_charset_info, + field->vcol_info->expr_str.str, + field->vcol_info->expr_str.str + + field->vcol_info->expr_str.length, + VIRTUAL_COLUMN_EXPRESSION_MAXLEN); + + if (tmp_len < field->vcol_info->expr_str.length) + { + my_error(ER_WRONG_STRING_LENGTH, MYF(0), + field->vcol_info->expr_str.str,"VIRTUAL COLUMN EXPRESSION", + (uint) VIRTUAL_COLUMN_EXPRESSION_MAXLEN); + DBUG_RETURN(1); + } + /* + Sum up the length of the expression string and the length of the + mandatory header to the total length of info on the defining + expressions saved in the frm file for virtual columns. + */ + vcol_info_length+= field->vcol_info->expr_str.length+ + (uint)FRM_VCOL_HEADER_SIZE; + } totlength+= field->length; com_length+= field->comment.length; @@ -651,8 +711,6 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, !time_stamp_pos) time_stamp_pos= (uint) field->offset+ (uint) data_offset + 1; length=field->pack_length; - /* Ensure we don't have any bugs when generating offsets */ - DBUG_ASSERT(reclength == field->offset + data_offset); if ((uint) field->offset+ (uint) data_offset+ length > reclength) reclength=(uint) (field->offset+ data_offset + length); n_length+= (ulong) strlen(field->field_name)+1; @@ -719,7 +777,8 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, /* Hack to avoid bugs with small static rows in MySQL */ reclength=max(file->min_record_length(table_options),reclength); if (info_length+(ulong) create_fields.elements*FCOMP+288+ - n_length+int_length+com_length > 65535L || int_count > 255) + n_length+int_length+com_length+vcol_info_length > 65535L || + int_count > 255) { my_message(ER_TOO_MANY_FIELDS, ER(ER_TOO_MANY_FIELDS), MYF(0)); DBUG_RETURN(1); @@ -727,7 +786,7 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, bzero((char*)forminfo,288); length=(info_length+create_fields.elements*FCOMP+288+n_length+int_length+ - com_length); + com_length+vcol_info_length); int2store(forminfo,length); forminfo[256] = (uint8) screens; int2store(forminfo+258,create_fields.elements); @@ -744,7 +803,8 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, int2store(forminfo+280,22); /* Rows needed */ int2store(forminfo+282,null_fields); int2store(forminfo+284,com_length); - /* Up to forminfo+288 is free to use for additional information */ + int2store(forminfo+286,vcol_info_length); + /* forminfo+288 is free to use for additional information */ DBUG_RETURN(0); } /* pack_header */ @@ -783,7 +843,7 @@ static bool pack_fields(File file, List<Create_field> &create_fields, ulong data_offset) { reg2 uint i; - uint int_count, comment_length=0; + uint int_count, comment_length= 0, vcol_info_length=0; uchar buff[MAX_FIELD_WIDTH]; Create_field *field; DBUG_ENTER("pack_fields"); @@ -796,6 +856,7 @@ static bool pack_fields(File file, List<Create_field> &create_fields, while ((field=it++)) { uint recpos; + uint cur_vcol_expr_len= 0; buff[0]= (uchar) field->row; buff[1]= (uchar) field->col; buff[2]= (uchar) field->sc_length; @@ -818,6 +879,17 @@ static bool pack_fields(File file, List<Create_field> &create_fields, buff[14]= (uchar) field->charset->number; else buff[14]= 0; // Numerical + if (field->vcol_info) + { + /* + Use the interval_id place in the .frm file to store the length of + the additional data saved for the virtual field + */ + buff[12]= cur_vcol_expr_len= field->vcol_info->expr_str.length + + (uint)FRM_VCOL_HEADER_SIZE; + vcol_info_length+= cur_vcol_expr_len+(uint)FRM_VCOL_HEADER_SIZE; + buff[13]= (uchar) MYSQL_TYPE_VIRTUAL; + } int2store(buff+15, field->comment.length); comment_length+= field->comment.length; set_if_bigger(int_count,field->interval_id); @@ -912,6 +984,34 @@ static bool pack_fields(File file, List<Create_field> &create_fields, DBUG_RETURN(1); } } + if (vcol_info_length) + { + it.rewind(); + int_count=0; + while ((field=it++)) + { + /* + Pack each virtual field as follows: + byte 1 = 1 (always 1 to allow for future extensions) + byte 2 = sql_type + byte 3 = flags (as of now, 0 - no flags, 1 - field is physically stored) + byte 4-... = virtual column expression (text data) + */ + if (field->vcol_info && field->vcol_info->expr_str.length) + { + buff[0]= (uchar)1; + buff[1]= (uchar) field->sql_type; + buff[2]= (uchar) field->stored_in_db; + if (my_write(file, buff, 3, MYF_RW)) + DBUG_RETURN(1); + if (my_write(file, + (uchar*) field->vcol_info->expr_str.str, + field->vcol_info->expr_str.length, + MYF_RW)) + DBUG_RETURN(1); + } + } + } DBUG_RETURN(0); } diff --git a/sql/unireg.h b/sql/unireg.h index fd9d4e846bc..33cd5d1006d 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -213,6 +213,13 @@ #define DEFAULT_KEY_CACHE_NAME "default" +/* The length of the header part for each virtual column in the .frm file */ +#define FRM_VCOL_HEADER_SIZE 3 + +/* Maximum length of the defining expression for a virtual columns */ +#define VIRTUAL_COLUMN_EXPRESSION_MAXLEN 255 - FRM_VCOL_HEADER_SIZE + + /* Include prototypes for unireg */ #include "mysqld_error.h" diff --git a/sql/winservice.c b/sql/winservice.c new file mode 100644 index 00000000000..562f047fa79 --- /dev/null +++ b/sql/winservice.c @@ -0,0 +1,247 @@ +/* + Get Properties of an existing mysqld Windows service +*/ + +#include <windows.h> +#include <winsvc.h> +#include "winservice.h" +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + + +/* + Get version from an executable file +*/ +void get_file_version(const char *path, int *major, int *minor, int *patch) +{ + DWORD version_handle; + char *ver= 0; + VS_FIXEDFILEINFO info; + UINT len; + DWORD size; + void *p; + *major= *minor= *patch= 0; + + size= GetFileVersionInfoSize(path, &version_handle); + if (size == 0) + return; + ver= (char *)malloc(size); + if(!GetFileVersionInfo(path, version_handle, size, ver)) + goto end; + + if(!VerQueryValue(ver,"\\",&p,&len)) + goto end; + memcpy(&info,p ,sizeof(VS_FIXEDFILEINFO)); + + *major= (info.dwFileVersionMS & 0xFFFF0000) >> 16; + *minor= (info.dwFileVersionMS & 0x0000FFFF); + *patch= (info.dwFileVersionLS & 0xFFFF0000) >> 16; +end: + free(ver); +} + +void normalize_path(char *path, size_t size) +{ + char buf[MAX_PATH]; + if (*path== '"') + { + char *p; + strcpy_s(buf, MAX_PATH, path+1); + p= strchr(buf, '"'); + if (p) + *p=0; + } + else + strcpy_s(buf, MAX_PATH, path); + GetFullPathName(buf, MAX_PATH, buf, NULL); + strcpy_s(path, size, buf); +} + +/* + Retrieve some properties from windows mysqld service binary path. + We're interested in ini file location and datadir, and also in version of + the data. We tolerate missing mysqld.exe. + + Note that this function carefully avoids using mysql libraries (e.g dbug), + since it is used in unusual environments (windows installer, MFC), where we + do not have much control over how threads are created and destroyed, so we + cannot assume MySQL thread initilization here. +*/ +int get_mysql_service_properties(const wchar_t *bin_path, + mysqld_service_properties *props) +{ + int numargs; + wchar_t mysqld_path[MAX_PATH + 4]; + wchar_t *file_part; + wchar_t **args= NULL; + int retval= 1; + BOOL have_inifile; + + props->datadir[0]= 0; + props->inifile[0]= 0; + props->mysqld_exe[0]= 0; + props->version_major= 0; + props->version_minor= 0; + props->version_patch= 0; + + args= CommandLineToArgvW(bin_path, &numargs); + if(numargs == 2) + { + /* + There are rare cases where service config does not have + --defaults-filein the binary parth . There services were registered with + plain mysqld --install, the data directory is next to "bin" in this case. + Service name (second parameter) must be MySQL. + */ + if(wcscmp(args[1], L"MySQL") != 0) + goto end; + have_inifile= FALSE; + } + else if(numargs == 3) + { + have_inifile= TRUE; + } + else + { + goto end; + } + + if(have_inifile && wcsncmp(args[1], L"--defaults-file=", 16) != 0) + goto end; + + GetFullPathNameW(args[0], MAX_PATH, mysqld_path, &file_part); + + if(wcsstr(mysqld_path, L".exe") == NULL) + wcscat(mysqld_path, L".exe"); + + if(wcsicmp(file_part, L"mysqld.exe") != 0 && + wcsicmp(file_part, L"mysqld.exe") != 0 && + wcsicmp(file_part, L"mysqld-nt.exe") != 0) + { + /* The service executable is not mysqld. */ + goto end; + } + + wcstombs(props->mysqld_exe, mysqld_path, MAX_PATH); + /* If mysqld.exe exists, try to get its version from executable */ + if (GetFileAttributes(props->mysqld_exe) != INVALID_FILE_ATTRIBUTES) + { + get_file_version(props->mysqld_exe, &props->version_major, + &props->version_minor, &props->version_patch); + } + + if (have_inifile) + { + /* We have --defaults-file in service definition. */ + wcstombs(props->inifile, args[1]+16, MAX_PATH); + normalize_path(props->inifile, MAX_PATH); + if (GetFileAttributes(props->inifile) != INVALID_FILE_ATTRIBUTES) + { + GetPrivateProfileString("mysqld", "datadir", NULL, props->datadir, MAX_PATH, + props->inifile); + } + else + { + /* + Service will start even with invalid .ini file, using lookup for + datadir relative to mysqld.exe. This is equivalent to the case no ini + file used. + */ + props->inifile[0]= 0; + have_inifile= FALSE; + } + } + + if(!have_inifile) + { + /* + Hard, although a rare case, we're guessing datadir and defaults-file. + On Windows, defaults-file is traditionally install-root\my.ini + and datadir is install-root\data + */ + char install_root[MAX_PATH]; + int i; + char *p; + + /* + Get the install root(parent of bin directory where mysqld.exe) + is located. + */ + strcpy_s(install_root, MAX_PATH, props->mysqld_exe); + for (i=0; i< 2; i++) + { + p= strrchr(install_root, '\\'); + if(!p) + goto end; + *p= 0; + } + + /* Look for my.ini, my.cnf in the install root */ + sprintf_s(props->inifile, MAX_PATH, "%s\\my.ini", install_root); + if (GetFileAttributes(props->inifile) == INVALID_FILE_ATTRIBUTES) + { + sprintf_s(props->inifile, MAX_PATH, "%s\\my.cnf", install_root); + } + if (GetFileAttributes(props->inifile) != INVALID_FILE_ATTRIBUTES) + { + /* Ini file found, get datadir from there */ + GetPrivateProfileString("mysqld", "datadir", NULL, props->datadir, + MAX_PATH, props->inifile); + } + else + { + /* No ini file */ + props->inifile[0]= 0; + } + + /* Try datadir in install directory.*/ + if (props->datadir[0] == 0) + { + sprintf_s(props->datadir, MAX_PATH, "%s\\data", install_root); + } + } + + if (props->datadir[0]) + { + normalize_path(props->datadir, MAX_PATH); + /* Check if datadir really exists */ + if (GetFileAttributes(props->datadir) == INVALID_FILE_ATTRIBUTES) + goto end; + } + else + { + /* There is no datadir in ini file, bail out.*/ + goto end; + } + + /* + If version could not be determined so far, try mysql_upgrade_info in + database directory. + */ + if(props->version_major == 0) + { + char buf[MAX_PATH]; + FILE *mysql_upgrade_info; + + sprintf_s(buf, MAX_PATH, "%s\\mysql_upgrade_info", props->datadir); + mysql_upgrade_info= fopen(buf, "r"); + if(mysql_upgrade_info) + { + if (fgets(buf, MAX_PATH, mysql_upgrade_info)) + { + int major,minor,patch; + if (sscanf(buf, "%d.%d.%d", &major, &minor, &patch) == 3) + { + props->version_major= major; + props->version_minor= minor; + props->version_patch= patch; + } + } + } + } + retval = 0; +end: + LocalFree((HLOCAL)args); + return retval; +}
\ No newline at end of file diff --git a/sql/winservice.h b/sql/winservice.h new file mode 100644 index 00000000000..8957413783f --- /dev/null +++ b/sql/winservice.h @@ -0,0 +1,24 @@ +/*
+ Extract properties of a windows service binary path
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <windows.h>
+typedef struct mysqld_service_properties_st
+{
+ char mysqld_exe[MAX_PATH];
+ char inifile[MAX_PATH];
+ char datadir[MAX_PATH];
+ int version_major;
+ int version_minor;
+ int version_patch;
+} mysqld_service_properties;
+
+extern int get_mysql_service_properties(const wchar_t *bin_path,
+ mysqld_service_properties *props);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/archive/archive_reader.c b/storage/archive/archive_reader.c index 53c304559b0..9bce82208fd 100644 --- a/storage/archive/archive_reader.c +++ b/storage/archive/archive_reader.c @@ -108,12 +108,16 @@ int main(int argc, char *argv[]) printf("\tFRM length %u\n", reader_handle.frm_length); if (reader_handle.comment_start_pos) { - char *comment = - (char *) malloc(sizeof(char) * reader_handle.comment_length); - azread_comment(&reader_handle, comment); - printf("\tComment length %u\n\t\t%.*s\n", reader_handle.comment_length, - reader_handle.comment_length, comment); - free(comment); + char *comment = (char *) my_malloc(reader_handle.comment_length, + MYF(MY_WME)); + if (comment) + { + azread_comment(&reader_handle, comment); + printf("\tComment length %u\n\t\t%.*s\n", + reader_handle.comment_length, + reader_handle.comment_length, comment); + my_free(comment,MYF(0)); + } } } else @@ -195,7 +199,7 @@ int main(int argc, char *argv[]) azio_stream writer_handle; - buffer= (char *)malloc(reader_handle.longest_row); + buffer= (char *) my_malloc(reader_handle.longest_row, MYF(0)); if (buffer == NULL) { printf("Could not allocate memory for row %llu\n", row_count); @@ -266,7 +270,7 @@ int main(int argc, char *argv[]) break; } - free(buffer); + my_free(buffer, MYF(0)); azclose(&writer_handle); } diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index ec26ef65321..deee52749e0 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -360,6 +360,7 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc) { *rc= my_errno ? my_errno : -1; pthread_mutex_unlock(&archive_mutex); + pthread_mutex_destroy(&share->mutex); my_free(share, MYF(0)); DBUG_RETURN(NULL); } @@ -837,7 +838,7 @@ int ha_archive::write_row(uchar *buf) if (!share->archive_write_open) if (init_archive_writer()) - DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + DBUG_RETURN(errno); if (table->next_number_field && record == table->record[0]) @@ -1022,7 +1023,8 @@ int ha_archive::rnd_init(bool scan) if (share->crashed) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); - init_archive_reader(); + if (init_archive_reader()) + DBUG_RETURN(errno); /* We rewind the file so that we can read from the beginning if scan */ if (scan) @@ -1313,12 +1315,14 @@ int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt) */ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) { - DBUG_ENTER("ha_archive::optimize"); int rc= 0; azio_stream writer; char writer_filename[FN_REFLEN]; + char* frm_string; + DBUG_ENTER("ha_archive::optimize"); - init_archive_reader(); + if (init_archive_reader()) + DBUG_RETURN(errno); // now we close both our writer and our reader for the rename if (share->archive_write_open) @@ -1327,12 +1331,28 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) share->archive_write_open= FALSE; } + if (!(frm_string= (char*) my_malloc(archive.frm_length, MYF(0)))) + return ENOMEM; + + azread_frm(&archive, frm_string); + /* Lets create a file to contain the new data */ fn_format(writer_filename, share->table_name, "", ARN, MY_REPLACE_EXT | MY_UNPACK_FILENAME); if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR|O_BINARY))) - DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + { + my_free(frm_string, MYF(0)); + DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + } + + rc= azwrite_frm(&writer, frm_string, archive.frm_length); + my_free(frm_string, MYF(0)); + if (rc) + { + rc= HA_ERR_CRASHED_ON_USAGE; + goto error; + } /* An extended rebuild is a lot more effort. We open up each row and re-record it. @@ -1410,7 +1430,6 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) // make the file we just wrote be our data file rc = my_rename(writer_filename,share->data_file_name,MYF(0)); - DBUG_RETURN(rc); error: DBUG_PRINT("ha_archive", ("Failed to recover, error was %d", rc)); @@ -1533,7 +1552,9 @@ int ha_archive::info(uint flag) if (flag & HA_STATUS_AUTO) { - init_archive_reader(); + if (init_archive_reader()) + DBUG_RETURN(errno); + pthread_mutex_lock(&share->mutex); azflush(&archive, Z_SYNC_FLUSH); pthread_mutex_unlock(&share->mutex); @@ -1614,6 +1635,9 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt) Now we will rewind the archive file so that we are positioned at the start of the file. */ + if (init_archive_reader()) + DBUG_RETURN(errno); + read_data_header(&archive); while (!(rc= get_row(&archive, table->record[0]))) count--; @@ -1691,4 +1715,21 @@ mysql_declare_plugin(archive) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(archive) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &archive_storage_engine, + "ARCHIVE", + "Brian Aker, MySQL AB", + "Archive storage engine", + PLUGIN_LICENSE_GPL, + archive_db_init, /* Plugin Init */ + archive_db_done, /* Plugin Deinit */ + 0x0300 /* 3.0 */, + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index b13cdab7a3a..5f4f954763a 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -372,3 +372,20 @@ mysql_declare_plugin(blackhole) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(blackhole) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &blackhole_storage_engine, + "BLACKHOLE", + "MySQL AB", + "/dev/null storage engine (anything you write to it disappears)", + PLUGIN_LICENSE_GPL, + blackhole_init, /* Plugin Init */ + blackhole_fini, /* Plugin Deinit */ + 0x0100 /* 1.0 */, + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 3a6b2b1578c..f1b081be8d4 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -1653,4 +1653,20 @@ mysql_declare_plugin(csv) NULL /* config options */ } mysql_declare_plugin_end; - +maria_declare_plugin(csv) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &csv_storage_engine, + "CSV", + "Brian Aker, MySQL AB", + "CSV storage engine", + PLUGIN_LICENSE_GPL, + tina_init_func, /* Plugin Init */ + tina_done_func, /* Plugin Deinit */ + 0x0100 /* 1.0 */, + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/example/Makefile.am b/storage/example/Makefile.am index 6d962d8cd16..1ef7d9fc86e 100644 --- a/storage/example/Makefile.am +++ b/storage/example/Makefile.am @@ -34,7 +34,7 @@ noinst_HEADERS = ha_example.h EXTRA_LTLIBRARIES = libexample.la ha_example.la pkgplugin_LTLIBRARIES = @plugin_example_shared_target@ -ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir) +ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices ha_example_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_example_la_SOURCES = ha_example.cc diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index da6abc40bc6..067bd00cdbf 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -115,6 +115,82 @@ static HASH example_open_tables; /* The mutex used to init the hash; variable for example share methods */ pthread_mutex_t example_mutex; + +/** + Structure for CREATE TABLE options (table options). + It needs to be called ha_table_option_struct. + + The option values can be specified in the CREATE TABLE at the end: + CREATE TABLE ( ... ) *here* +*/ + +struct ha_table_option_struct +{ + const char *strparam; + ulonglong ullparam; + uint enumparam; + bool boolparam; +}; + + +/** + Structure for CREATE TABLE options (field options). + It needs to be called ha_field_option_struct. + + The option values can be specified in the CREATE TABLE per field: + CREATE TABLE ( field ... *here*, ... ) +*/ + +struct ha_field_option_struct +{ + const char *complex_param_to_parse_it_in_engine; +}; + +/* + no example here, but index options can be declared similarly + using the ha_index_option_struct structure. + + Their values can be specified in the CREATE TABLE per index: + CREATE TABLE ( field ..., .., INDEX .... *here*, ... ) +*/ + +ha_create_table_option example_table_option_list[]= +{ + /* + one numeric option, with the default of UINT_MAX32, valid + range of values 0..UINT_MAX32, and a "block size" of 10 + (any value must be divisible by 10). + */ + HA_TOPTION_NUMBER("ULL", ullparam, UINT_MAX32, 0, UINT_MAX32, 10), + /* + one option that takes an arbitrary string + */ + HA_TOPTION_STRING("STR", strparam), + /* + one enum option. a valid values are strings ONE and TWO. + A default value is 0, that is "one". + */ + HA_TOPTION_ENUM("one_or_two", enumparam, "one,two", 0), + /* + one boolean option, the valid values are YES/NO, ON/OFF, 1/0. + The default is 1, that is true, yes, on. + */ + HA_TOPTION_BOOL("YESNO", boolparam, 1), + HA_TOPTION_END +}; + +ha_create_table_option example_field_option_list[]= +{ + /* + If the engine wants something more complex than a string, number, enum, + or boolean - for example a list - it needs to specify the option + as a string and parse it internally. + */ + HA_FOPTION_STRING("COMPLEX", complex_param_to_parse_it_in_engine), + HA_FOPTION_END +}; + + /** @brief Function we use in the creation of our hash to get key. @@ -140,6 +216,8 @@ static int example_init_func(void *p) example_hton->state= SHOW_OPTION_YES; example_hton->create= example_create_handler; example_hton->flags= HTON_CAN_RECREATE; + example_hton->table_options= example_table_option_list; + example_hton->field_options= example_field_option_list; DBUG_RETURN(0); } @@ -297,6 +375,16 @@ int ha_example::open(const char *name, int mode, uint test_if_locked) DBUG_RETURN(1); thr_lock_data_init(&share->lock,&lock,NULL); +#ifndef DBUG_OFF + ha_table_option_struct *options= table->s->option_struct; + + DBUG_ASSERT(options); + DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\ + "boolparam: %u", + (options->strparam ? options->strparam : "<NULL>"), + options->ullparam, options->enumparam, options->boolparam)); +#endif + DBUG_RETURN(0); } @@ -509,7 +597,7 @@ int ha_example::index_last(uchar *buf) int ha_example::rnd_init(bool scan) { DBUG_ENTER("ha_example::rnd_init"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + DBUG_RETURN(0); } int ha_example::rnd_end() @@ -776,27 +864,6 @@ int ha_example::delete_table(const char *name) /** @brief - Renames a table from one name to another via an alter table call. - - @details - If you do not implement this, the default rename_table() is called from - handler.cc and it will delete all files with the file extensions returned - by bas_ext(). - - Called from sql_table.cc by mysql_rename_table(). - - @see - mysql_rename_table() in sql_table.cc -*/ -int ha_example::rename_table(const char * from, const char * to) -{ - DBUG_ENTER("ha_example::rename_table "); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); -} - - -/** - @brief Given a starting key and an ending key, estimate the number of rows that will exist between the two keys. @@ -838,15 +905,103 @@ ha_rows ha_example::records_in_range(uint inx, key_range *min_key, int ha_example::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) { +#ifndef DBUG_OFF + ha_table_option_struct *options= table_arg->s->option_struct; DBUG_ENTER("ha_example::create"); /* - This is not implemented but we want someone to be able to see that it - works. + This example shows how to support custom engine specific table and field + options. */ + DBUG_ASSERT(options); + DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\ + "boolparam: %u", + (options->strparam ? options->strparam : "<NULL>"), + options->ullparam, options->enumparam, options->boolparam)); + for (Field **field= table_arg->s->field; *field; field++) + { + ha_field_option_struct *field_options= (*field)->option_struct; + DBUG_ASSERT(field_options); + DBUG_PRINT("info", ("field: %s complex: '%-.64s'", + (*field)->field_name, + (field_options->complex_param_to_parse_it_in_engine ? + field_options->complex_param_to_parse_it_in_engine : + "<NULL>"))); + } +#endif DBUG_RETURN(0); } +/** + check_if_incompatible_data() called if ALTER TABLE can't detect otherwise + if new and old definition are compatible + + @details If there are no other explicit signs like changed number of + fields this function will be called by compare_tables() + (sql/sql_tables.cc) to decide should we rewrite whole table or only .frm + file. + +*/ + +bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info, + uint table_changes) +{ + ha_table_option_struct *param_old, *param_new; + uint i; + DBUG_ENTER("ha_example::check_if_incompatible_data"); + /* + This example shows how custom engine specific table and field + options can be accessed from this function to be compared. + */ + param_new= info->option_struct; + DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u " + "boolparam: %u", + (param_new->strparam ? param_new->strparam : "<NULL>"), + param_new->ullparam, param_new->enumparam, + param_new->boolparam)); + + param_old= table->s->option_struct; + DBUG_PRINT("info", ("old strparam: '%-.64s' ullparam: %llu enumparam: %u " + "boolparam: %u", + (param_old->strparam ? param_old->strparam : "<NULL>"), + param_old->ullparam, param_old->enumparam, + param_old->boolparam)); + + /* + check important parameters: + for this example engine, we'll assume that changing ullparam or + boolparam requires a table to be rebuilt, while changing strparam + or enumparam - does not. + */ + if (param_new->ullparam != param_old->ullparam || + param_new->boolparam != param_old->boolparam) + DBUG_RETURN(COMPATIBLE_DATA_NO); + + for (i= 0; i < table->s->fields; i++) + { + ha_field_option_struct *f_old, *f_new; + f_old= table->s->field[i]->option_struct; + DBUG_ASSERT(f_old); + DBUG_PRINT("info", ("old field: %u old complex: '%-.64s'", i, + (f_old->complex_param_to_parse_it_in_engine ? + f_old->complex_param_to_parse_it_in_engine : + "<NULL>"))); + if (info->fields_option_struct[i]) + { + f_new= info->fields_option_struct[i]; + DBUG_PRINT("info", ("old field: %u new complex: '%-.64s'", i, + (f_new->complex_param_to_parse_it_in_engine ? + f_new->complex_param_to_parse_it_in_engine : + "<NULL>"))); + } + else + DBUG_PRINT("info", ("old field %i did not changed", i)); + } + + DBUG_RETURN(COMPATIBLE_DATA_YES); +} + + struct st_mysql_storage_engine example_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; @@ -892,6 +1047,24 @@ static struct st_mysql_sys_var* example_system_variables[]= { NULL }; +// this is an example of SHOW_FUNC and of my_snprintf() service +static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var, + char *buf) +{ + var->type= SHOW_CHAR; + var->value= buf; // it's of SHOW_VAR_FUNC_BUFF_SIZE bytes + my_snprintf(buf, SHOW_VAR_FUNC_BUFF_SIZE, + "enum_var is %u, ulong_var is %lu, %.6b", // %b is MySQL extension + srv_enum_var, srv_ulong_var, "really"); + return 0; +} + +static struct st_mysql_show_var func_status[]= +{ + {"example_func_example", (char *)show_func_example, SHOW_FUNC}, + {0,0,SHOW_UNDEF} +}; + mysql_declare_plugin(example) { MYSQL_STORAGE_ENGINE_PLUGIN, @@ -903,8 +1076,25 @@ mysql_declare_plugin(example) example_init_func, /* Plugin Init */ example_done_func, /* Plugin Deinit */ 0x0001 /* 0.1 */, - NULL, /* status variables */ + func_status, /* status variables */ example_system_variables, /* system variables */ NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(example) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &example_storage_engine, + "EXAMPLE", + "Brian Aker, MySQL AB", + "Example storage engine", + PLUGIN_LICENSE_GPL, + example_init_func, /* Plugin Init */ + example_done_func, /* Plugin Deinit */ + 0x0001 /* 0.1 */, + func_status, /* status variables */ + example_system_variables, /* system variables */ + "0.1", /* string version */ + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h index a5ae2d3482c..79e1c422b95 100644 --- a/storage/example/ha_example.h +++ b/storage/example/ha_example.h @@ -245,9 +245,10 @@ public: ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); int delete_table(const char *from); - int rename_table(const char * from, const char * to); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); ///< required + bool check_if_incompatible_data(HA_CREATE_INFO *info, + uint table_changes); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); ///< required diff --git a/storage/federated/Makefile.am b/storage/federated/Makefile.am index 31778a24550..b4ee202cab3 100644 --- a/storage/federated/Makefile.am +++ b/storage/federated/Makefile.am @@ -32,7 +32,8 @@ noinst_HEADERS = ha_federated.h EXTRA_LTLIBRARIES = libfederated.la libfederated_embedded.la ha_federated.la pkgplugin_LTLIBRARIES = @plugin_federated_shared_target@ -ha_federated_la_LDFLAGS = -module -rpath $(pkgplugindir) +ha_federated_la_LDFLAGS = -module -rpath $(pkgplugindir) \ + -L$(top_builddir)/libservices -lmysqlservices ha_federated_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_federated_la_CFLAGS = -shared $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_federated_la_SOURCES = ha_federated.cc $(top_srcdir)/mysys/string.c diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 27e4d787766..40d33bde457 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -3409,3 +3409,20 @@ mysql_declare_plugin(federated) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(federated) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &federated_storage_engine, + "FEDERATED", + "Patrick Galbraith and Brian Aker, MySQL AB", + "Federated MySQL storage engine", + PLUGIN_LICENSE_GPL, + federated_db_init, /* Plugin Init */ + federated_done, /* Plugin Deinit */ + 0x0100 /* 1.0 */, + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_BETA /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/federatedx/Makefile.am b/storage/federatedx/Makefile.am index 9296e9e00ea..8dd6770e03f 100644 --- a/storage/federatedx/Makefile.am +++ b/storage/federatedx/Makefile.am @@ -19,7 +19,8 @@ noinst_HEADERS = ha_federatedx.h federatedx_probes.h EXTRA_LTLIBRARIES = libfederatedx.la libfederatedx_common.la libfederatedx_embedded.la ha_federatedx.la pkgplugin_LTLIBRARIES = @plugin_federatedx_shared_target@ -ha_federatedx_la_LDFLAGS = -module -rpath $(pkgplugindir) +ha_federatedx_la_LDFLAGS = -module -rpath $(pkgplugindir) \ + -L$(top_builddir)/libservices -lmysqlservices ha_federatedx_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 6a52b0a5e85..d97588dcc3d 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -1455,7 +1455,8 @@ static void fill_server(MEM_ROOT *mem_root, FEDERATEDX_SERVER *server, key.append(password); server->key_length= key.length(); - server->key= (uchar *) memdup_root(mem_root, key.ptr(), key.length()+1); + /* Copy and add end \0 */ + server->key= (uchar *) strmake_root(mem_root, key.ptr(), key.length()); /* pointer magic */ server->scheme+= (intptr) server->key; @@ -1584,7 +1585,7 @@ static FEDERATEDX_SHARE *get_share(const char *table_name, TABLE *table) if (!(share= (FEDERATEDX_SHARE *) memdup_root(&mem_root, (char*)&tmp_share, sizeof(*share))) || !(share->share_key= (char*) memdup_root(&mem_root, tmp_share.share_key, tmp_share.share_key_length+1)) || - !(share->select_query= (char*) strmake_root(&mem_root, query.ptr(), query.length() + 1))) + !(share->select_query= (char*) strmake_root(&mem_root, query.ptr(), query.length()))) goto error; share->mem_root= mem_root; @@ -3437,11 +3438,13 @@ bool ha_federatedx::get_error_message(int error, String* buf) buf->qs_append(remote_error_number); buf->append(STRING_WITH_LEN(": ")); buf->append(remote_error_buf); + /* Ensure string ends with \0 */ + (void) buf->c_ptr_safe(); remote_error_number= 0; remote_error_buf[0]= '\0'; } - DBUG_PRINT("exit", ("message: %s", buf->ptr())); + DBUG_PRINT("exit", ("message: %s", buf->c_ptr_safe())); DBUG_RETURN(FALSE); } @@ -3581,9 +3584,26 @@ mysql_declare_plugin(federatedx) PLUGIN_LICENSE_GPL, federatedx_db_init, /* Plugin Init */ federatedx_done, /* Plugin Deinit */ - 0x0100 /* 1.0 */, + 0x0200 /* 2.0 */, NULL, /* status variables */ NULL, /* system variables */ NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(federatedx) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &federatedx_storage_engine, + "FEDERATED", + "Patrick Galbraith", + "FederatedX pluggable storage engine", + PLUGIN_LICENSE_GPL, + federatedx_db_init, /* Plugin Init */ + federatedx_done, /* Plugin Deinit */ + 0x0200 /* 2.0 */, + NULL, /* status variables */ + NULL, /* system variables */ + "2.0", /* string version */ + MariaDB_PLUGIN_MATURITY_BETA /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index a640a129e82..a5d8679105a 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -770,3 +770,20 @@ mysql_declare_plugin(heap) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(heap) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &heap_storage_engine, + "MEMORY", + "MySQL AB", + "Hash based, stored in memory, useful for temporary tables", + PLUGIN_LICENSE_GPL, + heap_init, + NULL, + 0x0100, /* 1.0 */ + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index 5208d4676c3..f541d618c7b 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -85,8 +85,6 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1; /* fall_through */ case HA_KEYTYPE_VARTEXT1: - if (!my_binary_compare(keyinfo->seg[j].charset)) - keyinfo->flag|= HA_END_SPACE_KEY; keyinfo->flag|= HA_VAR_LENGTH_KEY; length+= 2; /* Save number of bytes used to store length */ @@ -96,8 +94,6 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, /* Case-insensitiveness is handled in coll->hash_sort */ /* fall_through */ case HA_KEYTYPE_VARTEXT2: - if (!my_binary_compare(keyinfo->seg[j].charset)) - keyinfo->flag|= HA_END_SPACE_KEY; keyinfo->flag|= HA_VAR_LENGTH_KEY; length+= 2; /* Save number of bytes used to store length */ @@ -111,8 +107,6 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, default: break; } - if (keyinfo->seg[j].flag & HA_END_SPACE_ARE_EQUAL) - keyinfo->flag|= HA_END_SPACE_KEY; } keyinfo->length= length; length+= keyinfo->rb_tree.size_of_element + diff --git a/storage/heap/hp_rkey.c b/storage/heap/hp_rkey.c index 6eeac6acd7b..27d1114770e 100644 --- a/storage/heap/hp_rkey.c +++ b/storage/heap/hp_rkey.c @@ -63,7 +63,7 @@ int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key, info->update= 0; DBUG_RETURN(my_errno); } - if (!(keyinfo->flag & HA_NOSAME) || (keyinfo->flag & HA_END_SPACE_KEY)) + if (!(keyinfo->flag & HA_NOSAME)) memcpy(info->lastkey, key, (size_t) keyinfo->length); } memcpy(record, pos, (size_t) share->reclength); diff --git a/storage/ibmdb2i/db2i_ioBuffers.h b/storage/ibmdb2i/db2i_ioBuffers.h index 350d854f055..8fb815ba3be 100644 --- a/storage/ibmdb2i/db2i_ioBuffers.h +++ b/storage/ibmdb2i/db2i_ioBuffers.h @@ -290,7 +290,7 @@ class IOAsyncReadBuffer : public IOReadBuffer Return a pointer to the next row in the table, where "next" is defined by the orientation. - @param orientaton + @param orientation @param[out] rrn The relative record number of the row returned. Not reliable if NULL is returned by this function. diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc index 39096be7848..f77927421d2 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.cc +++ b/storage/ibmdb2i/ha_ibmdb2i.cc @@ -1158,9 +1158,7 @@ int ha_ibmdb2i::rnd_init(bool scan) rrnAssocHandle= 0; - DBUG_RETURN(0); // MySQL sometimes does not check the return code, causing - // an assert in ha_rnd_end later on if we return a non-zero - // value here. + DBUG_RETURN(0); } int ha_ibmdb2i::rnd_end() @@ -3357,3 +3355,20 @@ mysql_declare_plugin(ibmdb2i) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(ibmdb2i) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &ibmdb2i_storage_engine, + "IBMDB2I", + "The IBM development team in Rochester, Minnesota", + "IBM DB2 for i Storage Engine", + PLUGIN_LICENSE_GPL, + ibmdb2i_init_func, /* Plugin Init */ + ibmdb2i_done_func, /* Plugin Deinit */ + 0x0100 /* 1.0 */, + NULL, /* status variables */ + ibmdb2i_system_variables, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_UNKNOWN /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/innodb_plugin/Makefile.am b/storage/innodb_plugin/Makefile.am index 965d5c128eb..846a6acef36 100644 --- a/storage/innodb_plugin/Makefile.am +++ b/storage/innodb_plugin/Makefile.am @@ -330,7 +330,7 @@ libinnobase_la_CFLAGS= $(AM_CFLAGS) EXTRA_LTLIBRARIES= libinnobase.la ha_innodb_plugin.la pkgplugin_LTLIBRARIES= @plugin_innodb_plugin_shared_target@ -ha_innodb_plugin_la_LDFLAGS= -module -rpath $(pkgplugindir) +ha_innodb_plugin_la_LDFLAGS= -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices ha_innodb_plugin_la_CXXFLAGS= -shared $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS) ha_innodb_plugin_la_CFLAGS= -shared $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) ha_innodb_plugin_la_SOURCES= $(libinnobase_la_SOURCES) diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 848c1b5c733..f3804d5e944 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -2706,7 +2706,7 @@ innobase_rollback_to_savepoint( /* TODO: use provided savepoint data area to store savepoint data */ - longlong2str((ulint)savepoint, name, 36); + longlong2str((ulint)savepoint, name, 36, 1); error = (int) trx_rollback_to_savepoint_for_mysql(trx, name, &mysql_binlog_cache_pos); @@ -2737,7 +2737,7 @@ innobase_release_savepoint( /* TODO: use provided savepoint data area to store savepoint data */ - longlong2str((ulint)savepoint, name, 36); + longlong2str((ulint)savepoint, name, 36, 1); error = (int) trx_release_savepoint_for_mysql(trx, name); @@ -2784,7 +2784,7 @@ innobase_savepoint( /* TODO: use provided savepoint data area to store savepoint data */ char name[64]; - longlong2str((ulint)savepoint,name,36); + longlong2str((ulint)savepoint,name,36,1); error = (int) trx_savepoint_for_mysql(trx, name, (ib_int64_t)0); diff --git a/storage/innodb_plugin/trx/trx0sys.c b/storage/innodb_plugin/trx/trx0sys.c index 352fa6af219..2aadcca2dae 100644 --- a/storage/innodb_plugin/trx/trx0sys.c +++ b/storage/innodb_plugin/trx/trx0sys.c @@ -1344,7 +1344,7 @@ trx_sys_print_mysql_binlog_offset_from_page( /* THESE ARE COPIED FROM NON-HOTBACKUP PART OF THE INNODB SOURCE TREE - (This code duplicaton should be fixed at some point!) + (This code duplication should be fixed at some point!) */ #define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */ diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt index ad3a64f9558..82a631d5086 100644 --- a/storage/maria/CMakeLists.txt +++ b/storage/maria/CMakeLists.txt @@ -20,7 +20,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/regex ${CMAKE_SOURCE_DIR}/extra/yassl/include) -SET(MARIA_SOURCES ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c +SET(ARIA_SOURCES ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c ma_rnext.c ma_rnext_same.c ma_search.c ma_page.c ma_key_recover.c ma_key.c ma_locking.c ma_state.c @@ -40,54 +40,45 @@ SET(MARIA_SOURCES ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c ha_maria.cc trnman.c lockman.c tablockman.c ma_rt_index.c ma_rt_key.c ma_rt_mbr.c ma_rt_split.c ma_sp_key.c ma_control_file.c ma_loghandler.c - ma_pagecache.c ma_pagecaches.c + ma_pagecache.c ma_pagecaches.c compat_aliases.cc compat_aliases.h ma_checkpoint.c ma_recovery.c ma_commit.c ma_pagecrc.c - ha_maria.h maria_def.h ma_recovery_util.c + ha_maria.h maria_def.h ma_recovery_util.c ma_servicethread.c ) -MYSQL_STORAGE_ENGINE(MARIA) +MYSQL_STORAGE_ENGINE(ARIA) IF(NOT SOURCE_SUBLIBS) - ADD_DEPENDENCIES(libmaria_s GenError) -ADD_EXECUTABLE(maria_ftdump maria_ftdump.c) -TARGET_LINK_LIBRARIES(maria_ftdump libmaria_s libmyisam_s mysys dbug strings zlib wsock32) + ADD_DEPENDENCIES(libaria_s GenError) -ADD_EXECUTABLE(maria_chk maria_chk.c) -TARGET_LINK_LIBRARIES(maria_chk libmaria_s libmyisam_s mysys dbug strings zlib wsock32) +MYSQL_ADD_EXECUTABLE(aria_ftdump maria_ftdump.c) +TARGET_LINK_LIBRARIES(aria_ftdump libaria_s libmyisam_s mysys dbug strings zlib wsock32) -ADD_EXECUTABLE(maria_read_log maria_read_log.c) -TARGET_LINK_LIBRARIES(maria_read_log libmaria_s libmyisam_s mysys dbug strings zlib wsock32) +MYSQL_ADD_EXECUTABLE(aria_chk maria_chk.c) +TARGET_LINK_LIBRARIES(aria_chk libaria_s libmyisam_s mysys dbug strings zlib wsock32) -ADD_EXECUTABLE(maria_pack maria_pack.c) -TARGET_LINK_LIBRARIES(maria_pack libmaria_s libmyisam_s mysys dbug strings zlib wsock32) +MYSQL_ADD_EXECUTABLE(aria_read_log maria_read_log.c) +TARGET_LINK_LIBRARIES(aria_read_log libaria_s libmyisam_s mysys dbug strings zlib wsock32) + +MYSQL_ADD_EXECUTABLE(aria_pack maria_pack.c) +TARGET_LINK_LIBRARIES(aria_pack libaria_s libmyisam_s mysys dbug strings zlib wsock32) + +MYSQL_ADD_EXECUTABLE(aria_dump_log maria_dump_log.c unittest/ma_loghandler_examples.c) +TARGET_LINK_LIBRARIES(aria_dump_log libaria_s libmyisam_s mysys dbug strings zlib wsock32) -ADD_EXECUTABLE(maria_dump_log maria_dump_log.c unittest/ma_loghandler_examples.c) -TARGET_LINK_LIBRARIES(maria_dump_log libmaria_s libmyisam_s mysys dbug strings zlib wsock32) ADD_EXECUTABLE(ma_test1 ma_test1.c) -TARGET_LINK_LIBRARIES(ma_test1 libmaria_s libmyisam_s mysys dbug strings zlib wsock32) +TARGET_LINK_LIBRARIES(ma_test1 libaria_s libmyisam_s mysys dbug strings zlib wsock32) ADD_EXECUTABLE(ma_test2 ma_test2.c) -TARGET_LINK_LIBRARIES(ma_test2 libmaria_s libmyisam_s mysys dbug strings zlib wsock32) +TARGET_LINK_LIBRARIES(ma_test2 libaria_s libmyisam_s mysys dbug strings zlib wsock32) ADD_EXECUTABLE(ma_test3 ma_test3.c) -TARGET_LINK_LIBRARIES(ma_test3 libmaria_s libmyisam_s mysys dbug strings zlib wsock32) +TARGET_LINK_LIBRARIES(ma_test3 libaria_s libmyisam_s mysys dbug strings zlib wsock32) ADD_EXECUTABLE(ma_rt_test ma_rt_test.c) -TARGET_LINK_LIBRARIES(ma_rt_test libmaria_s libmyisam_s mysys dbug strings zlib wsock32) +TARGET_LINK_LIBRARIES(ma_rt_test libaria_s libmyisam_s mysys dbug strings zlib wsock32) ADD_EXECUTABLE(ma_sp_test ma_sp_test.c) -TARGET_LINK_LIBRARIES(ma_sp_test libmaria_s libmyisam_s mysys dbug strings zlib wsock32) - -IF(EMBED_MANIFESTS) - MYSQL_EMBED_MANIFEST("maria_ftdump" "asInvoker") - MYSQL_EMBED_MANIFEST("maria_chk" "asInvoker") - MYSQL_EMBED_MANIFEST("maria_read_log" "asInvoker") - MYSQL_EMBED_MANIFEST("maria_pack" "asInvoker") -ENDIF(EMBED_MANIFESTS) - -INSTALL(TARGETS maria_ftdump maria_chk maria_read_log maria_pack maria_dump_log - DESTINATION bin COMPONENT runtime) - +TARGET_LINK_LIBRARIES(ma_sp_test libaria_s libmyisam_s mysys dbug strings zlib wsock32) ENDIF(NOT SOURCE_SUBLIBS) diff --git a/storage/maria/Makefile.am b/storage/maria/Makefile.am index 0444aa9c816..c2bb61e77dd 100644 --- a/storage/maria/Makefile.am +++ b/storage/maria/Makefile.am @@ -27,46 +27,49 @@ LDADD = DEFS = @DEFS@ -# "." is needed first because tests in unittest need libmaria +# "." is needed first because tests in unittest need libaria SUBDIRS = . unittest EXTRA_DIST = ma_test_all.sh ma_test_all.res ma_test_big.sh \ ma_ft_stem.c CMakeLists.txt plug.in ma_test_recovery pkgdata_DATA = -pkglib_LIBRARIES = libmaria.a -noinst_LTLIBRARIES = libmaria.la libmaria_s.la \ - @plugin_maria_embedded_static_target@ -EXTRA_LTLIBRARIES = libmaria_embedded.la -bin_PROGRAMS = maria_chk maria_pack maria_ftdump maria_read_log \ - maria_dump_log -maria_chk_DEPENDENCIES= $(LIBRARIES) +pkglib_LIBRARIES = libaria.a +noinst_LTLIBRARIES = libaria.la libaria_s.la \ + @plugin_aria_embedded_static_target@ +EXTRA_LTLIBRARIES = libaria_embedded.la +bin_PROGRAMS = aria_chk aria_pack aria_ftdump aria_read_log \ + aria_dump_log +aria_chk_DEPENDENCIES= $(LIBRARIES) # Only reason to link with libmyisam.a here is that it's where some fulltext -# pieces are (but soon we'll remove fulltext dependencies from Maria). +# pieces are (but soon we'll remove fulltext dependencies from Aria). # For now, it imposes that storage/myisam be built before storage/maria. -maria_chk_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +aria_chk_SOURCES= maria_chk.c +aria_chk_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -maria_pack_DEPENDENCIES=$(LIBRARIES) -maria_pack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +aria_pack_SOURCES= maria_pack.c +aria_pack_DEPENDENCIES=$(LIBRARIES) +aria_pack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -maria_read_log_DEPENDENCIES=$(LIBRARIES) -maria_read_log_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +aria_read_log_SOURCES= maria_read_log.c +aria_read_log_DEPENDENCIES=$(LIBRARIES) +aria_read_log_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -maria_dump_log_DEPENDENCIES=$(LIBRARIES) ma_loghandler.c -maria_dump_log_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.la \ +aria_dump_log_DEPENDENCIES=$(LIBRARIES) ma_loghandler.c +aria_dump_log_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -maria_dump_log_SOURCES= maria_dump_log.c unittest/ma_loghandler_examples.c +aria_dump_log_SOURCES= maria_dump_log.c unittest/ma_loghandler_examples.c noinst_PROGRAMS = ma_test1 ma_test2 ma_test3 ma_rt_test ma_sp_test noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h \ ma_sp_defs.h ma_fulltext.h ma_ftdefs.h ma_ft_test1.h \ @@ -75,46 +78,48 @@ noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h \ ma_loghandler.h ma_loghandler_lsn.h ma_pagecache.h \ ma_checkpoint.h ma_recovery.h ma_commit.h ma_state.h \ trnman_public.h ma_check_standalone.h \ - ma_key_recover.h ma_recovery_util.h + ma_key_recover.h ma_recovery_util.h \ + ma_servicethread.h compat_aliases.h ma_test1_DEPENDENCIES= $(LIBRARIES) -ma_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +ma_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ ma_test2_DEPENDENCIES= $(LIBRARIES) -ma_test2_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +ma_test2_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ ma_test3_DEPENDENCIES= $(LIBRARIES) -ma_test3_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +ma_test3_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ #ma_ft_test1_DEPENDENCIES= $(LIBRARIES) #ma_ft_eval_DEPENDENCIES= $(LIBRARIES) -maria_ftdump_DEPENDENCIES= $(LIBRARIES) -maria_ftdump_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +aria_ftdump_SOURCES= maria_ftdump.c +aria_ftdump_DEPENDENCIES= $(LIBRARIES) +aria_ftdump_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ ma_rt_test_DEPENDENCIES= $(LIBRARIES) -ma_rt_test_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +ma_rt_test_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ ma_sp_test_DEPENDENCIES= $(LIBRARIES) -ma_sp_test_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +ma_sp_test_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -libmaria_la_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \ +libaria_la_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \ ma_rnext.c ma_rnext_same.c \ ma_search.c ma_page.c ma_key_recover.c ma_key.c \ ma_locking.c ma_state.c \ @@ -136,21 +141,22 @@ libmaria_la_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \ ma_sp_key.c ma_control_file.c ma_loghandler.c \ ma_pagecache.c ma_pagecaches.c \ ma_checkpoint.c ma_recovery.c ma_commit.c \ - ma_pagecrc.c ma_recovery_util.c + ma_pagecrc.c ma_recovery_util.c \ + compat_aliases.cc ma_servicethread.c -libmaria_s_la_SOURCES = ha_maria.cc -libmaria_s_la_CXXFLAGS = $(AM_CXXFLAGS) -libmaria_s_la_LIBADD = libmaria.la -libmaria_embedded_la_SOURCES = ha_maria.cc -libmaria_embedded_la_LIBADD = libmaria.la -libmaria_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@ +libaria_s_la_SOURCES = ha_maria.cc +libaria_s_la_CXXFLAGS = $(AM_CXXFLAGS) +libaria_s_la_LIBADD = libaria.la +libaria_embedded_la_SOURCES = ha_maria.cc +libaria_embedded_la_LIBADD = libaria.la +libaria_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@ -libmaria_a_SOURCES= -libmaria.a: libmaria.la - $(CP) .libs/libmaria.a $@ +libaria_a_SOURCES= +libaria.a: libaria.la + $(CP) .libs/libaria.a $@ -CLEANFILES = test?.MA? FT?.MA? isam.log ma_test_all ma_rt_test.MA? sp_test.MA? maria_log_control maria_log.0000* +CLEANFILES = test?.MA? FT?.MA? isam.log ma_test_all ma_rt_test.MA? sp_test.MA? aria_log_control aria_log.0000* SUFFIXES = .sh diff --git a/storage/maria/compat_aliases.cc b/storage/maria/compat_aliases.cc new file mode 100644 index 00000000000..ce8838b2da2 --- /dev/null +++ b/storage/maria/compat_aliases.cc @@ -0,0 +1,250 @@ +/* Copyright (C) 2010 Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + compatibility aliases for system and static variables +*/ +#include <my_global.h> +#include <maria.h> +#include <mysql/plugin.h> +#include "ma_loghandler.h" +#include "compat_aliases.h" + +ulong block_size_alias; +static MYSQL_SYSVAR_ULONG(block_size, block_size_alias, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Deprecated, use --aria-block-size instead", 0, 0, + MARIA_KEY_BLOCK_LENGTH, MARIA_MIN_KEY_BLOCK_LENGTH, + MARIA_MAX_KEY_BLOCK_LENGTH, MARIA_MIN_KEY_BLOCK_LENGTH); + +ulong checkpoint_interval_alias; +static MYSQL_SYSVAR_ULONG(checkpoint_interval, checkpoint_interval_alias, + PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-checkpoint-interval instead", + NULL, NULL, 30, 0, UINT_MAX, 1); + +ulong force_start_after_recovery_failures_alias; +static MYSQL_SYSVAR_ULONG(force_start_after_recovery_failures, force_start_after_recovery_failures_alias, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Deprecated, use --aria-force-start-after-recovery-failures instead", + NULL, NULL, 0, 0, UINT_MAX8, 1); + +my_bool page_checksum_alias; +static MYSQL_SYSVAR_BOOL(page_checksum, page_checksum_alias, 0, + "Deprecated, use --aria-page-checksum instead", 0, 0, 1); + +char *log_dir_path_alias; +static MYSQL_SYSVAR_STR(log_dir_path, log_dir_path_alias, + PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Deprecated, use --aria-log-dir-path instead", + NULL, NULL, mysql_real_data_home); + +ulong log_file_size_alias; +static MYSQL_SYSVAR_ULONG(log_file_size, log_file_size_alias, + PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-log-file-size instead", + NULL, NULL, TRANSLOG_FILE_SIZE, + TRANSLOG_MIN_FILE_SIZE, 0xffffffffL, TRANSLOG_PAGE_SIZE); + +ulong group_commit_alias; +static MYSQL_SYSVAR_ENUM(group_commit, group_commit_alias, + PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-group-commit instead", + NULL, NULL, + TRANSLOG_GCOMMIT_NONE, &maria_group_commit_typelib); + +ulong group_commit_interval_alias; +static MYSQL_SYSVAR_ULONG(group_commit_interval, group_commit_interval_alias, + PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-group-commit-interval instead", + NULL, NULL, 0, 0, UINT_MAX, 1); + +ulong log_purge_type_alias; +static MYSQL_SYSVAR_ENUM(log_purge_type, log_purge_type_alias, + PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-log-purge-type instead", + NULL, NULL, TRANSLOG_PURGE_IMMIDIATE, + &maria_translog_purge_type_typelib); + +ulonglong max_sort_file_size_alias; +static MYSQL_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size_alias, + PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-max-temp-length instead", + 0, 0, MAX_FILE_SIZE, 0, MAX_FILE_SIZE, 1024*1024); + +ulong pagecache_age_threshold_alias; +static MYSQL_SYSVAR_ULONG(pagecache_age_threshold, pagecache_age_threshold_alias, + PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-pagecache-age-threshold instead", + 0, 0, 300, 100, ~0L, 100); + +ulonglong pagecache_buffer_size_alias; +static MYSQL_SYSVAR_ULONGLONG(pagecache_buffer_size, pagecache_buffer_size_alias, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Deprecated, use --aria-pagecache-buffer-size instead", + 0, 0, KEY_CACHE_SIZE, MALLOC_OVERHEAD, ~0UL, IO_SIZE); + +ulong pagecache_division_limit_alias; +static MYSQL_SYSVAR_ULONG(pagecache_division_limit, pagecache_division_limit_alias, + PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-pagecache-division-limit instead", + 0, 0, 100, 1, 100, 1); + +ulong recover_alias; +static MYSQL_SYSVAR_ENUM(recover, recover_alias, PLUGIN_VAR_OPCMDARG, + "Deprecated, use --aria-recover instead", + NULL, NULL, HA_RECOVER_DEFAULT, &maria_recover_typelib); + +ulong repair_threads_alias; +static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-repair-threads instead", + 0, 0, 1, 1, ~0L, 1); + +ulong sort_buffer_size_alias; +static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-sort-buffer-size instead", + 0, 0, 128L*1024L*1024L, 4, ~0L, 1); + +ulong stats_method_alias; +static MYSQL_THDVAR_ENUM(stats_method, PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-stats-method instead", + 0, 0, 0, &maria_stats_method_typelib); + +ulong sync_log_dir_alias; +static MYSQL_SYSVAR_ENUM(sync_log_dir, sync_log_dir_alias, + PLUGIN_VAR_RQCMDARG, + "Deprecated, use --aria-sync-log-dir instead", + NULL, NULL, TRANSLOG_SYNC_DIR_NEWFILE, + &maria_sync_log_dir_typelib); + +my_bool used_for_temp_tables_alias= 1; +static MYSQL_SYSVAR_BOOL(used_for_temp_tables, + used_for_temp_tables_alias, PLUGIN_VAR_READONLY | PLUGIN_VAR_NOCMDOPT, + NULL, 0, 0, 1); + +static struct st_mysql_show_var status_variables_aliases[]= { + {"Maria", (char*) &status_variables, SHOW_ARRAY}, + {NullS, NullS, SHOW_LONG} +}; + +/* + There is one problem with aliases for command-line options. + Plugin initialization works like this + + for all plugins: + prepare command-line options + initialize command-line option variables to the default values + parse command line, assign values as necessary + + for all plugins: + call the plugin initialization function + + it means, we cannot have maria* and aria* command-line options to use + the same underlying variables - because after assigning maria* values, + MySQL will put there default values again preparing for parsing aria* + values. So, maria* values will be lost. + + So, we create separate set of variables for maria* options, + and take both values into account in ha_maria_init(). + + When the command line was parsed, we patch maria* options + to use the same variables as aria* options so that + set @@maria_some_var would have the same value as @@aria_some_var + without forcing us to copy the values around all the time. +*/ + +static struct st_mysql_sys_var* system_variables_aliases[]= { + MYSQL_SYSVAR(block_size), + MYSQL_SYSVAR(checkpoint_interval), + MYSQL_SYSVAR(force_start_after_recovery_failures), + MYSQL_SYSVAR(group_commit), + MYSQL_SYSVAR(group_commit_interval), + MYSQL_SYSVAR(log_dir_path), + MYSQL_SYSVAR(log_file_size), + MYSQL_SYSVAR(log_purge_type), + MYSQL_SYSVAR(max_sort_file_size), + MYSQL_SYSVAR(page_checksum), + MYSQL_SYSVAR(pagecache_age_threshold), + MYSQL_SYSVAR(pagecache_buffer_size), + MYSQL_SYSVAR(pagecache_division_limit), + MYSQL_SYSVAR(recover), + MYSQL_SYSVAR(repair_threads), + MYSQL_SYSVAR(sort_buffer_size), + MYSQL_SYSVAR(stats_method), + MYSQL_SYSVAR(sync_log_dir), + MYSQL_SYSVAR(used_for_temp_tables), + NULL +}; + +#define COPY_SYSVAR(name) \ + memcpy(&MYSQL_SYSVAR_NAME(name), system_variables[i++], \ + sizeof(MYSQL_SYSVAR_NAME(name))); \ + if (name ## _alias != MYSQL_SYSVAR_NAME(name).def_val && \ + *MYSQL_SYSVAR_NAME(name).value == MYSQL_SYSVAR_NAME(name).def_val) \ + *MYSQL_SYSVAR_NAME(name).value= name ## _alias; + +#define COPY_THDVAR(name) \ + name ## _alias= THDVAR(0, name); \ + memcpy(&MYSQL_SYSVAR_NAME(name), system_variables[i++], \ + sizeof(MYSQL_SYSVAR_NAME(name))); \ + if (name ## _alias != MYSQL_SYSVAR_NAME(name).def_val && \ + THDVAR(0, name) == MYSQL_SYSVAR_NAME(name).def_val) \ + THDVAR(0, name)= name ## _alias; + +/* Note: + The following list must be identical to the list for system_variables[] in ha_maria.cc +*/ + +void copy_variable_aliases() +{ + int i= 0; + COPY_SYSVAR(block_size); + COPY_SYSVAR(checkpoint_interval); + i++; // Skip checkpoint_min_log_activity + COPY_SYSVAR(force_start_after_recovery_failures); + COPY_SYSVAR(group_commit); + COPY_SYSVAR(group_commit_interval); + COPY_SYSVAR(log_dir_path); + COPY_SYSVAR(log_file_size); + COPY_SYSVAR(log_purge_type); + COPY_SYSVAR(max_sort_file_size); + COPY_SYSVAR(page_checksum); + COPY_SYSVAR(pagecache_age_threshold); + COPY_SYSVAR(pagecache_buffer_size); + COPY_SYSVAR(pagecache_division_limit); + COPY_SYSVAR(recover); + COPY_THDVAR(repair_threads); + COPY_THDVAR(sort_buffer_size); + COPY_THDVAR(stats_method); + COPY_SYSVAR(sync_log_dir); + COPY_SYSVAR(used_for_temp_tables); +} + +struct st_maria_plugin compat_aliases= { + MYSQL_DAEMON_PLUGIN, + &maria_storage_engine, + "Maria", + "Monty Program Ab", + "Compatibility aliases for the Aria engine", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0105, + status_variables_aliases, + system_variables_aliases, + "1.5", + MariaDB_PLUGIN_MATURITY_GAMMA +}; + diff --git a/storage/maria/compat_aliases.h b/storage/maria/compat_aliases.h new file mode 100644 index 00000000000..46a4da74eec --- /dev/null +++ b/storage/maria/compat_aliases.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2010 Monty Program Ab + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +extern struct st_maria_plugin compat_aliases; +extern char mysql_real_data_home[FN_REFLEN]; +extern TYPELIB maria_recover_typelib; +extern TYPELIB maria_stats_method_typelib; +extern TYPELIB maria_translog_purge_type_typelib; +extern TYPELIB maria_sync_log_dir_typelib; +extern TYPELIB maria_group_commit_typelib; +extern struct st_mysql_storage_engine maria_storage_engine; +extern my_bool use_maria_for_temp_tables; +extern struct st_mysql_sys_var* system_variables[]; +extern st_mysql_show_var status_variables[]; +void copy_variable_aliases(); diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 5661e1f06d7..60fa7a58fb6 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -29,6 +29,7 @@ #include "ha_maria.h" #include "trnman_public.h" #include "trnman.h" +#include "compat_aliases.h" C_MODE_START #include "maria_def.h" @@ -102,22 +103,40 @@ TYPELIB maria_translog_purge_type_typelib= array_elements(maria_translog_purge_type_names) - 1, "", maria_translog_purge_type_names, NULL }; + +/* transactional log directory sync */ const char *maria_sync_log_dir_names[]= { "NEVER", "NEWFILE", "ALWAYS", NullS }; - TYPELIB maria_sync_log_dir_typelib= { array_elements(maria_sync_log_dir_names) - 1, "", maria_sync_log_dir_names, NULL }; +/* transactional log group commit */ +const char *maria_group_commit_names[]= +{ + "none", "hard", "soft", NullS +}; +TYPELIB maria_group_commit_typelib= +{ + array_elements(maria_group_commit_names) - 1, "", + maria_group_commit_names, NULL +}; + /** Interval between background checkpoints in seconds */ static ulong checkpoint_interval; static void update_checkpoint_interval(MYSQL_THD thd, struct st_mysql_sys_var *var, void *var_ptr, const void *save); +static void update_maria_group_commit(MYSQL_THD thd, + struct st_mysql_sys_var *var, + void *var_ptr, const void *save); +static void update_maria_group_commit_interval(MYSQL_THD thd, + struct st_mysql_sys_var *var, + void *var_ptr, const void *save); /** After that many consecutive recovery failures, remove logs */ static ulong force_start_after_recovery_failures; static void update_log_file_size(MYSQL_THD thd, @@ -126,16 +145,22 @@ static void update_log_file_size(MYSQL_THD thd, static MYSQL_SYSVAR_ULONG(block_size, maria_block_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "Block size to be used for MARIA index pages.", 0, 0, + "Block size to be used for Aria index pages.", 0, 0, MARIA_KEY_BLOCK_LENGTH, MARIA_MIN_KEY_BLOCK_LENGTH, MARIA_MAX_KEY_BLOCK_LENGTH, MARIA_MIN_KEY_BLOCK_LENGTH); static MYSQL_SYSVAR_ULONG(checkpoint_interval, checkpoint_interval, PLUGIN_VAR_RQCMDARG, - "Interval between automatic checkpoints, in seconds; 0 means" + "Interval between tries to do an automatic checkpoints. In seconds; 0 means" " 'no automatic checkpoints' which makes sense only for testing.", NULL, update_checkpoint_interval, 30, 0, UINT_MAX, 1); +static MYSQL_SYSVAR_ULONG(checkpoint_log_activity, maria_checkpoint_min_log_activity, + PLUGIN_VAR_RQCMDARG, + "Number of bytes that the transaction log has to grow between checkpoints before a new " + "checkpoint is written to the log.", + NULL, NULL, 1024*1024, 0, UINT_MAX, 1); + static MYSQL_SYSVAR_ULONG(force_start_after_recovery_failures, force_start_after_recovery_failures, /* @@ -164,9 +189,27 @@ static MYSQL_SYSVAR_ULONG(log_file_size, log_file_size, NULL, update_log_file_size, TRANSLOG_FILE_SIZE, TRANSLOG_MIN_FILE_SIZE, 0xffffffffL, TRANSLOG_PAGE_SIZE); +static MYSQL_SYSVAR_ENUM(group_commit, maria_group_commit, + PLUGIN_VAR_RQCMDARG, + "Specifies Aria group commit mode. " + "Possible values are \"none\" (no group commit), " + "\"hard\" (with waiting to actual commit), " + "\"soft\" (no wait for commit (DANGEROUS!!!))", + NULL, update_maria_group_commit, + TRANSLOG_GCOMMIT_NONE, &maria_group_commit_typelib); + +static MYSQL_SYSVAR_ULONG(group_commit_interval, maria_group_commit_interval, + PLUGIN_VAR_RQCMDARG, + "Interval between commite in microseconds (1/1000000c)." + " 0 stands for no waiting" + " for other threads to come and do a commit in \"hard\" mode and no" + " sync()/commit at all in \"soft\" mode. Option has only an effect" + " if aria_group_commit is used", + NULL, update_maria_group_commit_interval, 0, 0, UINT_MAX, 1); + static MYSQL_SYSVAR_ENUM(log_purge_type, log_purge_type, PLUGIN_VAR_RQCMDARG, - "Specifies how maria transactional log will be purged. " + "Specifies how Aria transactional log will be purged. " "Possible values of name are \"immediate\", \"external\" " "and \"at_flush\"", NULL, NULL, TRANSLOG_PURGE_IMMIDIATE, @@ -176,7 +219,7 @@ static MYSQL_SYSVAR_ULONGLONG(max_sort_file_size, maria_max_temp_length, PLUGIN_VAR_RQCMDARG, "Don't use the fast sort index method to created index if the " "temporary file would get bigger than this.", - 0, 0, MAX_FILE_SIZE, 0, MAX_FILE_SIZE, 1024*1024); + 0, 0, MAX_FILE_SIZE & ~(1*MB-1), 0, MAX_FILE_SIZE, 1*MB); static MYSQL_SYSVAR_ULONG(pagecache_age_threshold, pagecache_age_threshold, PLUGIN_VAR_RQCMDARG, @@ -188,10 +231,10 @@ static MYSQL_SYSVAR_ULONG(pagecache_age_threshold, static MYSQL_SYSVAR_ULONGLONG(pagecache_buffer_size, pagecache_buffer_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "The size of the buffer used for index blocks for Maria tables. " + "The size of the buffer used for index blocks for Aria tables. " "Increase this to get better index handling (for all reads and " "multiple writes) to as much as you can afford.", 0, 0, - KEY_CACHE_SIZE, 8192*16L, ~(ulong) 0, IO_SIZE); + KEY_CACHE_SIZE, 8192*16L, ~(ulong) 0, 1); static MYSQL_SYSVAR_ULONG(pagecache_division_limit, pagecache_division_limit, PLUGIN_VAR_RQCMDARG, @@ -205,7 +248,7 @@ static MYSQL_SYSVAR_ENUM(recover, maria_recover_options, PLUGIN_VAR_OPCMDARG, NULL, NULL, HA_RECOVER_DEFAULT, &maria_recover_typelib); static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG, - "Number of threads to use when repairing maria tables. The value of 1 " + "Number of threads to use when repairing Aria tables. The value of 1 " "disables parallel repair.", 0, 0, 1, 1, ~0L, 1); @@ -215,7 +258,7 @@ static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG, 0, 0, 128L*1024L*1024L, 4, ~0L, 1); static MYSQL_THDVAR_ENUM(stats_method, PLUGIN_VAR_RQCMDARG, - "Specifies how maria index statistics collection code should treat " + "Specifies how Aria index statistics collection code should treat " "NULLs. Possible values are \"nulls_unequal\", \"nulls_equal\", " "and \"nulls_ignored\".", 0, 0, 0, &maria_stats_method_typelib); @@ -226,14 +269,15 @@ static MYSQL_SYSVAR_ENUM(sync_log_dir, sync_log_dir, PLUGIN_VAR_RQCMDARG, &maria_sync_log_dir_typelib); #ifdef USE_MARIA_FOR_TMP_TABLES -static my_bool use_maria_for_temp_tables= 1; +#define USE_MARIA_FOR_TMP_TABLES_VAL 1 #else -static my_bool use_maria_for_temp_tables= 0; +#define USE_MARIA_FOR_TMP_TABLES_VAL 0 #endif +my_bool use_maria_for_temp_tables= USE_MARIA_FOR_TMP_TABLES_VAL; static MYSQL_SYSVAR_BOOL(used_for_temp_tables, use_maria_for_temp_tables, PLUGIN_VAR_READONLY | PLUGIN_VAR_NOCMDOPT, - "Whether temporary tables should be MyISAM or Maria", 0, 0, + "Whether temporary tables should be MyISAM or Aria", 0, 0, 1); /***************************************************************************** @@ -266,7 +310,7 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type, if (!thd->vio_ok()) { - sql_print_error(fmt, args); + sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf); return; } @@ -274,6 +318,8 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type, (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR | T_AUTO_REPAIR)) { my_message(ER_NOT_KEYFILE, msgbuf, MYF(MY_WME)); + if (thd->variables.log_warnings > 2) + sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf); return; } length= (uint) (strxmov(name, param->db_name, ".", param->table_name, @@ -292,8 +338,11 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type, protocol->store(msg_type, system_charset_info); protocol->store(msgbuf, msg_length, system_charset_info); if (protocol->write()) - sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n", - msgbuf); + sql_print_error("Failed on my_net_write, writing to stderr instead: %s.%s: %s\n", + param->db_name, param->table_name, msgbuf); + else if (thd->variables.log_warnings > 2) + sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf); + return; } @@ -432,7 +481,7 @@ static int table2maria(TABLE *table_arg, data_file_type row_type, recinfo_pos= recinfo; create_info->null_bytes= table_arg->s->null_bytes; - while (recpos < (uint) share->reclength) + while (recpos < (uint) share->stored_rec_length) { Field **field, *found= 0; minpos= share->reclength; @@ -783,7 +832,7 @@ int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY | HA_FILE_BASED | HA_CAN_GEOMETRY | CANNOT_ROLLBACK_FLAG | - HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS | + HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS | HA_CAN_VIRTUAL_COLUMNS | HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT), can_enable_indexes(1), bulk_insert_single_undo(BULK_INSERT_NONE) {} @@ -836,7 +885,7 @@ double ha_maria::scan_time() } /* - We need to be able to store at least two keys on an index page as the + We need to be able to store at least 2 keys on an index page as the splitting algorithms depends on this. (With only one key on a page we also can't use any compression, which may make the index file much larger) @@ -1022,8 +1071,6 @@ int ha_maria::close(void) int ha_maria::write_row(uchar * buf) { - ha_statistic_increment(&SSV::ha_write_count); - /* If we have a timestamp column, update it to the current time */ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); @@ -1056,7 +1103,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) param.thd= thd; param.op_name= "check"; param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.testflag= check_opt->flags | T_CHECK | T_SILENT; param.stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method); @@ -1154,7 +1201,7 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt) param.thd= thd; param.op_name= "analyze"; param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS | T_DONT_CHECK_CHECKSUM); param.using_global_keycache= 1; @@ -1435,7 +1482,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize) if (file->dfile.file == -1) { sql_print_information("Retrying repair of: '%s' failed. " - "Please try REPAIR EXTENDED or maria_chk", + "Please try REPAIR EXTENDED or aria_chk", table->s->path.str); DBUG_RETURN(HA_ADMIN_FAILED); } @@ -1449,7 +1496,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize) _ma_copy_nontrans_state_information(file); param->db_name= table->s->db.str; - param->table_name= table->alias; + param->table_name= table->alias.c_ptr(); param->tmpfile_createflag= O_RDWR | O_TRUNC; param->using_global_keycache= 1; param->thd= thd; @@ -1930,19 +1977,21 @@ void ha_maria::start_bulk_insert(ha_rows rows) we don't want to update the key statistics based of only a few rows. Index file rebuild requires an exclusive lock, so if versioning is on don't do it (see how ha_maria::store_lock() tries to predict repair). - We can repair index only if we have an exclusive (TL_WRITE) lock. To - see if table is empty, we shouldn't rely on the old records' count from - our transaction's start (if that old count is 0 but now there are - records in the table, we would wrongly destroy them). - So we need to look at share->state.state.records. - As a safety net for now, we don't remove the test of - file->state->records, because there is uncertainty on what will happen - during repair if the two states disagree. + We can repair index only if we have an exclusive (TL_WRITE) lock or + if this is inside an ALTER TABLE, in which case lock_type == TL_UNLOCK. + + To see if table is empty, we shouldn't rely on the old record + count from our transaction's start (if that old count is 0 but + now there are records in the table, we would wrongly destroy + them). So we need to look at share->state.state.records. As a + safety net for now, we don't remove the test of + file->state->records, because there is uncertainty on what will + happen during repair if the two states disagree. */ if ((file->state->records == 0) && (share->state.state.records == 0) && can_enable_indexes && (!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES) && - (file->lock.type == TL_WRITE)) + (file->lock.type == TL_WRITE || file->lock.type == TL_UNLOCK)) { /** @todo for a single-row INSERT SELECT, we will go into repair, which @@ -2059,13 +2108,17 @@ bool ha_maria::check_and_repair(THD *thd) if (crashed) { + bool save_log_all_errors; sql_print_warning("Recovering table: '%s'", table->s->path.str); + save_log_all_errors= thd->log_all_errors; + thd->log_all_errors|= (thd->variables.log_warnings > 2); check_opt.flags= ((maria_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) | (maria_recover_options & HA_RECOVER_FORCE ? 0 : T_SAFE_REPAIR) | T_AUTO_REPAIR); if (repair(thd, &check_opt)) error= 1; + thd->log_all_errors= save_log_all_errors; } pthread_mutex_lock(&LOCK_thread_count); thd->query_string= old_query; @@ -2092,7 +2145,6 @@ bool ha_maria::is_crashed() const int ha_maria::update_row(const uchar * old_data, uchar * new_data) { CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING("UPDATE in WRITE CONCURRENT"); - ha_statistic_increment(&SSV::ha_update_count); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return maria_update(file, old_data, new_data); @@ -2102,7 +2154,6 @@ int ha_maria::update_row(const uchar * old_data, uchar * new_data) int ha_maria::delete_row(const uchar * buf) { CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING("DELETE in WRITE CONCURRENT"); - ha_statistic_increment(&SSV::ha_delete_count); return maria_delete(file, buf); } @@ -2112,7 +2163,6 @@ int ha_maria::index_read_map(uchar * buf, const uchar * key, enum ha_rkey_function find_flag) { DBUG_ASSERT(inited == INDEX); - ha_statistic_increment(&SSV::ha_read_key_count); int error= maria_rkey(file, buf, active_index, key, keypart_map, find_flag); table->status= error ? STATUS_NOT_FOUND : 0; return error; @@ -2123,7 +2173,6 @@ int ha_maria::index_read_idx_map(uchar * buf, uint index, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) { - ha_statistic_increment(&SSV::ha_read_key_count); int error= maria_rkey(file, buf, index, key, keypart_map, find_flag); table->status= error ? STATUS_NOT_FOUND : 0; return error; @@ -2135,7 +2184,6 @@ int ha_maria::index_read_last_map(uchar * buf, const uchar * key, { DBUG_ENTER("ha_maria::index_read_last_map"); DBUG_ASSERT(inited == INDEX); - ha_statistic_increment(&SSV::ha_read_key_count); int error= maria_rkey(file, buf, active_index, key, keypart_map, HA_READ_PREFIX_LAST); table->status= error ? STATUS_NOT_FOUND : 0; @@ -2146,7 +2194,6 @@ int ha_maria::index_read_last_map(uchar * buf, const uchar * key, int ha_maria::index_next(uchar * buf) { DBUG_ASSERT(inited == INDEX); - ha_statistic_increment(&SSV::ha_read_next_count); int error= maria_rnext(file, buf, active_index); table->status= error ? STATUS_NOT_FOUND : 0; return error; @@ -2156,7 +2203,6 @@ int ha_maria::index_next(uchar * buf) int ha_maria::index_prev(uchar * buf) { DBUG_ASSERT(inited == INDEX); - ha_statistic_increment(&SSV::ha_read_prev_count); int error= maria_rprev(file, buf, active_index); table->status= error ? STATUS_NOT_FOUND : 0; return error; @@ -2166,7 +2212,6 @@ int ha_maria::index_prev(uchar * buf) int ha_maria::index_first(uchar * buf) { DBUG_ASSERT(inited == INDEX); - ha_statistic_increment(&SSV::ha_read_first_count); int error= maria_rfirst(file, buf, active_index); table->status= error ? STATUS_NOT_FOUND : 0; return error; @@ -2176,7 +2221,6 @@ int ha_maria::index_first(uchar * buf) int ha_maria::index_last(uchar * buf) { DBUG_ASSERT(inited == INDEX); - ha_statistic_increment(&SSV::ha_read_last_count); int error= maria_rlast(file, buf, active_index); table->status= error ? STATUS_NOT_FOUND : 0; return error; @@ -2189,7 +2233,6 @@ int ha_maria::index_next_same(uchar * buf, { int error; DBUG_ASSERT(inited == INDEX); - ha_statistic_increment(&SSV::ha_read_next_count); /* TODO: Delete this loop in Maria 1.5 as versioning will ensure this never happens @@ -2221,7 +2264,6 @@ int ha_maria::rnd_end() int ha_maria::rnd_next(uchar *buf) { - ha_statistic_increment(&SSV::ha_read_rnd_next_count); int error= maria_scan(file, buf); table->status= error ? STATUS_NOT_FOUND : 0; return error; @@ -2243,7 +2285,6 @@ int ha_maria::restart_rnd_next(uchar *buf) int ha_maria::rnd_pos(uchar *buf, uchar *pos) { - ha_statistic_increment(&SSV::ha_read_rnd_count); int error= maria_rrnd(file, buf, my_get_ptr(pos, ref_length)); table->status= error ? STATUS_NOT_FOUND : 0; return error; @@ -3185,7 +3226,7 @@ static my_bool translog_callback_delete_all(const char *directory, /** - Helper function for option maria-force-start-after-recovery-failures. + Helper function for option aria-force-start-after-recovery-failures. Deletes logs if too many failures. Otherwise, increments the counter of failures in the control file. Notice how this has to be called _before_ translog_init() (if log is @@ -3201,9 +3242,9 @@ static int mark_recovery_start(const char* log_dir) DBUG_ENTER("mark_recovery_start"); if (unlikely(maria_recover_options == HA_RECOVER_NONE)) ma_message_no_user(ME_JUST_WARNING, "Please consider using option" - " --maria-recover[=...] to automatically check and" + " --aria-recover[=...] to automatically check and" " repair tables when logs are removed by option" - " --maria-force-start-after-recovery-failures=#"); + " --aria-force-start-after-recovery-failures=#"); if (recovery_failures >= force_start_after_recovery_failures) { /* @@ -3229,9 +3270,9 @@ static int mark_recovery_start(const char* log_dir) /** - Helper function for option maria-force-start-after-recovery-failures. + Helper function for option aria-force-start-after-recovery-failures. Records in the control file that recovery was a success, so that it's not - counted for maria-force-start-after-recovery-failures. + counted for aria-force-start-after-recovery-failures. */ static int mark_recovery_success(void) @@ -3258,6 +3299,7 @@ bool ha_maria::is_changed() const static int ha_maria_init(void *p) { int res; + copy_variable_aliases(); const char *log_dir= maria_data_root; maria_hton= (handlerton *)p; maria_hton->state= SHOW_OPTION_YES; @@ -3266,13 +3308,16 @@ static int ha_maria_init(void *p) maria_hton->panic= maria_hton_panic; maria_hton->commit= maria_commit; maria_hton->rollback= maria_rollback; +#ifdef MARIA_CANNOT_ROLLBACK + maria_hton->commit= 0; +#endif maria_hton->flush_logs= maria_flush_logs; maria_hton->show_status= maria_show_status; /* TODO: decide if we support Maria being used for log tables */ maria_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES; bzero(maria_log_pagecache, sizeof(*maria_log_pagecache)); maria_tmpdir= &mysql_tmpdir_list; /* For REDO */ - res= maria_init() || ma_control_file_open(TRUE, TRUE) || + res= maria_upgrade() || maria_init() || ma_control_file_open(TRUE, TRUE) || ((force_start_after_recovery_failures != 0) && mark_recovery_start(log_dir)) || !init_pagecache(maria_pagecache, @@ -3346,7 +3391,7 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name, *engine_data= 0; if (file->s->now_transactional && file->s->have_versioning) - return (file->trn->trid >= file->s->state.last_change_trn); + DBUG_RETURN(file->trn->trid >= file->s->state.last_change_trn); /* If a concurrent INSERT has happened just before the currently processed @@ -3378,10 +3423,13 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name, } #endif -static struct st_mysql_sys_var* system_variables[]= { +struct st_mysql_sys_var* system_variables[]= { MYSQL_SYSVAR(block_size), MYSQL_SYSVAR(checkpoint_interval), + MYSQL_SYSVAR(checkpoint_log_activity), MYSQL_SYSVAR(force_start_after_recovery_failures), + MYSQL_SYSVAR(group_commit), + MYSQL_SYSVAR(group_commit_interval), MYSQL_SYSVAR(log_dir_path), MYSQL_SYSVAR(log_file_size), MYSQL_SYSVAR(log_purge_type), @@ -3412,6 +3460,93 @@ static void update_checkpoint_interval(MYSQL_THD thd, ma_checkpoint_init(*(ulong *)var_ptr= (ulong)(*(long *)save)); } + +/** + @brief Updates group commit mode +*/ + +static void update_maria_group_commit(MYSQL_THD thd, + struct st_mysql_sys_var *var, + void *var_ptr, const void *save) +{ + ulong value= (ulong)*((long *)var_ptr); + DBUG_ENTER("update_maria_group_commit"); + DBUG_PRINT("enter", ("old value: %lu new value %lu rate %lu", + value, (ulong)(*(long *)save), + maria_group_commit_interval)); + /* old value */ + switch (value) { + case TRANSLOG_GCOMMIT_NONE: + break; + case TRANSLOG_GCOMMIT_HARD: + translog_hard_group_commit(FALSE); + break; + case TRANSLOG_GCOMMIT_SOFT: + translog_soft_sync(FALSE); + if (maria_group_commit_interval) + translog_soft_sync_end(); + break; + default: + DBUG_ASSERT(0); /* impossible */ + } + value= *(ulong *)var_ptr= (ulong)(*(long *)save); + translog_sync(); + /* new value */ + switch (value) { + case TRANSLOG_GCOMMIT_NONE: + break; + case TRANSLOG_GCOMMIT_HARD: + translog_hard_group_commit(TRUE); + break; + case TRANSLOG_GCOMMIT_SOFT: + translog_soft_sync(TRUE); + /* variable change made under global lock so we can just read it */ + if (maria_group_commit_interval) + translog_soft_sync_start(); + break; + default: + DBUG_ASSERT(0); /* impossible */ + } + DBUG_VOID_RETURN; +} + +/** + @brief Updates group commit interval +*/ + +static void update_maria_group_commit_interval(MYSQL_THD thd, + struct st_mysql_sys_var *var, + void *var_ptr, const void *save) +{ + ulong new_value= (ulong)*((long *)save); + ulong *value_ptr= (ulong*) var_ptr; + DBUG_ENTER("update_maria_group_commit_interval"); + DBUG_PRINT("enter", ("old value: %lu new value %lu group commit %lu", + *value_ptr, new_value, maria_group_commit)); + + /* variable change made under global lock so we can just read it */ + switch (maria_group_commit) { + case TRANSLOG_GCOMMIT_NONE: + *value_ptr= new_value; + translog_set_group_commit_interval(new_value); + break; + case TRANSLOG_GCOMMIT_HARD: + *value_ptr= new_value; + translog_set_group_commit_interval(new_value); + break; + case TRANSLOG_GCOMMIT_SOFT: + if (*value_ptr) + translog_soft_sync_end(); + translog_set_group_commit_interval(new_value); + if ((*value_ptr= new_value)) + translog_soft_sync_start(); + break; + default: + DBUG_ASSERT(0); /* impossible */ + } + DBUG_VOID_RETURN; +} + /** @brief Updates the transaction log file limit. */ @@ -3426,33 +3561,41 @@ static void update_log_file_size(MYSQL_THD thd, } -static SHOW_VAR status_variables[]= { - {"Maria_pagecache_blocks_not_flushed", (char*) &maria_pagecache_var.global_blocks_changed, SHOW_LONG_NOFLUSH}, - {"Maria_pagecache_blocks_unused", (char*) &maria_pagecache_var.blocks_unused, SHOW_LONG_NOFLUSH}, - {"Maria_pagecache_blocks_used", (char*) &maria_pagecache_var.blocks_used, SHOW_LONG_NOFLUSH}, - {"Maria_pagecache_read_requests", (char*) &maria_pagecache_var.global_cache_r_requests, SHOW_LONGLONG}, - {"Maria_pagecache_reads", (char*) &maria_pagecache_var.global_cache_read, SHOW_LONGLONG}, - {"Maria_pagecache_write_requests", (char*) &maria_pagecache_var.global_cache_w_requests, SHOW_LONGLONG}, - {"Maria_pagecache_writes", (char*) &maria_pagecache_var.global_cache_write, SHOW_LONGLONG}, +SHOW_VAR status_variables[]= { + {"pagecache_blocks_not_flushed", (char*) &maria_pagecache_var.global_blocks_changed, SHOW_LONG_NOFLUSH}, + {"pagecache_blocks_unused", (char*) &maria_pagecache_var.blocks_unused, SHOW_LONG_NOFLUSH}, + {"pagecache_blocks_used", (char*) &maria_pagecache_var.blocks_used, SHOW_LONG_NOFLUSH}, + {"pagecache_read_requests", (char*) &maria_pagecache_var.global_cache_r_requests, SHOW_LONGLONG}, + {"pagecache_reads", (char*) &maria_pagecache_var.global_cache_read, SHOW_LONGLONG}, + {"pagecache_write_requests", (char*) &maria_pagecache_var.global_cache_w_requests, SHOW_LONGLONG}, + {"pagecache_writes", (char*) &maria_pagecache_var.global_cache_write, SHOW_LONGLONG}, + {"transaction_log_syncs", (char*) &translog_syncs, SHOW_LONGLONG}, + {NullS, NullS, SHOW_LONG} +}; + +static struct st_mysql_show_var aria_status_variables[]= { + {"Aria", (char*) &status_variables, SHOW_ARRAY}, {NullS, NullS, SHOW_LONG} }; struct st_mysql_storage_engine maria_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; -mysql_declare_plugin(maria) +maria_declare_plugin(aria) +compat_aliases, { MYSQL_STORAGE_ENGINE_PLUGIN, &maria_storage_engine, - "MARIA", + "Aria", "Monty Program Ab", "Crash-safe tables with MyISAM heritage", PLUGIN_LICENSE_GPL, - ha_maria_init, /* Plugin Init */ - NULL, /* Plugin Deinit */ - 0x0100, /* 1.0 */ - status_variables, /* status variables */ - system_variables, /* system variables */ - NULL -} -mysql_declare_plugin_end; + ha_maria_init, /* Plugin Init */ + NULL, /* Plugin Deinit */ + 0x0105, /* 1.5 */ + aria_status_variables, /* status variables */ + system_variables, /* system variables */ + "1.5", /* string version */ + MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h index 6171f89cb18..c7af191c1e7 100644 --- a/storage/maria/ha_maria.h +++ b/storage/maria/ha_maria.h @@ -22,12 +22,6 @@ #include <maria.h> -#define HA_RECOVER_NONE 0 /* No automatic recover */ -#define HA_RECOVER_DEFAULT 1 /* Automatic recover active */ -#define HA_RECOVER_BACKUP 2 /* Make a backupfile on recover */ -#define HA_RECOVER_FORCE 4 /* Recover even if we loose rows */ -#define HA_RECOVER_QUICK 8 /* Don't check rows in data file */ - extern ulong maria_sort_buffer_size; extern TYPELIB maria_recover_typelib; extern ulong maria_recover_options; @@ -53,7 +47,7 @@ public: ~ha_maria() {} handler *clone(const char *name, MEM_ROOT *mem_root); const char *table_type() const - { return "MARIA"; } + { return "Aria"; } const char *index_type(uint key_number); const char **bas_ext() const; ulonglong table_flags() const diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index 81b436346b1..18ea1fc3997 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -176,6 +176,7 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share, PAGECACHE_LOCK_LEFT_UNLOCKED, PAGECACHE_PIN_LEFT_UNPINNED, PAGECACHE_WRITE_DELAY, 0, LSN_IMPOSSIBLE); + DBUG_ASSERT(!res); DBUG_RETURN(res); } else @@ -199,6 +200,7 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share, page_link.unlock= PAGECACHE_LOCK_LEFT_UNLOCKED; page_link.changed= 1; push_dynamic(&bitmap->pinned_pages, (const uchar*) (void*) &page_link); + DBUG_ASSERT(!res); DBUG_RETURN(res); } } @@ -274,31 +276,32 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file, first_bitmap_with_space= share->state.first_bitmap_with_space; _ma_bitmap_reset_cache(share); - /* - The bitmap used to map the file are aligned on 6 bytes. We now - calculate the max file size that can be used by the bitmap. This - is needed to get ma_info() give a true file size so that the user can - estimate if there is still space free for records in the file. - */ - { - pgcache_page_no_t last_bitmap_page; - ulong blocks, bytes; - - last_bitmap_page= *last_page - *last_page % bitmap->pages_covered; - blocks= *last_page - last_bitmap_page; - bytes= (blocks * 3) / 8; /* 3 bit per page / 8 bits per byte */ - /* Size needs to be aligned on 6 */ - bytes/= 6; - bytes*= 6; - bitmap->last_bitmap_page= last_bitmap_page; - bitmap->last_total_size= bytes; - *last_page= ((last_bitmap_page + bytes*8/3)); - } + /* + The bitmap used to map the file are aligned on 6 bytes. We now + calculate the max file size that can be used by the bitmap. This + is needed to get ma_info() give a true file size so that the user can + estimate if there is still space free for records in the file. + */ + { + pgcache_page_no_t last_bitmap_page; + pgcache_page_no_t blocks, bytes; + + last_bitmap_page= *last_page - *last_page % bitmap->pages_covered; + blocks= *last_page - last_bitmap_page; + bytes= (blocks * 3) / 8; /* 3 bit per page / 8 bits per byte */ + /* Size needs to be aligned on 6 */ + bytes/= 6; + bytes*= 6; + bitmap->last_bitmap_page= last_bitmap_page; + bitmap->last_total_size= bytes; + *last_page= ((last_bitmap_page + bytes*8/3)); + } /* Restore first_bitmap_with_space if it's resonable */ if (first_bitmap_with_space <= (share->state.state.data_file_length / share->block_size)) share->state.first_bitmap_with_space= first_bitmap_with_space; + return 0; } @@ -336,6 +339,40 @@ my_bool _ma_bitmap_end(MARIA_SHARE *share) return res; } +/* + Ensure that we have incremented open count before we try to read/write + a page while we have the bitmap lock. + This is needed to ensure that we don't call _ma_mark_file_changed() as + part of flushing a page to disk, as this locks share->internal_lock + and then mutex lock would happen in the wrong order. +*/ + +static inline void _ma_bitmap_mark_file_changed(MARIA_SHARE *share, + my_bool flush_translog) +{ + /* + It's extremely unlikely that the following test is true as it + only happens once if the table has changed. + */ + if (unlikely(!share->global_changed && + (share->state.changed & STATE_CHANGED))) + { + /* purecov: begin inspected */ + /* unlock mutex as it can't be hold during _ma_mark_file_changed() */ + pthread_mutex_unlock(&share->bitmap.bitmap_lock); + + /* + We have to flush the translog to ensure we have registered that the + table is open. + */ + if (flush_translog && share->now_transactional) + (void) translog_flush(share->state.logrec_file_id); + + _ma_mark_file_changed(share); + pthread_mutex_lock(&share->bitmap.bitmap_lock); + /* purecov: end */ + } +} /* Send updated bitmap to the page cache @@ -372,6 +409,12 @@ my_bool _ma_bitmap_flush(MARIA_SHARE *share) pthread_mutex_lock(&share->bitmap.bitmap_lock); if (share->bitmap.changed) { + /* + We have to mark the file changed here, as otherwise the following + write to pagecache may force a page out from this file, which would + cause _ma_mark_file_changed() to be called with bitmaplock hold! + */ + _ma_bitmap_mark_file_changed(share, 1); res= write_changed_bitmap(share, &share->bitmap); share->bitmap.changed= 0; } @@ -439,24 +482,13 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share) DBUG_RETURN(0); } + _ma_bitmap_mark_file_changed(share, 0); + /* - Before flusing bitmap, ensure that we have incremented open count. - This is needed to ensure that we don't call - _ma_mark_file_changed() as part of flushing bitmap page as in this - case we would use mutex lock in wrong order. - It's extremely unlikely that the following test is true as normally - this is happening when table is flushed. + The following should be true as it was tested above. We have to test + this again as _ma_bitmap_mark_file_changed() did temporarly release + the bitmap mutex. */ - if (unlikely(!share->global_changed)) - { - /* purecov: begin inspected */ - /* unlock bitmap mutex as it can't be hold during _ma_mark_file_changed */ - pthread_mutex_unlock(&bitmap->bitmap_lock); - _ma_mark_file_changed(share); - pthread_mutex_lock(&bitmap->bitmap_lock); - /* purecov: end */ - } - if (bitmap->changed || bitmap->changed_not_flushed) { bitmap->flush_all_requested++; @@ -656,7 +688,8 @@ void _ma_bitmap_delete_all(MARIA_SHARE *share) @notes This is called after we have swapped file descriptors and we want - bitmap to forget all cached information + bitmap to forget all cached information. + It's also called directly after we have opened a file. */ void _ma_bitmap_reset_cache(MARIA_SHARE *share) @@ -1061,6 +1094,13 @@ static my_bool _ma_change_bitmap_page(MARIA_HA *info, { DBUG_ENTER("_ma_change_bitmap_page"); + /* + We have to mark the file changed here, as otherwise the following + read/write to pagecache may force a page out from this file, which would + cause _ma_mark_file_changed() to be called with bitmaplock hold! + */ + _ma_bitmap_mark_file_changed(info->s, 1); + if (bitmap->changed) { if (write_changed_bitmap(info->s, bitmap)) @@ -1811,7 +1851,7 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size, find_where_to_split_row() share Maria share row Information of what is in the row (from calc_record_size()) - extents_length Number of bytes needed to store all extents + extents Max number of extents we have to store in header split_size Free size on the page (The head length must be less than this) @@ -1820,7 +1860,7 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size, */ static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row, - uint extents_length, uint split_size) + uint extents, uint split_size) { uint *lengths, *lengths_end; /* @@ -1830,19 +1870,20 @@ static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row, - One extent */ uint row_length= (row->min_length + - size_to_store_key_length(extents_length) + + size_to_store_key_length(extents) + ROW_EXTENT_SIZE); - DBUG_ASSERT(row_length < split_size); + DBUG_ASSERT(row_length <= split_size); + /* Store first in all_field_lengths the different parts that are written to the row. This needs to be in same order as in ma_block_rec.c::write_block_record() */ - row->null_field_lengths[-3]= extents_length; + row->null_field_lengths[-3]= extents * ROW_EXTENT_SIZE; row->null_field_lengths[-2]= share->base.fixed_not_null_fields_length; row->null_field_lengths[-1]= row->field_lengths_length; for (lengths= row->null_field_lengths - EXTRA_LENGTH_FIELDS, - lengths_end= (lengths + share->base.pack_fields - share->base.blobs + + lengths_end= (lengths + share->base.fields - share->base.blobs + EXTRA_LENGTH_FIELDS); lengths < lengths_end; lengths++) { if (row_length + *lengths > split_size) @@ -1998,18 +2039,19 @@ my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row, head_length+= ELEMENTS_RESERVED_FOR_MAIN_PART * ROW_EXTENT_SIZE; /* The first segment size is stored in 'row_length' */ - row_length= find_where_to_split_row(share, row, extents_length, + row_length= find_where_to_split_row(share, row, row->extents_count + + ELEMENTS_RESERVED_FOR_MAIN_PART-1, max_page_size); full_page_size= MAX_TAIL_SIZE(share->block_size); position= 0; - if (head_length - row_length <= full_page_size) + rest_length= head_length - row_length; + if (rest_length <= full_page_size) position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */ if (find_head(info, row_length, position)) goto abort; row->space_on_head_page= row_length; - rest_length= head_length - row_length; if (write_rest_of_head(info, position, rest_length)) goto abort; @@ -2076,8 +2118,7 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row, goto abort; /* Switch bitmap to current head page */ - bitmap_page= page / share->bitmap.pages_covered; - bitmap_page*= share->bitmap.pages_covered; + bitmap_page= page - page % share->bitmap.pages_covered; if (share->bitmap.page != bitmap_page && _ma_change_bitmap_page(info, &share->bitmap, bitmap_page)) @@ -2096,16 +2137,22 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row, /* Allocate enough space */ head_length+= ELEMENTS_RESERVED_FOR_MAIN_PART * ROW_EXTENT_SIZE; - /* The first segment size is stored in 'row_length' */ - row_length= find_where_to_split_row(share, row, extents_length, free_size); + /* + The first segment size is stored in 'row_length' + We have to add ELEMENTS_RESERVED_FOR_MAIN_PART here as the extent + information may be up to this size when the header splits. + */ + row_length= find_where_to_split_row(share, row, row->extents_count + + ELEMENTS_RESERVED_FOR_MAIN_PART-1, + free_size); position= 0; - if (head_length - row_length < MAX_TAIL_SIZE(share->block_size)) + rest_length= head_length - row_length; + if (rest_length <= MAX_TAIL_SIZE(share->block_size)) position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */ use_head(info, page, row_length, position); row->space_on_head_page= row_length; - rest_length= head_length - row_length; if (write_rest_of_head(info, position, rest_length)) goto abort; @@ -2193,7 +2240,7 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap, Get bitmap pattern for a given page SYNOPSIS - get_page_bits() + bitmap_get_page_bits() info Maria handler bitmap Bitmap handler page Page number @@ -2203,8 +2250,8 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap, ~0 Error (couldn't read page) */ -uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap, - pgcache_page_no_t page) +static uint bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap, + pgcache_page_no_t page) { pgcache_page_no_t bitmap_page; uint offset_page, offset, tmp; @@ -2230,6 +2277,19 @@ uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap, } +/* As above, but take a lock while getting the data */ + +uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap, + pgcache_page_no_t page) +{ + uint tmp; + pthread_mutex_lock(&bitmap->bitmap_lock); + tmp= bitmap_get_page_bits(info, bitmap, page); + pthread_mutex_unlock(&bitmap->bitmap_lock); + return tmp; +} + + /* Mark all pages in a region as free @@ -2309,6 +2369,7 @@ my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info, DBUG_RETURN(0); } + /* Set all pages in a region as used @@ -2545,7 +2606,7 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks) else { DBUG_ASSERT(current_bitmap_value == - _ma_bitmap_get_page_bits(info, bitmap, block->page)); + bitmap_get_page_bits(info, bitmap, block->page)); } /* Handle all full pages and tail pages (for head page and blob) */ @@ -2577,7 +2638,7 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks) to not set the bits to the same value as before. */ DBUG_ASSERT(current_bitmap_value == - _ma_bitmap_get_page_bits(info, bitmap, block->page)); + bitmap_get_page_bits(info, bitmap, block->page)); if (bits != current_bitmap_value) { diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index c7c1a131441..6165e211566 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -1034,7 +1034,7 @@ make_space_for_directory(MARIA_HA *info, UNDO of DELETE (in which case we know the row was on the page before) or if the bitmap told us there was space on page */ - DBUG_ASSERT(0); + DBUG_ASSERT(!maria_assert_if_crashed_table); return(1); } } @@ -1721,7 +1721,7 @@ struct st_row_pos_info static my_bool get_head_or_tail_page(MARIA_HA *info, - MARIA_BITMAP_BLOCK *block, + const MARIA_BITMAP_BLOCK *block, uchar *buff, uint length, uint page_type, enum pagecache_page_lock lock, struct st_row_pos_info *res) @@ -1791,6 +1791,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info, DBUG_RETURN(0); crashed: + DBUG_ASSERT(!maria_assert_if_crashed_table); _ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); /* File crashed */ DBUG_RETURN(1); } @@ -1820,7 +1821,7 @@ crashed: */ static my_bool get_rowpos_in_head_or_tail_page(MARIA_HA *info, - MARIA_BITMAP_BLOCK *block, + const MARIA_BITMAP_BLOCK *block, uchar *buff, uint length, uint page_type, enum pagecache_page_lock lock, @@ -1884,6 +1885,7 @@ static my_bool get_rowpos_in_head_or_tail_page(MARIA_HA *info, DBUG_RETURN(0); err: + DBUG_ASSERT(!maria_assert_if_crashed_table); _ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); /* File crashed */ DBUG_RETURN(1); } @@ -2255,7 +2257,7 @@ static void store_extent_info(uchar *to, for (block= first_block, end_block= first_block+count ; block < end_block; block++) { - /* The following is only false for marker blocks */ + /* The following is only false for marker (unused) blocks */ if (likely(block->used & BLOCKUSED_USED)) { uint page_count= block->page_count; @@ -2770,7 +2772,7 @@ static my_bool write_block_record(MARIA_HA *info, DBUG_ASSERT(length <= column->length); break; default: /* Wrong data */ - DBUG_ASSERT(0); + DBUG_ASSERT(!maria_assert_if_crashed_table); length=0; break; } @@ -3086,9 +3088,10 @@ static my_bool write_block_record(MARIA_HA *info, extent_data= row_extents_second_part + ((last_head_block - head_block) - 2) * ROW_EXTENT_SIZE; } - DBUG_ASSERT(uint2korr(extent_data+5) & TAIL_BIT); + /* Write information for tail block in the reserved space */ page_store(extent_data, head_tail_block->page); - int2store(extent_data + PAGE_STORE_SIZE, head_tail_block->page_count); + pagerange_store(extent_data + PAGE_STORE_SIZE, + head_tail_block->page_count); } } else @@ -3433,6 +3436,7 @@ static my_bool write_block_record(MARIA_HA *info, DBUG_RETURN(0); crashed: + DBUG_ASSERT(!maria_assert_if_crashed_table); /* Something was wrong with data on page */ _ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); @@ -3640,6 +3644,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info) } } } + _ma_bitmap_unlock(share); if (share->now_transactional) { if (_ma_write_clr(info, info->cur_row.orig_undo_lsn, @@ -3649,7 +3654,6 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info) &lsn, (void*) 0)) res= 1; } - _ma_bitmap_unlock(share); _ma_unpin_all_pages_and_finalize_row(info, lsn); DBUG_RETURN(res); } @@ -3827,6 +3831,7 @@ static my_bool _ma_update_block_record2(MARIA_HA *info, DBUG_RETURN(0); err: + DBUG_ASSERT(!maria_assert_if_crashed_table); DBUG_PRINT("error", ("errpos: %d", errpos)); if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); @@ -3967,6 +3972,7 @@ static my_bool _ma_update_at_original_place(MARIA_HA *info, DBUG_RETURN(0); err: + DBUG_ASSERT(!maria_assert_if_crashed_table); _ma_mark_file_crashed(share); if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); @@ -4201,6 +4207,13 @@ static my_bool delete_head_or_tail(MARIA_HA *info, log_data, NULL)) DBUG_RETURN(1); } + /* + Mark that this page must be written to disk by page cache, even + if we could call pagecache_delete() on it. + This is needed to ensure that repair finds the empty page on disk + and not old data. + */ + pagecache_set_write_on_delete_by_link(page_link.link); DBUG_ASSERT(empty_space >= share->bitmap.sizes[0]); } @@ -4341,6 +4354,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record) DBUG_RETURN(0); err: + DBUG_ASSERT(!maria_assert_if_crashed_table); _ma_bitmap_flushable(info, -1); _ma_unpin_all_pages_and_finalize_row(info, LSN_IMPOSSIBLE); DBUG_RETURN(1); @@ -4541,6 +4555,7 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent, crashed: + DBUG_ASSERT(!maria_assert_if_crashed_table); _ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); DBUG_PRINT("error", ("wrong extent information")); DBUG_RETURN(0); @@ -4688,6 +4703,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record, if (!info->trn) { /* File crashed */ + DBUG_ASSERT(!maria_assert_if_crashed_table); _ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); DBUG_RETURN(HA_ERR_WRONG_IN_RECORD); } @@ -4969,6 +4985,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record, DBUG_RETURN(0); err: + DBUG_ASSERT(!maria_assert_if_crashed_table); /* Something was wrong with data on record */ DBUG_PRINT("error", ("Found record with wrong data")); _ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); @@ -5113,6 +5130,7 @@ int _ma_read_block_record(MARIA_HA *info, uchar *record, DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == HEAD_PAGE); if (!(data= get_record_position(buff, block_size, offset, &end_of_data))) { + DBUG_ASSERT(!maria_assert_if_crashed_table); DBUG_PRINT("error", ("Wrong directory entry in data block")); my_errno= HA_ERR_RECORD_DELETED; /* File crashed */ DBUG_RETURN(HA_ERR_RECORD_DELETED); @@ -5343,7 +5361,7 @@ restart_record_read: #ifdef SANITY_CHECKS if (info->scan.dir < info->scan.dir_end) { - DBUG_ASSERT(0); + DBUG_ASSERT(!maria_assert_if_crashed_table); goto err; } #endif @@ -5455,7 +5473,7 @@ restart_bitmap_scan: /* Read next bitmap */ info->scan.bitmap_page+= share->bitmap.pages_covered; filepos= (my_off_t) info->scan.bitmap_page * block_size; - if (unlikely(filepos >= share->state.state.data_file_length)) + if (unlikely(info->scan.bitmap_page >= info->scan.max_page)) { DBUG_PRINT("info", ("Found end of file")); DBUG_RETURN((my_errno= HA_ERR_END_OF_FILE)); @@ -5473,6 +5491,7 @@ restart_bitmap_scan: goto restart_bitmap_scan; err: + DBUG_ASSERT(!maria_assert_if_crashed_table); DBUG_PRINT("error", ("Wrong data on page")); _ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); DBUG_RETURN(HA_ERR_WRONG_IN_RECORD); @@ -6404,7 +6423,7 @@ err: PAGECACHE_UNPIN, LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, 0, FALSE); _ma_mark_file_crashed(share); - DBUG_ASSERT(0); /* catch recovery errors early */ + DBUG_ASSERT(!maria_assert_if_crashed_table); /* catch recovery error early */ DBUG_RETURN((my_errno= error)); } @@ -6507,7 +6526,7 @@ err: PAGECACHE_UNPIN, LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, 0, FALSE); _ma_mark_file_crashed(share); - DBUG_ASSERT(0); + DBUG_ASSERT(!maria_assert_if_crashed_table); DBUG_RETURN((my_errno= error)); } @@ -6579,7 +6598,7 @@ uint _ma_apply_redo_free_blocks(MARIA_HA *info, { pthread_mutex_unlock(&share->bitmap.bitmap_lock); _ma_mark_file_crashed(share); - DBUG_ASSERT(0); + DBUG_ASSERT(!maria_assert_if_crashed_table); DBUG_RETURN(res); } } @@ -6665,7 +6684,7 @@ uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn, err: _ma_mark_file_crashed(share); - DBUG_ASSERT(0); + DBUG_ASSERT(!maria_assert_if_crashed_table); DBUG_RETURN(1); } @@ -6866,7 +6885,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, err: _ma_mark_file_crashed(share); - DBUG_ASSERT(0); + DBUG_ASSERT(!maria_assert_if_crashed_table); DBUG_RETURN(1); } @@ -6936,6 +6955,7 @@ end: DBUG_RETURN(res); err: + DBUG_ASSERT(!maria_assert_if_crashed_table); res= 1; _ma_mark_file_crashed(share); goto end; @@ -7174,6 +7194,7 @@ my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn, DBUG_RETURN(0); err: + DBUG_ASSERT(!maria_assert_if_crashed_table); _ma_mark_file_crashed(share); if (info->non_flushable_state) _ma_bitmap_flushable(info, -1); @@ -7349,6 +7370,7 @@ end: DBUG_RETURN(error); err: + DBUG_ASSERT(!maria_assert_if_crashed_table); error= 1; _ma_mark_file_crashed(share); goto end; diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h index 2a323d16ffa..45f5613bb60 100644 --- a/storage/maria/ma_blockrec.h +++ b/storage/maria/ma_blockrec.h @@ -59,7 +59,6 @@ /* Minimum header size needed for a new row */ #define BASE_ROW_HEADER_SIZE FLAG_SIZE -#define TRANS_ROW_EXTRA_HEADER_SIZE TRANSID_SIZE #define PAGE_TYPE_MASK 7 enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_TYPE }; diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 62299df9f7d..ef6484adbe9 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -234,14 +234,14 @@ int maria_chk_del(HA_CHECK *param, register MARIA_HA *info, { if (test_flag & T_VERBOSE) puts(""); _ma_check_print_error(param,"Can't read delete-link at filepos: %s", - llstr(next_link,buff)); + llstr(next_link,buff)); DBUG_RETURN(1); } if (*buff != '\0') { if (test_flag & T_VERBOSE) puts(""); _ma_check_print_error(param,"Record at pos: %s is not remove-marked", - llstr(next_link,buff)); + llstr(next_link,buff)); goto wrong; } if (share->options & HA_OPTION_PACK_RECORD) @@ -250,7 +250,9 @@ int maria_chk_del(HA_CHECK *param, register MARIA_HA *info, if (empty && prev_link != old_link) { if (test_flag & T_VERBOSE) puts(""); - _ma_check_print_error(param,"Deleted block at %s doesn't point back at previous delete link",llstr(next_link,buff2)); + _ma_check_print_error(param, + "Deleted block at %s doesn't point back at previous delete link", + llstr(next_link,buff2)); goto wrong; } old_link=next_link; @@ -269,23 +271,23 @@ int maria_chk_del(HA_CHECK *param, register MARIA_HA *info, if (empty != share->state.state.empty) { _ma_check_print_warning(param, - "Found %s deleted space in delete link chain. Should be %s", - llstr(empty,buff2), - llstr(share->state.state.empty,buff)); + "Found %s deleted space in delete link chain. Should be %s", + llstr(empty,buff2), + llstr(share->state.state.empty,buff)); } if (next_link != HA_OFFSET_ERROR) { _ma_check_print_error(param, - "Found more than the expected %s deleted rows in delete link chain", - llstr(share->state.state.del, buff)); + "Found more than the expected %s deleted rows in delete link chain", + llstr(share->state.state.del, buff)); goto wrong; } if (i != 0) { _ma_check_print_error(param, - "Found %s deleted rows in delete link chain. Should be %s", - llstr(share->state.state.del - i, buff2), - llstr(share->state.state.del, buff)); + "Found %s deleted rows in delete link chain. Should be %s", + llstr(share->state.state.del - i, buff2), + llstr(share->state.state.del, buff)); goto wrong; } } @@ -410,13 +412,13 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info) { error=1; _ma_check_print_error(param, - "Size of indexfile is: %-8s Should be: %s", + "Size of indexfile is: %-8s Expected: %s", llstr(size,buff), llstr(skr,buff2)); share->state.state.key_file_length= size; } else if (!(param->testflag & T_VERY_SILENT)) _ma_check_print_warning(param, - "Size of indexfile is: %-8s Should be: %s", + "Size of indexfile is: %-8s Expected: %s", llstr(size,buff), llstr(skr,buff2)); } if (size > share->base.max_key_file_length) @@ -431,8 +433,8 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info) ulonglong2double(share->state.state.key_file_length) > ulonglong2double(share->base.margin_key_file_length)*0.9) _ma_check_print_warning(param,"Keyfile is almost full, %10s of %10s used", - llstr(share->state.state.key_file_length,buff), - llstr(share->base.max_key_file_length,buff)); + llstr(share->state.state.key_file_length,buff), + llstr(share->base.max_key_file_length,buff)); size= my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)); skr=(my_off_t) share->state.state.data_file_length; @@ -449,15 +451,15 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info) if (skr > size && skr != size + MEMMAP_EXTRA_MARGIN) { error=1; - _ma_check_print_error(param,"Size of datafile is: %-9s Should be: %s", + _ma_check_print_error(param,"Size of datafile is: %-9s Expected: %s", llstr(size,buff), llstr(skr,buff2)); param->testflag|=T_RETRY_WITHOUT_QUICK; } else { _ma_check_print_warning(param, - "Size of datafile is: %-9s Should be: %s", - llstr(size,buff), llstr(skr,buff2)); + "Size of datafile is: %-9s Expected: %s", + llstr(size,buff), llstr(skr,buff2)); } } if (size > share->base.max_data_file_length) @@ -471,8 +473,8 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info) ulonglong2double(share->state.state.data_file_length) > (ulonglong2double(share->base.max_data_file_length)*0.9)) _ma_check_print_warning(param, "Datafile is almost full, %10s of %10s used", - llstr(share->state.state.data_file_length,buff), - llstr(share->base.max_data_file_length,buff2)); + llstr(share->state.state.data_file_length,buff), + llstr(share->base.max_data_file_length,buff2)); DBUG_RETURN(error); } /* maria_chk_size */ @@ -1813,7 +1815,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend, char llbuff[22], llbuff2[22]; uint block_size= share->block_size; ha_rows full_page_count, tail_count; - my_bool full_dir; + my_bool full_dir, now_transactional; uint offset_page, offset, free_count; LINT_INIT(full_dir); @@ -1824,6 +1826,10 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend, my_errno); return 1; } + + now_transactional= info->s->now_transactional; + info->s->now_transactional= 0; /* Don't log changes */ + bitmap_buff= info->scan.bitmap_buff; page_buff= info->scan.page_buff; full_page_count= tail_count= 0; @@ -1843,7 +1849,8 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend, if (_ma_killed_ptr(param)) { _ma_scan_end_block_record(info); - return -1; + info->s->now_transactional= now_transactional; + return -1; /* Interrupted */ } if ((page % share->bitmap.pages_covered) == 0) { @@ -2019,10 +2026,12 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend, llstr(param->tail_count, llbuff), llstr(tail_count, llbuff2)); + info->s->now_transactional= now_transactional; return param->error_printed != 0; err: _ma_scan_end_block_record(info); + info->s->now_transactional= now_transactional; return 1; } @@ -2314,7 +2323,7 @@ static int initialize_variables_for_repair(HA_CHECK *param, { MARIA_SHARE *share= info->s; - /* Ro allow us to restore state and check how state changed */ + /* Make a copy to allow us to restore state and check how state changed */ memcpy(org_share, share, sizeof(*share)); /* Repair code relies on share->state.state so we have to update it here */ @@ -2334,6 +2343,14 @@ static int initialize_variables_for_repair(HA_CHECK *param, param->testflag&= ~T_QUICK; param->org_key_map= share->state.key_map; + /* + Clear check variables set by repair. This is needed to allow one to run + several repair's in a row with same param + */ + param->retry_repair= 0; + param->warning_printed= 0; + param->error_printed= 0; + sort_param->sort_info= sort_info; sort_param->fix_datafile= ! rep_quick; sort_param->calc_checksum= test(param->testflag & T_CALC_CHECKSUM); @@ -2555,7 +2572,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, start_records= share->state.state.records; if (!(param->testflag & T_SILENT)) { - printf("- recovering (with keycache) MARIA-table '%s'\n",name); + printf("- recovering (with keycache) Aria-table '%s'\n",name); printf("Data records: %s\n", llstr(start_records, llbuff)); } @@ -3042,7 +3059,7 @@ int maria_sort_index(HA_CHECK *param, register MARIA_HA *info, char *name) DBUG_RETURN(0); if (!(param->testflag & T_SILENT)) - printf("- Sorting index for MARIA-table '%s'\n",name); + printf("- Sorting index for Aria-table '%s'\n",name); if (protect_against_repair_crash(info, param, FALSE)) DBUG_RETURN(1); @@ -3276,7 +3293,7 @@ static my_bool maria_zerofill_index(HA_CHECK *param, MARIA_HA *info, DBUG_ENTER("maria_zerofill_index"); if (!(param->testflag & T_SILENT)) - printf("- Zerofilling index for MARIA-table '%s'\n",name); + printf("- Zerofilling index for Aria-table '%s'\n",name); /* Go through the index file */ for (pos= share->base.keystart, page= (ulonglong) (pos / block_size); @@ -3371,7 +3388,7 @@ static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info, DBUG_RETURN(0); if (!(param->testflag & T_SILENT)) - printf("- Zerofilling data for MARIA-table '%s'\n",name); + printf("- Zerofilling data for Aria-table '%s'\n",name); /* Go through the record file */ for (page= 1, pos= block_size; @@ -3629,7 +3646,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, start_records= share->state.state.records; if (!(param->testflag & T_SILENT)) { - printf("- recovering (with sort) MARIA-table '%s'\n",name); + printf("- recovering (with sort) Aria-table '%s'\n",name); printf("Data records: %s\n", llstr(start_records,llbuff)); } @@ -4136,7 +4153,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, start_records= share->state.state.records; if (!(param->testflag & T_SILENT)) { - printf("- parallel recovering (with sort) MARIA-table '%s'\n",name); + printf("- parallel recovering (with sort) Aria-table '%s'\n",name); printf("Data records: %s\n", llstr(start_records, llbuff)); } @@ -5734,7 +5751,7 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param) _ma_check_print_error(param, "Recover aborted; Can't run standard recovery on " "compressed tables with errors in data-file. " - "Use 'maria_chk --safe-recover' to fix it"); + "Use 'aria_chk --safe-recover' to fix it"); DBUG_RETURN(1); } @@ -6047,7 +6064,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename) (*org_info)->s->state.state.records= info.state->records; if (share.state.create_time) (*org_info)->s->state.create_time=share.state.create_time; -#ifdef EXTERNAL_LOCKING +#ifdef MARIA_EXTERNAL_LOCKING (*org_info)->s->state.unique= (*org_info)->this_unique= share.state.unique; #endif (*org_info)->s->state.state.checksum= info.state->checksum; @@ -6178,7 +6195,7 @@ void _ma_update_auto_increment_key(HA_CHECK *param, MARIA_HA *info, } if (!(param->testflag & T_SILENT) && !(param->testflag & T_REP)) - printf("Updating MARIA file: %s\n", param->isam_file_name); + printf("Updating Aria file: %s\n", param->isam_file_name); /* We have to use an allocated buffer instead of info->rec_buff as _ma_put_key_in_record() may use info->rec_buff @@ -6527,6 +6544,17 @@ static void copy_data_file_state(MARIA_STATE_INFO *to, } +/* Return 1 if block is full of zero's */ + +static my_bool zero_filled_block(uchar *tmp, uint length) +{ + while (length--) + if (*(tmp++) != 0) + return 0; + return 1; +} + + /* Read 'safely' next record while scanning table. @@ -6628,9 +6656,21 @@ read_next_page: { if (my_errno == HA_ERR_WRONG_CRC) { - _ma_check_print_info(sort_info->param, - "Wrong CRC on datapage at %s", - llstr(page, llbuff)); + /* + Don't give errors for zero filled blocks. These can + sometimes be found at end of a bitmap when we wrote a big + record last that was moved to the next bitmap. + */ + if (!zero_filled_block(info->scan.page_buff, share->block_size) || + _ma_check_bitmap_data(info, UNALLOCATED_PAGE, 0, + _ma_bitmap_get_page_bits(info, + &share->bitmap, + page))) + { + _ma_check_print_info(sort_info->param, + "Wrong CRC on datapage at %s", + llstr(page, llbuff)); + } continue; } DBUG_RETURN(my_errno); @@ -6822,7 +6862,7 @@ static void _ma_check_print_not_visible_error(HA_CHECK *param, TrID used_trid) { _ma_check_print_warning(param, "Found row with transaction id %s but no " - "maria_control_file was used or specified. " + "aria_control_file was used or specified. " "The table may be corrupted", llstr(used_trid, buff)); } @@ -6830,7 +6870,7 @@ static void _ma_check_print_not_visible_error(HA_CHECK *param, TrID used_trid) { _ma_check_print_error(param, "Found row with transaction id %s when max " - "transaction id according to maria_control_file " + "transaction id according to aria_control_file " "is %s", llstr(used_trid, buff), llstr(param->max_trid, buff2)); diff --git a/storage/maria/ma_check_standalone.h b/storage/maria/ma_check_standalone.h index 9b30c96089f..8cda285bb99 100644 --- a/storage/maria/ma_check_standalone.h +++ b/storage/maria/ma_check_standalone.h @@ -64,7 +64,7 @@ void _ma_check_print_warning(HA_CHECK *param, const char *fmt,...) if (!param->warning_printed && !param->error_printed) { if (param->testflag & T_SILENT) - fprintf(stderr,"%s: MARIA file %s\n",my_progname_short, + fprintf(stderr,"%s: Aria file %s\n",my_progname_short, param->isam_file_name); param->out_flag|= O_DATA_LOST; } @@ -90,7 +90,7 @@ void _ma_check_print_error(HA_CHECK *param, const char *fmt,...) if (!param->warning_printed && !param->error_printed) { if (param->testflag & T_SILENT) - fprintf(stderr,"%s: MARIA file %s\n",my_progname_short,param->isam_file_name); + fprintf(stderr,"%s: Aria file %s\n",my_progname_short,param->isam_file_name); param->out_flag|= O_DATA_LOST; } param->error_printed|=1; diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c index fdeec982f08..6576c365a47 100644 --- a/storage/maria/ma_checkpoint.c +++ b/storage/maria/ma_checkpoint.c @@ -35,6 +35,7 @@ #include "ma_blockrec.h" #include "ma_checkpoint.h" #include "ma_loghandler_lsn.h" +#include "ma_servicethread.h" /** @brief type of checkpoint currently running */ @@ -43,10 +44,9 @@ static CHECKPOINT_LEVEL checkpoint_in_progress= CHECKPOINT_NONE; static pthread_mutex_t LOCK_checkpoint; /** @brief for killing the background checkpoint thread */ static pthread_cond_t COND_checkpoint; -/** @brief if checkpoint module was inited or not */ -static my_bool checkpoint_inited= FALSE; -/** @brief 'kill' flag for the background checkpoint thread */ -static int checkpoint_thread_die; +/** @brief control structure for checkpoint background thread */ +static MA_SERVICE_THREAD_CONTROL checkpoint_control= + {THREAD_DEAD, FALSE, &LOCK_checkpoint, &COND_checkpoint}; /* is ulong like pagecache->blocks_changed */ static ulong pages_to_flush_before_next_checkpoint; static PAGECACHE_FILE *dfiles, /**< data files to flush in background */ @@ -99,7 +99,7 @@ int ma_checkpoint_execute(CHECKPOINT_LEVEL level, my_bool no_wait) int result= 0; DBUG_ENTER("ma_checkpoint_execute"); - if (!checkpoint_inited) + if (!checkpoint_control.inited) { /* If ha_maria failed to start, maria_panic_hton is called, we come here. @@ -329,17 +329,17 @@ int ma_checkpoint_init(ulong interval) pthread_t th; int res= 0; DBUG_ENTER("ma_checkpoint_init"); - checkpoint_inited= TRUE; - checkpoint_thread_die= 2; /* not yet born == dead */ - if (pthread_mutex_init(&LOCK_checkpoint, MY_MUTEX_INIT_SLOW) || - pthread_cond_init(&COND_checkpoint, 0)) + if (ma_service_thread_control_init(&checkpoint_control)) res= 1; else if (interval > 0) { compile_time_assert(sizeof(void *) >= sizeof(ulong)); if (!(res= pthread_create(&th, NULL, ma_checkpoint_background, (void *)interval))) - checkpoint_thread_die= 0; /* thread lives, will have to be killed */ + { + /* thread lives, will have to be killed */ + checkpoint_control.status= THREAD_RUNNING; + } } DBUG_RETURN(res); } @@ -428,30 +428,12 @@ void ma_checkpoint_end(void) DBUG_EXECUTE_IF("maria_crash", { DBUG_PRINT("maria_crash", ("now")); DBUG_ABORT(); }); - if (checkpoint_inited) + if (checkpoint_control.inited) { - pthread_mutex_lock(&LOCK_checkpoint); - if (checkpoint_thread_die != 2) /* thread was started ok */ - { - DBUG_PRINT("info",("killing Maria background checkpoint thread")); - checkpoint_thread_die= 1; /* kill it */ - do /* and wait for it to be dead */ - { - /* wake it up if it was in a sleep */ - pthread_cond_broadcast(&COND_checkpoint); - DBUG_PRINT("info",("waiting for Maria background checkpoint thread" - " to die")); - pthread_cond_wait(&COND_checkpoint, &LOCK_checkpoint); - } - while (checkpoint_thread_die != 2); - } - pthread_mutex_unlock(&LOCK_checkpoint); + ma_service_thread_control_end(&checkpoint_control); my_free((uchar *)dfiles, MYF(MY_ALLOW_ZERO_PTR)); my_free((uchar *)kfiles, MYF(MY_ALLOW_ZERO_PTR)); dfiles= kfiles= NULL; - pthread_mutex_destroy(&LOCK_checkpoint); - pthread_cond_destroy(&COND_checkpoint); - checkpoint_inited= FALSE; } DBUG_VOID_RETURN; } @@ -551,10 +533,13 @@ filter_flush_file_evenly(enum pagecache_page_type type, risk could be that while a checkpoint happens no LRD flushing happens. */ +static ulong maria_checkpoint_min_cache_activity= 10*1024*1024; +/* Set in ha_maria.cc */ +ulong maria_checkpoint_min_log_activity= 1*1024*1024; + pthread_handler_t ma_checkpoint_background(void *arg) { /** @brief At least this of log/page bytes written between checkpoints */ - const uint checkpoint_min_activity= 2*1024*1024; /* If the interval could be changed by the user while we are in this thread, it could be annoying: for example it could cause "case 2" to be executed @@ -591,10 +576,12 @@ pthread_handler_t ma_checkpoint_background(void *arg) #if 0 /* good for testing, to do a lot of checkpoints, finds a lot of bugs */ sleeps=0; #endif - struct timespec abstime; switch (sleeps % interval) { case 0: + { + TRANSLOG_ADDRESS horizon= translog_get_horizon(); + /* With background flushing evenly distributed over the time between two checkpoints, we should have only little flushing to do @@ -607,15 +594,19 @@ pthread_handler_t ma_checkpoint_background(void *arg) would decrease the amount of read pages in recovery). In case of one short statement per minute (very low load), we don't want to checkpoint every minute, hence the positive - checkpoint_min_activity. + maria_checkpoint_min_activity. */ - if (((translog_get_horizon() - log_horizon_at_last_checkpoint) + - (maria_pagecache->global_cache_write - - pagecache_flushes_at_last_checkpoint) * - maria_pagecache->block_size) < checkpoint_min_activity) + if ((ulonglong) (horizon - log_horizon_at_last_checkpoint) <= + maria_checkpoint_min_log_activity && + ((ulonglong) (maria_pagecache->global_cache_write - + pagecache_flushes_at_last_checkpoint) * + maria_pagecache->block_size) <= + maria_checkpoint_min_cache_activity) { - /* don't take checkpoint, so don't know what to flush */ - pages_to_flush_before_next_checkpoint= 0; + /* + Not enough has happend since last checkpoint. + Sleep for a while and try again later + */ sleep_time= interval; break; } @@ -635,6 +626,7 @@ pthread_handler_t ma_checkpoint_background(void *arg) and sleep until the next checkpoint. */ break; + } case 1: /* set up parameters for background page flushing */ filter_param.up_to_lsn= last_checkpoint_lsn; @@ -704,25 +696,11 @@ pthread_handler_t ma_checkpoint_background(void *arg) sleep_time= interval - (sleeps % interval); } } - pthread_mutex_lock(&LOCK_checkpoint); - if (checkpoint_thread_die == 1) - break; -#if 0 /* good for testing, to do a lot of checkpoints, finds a lot of bugs */ - pthread_mutex_unlock(&LOCK_checkpoint); - my_sleep(100000); /* a tenth of a second */ - pthread_mutex_lock(&LOCK_checkpoint); -#else - /* To have a killable sleep, we use timedwait like our SQL GET_LOCK() */ - DBUG_PRINT("info", ("sleeping %u seconds", sleep_time)); - set_timespec(abstime, sleep_time); - pthread_cond_timedwait(&COND_checkpoint, &LOCK_checkpoint, &abstime); -#endif - if (checkpoint_thread_die == 1) + if (my_service_thread_sleep(&checkpoint_control, + sleep_time * 1000000000ULL)) break; - pthread_mutex_unlock(&LOCK_checkpoint); sleeps+= sleep_time; } - pthread_mutex_unlock(&LOCK_checkpoint); DBUG_PRINT("info",("Maria background checkpoint thread ends")); { CHECKPOINT_LEVEL level= CHECKPOINT_FULL; @@ -733,12 +711,7 @@ pthread_handler_t ma_checkpoint_background(void *arg) DBUG_EXECUTE_IF("maria_checkpoint_indirect", level= CHECKPOINT_INDIRECT;); ma_checkpoint_execute(level, FALSE); } - pthread_mutex_lock(&LOCK_checkpoint); - checkpoint_thread_die= 2; /* indicate that we are dead */ - /* wake up ma_checkpoint_end() which may be waiting for our death */ - pthread_cond_broadcast(&COND_checkpoint); - /* broadcast was inside unlock because ma_checkpoint_end() destroys mutex */ - pthread_mutex_unlock(&LOCK_checkpoint); + my_service_thread_signal_end(&checkpoint_control); my_thread_end(); return 0; } @@ -1049,17 +1022,25 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) possible that Recovery does not start from before the REDO and thus the state is not recovered. A solution may be to set share->changed=1 under log mutex when writing log records. - But as anyway we have another problem below, this optimization would - be of little use. + + The current solution is to keep a copy the last saved state and + not write the state if it was same as last time. It's ok if + is_of_horizon would be different on disk if all other data is + the same. */ - /** @todo flush state only if changed since last checkpoint */ DBUG_ASSERT(share->last_version != 0); state_copy->state.is_of_horizon= share->state.is_of_horizon= - state_copies_horizon; - if (kfile.file >= 0) + share->checkpoint_state.is_of_horizon= state_copies_horizon; + if (kfile.file >= 0 && memcmp(&share->checkpoint_state, + &state_copy->state, + sizeof(state_copy->state))) + { sync_error|= _ma_state_info_write_sub(kfile.file, &state_copy->state, MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET); + memcpy(&share->checkpoint_state, + &state_copy->state, sizeof(state_copy->state)); + } /* We don't set share->changed=0 because it may interfere with a concurrent _ma_writeinfo() doing share->changed=1 (cancel its diff --git a/storage/maria/ma_checkpoint.h b/storage/maria/ma_checkpoint.h index 69645c6bcda..126f8111a23 100644 --- a/storage/maria/ma_checkpoint.h +++ b/storage/maria/ma_checkpoint.h @@ -89,4 +89,4 @@ static inline LSN lsn_read_non_atomic_32(const volatile LSN *x) @param sentence text to write */ #define ma_message_no_user(level, sentence) \ - my_printf_error(HA_ERR_GENERIC, "Maria engine: %s", MYF(level), sentence) + my_printf_error(HA_ERR_GENERIC, "Aria engine: %s", MYF(level), sentence) diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c index e97664ebe42..2427dfd042d 100644 --- a/storage/maria/ma_close.c +++ b/storage/maria/ma_close.c @@ -28,7 +28,8 @@ int maria_close(register MARIA_HA *info) my_bool share_can_be_freed= FALSE; MARIA_SHARE *share= info->s; DBUG_ENTER("maria_close"); - DBUG_PRINT("enter",("base: 0x%lx reopen: %u locks: %u", + DBUG_PRINT("enter",("name: '%s' base: 0x%lx reopen: %u locks: %u", + share->open_file_name.str, (long) info, (uint) share->reopen, (uint) share->tot_locks)); diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c index ac246f09337..6f9018885e9 100644 --- a/storage/maria/ma_control_file.c +++ b/storage/maria/ma_control_file.c @@ -234,7 +234,7 @@ static int lock_control_file(const char *name) { if (retry == 0) my_printf_error(HA_ERR_INITIALIZATION, - "Can't lock maria control file '%s' for exclusive use, " + "Can't lock aria control file '%s' for exclusive use, " "error: %d. Will retry for %d seconds", 0, name, my_errno, MARIA_MAX_CONTROL_FILE_LOCK_RETRY); if (retry++ > MARIA_MAX_CONTROL_FILE_LOCK_RETRY) @@ -372,14 +372,14 @@ CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, CF_MAGIC_STRING, CF_MAGIC_STRING_SIZE)) { error= CONTROL_FILE_BAD_MAGIC_STRING; - errmsg= "Missing valid id at start of file. File is not a valid maria control file"; + errmsg= "Missing valid id at start of file. File is not a valid aria control file"; goto err; } if (buffer[CF_VERSION_OFFSET] > CONTROL_FILE_VERSION) { error= CONTROL_FILE_BAD_VERSION; - sprintf(errmsg_buff, "File is from a future maria system: %d. Current version is: %d", + sprintf(errmsg_buff, "File is from a future aria system: %d. Current version is: %d", (int) buffer[CF_VERSION_OFFSET], CONTROL_FILE_VERSION); errmsg= errmsg_buff; goto err; @@ -402,7 +402,7 @@ CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, { error= CONTROL_FILE_WRONG_BLOCKSIZE; sprintf(errmsg_buff, - "Block size in control file (%u) is different than given maria_block_size: %u", + "Block size in control file (%u) is different than given aria_block_size: %u", new_block_size, (uint) maria_block_size); errmsg= errmsg_buff; goto err; @@ -445,7 +445,7 @@ ok: err: if (print_error) my_printf_error(HA_ERR_INITIALIZATION, - "Got error '%s' when trying to use maria control file " + "Got error '%s' when trying to use aria control file " "'%s'", 0, errmsg, name); ma_control_file_end(); /* will unlock file if needed */ DBUG_RETURN(error); diff --git a/storage/maria/ma_control_file.h b/storage/maria/ma_control_file.h index 4cb5527620d..f828ae69c6d 100644 --- a/storage/maria/ma_control_file.h +++ b/storage/maria/ma_control_file.h @@ -21,7 +21,7 @@ #ifndef _ma_control_file_h #define _ma_control_file_h -#define CONTROL_FILE_BASE_NAME "maria_log_control" +#define CONTROL_FILE_BASE_NAME "aria_log_control" /* Major version for control file. Should only be changed when doing big changes that made the new control file incompatible with all diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c index 4d52a13453d..54ebcdc709e 100644 --- a/storage/maria/ma_create.c +++ b/storage/maria/ma_create.c @@ -204,7 +204,8 @@ int maria_create(const char *name, enum data_file_type datafile_type, pack_reclength++; not_block_record_extra_length++; max_field_lengths++; - packed++; + if (datafile_type != DYNAMIC_RECORD) + packed++; column->fill_length= 1; options|= HA_OPTION_NULL_FIELDS; /* Use ma_checksum() */ @@ -661,7 +662,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, if (info_length > 65535) { my_printf_error(HA_WRONG_CREATE_OPTION, - "Maria table '%s' has too many columns and/or " + "Aria table '%s' has too many columns and/or " "indexes and/or unique constraints.", MYF(0), name + dirname_length(name)); my_errno= HA_WRONG_CREATE_OPTION; @@ -684,7 +685,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, share.state.dellink = HA_OFFSET_ERROR; share.state.first_bitmap_with_space= 0; -#ifdef EXTERNAL_LOCKING +#ifdef MARIA_EXTERNAL_LOCKING share.state.process= (ulong) getpid(); #endif share.state.version= (ulong) time((time_t*) 0); @@ -849,7 +850,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, */ if (_ma_test_if_reopen(filename)) { - my_printf_error(0, "MARIA table '%s' is in use " + my_printf_error(0, "Aria table '%s' is in use " "(most likely by a MERGE table). Try FLUSH TABLES.", MYF(0), name + dirname_length(name)); my_errno= HA_ERR_TABLE_EXIST; diff --git a/storage/maria/ma_dbug.c b/storage/maria/ma_dbug.c index 24389fce321..af90a108e2a 100644 --- a/storage/maria/ma_dbug.c +++ b/storage/maria/ma_dbug.c @@ -124,7 +124,7 @@ void _ma_print_keydata(FILE *stream, register HA_KEYSEG *keyseg, case HA_KEYTYPE_LONGLONG: { char buff[21]; - longlong2str(mi_sint8korr(key),buff,-10); + longlong10_to_str(mi_sint8korr(key),buff,-10); VOID(fprintf(stream,"%s",buff)); key=end; break; @@ -132,7 +132,7 @@ void _ma_print_keydata(FILE *stream, register HA_KEYSEG *keyseg, case HA_KEYTYPE_ULONGLONG: { char buff[21]; - longlong2str(mi_sint8korr(key),buff,10); + longlong10_to_str(mi_sint8korr(key),buff,10); VOID(fprintf(stream,"%s",buff)); key=end; break; diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c index ab66499ecfe..a4e485066f5 100644 --- a/storage/maria/ma_delete.c +++ b/storage/maria/ma_delete.c @@ -571,6 +571,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key, endpos= leaf_page->buff + leaf_length; tmp_key.keyinfo= keyinfo; tmp_key.data= keybuff; + next_buff= 0; if (!(key_start= _ma_get_last_key(&tmp_key, leaf_page, endpos))) DBUG_RETURN(-1); @@ -597,9 +598,11 @@ static int del(MARIA_HA *info, MARIA_KEY *key, /* underflow writes "next_page" to disk */ ret_value= underflow(info, keyinfo, leaf_page, &next_page, endpos); - if (ret_value == 0 && leaf_page->size > - share->max_index_block_size) + if (ret_value < 0) + goto err; + if (leaf_page->size > share->max_index_block_size) { + DBUG_ASSERT(ret_value == 0); ret_value= (_ma_split_page(info, key, leaf_page, share->max_index_block_size, (uchar*) 0, 0, 0, @@ -632,6 +635,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key, goto err; } my_afree(next_buff); + DBUG_ASSERT(leaf_page->size <= share->max_index_block_size); DBUG_RETURN(ret_value); } @@ -709,10 +713,14 @@ static int del(MARIA_HA *info, MARIA_KEY *key, KEY_OP_DEBUG_LOG_ADD_2)) goto err; + DBUG_ASSERT(leaf_page->size <= share->max_index_block_size); DBUG_RETURN(new_leaf_length <= (info->quick_mode ? MARIA_MIN_KEYBLOCK_LENGTH : (uint) keyinfo->underflow_block_length)); err: + if (next_buff) + my_afree(next_buff); + DBUG_RETURN(-1); } /* del */ @@ -731,9 +739,18 @@ err: leaf_page is saved to disk Caller must save anc_buff + For the algoritm to work, we have to ensure for packed keys that + key_length + (underflow_length + max_block_length + key_length) / 2 + <= block_length. + From which follows that underflow_length <= block_length - key_length *3 + For not packed keys we have: + (underflow_length + max_block_length + key_length) / 2 <= block_length + From which follows that underflow_length < block_length - key_length + This is ensured by setting of underflow_block_length. + @return @retval 0 ok - @retval 1 ok, but anc_buff did underflow + @retval 1 ok, but anc_page did underflow @retval -1 error */ @@ -1153,7 +1170,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo, _ma_kpointer(info,leaf_key.data + leaf_key.data_length + leaf_key.ref_length, leaf_page->pos); - /* Save key in anc_page */ + /* Save parting key found by _ma_find_half_pos() in anc_page */ DBUG_DUMP("anc_buff", anc_buff, new_anc_length); DBUG_DUMP_KEY("key_to_anc", &leaf_key); anc_end_pos= anc_buff + new_anc_length; @@ -1191,6 +1208,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo, bmove(leaf_buff+p_length+t_length, half_pos, tmp_length); (*keyinfo->store_key)(keyinfo,leaf_buff+p_length, &key_inserted); new_leaf_length= tmp_length + t_length + p_length; + DBUG_ASSERT(new_leaf_length <= share->max_index_block_size); leaf_page->size= new_leaf_length; leaf_page->flag= page_flag; @@ -1232,7 +1250,6 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo, /* Log changes to next page This contains original data with some suffix data deleted - */ DBUG_ASSERT(new_buff_length <= buff_length); if (_ma_log_suffix(&next_page, buff_length, new_buff_length)) diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c index 7b120910a42..a88ef3bc3ba 100644 --- a/storage/maria/ma_dynrec.c +++ b/storage/maria/ma_dynrec.c @@ -1768,6 +1768,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, { if (filepos >= info->state->data_file_length) { +#ifdef MARIA_EXTERNAL_LOCKING if (!info_read) { /* Check if changed */ info_read=1; @@ -1780,6 +1781,10 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, my_errno= HA_ERR_END_OF_FILE; goto err; } +#else + my_errno= HA_ERR_END_OF_FILE; + goto err; +#endif } if (info->opt_flag & READ_CACHE_USED) { diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c index d9e551eaaf8..d2e011fcf24 100644 --- a/storage/maria/ma_extra.c +++ b/storage/maria/ma_extra.c @@ -319,7 +319,6 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, my_bool do_flush= test(function != HA_EXTRA_PREPARE_FOR_DROP); my_bool save_global_changed; enum flush_type type; - pthread_mutex_lock(&THR_LOCK_maria); /* This share, to have last_version=0, needs to save all its data/index blocks to disk if this is not for a DROP TABLE. Otherwise they would be @@ -353,12 +352,14 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, type= do_flush ? FLUSH_RELEASE : FLUSH_IGNORE_CHANGED; save_global_changed= share->global_changed; share->global_changed= 1; /* Don't increment open count */ + pthread_mutex_unlock(&share->intern_lock); if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX, type, type)) { error=my_errno; share->changed= 1; } + pthread_mutex_lock(&share->intern_lock); share->global_changed= save_global_changed; if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED)) { @@ -395,10 +396,9 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, error= my_errno; share->bitmap.changed_not_flushed= 0; } - /* For protection against Checkpoint, we set under intern_lock: */ + /* last_version must be protected by intern_lock; See collect_tables() */ share->last_version= 0L; /* Impossible version */ pthread_mutex_unlock(&share->intern_lock); - pthread_mutex_unlock(&THR_LOCK_maria); break; } case HA_EXTRA_PREPARE_FOR_FORCED_CLOSE: diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c index 5e613d8520d..208b39f3b32 100644 --- a/storage/maria/ma_ft_boolean_search.c +++ b/storage/maria/ma_ft_boolean_search.c @@ -594,7 +594,7 @@ FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr, sizeof(FTB_WORD *)*ftb->queue.elements); memcpy(ftb->list, ftb->queue.root+1, sizeof(FTB_WORD *)*ftb->queue.elements); my_qsort2(ftb->list, ftb->queue.elements, sizeof(FTB_WORD *), - (qsort2_cmp)FTB_WORD_cmp_list, ftb->charset); + (qsort2_cmp)FTB_WORD_cmp_list, (void*) ftb->charset); if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC; ftb->state=READY; return ftb; diff --git a/storage/maria/ma_ft_parser.c b/storage/maria/ma_ft_parser.c index 9c988c41c7b..b35c2227ca2 100644 --- a/storage/maria/ma_ft_parser.c +++ b/storage/maria/ma_ft_parser.c @@ -254,7 +254,8 @@ void maria_ft_parse_init(TREE *wtree, CHARSET_INFO *cs) { DBUG_ENTER("maria_ft_parse_init"); if (!is_tree_inited(wtree)) - init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,NULL, cs); + init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0, NULL, + (void*) cs); DBUG_VOID_RETURN; } diff --git a/storage/maria/ma_init.c b/storage/maria/ma_init.c index 8f695acfe5a..7aee13255de 100644 --- a/storage/maria/ma_init.c +++ b/storage/maria/ma_init.c @@ -89,6 +89,11 @@ void maria_end(void) maria_inited= maria_multi_threaded= FALSE; ft_free_stopwords(); ma_checkpoint_end(); + if (translog_status == TRANSLOG_OK) + { + translog_soft_sync_end(); + translog_sync(); + } if ((trid= trnman_get_max_trid()) > max_trid_in_control_file) { /* @@ -109,3 +114,72 @@ void maria_end(void) hash_free(&maria_stored_state); } } + +/** + Upgrade from older Aria versions: + + - In MariaDB 5.1, the name of the control file and log files had the + 'maria' prefix, now they have the 'aria' prefix. + + @return: 0 ok + 1 error + +*/ + +my_bool maria_upgrade() +{ + char name[FN_REFLEN], new_name[FN_REFLEN]; + DBUG_ENTER("maria_upgrade"); + + fn_format(name, "maria_log_control", maria_data_root, "", MYF(MY_WME)); + + if (!my_access(name,F_OK)) + { + /* + Old style control file found; Rename the control file and the log files. + We start by renaming all log files, so that if we get a crash + we will continue from where we left. + */ + uint i; + MY_DIR *dir= my_dir(maria_data_root, MYF(MY_WME)); + if (!dir) + DBUG_RETURN(1); + + my_message(HA_ERR_INITIALIZATION, + "Found old style Maria log files; " + "Converting them to Aria names", + MYF(ME_JUST_INFO)); + + for (i= 0; i < dir->number_off_files; i++) + { + const char *file= dir->dir_entry[i].name; + if (strncmp(file, "maria_log.", 10) == 0 && + file[10] >= '0' && file[10] <= '9' && + file[11] >= '0' && file[11] <= '9' && + file[12] >= '0' && file[12] <= '9' && + file[13] >= '0' && file[13] <= '9' && + file[14] >= '0' && file[14] <= '9' && + file[15] >= '0' && file[15] <= '9' && + file[16] >= '0' && file[16] <= '9' && + file[17] >= '0' && file[17] <= '9' && + file[18] == '\0') + { + /* Remove the 'm' in 'maria' */ + char old_logname[FN_REFLEN], new_logname[FN_REFLEN]; + fn_format(old_logname, file, maria_data_root, "", MYF(0)); + fn_format(new_logname, file+1, maria_data_root, "", MYF(0)); + if (my_rename(old_logname, new_logname, MYF(MY_WME))) + { + my_dirend(dir); + DBUG_RETURN(1); + } + } + } + my_dirend(dir); + + fn_format(new_name, CONTROL_FILE_BASE_NAME, maria_data_root, "", MYF(0)); + if (my_rename(name, new_name, MYF(MY_WME))) + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c index 633fd59ef2a..acc359ff212 100644 --- a/storage/maria/ma_locking.c +++ b/storage/maria/ma_locking.c @@ -103,7 +103,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type) rw_unlock(&share->mmap_lock); } #endif -#ifdef EXTERNAL_LOCKING +#ifdef MARIA_EXTERNAL_LOCKING share->state.process= share->last_process=share->this_process; share->state.unique= info->last_unique= info->this_unique; share->state.update_count= info->last_loop= ++info->this_loop; @@ -303,7 +303,7 @@ int _ma_writeinfo(register MARIA_HA *info, uint operation) { /* Two threads can't be here */ olderror= my_errno; /* Remember last error */ -#ifdef EXTERNAL_LOCKING +#ifdef MARIA_EXTERNAL_LOCKING /* The following only makes sense if we want to be allow two different processes access the same table at the same time @@ -341,7 +341,7 @@ int _ma_writeinfo(register MARIA_HA *info, uint operation) int _ma_test_if_changed(register MARIA_HA *info) { -#ifdef EXTERNAL_LOCKING +#ifdef MARIA_EXTERNAL_LOCKING MARIA_SHARE *share= info->s; if (share->state.process != share->last_process || share->state.unique != info->last_unique || diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index ce7253d4c39..6f70fdf34cf 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -18,6 +18,7 @@ #include "ma_blockrec.h" /* for some constants and in-write hooks */ #include "ma_key_recover.h" /* For some in-write hooks */ #include "ma_checkpoint.h" +#include "ma_servicethread.h" /* On Windows, neither my_open() nor my_sync() work for directories. @@ -47,6 +48,15 @@ #include <m_ctype.h> #endif +/** @brief protects checkpoint_in_progress */ +static pthread_mutex_t LOCK_soft_sync; +/** @brief for killing the background checkpoint thread */ +static pthread_cond_t COND_soft_sync; +/** @brief control structure for checkpoint background thread */ +static MA_SERVICE_THREAD_CONTROL soft_sync_control= + {THREAD_DEAD, FALSE, &LOCK_soft_sync, &COND_soft_sync}; + + /* transaction log file descriptor */ typedef struct st_translog_file { @@ -124,10 +134,24 @@ struct st_translog_buffer /* Previous buffer offset to detect it flush finish */ TRANSLOG_ADDRESS prev_buffer_offset; /* + If the buffer was forced to close it save value of its horizon + otherwise LSN_IMPOSSIBLE + */ + TRANSLOG_ADDRESS pre_force_close_horizon; + /* How much is written (or will be written when copy_to_buffer_in_progress become 0) to this buffer */ translog_size_t size; + /* + When moving from one log buffer to another, we write the last of the + previous buffer to file and then move to start using the new log + buffer. In the case of a part filed last page, this page is not moved + to the start of the new buffer but instead we set the 'skip_data' + variable to tell us how much data at the beginning of the buffer is not + relevant. + */ + uint skipped_data; /* File handler for this buffer */ TRANSLOG_FILE *file; /* Threads which are waiting for buffer filling/freeing */ @@ -304,6 +328,7 @@ struct st_translog_descriptor */ pthread_mutex_t log_flush_lock; pthread_cond_t log_flush_cond; + pthread_cond_t new_goal_cond; /* Protects changing of headers of finished files (max_lsn) */ pthread_mutex_t file_header_lock; @@ -344,13 +369,39 @@ static struct st_translog_descriptor log_descriptor; ulong log_purge_type= TRANSLOG_PURGE_IMMIDIATE; ulong log_file_size= TRANSLOG_FILE_SIZE; +/* sync() of log files directory mode */ ulong sync_log_dir= TRANSLOG_SYNC_DIR_NEWFILE; +ulong maria_group_commit= TRANSLOG_GCOMMIT_NONE; +ulong maria_group_commit_interval= 0; /* Marker for end of log */ static uchar end_of_log= 0; #define END_OF_LOG &end_of_log +/** + Switch for "soft" sync (no real sync() but periodical sync by service + thread) +*/ +static volatile my_bool soft_sync= FALSE; +/** + Switch for "hard" group commit mode +*/ +static volatile my_bool hard_group_commit= FALSE; +/** + File numbers interval which have to be sync() +*/ +static uint32 soft_sync_min= 0; +static uint32 soft_sync_max= 0; +static uint32 soft_need_sync= 1; +/** + stores interval in microseconds +*/ +static uint32 group_commit_wait= 0; enum enum_translog_status translog_status= TRANSLOG_UNINITED; +ulonglong translog_syncs= 0; /* Number of sync()s */ + +/* time of last flush */ +static ulonglong flush_start= 0; /* chunk types */ #define TRANSLOG_CHUNK_LSN 0x00 /* 0 chunk refer as LSN (head or tail */ @@ -858,7 +909,7 @@ char *translog_filename_by_fileno(uint32 file_no, char *path) DBUG_ASSERT(file_no <= 0xfffffff); /* log_descriptor.directory is already formated */ - end= strxmov(path, log_descriptor.directory, "maria_log.0000000", NullS); + end= strxmov(path, log_descriptor.directory, "aria_log.0000000", NullS); length= (uint) (int10_to_str(file_no, buff, 10) - buff); strmov(end - length +1, buff); @@ -980,12 +1031,17 @@ static TRANSLOG_FILE *get_logfile_by_number(uint32 file_no) static TRANSLOG_FILE *get_current_logfile() { TRANSLOG_FILE *file; + DBUG_ENTER("get_current_logfile"); rw_rdlock(&log_descriptor.open_files_lock); + DBUG_PRINT("info", ("max_file: %lu min_file: %lu open_files: %lu", + (ulong) log_descriptor.max_file, + (ulong) log_descriptor.min_file, + (ulong) log_descriptor.open_files.elements)); DBUG_ASSERT(log_descriptor.max_file - log_descriptor.min_file + 1 == log_descriptor.open_files.elements); file= *dynamic_element(&log_descriptor.open_files, 0, TRANSLOG_FILE **); rw_unlock(&log_descriptor.open_files_lock); - return (file); + DBUG_RETURN(file); } uchar NEAR maria_trans_file_magic[]= @@ -1069,6 +1125,7 @@ static my_bool translog_write_file_header() static my_bool translog_max_lsn_to_header(File file, LSN lsn) { uchar lsn_buff[LSN_STORE_SIZE]; + my_bool rc; DBUG_ENTER("translog_max_lsn_to_header"); DBUG_PRINT("enter", ("File descriptor: %ld " "lsn: (%lu,0x%lx)", @@ -1077,11 +1134,17 @@ static my_bool translog_max_lsn_to_header(File file, LSN lsn) lsn_store(lsn_buff, lsn); - DBUG_RETURN(my_pwrite(file, lsn_buff, - LSN_STORE_SIZE, - (LOG_HEADER_DATA_SIZE - LSN_STORE_SIZE), - log_write_flags) != 0 || - my_sync(file, MYF(MY_WME)) != 0); + rc= (my_pwrite(file, lsn_buff, + LSN_STORE_SIZE, + (LOG_HEADER_DATA_SIZE - LSN_STORE_SIZE), + log_write_flags) != 0 || + my_sync(file, MYF(MY_WME)) != 0); + /* + We should not increase counter in case of error above, but it is so + unlikely that we can ignore this case + */ + translog_syncs++; + DBUG_RETURN(rc); } @@ -1136,7 +1199,7 @@ my_bool translog_read_file_header(LOGHANDLER_FILE_INFO *desc, File file) DBUG_RETURN(1); } translog_interpret_file_header(desc, page_buff); - DBUG_PRINT("info", ("timestamp: %llu maria ver: %lu mysql ver: %lu " + DBUG_PRINT("info", ("timestamp: %llu aria ver: %lu mysql ver: %lu " "server id %lu page size %lu file number %lu " "max lsn: (%lu,0x%lx)", (ulonglong) desc->timestamp, @@ -1377,7 +1440,7 @@ LSN translog_get_file_max_lsn_stored(uint32 file) { LOGHANDLER_FILE_INFO info; - File fd; + File fd; LINT_INIT_STRUCT(info); fd= open_logfile_by_number_no_cache(file); if ((fd < 0) || @@ -1408,7 +1471,9 @@ LSN translog_get_file_max_lsn_stored(uint32 file) static my_bool translog_buffer_init(struct st_translog_buffer *buffer, int num) { DBUG_ENTER("translog_buffer_init"); - buffer->prev_last_lsn= buffer->last_lsn= LSN_IMPOSSIBLE; + buffer->pre_force_close_horizon= + buffer->prev_last_lsn= buffer->last_lsn= + LSN_IMPOSSIBLE; DBUG_PRINT("info", ("last_lsn and prev_last_lsn set to 0 buffer: 0x%lx", (ulong) buffer)); @@ -1420,6 +1485,7 @@ static my_bool translog_buffer_init(struct st_translog_buffer *buffer, int num) memset(buffer->buffer, TRANSLOG_FILLER, TRANSLOG_WRITE_BUFFER); /* Buffer size */ buffer->size= 0; + buffer->skipped_data= 0; /* cond of thread which is waiting for buffer filling */ if (pthread_cond_init(&buffer->waiting_filling_buffer, 0)) DBUG_RETURN(1); @@ -1474,7 +1540,10 @@ static my_bool translog_close_log_file(TRANSLOG_FILE *file) TODO: sync only we have changed the log */ if (!file->is_sync) + { rc= my_sync(file->handler.file, MYF(MY_WME)); + translog_syncs++; + } rc|= my_close(file->handler.file, MYF(MY_WME)); my_free(file, MYF(0)); return test(rc); @@ -2029,7 +2098,8 @@ static void translog_start_buffer(struct st_translog_buffer *buffer, (ulong) LSN_OFFSET(log_descriptor.horizon), (ulong) LSN_OFFSET(log_descriptor.horizon))); DBUG_ASSERT(buffer_no == buffer->buffer_no); - buffer->prev_last_lsn= buffer->last_lsn= LSN_IMPOSSIBLE; + buffer->pre_force_close_horizon= + buffer->prev_last_lsn= buffer->last_lsn= LSN_IMPOSSIBLE; DBUG_PRINT("info", ("last_lsn and prev_last_lsn set to 0 buffer: 0x%lx", (ulong) buffer)); buffer->offset= log_descriptor.horizon; @@ -2037,6 +2107,7 @@ static void translog_start_buffer(struct st_translog_buffer *buffer, buffer->file= get_current_logfile(); buffer->overlay= 0; buffer->size= 0; + buffer->skipped_data= 0; translog_cursor_init(cursor, buffer, buffer_no); DBUG_PRINT("info", ("file: #%ld (%d) init cursor #%u: 0x%lx " "chaser: %d Size: %lu (%lu)", @@ -2497,6 +2568,7 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer) TRANSLOG_ADDRESS offset= buffer->offset; TRANSLOG_FILE *file= buffer->file; uint8 ver= buffer->ver; + uint skipped_data; DBUG_ENTER("translog_buffer_flush"); DBUG_PRINT("enter", ("Buffer: #%u 0x%lx file: %d offset: (%lu,0x%lx) size: %lu", @@ -2530,6 +2602,8 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer) disk */ file= buffer->file; + skipped_data= buffer->skipped_data; + DBUG_ASSERT(skipped_data < TRANSLOG_PAGE_SIZE); for (i= 0, pg= LSN_OFFSET(buffer->offset) / TRANSLOG_PAGE_SIZE; i < buffer->size; i+= TRANSLOG_PAGE_SIZE, pg++) @@ -2546,13 +2620,16 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer) DBUG_ASSERT(i + TRANSLOG_PAGE_SIZE <= buffer->size); if (translog_status != TRANSLOG_OK && translog_status != TRANSLOG_SHUTDOWN) DBUG_RETURN(1); - if (pagecache_inject(log_descriptor.pagecache, + if (pagecache_write_part(log_descriptor.pagecache, &file->handler, pg, 3, buffer->buffer + i, PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_LEFT_UNLOCKED, - PAGECACHE_PIN_LEFT_UNPINNED, 0, - LSN_IMPOSSIBLE)) + PAGECACHE_PIN_LEFT_UNPINNED, + PAGECACHE_WRITE_DONE, 0, + LSN_IMPOSSIBLE, + skipped_data, + TRANSLOG_PAGE_SIZE - skipped_data)) { DBUG_PRINT("error", ("Can't write page (%lu,0x%lx) to pagecache, error: %d", @@ -2562,10 +2639,12 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer) translog_stop_writing(); DBUG_RETURN(1); } + skipped_data= 0; } file->is_sync= 0; - if (my_pwrite(file->handler.file, buffer->buffer, - buffer->size, LSN_OFFSET(buffer->offset), + if (my_pwrite(file->handler.file, buffer->buffer + buffer->skipped_data, + buffer->size - buffer->skipped_data, + LSN_OFFSET(buffer->offset) + buffer->skipped_data, log_write_flags)) { DBUG_PRINT("error", ("Can't write buffer (%lu,0x%lx) size %lu " @@ -2958,6 +3037,7 @@ restart: uchar *from, *table= NULL; int is_last_unfinished_page; uint last_protected_sector= 0; + uint skipped_data= curr_buffer->skipped_data; TRANSLOG_FILE file_copy; uint8 ver= curr_buffer->ver; translog_wait_for_writers(curr_buffer); @@ -2970,7 +3050,38 @@ restart: } DBUG_ASSERT(LSN_FILE_NO(addr) == LSN_FILE_NO(curr_buffer->offset)); from= curr_buffer->buffer + (addr - curr_buffer->offset); - memcpy(buffer, from, TRANSLOG_PAGE_SIZE); + if (skipped_data && addr == curr_buffer->offset) + { + /* + We read page part of which is not present in buffer, + so we should read absent part from file (page cache actually) + */ + file= get_logfile_by_number(file_no); + DBUG_ASSERT(file != NULL); + /* + it's ok to not lock the page because: + - The log handler has it's own page cache. + - There is only one thread that can access the log + cache at a time + */ + if (!(buffer= pagecache_read(log_descriptor.pagecache, + &file->handler, + LSN_OFFSET(addr) / TRANSLOG_PAGE_SIZE, + 3, buffer, + PAGECACHE_PLAIN_PAGE, + PAGECACHE_LOCK_LEFT_UNLOCKED, + NULL))) + DBUG_RETURN(NULL); + } + else + skipped_data= 0; /* Read after skipped in buffer data */ + /* + Now we have correct data in buffer up to 'skipped_data'. The + following memcpy() will move the data from the internal buffer + that was not yet on disk. + */ + memcpy(buffer + skipped_data, from + skipped_data, + TRANSLOG_PAGE_SIZE - skipped_data); /* We can use copy then in translog_page_validator() because it do not put it permanently somewhere. @@ -3264,6 +3375,7 @@ static my_bool translog_truncate_log(TRANSLOG_ADDRESS addr) uint32 next_page_offset, page_rest; uint32 i; File fd; + int rc; TRANSLOG_VALIDATOR_DATA data; char path[FN_REFLEN]; uchar page_buff[TRANSLOG_PAGE_SIZE]; @@ -3289,14 +3401,19 @@ static my_bool translog_truncate_log(TRANSLOG_ADDRESS addr) TRANSLOG_PAGE_SIZE); page_rest= next_page_offset - LSN_OFFSET(addr); memset(page_buff, TRANSLOG_FILLER, page_rest); - if ((fd= open_logfile_by_number_no_cache(LSN_FILE_NO(addr))) < 0 || - ((my_chsize(fd, next_page_offset, TRANSLOG_FILLER, MYF(MY_WME)) || - (page_rest && my_pwrite(fd, page_buff, page_rest, LSN_OFFSET(addr), - log_write_flags)) || - my_sync(fd, MYF(MY_WME))) | - my_close(fd, MYF(MY_WME))) || - (sync_log_dir >= TRANSLOG_SYNC_DIR_ALWAYS && - sync_dir(log_descriptor.directory_fd, MYF(MY_WME | MY_IGNORE_BADFD)))) + rc= ((fd= open_logfile_by_number_no_cache(LSN_FILE_NO(addr))) < 0 || + ((my_chsize(fd, next_page_offset, TRANSLOG_FILLER, MYF(MY_WME)) || + (page_rest && my_pwrite(fd, page_buff, page_rest, LSN_OFFSET(addr), + log_write_flags)) || + my_sync(fd, MYF(MY_WME))))); + translog_syncs++; + rc|= (fd > 0 && my_close(fd, MYF(MY_WME))); + if (sync_log_dir >= TRANSLOG_SYNC_DIR_ALWAYS) + { + rc|= sync_dir(log_descriptor.directory_fd, MYF(MY_WME | MY_IGNORE_BADFD)); + translog_syncs++; + } + if (rc) DBUG_RETURN(1); /* fix the horizon */ @@ -3321,7 +3438,7 @@ static my_bool translog_truncate_log(TRANSLOG_ADDRESS addr) /** Applies function 'callback' to all files (in a directory) which - name looks like a log's name (maria_log.[0-9]{7}). + name looks like a log's name (aria_log.[0-9]{7}). If 'callback' returns TRUE this interrupts the walk and returns TRUE. Otherwise FALSE is returned after processing all log files. It cannot just use log_descriptor.directory because that may not yet have @@ -3347,7 +3464,7 @@ my_bool translog_walk_filenames(const char *directory, for (i= 0; i < dirp->number_off_files; i++) { char *file= dirp->dir_entry[i].name; - if (strncmp(file, "maria_log.", 10) == 0 && + if (strncmp(file, "aria_log.", 10) == 0 && file[10] >= '0' && file[10] <= '9' && file[11] >= '0' && file[11] <= '9' && file[12] >= '0' && file[12] <= '9' && @@ -3456,7 +3573,10 @@ my_bool translog_init_with_table(const char *directory, my_bool version_changed= 0; DBUG_ENTER("translog_init_with_table"); + translog_syncs= 0; + flush_start= 0; id_to_share= NULL; + log_descriptor.directory_fd= -1; log_descriptor.is_everything_flushed= 1; log_descriptor.flush_in_progress= 0; @@ -3484,6 +3604,7 @@ my_bool translog_init_with_table(const char *directory, pthread_mutex_init(&log_descriptor.dirty_buffer_mask_lock, MY_MUTEX_INIT_FAST) || pthread_cond_init(&log_descriptor.log_flush_cond, 0) || + pthread_cond_init(&log_descriptor.new_goal_cond, 0) || my_rwlock_init(&log_descriptor.open_files_lock, NULL) || my_init_dynamic_array(&log_descriptor.open_files, @@ -3574,7 +3695,7 @@ my_bool translog_init_with_table(const char *directory, my_bool pageok; DBUG_PRINT("info", ("log found...")); /* - TODO: scan directory for maria_log.XXXXXXXX files and find + TODO: scan directory for aria_log.XXXXXXXX files and find highest XXXXXXXX & set logs_found TODO: check that last checkpoint within present log addresses space @@ -3817,7 +3938,7 @@ my_bool translog_init_with_table(const char *directory, if (!old_log_was_recovered && old_flags == flags) { LOGHANDLER_FILE_INFO info; - LINT_INIT(info.maria_version); + LINT_INIT_STRUCT(info); /* Accessing &log_descriptor.open_files without mutex is safe @@ -3887,7 +4008,6 @@ my_bool translog_init_with_table(const char *directory, log_descriptor.flushed= log_descriptor.horizon; log_descriptor.in_buffers_only= log_descriptor.bc.buffer->offset; log_descriptor.max_lsn= LSN_IMPOSSIBLE; /* set to 0 */ - log_descriptor.previous_flush_horizon= log_descriptor.horizon; /* Now 'flushed' is set to 'horizon' value, but 'horizon' is (potentially) address of the next LSN and we want indicate that all LSNs that are @@ -3970,6 +4090,10 @@ my_bool translog_init_with_table(const char *directory, It is beginning of the log => there is no LSNs in the log => There is no harm in leaving it "as-is". */ + log_descriptor.previous_flush_horizon= log_descriptor.horizon; + DBUG_PRINT("info", ("previous_flush_horizon: (%lu,0x%lx)", + LSN_IN_PARTS(log_descriptor. + previous_flush_horizon))); DBUG_RETURN(0); } file_no--; @@ -4045,6 +4169,9 @@ my_bool translog_init_with_table(const char *directory, translog_free_record_header(&rec); } } + log_descriptor.previous_flush_horizon= log_descriptor.horizon; + DBUG_PRINT("info", ("previous_flush_horizon: (%lu,0x%lx)", + LSN_IN_PARTS(log_descriptor.previous_flush_horizon))); DBUG_RETURN(0); err: ma_message_no_user(0, "log initialization failed"); @@ -4132,6 +4259,7 @@ void translog_destroy() pthread_mutex_destroy(&log_descriptor.log_flush_lock); pthread_mutex_destroy(&log_descriptor.dirty_buffer_mask_lock); pthread_cond_destroy(&log_descriptor.log_flush_cond); + pthread_cond_destroy(&log_descriptor.new_goal_cond); rwlock_destroy(&log_descriptor.open_files_lock); delete_dynamic(&log_descriptor.open_files); delete_dynamic(&log_descriptor.unfinished_files); @@ -6856,11 +6984,11 @@ int translog_read_record_header_from_buffer(uchar *page, { translog_size_t res; DBUG_ENTER("translog_read_record_header_from_buffer"); + DBUG_PRINT("info", ("page byte: 0x%x offset: %u", + (uint) page[page_offset], (uint) page_offset)); DBUG_ASSERT(translog_is_LSN_chunk(page[page_offset])); DBUG_ASSERT(translog_status == TRANSLOG_OK || translog_status == TRANSLOG_READONLY); - DBUG_PRINT("info", ("page byte: 0x%x offset: %u", - (uint) page[page_offset], (uint) page_offset)); buff->type= (page[page_offset] & TRANSLOG_REC_TYPE); buff->short_trid= uint2korr(page + page_offset + 1); DBUG_PRINT("info", ("Type %u, Short TrID %u, LSN (%lu,0x%lx)", @@ -7327,27 +7455,27 @@ static void translog_force_current_buffer_to_finish() "Buffer addr: (%lu,0x%lx) " "Page addr: (%lu,0x%lx) " "size: %lu (%lu) Pg: %u left: %u in progress %u", - (uint) log_descriptor.bc.buffer_no, - (ulong) log_descriptor.bc.buffer, - LSN_IN_PARTS(log_descriptor.bc.buffer->offset), + (uint) old_buffer_no, + (ulong) old_buffer, + LSN_IN_PARTS(old_buffer->offset), (ulong) LSN_FILE_NO(log_descriptor.horizon), (ulong) (LSN_OFFSET(log_descriptor.horizon) - log_descriptor.bc.current_page_fill), - (ulong) log_descriptor.bc.buffer->size, + (ulong) old_buffer->size, (ulong) (log_descriptor.bc.ptr -log_descriptor.bc. buffer->buffer), (uint) log_descriptor.bc.current_page_fill, (uint) left, - (uint) log_descriptor.bc.buffer-> + (uint) old_buffer-> copy_to_buffer_in_progress)); translog_lock_assert_owner(); LINT_INIT(current_page_fill); - new_buff_beginning= log_descriptor.bc.buffer->offset; - new_buff_beginning+= log_descriptor.bc.buffer->size; /* increase offset */ + new_buff_beginning= old_buffer->offset; + new_buff_beginning+= old_buffer->size; /* increase offset */ DBUG_ASSERT(log_descriptor.bc.ptr !=NULL); DBUG_ASSERT(LSN_FILE_NO(log_descriptor.horizon) == - LSN_FILE_NO(log_descriptor.bc.buffer->offset)); + LSN_FILE_NO(old_buffer->offset)); translog_check_cursor(&log_descriptor.bc); DBUG_ASSERT(left < TRANSLOG_PAGE_SIZE); if (left) @@ -7358,18 +7486,20 @@ static void translog_force_current_buffer_to_finish() */ DBUG_PRINT("info", ("left: %u", (uint) left)); + old_buffer->pre_force_close_horizon= + old_buffer->offset + old_buffer->size; /* decrease offset */ new_buff_beginning-= log_descriptor.bc.current_page_fill; current_page_fill= log_descriptor.bc.current_page_fill; memset(log_descriptor.bc.ptr, TRANSLOG_FILLER, left); - log_descriptor.bc.buffer->size+= left; + old_buffer->size+= left; DBUG_PRINT("info", ("Finish Page buffer #%u: 0x%lx " "Size: %lu", - (uint) log_descriptor.bc.buffer->buffer_no, - (ulong) log_descriptor.bc.buffer, - (ulong) log_descriptor.bc.buffer->size)); - DBUG_ASSERT(log_descriptor.bc.buffer->buffer_no == + (uint) old_buffer->buffer_no, + (ulong) old_buffer, + (ulong) old_buffer->size)); + DBUG_ASSERT(old_buffer->buffer_no == log_descriptor.bc.buffer_no); } else @@ -7480,11 +7610,21 @@ static void translog_force_current_buffer_to_finish() if (left) { - /* - TODO: do not copy beginning of the page if we have no CRC or sector - checks on - */ - memcpy(new_buffer->buffer, data, current_page_fill); + if (log_descriptor.flags & + (TRANSLOG_PAGE_CRC | TRANSLOG_SECTOR_PROTECTION)) + memcpy(new_buffer->buffer, data, current_page_fill); + else + { + /* + This page header does not change if we add more data to the page so + we can not copy it and will not overwrite later + */ + new_buffer->skipped_data= current_page_fill; +#ifndef DBUG_OFF + memset(new_buffer->buffer, 0xa5, current_page_fill); +#endif + DBUG_ASSERT(new_buffer->skipped_data < TRANSLOG_PAGE_SIZE); + } } old_buffer->next_buffer_offset= new_buffer->offset; translog_buffer_lock(new_buffer); @@ -7532,6 +7672,7 @@ void translog_flush_set_new_goal_and_wait(TRANSLOG_ADDRESS lsn) { log_descriptor.next_pass_max_lsn= lsn; log_descriptor.max_lsn_requester= pthread_self(); + pthread_cond_broadcast(&log_descriptor.new_goal_cond); } while (flush_no == log_descriptor.flush_no) { @@ -7543,68 +7684,80 @@ void translog_flush_set_new_goal_and_wait(TRANSLOG_ADDRESS lsn) /** - @brief Flush the log up to given LSN (included) + @brief sync() range of files (inclusive) and directory (by request) - @param lsn log record serial number up to which (inclusive) - the log has to be flushed + @param min min internal file number to flush + @param max max internal file number to flush + @param sync_dir need sync directory - @return Operation status + return Operation status @retval 0 OK @retval 1 Error - */ -my_bool translog_flush(TRANSLOG_ADDRESS lsn) +static my_bool translog_sync_files(uint32 min, uint32 max, + my_bool sync_dir) { - LSN sent_to_disk= LSN_IMPOSSIBLE; - TRANSLOG_ADDRESS flush_horizon; - uint fn, i; - dirty_buffer_mask_t dirty_buffer_mask; - uint8 last_buffer_no, start_buffer_no; + uint fn; my_bool rc= 0; - DBUG_ENTER("translog_flush"); - DBUG_PRINT("enter", ("Flush up to LSN: (%lu,0x%lx)", LSN_IN_PARTS(lsn))); - DBUG_ASSERT(translog_status == TRANSLOG_OK || - translog_status == TRANSLOG_READONLY); - LINT_INIT(sent_to_disk); - LINT_INIT(last_buffer_no); + ulonglong flush_interval; + DBUG_ENTER("translog_sync_files"); + DBUG_PRINT("info", ("min: %lu max: %lu sync dir: %d", + (ulong) min, (ulong) max, (int) sync_dir)); + DBUG_ASSERT(min <= max); - pthread_mutex_lock(&log_descriptor.log_flush_lock); - DBUG_PRINT("info", ("Everything is flushed up to (%lu,0x%lx)", - LSN_IN_PARTS(log_descriptor.flushed))); - if (cmp_translog_addr(log_descriptor.flushed, lsn) >= 0) - { - pthread_mutex_unlock(&log_descriptor.log_flush_lock); - DBUG_RETURN(0); - } - if (log_descriptor.flush_in_progress) + flush_interval= group_commit_wait; + if (flush_interval) + flush_start= my_micro_time(); + for (fn= min; fn <= max; fn++) { - translog_flush_set_new_goal_and_wait(lsn); - if (!pthread_equal(log_descriptor.max_lsn_requester, pthread_self())) + TRANSLOG_FILE *file= get_logfile_by_number(fn); + DBUG_ASSERT(file != NULL); + if (!file->is_sync) { - /* fix lsn if it was horizon */ - if (cmp_translog_addr(lsn, log_descriptor.bc.buffer->last_lsn) > 0) - lsn= BUFFER_MAX_LSN(log_descriptor.bc.buffer); - translog_flush_wait_for_end(lsn); - pthread_mutex_unlock(&log_descriptor.log_flush_lock); - DBUG_RETURN(0); + if (my_sync(file->handler.file, MYF(MY_WME))) + { + rc= 1; + translog_stop_writing(); + DBUG_RETURN(rc); + } + translog_syncs++; + file->is_sync= 1; } - log_descriptor.next_pass_max_lsn= LSN_IMPOSSIBLE; } - log_descriptor.flush_in_progress= 1; - flush_horizon= log_descriptor.previous_flush_horizon; - DBUG_PRINT("info", ("flush_in_progress is set")); - pthread_mutex_unlock(&log_descriptor.log_flush_lock); - translog_lock(); - if (log_descriptor.is_everything_flushed) + if (sync_dir) { - DBUG_PRINT("info", ("everything is flushed")); - rc= (translog_status == TRANSLOG_READONLY); - translog_unlock(); - goto out; + if (!(rc= sync_dir(log_descriptor.directory_fd, + MYF(MY_WME | MY_IGNORE_BADFD)))) + translog_syncs++; } + DBUG_RETURN(rc); +} + + +/* + @brief Flushes buffers with LSNs in them less or equal address <lsn> + + @param lsn address up to which all LSNs should be flushed, + can be reset to real last LSN address + @parem sent_to_disk returns 'sent to disk' position + @param flush_horizon returns horizon of the flush + + @note About terminology see comment to translog_flush(). +*/ + +void translog_flush_buffers(TRANSLOG_ADDRESS *lsn, + TRANSLOG_ADDRESS *sent_to_disk, + TRANSLOG_ADDRESS *flush_horizon) +{ + dirty_buffer_mask_t dirty_buffer_mask; + uint i; + uint8 last_buffer_no, start_buffer_no; + DBUG_ENTER("translog_flush_buffers"); + LINT_INIT(last_buffer_no); + /* We will recheck information when will lock buffers one by one so we can use unprotected read here (this is just for @@ -7624,19 +7777,18 @@ my_bool translog_flush(TRANSLOG_ADDRESS lsn) (uint) start_buffer_no, (uint) log_descriptor.bc.buffer_no, LSN_IN_PARTS(log_descriptor.bc.buffer->prev_last_lsn))); - /* if LSN up to which we have to flush bigger then maximum LSN of previous buffer and at least one LSN was saved in the current buffer (last_lsn != - LSN_IMPOSSIBLE) then we better finish the current buffer. + LSN_IMPOSSIBLE) then we have to close the current buffer. */ - if (cmp_translog_addr(lsn, log_descriptor.bc.buffer->prev_last_lsn) > 0 && + if (cmp_translog_addr(*lsn, log_descriptor.bc.buffer->prev_last_lsn) > 0 && log_descriptor.bc.buffer->last_lsn != LSN_IMPOSSIBLE) { struct st_translog_buffer *buffer= log_descriptor.bc.buffer; - lsn= log_descriptor.bc.buffer->last_lsn; /* fix lsn if it was horizon */ + *lsn= log_descriptor.bc.buffer->last_lsn; /* fix lsn if it was horizon */ DBUG_PRINT("info", ("LSN to flush fixed to last lsn: (%lu,0x%lx)", - LSN_IN_PARTS(lsn))); + LSN_IN_PARTS(*lsn))); last_buffer_no= log_descriptor.bc.buffer_no; log_descriptor.is_everything_flushed= 1; translog_force_current_buffer_to_finish(); @@ -7645,9 +7797,9 @@ my_bool translog_flush(TRANSLOG_ADDRESS lsn) else if (log_descriptor.bc.buffer->prev_last_lsn != LSN_IMPOSSIBLE) { /* fix lsn if it was horizon */ - lsn= log_descriptor.bc.buffer->prev_last_lsn; + *lsn= log_descriptor.bc.buffer->prev_last_lsn; DBUG_PRINT("info", ("LSN to flush fixed to prev last lsn: (%lu,0x%lx)", - LSN_IN_PARTS(lsn))); + LSN_IN_PARTS(*lsn))); last_buffer_no= ((log_descriptor.bc.buffer_no + TRANSLOG_BUFFERS_NO -1) % TRANSLOG_BUFFERS_NO); translog_unlock(); @@ -7656,10 +7808,12 @@ my_bool translog_flush(TRANSLOG_ADDRESS lsn) { DBUG_PRINT("info", ("There is no LSNs yet generated => do nothing")); translog_unlock(); - goto out; + DBUG_VOID_RETURN; } - sent_to_disk= translog_get_sent_to_disk(); - if (cmp_translog_addr(lsn, sent_to_disk) > 0) + + /* flush buffers */ + *sent_to_disk= translog_get_sent_to_disk(); + if (cmp_translog_addr(*lsn, *sent_to_disk) > 0) { DBUG_PRINT("info", ("Start buffer #: %u last buffer #: %u", @@ -7679,53 +7833,235 @@ my_bool translog_flush(TRANSLOG_ADDRESS lsn) LSN_IN_PARTS(buffer->last_lsn), (buffer->file ? "dirty" : "closed"))); - if (buffer->prev_last_lsn <= lsn && + if (buffer->prev_last_lsn <= *lsn && buffer->file != NULL) { - DBUG_ASSERT(flush_horizon <= buffer->offset + buffer->size); - flush_horizon= buffer->offset + buffer->size; + DBUG_ASSERT(*flush_horizon <= buffer->offset + buffer->size); + *flush_horizon= (buffer->pre_force_close_horizon != LSN_IMPOSSIBLE ? + buffer->pre_force_close_horizon : + buffer->offset + buffer->size); + /* pre_force_close_horizon is reset during new buffer start */ + DBUG_PRINT("info", ("flush_horizon: (%lu,0x%lx)", + LSN_IN_PARTS(*flush_horizon))); + DBUG_ASSERT(*flush_horizon <= log_descriptor.horizon); + translog_buffer_flush(buffer); } translog_buffer_unlock(buffer); i= (i + 1) % TRANSLOG_BUFFERS_NO; } while (i != last_buffer_no); - sent_to_disk= translog_get_sent_to_disk(); + *sent_to_disk= translog_get_sent_to_disk(); } - /* sync files from previous flush till current one */ - for (fn= LSN_FILE_NO(log_descriptor.flushed); fn <= LSN_FILE_NO(lsn); fn++) + DBUG_VOID_RETURN; +} + +/** + @brief Flush the log up to given LSN (included) + + @param lsn log record serial number up to which (inclusive) + the log has to be flushed + + @return Operation status + @retval 0 OK + @retval 1 Error + + @note + + - Non group commit logic: Commits made in passes. Thread which started + flush first is performing actual flush, other threads sets new goal (LSN) + of the next pass (if it is maximum) and waits for the pass end or just + wait for the pass end. + + - If hard group commit enabled and rate set to zero: + The first thread sends all changed buffers to disk. This is repeated + as long as there are new LSNs added. The process can not loop + forever because we have limited number of threads and they will wait + for the data to be synced. + Pseudo code: + + do + send changed buffers to disk + while new_goal + sync + + - If hard group commit switched ON and less than rate microseconds has + passed from last sync, then after buffers have been sent to disk + wait until rate microseconds has passed since last sync, do sync and return. + This ensures that if we call sync infrequently we don't do any waits. + + - If soft group commit enabled everything works as with 'non group commit' + but the thread doesn't do any real sync(). If rate is not zero the + sync() will be performed by a service thread with the given rate + when needed (new LSN appears). + + @note Terminology: + 'sent to disk' means written to disk but not sync()ed, + 'flushed' mean sent to disk and synced(). +*/ + +my_bool translog_flush(TRANSLOG_ADDRESS lsn) +{ + struct timespec abstime; + ulonglong flush_interval; + ulonglong time_spent; + LSN sent_to_disk= LSN_IMPOSSIBLE; + TRANSLOG_ADDRESS flush_horizon; + my_bool rc= 0; + my_bool hgroup_commit_at_start; + DBUG_ENTER("translog_flush"); + DBUG_PRINT("enter", ("Flush up to LSN: (%lu,0x%lx)", LSN_IN_PARTS(lsn))); + DBUG_ASSERT(translog_status == TRANSLOG_OK || + translog_status == TRANSLOG_READONLY); + LINT_INIT(sent_to_disk); + LINT_INIT(flush_interval); + + pthread_mutex_lock(&log_descriptor.log_flush_lock); + DBUG_PRINT("info", ("Everything is flushed up to (%lu,0x%lx)", + LSN_IN_PARTS(log_descriptor.flushed))); + if (cmp_translog_addr(log_descriptor.flushed, lsn) >= 0) { - TRANSLOG_FILE *file= get_logfile_by_number(fn); - DBUG_ASSERT(file != NULL); - if (!file->is_sync) + pthread_mutex_unlock(&log_descriptor.log_flush_lock); + DBUG_RETURN(0); + } + if (log_descriptor.flush_in_progress) + { + translog_lock(); + /* fix lsn if it was horizon */ + if (cmp_translog_addr(lsn, log_descriptor.bc.buffer->last_lsn) > 0) + lsn= BUFFER_MAX_LSN(log_descriptor.bc.buffer); + translog_unlock(); + translog_flush_set_new_goal_and_wait(lsn); + if (!pthread_equal(log_descriptor.max_lsn_requester, pthread_self())) { - if (my_sync(file->handler.file, MYF(MY_WME))) + /* + translog_flush_wait_for_end() release log_flush_lock while is + waiting then acquire it again + */ + translog_flush_wait_for_end(lsn); + pthread_mutex_unlock(&log_descriptor.log_flush_lock); + DBUG_RETURN(0); + } + log_descriptor.next_pass_max_lsn= LSN_IMPOSSIBLE; + } + log_descriptor.flush_in_progress= 1; + flush_horizon= log_descriptor.previous_flush_horizon; + DBUG_PRINT("info", ("flush_in_progress is set, flush_horizon: (%lu,0x%lx)", + LSN_IN_PARTS(flush_horizon))); + pthread_mutex_unlock(&log_descriptor.log_flush_lock); + + hgroup_commit_at_start= hard_group_commit; + if (hgroup_commit_at_start) + flush_interval= group_commit_wait; + + translog_lock(); + if (log_descriptor.is_everything_flushed) + { + DBUG_PRINT("info", ("everything is flushed")); + translog_unlock(); + pthread_mutex_lock(&log_descriptor.log_flush_lock); + goto out; + } + + for (;;) + { + /* Following function flushes buffers and makes translog_unlock() */ + translog_flush_buffers(&lsn, &sent_to_disk, &flush_horizon); + + if (!hgroup_commit_at_start) + break; /* flush pass is ended */ + +retest: + /* + We do not check time here because pthread_mutex_lock rarely takes + a lot of time so we can sacrifice a bit precision to performance + (taking into account that my_micro_time() might be expensive call). + */ + if (flush_interval == 0) + break; /* flush pass is ended */ + + pthread_mutex_lock(&log_descriptor.log_flush_lock); + if (log_descriptor.next_pass_max_lsn == LSN_IMPOSSIBLE) + { + if (flush_interval == 0 || + (time_spent= (my_micro_time() - flush_start)) >= flush_interval) { - rc= 1; - translog_stop_writing(); - sent_to_disk= LSN_IMPOSSIBLE; - goto out; + pthread_mutex_unlock(&log_descriptor.log_flush_lock); + break; } - file->is_sync= 1; + DBUG_PRINT("info", ("flush waits: %llu interval: %llu spent: %llu", + flush_interval - time_spent, + flush_interval, time_spent)); + /* wait time or next goal */ + set_timespec_nsec(abstime, flush_interval - time_spent); + pthread_cond_timedwait(&log_descriptor.new_goal_cond, + &log_descriptor.log_flush_lock, + &abstime); + pthread_mutex_unlock(&log_descriptor.log_flush_lock); + DBUG_PRINT("info", ("retest conditions")); + goto retest; } + + /* take next goal */ + lsn= log_descriptor.next_pass_max_lsn; + log_descriptor.next_pass_max_lsn= LSN_IMPOSSIBLE; + /* prevent other thread from continue */ + log_descriptor.max_lsn_requester= pthread_self(); + DBUG_PRINT("info", ("flush took next goal: (%lu,0x%lx)", + LSN_IN_PARTS(lsn))); + pthread_mutex_unlock(&log_descriptor.log_flush_lock); + + /* next flush pass */ + DBUG_PRINT("info", ("next flush pass")); + translog_lock(); } - if (sync_log_dir >= TRANSLOG_SYNC_DIR_ALWAYS && - (LSN_FILE_NO(log_descriptor.previous_flush_horizon) != - LSN_FILE_NO(flush_horizon) || - ((LSN_OFFSET(log_descriptor.previous_flush_horizon) - 1) / - TRANSLOG_PAGE_SIZE) != - ((LSN_OFFSET(flush_horizon) - 1) / TRANSLOG_PAGE_SIZE))) - rc|= sync_dir(log_descriptor.directory_fd, MYF(MY_WME | MY_IGNORE_BADFD)); + /* + sync() files from previous flush till current one + */ + if (!soft_sync || hgroup_commit_at_start) + { + if ((rc= + translog_sync_files(LSN_FILE_NO(log_descriptor.flushed), + LSN_FILE_NO(lsn), + sync_log_dir >= TRANSLOG_SYNC_DIR_ALWAYS && + (LSN_FILE_NO(log_descriptor. + previous_flush_horizon) != + LSN_FILE_NO(flush_horizon) || + (LSN_OFFSET(log_descriptor. + previous_flush_horizon) / + TRANSLOG_PAGE_SIZE) != + (LSN_OFFSET(flush_horizon) / + TRANSLOG_PAGE_SIZE))))) + { + sent_to_disk= LSN_IMPOSSIBLE; + pthread_mutex_lock(&log_descriptor.log_flush_lock); + goto out; + } + /* keep values for soft sync() and forced sync() actual */ + { + uint32 fileno= LSN_FILE_NO(lsn); + soft_sync_min= fileno; + soft_sync_max= fileno; + } + } + else + { + soft_sync_max= LSN_FILE_NO(lsn); + soft_need_sync= 1; + } + + DBUG_ASSERT(flush_horizon <= log_descriptor.horizon); + + pthread_mutex_lock(&log_descriptor.log_flush_lock); log_descriptor.previous_flush_horizon= flush_horizon; out: - pthread_mutex_lock(&log_descriptor.log_flush_lock); if (sent_to_disk != LSN_IMPOSSIBLE) log_descriptor.flushed= sent_to_disk; log_descriptor.flush_in_progress= 0; log_descriptor.flush_no++; DBUG_PRINT("info", ("flush_in_progress is dropped")); - pthread_mutex_unlock(&log_descriptor.log_flush_lock);\ + pthread_mutex_unlock(&log_descriptor.log_flush_lock); pthread_cond_broadcast(&log_descriptor.log_flush_cond); DBUG_RETURN(rc); } @@ -7817,6 +8153,7 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn) before it's written to the log. */ share->id= id; + share->state.logrec_file_id= lsn; } pthread_mutex_unlock(&share->intern_lock); return 0; @@ -8104,6 +8441,8 @@ LSN translog_first_theoretical_lsn() my_bool translog_purge(TRANSLOG_ADDRESS low) { uint32 last_need_file= LSN_FILE_NO(low); + uint32 min_unsync; + int soft; TRANSLOG_ADDRESS horizon= translog_get_horizon(); int rc= 0; DBUG_ENTER("translog_purge"); @@ -8111,12 +8450,24 @@ my_bool translog_purge(TRANSLOG_ADDRESS low) DBUG_ASSERT(translog_status == TRANSLOG_OK || translog_status == TRANSLOG_READONLY); + soft= soft_sync; + min_unsync= soft_sync_min; + DBUG_PRINT("info", ("min_unsync: %lu", (ulong) min_unsync)); + if (soft && min_unsync < last_need_file) + { + last_need_file= min_unsync; + DBUG_PRINT("info", ("last_need_file set to %lu", (ulong)last_need_file)); + } + pthread_mutex_lock(&log_descriptor.purger_lock); + DBUG_PRINT("info", ("last_lsn_checked file: %lu:", + (ulong) log_descriptor.last_lsn_checked)); if (LSN_FILE_NO(log_descriptor.last_lsn_checked) < last_need_file) { uint32 i; uint32 min_file= translog_first_file(horizon, 1); DBUG_ASSERT(min_file != 0); /* log is already started */ + DBUG_PRINT("info", ("min_file: %lu:",(ulong) min_file)); for(i= min_file; i < last_need_file && rc == 0; i++) { LSN lsn= translog_get_file_max_lsn_stored(i); @@ -8309,6 +8660,192 @@ void translog_set_file_size(uint32 size) /** + Write debug information to log if we EXTRA_DEBUG is enabled +*/ + +my_bool translog_log_debug_info(TRN *trn __attribute__((unused)), + enum translog_debug_info_type type + __attribute__((unused)), + uchar *info __attribute__((unused)), + size_t length __attribute__((unused))) +{ +#ifdef EXTRA_DEBUG + LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; + uchar debug_type; + LSN lsn; + + if (!trn) + { + /* + We can't log the current transaction because we don't have + an active transaction. Use a temporary transaction object instead + */ + trn= &dummy_transaction_object; + } + debug_type= (uchar) type; + log_array[TRANSLOG_INTERNAL_PARTS + 0].str= &debug_type; + log_array[TRANSLOG_INTERNAL_PARTS + 0].length= 1; + log_array[TRANSLOG_INTERNAL_PARTS + 1].str= info; + log_array[TRANSLOG_INTERNAL_PARTS + 1].length= length; + return translog_write_record(&lsn, LOGREC_DEBUG_INFO, + trn, NULL, + (translog_size_t) (1+ length), + sizeof(log_array)/sizeof(log_array[0]), + log_array, NULL, NULL); +#else + return 0; +#endif +} + + + +/** + Sets soft sync mode + + @param mode TRUE if we need switch soft sync on else off +*/ + +void translog_soft_sync(my_bool mode) +{ + soft_sync= mode; +} + + +/** + Sets hard group commit + + @param mode TRUE if we need switch hard group commit on else off +*/ + +void translog_hard_group_commit(my_bool mode) +{ + hard_group_commit= mode; +} + + +/** + @brief forced log sync (used when we are switching modes) +*/ + +void translog_sync() +{ + uint32 max= get_current_logfile()->number; + uint32 min; + DBUG_ENTER("ma_translog_sync"); + + min= soft_sync_min; + if (!min) + min= max; + + translog_sync_files(min, max, sync_log_dir >= TRANSLOG_SYNC_DIR_ALWAYS); + + DBUG_VOID_RETURN; +} + + +/** + @brief set rate for group commit + + @param interval interval to set. + + @note We use this function with additional variable because have to + restart service thread with new value which we can't make inside changing + variable routine (update_maria_group_commit_interval) +*/ + +void translog_set_group_commit_interval(uint32 interval) +{ + DBUG_ENTER("translog_set_group_commit_interval"); + group_commit_wait= interval; + DBUG_PRINT("info", ("wait: %llu", + (ulonglong)group_commit_wait)); + DBUG_VOID_RETURN; +} + + +/** + @brief syncing service thread +*/ + +static pthread_handler_t +ma_soft_sync_background( void *arg __attribute__((unused))) +{ + + my_thread_init(); + { + DBUG_ENTER("ma_soft_sync_background"); + for(;;) + { + ulonglong prev_loop= my_micro_time(); + ulonglong time, sleep; + uint32 min, max, sync_request; + min= soft_sync_min; + max= soft_sync_max; + sync_request= soft_need_sync; + soft_sync_min= max; + soft_need_sync= 0; + + sleep= group_commit_wait; + if (sync_request) + translog_sync_files(min, max, FALSE); + time= my_micro_time() - prev_loop; + if (time > sleep) + sleep= 0; + else + sleep-= time; + if (my_service_thread_sleep(&soft_sync_control, sleep)) + break; + } + my_service_thread_signal_end(&soft_sync_control); + my_thread_end(); + DBUG_RETURN(0); + } +} + + +/** + @brief Starts syncing thread +*/ + +int translog_soft_sync_start(void) +{ + pthread_t th; + int res= 0; + uint32 min, max; + DBUG_ENTER("translog_soft_sync_start"); + + /* check and init variables */ + min= soft_sync_min; + max= soft_sync_max; + if (!max) + soft_sync_max= max= get_current_logfile()->number; + if (!min) + soft_sync_min= max; + soft_need_sync= 1; + + if (!(res= ma_service_thread_control_init(&soft_sync_control))) + if (!(res= pthread_create(&th, NULL, ma_soft_sync_background, NULL))) + soft_sync_control.status= THREAD_RUNNING; + DBUG_RETURN(res); +} + + +/** + @brief Stops syncing thread +*/ + +void translog_soft_sync_end(void) +{ + DBUG_ENTER("translog_soft_sync_end"); + if (soft_sync_control.inited) + { + ma_service_thread_control_end(&soft_sync_control); + } + DBUG_VOID_RETURN; +} + + +/** @brief Dump information about file header page. */ @@ -8316,10 +8853,11 @@ static void dump_header_page(uchar *buff) { LOGHANDLER_FILE_INFO desc; char strbuff[21]; + LINT_INIT_STRUCT(desc); translog_interpret_file_header(&desc, buff); printf(" This can be header page:\n" " Timestamp: %s\n" - " Maria log version: %lu\n" + " Aria log version: %lu\n" " Server version: %lu\n" " Server id %lu\n" " Page size %lu\n", @@ -8582,42 +9120,3 @@ void dump_page(uchar *buffer, File handler) } dump_datapage(buffer, handler); } - - -/** - Write debug information to log if we EXTRA_DEBUG is enabled -*/ - -my_bool translog_log_debug_info(TRN *trn __attribute__((unused)), - enum translog_debug_info_type type - __attribute__((unused)), - uchar *info __attribute__((unused)), - size_t length __attribute__((unused))) -{ -#ifdef EXTRA_DEBUG - LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; - uchar debug_type; - LSN lsn; - - if (!trn) - { - /* - We can't log the current transaction because we don't have - an active transaction. Use a temporary transaction object instead - */ - trn= &dummy_transaction_object; - } - debug_type= (uchar) type; - log_array[TRANSLOG_INTERNAL_PARTS + 0].str= &debug_type; - log_array[TRANSLOG_INTERNAL_PARTS + 0].length= 1; - log_array[TRANSLOG_INTERNAL_PARTS + 1].str= info; - log_array[TRANSLOG_INTERNAL_PARTS + 1].length= length; - return translog_write_record(&lsn, LOGREC_DEBUG_INFO, - trn, NULL, - (translog_size_t) (1+ length), - sizeof(log_array)/sizeof(log_array[0]), - log_array, NULL, NULL); -#else - return 0; -#endif -} diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h index c22d361d142..f33e92e9771 100644 --- a/storage/maria/ma_loghandler.h +++ b/storage/maria/ma_loghandler.h @@ -16,12 +16,14 @@ #ifndef _ma_loghandler_h #define _ma_loghandler_h +#define MB (1024UL*1024) + /* transaction log default cache size (TODO: make it global variable) */ -#define TRANSLOG_PAGECACHE_SIZE (1024U*1024*2) +#define TRANSLOG_PAGECACHE_SIZE (2*MB) /* transaction log default file size */ -#define TRANSLOG_FILE_SIZE (1024U*1024*1024) +#define TRANSLOG_FILE_SIZE (1024U*MB) /* minimum possible transaction log size */ -#define TRANSLOG_MIN_FILE_SIZE (1024U*1024*8) +#define TRANSLOG_MIN_FILE_SIZE (8*MB) /* transaction log default flags (TODO: make it global variable) */ #define TRANSLOG_DEFAULT_FLAGS 0 @@ -371,6 +373,14 @@ enum enum_translog_status TRANSLOG_SHUTDOWN /* going to shutdown the loghandler */ }; extern enum enum_translog_status translog_status; +extern ulonglong translog_syncs; /* Number of sync()s */ + +void translog_soft_sync(my_bool mode); +void translog_hard_group_commit(my_bool mode); +int translog_soft_sync_start(void); +void translog_soft_sync_end(void); +void translog_sync(); +void translog_set_group_commit_interval(uint32 interval); /* all the rest added because of recovery; should we make @@ -493,6 +503,14 @@ extern LOG_DESC log_record_type_descriptor[LOGREC_NUMBER_OF_TYPES]; typedef enum { + TRANSLOG_GCOMMIT_NONE, + TRANSLOG_GCOMMIT_HARD, + TRANSLOG_GCOMMIT_SOFT +} enum_maria_group_commit; +extern ulong maria_group_commit; +extern ulong maria_group_commit_interval; +typedef enum +{ TRANSLOG_PURGE_IMMIDIATE, TRANSLOG_PURGE_EXTERNAL, TRANSLOG_PURGE_ONDEMAND diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index c8e4572b8d4..3f15749ced5 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -135,7 +135,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name, info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND); info.opt_flag=READ_CHECK_USED; info.this_unique= (ulong) info.dfile.file; /* Uniq number in process */ -#ifdef EXTERNAL_LOCKING +#ifdef MARIA_EXTERNAL_LOCKING if (share->data_file_type == COMPRESSED_RECORD) info.this_unique= share->state.unique; info.this_loop=0; /* Update counter */ @@ -563,21 +563,40 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->block_size= share->base.block_size; /* Convenience */ share->max_index_block_size= share->block_size - KEYPAGE_CHECKSUM_SIZE; + share->keypage_header= ((share->base.born_transactional ? + LSN_STORE_SIZE + TRANSID_SIZE : + 0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + + KEYPAGE_USED_SIZE); { HA_KEYSEG *pos=share->keyparts; uint32 ftkey_nr= 1; for (i=0 ; i < keys ; i++) { - share->keyinfo[i].share= share; - disk_pos=_ma_keydef_read(disk_pos, &share->keyinfo[i]); - share->keyinfo[i].key_nr= i; + MARIA_KEYDEF *keyinfo= &share->keyinfo[i]; + keyinfo->share= share; + disk_pos=_ma_keydef_read(disk_pos, keyinfo); + keyinfo->key_nr= i; + + /* See ma_delete.cc::underflow() */ + if (!(keyinfo->flag & (HA_BINARY_PACK_KEY | HA_PACK_KEY))) + keyinfo->underflow_block_length= keyinfo->block_length/3; + else + { + /* Packed key, ensure we don't get overflow in underflow() */ + keyinfo->underflow_block_length= + max((int) (share->max_index_block_size - keyinfo->maxlength * 3), + (int) (share->keypage_header + share->base.key_reflength)); + set_if_smaller(keyinfo->underflow_block_length, + keyinfo->block_length/3); + } + disk_pos_assert(share, - disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE, + disk_pos + keyinfo->keysegs * HA_KEYSEG_SIZE, end_pos); - if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE) + if (keyinfo->key_alg == HA_KEY_ALG_RTREE) share->have_rtree= 1; - share->keyinfo[i].seg=pos; - for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++) + keyinfo->seg=pos; + for (j=0 ; j < keyinfo->keysegs; j++,pos++) { disk_pos=_ma_keyseg_read(disk_pos, pos); if (pos->type == HA_KEYTYPE_TEXT || @@ -595,25 +614,25 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) else if (pos->type == HA_KEYTYPE_BINARY) pos->charset= &my_charset_bin; } - if (share->keyinfo[i].flag & HA_SPATIAL) + if (keyinfo->flag & HA_SPATIAL) { #ifdef HAVE_SPATIAL uint sp_segs=SPDIMS*2; - share->keyinfo[i].seg=pos-sp_segs; - share->keyinfo[i].keysegs--; + keyinfo->seg=pos-sp_segs; + keyinfo->keysegs--; versioning= 0; #else my_errno=HA_ERR_UNSUPPORTED; goto err; #endif } - else if (share->keyinfo[i].flag & HA_FULLTEXT) + else if (keyinfo->flag & HA_FULLTEXT) { versioning= 0; DBUG_ASSERT(fulltext_keys); { uint k; - share->keyinfo[i].seg=pos; + keyinfo->seg=pos; for (k=0; k < FT_SEGS; k++) { *pos= ft_keysegs[k]; @@ -628,8 +647,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) } if (!share->ft2_keyinfo.seg) { - memcpy(&share->ft2_keyinfo, &share->keyinfo[i], - sizeof(MARIA_KEYDEF)); + memcpy(&share->ft2_keyinfo, keyinfo, sizeof(MARIA_KEYDEF)); share->ft2_keyinfo.keysegs=1; share->ft2_keyinfo.flag=0; share->ft2_keyinfo.keylength= @@ -639,10 +657,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->ft2_keyinfo.end=pos; setup_key_functions(& share->ft2_keyinfo); } - share->keyinfo[i].ftkey_nr= ftkey_nr++; + keyinfo->ftkey_nr= ftkey_nr++; } - setup_key_functions(share->keyinfo+i); - share->keyinfo[i].end=pos; + setup_key_functions(keyinfo); + keyinfo->end=pos; pos->type=HA_KEYTYPE_END; /* End */ pos->length=share->base.rec_reflength; pos->null_bit=0; @@ -686,10 +704,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->base.null_bytes + share->base.pack_bytes + test(share->options & HA_OPTION_CHECKSUM)); - share->keypage_header= ((share->base.born_transactional ? - LSN_STORE_SIZE + TRANSID_SIZE : - 0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + - KEYPAGE_USED_SIZE); share->kfile.file= kfile; if (open_flags & HA_OPEN_COPY) @@ -804,7 +818,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) _ma_set_index_pagecache_callbacks(&share->kfile, share); share->this_process=(ulong) getpid(); -#ifdef EXTERNAL_LOCKING +#ifdef MARIA_EXTERNAL_LOCKING share->last_process= share->state.process; #endif share->base.key_parts=key_parts; @@ -922,7 +936,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) { /* We must have internal_lock before bitmap_lock because we call - _ma_flush_tables_files() with internal_lock locked. + _ma_flush_table_files() with internal_lock locked. */ pthread_mutex_lock(&share->intern_lock); pthread_mutex_lock(&share->bitmap.bitmap_lock); @@ -1443,7 +1457,7 @@ static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state) uint _ma_state_info_read_dsk(File file __attribute__((unused)), MARIA_STATE_INFO *state __attribute__((unused))) { -#ifdef EXTERNAL_LOCKING +#ifdef MARIA_EXTERNAL_LOCKING uchar buff[MARIA_STATE_INFO_SIZE + MARIA_STATE_EXTRA_SIZE]; /* trick to detect transactional tables */ @@ -1580,7 +1594,6 @@ uchar *_ma_keydef_read(uchar *ptr, MARIA_KEYDEF *keydef) keydef->keylength = mi_uint2korr(ptr); ptr+= 2; keydef->minlength = mi_uint2korr(ptr); ptr+= 2; keydef->maxlength = mi_uint2korr(ptr); ptr+= 2; - keydef->underflow_block_length=keydef->block_length/3; keydef->version = 0; /* Not saved */ keydef->parser = &ft_default_parser; keydef->ftkey_nr = 0; diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c index bcd50f028ec..9f6a7406ea7 100644 --- a/storage/maria/ma_page.c +++ b/storage/maria/ma_page.c @@ -193,6 +193,7 @@ my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock, nod_flag= _ma_test_if_nod(share, buff); DBUG_ASSERT(page->size == page_length); + DBUG_ASSERT(page->size <= share->max_index_block_size); DBUG_ASSERT(page->flag == _ma_get_keypage_flag(share, buff)); if (page->pos < share->base.keystart || diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 63ba393e271..e96bf0cda25 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -173,6 +173,7 @@ struct st_pagecache_hash_link #define PCBLOCK_IN_FLUSH 16 /* block is in flush operation */ #define PCBLOCK_CHANGED 32 /* block buffer contains a dirty page */ #define PCBLOCK_DIRECT_W 64 /* possible direct write to the block */ +#define PCBLOCK_DEL_WRITE 128 /* should be written on delete */ /* page status, returned by find_block */ #define PAGE_READ 0 @@ -493,6 +494,7 @@ error: #define FLUSH_CACHE 2000 /* sort this many blocks at once */ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block); +static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link); #ifndef DBUG_OFF static void test_key_cache(PAGECACHE *pagecache, const char *where, my_bool lock); @@ -539,7 +541,7 @@ static void pagecache_debug_print _VARARGS((const char *fmt, ...)); #define KEYCACHE_DBUG_ASSERT(a) \ { if (! (a) && pagecache_debug_log) \ fclose(pagecache_debug_log); \ - assert(a); } + DBUG_ASSERT(a); } #else #define KEYCACHE_PRINT(l, m) #define KEYCACHE_DBUG_PRINT(l, m) DBUG_PRINT(l, m) @@ -1029,8 +1031,7 @@ ulong resize_pagecache(PAGECACHE *pagecache, #ifdef THREAD while (pagecache->cnt_for_resize_op) { - KEYCACHE_DBUG_PRINT("resize_pagecache: wait", - ("suspend thread %ld", thread->id)); + DBUG_PRINT("wait", ("suspend thread %s %ld", thread->name, thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } #else @@ -1049,8 +1050,9 @@ finish: /* Signal for the next resize request to proceeed if any */ if (wqueue->last_thread) { - KEYCACHE_DBUG_PRINT("resize_pagecache: signal", - ("thread %ld", wqueue->last_thread->next->id)); + DBUG_PRINT("signal", + ("thread %s %ld", wqueue->last_thread->next->name, + wqueue->last_thread->next->id)); pagecache_pthread_cond_signal(&wqueue->last_thread->next->suspend); } #endif @@ -1074,6 +1076,7 @@ static inline void inc_counter_for_resize_op(PAGECACHE *pagecache) Decrement counter blocking resize key cache operation; Signal the operation to proceed when counter becomes equal zero */ + static inline void dec_counter_for_resize_op(PAGECACHE *pagecache) { #ifdef THREAD @@ -1082,8 +1085,9 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache) if (!--pagecache->cnt_for_resize_op && (last_thread= pagecache->resize_queue.last_thread)) { - KEYCACHE_DBUG_PRINT("dec_counter_for_resize_op: signal", - ("thread %ld", last_thread->next->id)); + DBUG_PRINT("signal", + ("thread %s %ld", last_thread->next->name, + last_thread->next->id)); pagecache_pthread_cond_signal(&last_thread->next->suspend); } #else @@ -1255,7 +1259,7 @@ static void link_to_file_list(PAGECACHE *pagecache, link_changed(block, &pagecache->file_blocks[FILE_HASH(*file)]); if (block->status & PCBLOCK_CHANGED) { - block->status&= ~PCBLOCK_CHANGED; + block->status&= ~(PCBLOCK_CHANGED | PCBLOCK_DEL_WRITE); block->rec_lsn= LSN_MAX; pagecache->blocks_changed--; pagecache->global_blocks_changed--; @@ -1321,6 +1325,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, { PAGECACHE_BLOCK_LINK *ins; PAGECACHE_BLOCK_LINK **ptr_ins; + DBUG_ENTER("link_block"); PCBLOCK_INFO(block); KEYCACHE_DBUG_ASSERT(! (block->hash_link && block->hash_link->requests)); @@ -1335,6 +1340,11 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, PAGECACHE_HASH_LINK *hash_link= (PAGECACHE_HASH_LINK *) first_thread->opt_info; struct st_my_thread_var *thread; + + DBUG_ASSERT(block->requests + block->wlocks + block->rlocks + + block->pins == 0); + DBUG_ASSERT(block->next_used == NULL); + do { thread= next_thread; @@ -1345,7 +1355,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, */ if ((PAGECACHE_HASH_LINK *) thread->opt_info == hash_link) { - KEYCACHE_DBUG_PRINT("link_block: signal", ("thread: %ld", thread->id)); + DBUG_PRINT("signal", ("thread: %s %ld", thread->name, thread->id)); pagecache_pthread_cond_signal(&thread->suspend); wqueue_unlink_from_queue(&pagecache->waiting_for_block, thread); block->requests++; @@ -1353,14 +1363,17 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, } while (thread != last_thread); hash_link->block= block; - KEYCACHE_THREAD_TRACE("link_block: after signaling"); + /* Ensure that no other thread tries to use this block */ + block->status|= PCBLOCK_REASSIGNED; + + DBUG_PRINT("signal", ("after signal")); #if defined(PAGECACHE_DEBUG) KEYCACHE_DBUG_PRINT("link_block", ("linked,unlinked block: %u status: %x #requests: %u #available: %u", PCBLOCK_NUMBER(pagecache, block), block->status, block->requests, pagecache->blocks_available)); #endif - return; + DBUG_VOID_RETURN; } #else /* THREAD */ KEYCACHE_DBUG_ASSERT(! (!hot && pagecache->waiting_for_block.last_thread)); @@ -1380,8 +1393,6 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, else { /* The LRU chain is empty */ - /* QQ: Ask sanja if next line is correct; Should we really put block - in both chain if one chain is empty ? */ pagecache->used_last= pagecache->used_ins= block->next_used= block; block->prev_used= &block->next_used; } @@ -1395,6 +1406,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, KEYCACHE_DBUG_ASSERT((ulong) pagecache->blocks_available <= pagecache->blocks_used); #endif + DBUG_VOID_RETURN; } @@ -1403,7 +1415,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, SYNOPSIS unlink_block() - pagecache pointer to a page cache data structure + pagecache pointer to a page cache data structure block pointer to the block to unlink from the LRU chain RETURN VALUE @@ -1510,7 +1522,7 @@ static void unreg_request(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, int at_end) { DBUG_ENTER("unreg_request"); - DBUG_PRINT("enter", ("block 0x%lx (%u) status: %x reqs: %u", + DBUG_PRINT("enter", ("block 0x%lx (%u) status: %x requests: %u", (ulong)block, PCBLOCK_NUMBER(pagecache, block), block->status, block->requests)); PCBLOCK_INFO(block); @@ -1579,18 +1591,23 @@ static inline void remove_reader(PAGECACHE_BLOCK_LINK *block) static inline void wait_for_readers(PAGECACHE *pagecache __attribute__((unused)), - PAGECACHE_BLOCK_LINK *block) + PAGECACHE_BLOCK_LINK *block + __attribute__((unused))) { #ifdef THREAD struct st_my_thread_var *thread= my_thread_var; + DBUG_ASSERT(block->condvar == NULL); while (block->hash_link->requests) { - KEYCACHE_DBUG_PRINT("wait_for_readers: wait", - ("suspend thread: %ld block: %u", - thread->id, PCBLOCK_NUMBER(pagecache, block))); + DBUG_ENTER("wait_for_readers"); + DBUG_PRINT("wait", + ("suspend thread: %s %ld block: %u", + thread->name, thread->id, + PCBLOCK_NUMBER(pagecache, block))); block->condvar= &thread->suspend; pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); block->condvar= NULL; + DBUG_VOID_RETURN; } #else KEYCACHE_DBUG_ASSERT(block->hash_link->requests == 0); @@ -1599,6 +1616,30 @@ static inline void wait_for_readers(PAGECACHE *pagecache /* + Wait until the flush of the page is done. +*/ + +static void wait_for_flush(PAGECACHE *pagecache + __attribute__((unused)), + PAGECACHE_BLOCK_LINK *block + __attribute__((unused))) +{ + struct st_my_thread_var *thread= my_thread_var; + DBUG_ENTER("wait_for_flush"); + wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); + do + { + DBUG_PRINT("wait", + ("suspend thread %s %ld", thread->name, thread->id)); + pagecache_pthread_cond_wait(&thread->suspend, + &pagecache->cache_lock); + } + while(thread->next); + DBUG_VOID_RETURN; +} + + +/* Add a hash link to a bucket in the hash_table */ @@ -1619,10 +1660,14 @@ static inline void link_hash(PAGECACHE_HASH_LINK **start, static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link) { - KEYCACHE_DBUG_PRINT("unlink_hash", ("fd: %u pos_ %lu #requests=%u", - (uint) hash_link->file.file, (ulong) hash_link->pageno, - hash_link->requests)); - KEYCACHE_DBUG_ASSERT(hash_link->requests == 0); + DBUG_ENTER("unlink_hash"); + DBUG_PRINT("enter", ("hash_link: %p fd: %u pos: %lu requests: %u", + hash_link, (uint) hash_link->file.file, + (ulong) hash_link->pageno, + hash_link->requests)); + DBUG_ASSERT(hash_link->requests == 0); + DBUG_ASSERT(!hash_link->block || hash_link->block->pins == 0); + if ((*hash_link->prev= hash_link->next)) hash_link->next->prev= hash_link->prev; hash_link->block= NULL; @@ -1653,23 +1698,32 @@ static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link) if (page->file.file == hash_link->file.file && page->pageno == hash_link->pageno) { - KEYCACHE_DBUG_PRINT("unlink_hash: signal", ("thread %ld", thread->id)); + DBUG_PRINT("signal", ("thread %s %ld", thread->name, thread->id)); pagecache_pthread_cond_signal(&thread->suspend); wqueue_unlink_from_queue(&pagecache->waiting_for_hash_link, thread); } } while (thread != last_thread); + + /* + Add this to the hash, so that the waiting threads can find it + when they retry the call to get_hash_link(). This entry is special + in that it has no associated block. + */ link_hash(&pagecache->hash_root[PAGECACHE_HASH(pagecache, hash_link->file, hash_link->pageno)], hash_link); - return; + DBUG_VOID_RETURN; } #else /* THREAD */ KEYCACHE_DBUG_ASSERT(! (pagecache->waiting_for_hash_link.last_thread)); #endif /* THREAD */ + + /* Add hash to free hash list */ hash_link->next= pagecache->free_hash_list; pagecache->free_hash_list= hash_link; + DBUG_VOID_RETURN; } @@ -1700,8 +1754,6 @@ static PAGECACHE_HASH_LINK *get_present_hash_link(PAGECACHE *pagecache, #endif DBUG_ENTER("get_present_hash_link"); DBUG_PRINT("enter", ("fd: %u pos: %lu", (uint) file->file, (ulong) pageno)); - KEYCACHE_PRINT("get_present_hash_link", ("fd: %u pos: %lu", - (uint) file->file, (ulong) pageno)); /* Find the bucket in the hash table for the pair (file, pageno); @@ -1736,6 +1788,7 @@ static PAGECACHE_HASH_LINK *get_present_hash_link(PAGECACHE *pagecache, } if (hash_link) { + DBUG_PRINT("exit", ("hash_link: %p", hash_link)); /* Register the request for the page */ hash_link->requests++; } @@ -1757,9 +1810,7 @@ static PAGECACHE_HASH_LINK *get_hash_link(PAGECACHE *pagecache, { reg1 PAGECACHE_HASH_LINK *hash_link; PAGECACHE_HASH_LINK **start; - - KEYCACHE_DBUG_PRINT("get_hash_link", ("fd: %u pos: %lu", - (uint) file->file, (ulong) pageno)); + DBUG_ENTER("get_hash_link"); restart: /* try to find the page in the cache */ @@ -1770,6 +1821,9 @@ restart: /* There is no hash link in the hash table for the pair (file, pageno) */ if (pagecache->free_hash_list) { + DBUG_PRINT("info", ("free_hash_list: %p free_hash_list->next: %p", + pagecache->free_hash_list, + pagecache->free_hash_list->next)); hash_link= pagecache->free_hash_list; pagecache->free_hash_list= hash_link->next; } @@ -1783,21 +1837,20 @@ restart: /* Wait for a free hash link */ struct st_my_thread_var *thread= my_thread_var; PAGECACHE_PAGE page; - KEYCACHE_DBUG_PRINT("get_hash_link", ("waiting")); page.file= *file; page.pageno= pageno; thread->opt_info= (void *) &page; wqueue_link_into_queue(&pagecache->waiting_for_hash_link, thread); - KEYCACHE_DBUG_PRINT("get_hash_link: wait", - ("suspend thread %ld", thread->id)); + DBUG_PRINT("wait", + ("suspend thread %s %ld", thread->name, thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); thread->opt_info= NULL; + DBUG_PRINT("thread", ("restarting...")); + goto restart; #else - KEYCACHE_DBUG_ASSERT(0); + DBUG_ASSERT(0); #endif - DBUG_PRINT("info", ("restarting...")); - goto restart; } hash_link->file= *file; DBUG_ASSERT(pageno < ((ULL(1)) << 40)); @@ -1806,9 +1859,19 @@ restart: /* Register the request for the page */ hash_link->requests++; DBUG_ASSERT(hash_link->block == 0); + DBUG_ASSERT(hash_link->requests == 1); } - - return hash_link; + else + { + /* + We have to copy the flush_log callback, as it may change if the table + goes from non_transactional to transactional during recovery + */ + hash_link->file.flush_log_callback= file->flush_log_callback; + } + DBUG_PRINT("exit", ("hash_link: %p block: %p", hash_link, + hash_link->block)); + DBUG_RETURN(hash_link); } @@ -1922,16 +1985,7 @@ restart: hash_link->requests--; { #ifdef THREAD - struct st_my_thread_var *thread= my_thread_var; - wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); - do - { - KEYCACHE_DBUG_PRINT("find_block: wait", - ("suspend thread %ld", thread->id)); - pagecache_pthread_cond_wait(&thread->suspend, - &pagecache->cache_lock); - } - while(thread->next); + wait_for_flush(pagecache, block); #else KEYCACHE_DBUG_ASSERT(0); /* @@ -1944,6 +1998,7 @@ restart: #endif } /* Invalidate page in the block if it has not been done yet */ + DBUG_ASSERT(block->status); /* Should always be true */ if (block->status) free_block(pagecache, block); return 0; @@ -1982,8 +2037,8 @@ restart: /* Wait until the request can be resubmitted */ do { - KEYCACHE_DBUG_PRINT("find_block: wait", - ("suspend thread %ld", thread->id)); + DBUG_PRINT("wait", + ("suspend thread %s %ld", thread->name, thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -2055,32 +2110,39 @@ restart: /* There are no never used blocks, use a block from the LRU chain */ /* - Wait until a new block is added to the LRU chain; - several threads might wait here for the same page, - all of them must get the same block + Ensure that we are going to register the block. + (This should be true as a new block could not have been + pinned by caller). */ + DBUG_ASSERT(reg_req); #ifdef THREAD if (! pagecache->used_last) { + /* + Wait until a new block is added to the LRU chain; + several threads might wait here for the same page, + all of them must get the same block. + + The block is given to us by the next thread executing + link_block(). + */ + struct st_my_thread_var *thread= my_thread_var; thread->opt_info= (void *) hash_link; wqueue_link_into_queue(&pagecache->waiting_for_block, thread); do { - KEYCACHE_DBUG_PRINT("find_block: wait", - ("suspend thread %ld", thread->id)); + DBUG_PRINT("wait", + ("suspend thread %s %ld", thread->name, thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } while (thread->next); thread->opt_info= NULL; block= hash_link->block; - /* - Ensure that we are register this block (all blocks not used by this - thread has to be registered). - */ - DBUG_ASSERT(reg_req); + /* Ensure that the block is registered */ + DBUG_ASSERT(block->requests >= 1); } else #else @@ -2092,21 +2154,24 @@ restart: unlinking it from the chain */ block= pagecache->used_last->next_used; - block->hits_left= init_hits_left; - block->last_hit_time= 0; if (reg_req) reg_requests(pagecache, block, 1); hash_link->block= block; + DBUG_ASSERT(block->requests == 1); } + PCBLOCK_INFO(block); - DBUG_ASSERT(block->wlocks == 0); - DBUG_ASSERT(block->rlocks == 0); - DBUG_ASSERT(block->rlocks_queue == 0); - DBUG_ASSERT(block->pins == 0); + + DBUG_ASSERT(block->hash_link == hash_link || + !(block->status & PCBLOCK_IN_SWITCH)); if (block->hash_link != hash_link && ! (block->status & PCBLOCK_IN_SWITCH) ) { + /* If another thread is flushing the block, wait for it. */ + if (block->status & PCBLOCK_IN_FLUSH) + wait_for_flush(pagecache, block); + /* this is a primary request for a new page */ DBUG_ASSERT(block->wlocks == 0); DBUG_ASSERT(block->rlocks == 0); @@ -2153,15 +2218,20 @@ restart: /* Remove the hash link for this page from the hash table */ unlink_hash(pagecache, block->hash_link); - /* All pending requests for this page must be resubmitted */ + #ifdef THREAD + /* All pending requests for this page must be resubmitted. */ if (block->wqueue[COND_FOR_SAVED].last_thread) wqueue_release_queue(&block->wqueue[COND_FOR_SAVED]); #endif } link_to_file_list(pagecache, block, file, (my_bool)(block->hash_link ? 1 : 0)); + + block->hash_link= hash_link; PCBLOCK_INFO(block); + block->hits_left= init_hits_left; + block->last_hit_time= 0; block->status= error ? PCBLOCK_ERROR : 0; block->error= error ? (int16) my_errno : 0; #ifndef DBUG_OFF @@ -2169,7 +2239,6 @@ restart: if (error) my_debug_put_break_here(); #endif - block->hash_link= hash_link; page_status= PAGE_TO_BE_READ; DBUG_PRINT("info", ("page to be read set for page 0x%lx", (ulong)block)); @@ -2192,12 +2261,24 @@ restart: } else { + /* + The block was found in the cache. It's either a already read + block or a block waiting to be read by another thread. + */ if (reg_req) reg_requests(pagecache, block, 1); KEYCACHE_DBUG_PRINT("find_block", ("block->hash_link: %p hash_link: %p " "block->status: %u", block->hash_link, hash_link, block->status )); + /* + block->hash_link != hash_link can only happen when + the block is in PCBLOCK_IN_SWITCH above (is flushed out + to be replaced by another block). The SWITCH code will change + block->hash_link to point to hash_link. + */ + KEYCACHE_DBUG_ASSERT(block->hash_link == hash_link || + block->status & PCBLOCK_IN_SWITCH); page_status= (((block->hash_link == hash_link) && (block->status & PCBLOCK_READ)) ? PAGE_READ : PAGE_WAIT_TO_BE_READ); @@ -2331,8 +2412,8 @@ static my_bool pagecache_wait_lock(PAGECACHE *pagecache, dec_counter_for_resize_op(pagecache); do { - KEYCACHE_DBUG_PRINT("get_wrlock: wait", - ("suspend thread %ld", thread->id)); + DBUG_PRINT("wait", + ("suspend thread %s %ld", thread->name, thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -2574,6 +2655,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache, DBUG_ASSERT(!any || ((lock == PAGECACHE_LOCK_LEFT_UNLOCKED) && (pin == PAGECACHE_UNPIN))); + DBUG_ASSERT(block->hash_link->block == block); switch (lock) { case PAGECACHE_LOCK_WRITE: /* free -> write */ @@ -2701,6 +2783,7 @@ static void read_block(PAGECACHE *pagecache, pagecache_pthread_mutex_lock(&pagecache->cache_lock); if (error) { + DBUG_ASSERT(maria_in_recovery || !maria_assert_if_crashed_table); block->status|= PCBLOCK_ERROR; block->error= (int16) my_errno; my_debug_put_break_here(); @@ -2740,8 +2823,8 @@ static void read_block(PAGECACHE *pagecache, wqueue_add_to_queue(&block->wqueue[COND_FOR_REQUESTED], thread); do { - DBUG_PRINT("read_block: wait", - ("suspend thread %ld", thread->id)); + DBUG_PRINT("wait", + ("suspend thread %s %ld", thread->name, thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -3443,7 +3526,7 @@ restart: } else { - if (!(status & PCBLOCK_ERROR)) + if (status & PCBLOCK_READ) { #if !defined(SERIALIZED_READ_FROM_CACHE) pagecache_pthread_mutex_unlock(&pagecache->cache_lock); @@ -3457,7 +3540,7 @@ restart: pagecache_pthread_mutex_lock(&pagecache->cache_lock); #endif } - else + if (status & PCBLOCK_ERROR) my_errno= block->error; } @@ -3510,6 +3593,31 @@ no_key_cache: /* Key cache is not used */ /* + @brief Set/reset flag that page always should be flushed on delete + + @param pagecache pointer to a page cache data structure + @param link direct link to page (returned by read or write) + @param write write on delete flag value + +*/ + +void pagecache_set_write_on_delete_by_link(PAGECACHE_BLOCK_LINK *block) +{ + DBUG_ENTER("pagecache_set_write_on_delete_by_link"); + DBUG_PRINT("enter", ("fd: %d block 0x%lx %d -> TRUE", + block->hash_link->file.file, + (ulong) block, + (int) block->status & PCBLOCK_DEL_WRITE)); + DBUG_ASSERT(block->pins); /* should be pinned */ + DBUG_ASSERT(block->wlocks); /* should be write locked */ + + block->status|= PCBLOCK_DEL_WRITE; + + DBUG_VOID_RETURN; +} + + +/* @brief Delete page from the buffer (common part for link and file/page) @param pagecache pointer to a page cache data structure @@ -3538,6 +3646,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache, } if (block->status & PCBLOCK_CHANGED) { + flush= (flush || (block->status & PCBLOCK_DEL_WRITE)); if (flush) { /* The block contains a dirty page - push it out of the cache */ @@ -3600,7 +3709,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache, DBUG_ASSERT(0); DBUG_ASSERT(block->hash_link->requests > 0); page_link->requests--; - /* See NOTE for pagecache_unlock about registering requests. */ + /* See NOTE for pagecache_unlock() about registering requests. */ free_block(pagecache, block); dec_counter_for_resize_op(pagecache); return 0; @@ -4205,6 +4314,7 @@ end: static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block) { + uint status= block->status; KEYCACHE_THREAD_TRACE("free block"); KEYCACHE_DBUG_PRINT("free_block", ("block: %u hash_link 0x%lx", @@ -4229,30 +4339,44 @@ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block) DBUG_ASSERT(block->rlocks == 0); DBUG_ASSERT(block->rlocks_queue == 0); DBUG_ASSERT(block->pins == 0); - DBUG_ASSERT((block->status & ~(PCBLOCK_ERROR | PCBLOCK_READ | PCBLOCK_IN_FLUSH | PCBLOCK_CHANGED | PCBLOCK_REASSIGNED)) == 0); + DBUG_ASSERT((block->status & ~(PCBLOCK_ERROR | PCBLOCK_READ | PCBLOCK_IN_FLUSH | PCBLOCK_CHANGED | PCBLOCK_REASSIGNED | PCBLOCK_DEL_WRITE)) == 0); + DBUG_ASSERT(block->requests >= 1); + DBUG_ASSERT(block->next_used == NULL); block->status= 0; #ifndef DBUG_OFF block->type= PAGECACHE_EMPTY_PAGE; #endif block->rec_lsn= LSN_MAX; + block->hash_link= NULL; + if (block->temperature == PCBLOCK_WARM) + pagecache->warm_blocks--; + block->temperature= PCBLOCK_COLD; KEYCACHE_THREAD_TRACE("free block"); KEYCACHE_DBUG_PRINT("free_block", ("block is freed")); unreg_request(pagecache, block, 0); - DBUG_ASSERT(block->requests == 0); - DBUG_ASSERT(block->next_used != 0); - block->hash_link= NULL; - /* Remove the free block from the LRU ring. */ - unlink_block(pagecache, block); - if (block->temperature == PCBLOCK_WARM) - pagecache->warm_blocks--; - block->temperature= PCBLOCK_COLD; - /* Insert the free block in the free list. */ - block->next_used= pagecache->free_block_list; - pagecache->free_block_list= block; - /* Keep track of the number of currently unused blocks. */ - pagecache->blocks_unused++; + /* + Block->requests is != 0 if unreg_requests()/link_block() gave the block + to a waiting thread + */ + if (!block->requests) + { + DBUG_ASSERT(block->next_used != 0); + + /* Remove the free block from the LRU ring. */ + unlink_block(pagecache, block); + /* Insert the free block in the free list. */ + block->next_used= pagecache->free_block_list; + pagecache->free_block_list= block; + /* Keep track of the number of currently unused blocks. */ + pagecache->blocks_unused++; + } + else + { + /* keep flag set by link_block() */ + block->status= status & PCBLOCK_REASSIGNED; + } #ifdef THREAD /* All pending requests for this page must be resubmitted. */ @@ -4510,8 +4634,9 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, wqueue_add_to_queue(&other_flusher->flush_queue, thread); do { - KEYCACHE_DBUG_PRINT("flush_pagecache_blocks_int: wait1", - ("suspend thread %ld", thread->id)); + DBUG_PRINT("wait", + ("(1) suspend thread %s %ld", + thread->name, thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -4672,8 +4797,9 @@ restart: wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); do { - KEYCACHE_DBUG_PRINT("flush_pagecache_blocks_int: wait2", - ("suspend thread %ld", thread->id)); + DBUG_PRINT("wait", + ("(2) suspend thread %s %ld", + thread->name, thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -4883,8 +5009,8 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache, wqueue_add_to_queue(&other_flusher->flush_queue, thread); do { - KEYCACHE_DBUG_PRINT("pagecache_collect_changed_blocks_with_lsn: wait", - ("suspend thread %ld", thread->id)); + DBUG_PRINT("wait", + ("suspend thread %s %ld", thread->name, thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -5028,7 +5154,7 @@ static void pagecache_dump(PAGECACHE *pagecache) PAGECACHE_PAGE *page; uint i; - fprintf(pagecache_dump_file, "thread:%u\n", thread->id); + fprintf(pagecache_dump_file, "thread: %s %ld\n", thread->name, thread->id); i=0; thread=last=waiting_for_hash_link.last_thread; @@ -5039,8 +5165,9 @@ static void pagecache_dump(PAGECACHE *pagecache) thread= thread->next; page= (PAGECACHE_PAGE *) thread->opt_info; fprintf(pagecache_dump_file, - "thread:%u, (file,pageno)=(%u,%lu)\n", - thread->id,(uint) page->file.file,(ulong) page->pageno); + "thread: %s %ld, (file,pageno)=(%u,%lu)\n", + thread->name, thread->id, + (uint) page->file.file,(ulong) page->pageno); if (++i == MAX_QUEUE_LEN) break; } @@ -5055,8 +5182,9 @@ static void pagecache_dump(PAGECACHE *pagecache) thread=thread->next; hash_link= (PAGECACHE_HASH_LINK *) thread->opt_info; fprintf(pagecache_dump_file, - "thread:%u hash_link:%u (file,pageno)=(%u,%lu)\n", - thread->id, (uint) PAGECACHE_HASH_LINK_NUMBER(pagecache, hash_link), + "thread: %s %u hash_link:%u (file,pageno)=(%u,%lu)\n", + thread->name, thread->id, + (uint) PAGECACHE_HASH_LINK_NUMBER(pagecache, hash_link), (uint) hash_link->file.file,(ulong) hash_link->pageno); if (++i == MAX_QUEUE_LEN) break; @@ -5085,7 +5213,7 @@ static void pagecache_dump(PAGECACHE *pagecache) { thread=thread->next; fprintf(pagecache_dump_file, - "thread:%u\n", thread->id); + "thread: %s %ld\n", thread->name, thread->id); if (++i == MAX_QUEUE_LEN) break; } diff --git a/storage/maria/ma_pagecache.h b/storage/maria/ma_pagecache.h index 5ed5719a8af..ca2a3822f66 100644 --- a/storage/maria/ma_pagecache.h +++ b/storage/maria/ma_pagecache.h @@ -252,6 +252,7 @@ extern void pagecache_unpin(PAGECACHE *pagecache, extern void pagecache_unpin_by_link(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *link, LSN lsn); +extern void pagecache_set_write_on_delete_by_link(PAGECACHE_BLOCK_LINK *block); /* Results of flush operation (bit field in fact) */ diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 73ecb208662..96504cfba2d 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -60,6 +60,7 @@ static int (*save_error_handler_hook)(uint, const char *,myf); static uint recovery_warnings; /**< count of warnings */ static uint recovery_found_crashed_tables; HASH tables_to_redo; /* For maria_read_log */ +ulong maria_recovery_force_crash_counter; #define prototype_redo_exec_hook(R) \ static int exec_REDO_LOGREC_ ## R(const TRANSLOG_HEADER_BUFFER *rec) @@ -228,12 +229,12 @@ int maria_recovery_from_log(void) maria_in_recovery= TRUE; #ifdef EXTRA_DEBUG - fn_format(name_buff, "maria_recovery.trace", maria_data_root, "", MYF(0)); + fn_format(name_buff, "aria_recovery.trace", maria_data_root, "", MYF(0)); trace_file= my_fopen(name_buff, O_WRONLY|O_APPEND|O_CREAT, MYF(MY_WME)); #else trace_file= NULL; /* no trace file for being fast */ #endif - tprint(trace_file, "TRACE of the last MARIA recovery from mysqld\n"); + tprint(trace_file, "TRACE of the last Aria recovery from mysqld\n"); DBUG_ASSERT(maria_pagecache->inited); res= maria_apply_log(LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, MARIA_LOG_APPLY, trace_file, TRUE, TRUE, TRUE, &warnings_count); @@ -319,25 +320,32 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn, skip_DDLs= skip_DDLs_arg; skipped_undo_phase= 0; + trnman_init(max_trid_in_control_file); + if (from_lsn == LSN_IMPOSSIBLE) { if (last_checkpoint_lsn == LSN_IMPOSSIBLE) { from_lsn= translog_first_lsn_in_log(); if (unlikely(from_lsn == LSN_ERROR)) + { + trnman_destroy(); goto err; + } } else { from_lsn= parse_checkpoint_record(last_checkpoint_lsn); if (from_lsn == LSN_ERROR) + { + trnman_destroy(); goto err; + } } } now= my_getsystime(); in_redo_phase= TRUE; - trnman_init(max_trid_in_control_file); if (run_redo_phase(from_lsn, end_lsn, apply)) { ma_message_no_user(0, "Redo phase failed"); @@ -525,14 +533,14 @@ end: if (!trace_file) fputc('\n', stderr); my_message(HA_ERR_INITIALIZATION, - "Maria recovery failed. Please run maria_chk -r on all maria " - "tables and delete all maria_log.######## files", MYF(0)); + "Aria recovery failed. Please run aria_chk -r on all Aria " + "tables and delete all aria_log.######## files", MYF(0)); } procent_printed= 0; /* We don't cleanly close tables if we hit some error (may corrupt them by flushing some wrong blocks made from wrong REDOs). It also leaves their - open_count>0, which ensures that --maria-recover, if used, will try to + open_count>0, which ensures that --aria-recover, if used, will try to repair them. */ DBUG_RETURN(error); @@ -695,7 +703,7 @@ prototype_redo_exec_hook(INCOMPLETE_LOG) failure in _ma_apply_redo_insert_row_head_or_tail(): new data page is created whereas rownr is not 0). So when the server disables logging for ALTER TABLE or CREATE SELECT, it - logs LOGREC_INCOMPLETE_LOG to warn maria_read_log and then the user. + logs LOGREC_INCOMPLETE_LOG to warn aria_read_log and then the user. Another issue is that replaying of DDLs is not correct enough to work if there was a crash during a DDL (see comment in execution of @@ -959,7 +967,7 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE) new_name); /* Here is why we skip CREATE/DROP/RENAME when doing a recovery from - ha_maria (whereas we do when called from maria_read_log). Consider: + ha_maria (whereas we do when called from aria_read_log). Consider: CREATE TABLE t; RENAME TABLE t to u; DROP TABLE u; @@ -979,8 +987,8 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE) crash. We however sync files and directories at each file rename. The SQL layer is anyway not crash-safe for DDLs (except the repartioning-related ones). - We replay DDLs in maria_read_log to be able to recreate tables from - scratch. It means that "maria_read_log -a" should not be used on a + We replay DDLs in aria_read_log to be able to recreate tables from + scratch. It means that "aria_read_log -a" should not be used on a database which just crashed during a DDL. And also ALTER TABLE does not log insertions of records into the temporary table, so replaying may fail (grep for INCOMPLETE_LOG in files). @@ -1407,7 +1415,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) if (maria_is_crashed(info)) { eprint(tracef, "Table '%s' is crashed, skipping it. Please repair it with" - " maria_chk -r", share->open_file_name.str); + " aria_chk -r", share->open_file_name.str); recovery_found_crashed_tables++; error= -1; /* not fatal, try with other tables */ goto end; @@ -2068,7 +2076,7 @@ prototype_redo_exec_hook(IMPORTED_TABLE) return 1; } name= (char *)log_record_buffer.str; - tprint(tracef, "Table '%s' was imported (auto-zerofilled) in this Maria instance\n", name); + tprint(tracef, "Table '%s' was imported (auto-zerofilled) in this Aria instance\n", name); return 0; } @@ -2939,6 +2947,12 @@ static int run_undo_phase(uint uncommitted) translog_free_record_header(&rec); } + /* Force a crash to test recovery of recovery */ + if (maria_recovery_force_crash_counter) + { + DBUG_ASSERT(--maria_recovery_force_crash_counter > 0); + } + if (trnman_rollback_trn(trn)) DBUG_RETURN(1); /* We could want to span a few threads (4?) instead of 1 */ @@ -3201,9 +3215,11 @@ static LSN parse_checkpoint_record(LSN lsn) tprint(tracef, "Loading data from checkpoint record at LSN (%lu,0x%lx)\n", LSN_IN_PARTS(lsn)); - if ((len= translog_read_record_header(lsn, &rec)) == RECHEADER_READ_ERROR) + if ((len= translog_read_record_header(lsn, &rec)) == RECHEADER_READ_ERROR || + rec.type != LOGREC_CHECKPOINT) { - tprint(tracef, "Cannot find checkpoint record where it should be\n"); + eprint(tracef, "Cannot find checkpoint record at LSN (%lu,0x%lx)", + LSN_IN_PARTS(lsn)); return LSN_ERROR; } @@ -3436,6 +3452,12 @@ static int close_all_tables(void) prepare_table_for_close(info, addr); error|= maria_close(info); pthread_mutex_lock(&THR_LOCK_maria); + + /* Force a crash to test recovery of recovery */ + if (maria_recovery_force_crash_counter) + { + DBUG_ASSERT(--maria_recovery_force_crash_counter > 0); + } } end: pthread_mutex_unlock(&THR_LOCK_maria); @@ -3510,7 +3532,7 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info, /* Reset state pointers. This is needed as in ALTER table we may do - commit fllowed by _ma_renable_logging_for_table and then + commit followed by _ma_renable_logging_for_table and then info->state may point to a state that was deleted by _ma_trnman_end_trans_hook() */ diff --git a/storage/maria/ma_recovery.h b/storage/maria/ma_recovery.h index 5b22c4fd9b2..45dba0e86b3 100644 --- a/storage/maria/ma_recovery.h +++ b/storage/maria/ma_recovery.h @@ -32,4 +32,5 @@ int maria_apply_log(LSN lsn, LSN lsn_end, enum maria_apply_log_way apply, my_bool take_checkpoints, uint *warnings_count); /* Table of tables to recover */ extern HASH tables_to_redo; +extern ulong maria_recovery_force_crash_counter; C_MODE_END diff --git a/storage/maria/ma_rt_split.c b/storage/maria/ma_rt_split.c index d8224dcbdd5..ea90b60ce12 100644 --- a/storage/maria/ma_rt_split.c +++ b/storage/maria/ma_rt_split.c @@ -542,8 +542,7 @@ int maria_rtree_split_page(const MARIA_KEY *key, MARIA_PAGE *page, } DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs)); - my_afree(new_page); - + my_afree(new_page_buff); split_err: my_afree(coord_buf); DBUG_RETURN(err_code); diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c index 1d5800eb3de..d6270daacee 100644 --- a/storage/maria/ma_search.c +++ b/storage/maria/ma_search.c @@ -435,7 +435,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, uint length_pack; MARIA_KEYDEF *keyinfo= key->keyinfo; MARIA_SHARE *share= keyinfo->share; - uchar *sort_order= keyinfo->seg->charset->sort_order; + const uchar *sort_order= keyinfo->seg->charset->sort_order; DBUG_ENTER("_ma_prefix_search"); LINT_INIT(length); @@ -1916,7 +1916,7 @@ _ma_calc_var_pack_key_length(const MARIA_KEY *int_key, uint nod_flag, uint key_length,ref_length,org_key_length=0, length_pack,new_key_length,diff_flag,pack_marker; const uchar *key, *start, *end, *key_end; - uchar *sort_order; + const uchar *sort_order; my_bool same_length; MARIA_KEYDEF *keyinfo= int_key->keyinfo; diff --git a/storage/maria/ma_servicethread.c b/storage/maria/ma_servicethread.c new file mode 100644 index 00000000000..a8099c998e9 --- /dev/null +++ b/storage/maria/ma_servicethread.c @@ -0,0 +1,134 @@ +#include "maria_def.h" +#include "ma_servicethread.h" + +/** + Initializes the service thread + + @param control control block + + @return Operation status + @retval 0 OK + @retval 1 error +*/ + +int ma_service_thread_control_init(MA_SERVICE_THREAD_CONTROL *control) +{ + int res= 0; + DBUG_ENTER("ma_service_thread_control_init"); + DBUG_PRINT("init", ("control 0x%lx", (ulong) control)); + control->inited= TRUE; + control->status= THREAD_DEAD; /* not yet born == dead */ + res= (pthread_mutex_init(control->LOCK_control, MY_MUTEX_INIT_SLOW) || + pthread_cond_init(control->COND_control, 0)); + DBUG_PRINT("info", ("init: %s", (res ? "Error" : "OK"))); + DBUG_RETURN(res); +} + + +/** + Kill the service thread + + @param control control block + + @note The service thread should react on condition and status equal + THREAD_DYING, by setting status THREAD_DEAD, and issuing message to + control thread via condition and exiting. The base way to do so is using + my_service_thread_sleep() and my_service_thread_signal_end() +*/ + +void ma_service_thread_control_end(MA_SERVICE_THREAD_CONTROL *control) +{ + DBUG_ENTER("ma_service_thread_control_end"); + DBUG_PRINT("init", ("control 0x%lx", (ulong) control)); + DBUG_ASSERT(control->inited); + pthread_mutex_lock(control->LOCK_control); + if (control->status != THREAD_DEAD) /* thread was started OK */ + { + DBUG_PRINT("info",("killing Maria background thread")); + control->status= THREAD_DYING; /* kill it */ + do /* and wait for it to be dead */ + { + /* wake it up if it was in a sleep */ + pthread_cond_broadcast(control->COND_control); + DBUG_PRINT("info",("waiting for Maria background thread to die")); + pthread_cond_wait(control->COND_control, control->LOCK_control); + } + while (control->status != THREAD_DEAD); + } + pthread_mutex_unlock(control->LOCK_control); + pthread_mutex_destroy(control->LOCK_control); + pthread_cond_destroy(control->COND_control); + control->inited= FALSE; + DBUG_VOID_RETURN; +} + + +/** + Sleep for given number of nanoseconds with reaction on thread kill + + @param control control block + @param sleep_time time of sleeping + + @return Operation status + @retval FALSE Time out + @retval TRUE Thread should be killed +*/ + +my_bool my_service_thread_sleep(MA_SERVICE_THREAD_CONTROL *control, + ulonglong sleep_time) +{ + struct timespec abstime; + my_bool res= FALSE; + DBUG_ENTER("my_service_thread_sleep"); + DBUG_PRINT("init", ("control 0x%lx", (ulong) control)); + pthread_mutex_lock(control->LOCK_control); + if (control->status == THREAD_DYING) + { + pthread_mutex_unlock(control->LOCK_control); + DBUG_RETURN(TRUE); + } +#if 0 /* good for testing, to do a lot of checkpoints, finds a lot of bugs */ + pthread_mutex_unlock(&control->LOCK_control); + my_sleep(100000); /* a tenth of a second */ + pthread_mutex_lock(&control->LOCK_control); +#else + /* To have a killable sleep, we use timedwait like our SQL GET_LOCK() */ + DBUG_PRINT("info", ("sleeping %llu nano seconds", sleep_time)); + if (sleep_time) + { + set_timespec_nsec(abstime, sleep_time); + pthread_cond_timedwait(control->COND_control, + control->LOCK_control, &abstime); + } +#endif + if (control->status == THREAD_DYING) + res= TRUE; + pthread_mutex_unlock(control->LOCK_control); + DBUG_RETURN(res); +} + + +/** + inform about thread exiting + + @param control control block +*/ + +void my_service_thread_signal_end(MA_SERVICE_THREAD_CONTROL *control) +{ + DBUG_ENTER("my_service_thread_signal_end"); + DBUG_PRINT("init", ("control 0x%lx", (ulong) control)); + pthread_mutex_lock(control->LOCK_control); + control->status = THREAD_DEAD; /* indicate that we are dead */ + /* + wake up ma_service_thread_control_end which may be waiting for + our death + */ + pthread_cond_broadcast(control->COND_control); + /* + broadcast was inside unlock because ma_service_thread_control_end + destroys mutex + */ + pthread_mutex_unlock(control->LOCK_control); + DBUG_VOID_RETURN; +} diff --git a/storage/maria/ma_servicethread.h b/storage/maria/ma_servicethread.h new file mode 100644 index 00000000000..153ff9ebd14 --- /dev/null +++ b/storage/maria/ma_servicethread.h @@ -0,0 +1,22 @@ +#include <my_pthread.h> + +enum ma_service_thread_state {THREAD_RUNNING, THREAD_DYING, THREAD_DEAD}; + +typedef struct st_ma_service_thread_control +{ + /** 'kill' flag for the background thread */ + enum ma_service_thread_state status; + /** if thread module was inited or not */ + my_bool inited; + /** for killing the background thread */ + pthread_mutex_t *LOCK_control; + /** for killing the background thread */ + pthread_cond_t *COND_control; +} MA_SERVICE_THREAD_CONTROL; + + +int ma_service_thread_control_init(MA_SERVICE_THREAD_CONTROL *control); +void ma_service_thread_control_end(MA_SERVICE_THREAD_CONTROL *control); +my_bool my_service_thread_sleep(MA_SERVICE_THREAD_CONTROL *control, + ulonglong sleep_time); +void my_service_thread_signal_end(MA_SERVICE_THREAD_CONTROL *control); diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c index a58d10ca907..5c5bd8f8d6c 100644 --- a/storage/maria/ma_sort.c +++ b/storage/maria/ma_sort.c @@ -154,7 +154,7 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages, keys < (uint) maxbuffer) { _ma_check_print_error(info->sort_info->param, - "maria_sort_buffer_size is too small"); + "aria_sort_buffer_size is too small"); goto err; } } @@ -178,7 +178,7 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages, } if (memavl < MIN_SORT_MEMORY) { - _ma_check_print_error(info->sort_info->param, "Maria sort buffer" + _ma_check_print_error(info->sort_info->param, "Aria sort buffer" " too small"); /* purecov: tested */ goto err; /* purecov: tested */ } @@ -383,7 +383,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg) keys < maxbuffer) { _ma_check_print_error(sort_param->sort_info->param, - "maria_sort_buffer_size is too small"); + "aria_sort_buffer_size is too small"); goto err; } } @@ -411,7 +411,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg) if (memavl < MIN_SORT_MEMORY) { _ma_check_print_error(sort_param->sort_info->param, - "Maria sort buffer too small"); + "Aria sort buffer too small"); goto err; /* purecov: tested */ } diff --git a/storage/maria/ma_test_force_start.pl b/storage/maria/ma_test_force_start.pl index 7ab8190a738..8148b2f212b 100755 --- a/storage/maria/ma_test_force_start.pl +++ b/storage/maria/ma_test_force_start.pl @@ -6,7 +6,7 @@ use warnings; my $usage= <<EOF; This program tests that the options ---maria-force-start-after-recovery-failures --maria-recover work as +--aria-force-start-after-recovery-failures --aria-recover work as expected. It has to be run from directory mysql-test, and works with non-debug and debug binaries. @@ -43,7 +43,7 @@ my $error_log_name= "./var/log/master.err"; my @cmd_output; my $whatever; # garbage data $ENV{MTR_VERSION} = 1; # MTR2 does not have --start-and-exit -my $base_server_cmd= "perl mysql-test-run.pl --mysqld=--maria-force-start-after-recovery-failures=$force_after --suite=maria maria.maria-recover ";
+my $base_server_cmd= "perl mysql-test-run.pl --mysqld=--aria-force-start-after-recovery-failures=$force_after --suite=maria maria.maria-recover ";
if ($^O =~ /^mswin/i) { print <<EOF; @@ -101,7 +101,7 @@ open(FILE, ">", $sql_name) or die; # sort_get_next_record() whose failure itself does not cause a retry. print FILE "create table t1 (a varchar(1000)". - ($corrupt_index ? ", index(a)" : "") .") engine=maria;\n"; + ($corrupt_index ? ", index(a)" : "") .") engine=aria;\n"; print FILE <<EOF; insert into t1 values("ThursdayMorningsMarket"); # If Recovery executes REDO_INDEX_NEW_PAGE it will overwrite our @@ -109,7 +109,7 @@ insert into t1 values("ThursdayMorningsMarket"); # create_rename_lsn using OPTIMIZE TABLE. This also makes sure to put # the pages on disk, so that we can corrupt them. optimize table t1; -# mark table open, so that --maria-recover repairs it +# mark table open, so that --aria-recover repairs it insert into t1 select concat(a,'b') from t1 limit 1; EOF close FILE; @@ -123,7 +123,7 @@ kill_server(9); print "ruining " . ($corrupt_index ? "first page of keys" : "bitmap page") . - " in table to test maria-recover\n"; + " in table to test aria-recover\n"; open(FILE, "+<", "./var/master-data/test/t1.$corrupt_file") or die; $whatever= ("\xAB" x 100); sysseek (FILE, $corrupt_index ? 8192 : (8192-100-100), 0) or die; @@ -131,7 +131,7 @@ syswrite (FILE, $whatever) or die; close FILE; print "ruining log to make recovery fail; mysqld should fail the $force_after first restarts\n"; -open(FILE, "+<", "./var/tmp/maria_log.00000001") or die; +open(FILE, "+<", "./var/tmp/aria_log.00000001") or die; $whatever= ("\xAB" x 8192); sysseek (FILE, 99, 0) or die; syswrite (FILE, $whatever) or die; @@ -148,8 +148,8 @@ for($i= 1; $i <= $force_after; $i= $i + 1) open(FILE, "<", $error_log_name) or die; @cmd_output= <FILE>; close FILE; - die unless grep(/\[ERROR\] mysqld(.exe)*: Maria engine: log initialization failed/, @cmd_output); - die unless grep(/\[ERROR\] Plugin 'MARIA' init function returned error./, @cmd_output); + die unless grep(/\[ERROR\] mysqld(.exe)*: Aria engine: log initialization failed/, @cmd_output); + die unless grep(/\[ERROR\] Plugin 'Aria' init function returned error./, @cmd_output); print "failed - ok\n"; } @@ -160,13 +160,13 @@ die if $?; open(FILE, "<", $error_log_name) or die; @cmd_output= <FILE>; close FILE; -die unless grep(/\[Warning\] mysqld(.exe)*: Maria engine: removed all logs after [\d]+ consecutive failures of recovery from logs/, @cmd_output); -die unless grep(/\[ERROR\] mysqld(.exe)*: File '.*tmp.maria_log.00000001' not found \(Errcode: 2\)/, @cmd_output); +die unless grep(/\[Warning\] mysqld(.exe)*: Aria engine: removed all logs after [\d]+ consecutive failures of recovery from logs/, @cmd_output); +die unless grep(/\[ERROR\] mysqld(.exe)*: File '.*tmp.aria_log.00000001' not found \(Errcode: 2\)/, @cmd_output); print "success - ok\n"; open(FILE, ">", $sql_name) or die; print FILE <<EOF; -set global maria_recover=normal; +set global aria_recover=normal; insert into t1 values('aaa'); EOF close FILE; diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index b4bf5086e0b..322bc4fcf20 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -1070,7 +1070,6 @@ int _ma_split_page(MARIA_HA *info, MARIA_KEY *key, MARIA_PAGE *split_page, Returns pointer to start of key. key will contain the key. - return_key_length will contain the length of key after_key will contain the position to where the next key starts */ diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index 5c0ba13b2ab..52a30dce235 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -36,7 +36,7 @@ SET_STACK_SIZE(9000) /* Minimum stack size for program */ static uint decode_bits; static char **default_argv; -static const char *load_default_groups[]= { "maria_chk", 0 }; +static const char *load_default_groups[]= { "aria_chk", 0 }; static const char *set_collation_name, *opt_tmpdir, *opt_log_dir; static const char *default_log_dir; static CHARSET_INFO *set_collation; @@ -82,8 +82,8 @@ static const char *bitmap_description[]= }; static const char *maria_stats_method_str="nulls_unequal"; -static char default_open_errmsg[]= "%d when opening MARIA-table '%s'"; -static char default_close_errmsg[]= "%d when closing MARIA-table '%s'"; +static char default_open_errmsg[]= "%d when opening Aria table '%s'"; +static char default_close_errmsg[]= "%d when closing Aria table '%s'"; static void get_options(int *argc,char * * *argv); static void print_version(void); @@ -184,7 +184,7 @@ end: char buff[22],buff2[22]; if (!(check_param.testflag & T_SILENT) || check_param.testflag & T_INFO) puts("\n---------"); - printf("\nTotal of all %d MARIA-files:\nData records: %9s Deleted blocks: %9s\n",check_param.total_files,llstr(check_param.total_records,buff), + printf("\nTotal of all %d Aria-files:\nData records: %9s Deleted blocks: %9s\n",check_param.total_files,llstr(check_param.total_records,buff), llstr(check_param.total_deleted,buff2)); } free_defaults(default_argv); @@ -274,7 +274,7 @@ static struct my_option my_long_options[] = (uchar**)&opt_ignore_control_file, 0, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"keys-used", 'k', - "Tell MARIA to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts.", + "Tell Aria to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts.", &check_param.keys_in_use, &check_param.keys_in_use, 0, GET_ULL, REQUIRED_ARG, -1, 0, 0, 0, 0, 0}, @@ -286,7 +286,7 @@ static struct my_option my_long_options[] = "Path for log files.", (char**) &opt_log_dir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"max-record-length", OPT_MAX_RECORD_LENGTH, - "Skip rows bigger than this if maria_chk can't allocate memory to hold it", + "Skip rows bigger than this if aria_chk can't allocate memory to hold it", &check_param.max_record_length, &check_param.max_record_length, 0, GET_ULL, REQUIRED_ARG, LONGLONG_MAX, 0, LONGLONG_MAX, 0, 0, 0}, @@ -329,7 +329,7 @@ static struct my_option my_long_options[] = (char**) &set_collation_name, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"silent", 's', - "Only print errors. One can use two -s to make maria_chk very silent.", + "Only print errors. One can use two -s to make aria_chk very silent.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DBUG_OFF #ifdef SAFEMALLOC @@ -361,7 +361,7 @@ static struct my_option my_long_options[] = &opt_update_state, &opt_update_state, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"unpack", 'u', - "Unpack file packed with maria_pack.", + "Unpack file packed with aria_pack.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Print more information. This can be used with --description and --check. Use many -v for more verbosity!", @@ -411,7 +411,7 @@ static struct my_option my_long_options[] = { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "", &ft_max_word_len, &ft_max_word_len, 0, GET_ULONG, REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, HA_FT_MAXCHARLEN, 0, 1, 0}, - { "maria_ft_stopword_file", OPT_FT_STOPWORD_FILE, + { "aria_ft_stopword_file", OPT_FT_STOPWORD_FILE, "Use stopwords from this file instead of built-in list.", (char**) &ft_stopword_file, (char**) &ft_stopword_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -447,7 +447,7 @@ static void usage(void) print_version(); puts("By Monty, for your professional use"); puts("This software comes with NO WARRANTY: see the PUBLIC for details.\n"); - puts("Description, check and repair of MARIA tables."); + puts("Description, check and repair of Aria tables."); puts("Used without options all tables on the command will be checked for errors"); printf("Usage: %s [OPTIONS] tables[.MAI]\n", my_progname_short); printf("\nGlobal options:\n"); @@ -484,10 +484,10 @@ static void usage(void) puts(" --start-check-pos=# Start reading file at given offset.\n"); #endif - puts("Check options (check is the default action for maria_chk):\n\ + puts("Check options (check is the default action for aria_chk):\n\ -c, --check Check table for errors.\n\ -e, --extend-check Check the table VERY throughly. Only use this in\n\ - extreme cases as maria_chk should normally be able to\n\ + extreme cases as aria_chk should normally be able to\n\ find out if the table is ok even without this switch.\n\ -F, --fast Check only tables that haven't been closed properly.\n\ -C, --check-only-changed\n\ @@ -520,11 +520,11 @@ Recover (repair)/ options (When using '--recover' or '--safe-recover'):\n\ Normally this will also find a lot of garbage rows;\n\ Don't use this option if you are not totally desperate.\n\ -f, --force Overwrite old temporary files.\n\ - -k, --keys-used=# Tell MARIA to update only some specific keys. # is a\n\ + -k, --keys-used=# Tell Aria to update only some specific keys. # is a\n\ bit mask of which keys to use. This can be used to\n\ get faster inserts.\n\ --max-record-length=#\n\ - Skip rows bigger than this if maria_chk can't allocate\n\ + Skip rows bigger than this if aria_chk can't allocate\n\ memory to hold it.\n\ -r, --recover Can fix almost anything except unique keys that aren't\n\ unique.\n\ @@ -538,18 +538,18 @@ Recover (repair)/ options (When using '--recover' or '--safe-recover'):\n\ handle a couple of cases where '-r' reports that it\n\ can't fix the data file.\n\ --transaction-log Log repair command to transaction log. This is needed\n\ - if one wants to use the maria_read_log to repeat the \n\ + if one wants to use the aria_read_log to repeat the \n\ repair\n\ --character-sets-dir=...\n\ Directory where character sets are.\n\ --set-collation=name\n\ Change the collation used by the index.\n\ -q, --quick Faster repair by not modifying the data file.\n\ - One can give a second '-q' to force maria_chk to\n\ + One can give a second '-q' to force aria_chk to\n\ modify the original datafile in case of duplicate keys.\n\ NOTE: Tables where the data file is currupted can't be\n\ fixed with this option.\n\ - -u, --unpack Unpack file packed with mariapack.\n\ + -u, --unpack Unpack file packed with ariapack.\n\ "); puts("Other actions:\n\ @@ -801,7 +801,7 @@ get_one_option(int optid, check_param.testflag|= T_UPDATE_STATE; break; case '#': - DBUG_SET_INITIAL(argument ? argument : "d:t:o,/tmp/maria_chk.trace"); + DBUG_SET_INITIAL(argument ? argument : "d:t:o,/tmp/aria_chk.trace"); opt_debug= 1; break; case OPT_SKIP_SAFEMALLOC: @@ -878,9 +878,9 @@ static void get_options(register int *argc,register char ***argv) load_defaults("my", load_default_groups, argc, argv); default_argv= *argv; + check_param.testflag= T_UPDATE_STATE; if (isatty(fileno(stdout))) check_param.testflag|=T_WRITE_LOOP; - check_param.testflag= T_UPDATE_STATE; if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); @@ -938,11 +938,18 @@ static void get_options(register int *argc,register char ***argv) } /* get options */ - /* Check table */ +/** + Check/repair table + + @return 0 table is ok + @return 1 Got warning during check + @return 2 Got error during check/repair. +*/ static int maria_chk(HA_CHECK *param, char *filename) { int error,lock_type,recreate; + uint warning_printed_by_chk_status; my_bool rep_quick= test(param->testflag & (T_QUICK | T_FORCE_UNIQUENESS)); MARIA_HA *info; File datafile; @@ -955,6 +962,7 @@ static int maria_chk(HA_CHECK *param, char *filename) recreate=0; datafile=0; param->isam_file_name=filename; /* For error messages */ + warning_printed_by_chk_status= 0; if (!(info=maria_open(filename, (param->testflag & (T_DESCRIPT | T_READONLY)) ? O_RDONLY : O_RDWR, @@ -971,7 +979,7 @@ static int maria_chk(HA_CHECK *param, char *filename) _ma_check_print_error(param,"'%s' doesn't have a correct index definition. You need to recreate it before you can do a repair",filename); break; case HA_ERR_NOT_A_TABLE: - _ma_check_print_error(param,"'%s' is not a MARIA-table",filename); + _ma_check_print_error(param,"'%s' is not a Aria table",filename); break; case HA_ERR_CRASHED_ON_USAGE: _ma_check_print_error(param,"'%s' is marked as crashed",filename); @@ -980,10 +988,10 @@ static int maria_chk(HA_CHECK *param, char *filename) _ma_check_print_error(param,"'%s' is marked as crashed after last repair",filename); break; case HA_ERR_OLD_FILE: - _ma_check_print_error(param,"'%s' is a old type of MARIA-table", filename); + _ma_check_print_error(param,"'%s' is a old type of Aria table", filename); break; case HA_ERR_NEW_FILE: - _ma_check_print_error(param,"'%s' uses new features not supported by this version of the MARIA library", filename); + _ma_check_print_error(param,"'%s' uses new features not supported by this version of the Aria library", filename); break; case HA_ERR_END_OF_FILE: _ma_check_print_error(param,"Couldn't read complete header from '%s'", filename); @@ -999,7 +1007,7 @@ static int maria_chk(HA_CHECK *param, char *filename) filename); break; default: - _ma_check_print_error(param,"%d when opening MARIA-table '%s'", + _ma_check_print_error(param,"%d when opening Aria table '%s'", my_errno,filename); break; } @@ -1066,10 +1074,10 @@ static int maria_chk(HA_CHECK *param, char *filename) if (!need_to_check) { if (!(param->testflag & T_SILENT) || param->testflag & T_INFO) - printf("MARIA file: %s is already checked\n",filename); + printf("Aria file: %s is already checked\n",filename); if (maria_close(info)) { - _ma_check_print_error(param,"%d when closing MARIA-table '%s'", + _ma_check_print_error(param,"%d when closing Aria table '%s'", my_errno,filename); DBUG_RETURN(1); } @@ -1096,7 +1104,7 @@ static int maria_chk(HA_CHECK *param, char *filename) if (maria_recreate_table(param, &info,filename)) { VOID(fprintf(stderr, - "MARIA-table '%s' is not fixed because of errors\n", + "Aria table '%s' is not fixed because of errors\n", filename)); return(-1); } @@ -1289,7 +1297,7 @@ static int maria_chk(HA_CHECK *param, char *filename) else if ((param->testflag & T_CHECK) || !(param->testflag & T_AUTO_INC)) { if (!(param->testflag & T_VERY_SILENT) || param->testflag & T_INFO) - printf("Checking MARIA file: %s\n",filename); + printf("Checking Aria file: %s\n",filename); if (!(param->testflag & T_SILENT)) printf("Data records: %7s Deleted blocks: %7s\n", llstr(info->state->records,llbuff), @@ -1297,7 +1305,12 @@ static int maria_chk(HA_CHECK *param, char *filename) maria_chk_init_for_check(param, info); if (opt_warning_for_wrong_transid == 0) param->max_trid= ~ (ulonglong) 0; + error= maria_chk_status(param,info); + /* Forget warning printed by maria_chk_status if no problems found */ + warning_printed_by_chk_status= param->warning_printed; + param->warning_printed= 0; + maria_intersect_keys_active(share->state.key_map, param->keys_in_use); error|= maria_chk_size(param,info); if (!error || !(param->testflag & (T_FAST | T_FORCE_CREATE))) @@ -1365,8 +1378,12 @@ static int maria_chk(HA_CHECK *param, char *filename) (state_updated ? UPDATE_STAT : 0) | ((param->testflag & T_SORT_RECORDS) ? UPDATE_SORT : 0))); - if (!(param->testflag & T_SILENT)) + if (warning_printed_by_chk_status) + _ma_check_print_info(param, "Aria table '%s' was ok. Status updated", + filename); + else if (!(param->testflag & T_SILENT)) printf("State updated\n"); + warning_printed_by_chk_status= 0; } info->update&= ~HA_STATE_CHANGED; _ma_reenable_logging_for_table(info, FALSE); @@ -1404,10 +1421,11 @@ end2: if (param->error_printed) { + error= 2; if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX)) { VOID(fprintf(stderr, - "MARIA-table '%s' is not fixed because of errors\n", + "Aria table '%s' is not fixed because of errors\n", filename)); if (param->testflag & T_REP_ANY) VOID(fprintf(stderr, @@ -1416,14 +1434,19 @@ end2: else if (!(param->error_printed & 2) && !(param->testflag & T_FORCE_CREATE)) VOID(fprintf(stderr, - "MARIA-table '%s' is corrupted\nFix it using switch \"-r\" or \"-o\"\n", + "Aria table '%s' is corrupted\nFix it using switch \"-r\" or \"-o\"\n", filename)); } - else if (param->warning_printed && + else if ((param->warning_printed || warning_printed_by_chk_status) && ! (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX | T_FORCE_CREATE))) - VOID(fprintf(stderr, "MARIA-table '%s' is usable but should be fixed\n", + { + if (!error) + error= 1; + VOID(fprintf(stderr, "Aria table '%s' is usable but should be fixed\n", filename)); + } + VOID(fflush(stderr)); DBUG_RETURN(error); } /* maria_chk */ @@ -1453,7 +1476,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) DBUG_VOID_RETURN; } - printf("MARIA file: %s\n",name); + printf("Aria file: %s\n",name); printf("Record format: %s\n", record_formats[share->data_file_type]); printf("Crashsafe: %s\n", share->base.born_transactional ? "yes" : "no"); @@ -1561,7 +1584,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) printf("Recordlength: %16d\n",(int) share->base.pack_reclength); if (! maria_is_all_keys_active(share->state.key_map, share->base.keys)) { - longlong2str(share->state.key_map,buff,2); + longlong2str(share->state.key_map,buff,2,1); printf("Using only keys '%s' of %d possibly keys\n", buff, share->base.keys); } @@ -1754,14 +1777,14 @@ static int maria_sort_records(HA_CHECK *param, { _ma_check_print_warning(param, "Can't sort table '%s' on key %d; No such key", - name,sort_key+1); + name,sort_key+1); param->error_printed=0; DBUG_RETURN(0); /* Nothing to do */ } if (keyinfo->flag & HA_FULLTEXT) { _ma_check_print_warning(param,"Can't sort table '%s' on FULLTEXT key %d", - name,sort_key+1); + name,sort_key+1); param->error_printed=0; DBUG_RETURN(0); /* Nothing to do */ } @@ -1784,7 +1807,7 @@ static int maria_sort_records(HA_CHECK *param, } if (!(param->testflag & T_SILENT)) { - printf("- Sorting records for MARIA-table '%s'\n",name); + printf("- Sorting records for Aria table '%s'\n",name); if (write_info) printf("Data records: %9s Deleted: %9s\n", llstr(info->state->records,llbuff), @@ -2027,7 +2050,7 @@ static my_bool write_log_record(HA_CHECK *param) { if (write_log_record_for_repair(param, info)) _ma_check_print_error(param, "%d when writing log record for" - " MARIA-table '%s'", my_errno, + " Aria table '%s'", my_errno, param->isam_file_name); else if (maria_close(info)) _ma_check_print_error(param, default_close_errmsg, my_errno, diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 41501b8eb74..4692896212d 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -126,6 +126,8 @@ typedef struct st_maria_state_info increased. */ LSN skip_redo_lsn; + /* LSN when we wrote file id to the log */ + LSN logrec_file_id; /* the following isn't saved on disk */ uint state_diff_length; /* Should be 0 */ @@ -276,6 +278,7 @@ typedef struct st_maria_file_bitmap typedef struct st_maria_share { /* Shared between opens */ MARIA_STATE_INFO state; + MARIA_STATE_INFO checkpoint_state; /* Copy of saved state by checkpoint */ MARIA_BASE_INFO base; MARIA_STATE_HISTORY *state_history; MARIA_KEYDEF ft2_keyinfo; /* Second-level ft-key definition */ @@ -737,7 +740,7 @@ struct st_maria_handler { length=mi_uint2korr((key)+1)+3; } \ } -#define maria_max_key_length() ((maria_block_size - MAX_KEYPAGE_HEADER_SIZE)/2 - MARIA_INDEX_OVERHEAD_SIZE) +#define maria_max_key_length() ((maria_block_size - MAX_KEYPAGE_HEADER_SIZE)/3 - MARIA_INDEX_OVERHEAD_SIZE) #define get_pack_length(length) ((length) >= 255 ? 3 : 1) #define _ma_have_versioning(info) ((info)->row_flag & ROW_FLAG_TRANSID) @@ -818,6 +821,7 @@ extern uchar maria_zero_string[]; extern my_bool maria_inited, maria_in_ha_maria, maria_recovery_changed_data; extern my_bool maria_recovery_verbose; extern my_bool maria_assert_if_crashed_table; +extern ulong maria_checkpoint_min_log_activity; extern HASH maria_stored_state; extern int (*maria_create_trn_hook)(MARIA_HA *); diff --git a/storage/maria/maria_dump_log.c b/storage/maria/maria_dump_log.c index bc7ec566462..f01eee1ad96 100644 --- a/storage/maria/maria_dump_log.c +++ b/storage/maria/maria_dump_log.c @@ -16,13 +16,13 @@ #include "maria_def.h" #include <my_getopt.h> extern void translog_example_table_init(); -static const char *load_default_groups[]= { "maria_dump_log",0 }; +static const char *load_default_groups[]= { "aria_dump_log",0 }; static void get_options(int *argc,char * * *argv); #ifndef DBUG_OFF #if defined(__WIN__) -const char *default_dbug_option= "d:t:i:O,\\maria_dump_log.trace"; +const char *default_dbug_option= "d:t:i:O,\\aria_dump_log.trace"; #else -const char *default_dbug_option= "d:t:i:o,/tmp/maria_dump_log.trace"; +const char *default_dbug_option= "d:t:i:o,/tmp/aria_dump_log.trace"; #endif #endif static ulonglong opt_offset; @@ -79,7 +79,7 @@ static void usage(void) puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); puts("and you are welcome to modify and redistribute it under the GPL license\n"); - puts("Dump content of maria log pages."); + puts("Dump content of aria log pages."); VOID(printf("\nUsage: %s -f file OPTIONS\n", my_progname_short)); my_print_help(my_long_options); print_defaults("my", load_default_groups); diff --git a/storage/maria/maria_ftdump.c b/storage/maria/maria_ftdump.c index 895bbf85b0f..870d07fa96e 100644 --- a/storage/maria/maria_ftdump.c +++ b/storage/maria/maria_ftdump.c @@ -263,7 +263,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), static void usage() { - printf("Use: maria_ft_dump <table_name> <index_num>\n"); + printf("Use: aria_ft_dump <table_name> <index_num>\n"); my_print_help(my_long_options); my_print_variables(my_long_options); NETWARE_SET_SCREEN_MODE(1); diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c index ba586c3a882..c87ecfa7776 100644 --- a/storage/maria/maria_pack.c +++ b/storage/maria/maria_pack.c @@ -197,7 +197,7 @@ static struct st_file_buffer file_buffer; static QUEUE queue; static HUFF_COUNTS *global_count; static char zero_string[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -static const char *load_default_groups[]= { "mariapack",0 }; +static const char *load_default_groups[]= { "ariapack",0 }; /* The main program */ @@ -238,7 +238,7 @@ int main(int argc, char **argv) } } if (ok && isamchk_neaded && !silent) - puts("Remember to run maria_chk -rq on compressed tables"); + puts("Remember to run aria_chk -rq on compressed tables"); VOID(fflush(stdout)); VOID(fflush(stderr)); free_defaults(default_argv); @@ -306,11 +306,11 @@ static void usage(void) puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); puts("and you are welcome to modify and redistribute it under the GPL license\n"); - puts("Pack a MARIA-table to take much less space."); - puts("Keys are not updated, you must run maria_chk -rq on the index (.MAI) file"); + puts("Pack a Aria-table to take much less space."); + puts("Keys are not updated, you must run aria_chk -rq on the index (.MAI) file"); puts("afterwards to update the keys."); puts("You should give the .MAI file as the filename argument."); - puts("To unpack a packed table, run maria_chk -u on the table"); + puts("To unpack a packed table, run aria_chk -u on the table"); VOID(printf("\nUsage: %s [OPTIONS] filename...\n", my_progname)); my_print_help(my_long_options); @@ -359,7 +359,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), silent= 0; break; case '#': - DBUG_PUSH(argument ? argument : "d:t:o,/tmp/maria_pack.trace"); + DBUG_PUSH(argument ? argument : "d:t:o,/tmp/aria_pack.trace"); break; case 'V': print_version(); @@ -2992,7 +2992,7 @@ static int save_state(MARIA_HA *isam_file,PACK_MRG_INFO *mrg, } /* If there are no disabled indexes, keep key_file_length value from - original file so "maria_chk -rq" can use this value (this is necessary + original file so "aria_chk -rq" can use this value (this is necessary because index size cannot be easily calculated for fulltext keys) */ maria_clear_all_keys_active(share->state.key_map); diff --git a/storage/maria/maria_read_log.c b/storage/maria/maria_read_log.c index d323c9500ee..b3f3eb345be 100644 --- a/storage/maria/maria_read_log.c +++ b/storage/maria/maria_read_log.c @@ -20,19 +20,19 @@ #define LOG_FLAGS 0 -static const char *load_default_groups[]= { "maria_read_log",0 }; +static const char *load_default_groups[]= { "aria_read_log",0 }; static void get_options(int *argc,char * * *argv); #ifndef DBUG_OFF #if defined(__WIN__) -const char *default_dbug_option= "d:t:O,\\maria_read_log.trace"; +const char *default_dbug_option= "d:t:O,\\aria_read_log.trace"; #else -const char *default_dbug_option= "d:t:o,/tmp/maria_read_log.trace"; +const char *default_dbug_option= "d:t:o,/tmp/aria_read_log.trace"; #endif #endif /* DBUG_OFF */ static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent; static my_bool opt_check; static const char *opt_tmpdir; -static ulong opt_page_buffer_size; +static ulong opt_page_buffer_size, opt_translog_buffer_size; static ulonglong opt_start_from_lsn, opt_end_lsn, opt_start_from_checkpoint; static MY_TMPDIR maria_chk_tmpdir; @@ -53,7 +53,7 @@ int main(int argc, char **argv) if (maria_init()) { - fprintf(stderr, "Can't init Maria engine (%d)\n", errno); + fprintf(stderr, "Can't init Aria engine (%d)\n", errno); goto err; } maria_block_size= 0; /* Use block size from file */ @@ -80,9 +80,8 @@ int main(int argc, char **argv) But if it finds a log and this log was crashed, it will create a new log, which is useless. TODO: start log handler in read-only mode. */ - if (init_pagecache(maria_log_pagecache, - TRANSLOG_PAGECACHE_SIZE, 0, 0, - TRANSLOG_PAGE_SIZE, MY_WME) == 0 || + if (init_pagecache(maria_log_pagecache, opt_translog_buffer_size, + 0, 0, TRANSLOG_PAGE_SIZE, MY_WME) == 0 || translog_init(maria_data_root, TRANSLOG_FILE_SIZE, 0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS, opt_display_only)) @@ -134,7 +133,7 @@ int main(int argc, char **argv) opt_apply_undo= 0; } - fprintf(stdout, "TRACE of the last maria_read_log\n"); + fprintf(stdout, "TRACE of the last aria_read_log\n"); if (maria_apply_log(lsn, opt_end_lsn, opt_apply ? MARIA_LOG_APPLY : (opt_check ? MARIA_LOG_CHECK : MARIA_LOG_DISPLAY_HEADER), opt_silent ? NULL : stdout, @@ -166,7 +165,7 @@ err: #include "ma_check_standalone.h" enum options_mc { - OPT_CHARSETS_DIR=256 + OPT_CHARSETS_DIR=256, OPT_FORCE_CRASH, OPT_TRANSLOG_BUFFER_SIZE }; static struct my_option my_long_options[] = @@ -186,6 +185,9 @@ static struct my_option my_long_options[] = #ifndef DBUG_OFF {"debug", '#', "Output debug log. Often the argument is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"force-crash", OPT_FORCE_CRASH, "Force crash after # recovery events", + &maria_recovery_force_crash_counter, 0,0, GET_ULONG, REQUIRED_ARG, + 0, 0, ~(long) 0, 0, 0, 0}, #endif {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -195,12 +197,12 @@ static struct my_option my_long_options[] = { "end-lsn", 'e', "Stop applying at this lsn. If end-lsn is used, UNDO:s " "will not be applied", &opt_end_lsn, &opt_end_lsn, 0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 }, - {"maria-log-dir-path", 'h', + {"aria-log-dir-path", 'h', "Path to the directory where to store transactional log", (uchar **) &maria_data_root, (uchar **) &maria_data_root, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { "page-buffer-size", 'P', - "The size of the buffer used for index blocks for Maria tables", + "The size of the buffer used for index blocks for Aria tables", &opt_page_buffer_size, &opt_page_buffer_size, 0, GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, 1024L*1024L, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD, @@ -225,6 +227,12 @@ static struct my_option my_long_options[] = "colon (:)" #endif , (char**) &opt_tmpdir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "translog-buffer-size", OPT_TRANSLOG_BUFFER_SIZE, + "The size of the buffer used for transaction log for Aria tables", + &opt_translog_buffer_size, &opt_translog_buffer_size, 0, + GET_ULONG, REQUIRED_ARG, (long) TRANSLOG_PAGECACHE_SIZE, + 1024L*1024L, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD, + (long) IO_SIZE, 0}, {"undo", 'u', "Apply UNDO records to tables. (disable with --disable-undo)", (uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -253,10 +261,10 @@ static void usage(void) puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); puts("and you are welcome to modify and redistribute it under the GPL license\n"); - puts("Display and apply log records from a MARIA transaction log"); + puts("Display and apply log records from a Aria transaction log"); puts("found in the current directory (for now)"); #ifndef IDENTICAL_PAGES_AFTER_RECOVERY - puts("\nNote: Maria is compiled without -DIDENTICAL_PAGES_AFTER_RECOVERY\n" + puts("\nNote: Aria is compiled without -DIDENTICAL_PAGES_AFTER_RECOVERY\n" "which means that the table files are not byte-to-byte identical to\n" "files created during normal execution. This should be ok, except for\n" "test scripts that tries to compare files before and after recovery."); diff --git a/storage/maria/plug.in b/storage/maria/plug.in index f7c54da2190..609adcb2f66 100644 --- a/storage/maria/plug.in +++ b/storage/maria/plug.in @@ -1,19 +1,17 @@ -MYSQL_STORAGE_ENGINE(maria,, [Maria Storage Engine], +MYSQL_STORAGE_ENGINE(aria,, [Aria Storage Engine], [Crash-safe tables with MyISAM heritage], [default,max,max-no-ndb]) -MYSQL_PLUGIN_STATIC(maria, [libmaria_s.la], [libmaria_embedded.la]) -# Maria will probably go first into max builds, not all builds, -# so we don't declare it mandatory. +MYSQL_PLUGIN_STATIC(aria, [libaria_s.la], [libaria_embedded.la]) -MYSQL_PLUGIN_ACTIONS(maria, [ +MYSQL_PLUGIN_ACTIONS(aria, [ # AC_CONFIG_FILES(storage/maria/unittest/Makefile) -AC_ARG_WITH(maria-tmp-tables, - AC_HELP_STRING([--with-maria-tmp-tables],[Use Maria for internal temporary tables]), - [with_maria_tmp_tables=$withval], - [with_maria_tmp_tables=yes] +AC_ARG_WITH(aria-tmp-tables, + AC_HELP_STRING([--with-aria-tmp-tables],[Use Aria for internal temporary tables]), + [with_aria_tmp_tables=$withval], + [with_aria_tmp_tables=yes] ) -if test "$with_maria_tmp_tables" = "yes" +if test "$with_aria_tmp_tables" = "yes" then - AC_DEFINE([USE_MARIA_FOR_TMP_TABLES], [1], [Maria is used for internal temporary tables]) + AC_DEFINE([USE_MARIA_FOR_TMP_TABLES], [1], [Aria is used for internal temporary tables]) fi ]) diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c index 05330baed76..36880a59b51 100644 --- a/storage/maria/trnman.c +++ b/storage/maria/trnman.c @@ -179,6 +179,7 @@ int trnman_init(TrID initial_trid) trnman_allocated_transactions= 0; /* This is needed for recovery and repair */ dummy_transaction_object.min_read_from= ~(TrID) 0; + dummy_transaction_object.first_undo_lsn= TRANSACTION_LOGGED_LONG_ID; pool= 0; global_trid_generator= initial_trid; diff --git a/storage/maria/unittest/Makefile.am b/storage/maria/unittest/Makefile.am index 78db7f7b7f4..557e14b0515 100644 --- a/storage/maria/unittest/Makefile.am +++ b/storage/maria/unittest/Makefile.am @@ -20,9 +20,9 @@ INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \ EXTRA_DIST= ma_test_all-t CMakeLists.txt \ ma_test_recovery.pl ma_test_recovery.expected # Only reason to link with libmyisam.a here is that it's where some fulltext -# pieces are (but soon we'll remove fulltext dependencies from Maria). +# pieces are (but soon we'll remove fulltext dependencies from Aria). LDADD= $(top_builddir)/unittest/mytap/libmytap.a \ - $(top_builddir)/storage/maria/libmaria.a \ + $(top_builddir)/storage/maria/libaria.a \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ @@ -108,5 +108,5 @@ ma_pagecache_rwconsist2_1k_t_CPPFLAGS = -DTEST_PAGE_SIZE=1024 # the generic lock manager may not be used in the end and lockman1-t crashes, # and lockman2-t takes at least quarter an hour, # so we don't build lockman-t and lockman1-t and lockman2-t -CLEANFILES = maria_log_control page_cache_test_file_1 \ - maria_log.???????? +CLEANFILES = aria_log_control page_cache_test_file_1 \ + aria_log.???????? diff --git a/storage/maria/unittest/ma_control_file-t.c b/storage/maria/unittest/ma_control_file-t.c index 6702e4deb2f..ca559fe57df 100644 --- a/storage/maria/unittest/ma_control_file-t.c +++ b/storage/maria/unittest/ma_control_file-t.c @@ -13,7 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Unit test of the control file module of the Maria engine WL#3234 */ +/* Unit test of the control file module of the Aria engine WL#3234 */ /* Note that it is not possible to test the durability of the write (can't @@ -24,11 +24,11 @@ #include <my_sys.h> #include <tap.h> -#ifndef WITH_MARIA_STORAGE_ENGINE +#ifndef WITH_ARIA_STORAGE_ENGINE /* - If Maria is not compiled in, normally we don't come to building this test. + If Aria is not compiled in, normally we don't come to building this test. */ -#error "Maria engine is not compiled in, test cannot be built" +#error "Aria engine is not compiled in, test cannot be built" #endif #include "maria.h" @@ -117,6 +117,26 @@ static CONTROL_FILE_ERROR local_ma_control_file_open(void) return error; } +static char *create_tmpdir(const char *progname) +{ + static char test_dirname[FN_REFLEN]; + char tmp_name[FN_REFLEN]; + uint length; + + /* Create a temporary directory of name TMP-'executable', but without the -t extension */ + fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT); + length= strlen(tmp_name); + if (length > 2 && tmp_name[length-2] == '-' && tmp_name[length-1] == 't') + tmp_name[length-2]= 0; + strxmov(test_dirname, "TMP-", tmp_name, NullS); + + /* + Don't give an error if we can't create dir, as it may already exist from a previously aborted + run + */ + (void) my_mkdir(test_dirname, 0777, MYF(0)); + return test_dirname; +} int main(int argc,char *argv[]) @@ -124,11 +144,12 @@ int main(int argc,char *argv[]) MY_INIT(argv[0]); my_init(); - maria_data_root= (char *)"."; default_error_handler_hook= error_handler_hook; plan(12); + maria_data_root= create_tmpdir(argv[0]); + diag("Unit tests for control file"); get_options(argc,argv); @@ -155,6 +176,9 @@ int main(int argc,char *argv[]) ok(0 == test_bad_blocksize(), "test of bad blocksize"); ok(0 == test_bad_size(), "test of too small/big file"); + delete_file(0); + rmdir(maria_data_root); + return exit_status(); } @@ -547,7 +571,7 @@ static struct my_option my_long_options[] = static void version(void) { printf("ma_control_file_test: unit test for the control file " - "module of the Maria storage engine. Ver 1.0 \n"); + "module of the Aria storage engine. Ver 1.0 \n"); } static my_bool diff --git a/storage/maria/unittest/ma_maria_log_cleanup.c b/storage/maria/unittest/ma_maria_log_cleanup.c index 7c78bf3a1a4..5e84acf41af 100644 --- a/storage/maria/unittest/ma_maria_log_cleanup.c +++ b/storage/maria/unittest/ma_maria_log_cleanup.c @@ -16,7 +16,7 @@ #include "../maria_def.h" #include <my_dir.h> -my_bool maria_log_remove() +my_bool maria_log_remove(const char *testdir) { MY_DIR *dirp; uint i; @@ -38,7 +38,8 @@ my_bool maria_log_remove() for (i= 0; i < dirp->number_off_files; i++) { char *file= dirp->dir_entry[i].name; - if (strncmp(file, "maria_log.", 10) == 0 && + if (strncmp(file, "aria_log.", 9) == 0 && + file[9] >= '0' && file[9] <= '9' && file[10] >= '0' && file[10] <= '9' && file[11] >= '0' && file[11] <= '9' && file[12] >= '0' && file[12] <= '9' && @@ -46,8 +47,7 @@ my_bool maria_log_remove() file[14] >= '0' && file[14] <= '9' && file[15] >= '0' && file[15] <= '9' && file[16] >= '0' && file[16] <= '9' && - file[17] >= '0' && file[17] <= '9' && - file[18] == '\0') + file[17] == '\0') { if (fn_format(file_name, file, maria_data_root, "", MYF(MY_WME)) == NullS || @@ -59,6 +59,28 @@ my_bool maria_log_remove() } } my_dirend(dirp); + if (testdir) + rmdir(testdir); return 0; } +char *create_tmpdir(const char *progname) +{ + static char test_dirname[FN_REFLEN]; + char tmp_name[FN_REFLEN]; + uint length; + + /* Create a temporary directory of name TMP-'executable', but without the -t extension */ + fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT); + length= strlen(tmp_name); + if (length > 2 && tmp_name[length-2] == '-' && tmp_name[length-1] == 't') + tmp_name[length-2]= 0; + strxmov(test_dirname, "TMP-", tmp_name, NullS); + + /* + Don't give an error if we can't create dir, as it may already exist from a previously aborted + run + */ + (void) my_mkdir(test_dirname, 0777, MYF(0)); + return test_dirname; +} diff --git a/storage/maria/unittest/ma_pagecache_consist.c b/storage/maria/unittest/ma_pagecache_consist.c index 0a9e5737c7e..c060f7691a6 100644 --- a/storage/maria/unittest/ma_pagecache_consist.c +++ b/storage/maria/unittest/ma_pagecache_consist.c @@ -30,7 +30,8 @@ static const char* default_dbug_option; #endif -static char *file1_name= (char*)"page_cache_test_file_1"; +static const char *base_file1_name= "page_cache_test_file_1"; +static char file1_name[FN_REFLEN]; static PAGECACHE_FILE file1; static pthread_cond_t COND_thread_count; static pthread_mutex_t LOCK_thread_count; @@ -330,6 +331,27 @@ static void *test_thread_writer(void *arg) return 0; } +static char *create_tmpdir(const char *progname) +{ + static char test_dirname[FN_REFLEN]; + char tmp_name[FN_REFLEN]; + uint length; + + /* Create a temporary directory of name TMP-'executable', but without the -t extension */ + fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT); + length= strlen(tmp_name); + if (length > 2 && tmp_name[length-2] == '-' && tmp_name[length-1] == 't') + tmp_name[length-2]= 0; + strxmov(test_dirname, "TMP-", tmp_name, NullS); + + /* + Don't give an error if we can't create dir, as it may already exist from a previously aborted + run + */ + (void) my_mkdir(test_dirname, 0777, MYF(0)); + return test_dirname; +} + int main(int argc __attribute__((unused)), char **argv __attribute__((unused))) @@ -337,7 +359,6 @@ int main(int argc __attribute__((unused)), pthread_t tid; pthread_attr_t thr_attr; int *param, error, pagen; - MY_INIT(argv[0]); #ifndef DBUG_OFF @@ -357,9 +378,13 @@ int main(int argc __attribute__((unused)), DBUG_ENTER("main"); DBUG_PRINT("info", ("Main thread: %s\n", my_thread_name())); plan(number_of_writers + number_of_readers); + SKIP_BIG_TESTS(number_of_writers + number_of_readers) { + char *test_dirname= create_tmpdir(argv[0]); + fn_format(file1_name, base_file1_name, test_dirname, "", MYF(0)); + if ((file1.file= my_open(file1_name, O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1) { @@ -491,6 +516,7 @@ int main(int argc __attribute__((unused)), DBUG_PRINT("info", ("file1 (%d) closed", file1.file)); DBUG_PRINT("info", ("Program end")); + rmdir(test_dirname); } /* SKIP_BIG_TESTS */ my_end(0); diff --git a/storage/maria/unittest/ma_pagecache_rwconsist.c b/storage/maria/unittest/ma_pagecache_rwconsist.c index ff386c48414..511a503f349 100644 --- a/storage/maria/unittest/ma_pagecache_rwconsist.c +++ b/storage/maria/unittest/ma_pagecache_rwconsist.c @@ -33,7 +33,8 @@ static const char* default_dbug_option; #define SLEEP my_sleep(5) -static char *file1_name= (char*)"page_cache_test_file_1"; +static const char *base_file1_name= "page_cache_test_file_1"; +static char file1_name[FN_REFLEN]; static PAGECACHE_FILE file1; static pthread_cond_t COND_thread_count; static pthread_mutex_t LOCK_thread_count; @@ -200,6 +201,27 @@ static void *test_thread_writer(void *arg) return 0; } +char *create_tmpdir(const char *progname) +{ + static char test_dirname[FN_REFLEN]; + char tmp_name[FN_REFLEN]; + uint length; + + /* Create a temporary directory of name TMP-'executable', but without the -t extension */ + fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT); + length= strlen(tmp_name); + if (length > 2 && tmp_name[length-2] == '-' && tmp_name[length-1] == 't') + tmp_name[length-2]= 0; + strxmov(test_dirname, "TMP-", tmp_name, NullS); + + /* + Don't give an error if we can't create dir, as it may already exist from a previously aborted + run + */ + (void) my_mkdir(test_dirname, 0777, MYF(0)); + return test_dirname; +} + int main(int argc __attribute__((unused)), char **argv __attribute__((unused))) @@ -230,6 +252,9 @@ int main(int argc __attribute__((unused)), SKIP_BIG_TESTS(number_of_writers + number_of_readers) { + char *test_dirname= create_tmpdir(argv[0]); + fn_format(file1_name, base_file1_name, test_dirname, "", MYF(0)); + if ((file1.file= my_open(file1_name, O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1) { @@ -355,6 +380,8 @@ int main(int argc __attribute__((unused)), DBUG_PRINT("info", ("file1 (%d) closed", file1.file)); DBUG_PRINT("info", ("Program end")); + + rmdir(test_dirname); } /* SKIP_BIG_TESTS */ my_end(0); diff --git a/storage/maria/unittest/ma_pagecache_rwconsist2.c b/storage/maria/unittest/ma_pagecache_rwconsist2.c index 34183a2d0ab..97d821832fe 100644 --- a/storage/maria/unittest/ma_pagecache_rwconsist2.c +++ b/storage/maria/unittest/ma_pagecache_rwconsist2.c @@ -40,7 +40,8 @@ static const char* default_dbug_option; #define SLEEP my_sleep(5) -static char *file1_name= (char*)"page_cache_test_file_1"; +static const char *base_file1_name= "page_cache_test_file_1"; +static char file1_name[FN_REFLEN]; static PAGECACHE_FILE file1; static pthread_cond_t COND_thread_count; static pthread_mutex_t LOCK_thread_count; @@ -196,6 +197,27 @@ static void *test_thread_writer(void *arg) return 0; } +static char *create_tmpdir(const char *progname) +{ + static char test_dirname[FN_REFLEN]; + char tmp_name[FN_REFLEN]; + uint length; + + /* Create a temporary directory of name TMP-'executable', but without the -t extension */ + fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT); + length= strlen(tmp_name); + if (length > 2 && tmp_name[length-2] == '-' && tmp_name[length-1] == 't') + tmp_name[length-2]= 0; + strxmov(test_dirname, "TMP-", tmp_name, NullS); + + /* + Don't give an error if we can't create dir, as it may already exist from a previously aborted + run + */ + (void) my_mkdir(test_dirname, 0777, MYF(0)); + return test_dirname; +} + int main(int argc __attribute__((unused)), char **argv __attribute__((unused))) @@ -226,6 +248,9 @@ int main(int argc __attribute__((unused)), SKIP_BIG_TESTS(number_of_writers + number_of_readers) { + char *test_dirname= create_tmpdir(argv[0]); + fn_format(file1_name, base_file1_name, test_dirname, "", MYF(0)); + if ((file1.file= my_open(file1_name, O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1) { @@ -350,6 +375,8 @@ int main(int argc __attribute__((unused)), DBUG_PRINT("info", ("file1 (%d) closed", file1.file)); DBUG_PRINT("info", ("Program end")); + + rmdir(test_dirname); } /* SKIP_BIG_TESTS */ my_end(0); diff --git a/storage/maria/unittest/ma_pagecache_single.c b/storage/maria/unittest/ma_pagecache_single.c index 32e588e165a..750339f3074 100644 --- a/storage/maria/unittest/ma_pagecache_single.c +++ b/storage/maria/unittest/ma_pagecache_single.c @@ -35,8 +35,9 @@ static const char* default_dbug_option; #define SKIP_BIG_TESTS(X) /* no-op */ #endif -static char *file1_name= (char*)"page_cache_test_file_1"; -static char *file2_name= (char*)"page_cache_test_file_2"; +static const char *base_file1_name= "page_cache_test_file_1"; +static const char *base_file2_name= "page_cache_test_file_2"; +static char file1_name[FN_REFLEN], file2_name[FN_REFLEN]; static PAGECACHE_FILE file1; static pthread_cond_t COND_thread_count; static pthread_mutex_t LOCK_thread_count; @@ -720,6 +721,28 @@ static void *test_thread(void *arg) } +static char *create_tmpdir(const char *progname) +{ + static char test_dirname[FN_REFLEN]; + char tmp_name[FN_REFLEN]; + uint length; + + /* Create a temporary directory of name TMP-'executable', but without the -t extension */ + fn_format(tmp_name, progname, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT); + length= strlen(tmp_name); + if (length > 2 && tmp_name[length-2] == '-' && tmp_name[length-1] == 't') + tmp_name[length-2]= 0; + strxmov(test_dirname, "TMP-", tmp_name, NullS); + + /* + Don't give an error if we can't create dir, as it may already exist from a previously aborted + run + */ + (void) my_mkdir(test_dirname, 0777, MYF(0)); + return test_dirname; +} + + int main(int argc __attribute__((unused)), char **argv __attribute__((unused))) { @@ -748,6 +771,9 @@ int main(int argc __attribute__((unused)), plan(18); SKIP_BIG_TESTS(18) { + char *test_dirname= create_tmpdir(argv[0]); + fn_format(file1_name, base_file1_name, test_dirname, "", MYF(0)); + fn_format(file2_name, base_file2_name, test_dirname, "", MYF(0)); if ((tmp_file= my_open(file2_name, O_CREAT | O_TRUNC | O_RDWR, MYF(MY_WME))) < 0) @@ -841,13 +867,13 @@ int main(int argc __attribute__((unused)), exit(1); my_delete(file1_name, MYF(0)); + rmdir(test_dirname); } /* SKIP_BIG_TESTS */ DBUG_PRINT("info", ("file1 (%d) closed", file1.file)); DBUG_PRINT("info", ("Program end")); my_end(0); - } return exit_status(); } diff --git a/storage/maria/unittest/ma_test_all-t b/storage/maria/unittest/ma_test_all-t index 036e96caebb..4d72c6dfadf 100755 --- a/storage/maria/unittest/ma_test_all-t +++ b/storage/maria/unittest/ma_test_all-t @@ -20,7 +20,7 @@ $opt_number_of_tests= 0; $opt_run_tests= undef(); my $maria_path; # path to "storage/maria" -my $maria_exe_path; # path to executables (ma_test1, maria_chk etc) +my $maria_exe_path; # path to executables (ma_test1, aria_chk etc) my $my_progname= $0; $my_progname=~ s/.*[\/]//; my $runtime_error= 0; # Return 1 if error(s) occur during run @@ -28,9 +28,10 @@ my $NEW_TEST= 0; # Test group separator in an array of tests my $test_begin= 0; my $test_end= 0; my $test_counter= 0; +my $using_internal_tmpdir= 0; my $full_tmpdir; my $tmpdir="tmp"; - +my $exec_dir="TMP-ma_test_all"; # Run test in this directory run_tests(); #### @@ -60,7 +61,14 @@ sub run_tests print "$my_progname version $VER\n"; exit(0); } - $maria_path= dirname($0) . "/.."; + + if (! -d $exec_dir) + { + die if (!mkdir("$exec_dir")); + } + chdir($exec_dir); + + $maria_path= "../" . dirname($0) . "/.."; my $suffix= ( $^O =~ /win/i && $^O !~ /darwin/i ) ? ".exe" : ""; $maria_exe_path= "$maria_path/release"; @@ -76,7 +84,7 @@ sub run_tests $maria_exe_path= $maria_path; if ( ! -f "$maria_exe_path/ma_test1$suffix" ) { - die("Cannot find ma_test1 executable\n"); + die("Cannot find ma_test1 executable in $maria_path\n"); } } } @@ -90,7 +98,8 @@ sub run_tests } else { - $full_tmpdir= "tmp"; + $full_tmpdir= $tmpdir; + $using_internal_tmpdir= 1; if (! -d "$full_tmpdir") { die if (!mkdir("$full_tmpdir")); @@ -227,6 +236,13 @@ sub run_tests run_tests_on_clrs($suffix, $opt_verbose, 0); unlink_all_possible_tmp_files(); + if ($using_internal_tmpdir) + { + rmdir($tmpdir); + } + rmdir($exec_dir); + chdir(".."); + rmdir($exec_dir); exit($runtime_error); } @@ -300,22 +316,22 @@ sub run_check_tests unlink_log_files(); ok("$maria_exe_path/ma_test1$suffix $silent -h$tmpdir $ma_test1_opt[$i][0] $row_type", $verbose, $i + 1); - ok("$maria_exe_path/maria_chk$suffix -h$tmpdir $ma_test1_opt[$i][1] $tmpdir/test1", + ok("$maria_exe_path/aria_chk$suffix -h$tmpdir $ma_test1_opt[$i][1] $tmpdir/test1", $verbose, $i + 1); } # # These tests are outside the loops. Make sure to include them in # nr_tests manually # - ok("$maria_exe_path/maria_pack$suffix --force -s $tmpdir/test1", $verbose, 0); - ok("$maria_exe_path/maria_chk$suffix -ess $tmpdir/test1", $verbose, 0); + ok("$maria_exe_path/aria_pack$suffix --force -s $tmpdir/test1", $verbose, 0); + ok("$maria_exe_path/aria_chk$suffix -ess $tmpdir/test1", $verbose, 0); for ($i= 0; defined($ma_test2_opt[$i]); $i++) { unlink_log_files(); ok("$maria_exe_path/ma_test2$suffix $silent -h$tmpdir $ma_test2_opt[$i][0] $row_type", $verbose, $i + 1); - ok("$maria_exe_path/maria_chk$suffix -h$tmpdir $ma_test2_opt[$i][1] $tmpdir/test2", + ok("$maria_exe_path/aria_chk$suffix -h$tmpdir $ma_test2_opt[$i][1] $tmpdir/test2", $verbose, $i + 1); } @@ -324,7 +340,7 @@ sub run_check_tests unlink_log_files(); ok("$maria_exe_path/ma_rt_test$suffix $silent -h$tmpdir $ma_rt_test_opt[$i][0] $row_type", $verbose, $i + 1); - ok("$maria_exe_path/maria_chk$suffix -h$tmpdir $ma_rt_test_opt[$i][1] $tmpdir/rt_test", + ok("$maria_exe_path/aria_chk$suffix -h$tmpdir $ma_rt_test_opt[$i][1] $tmpdir/rt_test", $verbose, $i + 1); } @@ -343,35 +359,35 @@ sub run_repair_tests() my ($i); my @t= ($NEW_TEST, - "$maria_exe_path/ma_test1$suffix -h$tmpdir $silent --checksum $row_type", - "$maria_exe_path/maria_chk$suffix -h$tmpdir -se $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -h$tmpdir --silent -re --transaction-log $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -h$tmpdir -rs $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rqs -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rs --correct-checksum -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rqs --correct-checksum -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -ros --correct-checksum -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rqos --correct-checksum -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -sz -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1", - "$maria_exe_path/ma_test2$suffix -h$tmpdir $silent -c -d1 $row_type", - "$maria_exe_path/maria_chk$suffix -s --parallel-recover -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_chk$suffix -s --parallel-recover --quick -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test2", - "$maria_exe_path/ma_test2$suffix -h$tmpdir $silent -c $row_type", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_chk$suffix -sr -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test2", - "$maria_exe_path/ma_test2$suffix -h$tmpdir $silent -c -t4 -b32768 $row_type", - "$maria_exe_path/maria_chk$suffix -s --zerofill -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1" + "$maria_exe_path/ma_test1$suffix $silent --checksum $row_type", + "$maria_exe_path/aria_chk$suffix -se test1", + "$maria_exe_path/aria_chk$suffix --silent -re --transaction-log test1", + "$maria_exe_path/aria_chk$suffix -rs test1", + "$maria_exe_path/aria_chk$suffix -se test1", + "$maria_exe_path/aria_chk$suffix -rqs test1", + "$maria_exe_path/aria_chk$suffix -se test1", + "$maria_exe_path/aria_chk$suffix -rs --correct-checksum test1", + "$maria_exe_path/aria_chk$suffix -se test1", + "$maria_exe_path/aria_chk$suffix -rqs --correct-checksum test1", + "$maria_exe_path/aria_chk$suffix -se test1", + "$maria_exe_path/aria_chk$suffix -ros --correct-checksum test1", + "$maria_exe_path/aria_chk$suffix -se test1", + "$maria_exe_path/aria_chk$suffix -rqos --correct-checksum test1", + "$maria_exe_path/aria_chk$suffix -se test1", + "$maria_exe_path/aria_chk$suffix -sz test1", + "$maria_exe_path/aria_chk$suffix -se test1", + "$maria_exe_path/ma_test2$suffix $silent -c -d1 $row_type", + "$maria_exe_path/aria_chk$suffix -s --parallel-recover test2", + "$maria_exe_path/aria_chk$suffix -se test2", + "$maria_exe_path/aria_chk$suffix -s --parallel-recover --quick test2", + "$maria_exe_path/aria_chk$suffix -se test2", + "$maria_exe_path/ma_test2$suffix $silent -c $row_type", + "$maria_exe_path/aria_chk$suffix -se test2", + "$maria_exe_path/aria_chk$suffix -sr test2", + "$maria_exe_path/aria_chk$suffix -se test2", + "$maria_exe_path/ma_test2$suffix $silent -c -t4 -b32768 $row_type", + "$maria_exe_path/aria_chk$suffix -s --zerofill test1", + "$maria_exe_path/aria_chk$suffix -se test1" ); return &count_tests(\@t) if ($count); @@ -389,53 +405,56 @@ sub run_pack_tests() my ($i); my @t= ($NEW_TEST, - "$maria_exe_path/ma_test1$suffix -h$tmpdir $silent --checksum $row_type", - "$maria_exe_path/maria_pack$suffix --force -s $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -ess -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rqs -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -es -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rs -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -es -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rus -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -es -h$tmpdir $tmpdir/test1", + "$maria_exe_path/ma_test1$suffix $silent --checksum $row_type", + "$maria_exe_path/aria_pack$suffix --force -s test1", + "$maria_exe_path/aria_chk$suffix -ess test1", + "$maria_exe_path/aria_chk$suffix -rqs test1", + "$maria_exe_path/aria_chk$suffix -es test1", + "$maria_exe_path/aria_chk$suffix -rs test1", + "$maria_exe_path/aria_chk$suffix -es test1", + "$maria_exe_path/aria_chk$suffix -rus test1", + "$maria_exe_path/aria_chk$suffix -es test1", $NEW_TEST, - "$maria_exe_path/ma_test1$suffix -h$tmpdir $silent --checksum $row_type", - "$maria_exe_path/maria_pack$suffix --force -s $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rus --safe-recover -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -es -h$tmpdir $tmpdir/test1", + "$maria_exe_path/ma_test1$suffix $silent --checksum $row_type", + "$maria_exe_path/aria_pack$suffix --force -s test1", + "$maria_exe_path/aria_chk$suffix -rus --safe-recover test1", + "$maria_exe_path/aria_chk$suffix -es test1", $NEW_TEST, - "$maria_exe_path/ma_test1$suffix -h$tmpdir $silent --checksum -S $row_type", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -ros -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rqs -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test1", + "$maria_exe_path/ma_test1$suffix $silent --checksum -S $row_type", + "$maria_exe_path/aria_chk$suffix -se test1", + "$maria_exe_path/aria_chk$suffix -ros test1", + "$maria_exe_path/aria_chk$suffix -rqs test1", + "$maria_exe_path/aria_chk$suffix -se test1", $NEW_TEST, - "$maria_exe_path/maria_pack$suffix --force -s $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rqs -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -es -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -rus -h$tmpdir $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -es -h$tmpdir $tmpdir/test1", + "$maria_exe_path/aria_pack$suffix --force -s test1", + "$maria_exe_path/aria_chk$suffix -rqs test1", + "$maria_exe_path/aria_chk$suffix -es test1", + "$maria_exe_path/aria_chk$suffix -rus test1", + "$maria_exe_path/aria_chk$suffix -es test1", $NEW_TEST, - "$maria_exe_path/ma_test2$suffix -h$tmpdir $silent -c -d1 $row_type", - "$maria_exe_path/maria_chk$suffix -s --parallel-recover -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_chk$suffix -s --unpack --parallel-recover -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_pack$suffix --force -s $tmpdir/test1", - "$maria_exe_path/maria_chk$suffix -s --unpack --parallel-recover -h$tmpdir $tmpdir/test2", - "$maria_exe_path/maria_chk$suffix -se -h$tmpdir $tmpdir/test2", + "$maria_exe_path/ma_test2$suffix $silent -c -d1 $row_type", + "$maria_exe_path/aria_chk$suffix -s --parallel-recover test2", + "$maria_exe_path/aria_chk$suffix -se test2", + "$maria_exe_path/aria_chk$suffix -s --unpack --parallel-recover test2", + "$maria_exe_path/aria_chk$suffix -se test2", + "$maria_exe_path/aria_pack$suffix --force -s test1", + "$maria_exe_path/aria_chk$suffix -s --unpack --parallel-recover test2", + "$maria_exe_path/aria_chk$suffix -se test2", $NEW_TEST, - "$maria_exe_path/ma_test1$suffix -h$tmpdir $silent -c $row_type", - "cp $tmpdir/test1.MAD $tmpdir/test2.MAD", - "cp $tmpdir/test1.MAI $tmpdir/test2.MAI", - "$maria_exe_path/maria_pack$suffix --force -s --join=$tmpdir/test3 $tmpdir/test1 $tmpdir/test2", - "$maria_exe_path/maria_chk -s -h$tmpdir $tmpdir/test3", - "$maria_exe_path/maria_chk -s --safe-recover -h$tmpdir $tmpdir/test3", - "$maria_exe_path/maria_chk -s -h$tmpdir $tmpdir/test3" + "$maria_exe_path/ma_test1$suffix $silent -c $row_type", + "cp test1.MAD test2.MAD", + "cp test1.MAI test2.MAI", + "$maria_exe_path/aria_pack$suffix --force -s --join=test3 test1 test2", ); - return &count_tests(\@t) if ($count); + return (&count_tests(\@t) + 3) if ($count); + &run_test_bunch(\@t, $verbose, 0); + + ok("$maria_exe_path/aria_chk -s test3", $verbose, 0, 1); + @t= ("$maria_exe_path/aria_chk -s --safe-recover test3", + "$maria_exe_path/aria_chk -s test3"); &run_test_bunch(\@t, $verbose, 0); + return 0; } @@ -452,7 +471,7 @@ sub run_tests_on_warnings_and_errors ok("$maria_exe_path/ma_test2$suffix -h$tmpdir $silent -L -K -W -P -S -R1 -m500", $verbose, 0); - ok("$maria_exe_path/maria_chk$suffix -h$tmpdir -sm $tmpdir/test2", $verbose, 0); + ok("$maria_exe_path/aria_chk$suffix -h$tmpdir -sm $tmpdir/test2", $verbose, 0); # ma_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135\n # In the following a failure is a success and success is a failure $com= "$maria_exe_path/ma_test2$suffix -h$tmpdir $silent -L -K -R1 -m2000 "; @@ -460,15 +479,15 @@ sub run_tests_on_warnings_and_errors ok($com, $verbose, 0, 1); ok("cat ma_test2_message.txt", $verbose, 0); ok("grep \"Error: 135\" ma_test2_message.txt > /dev/null", $verbose, 0); - # maria_exe_path/maria_chk$suffix -h$tmpdir -sm $tmpdir/test2 will warn that + # maria_exe_path/aria_chk$suffix -h$tmpdir -sm $tmpdir/test2 will warn that # Datafile is almost full - ok("$maria_exe_path/maria_chk$suffix -h$tmpdir -sm $tmpdir/test2 >ma_test2_message.txt 2>&1", - $verbose, 0); + ok("$maria_exe_path/aria_chk$suffix -h$tmpdir -sm $tmpdir/test2 >ma_test2_message.txt 2>&1", + $verbose, 0, 1); ok("cat ma_test2_message.txt", $verbose, 0); ok("grep \"warning: Datafile is almost full\" ma_test2_message.txt>/dev/null", $verbose, 0); unlink <ma_test2_message.txt>; - ok("$maria_exe_path/maria_chk$suffix -h$tmpdir -ssm $tmpdir/test2", $verbose, 0); + ok("$maria_exe_path/aria_chk$suffix -h$tmpdir -ssm $tmpdir/test2", $verbose, 0); return 0; } @@ -497,31 +516,31 @@ sub run_tests_on_clrs my @t= ($NEW_TEST, "$maria_exe_path/ma_test2$suffix -h$tmpdir -s -L -K -W -P -M -T -c -b -t2 -A1", - "cp $tmpdir/maria_log_control $tmpdir/maria_log_control.backup", - "$maria_exe_path/maria_read_log$suffix -a -s -h$tmpdir", - "$maria_exe_path/maria_chk$suffix -h$tmpdir -s -e $tmpdir/test2", - "mv $tmpdir/maria_log_control.backup $tmpdir/maria_log_control", + "cp $tmpdir/aria_log_control $tmpdir/aria_log_control.backup", + "$maria_exe_path/aria_read_log$suffix -a -s -h$tmpdir", + "$maria_exe_path/aria_chk$suffix -h$tmpdir -s -e $tmpdir/test2", + "mv $tmpdir/aria_log_control.backup $tmpdir/aria_log_control", "rm $tmpdir/test2.MA?", - "$maria_exe_path/maria_read_log$suffix -a -s -h$tmpdir", - "$maria_exe_path/maria_chk$suffix -h$tmpdir -s -e $tmpdir/test2", + "$maria_exe_path/aria_read_log$suffix -a -s -h$tmpdir", + "$maria_exe_path/aria_chk$suffix -h$tmpdir -s -e $tmpdir/test2", "rm $tmpdir/test2.MA?", $NEW_TEST, "$maria_exe_path/ma_test2$suffix -h$tmpdir -s -L -K -W -P -M -T -c -b -t2 -A1", - "$maria_exe_path/maria_read_log$suffix -a -s -h$tmpdir ", - "$maria_exe_path/maria_chk$suffix -h$tmpdir -s -e $tmpdir/test2", + "$maria_exe_path/aria_read_log$suffix -a -s -h$tmpdir ", + "$maria_exe_path/aria_chk$suffix -h$tmpdir -s -e $tmpdir/test2", "rm $tmpdir/test2.MA?", - "$maria_exe_path/maria_read_log$suffix -a -s -h$tmpdir", - "$maria_exe_path/maria_chk$suffix -h$tmpdir -e -s $tmpdir/test2", + "$maria_exe_path/aria_read_log$suffix -a -s -h$tmpdir", + "$maria_exe_path/aria_chk$suffix -h$tmpdir -e -s $tmpdir/test2", "rm $tmpdir/test2.MA?", $NEW_TEST, "$maria_exe_path/ma_test2$suffix -h$tmpdir -s -L -K -W -P -M -T -c -b32768 -t4 -A1", - "$maria_exe_path/maria_read_log$suffix -a -s -h$tmpdir", - "$maria_exe_path/maria_chk$suffix -h$tmpdir -es $tmpdir/test2", - "$maria_exe_path/maria_read_log$suffix -a -s -h$tmpdir ", - "$maria_exe_path/maria_chk$suffix -h$tmpdir -es $tmpdir/test2", + "$maria_exe_path/aria_read_log$suffix -a -s -h$tmpdir", + "$maria_exe_path/aria_chk$suffix -h$tmpdir -es $tmpdir/test2", + "$maria_exe_path/aria_read_log$suffix -a -s -h$tmpdir ", + "$maria_exe_path/aria_chk$suffix -h$tmpdir -es $tmpdir/test2", "rm $tmpdir/test2.MA?", - "$maria_exe_path/maria_read_log$suffix -a -s -h$tmpdir", - "$maria_exe_path/maria_chk$suffix -h$tmpdir -es $tmpdir/test2", + "$maria_exe_path/aria_read_log$suffix -a -s -h$tmpdir", + "$maria_exe_path/aria_chk$suffix -h$tmpdir -es $tmpdir/test2", "rm $tmpdir/test2.MA?" ); @@ -550,7 +569,7 @@ sub run_tests_on_clrs sub ok { my ($com, $verbose, $iteration, $expected_error)= @_; - my ($msg, $output, $err, $len); + my ($msg, $output, $err, $errcode, $len); $test_counter++; if ($test_begin > $test_counter) @@ -580,8 +599,9 @@ sub ok print " " x (62 - $len); } $err= $?; + $errcode= ($? >> 8); if ((!$err && !$expected_error) || - (($err >> 8) == $expected_error && $expected_error)) + ($errcode == $expected_error && $expected_error)) { print "[ " if ($verbose); print "ok"; @@ -618,7 +638,7 @@ sub ok } $msg.= "at line "; $msg.= (caller)[2]; - $msg.= "\n(errcode: $err, test: $test_counter)\n"; + $msg.= "\n(errcode: $errcode, test: $test_counter)\n"; if ($expected_error) { $msg.= "Was expecting errcode: $expected_error\n"; @@ -673,7 +693,7 @@ sub count_tests sub unlink_log_files { - unlink "$full_tmpdir/maria_log_control", "$full_tmpdir/maria_log.00000001", "$full_tmpdir/maria_log.00000002"; + unlink "$full_tmpdir/aria_log_control", "$full_tmpdir/aria_log.00000001", "$full_tmpdir/aria_log.00000002"; } sub unlink_all_possible_tmp_files() @@ -681,7 +701,7 @@ sub unlink_all_possible_tmp_files() unlink_log_files(); # Unlink tmp files that may have been created when testing the test programs - unlink <$full_tmpdir/*.TMD maria_log_control maria_log.00000001 maria_log.00000002 maria_logtest1.MA? test2.MA? test3.MA?>; + unlink <$full_tmpdir/*.TMD $full_tmpdir/aria_read_log_test1.txt $full_tmpdir/test1*.MA? $full_tmpdir/ma_test_recovery.output aria_log_control aria_log.00000001 aria_log.00000002 aria_logtest1.MA? test1.MA? test2.MA? test3.MA?>; } #### @@ -720,7 +740,7 @@ $my_progname version $VER Description: -Run various Maria related tests. Typically used via make test as a unittest. +Run various Aria related tests. Typically used via make test as a unittest. Options --help Show this help and exit. @@ -733,6 +753,7 @@ Options might depend on previous ones. --start-from=... Alias for --run-tests --silent=... Silent option passed to ma_test* tests ('$opt_silent') +--tmpdir=... Store tests data in this directory (works for most tests) --valgrind=... Options for valgrind. ('$opt_valgrind') --verbose Be more verbose. Will print each unittest on a line diff --git a/storage/maria/unittest/ma_test_loghandler-t.c b/storage/maria/unittest/ma_test_loghandler-t.c index 53459a5239d..4603992350f 100644 --- a/storage/maria/unittest/ma_test_loghandler-t.c +++ b/storage/maria/unittest/ma_test_loghandler-t.c @@ -19,7 +19,8 @@ #include <tap.h> #include "../trnman.h" -extern my_bool maria_log_remove(); +extern my_bool maria_log_remove(const char *testdir); +extern char *create_tmpdir(const char *progname); extern void example_loghandler_init(); #ifndef DBUG_OFF @@ -161,7 +162,6 @@ int main(int argc __attribute__((unused)), char *argv[]) LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 3]; struct st_translog_scanner_data scanner; int rc; - MY_INIT(argv[0]); if (my_set_max_open_files(100) < 100) @@ -170,9 +170,11 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } bzero(&pagecache, sizeof(pagecache)); - maria_data_root= (char *)"."; - if (maria_log_remove()) + + maria_data_root= create_tmpdir(argv[0]); + if (maria_log_remove(0)) exit(1); + /* We don't need to do physical syncs in this test */ my_disable_sync= 1; @@ -207,7 +209,7 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, LOG_FLAGS, 0, &translog_example_table_init, 0)) { @@ -656,7 +658,7 @@ err: end_pagecache(&pagecache, 1); ma_control_file_end(); - if (maria_log_remove()) + if (maria_log_remove(maria_data_root)) exit(1); return(test(exit_status())); diff --git a/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c b/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c index 06d9a00c04c..7e5b9543e98 100644 --- a/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c +++ b/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c @@ -19,7 +19,8 @@ #include <tap.h> #include "../trnman.h" -extern my_bool maria_log_remove(); +extern my_bool maria_log_remove(const char *testdir); +extern char *create_tmpdir(const char *progname); extern void translog_example_table_init(); #ifndef DBUG_OFF @@ -31,7 +32,6 @@ static const char *default_dbug_option; #define LOG_FILE_SIZE (1024L*1024L*1024L + 1024L*1024L*512) #define LOG_FLAGS 0 -static char *first_translog_file= (char*)"maria_log.00000001"; int main(int argc __attribute__((unused)), char *argv[]) { @@ -40,18 +40,18 @@ int main(int argc __attribute__((unused)), char *argv[]) PAGECACHE pagecache; LSN lsn, first_lsn, theor_lsn; LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 1]; - MY_INIT(argv[0]); plan(2); bzero(&pagecache, sizeof(pagecache)); - maria_data_root= (char *)"."; - if (maria_log_remove()) + /* + Don't give an error if we can't create dir, as it may already exist from a previously aborted + run + */ + maria_data_root= create_tmpdir(argv[0]); + if (maria_log_remove(0)) exit(1); - /* be sure that we have no logs in the directory*/ - my_delete(CONTROL_FILE_BASE_NAME, MYF(0)); - my_delete(first_translog_file, MYF(0)); bzero(long_tr_id, 6); #ifndef DBUG_OFF @@ -78,9 +78,8 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, - LOG_FLAGS, 0, &translog_example_table_init, - 0)) + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, + LOG_FLAGS, 0, &translog_example_table_init, 0)) { fprintf(stderr, "Can't init loghandler (%d)\n", errno); exit(1); @@ -154,7 +153,7 @@ int main(int argc __attribute__((unused)), char *argv[]) translog_destroy(); end_pagecache(&pagecache, 1); ma_control_file_end(); - if (maria_log_remove()) + if (maria_log_remove(maria_data_root)) exit(1); exit(0); } diff --git a/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c b/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c index 64f486b8cf1..915bec4893d 100644 --- a/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c +++ b/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c @@ -19,7 +19,8 @@ #include <tap.h> #include "../trnman.h" -extern my_bool maria_log_remove(); +extern my_bool maria_log_remove(const char *testdir); +extern char *create_tmpdir(const char *progname); extern void translog_example_table_init(); #ifndef DBUG_OFF @@ -40,14 +41,14 @@ int main(int argc __attribute__((unused)), char *argv[]) PAGECACHE pagecache; LSN lsn, max_lsn, last_lsn= LSN_IMPOSSIBLE; LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 1]; - MY_INIT(argv[0]); plan(2); bzero(&pagecache, sizeof(pagecache)); - maria_data_root= (char *)"."; - if (maria_log_remove()) + + maria_data_root= create_tmpdir(argv[0]); + if (maria_log_remove(0)) exit(1); bzero(long_tr_id, 6); @@ -75,7 +76,7 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, LOG_FLAGS, 0, &translog_example_table_init, 0)) { @@ -150,7 +151,7 @@ int main(int argc __attribute__((unused)), char *argv[]) translog_destroy(); end_pagecache(&pagecache, 1); ma_control_file_end(); - if (maria_log_remove()) + if (maria_log_remove(maria_data_root)) exit(1); exit(0); } diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c index aab94ff10c7..6ea9c95acfa 100644 --- a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c @@ -21,7 +21,8 @@ #include "sequence_storage.h" #include <my_getopt.h> -extern my_bool maria_log_remove(); +extern my_bool maria_log_remove(const char *testdir); +extern char *create_tmpdir(const char *progname); extern void translog_example_table_init(); #ifndef DBUG_OFF @@ -238,21 +239,23 @@ int main(int argc __attribute__((unused)), char *argv[]) TRANSLOG_HEADER_BUFFER rec; LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 2]; struct st_translog_scanner_data scanner; + const char *progname=argv[0]; int rc; - MY_INIT(argv[0]); - bzero(&pagecache, sizeof(pagecache)); - maria_data_root= (char *)"."; + load_defaults("my", load_default_groups, &argc, &argv); - default_argv= argv; get_options(&argc, &argv); - /* We don't need to do physical syncs in this test */ - my_disable_sync= 1; + default_argv= argv; - if (maria_log_remove()) + bzero(&pagecache, sizeof(pagecache)); + maria_data_root= create_tmpdir(progname); + if (maria_log_remove(0)) exit(1); + /* We don't need to do physical syncs in this test */ + my_disable_sync= 1; + { uchar buff[4]; for (i= 0; i < (LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2); i++) @@ -276,7 +279,7 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, 0, 0, &translog_example_table_init, 0)) { fprintf(stderr, "Can't init loghandler (%d)\n", errno); @@ -439,7 +442,7 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "pass2: Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, 0, READONLY, &translog_example_table_init, 0)) { fprintf(stderr, "pass2: Can't init loghandler (%d)\n", errno); @@ -741,7 +744,7 @@ err: ma_control_file_end(); free_defaults(default_argv); seq_storage_destroy(&seq); - if (maria_log_remove()) + if (maria_log_remove(maria_data_root)) exit(1); return (test(exit_status())); diff --git a/storage/maria/unittest/ma_test_loghandler_multithread-t.c b/storage/maria/unittest/ma_test_loghandler_multithread-t.c index e46fe047a97..234b233bf52 100644 --- a/storage/maria/unittest/ma_test_loghandler_multithread-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multithread-t.c @@ -19,8 +19,8 @@ #include <tap.h> #include "../trnman.h" -extern my_bool maria_log_remove(); -extern void translog_example_table_init(); +extern my_bool maria_log_remove(const char *testdir); +extern char *create_tmpdir(const char *progname); #ifndef DBUG_OFF static const char *default_dbug_option; @@ -268,6 +268,7 @@ int main(int argc __attribute__((unused)), pthread_attr_t thr_attr; int *param, error; int rc; + MY_INIT(argv[0]); plan(WRITERS + FLUSHERS + ITERATIONS * WRITERS * 3 + FLUSH_ITERATIONS * FLUSHERS ); @@ -275,7 +276,10 @@ int main(int argc __attribute__((unused)), my_disable_sync= 1; bzero(&pagecache, sizeof(pagecache)); - maria_data_root= (char *)"."; + maria_data_root= create_tmpdir(argv[0]); + if (maria_log_remove(0)) + exit(1); + long_buffer= malloc(LONG_BUFFER_SIZE + 7 * 2 + 2); if (long_buffer == 0) { @@ -285,11 +289,6 @@ int main(int argc __attribute__((unused)), for (i= 0; i < (LONG_BUFFER_SIZE + 7 * 2 + 2); i++) long_buffer[i]= (i & 0xFF); - MY_INIT(argv[0]); - if (maria_log_remove()) - exit(1); - - #ifndef DBUG_OFF #if defined(__WIN__) default_dbug_option= "d:t:i:O,\\ma_test_loghandler.trace"; @@ -347,7 +346,7 @@ int main(int argc __attribute__((unused)), fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, LOG_FLAGS, 0, &translog_example_table_init, 0)) { @@ -546,7 +545,7 @@ err: translog_destroy(); end_pagecache(&pagecache, 1); ma_control_file_end(); - if (maria_log_remove()) + if (maria_log_remove(maria_data_root)) exit(1); return(exit_status()); diff --git a/storage/maria/unittest/ma_test_loghandler_noflush-t.c b/storage/maria/unittest/ma_test_loghandler_noflush-t.c index 973dfd03bcf..3e1ce202fac 100644 --- a/storage/maria/unittest/ma_test_loghandler_noflush-t.c +++ b/storage/maria/unittest/ma_test_loghandler_noflush-t.c @@ -19,7 +19,8 @@ #include <tap.h> #include "../trnman.h" -extern my_bool maria_log_remove(); +extern my_bool maria_log_remove(const char *testdir); +extern char *create_tmpdir(const char *progname); extern void translog_example_table_init(); #ifndef DBUG_OFF @@ -31,8 +32,6 @@ static const char *default_dbug_option; #define LOG_FILE_SIZE (1024L*1024L*1024L + 1024L*1024L*512) #define LOG_FLAGS 0 -static char *first_translog_file= (char*)"maria_log.00000001"; - int main(int argc __attribute__((unused)), char *argv[]) { uint pagen; @@ -49,12 +48,9 @@ int main(int argc __attribute__((unused)), char *argv[]) plan(1); bzero(&pagecache, sizeof(pagecache)); - maria_data_root= (char *)"."; - if (maria_log_remove()) + maria_data_root= create_tmpdir(argv[0]); + if (maria_log_remove(0)) exit(1); - /* be sure that we have no logs in the directory*/ - my_delete(CONTROL_FILE_BASE_NAME, MYF(0)); - my_delete(first_translog_file, MYF(0)); bzero(long_tr_id, 6); #ifndef DBUG_OFF @@ -81,7 +77,7 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, LOG_FLAGS, 0, &translog_example_table_init, 0)) { @@ -139,7 +135,7 @@ err: translog_destroy(); end_pagecache(&pagecache, 1); ma_control_file_end(); - if (maria_log_remove()) + if (maria_log_remove(maria_data_root)) exit(1); exit(rc); diff --git a/storage/maria/unittest/ma_test_loghandler_nologs-t.c b/storage/maria/unittest/ma_test_loghandler_nologs-t.c index 34508d1d751..03badc9aced 100644 --- a/storage/maria/unittest/ma_test_loghandler_nologs-t.c +++ b/storage/maria/unittest/ma_test_loghandler_nologs-t.c @@ -19,8 +19,8 @@ #include <tap.h> #include "../trnman.h" -extern my_bool maria_log_remove(); -extern void example_loghandler_init(); +extern my_bool maria_log_remove(const char *testdir); +extern char *create_tmpdir(const char *progname); #ifndef DBUG_OFF static const char *default_dbug_option; @@ -49,8 +49,8 @@ int main(int argc __attribute__((unused)), char *argv[]) bzero(&pagecache, sizeof(pagecache)); bzero(long_buffer, LONG_BUFFER_SIZE); - maria_data_root= (char *)"."; - if (maria_log_remove()) + maria_data_root= create_tmpdir(argv[0]); + if (maria_log_remove(0)) exit(1); bzero(long_tr_id, 6); @@ -78,7 +78,7 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, LOG_FLAGS, 0, &translog_example_table_init, 0)) { @@ -151,7 +151,7 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, LOG_FLAGS, 0, &translog_example_table_init, 1)) { @@ -189,7 +189,7 @@ int main(int argc __attribute__((unused)), char *argv[]) ok(1, "New log is OK"); - if (maria_log_remove()) + if (maria_log_remove(maria_data_root)) exit(1); exit(0); } diff --git a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c index a32cf32c787..4e8f7a744ee 100644 --- a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c +++ b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c @@ -19,8 +19,8 @@ #include <tap.h> #include "../trnman.h" -extern my_bool maria_log_remove(); -extern void translog_example_table_init(); +extern my_bool maria_log_remove(const char *testdir); +extern char *create_tmpdir(const char *progname); #ifndef DBUG_OFF static const char *default_dbug_option; @@ -31,8 +31,10 @@ static const char *default_dbug_option; #define LOG_FILE_SIZE (1024L*1024L*1024L + 1024L*1024L*512) #define LOG_FLAGS 0 -static char *first_translog_file= (char*)"maria_log.00000001"; -static char *file1_name= (char*)"page_cache_test_file_1"; +static const char *base_first_translog_file= "aria_log.00000001"; +static const char *base_file1_name= "page_cache_test_file_1"; +static char file1_name[FN_REFLEN], first_translog_file[FN_REFLEN]; + static PAGECACHE_FILE file1; @@ -68,18 +70,15 @@ int main(int argc __attribute__((unused)), char *argv[]) LSN lsn; my_off_t file_size; LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 1]; - MY_INIT(argv[0]); plan(1); bzero(&pagecache, sizeof(pagecache)); - maria_data_root= (char *)"."; - if (maria_log_remove()) + maria_data_root= create_tmpdir(argv[0]); + if (maria_log_remove(0)) exit(1); - /* be sure that we have no logs in the directory*/ - my_delete(CONTROL_FILE_BASE_NAME, MYF(0)); - my_delete(first_translog_file, MYF(0)); + fn_format(first_translog_file, base_first_translog_file, maria_data_root, "", MYF(0)); bzero(long_tr_id, 6); #ifndef DBUG_OFF @@ -106,7 +105,7 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, LOG_FLAGS, 0, &translog_example_table_init, 0)) { @@ -145,6 +144,7 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } + fn_format(file1_name, base_file1_name, maria_data_root, "", MYF(0)); if ((file1.file= my_open(file1_name, O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1) { @@ -192,9 +192,9 @@ int main(int argc __attribute__((unused)), char *argv[]) translog_destroy(); end_pagecache(&pagecache, 1); ma_control_file_end(); - my_delete(CONTROL_FILE_BASE_NAME, MYF(0)); - my_delete(first_translog_file, MYF(0)); - my_delete(file1_name, MYF(0)); + my_delete(file1_name, MYF(MY_WME)); + if (maria_log_remove(maria_data_root)) + exit(1); exit(0); } diff --git a/storage/maria/unittest/ma_test_loghandler_purge-t.c b/storage/maria/unittest/ma_test_loghandler_purge-t.c index d37b45bc3ca..8badfd9451e 100644 --- a/storage/maria/unittest/ma_test_loghandler_purge-t.c +++ b/storage/maria/unittest/ma_test_loghandler_purge-t.c @@ -19,8 +19,8 @@ #include <tap.h> #include "../trnman.h" -extern my_bool maria_log_remove(); -extern void translog_example_table_init(); +extern my_bool maria_log_remove(const char *testdir); +extern char *create_tmpdir(const char *progname); #ifndef DBUG_OFF static const char *default_dbug_option; @@ -49,8 +49,8 @@ int main(int argc __attribute__((unused)), char *argv[]) bzero(&pagecache, sizeof(pagecache)); bzero(long_buffer, LONG_BUFFER_SIZE); - maria_data_root= (char *)"."; - if (maria_log_remove()) + maria_data_root= create_tmpdir(argv[0]); + if (maria_log_remove(0)) exit(1); bzero(long_tr_id, 6); @@ -78,7 +78,7 @@ int main(int argc __attribute__((unused)), char *argv[]) fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); } - if (translog_init_with_table(".", LOG_FILE_SIZE, 50112, 0, &pagecache, + if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, LOG_FLAGS, 0, &translog_example_table_init, 0)) { @@ -186,7 +186,7 @@ int main(int argc __attribute__((unused)), char *argv[]) translog_destroy(); end_pagecache(&pagecache, 1); ma_control_file_end(); - if (maria_log_remove()) + if (maria_log_remove(maria_data_root)) exit(1); exit(0); } diff --git a/storage/maria/unittest/ma_test_recovery.expected b/storage/maria/unittest/ma_test_recovery.expected index b95575173ee..5f7dd54e673 100644 --- a/storage/maria/unittest/ma_test_recovery.expected +++ b/storage/maria/unittest/ma_test_recovery.expected @@ -67,7 +67,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t2 -A1 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -76,7 +76,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -85,7 +85,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -96,7 +96,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t6 -A1 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -105,7 +105,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -114,7 +114,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -164,7 +164,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t2 -A2 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -173,7 +173,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -182,7 +182,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -193,7 +193,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t6 -A2 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -202,7 +202,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -211,7 +211,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -261,7 +261,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t2 -A3 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -270,7 +270,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -279,7 +279,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -290,7 +290,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t6 -A3 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -299,7 +299,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -308,7 +308,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -358,7 +358,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t2 -A4 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -367,7 +367,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -376,7 +376,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -387,7 +387,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -t6 -A4 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -396,7 +396,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -405,7 +405,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -455,7 +455,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t2 -A1 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -464,7 +464,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -473,7 +473,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -484,7 +484,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t6 -A1 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -493,7 +493,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -502,7 +502,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -552,7 +552,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t2 -A2 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -561,7 +561,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -570,7 +570,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -581,7 +581,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t6 -A2 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -590,7 +590,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -599,7 +599,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -649,7 +649,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t2 -A3 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -658,7 +658,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -667,7 +667,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -678,7 +678,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t6 -A3 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -687,7 +687,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -696,7 +696,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -746,7 +746,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t2 -A4 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -755,7 +755,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -764,7 +764,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -775,7 +775,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -t6 -A4 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -784,7 +784,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -793,7 +793,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -843,7 +843,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t2 -A1 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -852,7 +852,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -861,7 +861,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -872,7 +872,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t6 -A1 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -881,7 +881,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -890,7 +890,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -940,7 +940,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t2 -A2 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -949,7 +949,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -958,7 +958,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -969,7 +969,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t6 -A2 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -978,7 +978,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -987,7 +987,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1037,7 +1037,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t2 -A3 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1046,7 +1046,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1055,7 +1055,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1066,7 +1066,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t6 -A3 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1075,7 +1075,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1084,7 +1084,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1134,7 +1134,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t2 -A4 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1143,7 +1143,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1152,7 +1152,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1163,7 +1163,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -H1 -t6 -A4 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1172,7 +1172,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1181,7 +1181,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1231,7 +1231,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t2 -A1 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1240,7 +1240,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1249,7 +1249,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1260,7 +1260,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t6 -A1 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1269,7 +1269,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1278,7 +1278,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1328,7 +1328,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t2 -A2 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1337,7 +1337,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1346,7 +1346,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1357,7 +1357,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t6 -A2 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1366,7 +1366,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1375,7 +1375,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1425,7 +1425,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t2 -A3 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1434,7 +1434,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1443,7 +1443,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1454,7 +1454,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t6 -A3 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1463,7 +1463,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1472,7 +1472,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1522,7 +1522,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t2 -A4 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1531,7 +1531,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1540,7 +1540,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1551,7 +1551,7 @@ TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t1 (commit at end) TEST WITH ma_test2 -s -L -K -W -P -M -T -c -b32768 -H1 -t6 -A4 (additional aborted work) Dying on request without maria_commit()/maria_close() applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1560,7 +1560,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing idempotency applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable @@ -1569,7 +1569,7 @@ Differences in maria_chk -dvv, recovery not yet perfect ! ========DIFF END======= testing applying of CLRs to recreate table applying log -Differences in maria_chk -dvv, recovery not yet perfect ! +Differences in aria_chk -dvv, recovery not yet perfect ! ========DIFF START======= 6c6 < Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable diff --git a/storage/maria/unittest/ma_test_recovery.pl b/storage/maria/unittest/ma_test_recovery.pl index 1f8bdd88e1a..f3a5bffbc36 100755 --- a/storage/maria/unittest/ma_test_recovery.pl +++ b/storage/maria/unittest/ma_test_recovery.pl @@ -17,7 +17,7 @@ $opt_abort_on_error=0; my $silent= "-s"; my $maria_path; # path to "storage/maria" -my $maria_exe_path; # path to executables (ma_test1, maria_chk etc) +my $maria_exe_path; # path to executables (ma_test1, aria_chk etc) my $tmp= "./tmp"; my $my_progname= $0; my $suffix; @@ -74,7 +74,7 @@ sub main { mkdir $tmp; } - print "MARIA RECOVERY TESTS\n"; + print "ARIA RECOVERY TESTS\n"; # To not flood the screen, we redirect all the commands below to a text file # and just give a final error if their output is not as expected @@ -98,7 +98,7 @@ sub main foreach my $prog (@t) { - unlink <maria_log.* maria_log_control>; + unlink <aria_log.* aria_log_control>; my $prog_no_suffix= $prog; $prog_no_suffix=~ s/$suffix// if ($suffix); print MY_LOG "TEST WITH $prog_no_suffix\n"; @@ -113,11 +113,11 @@ sub main { die("can't guess table name"); } - $com= "$maria_exe_path/maria_chk$suffix -dvv $table "; + $com= "$maria_exe_path/aria_chk$suffix -dvv $table "; $com.= "| grep -v \"Creation time:\" | grep -v \"recover time:\" | grep -v \"file length\" | grep -v \"LSNs:\" | grep -v \"UUID:\""; - $com.= "> $tmp/maria_chk_message.good.txt 2>&1"; + $com.= "> $tmp/aria_chk_message.good.txt 2>&1"; my_exec($com); - my $checksum= my_exec("$maria_exe_path/maria_chk$suffix -dss $table"); + my $checksum= my_exec("$maria_exe_path/aria_chk$suffix -dss $table"); move("$table.MAD", "$tmp/$table-good.MAD") || die "Can't move $table.MAD to $tmp/$table-good.MAD\n"; move("$table.MAI", "$tmp/$table-good.MAI") || @@ -181,7 +181,7 @@ sub main } $commit_run_args= $t2[$k + 1]; $abort_run_args= $t2[$k + 2]; - unlink <maria_log.* maria_log_control>; + unlink <aria_log.* aria_log_control>; my $prog_no_suffix= $prog; $prog_no_suffix=~ s/$suffix// if ($suffix); print MY_LOG "TEST WITH $prog_no_suffix $commit_run_args (commit at end)\n"; @@ -196,17 +196,17 @@ sub main { die("can't guess table name"); } - $com= "$maria_exe_path/maria_chk$suffix -dvv $table "; + $com= "$maria_exe_path/aria_chk$suffix -dvv $table "; $com.= "| grep -v \"Creation time:\" | grep -v \"recover time:\" | grep -v \"recover time:\" |grep -v \"file length\" | grep -v \"LSNs:\" | grep -v \"UUID:\" "; - $com.= "> $tmp/maria_chk_message.good.txt 2>&1"; + $com.= "> $tmp/aria_chk_message.good.txt 2>&1"; $res= my_exec($com); print MY_LOG $res; - $checksum= my_exec("$maria_exe_path/maria_chk$suffix -dss $table"); + $checksum= my_exec("$maria_exe_path/aria_chk$suffix -dss $table"); move("$table.MAD", "$tmp/$table-good.MAD") || die "Can't move $table.MAD to $tmp/$table-good.MAD\n"; move("$table.MAI", "$tmp/$table-good.MAI") || die "Can't move $table.MAI to $tmp/$table-good.MAI\n"; - unlink <maria_log.* maria_log_control>; + unlink <aria_log.* aria_log_control>; print MY_LOG "TEST WITH $prog_no_suffix $abort_run_args$test_undo[$j] (additional aborted work)\n"; $res= my_exec("$maria_exe_path/$prog $abort_run_args$test_undo[$j]"); print MY_LOG $res; @@ -216,10 +216,10 @@ sub main die "Can't copy $table.MAI to $tmp/$table-before_undo.MAI\n"; # The lines below seem unneeded, will be removed soon - # We have to copy and restore logs, as running maria_read_log will - # change the maria_control_file - # rm -f $tmp/maria_log.* $tmp/maria_log_control - # cp $maria_path/maria_log* $tmp + # We have to copy and restore logs, as running aria_read_log will + # change the aria_control_file + # rm -f $tmp/aria_log.* $tmp/aria_log_control + # cp $maria_path/aria_log* $tmp if ($test_undo[$j] != 3) { apply_log($table, "shouldchangelog"); # should undo aborted work @@ -246,13 +246,13 @@ sub main print MY_LOG $res; print MY_LOG "testing applying of CLRs to recreate table\n"; unlink <$table.MA?>; - # cp $tmp/maria_log* $maria_path #unneeded + # cp $tmp/aria_log* $maria_path #unneeded apply_log($table, "shouldnotchangelog"); check_table_is_same($table, $checksum); $res= physical_cmp($table, "$tmp/$table-after_undo"); print MY_LOG $res; } - unlink <$table.* $tmp/$table* $tmp/maria_chk_*.txt $tmp/maria_read_log_$table.txt>; + unlink <$table.* $tmp/$table* $tmp/aria_chk_*.txt $tmp/aria_read_log_$table.txt>; } } } @@ -263,7 +263,7 @@ sub main } close(MY_LOG); - # also note that maria_chk -dvv shows differences for ma_test2 in UNDO phase, + # also note that aria_chk -dvv shows differences for ma_test2 in UNDO phase, # this is normal: removing records does not shrink the data/key file, # does not put back the "analyzed,optimized keys"(etc) index state. `diff -b $maria_path/unittest/ma_test_recovery.expected $tmp/ma_test_recovery.output`; @@ -296,29 +296,29 @@ sub check_table_is_same print "checking if table $table has changed\n"; } - $com= "$maria_exe_path/maria_chk$suffix -dvv $table | grep -v \"Creation time:\" | grep -v \"recover time:\""; - $com.= "| grep -v \"file length\" | grep -v \"LSNs:\" | grep -v \"UUID:\" > $tmp/maria_chk_message.txt 2>&1"; + $com= "$maria_exe_path/aria_chk$suffix -dvv $table | grep -v \"Creation time:\" | grep -v \"recover time:\""; + $com.= "| grep -v \"file length\" | grep -v \"LSNs:\" | grep -v \"UUID:\" > $tmp/aria_chk_message.txt 2>&1"; $res= `$com`; print MY_LOG $res; - $res= `$maria_exe_path/maria_chk$suffix -ss -e --read-only $table`; + $res= `$maria_exe_path/aria_chk$suffix -ss -e --read-only $table`; print MY_LOG $res; - $checksum2= `$maria_exe_path/maria_chk$suffix -dss $table`; + $checksum2= `$maria_exe_path/aria_chk$suffix -dss $table`; if ("$checksum" ne "$checksum2") { print MY_LOG "checksum differs for $table before and after recovery\n"; return 1; } - $com= "diff $tmp/maria_chk_message.good.txt $tmp/maria_chk_message.txt "; - $com.= "> $tmp/maria_chk_diff.txt || true"; + $com= "diff $tmp/aria_chk_message.good.txt $tmp/aria_chk_message.txt "; + $com.= "> $tmp/aria_chk_diff.txt || true"; $res= `$com`; print MY_LOG $res; - if (-s "$tmp/maria_chk_diff.txt") + if (-s "$tmp/aria_chk_diff.txt") { - print MY_LOG "Differences in maria_chk -dvv, recovery not yet perfect !\n"; + print MY_LOG "Differences in aria_chk -dvv, recovery not yet perfect !\n"; print MY_LOG "========DIFF START=======\n"; - open(MY_FILE, "<$tmp/maria_chk_diff.txt") || die "Can't open file maria_chk_diff.txt\n"; + open(MY_FILE, "<$tmp/aria_chk_diff.txt") || die "Can't open file aria_chk_diff.txt\n"; while (<MY_FILE>) { print MY_LOG $_; @@ -346,13 +346,13 @@ sub apply_log print MY_LOG "bad argument '$shouldchangelog'\n"; return 1; } - foreach (<maria_log.*>) + foreach (<aria_log.*>) { $log_md5.= md5_conv($_); } print MY_LOG "applying log\n"; - my_exec("$maria_exe_path/maria_read_log$suffix -a > $tmp/maria_read_log_$table.txt"); - foreach (<maria_log.*>) + my_exec("$maria_exe_path/aria_read_log$suffix -a > $tmp/aria_read_log_$table.txt"); + foreach (<aria_log.*>) { $log_md5_2.= md5_conv($_); } @@ -360,13 +360,13 @@ sub apply_log { if ("$shouldchangelog" eq "shouldnotchangelog") { - print MY_LOG "maria_read_log should not have modified the log\n"; + print MY_LOG "aria_read_log should not have modified the log\n"; return 1; } } elsif ("$shouldchangelog" eq "shouldchangelog") { - print MY_LOG "maria_read_log should have modified the log\n"; + print MY_LOG "aria_read_log should have modified the log\n"; return 1; } } @@ -415,7 +415,7 @@ sub physical_cmp # save original tables to restore them later copy("$table.MAD", "$tmp/before_zerofill$table_no.MAD") || die(); copy("$table.MAI", "$tmp/before_zerofill$table_no.MAI") || die(); - $com= "$maria_exe_path/maria_chk$suffix -ss --zerofill-keep-lsn --skip-update-state $table"; + $com= "$maria_exe_path/aria_chk$suffix -ss --zerofill-keep-lsn --skip-update-state $table"; $res= `$com`; print MY_LOG $res; $table_no= $table_no + 1; @@ -467,7 +467,7 @@ $my_progname version $VER Description: -Run various maria recovery tests and print the results +Run various Aria recovery tests and print the results Options --help Show this help and exit. diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt index 04f13380512..5185aee4ed6 100644 --- a/storage/myisam/CMakeLists.txt +++ b/storage/myisam/CMakeLists.txt @@ -32,16 +32,16 @@ SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c MYSQL_STORAGE_ENGINE(MYISAM) IF(NOT SOURCE_SUBLIBS) - ADD_EXECUTABLE(myisam_ftdump myisam_ftdump.c) + MYSQL_ADD_EXECUTABLE(myisam_ftdump myisam_ftdump.c DESTINATION bin) TARGET_LINK_LIBRARIES(myisam_ftdump libmyisam_s mysys debug dbug strings zlib wsock32) - ADD_EXECUTABLE(myisamchk myisamchk.c) + MYSQL_ADD_EXECUTABLE(myisamchk myisamchk.c DESTINATION bin) TARGET_LINK_LIBRARIES(myisamchk libmyisam_s mysys debug dbug strings zlib wsock32) - ADD_EXECUTABLE(myisamlog myisamlog.c) + MYSQL_ADD_EXECUTABLE(myisamlog myisamlog.c DESTINATION bin) TARGET_LINK_LIBRARIES(myisamlog libmyisam_s mysys debug dbug strings zlib wsock32) - ADD_EXECUTABLE(myisampack myisampack.c) + MYSQL_ADD_EXECUTABLE(myisampack myisampack.c DESTINATION bin) TARGET_LINK_LIBRARIES(myisampack libmyisam_s mysys debug dbug strings zlib wsock32) ADD_EXECUTABLE(mi_test1 mi_test1.c) @@ -61,13 +61,4 @@ IF(NOT SOURCE_SUBLIBS) SET_TARGET_PROPERTIES(myisamchk myisampack PROPERTIES LINK_FLAGS "setargv.obj") - IF(EMBED_MANIFESTS) - MYSQL_EMBED_MANIFEST("myisam_ftdump" "asInvoker") - MYSQL_EMBED_MANIFEST("myisamchk" "asInvoker") - MYSQL_EMBED_MANIFEST("myisamlog" "asInvoker") - MYSQL_EMBED_MANIFEST("myisampack" "asInvoker") - ENDIF(EMBED_MANIFESTS) - - INSTALL(TARGETS myisam_ftdump myisamchk myisamlog myisampack DESTINATION bin COMPONENT runtime) - ENDIF(NOT SOURCE_SUBLIBS) diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index e15cc35f0f8..65d5c5ca44c 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -605,7 +605,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, uchar *query, sizeof(FTB_WORD *)*ftb->queue.elements); memcpy(ftb->list, ftb->queue.root+1, sizeof(FTB_WORD *)*ftb->queue.elements); my_qsort2(ftb->list, ftb->queue.elements, sizeof(FTB_WORD *), - (qsort2_cmp)FTB_WORD_cmp_list, ftb->charset); + (qsort2_cmp)FTB_WORD_cmp_list, (void*) ftb->charset); if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC; ftb->state=READY; return ftb; diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c index 1e1fd1382bf..545ccaabaf8 100644 --- a/storage/myisam/ft_parser.c +++ b/storage/myisam/ft_parser.c @@ -255,7 +255,8 @@ void ft_parse_init(TREE *wtree, CHARSET_INFO *cs) { DBUG_ENTER("ft_parse_init"); if (!is_tree_inited(wtree)) - init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,NULL, cs); + init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,NULL, + (void*) cs); DBUG_VOID_RETURN; } diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 2be71dadf4b..f0a6eb3ea39 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -93,14 +93,16 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type, if (!thd->vio_ok()) { - sql_print_error("%s", msgbuf); + sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf); return; } if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR | T_AUTO_REPAIR)) { - my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME)); + my_message(ER_NOT_KEYFILE, msgbuf, MYF(MY_WME)); + if (thd->variables.log_warnings > 2 && ! thd->log_all_errors) + sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf); return; } length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) - @@ -125,6 +127,9 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type, if (protocol->write()) sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n", msgbuf); + else if (thd->variables.log_warnings > 2) + sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf); + #ifdef THREAD if (param->need_print_msg_lock) pthread_mutex_unlock(¶m->print_msg_mutex); @@ -258,7 +263,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, record= table_arg->record[0]; recpos= 0; recinfo_pos= recinfo; - while (recpos < (uint) share->reclength) + while (recpos < (uint) share->stored_rec_length) { Field **field, *found= 0; minpos= share->reclength; @@ -523,6 +528,7 @@ void mi_check_print_info(HA_CHECK *param, const char *fmt,...) va_list args; va_start(args, fmt); mi_check_print_msg(param, "info", fmt, args); + param->note_printed= 1; va_end(args); } @@ -543,6 +549,7 @@ ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), file(0), int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | + HA_CAN_VIRTUAL_COLUMNS | HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY | HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS | HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS | @@ -783,8 +790,6 @@ int ha_myisam::close(void) int ha_myisam::write_row(uchar *buf) { - ha_statistic_increment(&SSV::ha_write_count); - /* If we have a timestamp column, update it to the current time */ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); @@ -818,7 +823,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) param.thd = thd; param.op_name = "check"; param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.testflag = check_opt->flags | T_CHECK | T_SILENT; param.stats_method= (enum_handler_stats_method)thd->variables.myisam_stats_method; @@ -911,7 +916,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) param.thd = thd; param.op_name= "analyze"; param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS | T_DONT_CHECK_CHECKSUM); param.using_global_keycache = 1; @@ -1075,7 +1080,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK); /* Ensure we don't loose any rows when retrying without quick */ param.testflag|= T_SAFE_REPAIR; - sql_print_information("Retrying repair of: '%s' without quick", + sql_print_information("Retrying repair of: '%s' including modifying data file", table->s->path.str); continue; } @@ -1137,7 +1142,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK ¶m, bool do_optimize) DBUG_ENTER("ha_myisam::repair"); param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.tmpfile_createflag = O_RDWR | O_TRUNC; param.using_global_keycache = 1; param.thd= thd; @@ -1684,16 +1689,19 @@ bool ha_myisam::check_and_repair(THD *thd) if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt)) { + bool save_log_all_errors; sql_print_warning("Recovering table: '%s'",table->s->path.str); - if (myisam_recover_options & (HA_RECOVER_FULL_BACKUP | HA_RECOVER_BACKUP)) + save_log_all_errors= thd->log_all_errors; + thd->log_all_errors|= (thd->variables.log_warnings > 2); + if (myisam_recover_options & HA_RECOVER_FULL_BACKUP) { char buff[MY_BACKUP_NAME_EXTRA_LENGTH+1]; my_create_backup_name(buff, "", check_opt.start_time); - sql_print_information("Making backup of data with extension '%s'", buff); - } - if (myisam_recover_options & HA_RECOVER_FULL_BACKUP) + sql_print_information("Making backup of index file with extension '%s'", + buff); mi_make_backup_of_index(file, check_opt.start_time, MYF(MY_WME | ME_JUST_WARNING)); + } check_opt.flags= (((myisam_recover_options & (HA_RECOVER_BACKUP | HA_RECOVER_FULL_BACKUP)) ? T_BACKUP_DATA : 0) | @@ -1702,6 +1710,7 @@ bool ha_myisam::check_and_repair(THD *thd) T_AUTO_REPAIR); if (repair(thd, &check_opt)) error=1; + thd->log_all_errors= save_log_all_errors; } thd->set_query(old_query, old_query_length); DBUG_RETURN(error); @@ -1715,7 +1724,6 @@ bool ha_myisam::is_crashed() const int ha_myisam::update_row(const uchar *old_data, uchar *new_data) { - ha_statistic_increment(&SSV::ha_update_count); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return mi_update(file,old_data,new_data); @@ -1723,7 +1731,6 @@ int ha_myisam::update_row(const uchar *old_data, uchar *new_data) int ha_myisam::delete_row(const uchar *buf) { - ha_statistic_increment(&SSV::ha_delete_count); return mi_delete(file,buf); } @@ -1731,84 +1738,48 @@ int ha_myisam::index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) { - DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_key_count); - int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag); - table->status=error ? STATUS_NOT_FOUND: 0; - return error; + return mi_rkey(file, buf, active_index, key, keypart_map, find_flag); } int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) { - ha_statistic_increment(&SSV::ha_read_key_count); - int error=mi_rkey(file, buf, index, key, keypart_map, find_flag); - table->status=error ? STATUS_NOT_FOUND: 0; - return error; -} - -int ha_myisam::index_read_last_map(uchar *buf, const uchar *key, - key_part_map keypart_map) -{ - DBUG_ENTER("ha_myisam::index_read_last"); - DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_key_count); - int error=mi_rkey(file, buf, active_index, key, keypart_map, - HA_READ_PREFIX_LAST); - table->status=error ? STATUS_NOT_FOUND: 0; - DBUG_RETURN(error); + return mi_rkey(file, buf, index, key, keypart_map, find_flag); } int ha_myisam::index_next(uchar *buf) { - DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_next_count); - int error=mi_rnext(file,buf,active_index); - table->status=error ? STATUS_NOT_FOUND: 0; - return error; + return mi_rnext(file,buf,active_index); } int ha_myisam::index_prev(uchar *buf) { - DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_prev_count); - int error=mi_rprev(file,buf, active_index); - table->status=error ? STATUS_NOT_FOUND: 0; - return error; + return mi_rprev(file,buf, active_index); } int ha_myisam::index_first(uchar *buf) { - DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_first_count); - int error=mi_rfirst(file, buf, active_index); - table->status=error ? STATUS_NOT_FOUND: 0; - return error; + return mi_rfirst(file, buf, active_index); } int ha_myisam::index_last(uchar *buf) { - DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_last_count); - int error=mi_rlast(file, buf, active_index); - table->status=error ? STATUS_NOT_FOUND: 0; - return error; + return mi_rlast(file, buf, active_index); } int ha_myisam::index_next_same(uchar *buf, const uchar *key __attribute__((unused)), uint length __attribute__((unused))) { + DBUG_ENTER("ha_myisam::index_next_same"); int error; - DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_next_count); do { error= mi_rnext_same(file,buf); } while (error == HA_ERR_RECORD_DELETED); - table->status=error ? STATUS_NOT_FOUND: 0; - return error; + DBUG_PRINT("return",("%i", error)); + DBUG_RETURN(error); } @@ -1821,10 +1792,7 @@ int ha_myisam::rnd_init(bool scan) int ha_myisam::rnd_next(uchar *buf) { - ha_statistic_increment(&SSV::ha_read_rnd_next_count); - int error=mi_scan(file, buf); - table->status=error ? STATUS_NOT_FOUND: 0; - return error; + return mi_scan(file, buf); } int ha_myisam::remember_rnd_pos() @@ -1840,10 +1808,7 @@ int ha_myisam::restart_rnd_next(uchar *buf) int ha_myisam::rnd_pos(uchar *buf, uchar *pos) { - ha_statistic_increment(&SSV::ha_read_rnd_count); - int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length)); - table->status=error ? STATUS_NOT_FOUND: 0; - return error; + return mi_rrnd(file, buf, my_get_ptr(pos,ref_length)); } void ha_myisam::position(const uchar *record) @@ -2144,8 +2109,6 @@ int ha_myisam::ft_read(uchar *buf) &LOCK_status); // why ? error=ft_handler->please->read_next(ft_handler,(char*) buf); - - table->status=error ? STATUS_NOT_FOUND: 0; return error; } @@ -2234,6 +2197,23 @@ mysql_declare_plugin(myisam) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(myisam) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &myisam_storage_engine, + "MyISAM", + "MySQL AB", + "Default engine as of MySQL 3.23 with great performance", + PLUGIN_LICENSE_GPL, + myisam_init, /* Plugin Init */ + NULL, /* Plugin Deinit */ + 0x0100, /* 1.0 */ + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +} +maria_declare_plugin_end; #ifdef HAVE_QUERY_CACHE diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index ea9db8f0f2b..3a3b5536a30 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -73,7 +73,6 @@ class ha_myisam: public handler int index_read_idx_map(uchar *buf, uint index, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag); - int index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map); int index_next(uchar * buf); int index_prev(uchar * buf); int index_first(uchar * buf); diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 35919a7bf36..36c79b3d12f 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -87,6 +87,8 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks, uint buffer_length); static ha_checksum mi_byte_checksum(const uchar *buf, uint length); static void set_data_file_type(MI_SORT_INFO *sort_info, MYISAM_SHARE *share); +static int replace_data_file(HA_CHECK *param, MI_INFO *info, + const char *name, File new_file); void myisamchk_init(HA_CHECK *param) { @@ -334,7 +336,8 @@ int chk_size(HA_CHECK *param, register MI_INFO *info) /* The following is needed if called externally (not from myisamchk) */ flush_key_blocks(info->s->key_cache, - info->s->kfile, FLUSH_FORCE_WRITE); + info->s->kfile, &info->s->dirty_part_map, + FLUSH_FORCE_WRITE); size= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE)); if ((skr=(my_off_t) info->state->key_file_length) != size) @@ -1329,7 +1332,7 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend) } if (param->testflag & T_INFO) { - if (param->warning_printed || param->error_printed) + if (param->warning_printed || param->error_printed || param->note_printed) puts(""); if (used != 0 && ! param->error_printed) { @@ -1460,6 +1463,7 @@ static int mi_drop_all_indexes(HA_CHECK *param, MI_INFO *info, my_bool force) */ DBUG_PRINT("repair", ("all disabled are empty: create missing")); error= flush_key_blocks(share->key_cache, share->kfile, + &share->dirty_part_map, FLUSH_FORCE_WRITE); goto end; } @@ -1474,6 +1478,7 @@ static int mi_drop_all_indexes(HA_CHECK *param, MI_INFO *info, my_bool force) /* Remove all key blocks of this index file from key cache. */ if ((error= flush_key_blocks(share->key_cache, share->kfile, + &share->dirty_part_map, FLUSH_IGNORE_CHANGED))) goto end; /* purecov: inspected */ @@ -1520,6 +1525,8 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info, got_error=1; new_file= -1; sort_param.sort_info=&sort_info; + param->retry_repair= 0; + param->warning_printed= param->error_printed= param->note_printed= 0; if (!(param->testflag & T_SILENT)) { @@ -1535,7 +1542,7 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info, if (!param->using_global_keycache) VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size, - (size_t) param->use_buffers, 0, 0)); + (size_t) param->use_buffers, 0, 0, 0)); if (init_io_cache(¶m->read_cache,info->dfile, (uint) param->read_buffer_length, @@ -1664,7 +1671,7 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info, if (rep_quick && del+sort_info.dupp != info->state->del) { mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records"); - mi_check_print_error(param,"Run recovery again without -q"); + mi_check_print_error(param,"Run recovery again without --quick"); got_error=1; param->retry_repair=1; param->testflag|=T_RETRY_WITHOUT_QUICK; @@ -1716,17 +1723,8 @@ err: /* Replace the actual file with the temporary file */ if (new_file >= 0) { - my_close(new_file,MYF(0)); - info->dfile=new_file= -1; - if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, - DATA_TMP_EXT, - param->backup_time, - share->base.raid_chunks, - (param->testflag & T_BACKUP_DATA ? - MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info,share,name,-1)) - got_error=1; - + got_error= replace_data_file(param, info, name, new_file); + new_file= -1; param->retry_repair= 0; } } @@ -1752,7 +1750,8 @@ err: VOID(end_io_cache(¶m->read_cache)); info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); VOID(end_io_cache(&info->rec_cache)); - got_error|=flush_blocks(param, share->key_cache, share->kfile); + got_error|=flush_blocks(param, share->key_cache, share->kfile, + &share->dirty_part_map); if (!got_error && param->testflag & T_UNPACK) { share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD; @@ -1898,11 +1897,12 @@ void lock_memory(HA_CHECK *param __attribute__((unused))) /* Flush all changed blocks to disk */ -int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file) +int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file, + ulonglong *dirty_part_map) { - if (flush_key_blocks(key_cache, file, FLUSH_RELEASE)) + if (flush_key_blocks(key_cache, file, dirty_part_map, FLUSH_RELEASE)) { - mi_check_print_error(param,"%d when trying to write bufferts",my_errno); + mi_check_print_error(param,"%d when trying to write buffers",my_errno); return(1); } if (!param->using_global_keycache) @@ -1967,7 +1967,8 @@ int mi_sort_index(HA_CHECK *param, register MI_INFO *info, char * name) } /* Flush key cache for this file if we are calling this outside myisamchk */ - flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); + flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map, + FLUSH_IGNORE_CHANGED); share->state.version=(ulong) time((time_t*) 0); old_state= share->state; /* save state if not stored */ @@ -2215,7 +2216,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, MYISAM_SHARE *share=info->s; HA_KEYSEG *keyseg; ulong *rec_per_key_part; - char llbuff[22]; + char llbuff[22], llbuff2[22]; MI_SORT_INFO sort_info; ulonglong UNINIT_VAR(key_map); DBUG_ENTER("mi_repair_by_sort"); @@ -2231,12 +2232,15 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, printf("Data records: %s\n", llstr(start_records,llbuff)); } param->testflag|=T_REP; /* for easy checking */ + param->retry_repair= 0; + param->warning_printed= param->error_printed= param->note_printed= 0; if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) param->testflag|=T_CALC_CHECKSUM; bzero((char*)&sort_info,sizeof(sort_info)); bzero((char *)&sort_param, sizeof(sort_param)); + if (!(sort_info.key_block= alloc_key_blocks(param, (uint) param->sort_key_blocks, @@ -2248,7 +2252,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, init_io_cache(&info->rec_cache,info->dfile, (uint) param->write_buffer_length, WRITE_CACHE,new_header_length,1, - MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw))) + MYF((param->myf_rw & MY_WAIT_IF_FULL) | MY_WME)))) goto err; sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks; info->opt_flag|=WRITE_CACHE_USED; @@ -2420,7 +2424,10 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, (my_bool) (!(param->testflag & T_VERBOSE)), (uint) param->sort_buffer_length)) { - param->retry_repair=1; + param->retry_repair= 1; + if (! param->error_printed) + mi_check_print_error(param, "Couldn't fix table with create_index_by_sort(). Error: %d", + my_errno); goto err; } /* No need to calculate checksum again. */ @@ -2449,7 +2456,10 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, /* Don't repair if we loosed more than one row */ if (info->state->records+1 < start_records) { - info->state->records=start_records; + mi_check_print_error(param, + "Couldn't fix table as SAFE_REPAIR was requested and we would loose too many rows. %s -> %s", + llstr(start_records, llbuff), llstr(info->state->records, llbuff2)); + info->state->records= start_records; goto err; } } @@ -2479,7 +2489,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, if (rep_quick && del+sort_info.dupp != info->state->del) { mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records"); - mi_check_print_error(param,"Run recovery again without -q"); + mi_check_print_error(param,"Run recovery again without --quick"); got_error=1; param->retry_repair=1; param->testflag|=T_RETRY_WITHOUT_QUICK; @@ -2525,22 +2535,16 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, memcpy( &share->state.state, info->state, sizeof(*info->state)); err: - got_error|= flush_blocks(param, share->key_cache, share->kfile); + got_error|= flush_blocks(param, share->key_cache, share->kfile, + &share->dirty_part_map); VOID(end_io_cache(&info->rec_cache)); if (!got_error) { /* Replace the actual file with the temporary file */ if (new_file >= 0) { - my_close(new_file,MYF(0)); - info->dfile=new_file= -1; - if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, - DATA_TMP_EXT, param->backup_time, - share->base.raid_chunks, - (param->testflag & T_BACKUP_DATA ? - MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info,share,name,-1)) - got_error=1; + got_error= replace_data_file(param, info, name, new_file); + new_file= -1; } } if (got_error) @@ -2557,6 +2561,8 @@ err: param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); + if (killed_ptr(param)) + param->retry_repair= 0; /* No use to retry repair */ } else if (key_map == share->state.key_map) share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS; @@ -2657,6 +2663,9 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info, printf("Data records: %s\n", llstr(start_records,llbuff)); } param->testflag|=T_REP; /* for easy checking */ + param->retry_repair= 0; + param->warning_printed= 0; + param->error_printed= 0; if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) param->testflag|=T_CALC_CHECKSUM; @@ -3050,7 +3059,8 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info, memcpy(&share->state.state, info->state, sizeof(*info->state)); err: - got_error|= flush_blocks(param, share->key_cache, share->kfile); + got_error|= flush_blocks(param, share->key_cache, share->kfile, + &share->dirty_part_map); /* Destroy the write cache. The master thread did already detach from the share by remove_io_thread() or it was not yet started (if the @@ -3070,15 +3080,8 @@ err: /* Replace the actual file with the temporary file */ if (new_file >= 0) { - my_close(new_file,MYF(0)); - info->dfile=new_file= -1; - if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, - DATA_TMP_EXT, param->backup_time, - share->base.raid_chunks, - (param->testflag & T_BACKUP_DATA ? - MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info,share,name,-1)) - got_error=1; + got_error= replace_data_file(param, info, name, new_file); + new_file= -1; } } if (got_error) @@ -3095,6 +3098,8 @@ err: param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); + if (killed_ptr(param)) + param->retry_repair= 0; } else if (key_map == share->state.key_map) share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS; @@ -3130,7 +3135,13 @@ static int sort_key_read(MI_SORT_PARAM *sort_param, void *key) DBUG_ENTER("sort_key_read"); if ((error=sort_get_next_record(sort_param))) + { + DBUG_ASSERT(error < 0 || + sort_info->param->error_printed || + sort_info->param->warning_printed || + sort_info->param->note_printed); DBUG_RETURN(error); + } if (info->state->records == sort_info->max_records) { mi_check_print_error(sort_info->param, @@ -3247,7 +3258,12 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) DBUG_ENTER("sort_get_next_record"); if (killed_ptr(param)) + { + mi_check_print_error(param, "Repair killed by user with cause: %d", + (int) killed_ptr(param)); + param->retry_repair= 0; DBUG_RETURN(1); + } switch (share->data_file_type) { case BLOCK_RECORD: @@ -3336,6 +3352,8 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) } if (searching && ! sort_param->fix_datafile) { + mi_check_print_info(param, + "Datafile is corrupted; Restart repair with option to copy datafile"); param->error_printed=1; param->retry_repair=1; param->testflag|=T_RETRY_WITHOUT_QUICK; @@ -3397,6 +3415,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) } if (error) { + DBUG_ASSERT(param->note_printed); if (found_record) goto try_next; searching=1; @@ -3437,7 +3456,11 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) share->state.split++; } if (found_record) + { + mi_check_print_info(param, + "Found row block followed by deleted block"); goto try_next; + } if (searching) { pos+=MI_DYN_ALIGN_SIZE; @@ -3471,6 +3494,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) mi_check_print_error(param,"Not enough memory for blob at %s (need %lu)", llstr(sort_param->start_recpos,llbuff), (ulong) block_info.rec_len); + DBUG_ASSERT(param->error_printed); DBUG_RETURN(1); } else @@ -3552,8 +3576,6 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) if (_mi_rec_unpack(info,sort_param->record,sort_param->rec_buff, sort_param->find_length) != MY_FILE_ERROR) { - if (sort_param->read_cache.error < 0) - DBUG_RETURN(1); if (sort_param->calc_checksum) info->checksum= (*info->s->calc_check_checksum)(info, sort_param->record); @@ -3579,6 +3601,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) sort_param->key+1, llstr(sort_param->start_recpos,llbuff)); try_next: + DBUG_ASSERT(param->error_printed || param->note_printed); pos=(sort_param->start_recpos+=MI_DYN_ALIGN_SIZE); searching=1; } @@ -3647,6 +3670,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) DBUG_RETURN(0); } } + DBUG_ASSERT(0); /* Impossible */ DBUG_RETURN(1); /* Impossible */ } @@ -3708,7 +3732,7 @@ int sort_write_record(MI_SORT_PARAM *sort_param) if (sort_info->buff_length < reclength) { if (!(sort_info->buff=my_realloc(sort_info->buff, (uint) reclength, - MYF(MY_FREE_ON_ERROR | + MYF(MY_FREE_ON_ERROR | MY_WME | MY_ALLOW_ZERO_PTR)))) DBUG_RETURN(1); sort_info->buff_length=reclength; @@ -4743,3 +4767,29 @@ int mi_make_backup_of_index(MI_INFO *info, time_t backup_time, myf flags) my_create_backup_name(backup_name, info->s->index_file_name, backup_time); return my_copy(info->s->index_file_name, backup_name, flags); } + +static int replace_data_file(HA_CHECK *param, MI_INFO *info, + const char *name, File new_file) +{ + MYISAM_SHARE *share=info->s; + + my_close(new_file,MYF(0)); + info->dfile= -1; + if (param->testflag & T_BACKUP_DATA) + { + char buff[MY_BACKUP_NAME_EXTRA_LENGTH+1]; + my_create_backup_name(buff, "", param->backup_time); + my_printf_error(0, /* No error, just info */ + "Making backup of data file with extension '%s'", + MYF(ME_JUST_INFO | ME_NOREFRESH), buff); + } + + if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, + DATA_TMP_EXT, param->backup_time, + share->base.raid_chunks, + (param->testflag & T_BACKUP_DATA ? + MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || + mi_open_datafile(info, share, name, -1)) + return 1; + return 0; +} diff --git a/storage/myisam/mi_close.c b/storage/myisam/mi_close.c index d3888417fbd..c6e6289ffe1 100644 --- a/storage/myisam/mi_close.c +++ b/storage/myisam/mi_close.c @@ -67,6 +67,7 @@ int mi_close(register MI_INFO *info) if (share->kfile >= 0) DBUG_ABORT();); if (share->kfile >= 0 && flush_key_blocks(share->key_cache, share->kfile, + &share->dirty_part_map, ((share->temporary || share->deleting) ? FLUSH_IGNORE_CHANGED : FLUSH_RELEASE))) diff --git a/storage/myisam/mi_dbug.c b/storage/myisam/mi_dbug.c index f04f89eff9a..c942d17218d 100644 --- a/storage/myisam/mi_dbug.c +++ b/storage/myisam/mi_dbug.c @@ -121,7 +121,7 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg, case HA_KEYTYPE_LONGLONG: { char buff[21]; - longlong2str(mi_sint8korr(key),buff,-10); + longlong10_to_str(mi_sint8korr(key),buff,-10); VOID(fprintf(stream,"%s",buff)); key=end; break; @@ -129,7 +129,7 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg, case HA_KEYTYPE_ULONGLONG: { char buff[21]; - longlong2str(mi_sint8korr(key),buff,10); + longlong10_to_str(mi_sint8korr(key),buff,10); VOID(fprintf(stream,"%s",buff)); key=end; break; diff --git a/storage/myisam/mi_delete_all.c b/storage/myisam/mi_delete_all.c index 47e5f3246da..3c5e0638334 100644 --- a/storage/myisam/mi_delete_all.c +++ b/storage/myisam/mi_delete_all.c @@ -54,7 +54,8 @@ int mi_delete_all_rows(MI_INFO *info) If we are using delayed keys or if the user has done changes to the tables since it was locked then there may be key blocks in the key cache */ - flush_key_blocks(share->key_cache, share->kfile, FLUSH_IGNORE_CHANGED); + flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map, + FLUSH_IGNORE_CHANGED); #ifdef HAVE_MMAP if (share->file_map) mi_munmap_file(info); diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c index c36c0b9377f..d6dddeb9ed7 100644 --- a/storage/myisam/mi_extra.c +++ b/storage/myisam/mi_extra.c @@ -270,6 +270,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) pthread_mutex_lock(&share->intern_lock); /* Flush pages that we don't need anymore */ if (flush_key_blocks(share->key_cache, share->kfile, + &share->dirty_part_map, (function == HA_EXTRA_PREPARE_FOR_DROP ? FLUSH_IGNORE_CHANGED : FLUSH_RELEASE))) { @@ -328,7 +329,8 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) break; case HA_EXTRA_FLUSH: if (!share->temporary) - flush_key_blocks(share->key_cache, share->kfile, FLUSH_KEEP); + flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map, + FLUSH_KEEP); #ifdef HAVE_PWRITE _mi_decrement_open_count(info); #endif diff --git a/storage/myisam/mi_keycache.c b/storage/myisam/mi_keycache.c index 5cf3fede1ae..be0cdc470f1 100644 --- a/storage/myisam/mi_keycache.c +++ b/storage/myisam/mi_keycache.c @@ -75,7 +75,8 @@ int mi_assign_to_key_cache(MI_INFO *info, in the old key cache. */ - if (flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE)) + if (flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map, + FLUSH_RELEASE)) { error= my_errno; mi_print_error(info->s, HA_ERR_CRASHED); @@ -90,7 +91,8 @@ int mi_assign_to_key_cache(MI_INFO *info, (This can never fail as there is never any not written data in the new key cache) */ - (void) flush_key_blocks(key_cache, share->kfile, FLUSH_RELEASE); + (void) flush_key_blocks(key_cache, share->kfile, &share->dirty_part_map, + FLUSH_RELEASE); /* ensure that setting the key cache and changing the multi_key_cache @@ -102,6 +104,7 @@ int mi_assign_to_key_cache(MI_INFO *info, This should be seen at the lastes for the next call to an myisam function. */ share->key_cache= key_cache; + share->dirty_part_map= 0; /* store the key cache in the global hash structure for future opens */ if (multi_key_cache_set((uchar*) share->unique_file_name, diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index cbc341c0c49..06eed31847b 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -71,7 +71,9 @@ int mi_lock_database(MI_INFO *info, int lock_type) --share->tot_locks; if (info->lock_type == F_WRLCK && !share->w_locks && !share->delay_key_write && flush_key_blocks(share->key_cache, - share->kfile,FLUSH_KEEP)) + share->kfile, + &share->dirty_part_map, + FLUSH_KEEP)) { error=my_errno; mi_print_error(info->s, HA_ERR_CRASHED); @@ -553,7 +555,8 @@ int _mi_test_if_changed(register MI_INFO *info) { /* Keyfile has changed */ DBUG_PRINT("info",("index file changed")); if (share->state.process != share->this_process) - VOID(flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE)); + VOID(flush_key_blocks(share->key_cache, share->kfile, + &share->dirty_part_map, FLUSH_RELEASE)); share->last_process=share->state.process; info->last_unique= share->state.unique; info->last_loop= share->state.update_count; diff --git a/storage/myisam/mi_page.c b/storage/myisam/mi_page.c index 6b878e11567..d458437337c 100644 --- a/storage/myisam/mi_page.c +++ b/storage/myisam/mi_page.c @@ -89,10 +89,11 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo, info->state->key_file_length != page+length) length= ((mi_getint(buff)+IO_SIZE-1) & (uint) ~(IO_SIZE-1)); DBUG_RETURN((key_cache_write(info->s->key_cache, - info->s->kfile,page, level, (uchar*) buff,length, - (uint) keyinfo->block_length, - (int) ((info->lock_type != F_UNLCK) || - info->s->delay_key_write)))); + info->s->kfile, &info->s->dirty_part_map, + page, level, (uchar*) buff, length, + (uint) keyinfo->block_length, + (int) ((info->lock_type != F_UNLCK) || + info->s->delay_key_write)))); } /* mi_write_keypage */ @@ -111,7 +112,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos, mi_sizestore(buff,old_link); info->s->state.changed|= STATE_NOT_SORTED_PAGES; DBUG_RETURN(key_cache_write(info->s->key_cache, - info->s->kfile, pos , level, buff, + info->s->kfile, &info->s->dirty_part_map, + pos , level, buff, sizeof(buff), (uint) keyinfo->block_length, (int) (info->lock_type != F_UNLCK))); diff --git a/storage/myisam/mi_panic.c b/storage/myisam/mi_panic.c index b270712ba2d..99aef372027 100644 --- a/storage/myisam/mi_panic.c +++ b/storage/myisam/mi_panic.c @@ -47,7 +47,8 @@ int mi_panic(enum ha_panic_function flag) if (info->s->options & HA_OPTION_READ_ONLY_DATA) break; #endif - if (flush_key_blocks(info->s->key_cache, info->s->kfile, FLUSH_RELEASE)) + if (flush_key_blocks(info->s->key_cache, info->s->kfile, + &info->s->dirty_part_map, FLUSH_RELEASE)) error=my_errno; if (info->opt_flag & WRITE_CACHE_USED) if (flush_io_cache(&info->rec_cache)) diff --git a/storage/myisam/mi_preload.c b/storage/myisam/mi_preload.c index cb8d2984921..a2d751a709c 100644 --- a/storage/myisam/mi_preload.c +++ b/storage/myisam/mi_preload.c @@ -68,7 +68,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) } } else - block_length= share->key_cache->key_cache_block_size; + block_length= share->key_cache->param_block_size; length= info->preload_buff_size/block_length * block_length; set_if_bigger(length, block_length); @@ -76,7 +76,8 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME)))) DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM); - if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_RELEASE)) + if (flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map, + FLUSH_RELEASE)) goto err; do diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c index 52fd7b30aab..153064cb360 100644 --- a/storage/myisam/mi_search.c +++ b/storage/myisam/mi_search.c @@ -302,7 +302,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, uint UNINIT_VAR(prefix_len), suffix_len; int key_len_skip, UNINIT_VAR(seg_len_pack), key_len_left; uchar *end, *kseg, *vseg; - uchar *sort_order=keyinfo->seg->charset->sort_order; + const uchar *sort_order= keyinfo->seg->charset->sort_order; uchar tt_buff[HA_MAX_KEY_BUFF+2], *t_buff=tt_buff+2; uchar *UNINIT_VAR(saved_from), *UNINIT_VAR(saved_to); uchar *UNINIT_VAR(saved_vseg); @@ -1469,7 +1469,8 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, int length; uint key_length,ref_length,org_key_length=0, length_pack,new_key_length,diff_flag,pack_marker; - uchar *start,*end,*key_end,*sort_order; + uchar *start,*end,*key_end; + const uchar *sort_order; my_bool same_length; length_pack=s_temp->ref_length=s_temp->n_ref_length=s_temp->n_length=0; diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c index 4389cf0e8a5..c93cdc6fe21 100644 --- a/storage/myisam/mi_test1.c +++ b/storage/myisam/mi_test1.c @@ -52,7 +52,8 @@ int main(int argc,char *argv[]) MY_INIT(argv[0]); my_init(); if (key_cacheing) - init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,IO_SIZE*16,0,0); + init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,IO_SIZE*16,0,0, + DEFAULT_KEY_CACHE_PARTITIONS); get_options(argc,argv); exit(run_test("test1")); diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c index 90d23cbf73e..24fbdc57bbb 100644 --- a/storage/myisam/mi_test2.c +++ b/storage/myisam/mi_test2.c @@ -217,7 +217,8 @@ int main(int argc, char *argv[]) if (!silent) printf("- Writing key:s\n"); if (key_cacheing) - init_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size,0,0); + init_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size,0,0, + DEFAULT_KEY_CACHE_PARTITIONS); if (do_locking) mi_lock_database(file,F_WRLCK); if (write_cacheing) @@ -813,6 +814,8 @@ end: mi_panic(HA_PANIC_CLOSE); /* Should close log */ if (!silent) { + KEY_CACHE_STATISTICS stats; + printf("\nFollowing test have been made:\n"); printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete); if (rec_pointer_size) @@ -835,6 +838,8 @@ end: puts("Locking used"); if (use_blob) puts("blobs used"); + bzero(&stats, sizeof(stats)); + get_key_cache_statistics(dflt_key_cache, 0, &stats); printf("key cache status: \n\ blocks used:%10lu\n\ not flushed:%10lu\n\ @@ -842,12 +847,12 @@ w_requests: %10lu\n\ writes: %10lu\n\ r_requests: %10lu\n\ reads: %10lu\n", - dflt_key_cache->blocks_used, - dflt_key_cache->global_blocks_changed, - (ulong) dflt_key_cache->global_cache_w_requests, - (ulong) dflt_key_cache->global_cache_write, - (ulong) dflt_key_cache->global_cache_r_requests, - (ulong) dflt_key_cache->global_cache_read); + (ulong) stats.blocks_used, + (ulong) stats.blocks_changed, + (ulong) stats.write_requests, + (ulong) stats.writes, + (ulong) stats.read_requests, + (ulong) stats.reads); } end_key_cache(dflt_key_cache,1); if (blob_buffer) diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c index e792612a313..e4527bf441d 100644 --- a/storage/myisam/mi_test3.c +++ b/storage/myisam/mi_test3.c @@ -177,7 +177,8 @@ void start_test(int id) exit(1); } if (key_cacheing && rnd(2) == 0) - init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0); + init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0, + DEFAULT_KEY_CACHE_PARTITIONS); printf("Process %d, pid: %ld\n", id, (long) getpid()); fflush(stdout); diff --git a/storage/myisam/myisam_ftdump.c b/storage/myisam/myisam_ftdump.c index 80f49ea686b..039d04058e4 100644 --- a/storage/myisam/myisam_ftdump.c +++ b/storage/myisam/myisam_ftdump.c @@ -85,7 +85,7 @@ int main(int argc,char *argv[]) usage(); } - init_key_cache(dflt_key_cache,MI_KEY_BLOCK_LENGTH,USE_BUFFER_INIT, 0, 0); + init_key_cache(dflt_key_cache,MI_KEY_BLOCK_LENGTH,USE_BUFFER_INIT, 0, 0, 0); if (!(info=mi_open(argv[0], O_RDONLY, HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER))) diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 918efa61e5e..6277bd1b7de 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -1104,7 +1104,7 @@ static int myisamchk(HA_CHECK *param, char * filename) { if (param->testflag & (T_EXTEND | T_MEDIUM)) VOID(init_key_cache(dflt_key_cache,opt_key_cache_block_size, - (size_t) param->use_buffers, 0, 0)); + (size_t) param->use_buffers, 0, 0, 0)); VOID(init_io_cache(¶m->read_cache,datafile, (uint) param->read_buffer_length, READ_CACHE, @@ -1118,7 +1118,8 @@ static int myisamchk(HA_CHECK *param, char * filename) HA_OPTION_COMPRESS_RECORD)) || (param->testflag & (T_EXTEND | T_MEDIUM))) error|=chk_data_link(param, info, test(param->testflag & T_EXTEND)); - error|=flush_blocks(param, share->key_cache, share->kfile); + error|=flush_blocks(param, share->key_cache, share->kfile, + &share->dirty_part_map); VOID(end_io_cache(¶m->read_cache)); } if (!error) @@ -1313,7 +1314,7 @@ static void descript(HA_CHECK *param, register MI_INFO *info, char * name) printf("Recordlength: %13d\n",(int) share->base.pack_reclength); if (! mi_is_all_keys_active(share->state.key_map, share->base.keys)) { - longlong2str(share->state.key_map,buff,2); + longlong2str(share->state.key_map,buff,2,1); printf("Using only keys '%s' of %d possibly keys\n", buff, share->base.keys); } @@ -1526,7 +1527,7 @@ static int mi_sort_records(HA_CHECK *param, DBUG_RETURN(0); /* Nothing to do */ init_key_cache(dflt_key_cache, opt_key_cache_block_size, - (size_t) param->use_buffers, 0, 0); + (size_t) param->use_buffers, 0, 0, 0); if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length, WRITE_CACHE,share->pack.header_length,1, MYF(MY_WME | MY_WAIT_IF_FULL))) @@ -1641,8 +1642,8 @@ err: my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR)); sort_info.buff=0; share->state.sortkey=sort_key; - DBUG_RETURN(flush_blocks(param, share->key_cache, share->kfile) | - got_error); + DBUG_RETURN(flush_blocks(param, share->key_cache, share->kfile, + &share->dirty_part_map) | got_error); } /* sort_records */ @@ -1758,6 +1759,7 @@ void mi_check_print_info(HA_CHECK *param __attribute__((unused)), { va_list args; + param->note_printed=1; va_start(args,fmt); VOID(vfprintf(stdout, fmt, args)); VOID(fputc('\n',stdout)); diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index 7515d81218b..84d133566f9 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -176,6 +176,8 @@ typedef struct st_mi_isam_share *index_file_name; uchar *file_map; /* mem-map of file if possible */ KEY_CACHE *key_cache; /* ref to the current key cache */ + /* To mark the key cache partitions containing dirty pages for this file */ + ulonglong dirty_part_map; MI_DECODE_TREE *decode_trees; uint16 *decode_tables; /* Function to use for a row checksum. */ @@ -734,7 +736,8 @@ void mi_check_print_info _VARARGS((HA_CHECK *param, const char *fmt, ...)); #ifdef THREAD pthread_handler_t thr_find_all_keys(void *arg); #endif -int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file); +int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file, + ulonglong *dirty_part_map); #ifdef __cplusplus } #endif diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c index a03d9a5f0e0..095a0347753 100644 --- a/storage/myisam/myisamlog.c +++ b/storage/myisam/myisamlog.c @@ -335,7 +335,7 @@ static int examine_log(char * file_name, char **table_names) init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1, (tree_element_free) file_info_free, NULL); VOID(init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE, - 0, 0)); + 0, 0, 0)); files_open=0; access_time=0; while (access_time++ != number_of_commands && diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index 6a47b3717c7..b67f77654ad 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -153,6 +153,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, { mi_check_print_error(info->sort_info->param, "myisam_sort_buffer_size is too small"); + my_errno= ENOMEM; goto err; } } @@ -177,7 +178,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, if (memavl < MIN_SORT_BUFFER) { mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */ - goto err; /* purecov: tested */ + my_errno= ENOMEM; /* purecov: tested */ + goto err; /* purecov: tested */ } (*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */ diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 28e2a87e3c5..274ba2fcd81 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -1057,9 +1057,9 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd, /* When MERGE table is open, but not yet attached, other threads - could flush it, which means call mysql_lock_abort_for_thread() + could flush it, which means calling mysql_lock_abort_for_thread() on this threads TABLE. 'children_attached' is FALSE in this - situaton. Since the table is not locked, return no lock data. + situation. Since the table is not locked, return no lock data. */ if (!this->file->children_attached) goto end; /* purecov: tested */ @@ -1326,3 +1326,20 @@ mysql_declare_plugin(myisammrg) NULL /* config options */ } mysql_declare_plugin_end; +maria_declare_plugin(myisammrg) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &myisammrg_storage_engine, + "MRG_MYISAM", + "MySQL AB", + "Collection of identical MyISAM tables", + PLUGIN_LICENSE_GPL, + myisammrg_init, /* Plugin Init */ + NULL, /* Plugin Deinit */ + 0x0100, /* 1.0 */ + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/mysql_storage_engine.cmake b/storage/mysql_storage_engine.cmake index 8c4f1ac8c4f..cbe9a310d67 100644 --- a/storage/mysql_storage_engine.cmake +++ b/storage/mysql_storage_engine.cmake @@ -29,7 +29,7 @@ MACRO(MYSQL_PLUGIN engine) IF(NOT SOURCE_SUBLIBS) # Add common include directories - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include) STRING(TOUPPER ${engine} engine) IF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC") ADD_LIBRARY(${${engine}_LIB} ${${engine}_SOURCES}) @@ -40,13 +40,14 @@ IF(NOT SOURCE_SUBLIBS) MESSAGE("build ${engine} as static library (${${engine}_LIB}.lib)") ELSEIF(${ENGINE_BUILD_TYPE} STREQUAL "DYNAMIC") ADD_DEFINITIONS(-DMYSQL_DYNAMIC_PLUGIN) - ADD_LIBRARY(${${engine}_LIB} SHARED ${${engine}_SOURCES}) - TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqld) + ADD_VERSION_INFO(${${engine}_LIB} SHARED ${engine}_SOURCES) + ADD_LIBRARY(${${engine}_LIB} MODULE ${${engine}_SOURCES}) + TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqlservices mysqld) IF(${engine}_LIBS) TARGET_LINK_LIBRARIES(${${engine}_LIB} ${${engine}_LIBS}) ENDIF(${engine}_LIBS) # Install the plugin - INSTALL(TARGETS ${${engine}_LIB} DESTINATION lib/plugin COMPONENT runtime) + MYSQL_INSTALL_TARGETS(${${engine}_LIB} DESTINATION lib/plugin COMPONENT Server) MESSAGE("build ${engine} as DLL (${${engine}_LIB}.dll)") ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC") ENDIF(NOT SOURCE_SUBLIBS) @@ -56,7 +57,7 @@ MACRO(MYSQL_STORAGE_ENGINE engine) IF(NOT SOURCE_SUBLIBS) MYSQL_PLUGIN(${engine}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/sql - ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/regex ${CMAKE_BINARY_DIR}/sql ${CMAKE_SOURCE_DIR}/extra/yassl/include) IF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC") ADD_DEFINITIONS(-DWITH_${engine}_STORAGE_ENGINE -DMYSQL_SERVER) diff --git a/storage/ndb/include/kernel/signaldata/FsOpenReq.hpp b/storage/ndb/include/kernel/signaldata/FsOpenReq.hpp index 8126267f946..95dbf5204f1 100644 --- a/storage/ndb/include/kernel/signaldata/FsOpenReq.hpp +++ b/storage/ndb/include/kernel/signaldata/FsOpenReq.hpp @@ -203,7 +203,7 @@ Uint32 FsOpenReq::getVersion(const Uint32 fileNumber[]){ inline void FsOpenReq::setVersion(Uint32 fileNumber[], Uint8 val){ const Uint32 t = fileNumber[3]; - fileNumber[3] = t & 0x00FFFFFF | (((Uint32)val) << 24); + fileNumber[3] = (t & 0x00FFFFFF) | (((Uint32)val) << 24); } inline @@ -214,7 +214,7 @@ Uint32 FsOpenReq::getSuffix(const Uint32 fileNumber[]){ inline void FsOpenReq::setSuffix(Uint32 fileNumber[], Uint8 val){ const Uint32 t = fileNumber[3]; - fileNumber[3] = t & 0xFF00FFFF | (((Uint32)val) << 16); + fileNumber[3] = (t & 0xFF00FFFF) | (((Uint32)val) << 16); } inline @@ -225,7 +225,7 @@ Uint32 FsOpenReq::v1_getDisk(const Uint32 fileNumber[]){ inline void FsOpenReq::v1_setDisk(Uint32 fileNumber[], Uint8 val){ const Uint32 t = fileNumber[3]; - fileNumber[3] = t & 0xFFFF00FF | (((Uint32)val) << 8); + fileNumber[3] = (t & 0xFFFF00FF) | (((Uint32)val) << 8); } inline @@ -266,7 +266,7 @@ Uint32 FsOpenReq::v1_getP(const Uint32 fileNumber[]){ inline void FsOpenReq::v1_setP(Uint32 fileNumber[], Uint8 val){ const Uint32 t = fileNumber[3]; - fileNumber[3] = t & 0xFFFFFF00 | val; + fileNumber[3] = (t & 0xFFFFFF00) | val; } /****************/ diff --git a/storage/ndb/include/ndbapi/NdbDictionary.hpp b/storage/ndb/include/ndbapi/NdbDictionary.hpp index 0e782ba9214..8a23802e797 100644 --- a/storage/ndb/include/ndbapi/NdbDictionary.hpp +++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp @@ -20,7 +20,7 @@ class Ndb; struct charset_info_st; -typedef struct charset_info_st CHARSET_INFO; +typedef const struct charset_info_st CHARSET_INFO; /** * @class NdbDictionary diff --git a/storage/ndb/include/ndbapi/NdbError.hpp b/storage/ndb/include/ndbapi/NdbError.hpp index aa27caf78f9..b752e578bc1 100644 --- a/storage/ndb/include/ndbapi/NdbError.hpp +++ b/storage/ndb/include/ndbapi/NdbError.hpp @@ -66,7 +66,7 @@ struct NdbError { /** * The error code indicates a permanent error.<br> - * (Includes classificatons: NdbError::PermanentError, + * (Includes classifications: NdbError::PermanentError, * NdbError::ApplicationError, NdbError::NoDataFound, * NdbError::ConstraintViolation, NdbError::SchemaError, * NdbError::UserDefinedError, NdbError::InternalError, and, diff --git a/storage/ndb/include/util/File.hpp b/storage/ndb/include/util/File.hpp index b9d348683ec..bbddc24583a 100644 --- a/storage/ndb/include/util/File.hpp +++ b/storage/ndb/include/util/File.hpp @@ -31,7 +31,7 @@ public: * Returns time for last contents modification of a file. * * @param aFileName a filename to check. - * @return the time for last contents modificaton of the file. + * @return the time for last contents modification of the file. */ static time_t mtime(const char* aFileName); diff --git a/storage/ndb/include/util/NdbSqlUtil.hpp b/storage/ndb/include/util/NdbSqlUtil.hpp index 8d063f1908b..77bb79aca82 100644 --- a/storage/ndb/include/util/NdbSqlUtil.hpp +++ b/storage/ndb/include/util/NdbSqlUtil.hpp @@ -20,7 +20,6 @@ #include <kernel/ndb_limits.h> struct charset_info_st; -typedef struct charset_info_st CHARSET_INFO; class NdbSqlUtil { public: diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 8c096681b58..e25c15d50a0 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -2253,7 +2253,7 @@ int Dbtup::interpreterNextLab(Signal* signal, if(AttributeOffset::getCharsetFlag(TattrDesc2)) { Uint32 pos = AttributeOffset::getCharsetPos(TattrDesc2); - cs = tabptr.p->charsetArray[pos]; + cs = (void*) tabptr.p->charsetArray[pos]; } const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(typeId); diff --git a/storage/oqgraph/CMakeLists.txt b/storage/oqgraph/CMakeLists.txt new file mode 100644 index 00000000000..1eaec7ea028 --- /dev/null +++ b/storage/oqgraph/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright (C) 2006 MySQL AB
+#
+# 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
+
+FIND_PACKAGE(Boost)
+
+IF(Boost_FOUND)
+ INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
+ SET(CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIRS})
+ENDIF()
+
+INCLUDE (CheckCXXSourceCompiles)
+CHECK_CXX_SOURCE_COMPILES(
+"#include <boost/version.hpp>
+#if BOOST_VERSION >= 104000
+#else
+#error oops
+#endif
+int main() { return 0; }" BOOST_OK)
+
+# Only compile OQGRAPH on 32 bit, 64 bit does not compile yet (LPBUG 756966)
+IF(BOOST_OK AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+ INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_OQGRAPH /EHsc")
+
+ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+
+ SET(OQGRAPH_SOURCES ha_oqgraph.cc graphcore.cc)
+ MYSQL_STORAGE_ENGINE(OQGRAPH)
+ENDIF()
+
diff --git a/storage/oqgraph/Makefile.am b/storage/oqgraph/Makefile.am new file mode 100644 index 00000000000..e99e134db02 --- /dev/null +++ b/storage/oqgraph/Makefile.am @@ -0,0 +1,98 @@ +# Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query +# +# 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, or +# (at your option) any later version. +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +# ====================================================================== +# Open Query Graph Computation Engine, based on a concept by Arjen Lentz +# Mk.II implementation by Antony Curtis & Arjen Lentz +# For more information, documentation, support, enhancement engineering, +# and non-GPL licensing, see http://openquery.com/graph +# or contact graph@openquery.com +# For packaged binaries, see http://ourdelta.org +# ====================================================================== + +mysqlplugindir= $(pkglibdir)/plugin + +BOOST_CXXFLAGS = -frtti -fexceptions -fimplicit-templates +#BOOST_CXXFLAGS+= -g +#original flags before 2009-11-10 +#BOOST_CXXFLAGS+= -O3 -fomit-frame-pointer -fstrict-aliasing +#BOOST_CXXFLAGS+= -momit-leaf-frame-pointer -falign-loops +#modified flags: +# - remove omit-frame-pointer, x86 specific (fails on PPC) + hinders debugging +# Option details from gcc man: +# Don't keep the frame pointer in a register for functions that don't need one. +# This avoids the instructions to save, set up and restore frame pointers; +# it also makes an extra register available in many functions. +# It also makes debugging impossible on some machines. +# (automatically gets enabled anyway by -O* on some architectures) +BOOST_CXXFLAGS+= -O3 -fstrict-aliasing +BOOST_CXXFLAGS+= -falign-loops +if HAVE_FVISIBILITY_INLINES_HIDDEN +BOOST_CXXFLAGS+= -fvisibility-inlines-hidden +endif +BOOST_CXXFLAGS+= -funroll-loops -fno-trapping-math + +EXTRA_DIST = ha_oqgraph.h ha_oqgraph.cc graphcore.cc \ + graphcore-graph.h graphcore-types.h graphcore.h \ + CMakeLists.txt plug.in oqgraph_probes.d + +# DTRACE = @DTRACE@ +# DTRACEFLAGS = @DTRACEFLAGS@ +# DTRACEFILES = .libs/libha_oqgraph_la-ha_oqgraph.o + +ORIG_CXXFLAGS = @CXXFLAGS@ +CXXFLAGS= +noinst_HEADERS = ha_oqgraph.h \ + graphcore-graph.h graphcore-types.h graphcore.h +# oqgraph_probes.h + +noinst_LTLIBRARIES = libgraphcore.la +libgraphcore_la_SOURCES = graphcore.cc +libgraphcore_la_CXXFLAGS = $(ORIG_CXXFLAGS) $(BOOST_CXXFLAGS) + +if BUILD_OQGRAPH_FOR_MYSQL + +if BUILD_OQGRAPH_STANDALONE +INCLUDES = -DDBUG_ON -DSAFE_MUTEX -DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX -DHAVE_OQGRAPH $(MYSQL_INC) +else +INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/regex -I$(top_srcdir)/sql -I$(srcdir) -DHAVE_OQGRAPH +endif !BUILD_OQGRAPH_STANDALONE + +EXTRA_LTLIBRARIES = ha_oqgraph.la +mysqlplugin_LTLIBRARIES = @plugin_oqgraph_shared_target@ +ha_oqgraph_la_SOURCES = ha_oqgraph.cc +ha_oqgraph_la_LIBADD = libgraphcore.la + +# if HAVE_DTRACE +# ha_oqgraph_la_LIBADD += oqgraph_probes.o +# endif + +ha_oqgraph_la_LDFLAGS = -shared -module -rpath $(mysqlplugindir) +ha_oqgraph_la_CFLAGS = $(ORIG_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_oqgraph_la_CXXFLAGS = $(ORIG_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN + +# oqgraph_probes.h: oqgraph_probes.d +# $(DTRACE) $(DTRACEFLAGS) -h -s oqgraph_probes.d +# mv oqgraph_probes.h oqgraph_probes.h.bak +# sed "s/#include <unistd.h>//g" oqgraph_probes.h.bak > oqgraph_probes.h +# rm oqgraph_probes.h.bak + +# oqgraph_probes.o: +# $(DTRACE) $(DTRACEFLAGS) -G -s oqgraph_probes.d $(DTRACEFILES) + +endif BUILD_OQGRAPH_FOR_MYSQL + +# End diff --git a/storage/oqgraph/README b/storage/oqgraph/README new file mode 100644 index 00000000000..cb4fba7295b --- /dev/null +++ b/storage/oqgraph/README @@ -0,0 +1,16 @@ +OQGraph storage engine +Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query + +The Open Query GRAPH engine (OQGRAPH) is a computation engine allowing +hierarchies and more complex graph structures to be handled in a +relational fashion. In a nutshell, tree structures and +friend-of-a-friend style searches can now be done using standard SQL +syntax, and results joined onto other tables. + +See http://openquery.com/graph for more information. + + +INSTALLATION + +OQGraph requires at least version 1.40.0 of the Boost library. To +obtain a copy of the Boost library, see http://www.boost.org/ diff --git a/storage/oqgraph/graphcore-graph.h b/storage/oqgraph/graphcore-graph.h new file mode 100644 index 00000000000..46ddfb5335b --- /dev/null +++ b/storage/oqgraph/graphcore-graph.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query + + 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, or + (at your option) any later version. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* ====================================================================== + Open Query Graph Computation Engine, based on a concept by Arjen Lentz + Mk.II implementation by Antony Curtis & Arjen Lentz + For more information, documentation, support, enhancement engineering, + and non-GPL licensing, see http://openquery.com/graph + or contact graph@openquery.com + For packaged binaries, see http://ourdelta.org + ====================================================================== +*/ + +#ifndef oq_graphcore_graph_h_ +#define oq_graphcore_graph_h_ + +typedef adjacency_list +< + vecS, + vecS, + bidirectionalS, + VertexInfo, + EdgeInfo +> Graph; + +#define GRAPH_WEIGHTMAP(G) get(&EdgeInfo::weight, G) +typedef property_map<Graph, EdgeWeight EdgeInfo::*>::type weightmap_type; + +#define GRAPH_INDEXMAP(G) get(vertex_index, G) +typedef property_map<Graph, vertex_index_t>::type indexmap_type; + +#define GRAPH_IDMAP(G) get(&VertexInfo::id, G) +typedef property_map<Graph, VertexID VertexInfo::*>::type idmap_type; + +#endif diff --git a/storage/oqgraph/graphcore-types.h b/storage/oqgraph/graphcore-types.h new file mode 100644 index 00000000000..7a7e4c62729 --- /dev/null +++ b/storage/oqgraph/graphcore-types.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query + + 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, or + (at your option) any later version. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* ====================================================================== + Open Query Graph Computation Engine, based on a concept by Arjen Lentz + Mk.II implementation by Antony Curtis & Arjen Lentz + For more information, documentation, support, enhancement engineering, + and non-GPL licensing, see http://openquery.com/graph + or contact graph@openquery.com + For packaged binaries, see http://ourdelta.org + ====================================================================== +*/ + +#ifndef oq_graphcore_types_h_ +#define oq_graphcore_types_h_ +namespace open_query +{ + + typedef unsigned long long VertexID; + typedef double EdgeWeight; + +} +#endif diff --git a/storage/oqgraph/graphcore.cc b/storage/oqgraph/graphcore.cc new file mode 100644 index 00000000000..0b856ac253f --- /dev/null +++ b/storage/oqgraph/graphcore.cc @@ -0,0 +1,1101 @@ +/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query + + 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, or + (at your option) any later version. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* ====================================================================== + Open Query Graph Computation Engine, based on a concept by Arjen Lentz + Mk.II implementation by Antony Curtis & Arjen Lentz + For more information, documentation, support, enhancement engineering, + and non-GPL licensing, see http://openquery.com/graph + or contact graph@openquery.com + For packaged binaries, see http://ourdelta.org + ====================================================================== +*/ + +#include <string.h> + +#define BOOST_ALL_NO_LIB 1 + +#include <boost/config.hpp> + +#include <set> +#include <stack> + +#include <boost/property_map/property_map.hpp> + +#include <boost/graph/graph_concepts.hpp> +#include <boost/graph/graph_archetypes.hpp> +#include <boost/graph/adjacency_list.hpp> +#include <boost/graph/breadth_first_search.hpp> +#include <boost/graph/dijkstra_shortest_paths.hpp> +#include <boost/graph/iteration_macros.hpp> +#include <boost/graph/reverse_graph.hpp> +#include <boost/graph/graph_utility.hpp> + +#include "graphcore.h" + +using namespace open_query; +using namespace boost; + +static const row empty_row = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +namespace open_query +{ + enum vertex_id_t { vertex_id }; + + struct VertexInfo { + inline VertexInfo() { } + + inline VertexInfo(VertexID _id) + : id(_id) { } + + VertexID id; + }; + + struct EdgeInfo { + EdgeWeight weight; + }; +} + +namespace boost +{ + BOOST_INSTALL_PROPERTY(vertex, id); + + namespace graph + { + template<> + struct internal_vertex_name<VertexInfo> + { + typedef multi_index::member<VertexInfo, VertexID, &VertexInfo::id> type; + }; + + template<> + struct internal_vertex_constructor<VertexInfo> + { + typedef vertex_from_name<VertexInfo> type; + }; + } +} + +namespace open_query +{ + + #include "graphcore-graph.h" + + typedef graph_traits<Graph>::vertex_descriptor Vertex; + typedef graph_traits<Graph>::edge_descriptor Edge; + + typedef std::list<std::pair<Vertex,optional<EdgeWeight> > > shortest_path_list; + typedef shortest_path_list::iterator shortest_path_iterator; + + template<typename ID, typename IDMap> + class id_equals_t + { + public: + id_equals_t(ID id, IDMap map) + : m_id(id), m_map(map) + { } + template<typename V> + bool operator()(V u) const + { + return m_map[u] == m_id; + } + private: + ID m_id; + IDMap m_map; + }; + + template<typename ID, typename IDMap> + inline id_equals_t<ID,IDMap> + id_equals(ID id, IDMap idmap) + { + return id_equals_t<ID,IDMap>(id, idmap); + } + + template<typename T, typename Graph> + class target_equals_t + { + public: + target_equals_t(T target, Graph &g) + : m_target(target), m_g(g) + { } + template<typename V> + bool operator()(V u) const + { + return target(u, m_g) == m_target; + } + private: + T m_target; + Graph &m_g; + }; + + template<typename T, typename Graph> + inline target_equals_t<T,Graph> + target_equals(T target, Graph &g) + { + return target_equals_t<T,Graph>(target, g); + } + + template<typename T, typename Graph> + class source_equals_t + { + public: + source_equals_t(T source, Graph &g) + : m_source(source), m_g(g) + { } + template<typename V> + bool operator()(V u) const + { + return source(u, m_g) == m_source; + } + private: + T m_source; + Graph &m_g; + }; + + template<typename T, typename Graph> + inline source_equals_t<T,Graph> + source_equals(T source, Graph &g) + { + return source_equals_t<T,Graph>(source, g); + } + + struct reference + { + int m_flags; + int m_sequence; + Vertex m_vertex; + Edge m_edge; + EdgeWeight m_weight; + + enum + { + HAVE_SEQUENCE = 1, + HAVE_WEIGHT = 2, + HAVE_EDGE = 4, + }; + + inline reference() + : m_flags(0), m_sequence(0), + m_vertex(graph_traits<Graph>::null_vertex()), + m_edge(), m_weight(0) + { } + + inline reference(int s, Edge e) + : m_flags(HAVE_SEQUENCE | HAVE_EDGE), m_sequence(s), + m_vertex(graph_traits<Graph>::null_vertex()), + m_edge(e), m_weight(0) + { } + + inline reference(int s, Vertex v, const optional<Edge> &e, + const optional<EdgeWeight> &w) + : m_flags(HAVE_SEQUENCE | (w ? HAVE_WEIGHT : 0) | (e ? HAVE_EDGE : 0)), + m_sequence(s), m_vertex(v) + { + if (w) m_weight= *w; + if (e) m_edge= *e; + } + + inline reference(int s, Vertex v, Edge e, EdgeWeight w) + : m_flags(HAVE_SEQUENCE | HAVE_WEIGHT | HAVE_EDGE), + m_sequence(s), m_vertex(v), m_edge(e), m_weight(w) + { } + + inline reference(int s, Vertex v, EdgeWeight w) + : m_flags(HAVE_SEQUENCE | HAVE_WEIGHT), + m_sequence(s), m_vertex(v), m_edge(), m_weight(w) + { } + + inline reference(int s, Vertex v) + : m_flags(HAVE_SEQUENCE), m_sequence(s), m_vertex(v), m_edge(), + m_weight(0) + { } + + optional<int> sequence() const + { + if (m_flags & HAVE_SEQUENCE) + { + return m_sequence; + } + return optional<int>(); + } + + optional<Vertex> vertex() const + { + if (m_vertex != graph_traits<Graph>::null_vertex()) + return m_vertex; + return optional<Vertex>(); + } + + optional<Edge> edge() const + { + if (m_flags & HAVE_EDGE) + return m_edge; + return optional<Edge>(); + }; + + optional<EdgeWeight> weight() const + { + if (m_flags & HAVE_WEIGHT) + return m_weight; + return optional<EdgeWeight>(); + } + }; +} + +namespace open_query { + class GRAPHCORE_INTERNAL oqgraph_share + { + public: + Graph g; + + weightmap_type weightmap; + idmap_type idmap; + indexmap_type indexmap; + + optional<Vertex> find_vertex(VertexID id) const; + optional<Edge> find_edge(Vertex, Vertex) const; + + inline oqgraph_share() throw() + : g(), + weightmap(GRAPH_WEIGHTMAP(g)), + idmap(GRAPH_IDMAP(g)), + indexmap(GRAPH_INDEXMAP(g)) + { } + inline ~oqgraph_share() + { } + }; + + class GRAPHCORE_INTERNAL oqgraph_cursor + { + public: + oqgraph_share *const share; + + inline oqgraph_cursor(oqgraph_share *arg) + : share(arg) + { } + virtual ~oqgraph_cursor() + { } + + virtual int fetch_row(const row &, row&) = 0; + virtual int fetch_row(const row &, row&, const reference&) = 0; + virtual void current(reference& ref) const = 0; + }; +} + +namespace open_query { + class GRAPHCORE_INTERNAL stack_cursor : public oqgraph_cursor + { + private: + optional<EdgeWeight> no_weight; + public: + int sequence; + std::stack<reference> results; + reference last; + + inline stack_cursor(oqgraph_share *arg) + : oqgraph_cursor(arg), no_weight(), sequence(0), results(), last() + { } + + int fetch_row(const row &, row&); + int fetch_row(const row &, row&, const reference&); + + void current(reference& ref) const + { + ref= last; + } + }; + + class GRAPHCORE_INTERNAL vertices_cursor : public oqgraph_cursor + { + typedef graph_traits<Graph>::vertex_iterator vertex_iterator; + + size_t position; + reference last; + public: + inline vertices_cursor(oqgraph_share *arg) + : oqgraph_cursor(arg), position(0) + { } + + int fetch_row(const row &, row&); + int fetch_row(const row &, row&, const reference&); + + void current(reference& ref) const + { + ref= last; + } + + }; + + class GRAPHCORE_INTERNAL edges_cursor : public oqgraph_cursor + { + typedef graph_traits<Graph>::edge_iterator edge_iterator; + typedef edge_iterator::difference_type edge_difference; + + edge_difference position; + reference last; + public: + inline edges_cursor(oqgraph_share *arg) + : oqgraph_cursor(arg), position(0), last() + { } + + int fetch_row(const row &, row&); + int fetch_row(const row &, row&, const reference&); + + void current(reference& ref) const + { + ref= last; + } + }; + + struct GRAPHCORE_INTERNAL oqgraph_visit_dist + : public base_visitor<oqgraph_visit_dist> + { + typedef on_finish_vertex event_filter; + + oqgraph_visit_dist(std::vector<Vertex>::iterator p, + std::vector<EdgeWeight>::iterator d, + stack_cursor *cursor) + : seq(0), m_cursor(*cursor), m_p(p), m_d(d) + { assert(cursor); } + + template<class T, class Graph> + void operator()(T u, Graph &g) + { + m_cursor.results.push(reference(++seq, u, m_d[GRAPH_INDEXMAP(g)[u]])); + } + private: + int seq; + stack_cursor &m_cursor; + std::vector<Vertex>::iterator m_p; + std::vector<EdgeWeight>::iterator m_d; + }; + + template<bool record_weight, typename goal_filter> + struct GRAPHCORE_INTERNAL oqgraph_goal + : public base_visitor<oqgraph_goal<record_weight,goal_filter> > + { + typedef goal_filter event_filter; + + oqgraph_goal(Vertex goal, std::vector<Vertex>::iterator p, + stack_cursor *cursor) + : m_goal(goal), m_cursor(*cursor), m_p(p) + { assert(cursor); } + + template<class T, class Graph> + void operator()(T u, Graph &g) + { + if (u == m_goal) + { + int seq= 0; + indexmap_type indexmap= GRAPH_INDEXMAP(g); + + for (Vertex q, v= u;; v = q, seq++) + if ((q= m_p[ indexmap[v] ]) == v) + break; + + for (Vertex v= u;; u= v) + { + optional<Edge> edge; + optional<EdgeWeight> weight; + v= m_p[ indexmap[u] ]; + if (record_weight && u != v) + { + typename graph_traits<Graph>::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end)= out_edges(v, g); ei != ei_end; ++ei) + { + if (target(*ei, g) == u) + { + edge= *ei; + weight= GRAPH_WEIGHTMAP(g)[*ei]; + break; + } + } + } + else if (u != v) + weight= 1; + m_cursor.results.push(reference(seq--, u, edge, weight)); + if (u == v) + break; + } + throw this; + } + } + + private: + Vertex m_goal; + stack_cursor &m_cursor; + std::vector<Vertex>::iterator m_p; + }; +} + +namespace open_query +{ + inline oqgraph::oqgraph(oqgraph_share *arg) throw() + : share(arg), cursor(0) + { } + + inline oqgraph::~oqgraph() throw() + { + delete cursor; + } + + unsigned oqgraph::edges_count() const throw() + { + return num_edges(share->g); + } + + unsigned oqgraph::vertices_count() const throw() + { + return num_vertices(share->g); + } + + oqgraph* oqgraph::create(oqgraph_share *share) throw() + { + assert(share != NULL); + return new (std::nothrow) oqgraph(share); + } + + oqgraph_share* oqgraph::create() throw() + { + return new (std::nothrow) oqgraph_share(); + } + + optional<Edge> + oqgraph_share::find_edge(Vertex orig, Vertex dest) const + { + if (in_degree(dest, g) >= out_degree(orig, g)) + { + graph_traits<Graph>::out_edge_iterator ei, ei_end; + tie(ei, ei_end)= out_edges(orig, g); + if ((ei= find_if(ei, ei_end, target_equals(dest, g))) != ei_end) + return *ei; + } + else + { + graph_traits<Graph>::in_edge_iterator ei, ei_end; + tie(ei, ei_end)= in_edges(dest, g); + if ((ei= find_if(ei, ei_end, source_equals(orig, g))) != ei_end) + return *ei; + } + return optional<Edge>(); + } + + optional<Vertex> + oqgraph_share::find_vertex(VertexID id) const + { + return boost::graph::find_vertex(id, g); + } + + int oqgraph::delete_all() throw() + { + share->g.clear(); + return 0; + } + + int oqgraph::insert_edge( + VertexID orig_id, VertexID dest_id, EdgeWeight weight, bool replace) throw() + { + optional<Vertex> orig, dest; + optional<Edge> edge; + bool inserted= 0; + + if (weight < 0) + return INVALID_WEIGHT; + if (!(orig= share->find_vertex(orig_id))) + { + try + { + orig= add_vertex(VertexInfo(orig_id), share->g); + if (orig == graph_traits<Graph>::null_vertex()) + return CANNOT_ADD_VERTEX; + } + catch (...) + { + return CANNOT_ADD_VERTEX; + } + } + if (!(dest= share->find_vertex(dest_id))) + { + try + { + dest= add_vertex(VertexInfo(dest_id), share->g); + if (dest == graph_traits<Graph>::null_vertex()) + return CANNOT_ADD_VERTEX; + } + catch (...) + { + return CANNOT_ADD_VERTEX; + } + } + if (!(edge= share->find_edge(*orig, *dest))) + { + try + { + tie(edge, inserted)= add_edge(*orig, *dest, share->g); + if (!inserted) + return CANNOT_ADD_EDGE; + } + catch (...) + { + return CANNOT_ADD_EDGE; + } + } + else + { + if (!replace) + return DUPLICATE_EDGE; + } + share->weightmap[*edge]= weight; + return OK; + } + + int oqgraph::delete_edge(current_row_st) throw() + { + reference ref; + if (cursor) + return EDGE_NOT_FOUND; + cursor->current(ref); + optional<Edge> edge; + if (!(edge= ref.edge())) + return EDGE_NOT_FOUND; + Vertex orig= source(*edge, share->g); + Vertex dest= target(*edge, share->g); + remove_edge(*edge, share->g); + if (!degree(orig, share->g)) + remove_vertex(orig, share->g); + if (!degree(dest, share->g)) + remove_vertex(dest, share->g); + return OK; + } + + int oqgraph::modify_edge(current_row_st, + VertexID *orig_id, VertexID *dest_id, EdgeWeight *weight, + bool replace) throw() + { + if (!cursor) + return EDGE_NOT_FOUND; + reference ref; + cursor->current(ref); + optional<Edge> edge; + if (!(edge= ref.edge())) + return EDGE_NOT_FOUND; + if (weight && *weight < 0) + return INVALID_WEIGHT; + + optional<Vertex> orig= source(*edge, share->g), + dest= target(*edge, share->g); + + bool orig_neq= orig_id ? share->idmap[*orig] != *orig_id : 0; + bool dest_neq= dest_id ? share->idmap[*dest] != *dest_id : 0; + if (orig_neq || dest_neq) + { + optional<Edge> new_edge; + if (orig_neq && !(orig= share->find_vertex(*orig_id))) + { + try + { + orig= add_vertex(VertexInfo(*orig_id), share->g); + if (orig == graph_traits<Graph>::null_vertex()) + return CANNOT_ADD_VERTEX; + } + catch (...) + { + return CANNOT_ADD_VERTEX; + } + } + if (dest_neq && !(dest= share->find_vertex(*dest_id))) + { + try + { + dest= add_vertex(VertexInfo(*dest_id), share->g); + if (dest == graph_traits<Graph>::null_vertex()) + return CANNOT_ADD_VERTEX; + } + catch (...) + { + return CANNOT_ADD_VERTEX; + } + } + if (!(new_edge= share->find_edge(*orig, *dest))) + { + try + { + bool inserted; + tie(new_edge, inserted)= add_edge(*orig, *dest, share->g); + if (!inserted) + return CANNOT_ADD_EDGE; + } + catch (...) + { + return CANNOT_ADD_EDGE; + } + } + else + { + if (!replace) + return DUPLICATE_EDGE; + } + share->weightmap[*new_edge]= share->weightmap[*edge]; + remove_edge(*edge, share->g); + edge= new_edge; + } + if (weight) + share->weightmap[*edge]= *weight; + return OK; + } + + int oqgraph::modify_edge( + VertexID orig_id, VertexID dest_id, EdgeWeight weight) throw() + { + optional<Vertex> orig, dest; + optional<Edge> edge; + + if (weight < 0) + return INVALID_WEIGHT; + if (!(orig= share->find_vertex(orig_id))) + return EDGE_NOT_FOUND; + if (!(dest= share->find_vertex(dest_id))) + return EDGE_NOT_FOUND; + if (!(edge= share->find_edge(*orig, *dest))) + return EDGE_NOT_FOUND; + share->weightmap[*edge]= weight; + return OK; + } + + + int oqgraph::delete_edge(VertexID orig_id, VertexID dest_id) throw() + { + optional<Vertex> orig, dest; + optional<Edge> edge; + + if (!(orig= share->find_vertex(orig_id))) + return EDGE_NOT_FOUND; + if (!(dest= share->find_vertex(dest_id))) + return EDGE_NOT_FOUND; + if (!(edge= share->find_edge(*orig, *dest))) + return EDGE_NOT_FOUND; + remove_edge(*edge, share->g); + if (!degree(*orig, share->g)) + remove_vertex(*orig, share->g); + if (!degree(*dest, share->g)) + remove_vertex(*dest, share->g); + return OK; + } + + + int oqgraph::search(int *latch, VertexID *orig_id, VertexID *dest_id) throw() + { + optional<Vertex> orig, dest; + int op= 0, seq= 0; + enum { + NO_SEARCH = 0, + DIJKSTRAS = 1, + BREADTH_FIRST = 2, + + ALGORITHM = 0x0ffff, + HAVE_ORIG = 0x10000, + HAVE_DEST = 0x20000, + }; + + delete cursor; cursor= 0; + row_info= empty_row; + if ((row_info.latch_indicator= latch)) + op= ALGORITHM & (row_info.latch= *latch); + if ((row_info.orig_indicator= orig_id) && (op|= HAVE_ORIG)) + orig= share->find_vertex((row_info.orig= *orig_id)); + if ((row_info.dest_indicator= dest_id) && (op|= HAVE_DEST)) + dest= share->find_vertex((row_info.dest= *dest_id)); + //try + //{ + switch (op) + { + case NO_SEARCH | HAVE_ORIG | HAVE_DEST: + case NO_SEARCH | HAVE_ORIG: + if ((cursor= new (std::nothrow) stack_cursor(share)) && orig) + { + graph_traits<Graph>::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end)= out_edges(*orig, share->g); ei != ei_end; ++ei) + { + Vertex v= target(*ei, share->g); + static_cast<stack_cursor*>(cursor)-> + results.push(reference(++seq, v, *ei, share->weightmap[*ei])); + } + } + /* fall through */ + case NO_SEARCH | HAVE_DEST: + if ((op & HAVE_DEST) && + (cursor || (cursor= new (std::nothrow) stack_cursor(share))) && + dest) + { + graph_traits<Graph>::in_edge_iterator ei, ei_end; + for (tie(ei, ei_end)= in_edges(*dest, share->g); ei != ei_end; ++ei) + { + Vertex v= source(*ei, share->g); + static_cast<stack_cursor*>(cursor)-> + results.push(reference(++seq, v, *ei, share->weightmap[*ei])); + } + } + break; + + case NO_SEARCH: + cursor= new (std::nothrow) vertices_cursor(share); + break; + + case DIJKSTRAS | HAVE_ORIG | HAVE_DEST: + if ((cursor= new (std::nothrow) stack_cursor(share)) && orig && dest) + { + std::vector<Vertex> p(num_vertices(share->g)); + std::vector<EdgeWeight> d(num_vertices(share->g)); + oqgraph_goal<true, on_finish_vertex> + vis(*dest, p.begin(), static_cast<stack_cursor*>(cursor)); + p[share->indexmap[*orig]]= *orig; + try + { + dijkstra_shortest_paths(share->g, *orig, + weight_map( + share->weightmap + ). + distance_map( + make_iterator_property_map(d.begin(), share->indexmap) + ). + predecessor_map( + make_iterator_property_map(p.begin(), share->indexmap) + ). + visitor( + make_dijkstra_visitor(vis) + ) + ); + } + catch (...) + { /* printf("found\n"); */ } + } + break; + + case BREADTH_FIRST | HAVE_ORIG | HAVE_DEST: + if ((cursor= new (std::nothrow) stack_cursor(share)) && orig && dest) + { + std::vector<Vertex> p(num_vertices(share->g)); + oqgraph_goal<false, on_discover_vertex> + vis(*dest, p.begin(), static_cast<stack_cursor*>(cursor)); + p[share->indexmap[*orig]]= *orig; + try + { + breadth_first_search(share->g, *orig, + visitor(make_bfs_visitor( + std::make_pair( + record_predecessors( + make_iterator_property_map(p.begin(), share->indexmap), + on_tree_edge() + ), + vis) + ) + ) + ); + } + catch (...) + { /* printf("found\n"); */ } + } + break; + + case DIJKSTRAS | HAVE_ORIG: + case BREADTH_FIRST | HAVE_ORIG: + if ((cursor= new (std::nothrow) stack_cursor(share)) && (orig || dest)) + { + std::vector<Vertex> p(num_vertices(share->g)); + std::vector<EdgeWeight> d(num_vertices(share->g)); + oqgraph_visit_dist vis(p.begin(), d.begin(), + static_cast<stack_cursor*>(cursor)); + p[share->indexmap[*orig]]= *orig; + switch (ALGORITHM & op) + { + case DIJKSTRAS: + dijkstra_shortest_paths(share->g, *orig, + weight_map( + share->weightmap + ). + distance_map( + make_iterator_property_map(d.begin(), share->indexmap) + ). + predecessor_map( + make_iterator_property_map(p.begin(), share->indexmap) + ). + visitor( + make_dijkstra_visitor(vis) + ) + ); + break; + case BREADTH_FIRST: + breadth_first_search(share->g, *orig, + visitor(make_bfs_visitor( + std::make_pair( + record_predecessors( + make_iterator_property_map(p.begin(), + share->indexmap), + on_tree_edge() + ), + std::make_pair( + record_distances( + make_iterator_property_map(d.begin(), + share->indexmap), + on_tree_edge() + ), + vis + )) + )) + ); + break; + default: + abort(); + } + } + break; + + case BREADTH_FIRST | HAVE_DEST: + case DIJKSTRAS | HAVE_DEST: + if ((cursor= new (std::nothrow) stack_cursor(share)) && (orig || dest)) + { + std::vector<Vertex> p(num_vertices(share->g)); + std::vector<EdgeWeight> d(num_vertices(share->g)); + oqgraph_visit_dist vis(p.begin(), d.begin(), + static_cast<stack_cursor*>(cursor)); + reverse_graph<Graph> r(share->g); + p[share->indexmap[*dest]]= *dest; + switch (ALGORITHM & op) + { + case DIJKSTRAS: + dijkstra_shortest_paths(r, *dest, + weight_map( + share->weightmap + ). + distance_map( + make_iterator_property_map(d.begin(), share->indexmap) + ). + predecessor_map( + make_iterator_property_map(p.begin(), share->indexmap) + ). + visitor( + make_dijkstra_visitor(vis) + ) + ); + break; + case BREADTH_FIRST: + breadth_first_search(r, *dest, + visitor(make_bfs_visitor( + std::make_pair( + record_predecessors( + make_iterator_property_map(p.begin(), + share->indexmap), + on_tree_edge() + ), + std::make_pair( + record_distances( + make_iterator_property_map(d.begin(), + share->indexmap), + on_tree_edge() + ), + vis + )) + )) + ); + break; + default: + abort(); + } + } + break; + + default: + break; + } + return 0; + //} + //catch (...) + //{ + // return MISC_FAIL; + //} + } + + int oqgraph::fetch_row(row& result) throw() + { + if (!cursor) + return NO_MORE_DATA; + return cursor->fetch_row(row_info, result); + } + + int oqgraph::fetch_row(row& result, const void* ref_ptr) throw() + { + const reference &ref= *(const reference*) ref_ptr; + if (!cursor) + return NO_MORE_DATA; + return cursor->fetch_row(row_info, result, ref); + } + + void oqgraph::row_ref(void *ref_ptr) throw() + { + reference &ref= *(reference*) ref_ptr; + if (cursor) + cursor->current(ref); + else + ref= reference(); + } + + int oqgraph::random(bool scan) throw() + { + if (scan || !cursor) + { + delete cursor; cursor= 0; + if (!(cursor= new (std::nothrow) edges_cursor(share))) + return MISC_FAIL; + } + row_info= empty_row; + return OK; + } + + void oqgraph::free(oqgraph *graph) throw() + { + delete graph; + } + + void oqgraph::free(oqgraph_share *graph) throw() + { + delete graph; + } + + const size_t oqgraph::sizeof_ref= sizeof(reference); +} + +int stack_cursor::fetch_row(const row &row_info, row &result) +{ + if (!results.empty()) + { + if (int res= fetch_row(row_info, result, results.top())) + return res; + results.pop(); + return oqgraph::OK; + } + else + { + last= reference(); + return oqgraph::NO_MORE_DATA; + } +} + +int stack_cursor::fetch_row(const row &row_info, row &result, + const reference &ref) +{ + last= ref; + if (last.vertex()) + { + optional<int> seq; + optional<EdgeWeight> w; + optional<Vertex> v; + result= row_info; + if ((result.seq_indicator= seq= last.sequence())) + result.seq= *seq; + if ((result.link_indicator= v= last.vertex())) + result.link= share->idmap[*v]; + if ((result.weight_indicator= w= last.weight())) + result.weight= *w; + return oqgraph::OK; + } + else + return oqgraph::NO_MORE_DATA; +} + + +int vertices_cursor::fetch_row(const row &row_info, row &result) +{ + vertex_iterator it, end; + reference ref; + size_t count= position; + for (tie(it, end)= vertices(share->g); count && it != end; ++it, --count) + ; + if (it != end) + ref= reference(position+1, *it); + if (int res= fetch_row(row_info, result, ref)) + return res; + position++; + return oqgraph::OK; +} + +int vertices_cursor::fetch_row(const row &row_info, row &result, + const reference &ref) +{ + last= ref; + optional<Vertex> v= last.vertex(); + result= row_info; + if (v) + { + result.link_indicator= 1; + result.link= share->idmap[*v]; +#ifdef DISPLAY_VERTEX_INFO + result.seq_indicator= 1; + if ((result.seq= degree(*v, share->g))) + { + EdgeWeight weight= 0; + graph_traits<Graph>::in_edge_iterator iei, iei_end; + for (tie(iei, iei_end)= in_edges(*v, share->g); iei != iei_end; ++iei) + weight+= share->weightmap[*iei]; + graph_traits<Graph>::out_edge_iterator oei, oei_end; + for (tie(oei, oei_end)= out_edges(*v, share->g); oei != oei_end; ++oei) + weight+= share->weightmap[*oei]; + result.weight_indicator= 1; + result.weight= weight / result.seq; + } +#endif + return oqgraph::OK; + } + else + return oqgraph::NO_MORE_DATA; +} + +int edges_cursor::fetch_row(const row &row_info, row &result) +{ + edge_iterator it, end; + reference ref; + size_t count= position; + for (tie(it, end)= edges(share->g); count && it != end; ++it, --count) + ; + if (it != end) + ref= reference(position+1, *it); + if (int res= fetch_row(row_info, result, ref)) + return res; + ++position; + return oqgraph::OK; +} + +int edges_cursor::fetch_row(const row &row_info, row &result, + const reference &ref) +{ + optional<Edge> edge; + if ((edge= (last= ref).edge())) + { + result= row_info; + result.orig_indicator= result.dest_indicator= result.weight_indicator= 1; + result.orig= share->idmap[ source( *edge, share->g ) ]; + result.dest= share->idmap[ target( *edge, share->g ) ]; + result.weight= share->weightmap[ *edge ]; + return oqgraph::OK; + } + return oqgraph::NO_MORE_DATA; +} + +namespace boost { + GRAPHCORE_INTERNAL void throw_exception(std::exception const&) + { + abort(); + } +} diff --git a/storage/oqgraph/graphcore.h b/storage/oqgraph/graphcore.h new file mode 100644 index 00000000000..4aaddb2796f --- /dev/null +++ b/storage/oqgraph/graphcore.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query + + 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, or + (at your option) any later version. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* ====================================================================== + Open Query Graph Computation Engine, based on a concept by Arjen Lentz + Mk.II implementation by Antony Curtis & Arjen Lentz + For more information, documentation, support, enhancement engineering, + and non-GPL licensing, see http://openquery.com/graph + or contact graph@openquery.com + For packaged binaries, see http://ourdelta.org + ====================================================================== +*/ + +#ifndef oq_graphcore_h_ +#define oq_graphcore_h_ + +/* #define GRAPHCORE_INTERNAL __attribute__((visibility("hidden"))) */ +#define GRAPHCORE_INTERNAL + +#include "graphcore-types.h" + +namespace open_query +{ + class oqgraph_share; + class oqgraph_cursor; + + struct row + { + bool latch_indicator; + bool orig_indicator; + bool dest_indicator; + bool weight_indicator; + bool seq_indicator; + bool link_indicator; + + int latch; + VertexID orig; + VertexID dest; + EdgeWeight weight; + unsigned seq; + VertexID link; + }; + + class oqgraph + { + oqgraph_share *const share; + oqgraph_cursor *cursor; + row row_info; + + inline oqgraph(oqgraph_share*) throw(); + inline ~oqgraph() throw(); + public: + + enum error_code + { + OK= 0, + NO_MORE_DATA, + EDGE_NOT_FOUND, + INVALID_WEIGHT, + DUPLICATE_EDGE, + CANNOT_ADD_VERTEX, + CANNOT_ADD_EDGE, + MISC_FAIL + }; + + struct current_row_st {}; + static inline current_row_st current_row() + { return current_row_st(); } + + unsigned vertices_count() const throw(); + unsigned edges_count() const throw(); + + int delete_all(void) throw(); + + int insert_edge(VertexID, VertexID, EdgeWeight, bool=0) throw(); + int modify_edge(VertexID, VertexID, EdgeWeight) throw(); + int delete_edge(VertexID, VertexID) throw(); + + int modify_edge(current_row_st, + VertexID*, VertexID*, EdgeWeight*, bool=0) throw(); + int delete_edge(current_row_st) throw(); + + int replace_edge(VertexID orig, VertexID dest, EdgeWeight weight) throw() + { return insert_edge(orig, dest, weight, true); } + + int search(int*, VertexID*, VertexID*) throw(); + int random(bool) throw(); + + int fetch_row(row&) throw(); + int fetch_row(row&, const void*) throw(); + void row_ref(void*) throw(); + + static oqgraph* create(oqgraph_share*) throw(); + static oqgraph_share *create() throw(); + + static void free(oqgraph*) throw(); + static void free(oqgraph_share*) throw(); + + static const size_t sizeof_ref; + }; + +} +#endif diff --git a/storage/oqgraph/graphstore.c b/storage/oqgraph/graphstore.c new file mode 100644 index 00000000000..c5478b56ca5 --- /dev/null +++ b/storage/oqgraph/graphstore.c @@ -0,0 +1,356 @@ +/* + * Graph Engine - Copyright (C) 2007 by Arjen Lentz (arjen@openquery.com.au) + * graphstore.c internal storage system + */ +#include <stdlib.h> +#include <string.h> +#include <my_global.h> +#include <my_sys.h> +#include "graphstore.h" + + +/* + create a new vertex, and add it to the list (or start a list) + NOTE! gspp is ptr to base ptr + + returns 1 for ok, 0 for error +*/ +static int _add_vertex (GRAPHSTORE **gspp, GRAPH_VERTEXID id) +{ + GRAPHSTORE *newgsp; + GRAPHSTORE *gscurp; + + if (gspp == NULL) + return 0; + + /* not allowing 0 */ + if (!id) + return 0; + + if (*gspp != NULL) { + for (gscurp = *gspp; gscurp != NULL; gscurp = gscurp->next) { + if (gscurp->vertex->id == id) + return 1; /* we can ignore, id already exists */ + } + } + + /* allocate and initialise */ + if ((newgsp = my_malloc(sizeof (GRAPHSTORE),MYF(MY_ZEROFILL))) == NULL) + return 0; + + if ((newgsp->vertex = my_malloc(sizeof (GRAPH_VERTEX),MYF(MY_ZEROFILL))) == NULL) { + my_free(newgsp,MYF(0)); + return 0; + } + + newgsp->vertex->id = id; + /* add new vertex to end of list */ + if (*gspp != NULL) { + for (gscurp = *gspp; gscurp->next != NULL; gscurp = gscurp->next); + gscurp->next = newgsp; + } + else /* new list */ + *gspp = newgsp; + + /* ok */ + return 1; +} + + +/* + find a vertex by id + + returns ptr or NULL +*/ +static GRAPH_VERTEX *_find_vertex (GRAPHSTORE *gsp, GRAPH_VERTEXID id) +{ + /* just loop through the list to find id */ + while (gsp != NULL && gsp->vertex->id != id) + gsp = gsp->next; + + /* return ptr to vertex, or NULL */ + return (gsp != NULL ? gsp->vertex : NULL); +} + + +/* + add edge + both vertices must already exist; graphstore_insert() does this + + return 1 for ok, 0 for error (already exists, alloc error, etc) +*/ +static int _add_edge (GRAPHSTORE *gsp, GRAPH_VERTEXID origid, GRAPH_VERTEXID destid, GRAPH_WEIGHT weight) +{ + GRAPH_VERTEX *origvp, *destvp; + GRAPH_EDGE *ep, *newep; + + /* find both vertices */ + if ((origvp = _find_vertex(gsp,origid)) == NULL || + (destvp = _find_vertex(gsp,destid)) == NULL) + return 0; + + /* check if edge already exists */ + for (ep = origvp->forward_edge; ep != NULL; ep = ep->next_edge) { + if (ep->vertex->id == destid) + return 0; + } + + /* allocate and initialise new edge */ + if ((newep = my_malloc(sizeof (GRAPH_EDGE),MYF(MY_ZEROFILL))) == NULL) + return 0; + + newep->vertex = destvp; + newep->weight = weight; + + /* insert new edge at start of chain, that's easiest */ + ep = origvp->forward_edge; + origvp->forward_edge = newep; + newep->next_edge = ep; + + /* ok */ + return 1; +} + + +/* + create a new row, and add it to the graph set (or start set) + NOTE! gsetpp is ptr to base ptr + + returns 1 for ok, 0 for error +*/ +static int _add_graph_set (GRAPH_SET **gsetpp, GRAPH_TUPLE *gtp) +{ + GRAPH_SET *newgsetp; + GRAPH_SET *gsetcurp; + + if (gsetpp == NULL || gtp == NULL) + return 0; + + /* allocate and initialise */ + if ((newgsetp = my_malloc(sizeof (GRAPH_SET),MYF(MY_ZEROFILL))) == NULL) + return 0; + + /* put in the data */ + memcpy(&newgsetp->tuple,gtp,sizeof (GRAPH_TUPLE)); + + /* add new row to end of set */ + if (*gsetpp != NULL) { + for (gsetcurp = *gsetpp; gsetcurp->next != NULL; gsetcurp = gsetcurp->next); + gsetcurp->next = newgsetp; + } + else { /* new set */ + *gsetpp = newgsetp; + } + + /* ok */ + return 1; +} + + +/* + free a graph set (release memory) + + returns 1 for ok, 0 for error +*/ +int free_graph_set (GRAPH_SET *gsetp) +{ + GRAPH_SET *nextgsetp; + + if (gsetp == NULL) + return 0; + + while (gsetp != NULL) { + nextgsetp = gsetp->next; + /* free() is a void function, nothing to check */ + my_free(gsetp,MYF(0)); + gsetp = nextgsetp; + } + + /* ok */ + return 1; +} + + +/* + insert new data into graphstore + this can be either a vertex or an edge, depending on the params + NOTE! gspp is ptr to base ptr + + returns 1 for ok, 0 for error +*/ +int graphstore_insert (GRAPHSTORE **gspp, GRAPH_TUPLE *gtp) +{ + if (gspp == NULL) + return 0; + + /* if nada or no orig vertex, we can't do anything */ + if (gtp == NULL || !gtp->origid) + return 0; + +#if 0 +printf("inserting: origid=%lu destid=%lu weight=%lu\n",gtp->origid,gtp->destid,gtp->weight); +#endif + + if (!gtp->destid) /* no edge param so just adding vertex */ + return _add_vertex(gspp,gtp->origid); + + /* + add an edge + first add both vertices just in case they didn't yet exist... + not checking result there: if there's a prob, _add_edge() will catch. + */ + _add_vertex(gspp,gtp->origid); + _add_vertex(gspp,gtp->destid); + return _add_edge(*gspp,gtp->origid,gtp->destid,gtp->weight); +} + + +/* + this is an internal function used by graphstore_query() + + find any path from originating vertex to destid + if found, add to the result set on the way back + NOTE: recursive function! + + returns 1 for hit, 0 for nothing, -1 for error +*/ +int _find_any_path(GRAPH_SET **gsetpp, GRAPH_VERTEXID origid, GRAPH_VERTEXID destid, GRAPH_VERTEX *gvp, GRAPH_SEQ depth) +{ + GRAPH_EDGE *gep; + GRAPH_TUPLE tup; + int res; + + if (gvp->id == destid) { + /* found target! */ + bzero(&tup,sizeof (GRAPH_TUPLE)); + tup.origid = origid; + tup.destid = destid; + tup.seq = depth; + tup.linkid = gvp->id; + return (_add_graph_set(gsetpp,&tup) ? 1 : -1); + } + + /* walk through all edges for this vertex */ + for (gep = gvp->forward_edge; gep; gep = gep->next_edge) { + /* recurse */ + res = _find_any_path(gsetpp,origid,destid,gep->vertex,depth+1); + if (res < 0) + return res; + if (res > 0) { + /* found somewhere below this one, insert ourselves and return */ + bzero(&tup,sizeof (GRAPH_TUPLE)); + tup.origid = origid; + tup.destid = destid; + tup.weight = gep->weight; + tup.seq = depth; + tup.linkid = gvp->id; + return (_add_graph_set(gsetpp,&tup) ? 1 : -1); + } + } + + /* nothing found but no error */ + return 0; +} + + +/* + query graphstore + latch specifies what operation to perform + + we need to feed the conditions in... (through engine condition pushdown) + for now we just presume one condition per field so we just feed in a tuple + this also means we can just find constants, not ranges + + return ptr to GRAPH_SET + caller must free with free_graph_set() +*/ +GRAPH_SET *graphstore_query (GRAPHSTORE *gsp, GRAPH_TUPLE *gtp) +{ + GRAPH_SET *gsetp = NULL; + GRAPH_SET *gsetcurp; + GRAPH_SET *newgsetp; + + if (gsp == NULL || gtp == NULL) + return (NULL); + + switch (gtp->latch) { + case 0: /* return all vertices/edges */ + { + GRAPHSTORE *gscurp; + GRAPH_EDGE *gep; + GRAPH_TUPLE tup; + + /* walk through all vertices */ + for (gscurp = gsp; gscurp != NULL; gscurp = gscurp->next) { + /* check for condition */ + if (gtp->origid && gscurp->vertex->id != gtp->origid) + continue; + + bzero(&tup,sizeof (GRAPH_TUPLE)); + tup.origid = gscurp->vertex->id; + + /* no edges? */ + if (gscurp->vertex->forward_edge == NULL) { + /* just add vertex to set */ + if (!_add_graph_set(&gsetp,&tup)) { + if (gsetp != NULL) /* clean up */ + my_free(gsetp,MYF(0)); + return (NULL); + } + } + else { + /* walk through all edges */ + for (gep = gscurp->vertex->forward_edge; gep; gep = gep->next_edge) { + tup.destid = gep->vertex->id; + tup.weight = gep->weight; + + /* just add vertex to set */ + if (!_add_graph_set(&gsetp,&tup)) { + if (gsetp != NULL) /* clean up */ + my_free(gsetp,MYF(0)); + return (NULL); + } + } + } + } + } + break; + + case 1: /* find a path between origid and destid */ + /* yes it'll just go with the first path it finds! */ + { + GRAPHSTORE *gscurp; + GRAPH_VERTEX *origvp; + GRAPH_TUPLE tup; + + if (!gtp->origid || !gtp->destid) + return NULL; + + /* find both vertices */ + if ((origvp = _find_vertex(gsp,gtp->origid)) == NULL || + _find_vertex(gsp,gtp->destid) == NULL) + return NULL; + + if (_find_any_path(&gsetp,gtp->origid,gtp->destid,origvp,0) < 0) { /* error? */ + if (gsetp != NULL) /* clean up */ + my_free(gsetp,MYF(0)); + return NULL; + } + } + break; + + default: + /* this ends up being an empty set */ + break; + } + + /* Fix up latch column with the proper value - to be relationally correct */ + for (gsetcurp = gsetp; gsetcurp != NULL; gsetcurp = gsetcurp->next) + gsetcurp->tuple.latch = gtp->latch; + + return gsetp; +} + + + +/* end of graphstore.c */
\ No newline at end of file diff --git a/storage/oqgraph/graphstore.h b/storage/oqgraph/graphstore.h new file mode 100644 index 00000000000..61862221455 --- /dev/null +++ b/storage/oqgraph/graphstore.h @@ -0,0 +1,90 @@ +/* + * Graph Engine - Copyright (C) 2007 by Arjen Lentz (arjen@openquery.com.au) + * graphstore.h internal storage system + */ +//typedef unsigned short uint16; +//typedef unsigned long long uint64; + + +/* + This is essentially what a GRAPH engine table looks like on the MySQL end: + CREATE TABLE foo ( + latch SMALLINT UNSIGNED NULL, + origid BIGINT UNSIGNED NULL, + destid BIGINT UNSIGNED NULL, + weight BIGINT UNSIGNED NULL, + seq BIGINT UNSIGNED NULL, + linkid BIGINT UNSIGNED NULL + ) ENGINE=OQGRAPH +*/ + + +/* + We represent the above in C in the following way: +*/ +typedef uint16 GRAPH_LATCH; +typedef uint64 GRAPH_VERTEXID; +typedef uint64 GRAPH_WEIGHT; +typedef uint64 GRAPH_SEQ; + +typedef struct graph_tuple { + GRAPH_LATCH latch; /* function */ + GRAPH_VERTEXID origid; /* vertex (should be != 0) */ + GRAPH_VERTEXID destid; /* edge */ + GRAPH_WEIGHT weight; /* weight */ + GRAPH_SEQ seq; /* seq# within (origid) */ + GRAPH_VERTEXID linkid; /* current step between origid/destid */ +} GRAPH_TUPLE; + +typedef struct graph_set { + GRAPH_TUPLE tuple; + struct graph_set *next; +} GRAPH_SET; + + +/* + Internally, sets look nothing like the above + + - We have vertices, connected by edges. + - Each vertex' edges are maintained in a linked list. + - Edges can be weighted. + + There are some issues with this structure, it'd be a pest to do a delete + So for now, let's just not support deletes! +*/ +/* the below is half-gross and will likely change */ +typedef struct graph_edge { + struct graph_vertex { + GRAPH_VERTEXID id; + struct graph_edge *forward_edge; + } *vertex; + GRAPH_WEIGHT weight; + struct graph_edge *next_edge; +} GRAPH_EDGE; + +typedef struct graph_vertex GRAPH_VERTEX; + + +/* + A rough internal storage system for a set +*/ +/* this below is fully gross and will definitely change */ +typedef struct graphstore { + GRAPH_VERTEX *vertex; /* changed to ptr when integrating into MySQL */ + struct graphstore *next; +} GRAPHSTORE; + +#ifdef __cplusplus +extern "C" { +#endif + +/* public function declarations */ +int graphstore_insert (GRAPHSTORE **gspp, GRAPH_TUPLE *gtp); +GRAPH_SET *graphstore_query (GRAPHSTORE *gsp, GRAPH_TUPLE *gtp); +int free_graph_set (GRAPH_SET *gsetp); + +#ifdef __cplusplus +} +#endif + +/* end of graphstore.h */
\ No newline at end of file diff --git a/storage/oqgraph/ha_oqgraph.cc b/storage/oqgraph/ha_oqgraph.cc new file mode 100644 index 00000000000..cf9ef3d8997 --- /dev/null +++ b/storage/oqgraph/ha_oqgraph.cc @@ -0,0 +1,1041 @@ +/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query + Portions of this file copyright (C) 2000-2006 MySQL AB + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* ====================================================================== + Open Query Graph Computation Engine, based on a concept by Arjen Lentz + Mk.II implementation by Antony Curtis & Arjen Lentz + For more information, documentation, support, enhancement engineering, + and non-GPL licensing, see http://openquery.com/graph + or contact graph@openquery.com + For packaged binaries, see http://ourdelta.org + ====================================================================== +*/ + +#ifdef USE_PRAGMA_IMPLEMENTATION +#pragma implementation // gcc: Class implementation +#endif + +#define MYSQL_SERVER // to have THD +#include "mysql_priv.h" +#if MYSQL_VERSION_ID >= 50100 +#include <mysql/plugin.h> +#endif + +#ifdef HAVE_OQGRAPH + +#include "ha_oqgraph.h" +#include "graphcore.h" + +#define OQGRAPH_STATS_UPDATE_THRESHOLD 10 + +using namespace open_query; + + +struct oqgraph_info_st +{ + THR_LOCK lock; + oqgraph_share *graph; + uint use_count; + uint key_stat_version; + uint records; + bool dropped; + char name[FN_REFLEN+1]; +}; + +static const char oqgraph_description[]= + "Open Query Graph Computation Engine, stored in memory " + "(http://openquery.com/graph)"; + +#if MYSQL_VERSION_ID < 50100 +static bool oqgraph_init(); + +handlerton oqgraph_hton= { + "OQGRAPH", + SHOW_OPTION_YES, + oqgraph_description, + DB_TYPE_OQGRAPH, + oqgraph_init, + 0, /* slot */ + 0, /* savepoint size. */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* release savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ + HTON_NO_FLAGS +}; + +#define STATISTIC_INCREMENT(X) \ +statistic_increment(table->in_use->status_var.X, &LOCK_status) +#define MOVE(X) move_field(X) +#define RECORDS records +#else +#define STATISTIC_INCREMENT(X) ha_statistic_increment(&SSV::X) +#define MOVE(X) move_field_offset(X) +#define RECORDS stats.records +#endif + +static HASH oqgraph_open_tables; +static pthread_mutex_t LOCK_oqgraph; +static bool oqgraph_init_done= 0; + +#if MYSQL_VERSION_ID >= 50130 +#define HASH_KEY_LENGTH size_t +#else +#define HASH_KEY_LENGTH uint +#endif + +static uchar* get_key(const uchar *ptr, HASH_KEY_LENGTH *length, + my_bool) +{ + const OQGRAPH_INFO *share= (const OQGRAPH_INFO*) ptr; + *length= strlen(share->name); + return (uchar*) share->name; +} + +#if MYSQL_VERSION_ID >= 50100 +static handler* oqgraph_create_handler(handlerton *hton, TABLE_SHARE *table, + MEM_ROOT *mem_root) +{ + return new (mem_root) ha_oqgraph(hton, table); +} + +static int oqgraph_init(handlerton *hton) +{ +#else +static bool oqgraph_init() +{ + if (have_oqgraph == SHOW_OPTION_DISABLED) + return 1; +#endif + if (pthread_mutex_init(&LOCK_oqgraph, MY_MUTEX_INIT_FAST)) + goto error; + if (hash_init(&oqgraph_open_tables, &my_charset_bin, 32, 0, 0, + get_key, 0, 0)) + { + pthread_mutex_destroy(&LOCK_oqgraph); + goto error; + } +#if MYSQL_VERSION_ID >= 50100 + hton->state= SHOW_OPTION_YES; + hton->db_type= DB_TYPE_AUTOASSIGN; + hton->create= oqgraph_create_handler; + hton->flags= HTON_NO_FLAGS; +#endif + oqgraph_init_done= TRUE; + return 0; +error: +#if MYSQL_VERSION_ID < 50100 + have_oqgraph= SHOW_OPTION_DISABLED; +#endif + return 1; +} + +#if MYSQL_VERSION_ID >= 50100 +static int oqgraph_fini(void *) +{ + hash_free(&oqgraph_open_tables); + pthread_mutex_destroy(&LOCK_oqgraph); + oqgraph_init_done= FALSE; + return 0; +} +#endif + +static OQGRAPH_INFO *get_share(const char *name, TABLE *table=0) +{ + OQGRAPH_INFO *share; + uint length= strlen(name); + + safe_mutex_assert_owner(&LOCK_oqgraph); + if (!(share= (OQGRAPH_INFO*) hash_search(&oqgraph_open_tables, + (byte*) name, length))) + { + if (!table || + !(share= new OQGRAPH_INFO)) + return 0; + share->use_count= share->key_stat_version= share->records= 0; + share->dropped= 0; + strmov(share->name, name); + if (!(share->graph= oqgraph::create())) + { + delete share; + return 0; + } + if (my_hash_insert(&oqgraph_open_tables, (byte*) share)) + { + oqgraph::free(share->graph); + delete share; + return 0; + } + thr_lock_init(&share->lock); + } + share->use_count++; + return share; +} + +static int free_share(OQGRAPH_INFO *share, bool drop=0) +{ + safe_mutex_assert_owner(&LOCK_oqgraph); + if (!share) + return 0; + if (drop) + { + share->dropped= true; + hash_delete(&oqgraph_open_tables, (byte*) share); + } + if (!--share->use_count) + { + if (share->dropped) + { + thr_lock_delete(&share->lock); + oqgraph::free(share->graph); + delete share; + } + } + return 0; +} + +static int error_code(int res) +{ + switch (res) + { + case oqgraph::OK: + return 0; + case oqgraph::NO_MORE_DATA: + return HA_ERR_END_OF_FILE; + case oqgraph::EDGE_NOT_FOUND: + return HA_ERR_KEY_NOT_FOUND; + case oqgraph::INVALID_WEIGHT: + return HA_ERR_AUTOINC_ERANGE; + case oqgraph::DUPLICATE_EDGE: + return HA_ERR_FOUND_DUPP_KEY; + case oqgraph::CANNOT_ADD_VERTEX: + case oqgraph::CANNOT_ADD_EDGE: + return HA_ERR_RECORD_FILE_FULL; + case oqgraph::MISC_FAIL: + default: + return HA_ERR_CRASHED_ON_USAGE; + } +} + +/** + * Check if table complies with our designated structure + * + * ColName Type Attributes + * ======= ======== ============= + * latch SMALLINT UNSIGNED NULL + * origid BIGINT UNSIGNED NULL + * destid BIGINT UNSIGNED NULL + * weight DOUBLE NULL + * seq BIGINT UNSIGNED NULL + * linkid BIGINT UNSIGNED NULL + * ================================= + * + CREATE TABLE foo ( + latch SMALLINT UNSIGNED NULL, + origid BIGINT UNSIGNED NULL, + destid BIGINT UNSIGNED NULL, + weight DOUBLE NULL, + seq BIGINT UNSIGNED NULL, + linkid BIGINT UNSIGNED NULL, + KEY (latch, origid, destid) USING HASH, + KEY (latch, destid, origid) USING HASH + ) ENGINE=OQGRAPH + + */ +static int oqgraph_check_table_structure (TABLE *table_arg) +{ + int i; + struct { const char *colname; int coltype; } skel[] = { + { "latch" , MYSQL_TYPE_SHORT }, + { "origid", MYSQL_TYPE_LONGLONG }, + { "destid", MYSQL_TYPE_LONGLONG }, + { "weight", MYSQL_TYPE_DOUBLE }, + { "seq" , MYSQL_TYPE_LONGLONG }, + { "linkid", MYSQL_TYPE_LONGLONG }, + { NULL , 0} + }; + + DBUG_ENTER("ha_oqgraph::table_structure_ok"); + + Field **field= table_arg->field; + for (i= 0; *field && skel[i].colname; i++, field++) { + /* Check Column Type */ + if ((*field)->type() != skel[i].coltype) + DBUG_RETURN(-1); + if (skel[i].coltype != MYSQL_TYPE_DOUBLE) { + /* Check Is UNSIGNED */ + if (!((*field)->flags & UNSIGNED_FLAG )) + DBUG_RETURN(-1); + } + /* Check THAT NOT NULL isn't set */ + if ((*field)->flags & NOT_NULL_FLAG) + DBUG_RETURN(-1); + /* Check the column name */ + if (strcmp(skel[i].colname,(*field)->field_name)) + DBUG_RETURN(-1); + } + + if (skel[i].colname || *field || !table_arg->key_info || !table_arg->s->keys) + DBUG_RETURN(-1); + + KEY *key= table_arg->key_info; + for (uint i= 0; i < table_arg->s->keys; ++i, ++key) + { + Field **field= table_arg->field; + /* check that the first key part is the latch and it is a hash key */ + if (!(field[0] == key->key_part[0].field && + HA_KEY_ALG_HASH == key->algorithm)) + DBUG_RETURN(-1); + if (key->key_parts == 3) + { + /* KEY (latch, origid, destid) USING HASH */ + /* KEY (latch, destid, origid) USING HASH */ + if (!(field[1] == key->key_part[1].field && + field[2] == key->key_part[2].field) && + !(field[1] == key->key_part[2].field && + field[2] == key->key_part[1].field)) + DBUG_RETURN(-1); + } + else + DBUG_RETURN(-1); + } + + DBUG_RETURN(0); +} + +/***************************************************************************** +** OQGRAPH tables +*****************************************************************************/ + +#if MYSQL_VERSION_ID >= 50100 +ha_oqgraph::ha_oqgraph(handlerton *hton, TABLE_SHARE *table_arg) + : handler(hton, table_arg), +#else +ha_oqgraph::ha_oqgraph(TABLE *table_arg) + : handler(&oqgraph_hton, table_arg), +#endif + share(0), graph(0), records_changed(0), key_stat_version(0) +{ } + + +static const char *ha_oqgraph_exts[] = +{ + NullS +}; + +const char **ha_oqgraph::bas_ext() const +{ + return ha_oqgraph_exts; +} + +#if MYSQL_VERSION_ID >= 50100 +ulonglong ha_oqgraph::table_flags() const +#else +ulong ha_oqgraph::table_flags() const +#endif +{ + return (HA_NO_BLOBS | HA_NULL_IN_KEY | + HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | + HA_BINLOG_STMT_CAPABLE | HA_BINLOG_ROW_CAPABLE); +} + +ulong ha_oqgraph::index_flags(uint inx, uint part, bool all_parts) const +{ + return HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR; +} + +int ha_oqgraph::open(const char *name, int mode, uint test_if_locked) +{ + pthread_mutex_lock(&LOCK_oqgraph); + if ((share = get_share(name, table))) + { + ref_length= oqgraph::sizeof_ref; + } + + if (share) + { + /* Initialize variables for the opened table */ + thr_lock_data_init(&share->lock, &lock, NULL); + + graph= oqgraph::create(share->graph); + + /* + We cannot run update_key_stats() here because we do not have a + lock on the table. The 'records' count might just be changed + temporarily at this moment and we might get wrong statistics (Bug + #10178). Instead we request for update. This will be done in + ha_oqgraph::info(), which is always called before key statistics are + used. + */ + key_stat_version= share->key_stat_version-1; + } + pthread_mutex_unlock(&LOCK_oqgraph); + + return (share ? 0 : 1); +} + +int ha_oqgraph::close(void) +{ + pthread_mutex_lock(&LOCK_oqgraph); + oqgraph::free(graph); graph= 0; + int res= free_share(share); + pthread_mutex_unlock(&LOCK_oqgraph); + return error_code(res); +} + +void ha_oqgraph::update_key_stats() +{ + for (uint i= 0; i < table->s->keys; i++) + { + KEY *key=table->key_info+i; + if (!key->rec_per_key) + continue; + if (key->algorithm != HA_KEY_ALG_BTREE) + { + if (key->flags & HA_NOSAME) + key->rec_per_key[key->key_parts-1]= 1; + else + { + unsigned vertices= graph->vertices_count(); + unsigned edges= graph->edges_count(); + uint no_records= vertices ? 2 * (edges + vertices) / vertices : 2; + if (no_records < 2) + no_records= 2; + key->rec_per_key[key->key_parts-1]= no_records; + } + } + } + records_changed= 0; + /* At the end of update_key_stats() we can proudly claim they are OK. */ + key_stat_version= share->key_stat_version; +} + + +int ha_oqgraph::write_row(byte * buf) +{ + int res= oqgraph::MISC_FAIL; + Field ** const field= table->field; + STATISTIC_INCREMENT(ha_write_count); + +#if MYSQL_VERSION_ID >= 50100 + my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); +#endif + my_ptrdiff_t ptrdiff= buf - table->record[0]; + + if (ptrdiff) + { + field[1]->MOVE(ptrdiff); + field[2]->MOVE(ptrdiff); + field[3]->MOVE(ptrdiff); + } + + if (!field[1]->is_null() && !field[2]->is_null()) + { + VertexID orig_id= (VertexID) field[1]->val_int(); + VertexID dest_id= (VertexID) field[2]->val_int(); + EdgeWeight weight= 1; + + if (!field[3]->is_null()) + weight= (EdgeWeight) field[3]->val_real(); + + if (!(res= graph->insert_edge(orig_id, dest_id, weight, replace_dups))) + { + ++records_changed; + share->records++; + } + if (res == oqgraph::DUPLICATE_EDGE && ignore_dups && !insert_dups) + res= oqgraph::OK; + } + + if (ptrdiff) + { + field[1]->MOVE(-ptrdiff); + field[2]->MOVE(-ptrdiff); + field[3]->MOVE(-ptrdiff); + } +#if MYSQL_VERSION_ID >= 50100 + dbug_tmp_restore_column_map(table->read_set, old_map); +#endif + + if (!res && records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records) + { + /* + We can perform this safely since only one writer at the time is + allowed on the table. + */ + share->key_stat_version++; + } + + return error_code(res); +} + +int ha_oqgraph::update_row(const byte * old, byte * buf) +{ + int res= oqgraph::MISC_FAIL; + VertexID orig_id, dest_id; + EdgeWeight weight= 1; + Field **field= table->field; + STATISTIC_INCREMENT(ha_update_count); + +#if MYSQL_VERSION_ID >= 50100 + my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); +#endif + my_ptrdiff_t ptrdiff= buf - table->record[0]; + + if (ptrdiff) + { + field[0]->MOVE(ptrdiff); + field[1]->MOVE(ptrdiff); + field[2]->MOVE(ptrdiff); + field[3]->MOVE(ptrdiff); + } + + if (inited == INDEX || inited == RND) + { + VertexID *origp= 0, *destp= 0; + EdgeWeight *weightp= 0; + if (!field[1]->is_null()) + *(origp= &orig_id)= (VertexID) field[1]->val_int(); + if (!field[2]->is_null()) + *(destp= &dest_id)= (VertexID) field[2]->val_int(); + if (!field[3]->is_null()) + *(weightp= &weight)= (EdgeWeight) field[3]->val_real(); + + my_ptrdiff_t ptrdiff2= old - buf; + + field[0]->MOVE(ptrdiff2); + field[1]->MOVE(ptrdiff2); + field[2]->MOVE(ptrdiff2); + field[3]->MOVE(ptrdiff2); + + if (field[0]->is_null()) + { + if (!origp == field[1]->is_null() && + *origp == (VertexID) field[1]->val_int()) + origp= 0; + if (!destp == field[2]->is_null() && + *destp == (VertexID) field[2]->val_int()) + origp= 0; + if (!weightp == field[3]->is_null() && + *weightp == (VertexID) field[3]->val_real()) + weightp= 0; + + if (!(res= graph->modify_edge(oqgraph::current_row(), + origp, destp, weightp, replace_dups))) + ++records_changed; + else if (ignore_dups && res == oqgraph::DUPLICATE_EDGE) + res= oqgraph::OK; + } + + field[0]->MOVE(-ptrdiff2); + field[1]->MOVE(-ptrdiff2); + field[2]->MOVE(-ptrdiff2); + field[3]->MOVE(-ptrdiff2); + } + + if (ptrdiff) + { + field[0]->MOVE(-ptrdiff); + field[1]->MOVE(-ptrdiff); + field[2]->MOVE(-ptrdiff); + field[3]->MOVE(-ptrdiff); + } +#if MYSQL_VERSION_ID >= 50100 + dbug_tmp_restore_column_map(table->read_set, old_map); +#endif + + if (!res && records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records) + { + /* + We can perform this safely since only one writer at the time is + allowed on the table. + */ + share->key_stat_version++; + } + return error_code(res); +} + +int ha_oqgraph::delete_row(const byte * buf) +{ + int res= oqgraph::EDGE_NOT_FOUND; + Field **field= table->field; + STATISTIC_INCREMENT(ha_delete_count); + + if (inited == INDEX || inited == RND) + { + if ((res= graph->delete_edge(oqgraph::current_row())) == oqgraph::OK) + { + ++records_changed; + share->records--; + } + } + if (res != oqgraph::OK) + { +#if MYSQL_VERSION_ID >= 50100 + my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); +#endif + my_ptrdiff_t ptrdiff= buf - table->record[0]; + + if (ptrdiff) + { + field[0]->MOVE(ptrdiff); + field[1]->MOVE(ptrdiff); + field[2]->MOVE(ptrdiff); + } + + if (field[0]->is_null() && !field[1]->is_null() && !field[2]->is_null()) + { + VertexID orig_id= (VertexID) field[1]->val_int(); + VertexID dest_id= (VertexID) field[2]->val_int(); + + if ((res= graph->delete_edge(orig_id, dest_id)) == oqgraph::OK) + { + ++records_changed; + share->records--; + } + } + + if (ptrdiff) + { + field[0]->MOVE(-ptrdiff); + field[1]->MOVE(-ptrdiff); + field[2]->MOVE(-ptrdiff); + } +#if MYSQL_VERSION_ID >= 50100 + dbug_tmp_restore_column_map(table->read_set, old_map); +#endif + } + + if (!res && table->s->tmp_table == NO_TMP_TABLE && + records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records) + { + /* + We can perform this safely since only one writer at the time is + allowed on the table. + */ + share->key_stat_version++; + } + return error_code(res); +} + +int ha_oqgraph::index_read(byte * buf, const byte * key, uint key_len, + enum ha_rkey_function find_flag) +{ + DBUG_ASSERT(inited==INDEX); + return index_read_idx(buf, active_index, key, key_len, find_flag); +} + +int ha_oqgraph::index_next_same(byte *buf, const byte *key, uint key_len) +{ + int res; + open_query::row row; + DBUG_ASSERT(inited==INDEX); + STATISTIC_INCREMENT(ha_read_key_count); + if (!(res= graph->fetch_row(row))) + res= fill_record(buf, row); + table->status= res ? STATUS_NOT_FOUND : 0; + return error_code(res); +} + +int ha_oqgraph::index_read_idx(byte * buf, uint index, const byte * key, + uint key_len, enum ha_rkey_function find_flag) +{ + Field **field= table->field; + KEY *key_info= table->key_info + index; + int res; + VertexID orig_id, dest_id; + int latch; + VertexID *orig_idp=0, *dest_idp=0; + int *latchp=0; + open_query::row row; + STATISTIC_INCREMENT(ha_read_key_count); + + bmove_align(buf, table->s->default_values, table->s->reclength); + key_restore(buf, (byte*) key, key_info, key_len); + +#if MYSQL_VERSION_ID >= 50100 + my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); +#endif + my_ptrdiff_t ptrdiff= buf - table->record[0]; + + if (ptrdiff) + { + field[0]->MOVE(ptrdiff); + field[1]->MOVE(ptrdiff); + field[2]->MOVE(ptrdiff); + } + + if (!field[0]->is_null()) + { + latch= (int) field[0]->val_int(); + latchp= &latch; + } + + if (!field[1]->is_null()) + { + orig_id= (VertexID) field[1]->val_int(); + orig_idp= &orig_id; + } + + if (!field[2]->is_null()) + { + dest_id= (VertexID) field[2]->val_int(); + dest_idp= &dest_id; + } + + if (ptrdiff) + { + field[0]->MOVE(-ptrdiff); + field[1]->MOVE(-ptrdiff); + field[2]->MOVE(-ptrdiff); + } +#if MYSQL_VERSION_ID >= 50100 + dbug_tmp_restore_column_map(table->read_set, old_map); +#endif + + res= graph->search(latchp, orig_idp, dest_idp); + + if (!res && !(res= graph->fetch_row(row))) + res= fill_record(buf, row); + table->status = res ? STATUS_NOT_FOUND : 0; + return error_code(res); +} + +int ha_oqgraph::fill_record(byte *record, const open_query::row &row) +{ + Field **field= table->field; + + bmove_align(record, table->s->default_values, table->s->reclength); + +#if MYSQL_VERSION_ID >= 50100 + my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); +#endif + my_ptrdiff_t ptrdiff= record - table->record[0]; + + if (ptrdiff) + { + field[0]->MOVE(ptrdiff); + field[1]->MOVE(ptrdiff); + field[2]->MOVE(ptrdiff); + field[3]->MOVE(ptrdiff); + field[4]->MOVE(ptrdiff); + field[5]->MOVE(ptrdiff); + } + + // just each field specifically, no sense iterating + if (row.latch_indicator) + { + field[0]->set_notnull(); + field[0]->store((longlong) row.latch, 0); + } + + if (row.orig_indicator) + { + field[1]->set_notnull(); + field[1]->store((longlong) row.orig, 0); + } + + if (row.dest_indicator) + { + field[2]->set_notnull(); + field[2]->store((longlong) row.dest, 0); + } + + if (row.weight_indicator) + { + field[3]->set_notnull(); + field[3]->store((double) row.weight); + } + + if (row.seq_indicator) + { + field[4]->set_notnull(); + field[4]->store((longlong) row.seq, 0); + } + + if (row.link_indicator) + { + field[5]->set_notnull(); + field[5]->store((longlong) row.link, 0); + } + + if (ptrdiff) + { + field[0]->MOVE(-ptrdiff); + field[1]->MOVE(-ptrdiff); + field[2]->MOVE(-ptrdiff); + field[3]->MOVE(-ptrdiff); + field[4]->MOVE(-ptrdiff); + field[5]->MOVE(-ptrdiff); + } +#if MYSQL_VERSION_ID >= 50100 + dbug_tmp_restore_column_map(table->write_set, old_map); +#endif + + return 0; +} + +int ha_oqgraph::rnd_init(bool scan) +{ + return error_code(graph->random(scan)); +} + +int ha_oqgraph::rnd_next(byte *buf) +{ + int res; + open_query::row row; + STATISTIC_INCREMENT(ha_read_rnd_next_count); + if (!(res= graph->fetch_row(row))) + res= fill_record(buf, row); + table->status= res ? STATUS_NOT_FOUND: 0; + return error_code(res); +} + +int ha_oqgraph::rnd_pos(byte * buf, byte *pos) +{ + int res; + open_query::row row; + STATISTIC_INCREMENT(ha_read_rnd_count); + if (!(res= graph->fetch_row(row, pos))) + res= fill_record(buf, row); + table->status=res ? STATUS_NOT_FOUND: 0; + return error_code(res); +} + +void ha_oqgraph::position(const byte *record) +{ + graph->row_ref((void*) ref); // Ref is aligned +} + +int ha_oqgraph::cmp_ref(const byte *ref1, const byte *ref2) +{ + return memcmp(ref1, ref2, oqgraph::sizeof_ref); +} + +int ha_oqgraph::info(uint flag) +{ + RECORDS= graph->vertices_count() + graph->edges_count(); +#if 0 + records= hp_info.records; + deleted= hp_info.deleted; + errkey= hp_info.errkey; + mean_rec_length= hp_info.reclength; + data_file_length= hp_info.data_length; + index_file_length= hp_info.index_length; + max_data_file_length= hp_info.max_records* hp_info.reclength; + delete_length= hp_info.deleted * hp_info.reclength; +#endif + /* + If info() is called for the first time after open(), we will still + have to update the key statistics. Hoping that a table lock is now + in place. + */ + if (key_stat_version != share->key_stat_version) + update_key_stats(); + return 0; +} + +int ha_oqgraph::extra(enum ha_extra_function operation) +{ + switch (operation) + { + case HA_EXTRA_IGNORE_DUP_KEY: + ignore_dups= true; + break; + case HA_EXTRA_NO_IGNORE_DUP_KEY: + ignore_dups= false; + insert_dups= false; + break; + case HA_EXTRA_WRITE_CAN_REPLACE: + replace_dups= true; + break; + case HA_EXTRA_WRITE_CANNOT_REPLACE: + replace_dups= false; + break; + case HA_EXTRA_INSERT_WITH_UPDATE: + insert_dups= true; + break; + default: + break; + } + return 0; +} + +int ha_oqgraph::delete_all_rows() +{ + int res; + if (!(res= graph->delete_all())) + { + share->records= 0; + } + + if (!res && table->s->tmp_table == NO_TMP_TABLE) + { + /* + We can perform this safely since only one writer at the time is + allowed on the table. + */ + share->key_stat_version++; + } + return error_code(res); +} + +int ha_oqgraph::external_lock(THD *thd, int lock_type) +{ + return 0; // No external locking +} + + +THR_LOCK_DATA **ha_oqgraph::store_lock(THD *thd, + THR_LOCK_DATA **to, + enum thr_lock_type lock_type) +{ + if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) + lock.type=lock_type; + *to++= &lock; + return to; +} + +/* + We have to ignore ENOENT entries as the HEAP table is created on open and + not when doing a CREATE on the table. +*/ + +int ha_oqgraph::delete_table(const char *name) +{ + int res= 0; + OQGRAPH_INFO *share; + pthread_mutex_lock(&LOCK_oqgraph); + if ((share= get_share(name))) + { + res= free_share(share, true); + } + pthread_mutex_unlock(&LOCK_oqgraph); + return error_code(res); +} + +int ha_oqgraph::rename_table(const char * from, const char * to) +{ + pthread_mutex_lock(&LOCK_oqgraph); + if (OQGRAPH_INFO *share= get_share(from)) + { + strmov(share->name, to); + hash_update(&oqgraph_open_tables, (byte*) share, + (byte*) from, strlen(from)); + } + pthread_mutex_unlock(&LOCK_oqgraph); + return 0; +} + + +ha_rows ha_oqgraph::records_in_range(uint inx, key_range *min_key, + key_range *max_key) +{ + KEY *key=table->key_info+inx; + //if (key->algorithm == HA_KEY_ALG_BTREE) + // return btree_records_in_range(file, inx, min_key, max_key); + + if (!min_key || !max_key || + min_key->length != max_key->length || + min_key->length < key->key_length - key->key_part[2].store_length || + min_key->flag != HA_READ_KEY_EXACT || + max_key->flag != HA_READ_AFTER_KEY) + { + if (min_key->length == key->key_part[0].store_length) + { + // If latch is not null and equals 0, return # nodes + DBUG_ASSERT(key->key_part[0].store_length == 3); + if (key->key_part[0].null_bit && !min_key->key[0] && + !min_key->key[1] && !min_key->key[2]) + return graph->vertices_count(); + } + return HA_POS_ERROR; // Can only use exact keys + } + + if (RECORDS <= 1) + return RECORDS; + + /* Assert that info() did run. We need current statistics here. */ + DBUG_ASSERT(key_stat_version == share->key_stat_version); + ha_rows result= key->rec_per_key[key->key_parts-1]; + + return result; +} + + +int ha_oqgraph::create(const char *name, TABLE *table_arg, + HA_CREATE_INFO *create_info) +{ + int res = -1; + OQGRAPH_INFO *share; + + pthread_mutex_lock(&LOCK_oqgraph); + if ((share= get_share(name))) + { + free_share(share); + } + else + { + if (!oqgraph_check_table_structure(table_arg)) + res= 0;; + } + pthread_mutex_unlock(&LOCK_oqgraph); + + if (this->share) + info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); + return error_code(res); +} + + +void ha_oqgraph::update_create_info(HA_CREATE_INFO *create_info) +{ + table->file->info(HA_STATUS_AUTO); + //if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) + // create_info->auto_increment_value= auto_increment_value; +} + +#if MYSQL_VERSION_ID >= 50100 +struct st_mysql_storage_engine oqgraph_storage_engine= +{ MYSQL_HANDLERTON_INTERFACE_VERSION }; + +mysql_declare_plugin(oqgraph) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &oqgraph_storage_engine, + "OQGRAPH", + "Arjen Lentz & Antony T Curtis, Open Query", + oqgraph_description, + PLUGIN_LICENSE_GPL, + (int (*)(void*)) oqgraph_init, /* Plugin Init */ + oqgraph_fini, /* Plugin Deinit */ + 0x0200, /* Version: 2.0 */ + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ +} +mysql_declare_plugin_end; +#endif + +#endif diff --git a/storage/oqgraph/ha_oqgraph.h b/storage/oqgraph/ha_oqgraph.h new file mode 100644 index 00000000000..dcc14b074da --- /dev/null +++ b/storage/oqgraph/ha_oqgraph.h @@ -0,0 +1,114 @@ +/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query + Portions of this file copyright (C) 2000-2006 MySQL AB + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* ====================================================================== + Open Query Graph Computation Engine, based on a concept by Arjen Lentz + Mk.II implementation by Antony Curtis & Arjen Lentz + For more information, documentation, support, enhancement engineering, + and non-GPL licensing, see http://openquery.com/graph + or contact graph@openquery.com + For packaged binaries, see http://ourdelta.org + ====================================================================== +*/ + +#ifdef USE_PRAGMA_INTERFACE +#pragma interface /* gcc class implementation */ +#endif + + +typedef struct oqgraph_info_st OQGRAPH_INFO; + +#if MYSQL_VERSION_ID >= 50120 +typedef uchar byte; +#endif + +namespace open_query +{ + struct row; + class oqgraph; +} + +/* class for the the Open Query Graph handler */ + +class ha_oqgraph: public handler +{ + OQGRAPH_INFO *share; + open_query::oqgraph *graph; + THR_LOCK_DATA lock; + /* number of records changed since last statistics update */ + uint records_changed; + uint key_stat_version; + bool replace_dups, ignore_dups, insert_dups; + + int fill_record(byte*, const open_query::row&); + +public: +#if MYSQL_VERSION_ID >= 50100 + ha_oqgraph(handlerton *hton, TABLE_SHARE *table); + ulonglong table_flags() const; +#else + ha_oqgraph(TABLE *table); + ulong table_flags() const; +#endif + ~ha_oqgraph() {} + const char *table_type() const + { + return "OQGRAPH"; + } + const char *index_type(uint inx) + { + return "HASH"; + } + /* Rows also use a fixed-size format */ + enum row_type get_row_type() const { return ROW_TYPE_FIXED; } + const char **bas_ext() const; + ulong index_flags(uint inx, uint part, bool all_parts) const; + uint max_supported_keys() const { return MAX_KEY; } + uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; } + double scan_time() { return (double) 1000000000; } + double read_time(uint index, uint ranges, ha_rows rows) + { return 1; } + + int open(const char *name, int mode, uint test_if_locked); + int close(void); + int write_row(byte * buf); + int update_row(const byte * old_data, byte * new_data); + int delete_row(const byte * buf); + int index_read(byte * buf, const byte * key, + uint key_len, enum ha_rkey_function find_flag); + int index_read_idx(byte * buf, uint idx, const byte * key, + uint key_len, enum ha_rkey_function find_flag); + int index_next_same(byte * buf, const byte * key, uint key_len); + int rnd_init(bool scan); + int rnd_next(byte *buf); + int rnd_pos(byte * buf, byte *pos); + void position(const byte *record); + int info(uint); + int extra(enum ha_extra_function operation); + int external_lock(THD *thd, int lock_type); + int delete_all_rows(void); + ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); + int delete_table(const char *from); + int rename_table(const char * from, const char * to); + int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); + void update_create_info(HA_CREATE_INFO *create_info); + + THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, + enum thr_lock_type lock_type); + int cmp_ref(const byte *ref1, const byte *ref2); +private: + void update_key_stats(); +}; diff --git a/storage/oqgraph/oqgraph_config.h.in b/storage/oqgraph/oqgraph_config.h.in new file mode 100644 index 00000000000..18dad70a75d --- /dev/null +++ b/storage/oqgraph/oqgraph_config.h.in @@ -0,0 +1,73 @@ +/* src/oqgraph_config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Enables DTRACE Support */ +#undef HAVE_DTRACE + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <syslimits.h> header file. */ +#undef HAVE_SYSLIMITS_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Source directory for MySQL */ +#undef MYSQL_SRC + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t diff --git a/storage/oqgraph/oqgraph_probes.d b/storage/oqgraph/oqgraph_probes.d new file mode 100644 index 00000000000..bfdee29ba6e --- /dev/null +++ b/storage/oqgraph/oqgraph_probes.d @@ -0,0 +1,19 @@ +/* Copyright (C) 2004-2005 MySQL AB + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +provider oqgraph { + probe open(); + probe close(); +}; diff --git a/storage/oqgraph/plug.in b/storage/oqgraph/plug.in new file mode 100644 index 00000000000..d5ebe2e232a --- /dev/null +++ b/storage/oqgraph/plug.in @@ -0,0 +1,39 @@ +MYSQL_STORAGE_ENGINE(oqgraph,,[Graph Storage Engine], + [Open Query Graph Computation Engine], []) +MYSQL_PLUGIN_DYNAMIC(oqgraph, [ha_oqgraph.la]) +MYSQL_PLUGIN_ACTIONS(oqgraph,[ + AC_LANG_PUSH([C++]) + AC_MSG_CHECKING([whether compiler supports -fvisibility-inlines-hidden]) + OLD_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS -fvisibility-inlines-hidden" + AC_TRY_COMPILE([],[],[ + AM_CONDITIONAL(HAVE_FVISIBILITY_INLINES_HIDDEN, true) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + CXXFLAGS=$OLD_CXXFLAGS + AC_LANG_POP() +]) + +AM_CONDITIONAL([BUILD_OQGRAPH_FOR_MYSQL], true) +AM_CONDITIONAL([BUILD_OQGRAPH_STANDALONE], false) +AM_CONDITIONAL([HAVE_DTRACE], false) +AM_CONDITIONAL(HAVE_FVISIBILITY_INLINES_HIDDEN, false) + +AC_LANG_PUSH([C++]) + +AC_MSG_CHECKING([for Boost usable by OQGraph engine]) +AC_PREPROC_IFELSE( + [ +#include <boost/version.hpp> +#if BOOST_VERSION >= 104000 +#else +#error oops +#endif + ], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + MYSQL_PLUGIN_WITHOUT(oqgraph)]) + +AC_LANG_POP() diff --git a/storage/pbxt/CMakeLists.txt b/storage/pbxt/CMakeLists.txt index dca481ecbcf..0263d65afaa 100644 --- a/storage/pbxt/CMakeLists.txt +++ b/storage/pbxt/CMakeLists.txt @@ -22,6 +22,8 @@ # # This file is used to make the Windows version +INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYSQL_SERVER") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMYSQL_SERVER") @@ -98,3 +100,4 @@ src/xt_defs.h src/xt_errno.h) MYSQL_STORAGE_ENGINE(PBXT) + diff --git a/storage/pbxt/src/cache_xt.cc b/storage/pbxt/src/cache_xt.cc index 24e42d9e984..090250dd802 100644 --- a/storage/pbxt/src/cache_xt.cc +++ b/storage/pbxt/src/cache_xt.cc @@ -717,6 +717,11 @@ xtPublic void xt_ind_exit(XTThreadPtr self) ind_handle_exit(self); if (ind_cac_globals.cg_blocks) { + XTIndBlockPtr block = ind_cac_globals.cg_blocks; + for (u_int i=0; i<ind_cac_globals.cg_block_count; i++) { + XT_IPAGE_FREE_LOCK(self, &block->cb_lock); + block++; + } xt_free(self, ind_cac_globals.cg_blocks); ind_cac_globals.cg_blocks = NULL; xt_free_mutex(&ind_cac_globals.cg_lock); diff --git a/storage/pbxt/src/heap_xt.cc b/storage/pbxt/src/heap_xt.cc index a4e3fec1611..11331f6489f 100644 --- a/storage/pbxt/src/heap_xt.cc +++ b/storage/pbxt/src/heap_xt.cc @@ -109,6 +109,7 @@ xtPublic void xt_heap_release(XTThreadPtr self, XTHeapPtr hp) if (hp->h_finalize) (*hp->h_finalize)(self, hp); xt_spinlock_unlock(&hp->h_lock); + xt_spinlock_free(NULL, &hp->h_lock); xt_free(self, hp); return; } diff --git a/storage/pbxt/src/lock_xt.cc b/storage/pbxt/src/lock_xt.cc index 5dbba9db83a..e4a38716845 100644 --- a/storage/pbxt/src/lock_xt.cc +++ b/storage/pbxt/src/lock_xt.cc @@ -726,11 +726,15 @@ xtBool xt_init_row_locks(XTRowLocksPtr rl) rl->rl_groups[i].lg_list_in_use = 0; rl->rl_groups[i].lg_list = NULL; } + rl->valid = 1; return OK; } void xt_exit_row_locks(XTRowLocksPtr rl) { + if (!rl->valid) + return; + for (int i=0; i<XT_ROW_LOCK_GROUP_COUNT; i++) { xt_spinlock_free(NULL, &rl->rl_groups[i].lg_lock); rl->rl_groups[i].lg_wait_queue = NULL; @@ -741,6 +745,7 @@ void xt_exit_row_locks(XTRowLocksPtr rl) rl->rl_groups[i].lg_list = NULL; } } + rl->valid = 0; } /* diff --git a/storage/pbxt/src/lock_xt.h b/storage/pbxt/src/lock_xt.h index 4e5af648c37..28737478d48 100644 --- a/storage/pbxt/src/lock_xt.h +++ b/storage/pbxt/src/lock_xt.h @@ -658,6 +658,7 @@ typedef struct XTLockGroup { struct XTLockWait; typedef struct XTRowLocks { + int valid; XTLockGroupRec rl_groups[XT_ROW_LOCK_GROUP_COUNT]; void xt_cancel_temp_lock(XTLockWaitPtr lw); diff --git a/storage/pbxt/src/pthread_xt.cc b/storage/pbxt/src/pthread_xt.cc index c5dc2e41fdd..64c03db734c 100755 --- a/storage/pbxt/src/pthread_xt.cc +++ b/storage/pbxt/src/pthread_xt.cc @@ -547,44 +547,23 @@ xtPublic void xt_p_init_threading(void) xtPublic int xt_p_set_low_priority(pthread_t thr) { - if (pth_min_priority == pth_max_priority) { - /* Under Linux the priority of normal (non-runtime) - * threads are set using the standard methods - * for setting process priority. - */ - - /* We could set who == 0 because it should have the same affect - * as using the PID. - */ - - /* -20 = highest, 20 = lowest */ -#ifdef SET_GLOBAL_PRIORITY - if (setpriority(PRIO_PROCESS, getpid(), 20) == -1) - return errno; -#endif - return 0; - } - return pth_set_priority(thr, pth_min_priority); + if (pth_min_priority != pth_max_priority) + return pth_set_priority(thr, pth_min_priority); + return 0; } xtPublic int xt_p_set_normal_priority(pthread_t thr) { - if (pth_min_priority == pth_max_priority) { - if (setpriority(PRIO_PROCESS, getpid(), 0) == -1) - return errno; - return 0; - } - return pth_set_priority(thr, pth_normal_priority); + if (pth_min_priority != pth_max_priority) + return pth_set_priority(thr, pth_normal_priority); + return 0; } xtPublic int xt_p_set_high_priority(pthread_t thr) { - if (pth_min_priority == pth_max_priority) { - if (setpriority(PRIO_PROCESS, getpid(), -20) == -1) - return errno; - return 0; - } - return pth_set_priority(thr, pth_max_priority); + if (pth_min_priority != pth_max_priority) + return pth_set_priority(thr, pth_max_priority); + return 0; } #ifdef DEBUG_LOCKING diff --git a/storage/pbxt/src/thread_xt.cc b/storage/pbxt/src/thread_xt.cc index 171470f2bba..72bfab0921c 100644 --- a/storage/pbxt/src/thread_xt.cc +++ b/storage/pbxt/src/thread_xt.cc @@ -1175,7 +1175,7 @@ xtPublic XTThreadPtr xt_init_threading(u_int max_threads) #ifdef XT_TRACK_CONNECTIONS if (xt_thr_maximum_threads > XT_TRACK_MAX_CONNS) { xt_log_error(XT_NS_CONTEXT, XT_LOG_FATAL, XT_ERR_TOO_MANY_THREADS, 0, - "XT_TRACK_CONNECTIONS is enabled and xt_thr_maximum_threads > XT_TRACK_MAX_CONNS"); + "XT_TRACK_CONNECTIONS (debugging aid) is enabled and xt_thr_maximum_threads > XT_TRACK_MAX_CONNS. To continue restart with a smaller value for --max-connections"); goto failed; } #endif diff --git a/storage/pbxt/src/xaction_xt.cc b/storage/pbxt/src/xaction_xt.cc index 48abc5d2b66..0d94449c3da 100644 --- a/storage/pbxt/src/xaction_xt.cc +++ b/storage/pbxt/src/xaction_xt.cc @@ -1123,7 +1123,6 @@ xtPublic void xt_xn_init_db(XTThreadPtr self, XTDatabaseHPtr db) */ for (u_int i=0; i<XT_XN_NO_OF_SEGMENTS; i++) { seg = &db->db_xn_idx[i]; - XT_XACT_INIT_LOCK(self, &seg->xs_tab_lock); seg->xs_last_xn_id = db->db_xn_curr_id; } diff --git a/storage/sphinx/CMakeLists.txt b/storage/sphinx/CMakeLists.txt new file mode 100644 index 00000000000..1a46f50f4a7 --- /dev/null +++ b/storage/sphinx/CMakeLists.txt @@ -0,0 +1,12 @@ +INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") + +ADD_DEFINITIONS(-DMYSQL_SERVER) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/extra/yassl/include + ${CMAKE_SOURCE_DIR}/regex) + +SET(SPHINX_SOURCES ha_sphinx.cc) +SET(SPHINX_LIBS ws2_32.lib) +MYSQL_STORAGE_ENGINE(SPHINX) diff --git a/storage/sphinx/Makefile.am b/storage/sphinx/Makefile.am new file mode 100644 index 00000000000..67d01d08484 --- /dev/null +++ b/storage/sphinx/Makefile.am @@ -0,0 +1,54 @@ +# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +# +# 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; either version 2 of the License, or +# (at your option) any later version. +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#called from the top level Makefile + +MYSQLDATAdir = $(localstatedir) +MYSQLSHAREdir = $(pkgdatadir) +MYSQLBASEdir= $(prefix) +MYSQLLIBdir= $(pkglibdir) +pkgplugindir = $(pkglibdir)/plugin +INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ + -I$(top_srcdir)/regex \ + -I$(top_srcdir)/sql \ + -I$(srcdir) + +DEFS= @DEFS@ -D_REENTRANT -D_PTHREADS -DMYSQL_SERVER + +noinst_HEADERS = ha_sphinx.h + +EXTRA_LTLIBRARIES = libsphinx.la ha_sphinx.la +pkgplugin_LTLIBRARIES = @plugin_sphinx_shared_target@ sphinx.la + +ha_sphinx_la_LDFLAGS = -module -rpath $(MYSQLLIBdir) \ + -L$(top_builddir)/libservices -lmysqlservices +ha_sphinx_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_sphinx_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_sphinx_la_SOURCES = ha_sphinx.cc + +sphinx_la_LDFLAGS = -module +sphinx_la_CXXFLAGS = $(AM_CXXFLAGS) +sphinx_la_CFLAGS = $(AM_CFLAGS) +sphinx_la_SOURCES = snippets_udf.cc + +noinst_LTLIBRARIES = @plugin_sphinx_static_target@ +libsphinx_la_CXXFLAGS = $(AM_CXXFLAGS) +libsphinx_la_CFLAGS = $(AM_CFLAGS) +libsphinx_la_SOURCES= ha_sphinx.cc + +EXTRA_DIST = CMakeLists.txt plug.in +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/storage/sphinx/gen_data.php b/storage/sphinx/gen_data.php new file mode 100644 index 00000000000..dac374f095d --- /dev/null +++ b/storage/sphinx/gen_data.php @@ -0,0 +1,37 @@ +<?php + +$file_name= $argv[1]; + +//echo $file_name; + +$cont= file_get_contents($file_name); + +$words= explode(" ", $cont); + +//echo "words: ".(count($words))."\n"; + +$cw = count($words); + +echo "REPLACE INTO test.documents ( id, group_id, date_added, title, content ) VALUES\n"; + + +for ($i=1; $i<=100000; $i++) +{ + $count_words= mt_rand(10,30); + $pred = ""; + for ($j=0; $j<$count_words; $j++) + { + $pred .= chop($words[mt_rand(1, $cw-1)])." "; + } + $count_words= mt_rand(3,5); + $tit = ""; + for ($j=0; $j<$count_words; $j++) + { + $tit .= chop($words[mt_rand(1, $cw-1)])." "; + } + echo "($i,".mt_rand(1,20).",NOW(),'".addslashes($tit)."','".addslashes($pred)."'),\n"; +} + echo "(0,1,now(),'end','eND');\n"; + + +?> diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc new file mode 100644 index 00000000000..6f4f12a318c --- /dev/null +++ b/storage/sphinx/ha_sphinx.cc @@ -0,0 +1,3115 @@ +// +// $Id: ha_sphinx.cc 2058 2009-11-07 04:01:57Z shodan $ +// + +#ifdef USE_PRAGMA_IMPLEMENTATION +#pragma implementation // gcc: Class implementation +#endif + +#if _MSC_VER>=1400 +#define _CRT_SECURE_NO_DEPRECATE 1 +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + +#include <mysql_version.h> + +#if MYSQL_VERSION_ID>50100 +#include "mysql_priv.h" +#include <mysql/plugin.h> +#else +#include "../mysql_priv.h" +#endif + +#include <mysys_err.h> +#include <my_sys.h> + +#ifndef __WIN__ + // UNIX-specific + #include <my_net.h> + #include <netdb.h> + #include <sys/un.h> + + #define RECV_FLAGS MSG_WAITALL + + #define sphSockClose(_sock) ::close(_sock) +#else + // Windows-specific + #include <io.h> + #define strcasecmp stricmp + #define snprintf _snprintf + + #define RECV_FLAGS 0 + + #define sphSockClose(_sock) ::closesocket(_sock) +#endif + +#include <ctype.h> +#include "ha_sphinx.h" + +#ifndef MSG_WAITALL +#define MSG_WAITALL 0 +#endif + +#if _MSC_VER>=1400 +#pragma warning(push,4) +#endif + +///////////////////////////////////////////////////////////////////////////// + +/// there might be issues with min() on different platforms (eg. Gentoo, they say) +#define Min(a,b) ((a)<(b)?(a):(b)) + +/// unaligned RAM accesses are forbidden on SPARC +#if defined(sparc) || defined(__sparc__) +#define UNALIGNED_RAM_ACCESS 0 +#else +#define UNALIGNED_RAM_ACCESS 1 +#endif + +#if MYSQL_VERSION_ID<50100 +#define thd_ha_data(X,Y) (X)->ha_data[sphinx_hton.slot] +#define ha_thd() current_thd +#endif // <50100 + +#if UNALIGNED_RAM_ACCESS + +/// pass-through wrapper +template < typename T > inline T sphUnalignedRead ( const T & tRef ) +{ + return tRef; +} + +/// pass-through wrapper +template < typename T > void sphUnalignedWrite ( void * pPtr, const T & tVal ) +{ + *(T*)pPtr = tVal; +} + +#else + +/// unaligned read wrapper for some architectures (eg. SPARC) +template < typename T > +inline T sphUnalignedRead ( const T & tRef ) +{ + T uTmp; + byte * pSrc = (byte *) &tRef; + byte * pDst = (byte *) &uTmp; + for ( int i=0; i<(int)sizeof(T); i++ ) + *pDst++ = *pSrc++; + return uTmp; +} + +/// unaligned write wrapper for some architectures (eg. SPARC) +template < typename T > +void sphUnalignedWrite ( void * pPtr, const T & tVal ) +{ + byte * pDst = (byte *) pPtr; + byte * pSrc = (byte *) &tVal; + for ( int i=0; i<(int)sizeof(T); i++ ) + *pDst++ = *pSrc++; +} + +#endif + +///////////////////////////////////////////////////////////////////////////// + +// FIXME! make this all dynamic +#define SPHINXSE_MAX_FILTERS 32 + +#define SPHINXSE_DEFAULT_HOST "127.0.0.1" +#define SPHINXSE_DEFAULT_PORT 9312 +#define SPHINXSE_DEFAULT_INDEX "*" + +#define SPHINXSE_SYSTEM_COLUMNS 3 + +#define SPHINXSE_MAX_ALLOC (16*1024*1024) +#define SPHINXSE_MAX_KEYWORDSTATS 4096 + +// FIXME! all the following is cut-n-paste from sphinx.h and searchd.cpp +#define SPHINX_VERSION "0.9.9" + +enum +{ + SPHINX_SEARCHD_PROTO = 1, + SEARCHD_COMMAND_SEARCH = 0, + VER_COMMAND_SEARCH = 0x116, +}; + +/// search query sorting orders +enum ESphSortOrder +{ + SPH_SORT_RELEVANCE = 0, ///< sort by document relevance desc, then by date + SPH_SORT_ATTR_DESC = 1, ///< sort by document date desc, then by relevance desc + SPH_SORT_ATTR_ASC = 2, ///< sort by document date asc, then by relevance desc + SPH_SORT_TIME_SEGMENTS = 3, ///< sort by time segments (hour/day/week/etc) desc, then by relevance desc + SPH_SORT_EXTENDED = 4, ///< sort by SQL-like expression (eg. "@relevance DESC, price ASC, @id DESC") + SPH_SORT_EXPR = 5, ///< sort by expression + + SPH_SORT_TOTAL +}; + +/// search query matching mode +enum ESphMatchMode +{ + SPH_MATCH_ALL = 0, ///< match all query words + SPH_MATCH_ANY, ///< match any query word + SPH_MATCH_PHRASE, ///< match this exact phrase + SPH_MATCH_BOOLEAN, ///< match this boolean query + SPH_MATCH_EXTENDED, ///< match this extended query + SPH_MATCH_FULLSCAN, ///< match all document IDs w/o fulltext query, apply filters + SPH_MATCH_EXTENDED2, ///< extended engine V2 + + SPH_MATCH_TOTAL +}; + +/// search query relevance ranking mode +enum ESphRankMode +{ + SPH_RANK_PROXIMITY_BM25 = 0, ///< default mode, phrase proximity major factor and BM25 minor one + SPH_RANK_BM25 = 1, ///< statistical mode, BM25 ranking only (faster but worse quality) + SPH_RANK_NONE = 2, ///< no ranking, all matches get a weight of 1 + SPH_RANK_WORDCOUNT = 3, ///< simple word-count weighting, rank is a weighted sum of per-field keyword occurence counts + SPH_RANK_PROXIMITY = 4, ///< phrase proximity + SPH_RANK_MATCHANY = 5, ///< emulate old match-any weighting + SPH_RANK_FIELDMASK = 6, ///< sets bits where there were matches + + SPH_RANK_TOTAL, + SPH_RANK_DEFAULT = SPH_RANK_PROXIMITY_BM25 +}; + +/// search query grouping mode +enum ESphGroupBy +{ + SPH_GROUPBY_DAY = 0, ///< group by day + SPH_GROUPBY_WEEK = 1, ///< group by week + SPH_GROUPBY_MONTH = 2, ///< group by month + SPH_GROUPBY_YEAR = 3, ///< group by year + SPH_GROUPBY_ATTR = 4 ///< group by attribute value +}; + +/// known attribute types +enum +{ + SPH_ATTR_NONE = 0, ///< not an attribute at all + SPH_ATTR_INTEGER = 1, ///< this attr is just an integer + SPH_ATTR_TIMESTAMP = 2, ///< this attr is a timestamp + SPH_ATTR_ORDINAL = 3, ///< this attr is an ordinal string number (integer at search time, specially handled at indexing time) + SPH_ATTR_BOOL = 4, ///< this attr is a boolean bit field + SPH_ATTR_FLOAT = 5, + SPH_ATTR_BIGINT = 6, + + SPH_ATTR_MULTI = 0x40000000UL ///< this attr has multiple values (0 or more) +}; + +/// known answers +enum +{ + SEARCHD_OK = 0, ///< general success, command-specific reply follows + SEARCHD_ERROR = 1, ///< general failure, error message follows + SEARCHD_RETRY = 2, ///< temporary failure, error message follows, client should retry later + SEARCHD_WARNING = 3 ///< general success, warning message and command-specific reply follow +}; + +////////////////////////////////////////////////////////////////////////////// + +#define SPHINX_DEBUG_OUTPUT 0 +#define SPHINX_DEBUG_CALLS 0 + +#include <stdarg.h> + +#if SPHINX_DEBUG_OUTPUT +inline void SPH_DEBUG ( const char * format, ... ) +{ + va_list ap; + va_start ( ap, format ); + fprintf ( stderr, "SphinxSE: " ); + vfprintf ( stderr, format, ap ); + fprintf ( stderr, "\n" ); + va_end ( ap ); +} +#else +inline void SPH_DEBUG ( const char *, ... ) {} +#endif + +#if SPHINX_DEBUG_CALLS + +#define SPH_ENTER_FUNC() { SPH_DEBUG ( "enter %s", __FUNCTION__ ); } +#define SPH_ENTER_METHOD() { SPH_DEBUG ( "enter %s(this=%08x)", __FUNCTION__, this ); } +#define SPH_RET(_arg) { SPH_DEBUG ( "leave %s", __FUNCTION__ ); return _arg; } +#define SPH_VOID_RET() { SPH_DEBUG ( "leave %s", __FUNCTION__ ); return; } + +#else + +#define SPH_ENTER_FUNC() +#define SPH_ENTER_METHOD() +#define SPH_RET(_arg) { return(_arg); } +#define SPH_VOID_RET() { return; } + +#endif + + +#define SafeDelete(_arg) { if ( _arg ) delete ( _arg ); (_arg) = NULL; } +#define SafeDeleteArray(_arg) { if ( _arg ) delete [] ( _arg ); (_arg) = NULL; } + +////////////////////////////////////////////////////////////////////////////// + +/// a structure that will be shared among all open Sphinx SE handlers +struct CSphSEShare +{ + pthread_mutex_t m_tMutex; + THR_LOCK m_tLock; + + char * m_sTable; + char * m_sScheme; + char * m_sHost; ///< points into m_sScheme buffer, DO NOT FREE EXPLICITLY + char * m_sSocket; ///< points into m_sScheme buffer, DO NOT FREE EXPLICITLY + char * m_sIndex; ///< points into m_sScheme buffer, DO NOT FREE EXPLICITLY + ushort m_iPort; + uint m_iTableNameLen; + uint m_iUseCount; + CHARSET_INFO * m_pTableQueryCharset; + + int m_iTableFields; + char ** m_sTableField; + enum_field_types * m_eTableFieldType; + + CSphSEShare () + : m_sTable ( NULL ) + , m_sScheme ( NULL ) + , m_sHost ( NULL ) + , m_sSocket ( NULL ) + , m_sIndex ( NULL ) + , m_iPort ( 0 ) + , m_iTableNameLen ( 0 ) + , m_iUseCount ( 1 ) + , m_pTableQueryCharset ( NULL ) + + , m_iTableFields ( 0 ) + , m_sTableField ( NULL ) + , m_eTableFieldType ( NULL ) + { + thr_lock_init ( &m_tLock ); + pthread_mutex_init ( &m_tMutex, MY_MUTEX_INIT_FAST ); + } + + ~CSphSEShare () + { + pthread_mutex_destroy ( &m_tMutex ); + thr_lock_delete ( &m_tLock ); + + SafeDeleteArray ( m_sTable ); + SafeDeleteArray ( m_sScheme ); + ResetTable (); + } + + void ResetTable () + { + for ( int i=0; i<m_iTableFields; i++ ) + SafeDeleteArray ( m_sTableField[i] ); + SafeDeleteArray ( m_sTableField ); + SafeDeleteArray ( m_eTableFieldType ); + } +}; + +/// schema attribute +struct CSphSEAttr +{ + char * m_sName; ///< attribute name (received from Sphinx) + uint32 m_uType; ///< attribute type (received from Sphinx) + int m_iField; ///< field index in current table (-1 if none) + + CSphSEAttr() + : m_sName ( NULL ) + , m_uType ( SPH_ATTR_NONE ) + , m_iField ( -1 ) + {} + + ~CSphSEAttr () + { + SafeDeleteArray ( m_sName ); + } +}; + +/// word stats +struct CSphSEWordStats +{ + char * m_sWord; + int m_iDocs; + int m_iHits; + + CSphSEWordStats () + : m_sWord ( NULL ) + , m_iDocs ( 0 ) + , m_iHits ( 0 ) + {} + + ~CSphSEWordStats () + { + SafeDeleteArray ( m_sWord ); + } +}; + +/// request stats +struct CSphSEStats +{ +public: + int m_iMatchesTotal; + int m_iMatchesFound; + int m_iQueryMsec; + int m_iWords; + CSphSEWordStats * m_dWords; + bool m_bLastError; + char m_sLastMessage[1024]; + + CSphSEStats() + : m_dWords ( NULL ) + { + Reset (); + } + + void Reset () + { + m_iMatchesTotal = 0; + m_iMatchesFound = 0; + m_iQueryMsec = 0; + m_iWords = 0; + SafeDeleteArray ( m_dWords ); + m_bLastError = false; + m_sLastMessage[0] = '\0'; + } + + ~CSphSEStats() + { + Reset (); + } +}; + +/// thread local storage +struct CSphSEThreadData +{ + static const int MAX_QUERY_LEN = 262144; // 256k should be enough, right? + + bool m_bStats; + CSphSEStats m_tStats; + + bool m_bQuery; + char m_sQuery[MAX_QUERY_LEN]; + + CHARSET_INFO * m_pQueryCharset; + + CSphSEThreadData () + : m_bStats ( false ) + , m_bQuery ( false ) + , m_pQueryCharset ( NULL ) + {} +}; + +/// filter types +enum ESphFilter +{ + SPH_FILTER_VALUES = 0, ///< filter by integer values set + SPH_FILTER_RANGE = 1, ///< filter by integer range + SPH_FILTER_FLOATRANGE = 2 ///< filter by float range +}; + + +/// search query filter +struct CSphSEFilter +{ +public: + ESphFilter m_eType; + char * m_sAttrName; + longlong m_uMinValue; + longlong m_uMaxValue; + float m_fMinValue; + float m_fMaxValue; + int m_iValues; + longlong * m_pValues; + int m_bExclude; + +public: + CSphSEFilter () + : m_eType ( SPH_FILTER_VALUES ) + , m_sAttrName ( NULL ) + , m_uMinValue ( 0 ) + , m_uMaxValue ( UINT_MAX ) + , m_fMinValue ( 0.0f ) + , m_fMaxValue ( 0.0f ) + , m_iValues ( 0 ) + , m_pValues ( NULL ) + , m_bExclude ( 0 ) + { + } + + ~CSphSEFilter () + { + SafeDeleteArray ( m_pValues ); + } +}; + + +/// float vs dword conversion +inline uint32 sphF2DW ( float f ) { union { float f; uint32 d; } u; u.f = f; return u.d; } + +/// dword vs float conversion +inline float sphDW2F ( uint32 d ) { union { float f; uint32 d; } u; u.d = d; return u.f; } + + +/// client-side search query +struct CSphSEQuery +{ +public: + const char * m_sHost; + int m_iPort; + +private: + char * m_sQueryBuffer; + + const char * m_sIndex; + int m_iOffset; + int m_iLimit; + + bool m_bQuery; + char * m_sQuery; + uint32 * m_pWeights; + int m_iWeights; + ESphMatchMode m_eMode; + ESphRankMode m_eRanker; + ESphSortOrder m_eSort; + char * m_sSortBy; + int m_iMaxMatches; + int m_iMaxQueryTime; + uint32 m_iMinID; + uint32 m_iMaxID; + + int m_iFilters; + CSphSEFilter m_dFilters[SPHINXSE_MAX_FILTERS]; + + ESphGroupBy m_eGroupFunc; + char * m_sGroupBy; + char * m_sGroupSortBy; + int m_iCutoff; + int m_iRetryCount; + int m_iRetryDelay; + char * m_sGroupDistinct; ///< points to query buffer; do NOT delete + int m_iIndexWeights; + char * m_sIndexWeight[SPHINXSE_MAX_FILTERS]; ///< points to query buffer; do NOT delete + int m_iIndexWeight[SPHINXSE_MAX_FILTERS]; + int m_iFieldWeights; + char * m_sFieldWeight[SPHINXSE_MAX_FILTERS]; ///< points to query buffer; do NOT delete + int m_iFieldWeight[SPHINXSE_MAX_FILTERS]; + + bool m_bGeoAnchor; + char * m_sGeoLatAttr; + char * m_sGeoLongAttr; + float m_fGeoLatitude; + float m_fGeoLongitude; + + char * m_sComment; + + struct Override_t + { + union Value_t + { + uint32 m_uValue; + longlong m_iValue64; + float m_fValue; + }; + char * m_sName; ///< points to query buffer + int m_iType; + Dynamic_array<ulonglong> m_dIds; + Dynamic_array<Value_t> m_dValues; + }; + Dynamic_array<Override_t *> m_dOverrides; + +public: + char m_sParseError[256]; + +public: + CSphSEQuery ( const char * sQuery, int iLength, const char * sIndex ); + ~CSphSEQuery (); + + bool Parse (); + int BuildRequest ( char ** ppBuffer ); + +protected: + char * m_pBuf; + char * m_pCur; + int m_iBufLeft; + bool m_bBufOverrun; + + template < typename T > int ParseArray ( T ** ppValues, const char * sValue ); + bool ParseField ( char * sField ); + + void SendBytes ( const void * pBytes, int iBytes ); + void SendWord ( short int v ) { v = ntohs(v); SendBytes ( &v, sizeof(short int) ); } + void SendInt ( int v ) { v = ntohl(v); SendBytes ( &v, sizeof(int) ); } + void SendDword ( uint v ) { v = ntohl(v) ;SendBytes ( &v, sizeof(uint) ); } + void SendUint64 ( ulonglong v ) { SendDword ( uint(v>>32) ); SendDword ( uint(v&0xFFFFFFFFUL) ); } + void SendString ( const char * v ) { int iLen = strlen(v); SendDword(iLen); SendBytes ( v, iLen ); } + void SendFloat ( float v ) { SendDword ( sphF2DW(v) ); } +}; + +template int CSphSEQuery::ParseArray<uint32> ( uint32 **, const char * ); +template int CSphSEQuery::ParseArray<longlong> ( longlong **, const char * ); + +////////////////////////////////////////////////////////////////////////////// + +#if MYSQL_VERSION_ID>50100 + +#if MYSQL_VERSION_ID<50114 +#error Sphinx SE requires MySQL 5.1.14 or higher if compiling for 5.1.x series! +#endif + +static handler * sphinx_create_handler ( handlerton * hton, TABLE_SHARE * table, MEM_ROOT * mem_root ); +static int sphinx_init_func ( void * p ); +static int sphinx_close_connection ( handlerton * hton, THD * thd ); +static int sphinx_panic ( handlerton * hton, enum ha_panic_function flag ); +static bool sphinx_show_status ( handlerton * hton, THD * thd, stat_print_fn * stat_print, enum ha_stat_type stat_type ); + +#else + +static bool sphinx_init_func_for_handlerton (); +static int sphinx_close_connection ( THD * thd ); +bool sphinx_show_status ( THD * thd ); + +#endif // >50100 + +////////////////////////////////////////////////////////////////////////////// + +static const char sphinx_hton_name[] = "SPHINX"; +static const char sphinx_hton_comment[] = "Sphinx storage engine " SPHINX_VERSION; + +#if MYSQL_VERSION_ID<50100 +handlerton sphinx_hton = +{ + #ifdef MYSQL_HANDLERTON_INTERFACE_VERSION + MYSQL_HANDLERTON_INTERFACE_VERSION, + #endif + sphinx_hton_name, + SHOW_OPTION_YES, + sphinx_hton_comment, + DB_TYPE_SPHINX_DB, + sphinx_init_func_for_handlerton, + 0, // slot + 0, // savepoint size + sphinx_close_connection, // close_connection + NULL, // savepoint + NULL, // rollback to savepoint + NULL, // release savepoint + NULL, // commit + NULL, // rollback + NULL, // prepare + NULL, // recover + NULL, // commit_by_xid + NULL, // rollback_by_xid + NULL, // create_cursor_read_view + NULL, // set_cursor_read_view + NULL, // close_cursor_read_view + HTON_CAN_RECREATE +}; +#else +static handlerton * sphinx_hton_ptr = NULL; +#endif + +////////////////////////////////////////////////////////////////////////////// + +// variables for Sphinx shared methods +pthread_mutex_t sphinx_mutex; // mutex to init the hash +static int sphinx_init = 0; // flag whether the hash was initialized +static HASH sphinx_open_tables; // hash used to track open tables + +////////////////////////////////////////////////////////////////////////////// +// INITIALIZATION AND SHUTDOWN +////////////////////////////////////////////////////////////////////////////// + +// hashing function +#if MYSQL_VERSION_ID>=50120 +typedef size_t GetKeyLength_t; +#else +typedef uint GetKeyLength_t; +#endif + +static byte * sphinx_get_key ( const byte * pSharePtr, GetKeyLength_t * pLength, my_bool ) +{ + CSphSEShare * pShare = (CSphSEShare *) pSharePtr; + *pLength = (size_t) pShare->m_iTableNameLen; + return (byte*) pShare->m_sTable; +} + +#if MYSQL_VERSION_ID<50100 +static int sphinx_init_func ( void * ) // to avoid unused arg warning +#else +static int sphinx_init_func ( void * p ) +#endif +{ + SPH_ENTER_FUNC(); + if ( !sphinx_init ) + { + sphinx_init = 1; + VOID ( pthread_mutex_init ( &sphinx_mutex, MY_MUTEX_INIT_FAST ) ); + hash_init ( &sphinx_open_tables, system_charset_info, 32, 0, 0, + sphinx_get_key, 0, 0 ); + + #if MYSQL_VERSION_ID > 50100 + handlerton * hton = (handlerton*) p; + hton->state = SHOW_OPTION_YES; + hton->db_type = DB_TYPE_AUTOASSIGN; + hton->create = sphinx_create_handler; + hton->close_connection = sphinx_close_connection; + hton->show_status = sphinx_show_status; + hton->panic = sphinx_panic; + hton->flags = HTON_CAN_RECREATE; + sphinx_hton_ptr = hton; + #endif + } + SPH_RET(0); +} + + +#if MYSQL_VERSION_ID<50100 +static bool sphinx_init_func_for_handlerton () +{ + return sphinx_init_func ( &sphinx_hton ); +} +#endif + + +#if MYSQL_VERSION_ID>50100 + +static int sphinx_close_connection ( handlerton * hton, THD * thd ) +{ + // deallocate common handler data + SPH_ENTER_FUNC(); + void ** tmp = thd_ha_data ( thd, hton ); + CSphSEThreadData * pTls = (CSphSEThreadData*) (*tmp); + SafeDelete ( pTls ); + *tmp = NULL; + SPH_RET(0); +} + + +static int sphinx_done_func ( void * ) +{ + SPH_ENTER_FUNC(); + + int error = 0; + if ( sphinx_init ) + { + sphinx_init = 0; + if ( sphinx_open_tables.records ) + error = 1; + hash_free ( &sphinx_open_tables ); + pthread_mutex_destroy ( &sphinx_mutex ); + } + + SPH_RET(0); +} + + +static int sphinx_panic ( handlerton * hton, enum ha_panic_function ) +{ + return sphinx_done_func ( hton ); +} + +#else + +static int sphinx_close_connection ( THD * thd ) +{ + // deallocate common handler data + SPH_ENTER_FUNC(); + CSphSEThreadData * pTls = (CSphSEThreadData*) thd->ha_data[sphinx_hton.slot]; + SafeDelete ( pTls ); + thd->ha_data[sphinx_hton.slot] = NULL; + SPH_RET(0); +} + +#endif // >50100 + +////////////////////////////////////////////////////////////////////////////// +// SHOW STATUS +////////////////////////////////////////////////////////////////////////////// + +#if MYSQL_VERSION_ID>50100 +static bool sphinx_show_status ( handlerton * hton, THD * thd, stat_print_fn * stat_print, + enum ha_stat_type ) +#else +bool sphinx_show_status ( THD * thd ) +#endif +{ + SPH_ENTER_FUNC(); + +#if MYSQL_VERSION_ID<50100 + Protocol * protocol = thd->protocol; + List<Item> field_list; +#endif + + char buf1[IO_SIZE]; + uint buf1len; + char buf2[IO_SIZE]; + uint buf2len= 0; + String words; + + buf1[0] = '\0'; + buf2[0] = '\0'; + +#if MYSQL_VERSION_ID>50100 + CSphSEThreadData * pTls = (CSphSEThreadData*) ( *thd_ha_data ( thd, hton ) ); +#else + if ( have_sphinx_db!=SHOW_OPTION_YES ) + { + my_message ( ER_NOT_SUPPORTED_YET, + "failed to call SHOW SPHINX STATUS: --skip-sphinx was specified", + MYF(0) ); + SPH_RET(TRUE); + } + CSphSEThreadData * pTls = (CSphSEThreadData*) thd->ha_data[sphinx_hton.slot]; +#endif + + if ( pTls && pTls->m_bStats ) + { + const CSphSEStats * pStats = &pTls->m_tStats; + buf1len = my_snprintf ( buf1, sizeof(buf1), + "total: %d, total found: %d, time: %d, words: %d", + pStats->m_iMatchesTotal, pStats->m_iMatchesFound, pStats->m_iQueryMsec, pStats->m_iWords ); + +#if MYSQL_VERSION_ID>50100 + stat_print ( thd, sphinx_hton_name, strlen(sphinx_hton_name), + STRING_WITH_LEN("stats"), buf1, buf1len ); +#else + field_list.push_back ( new Item_empty_string ( "Type",10 ) ); + field_list.push_back ( new Item_empty_string ( "Name",FN_REFLEN ) ); + field_list.push_back ( new Item_empty_string ( "Status",10 ) ); + if ( protocol->send_fields ( &field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF ) ) + SPH_RET(TRUE); + + protocol->prepare_for_resend (); + protocol->store ( STRING_WITH_LEN("SPHINX"), system_charset_info ); + protocol->store ( STRING_WITH_LEN("stats"), system_charset_info ); + protocol->store ( buf1, buf1len, system_charset_info ); + if ( protocol->write() ) + SPH_RET(TRUE); +#endif + + if ( pStats->m_iWords ) + { + for ( int i=0; i<pStats->m_iWords; i++ ) + { + CSphSEWordStats & tWord = pStats->m_dWords[i]; + buf2len = my_snprintf ( buf2, sizeof(buf2), "%s%s:%d:%d ", + buf2, tWord.m_sWord, tWord.m_iDocs, tWord.m_iHits ); + } + + // convert it if we can + const char * sWord = buf2; + int iWord = buf2len; + + String sBuf3; + if ( pTls->m_pQueryCharset ) + { + uint iErrors; + sBuf3.copy ( buf2, buf2len, pTls->m_pQueryCharset, system_charset_info, &iErrors ); + sWord = sBuf3.c_ptr(); + iWord = sBuf3.length(); + } + +#if MYSQL_VERSION_ID>50100 + stat_print ( thd, sphinx_hton_name, strlen(sphinx_hton_name), + STRING_WITH_LEN("words"), sWord, iWord ); +#else + protocol->prepare_for_resend (); + protocol->store ( STRING_WITH_LEN("SPHINX"), system_charset_info ); + protocol->store ( STRING_WITH_LEN("words"), system_charset_info ); + protocol->store ( sWord, iWord, system_charset_info ); + if ( protocol->write() ) + SPH_RET(TRUE); +#endif + } + + // send last error or warning + if ( pStats->m_sLastMessage && pStats->m_sLastMessage[0] ) + { + const char * sMessageType = pStats->m_bLastError ? "error" : "warning"; + +#if MYSQL_VERSION_ID>50100 + stat_print ( thd, sphinx_hton_name, strlen(sphinx_hton_name), + sMessageType, strlen(sMessageType), pStats->m_sLastMessage, strlen(pStats->m_sLastMessage) ); +#else + protocol->prepare_for_resend (); + protocol->store ( STRING_WITH_LEN("SPHINX"), system_charset_info ); + protocol->store ( sMessageType, strlen(sMessageType), system_charset_info ); + protocol->store ( pStats->m_sLastMessage, strlen(pStats->m_sLastMessage), system_charset_info ); + if ( protocol->write() ) + SPH_RET(TRUE); +#endif + } + + } else + { + #if MYSQL_VERSION_ID < 50100 + field_list.push_back ( new Item_empty_string ( "Type", 10 ) ); + field_list.push_back ( new Item_empty_string ( "Name", FN_REFLEN ) ); + field_list.push_back ( new Item_empty_string ( "Status", 10 ) ); + if ( protocol->send_fields ( &field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF ) ) + SPH_RET(TRUE); + + protocol->prepare_for_resend (); + protocol->store ( STRING_WITH_LEN("SPHINX"), system_charset_info ); + protocol->store ( STRING_WITH_LEN("stats"), system_charset_info ); + protocol->store ( STRING_WITH_LEN("no query has been executed yet"), system_charset_info ); + if ( protocol->write() ) + SPH_RET(TRUE); + #endif + } + + #if MYSQL_VERSION_ID < 50100 + send_eof(thd); + #endif + + SPH_RET(FALSE); +} + +////////////////////////////////////////////////////////////////////////////// +// HELPERS +////////////////////////////////////////////////////////////////////////////// + +static char * sphDup ( const char * sSrc, int iLen=-1 ) +{ + if ( !sSrc ) + return NULL; + + if ( iLen<0 ) + iLen = strlen(sSrc); + + char * sRes = new char [ 1+iLen ]; + memcpy ( sRes, sSrc, iLen ); + sRes[iLen] = '\0'; + return sRes; +} + + +static void sphLogError ( const char * sFmt, ... ) +{ + // emit timestamp +#ifdef __WIN__ + SYSTEMTIME t; + GetLocalTime ( &t ); + + fprintf ( stderr, "%02d%02d%02d %2d:%02d:%02d SphinxSE: internal error: ", + (int)t.wYear % 100, (int)t.wMonth, (int)t.wDay, + (int)t.wHour, (int)t.wMinute, (int)t.wSecond ); +#else + // Unix version + time_t tStamp; + time ( &tStamp ); + + struct tm * pParsed; +#ifdef HAVE_LOCALTIME_R + struct tm tParsed; + localtime_r ( &tStamp, &tParsed ); + pParsed = &tParsed; +#else + pParsed = localtime ( &tStamp ); +#endif // HAVE_LOCALTIME_R + + fprintf ( stderr, "%02d%02d%02d %2d:%02d:%02d SphinxSE: internal error: ", + pParsed->tm_year % 100, pParsed->tm_mon + 1, pParsed->tm_mday, + pParsed->tm_hour, pParsed->tm_min, pParsed->tm_sec); +#endif // __WIN__ + + // emit message + va_list ap; + va_start ( ap, sFmt ); + vfprintf ( stderr, sFmt, ap ); + va_end ( ap ); + + // emit newline + fprintf ( stderr, "\n" ); +} + + + +// the following scheme variants are recognized +// +// sphinx://host/index +// sphinx://host:port/index +// unix://unix/domain/socket:index +// unix://unix/domain/socket +static bool ParseUrl ( CSphSEShare * share, TABLE * table, bool bCreate ) +{ + SPH_ENTER_FUNC(); + + if ( share ) + { + // check incoming stuff + if ( !table ) + { + sphLogError ( "table==NULL in ParseUrl()" ); + return false; + } + if ( !table->s ) + { + sphLogError ( "(table->s)==NULL in ParseUrl()" ); + return false; + } + + // free old stuff + share->ResetTable (); + + // fill new stuff + share->m_iTableFields = table->s->fields; + if ( share->m_iTableFields ) + { + share->m_sTableField = new char * [ share->m_iTableFields ]; + share->m_eTableFieldType = new enum_field_types [ share->m_iTableFields ]; + + for ( int i=0; i<share->m_iTableFields; i++ ) + { + share->m_sTableField[i] = sphDup ( table->field[i]->field_name ); + share->m_eTableFieldType[i] = table->field[i]->type(); + } + } + } + + char * sScheme = NULL; + char * sHost = (char*) SPHINXSE_DEFAULT_HOST; + char * sIndex = (char*) SPHINXSE_DEFAULT_INDEX; + int iPort = SPHINXSE_DEFAULT_PORT; + + bool bOk = true; + while ( table->s->connect_string.length!=0 ) + { + bOk = false; + sScheme = sphDup ( table->s->connect_string.str, table->s->connect_string.length ); + + sHost = strstr ( sScheme, "://" ); + if ( !sHost ) + break; + sHost[0] = '\0'; + sHost += 2; + + if ( !strcmp ( sScheme, "unix" ) ) + { + // unix-domain socket + iPort = 0; + if (!( sIndex = strrchr ( sHost, ':' ) )) + sIndex = (char*) SPHINXSE_DEFAULT_INDEX; + else + { + *sIndex++ = '\0'; + if ( !*sIndex ) + sIndex = (char*) SPHINXSE_DEFAULT_INDEX; + } + bOk = true; + break; + } + if( strcmp ( sScheme, "sphinx" )!=0 && strcmp ( sScheme, "inet" )!=0 ) + break; + + // tcp + sHost++; + char * sPort = strchr ( sHost, ':' ); + if ( sPort ) + { + *sPort++ = '\0'; + if ( *sPort ) + { + sIndex = strchr ( sPort, '/' ); + if ( sIndex ) + *sIndex++ = '\0'; + else + sIndex = (char*) SPHINXSE_DEFAULT_INDEX; + + iPort = atoi(sPort); + if ( !iPort ) + iPort = SPHINXSE_DEFAULT_PORT; + } + } else + { + sIndex = strchr ( sHost, '/' ); + if ( sIndex ) + *sIndex++ = '\0'; + else + sIndex = (char*) SPHINXSE_DEFAULT_INDEX; + } + + bOk = true; + break; + } + + if ( !bOk ) + { + my_error ( bCreate ? ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE : ER_FOREIGN_DATA_STRING_INVALID, + MYF(0), table->s->connect_string ); + } else + { + if ( share ) + { + SafeDeleteArray ( share->m_sScheme ); + share->m_sScheme = sScheme; + share->m_sHost = sHost; + share->m_sIndex = sIndex; + share->m_iPort = (ushort)iPort; + } + } + if ( !bOk && !share ) + SafeDeleteArray ( sScheme ); + + SPH_RET(bOk); +} + + +// Example of simple lock controls. The "share" it creates is structure we will +// pass to each sphinx handler. Do you have to have one of these? Well, you have +// pieces that are used for locking, and they are needed to function. +static CSphSEShare * get_share ( const char * table_name, TABLE * table ) +{ + SPH_ENTER_FUNC(); + pthread_mutex_lock ( &sphinx_mutex ); + + CSphSEShare * pShare = NULL; + for ( ;; ) + { + // check if we already have this share +#if MYSQL_VERSION_ID>=50120 + pShare = (CSphSEShare*) hash_search ( &sphinx_open_tables, (const uchar *) table_name, strlen(table_name) ); +#else +#ifdef __WIN__ + pShare = (CSphSEShare*) hash_search ( &sphinx_open_tables, (const byte *) table_name, strlen(table_name) ); +#else + pShare = (CSphSEShare*) hash_search ( &sphinx_open_tables, table_name, strlen(table_name) ); +#endif // win +#endif // pre-5.1.20 + + if ( pShare ) + { + pShare->m_iUseCount++; + break; + } + + // try to allocate new share + pShare = new CSphSEShare (); + if ( !pShare ) + break; + + // try to setup it + pShare->m_pTableQueryCharset = table->field[2]->charset(); + if ( !ParseUrl ( pShare, table, false ) ) + { + SafeDelete ( pShare ); + break; + } + + // try to hash it + pShare->m_iTableNameLen = strlen(table_name); + pShare->m_sTable = sphDup ( table_name ); + if ( my_hash_insert ( &sphinx_open_tables, (const byte *)pShare ) ) + { + SafeDelete ( pShare ); + break; + } + + // all seems fine + break; + } + + pthread_mutex_unlock ( &sphinx_mutex ); + SPH_RET(pShare); +} + + +// Free lock controls. We call this whenever we close a table. If the table had +// the last reference to the share then we free memory associated with it. +static int free_share ( CSphSEShare * pShare ) +{ + SPH_ENTER_FUNC(); + pthread_mutex_lock ( &sphinx_mutex ); + + if ( !--pShare->m_iUseCount ) + { + hash_delete ( &sphinx_open_tables, (byte *)pShare ); + SafeDelete ( pShare ); + } + + pthread_mutex_unlock ( &sphinx_mutex ); + SPH_RET(0); +} + + +#if MYSQL_VERSION_ID>50100 +static handler * sphinx_create_handler ( handlerton * hton, TABLE_SHARE * table, MEM_ROOT * mem_root ) +{ + return new ( mem_root ) ha_sphinx ( hton, table ); +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// CLIENT-SIDE REQUEST STUFF +////////////////////////////////////////////////////////////////////////////// + +CSphSEQuery::CSphSEQuery ( const char * sQuery, int iLength, const char * sIndex ) + : m_sHost ( "" ) + , m_iPort ( 0 ) + , m_sIndex ( sIndex ? sIndex : (char*) "*" ) + , m_iOffset ( 0 ) + , m_iLimit ( 20 ) + , m_bQuery ( false ) + , m_sQuery ( (char*) "" ) + , m_pWeights ( NULL ) + , m_iWeights ( 0 ) + , m_eMode ( SPH_MATCH_ALL ) + , m_eRanker ( SPH_RANK_PROXIMITY_BM25 ) + , m_eSort ( SPH_SORT_RELEVANCE ) + , m_sSortBy ( (char*) "" ) + , m_iMaxMatches ( 1000 ) + , m_iMaxQueryTime ( 0 ) + , m_iMinID ( 0 ) + , m_iMaxID ( 0 ) + , m_iFilters ( 0 ) + , m_eGroupFunc ( SPH_GROUPBY_DAY ) + , m_sGroupBy ( (char*) "" ) + , m_sGroupSortBy ( (char*) "@group desc" ) + , m_iCutoff ( 0 ) + , m_iRetryCount ( 0 ) + , m_iRetryDelay ( 0 ) + , m_sGroupDistinct ( (char*) "" ) + , m_iIndexWeights ( 0 ) + , m_iFieldWeights ( 0 ) + , m_bGeoAnchor ( false ) + , m_sGeoLatAttr ( (char*) "" ) + , m_sGeoLongAttr ( (char*) "" ) + , m_fGeoLatitude ( 0.0f ) + , m_fGeoLongitude ( 0.0f ) + , m_sComment ( (char*) "" ) + + , m_pBuf ( NULL ) + , m_pCur ( NULL ) + , m_iBufLeft ( 0 ) + , m_bBufOverrun ( false ) +{ + m_sQueryBuffer = new char [ iLength+2 ]; + memcpy ( m_sQueryBuffer, sQuery, iLength ); + m_sQueryBuffer[iLength]= ';'; + m_sQueryBuffer[iLength+1]= '\0'; +} + + +CSphSEQuery::~CSphSEQuery () +{ + SPH_ENTER_METHOD(); + SafeDeleteArray ( m_sQueryBuffer ); + SafeDeleteArray ( m_pWeights ); + SafeDeleteArray ( m_pBuf ); + for ( int i=0; i<m_dOverrides.elements(); i++ ) + SafeDelete ( m_dOverrides.at(i) ); + SPH_VOID_RET(); +} + + +template < typename T > +int CSphSEQuery::ParseArray ( T ** ppValues, const char * sValue ) +{ + SPH_ENTER_METHOD(); + + assert ( ppValues ); + assert ( !(*ppValues) ); + + const char * pValue; + bool bPrevDigit = false; + int iValues = 0; + + // count the values + for ( pValue=sValue; *pValue; pValue++ ) + { + bool bDigit = (*pValue)>='0' && (*pValue)<='9'; + if ( bDigit && !bPrevDigit ) + iValues++; + bPrevDigit = bDigit; + } + if ( !iValues ) + SPH_RET(0); + + // extract the values + T * pValues = new T [ iValues ]; + *ppValues = pValues; + + int iIndex = 0, iSign = 1; + T uValue = 0; + + bPrevDigit = false; + for ( pValue=sValue ;; pValue++ ) + { + bool bDigit = (*pValue)>='0' && (*pValue)<='9'; + + if ( bDigit ) + { + if ( !bPrevDigit ) + uValue = 0; + uValue = uValue*10 + ( (*pValue)-'0' ); + } + else if ( bPrevDigit ) + { + assert ( iIndex<iValues ); + pValues [ iIndex++ ] = uValue * iSign; + iSign = 1; + } + else if ( *pValue=='-' ) + iSign = -1; + bPrevDigit = bDigit; + + if ( !*pValue ) + break; + } + + SPH_RET(iValues); +} + + +static char * chop ( char * s ) +{ + while ( *s && isspace(*s) ) + s++; + + char * p = s + strlen(s); + while ( p>s && isspace(p[-1]) ) + p--; + *p = '\0'; + + return s; +} + + +static bool myisattr ( char c ) +{ + return + ( c>='0' && c<='9' ) || + ( c>='a' && c<='z' ) || + ( c>='A' && c<='Z' ) || + c=='_'; +} + + +bool CSphSEQuery::ParseField ( char * sField ) +{ + SPH_ENTER_METHOD(); + + // look for option name/value separator + char * sValue = strchr ( sField, '=' ); + if ( !sValue || sValue==sField || sValue[-1]=='\\' ) + { + // by default let's assume it's just query + if ( sField[0] ) + { + if ( m_bQuery ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "search query already specified; '%s' is redundant", sField ); + SPH_RET(false); + } else + { + m_sQuery = sField; + m_bQuery = true; + + // unescape + char *s = sField, *d = sField; + while ( *s ) + { + if ( *s!='\\' ) *d++ = *s; + s++; + } + *d = '\0'; + } + } + SPH_RET(true); + } + + // split + *sValue++ = '\0'; + sValue = chop ( sValue ); + int iValue = atoi ( sValue ); + + // handle options + char * sName = chop ( sField ); + + if ( !strcmp ( sName, "query" ) ) m_sQuery = sValue; + else if ( !strcmp ( sName, "host" ) ) m_sHost = sValue; + else if ( !strcmp ( sName, "port" ) ) m_iPort = iValue; + else if ( !strcmp ( sName, "index" ) ) m_sIndex = sValue; + else if ( !strcmp ( sName, "offset" ) ) m_iOffset = iValue; + else if ( !strcmp ( sName, "limit" ) ) m_iLimit = iValue; + else if ( !strcmp ( sName, "weights" ) ) m_iWeights = ParseArray<uint32> ( &m_pWeights, sValue ); + else if ( !strcmp ( sName, "minid" ) ) m_iMinID = iValue; + else if ( !strcmp ( sName, "maxid" ) ) m_iMaxID = iValue; + else if ( !strcmp ( sName, "maxmatches" ) ) m_iMaxMatches = iValue; + else if ( !strcmp ( sName, "maxquerytime" ) ) m_iMaxQueryTime = iValue; + else if ( !strcmp ( sName, "groupsort" ) ) m_sGroupSortBy = sValue; + else if ( !strcmp ( sName, "distinct" ) ) m_sGroupDistinct = sValue; + else if ( !strcmp ( sName, "cutoff" ) ) m_iCutoff = iValue; + else if ( !strcmp ( sName, "comment" ) ) m_sComment = sValue; + + else if ( !strcmp ( sName, "mode" ) ) + { + + m_eMode = SPH_MATCH_ALL; + if ( !strcmp ( sValue, "any") ) m_eMode = SPH_MATCH_ANY; + else if ( !strcmp ( sValue, "phrase" ) ) m_eMode = SPH_MATCH_PHRASE; + else if ( !strcmp ( sValue, "boolean") ) m_eMode = SPH_MATCH_BOOLEAN; + else if ( !strcmp ( sValue, "ext") ) m_eMode = SPH_MATCH_EXTENDED; + else if ( !strcmp ( sValue, "extended") ) m_eMode = SPH_MATCH_EXTENDED; + else if ( !strcmp ( sValue, "ext2") ) m_eMode = SPH_MATCH_EXTENDED2; + else if ( !strcmp ( sValue, "extended2") ) m_eMode = SPH_MATCH_EXTENDED2; + else if ( !strcmp ( sValue, "all") ) m_eMode = SPH_MATCH_ALL; + else if ( !strcmp ( sValue, "fullscan") ) m_eMode = SPH_MATCH_FULLSCAN; + else + { + snprintf ( m_sParseError, sizeof(m_sParseError), "unknown matching mode '%s'", sValue ); + SPH_RET(false); + } + } else if ( !strcmp ( sName, "ranker" ) ) + { + + m_eRanker = SPH_RANK_PROXIMITY_BM25; + if ( !strcmp ( sValue, "proximity_bm25") ) m_eRanker = SPH_RANK_PROXIMITY_BM25; + else if ( !strcmp ( sValue, "bm25" ) ) m_eRanker = SPH_RANK_BM25; + else if ( !strcmp ( sValue, "none" ) ) m_eRanker = SPH_RANK_NONE; + else if ( !strcmp ( sValue, "wordcount" ) ) m_eRanker = SPH_RANK_WORDCOUNT; + else if ( !strcmp ( sValue, "proximity" ) ) m_eRanker = SPH_RANK_PROXIMITY; + else if ( !strcmp ( sValue, "matchany" ) ) m_eRanker = SPH_RANK_MATCHANY; + else if ( !strcmp ( sValue, "fieldmask" ) ) m_eRanker = SPH_RANK_FIELDMASK; + else + { + snprintf ( m_sParseError, sizeof(m_sParseError), "unknown ranking mode '%s'", sValue ); + SPH_RET(false); + } + } else if ( !strcmp ( sName, "sort" ) ) + { + static const struct + { + const char * m_sName; + ESphSortOrder m_eSort; + } dSortModes[] = + { + { "relevance", SPH_SORT_RELEVANCE }, + { "attr_desc:", SPH_SORT_ATTR_DESC }, + { "attr_asc:", SPH_SORT_ATTR_ASC }, + { "time_segments:", SPH_SORT_TIME_SEGMENTS }, + { "extended:", SPH_SORT_EXTENDED }, + { "expr:", SPH_SORT_EXPR } + }; + + int i; + const int nModes = sizeof(dSortModes)/sizeof(dSortModes[0]); + for ( i=0; i<nModes; i++ ) + if ( !strncmp ( sValue, dSortModes[i].m_sName, strlen(dSortModes[i].m_sName) ) ) + { + m_eSort = dSortModes[i].m_eSort; + m_sSortBy = sValue + strlen(dSortModes[i].m_sName); + break; + } + if ( i==nModes ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "unknown sorting mode '%s'", sValue ); + SPH_RET(false); + } + + } else if ( !strcmp ( sName, "groupby" ) ) + { + static const struct + { + const char * m_sName; + ESphGroupBy m_eFunc; + } dGroupModes[] = + { + { "day:", SPH_GROUPBY_DAY }, + { "week:", SPH_GROUPBY_WEEK }, + { "month:", SPH_GROUPBY_MONTH }, + { "year:", SPH_GROUPBY_YEAR }, + { "attr:", SPH_GROUPBY_ATTR }, + }; + + int i; + const int nModes = sizeof(dGroupModes)/sizeof(dGroupModes[0]); + for ( i=0; i<nModes; i++ ) + if ( !strncmp ( sValue, dGroupModes[i].m_sName, strlen(dGroupModes[i].m_sName) ) ) + { + m_eGroupFunc = dGroupModes[i].m_eFunc; + m_sGroupBy = sValue + strlen(dGroupModes[i].m_sName); + break; + } + if ( i==nModes ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "unknown groupby mode '%s'", sValue ); + SPH_RET(false); + } + + } else if ( m_iFilters<SPHINXSE_MAX_FILTERS && + ( !strcmp ( sName, "range" ) || !strcmp ( sName, "!range" ) || !strcmp ( sName, "floatrange" ) || !strcmp ( sName, "!floatrange" ) ) ) + { + for ( ;; ) + { + char * p = sName; + CSphSEFilter & tFilter = m_dFilters [ m_iFilters ]; + tFilter.m_bExclude = ( *p=='!' ); if ( tFilter.m_bExclude ) p++; + tFilter.m_eType = ( *p=='f' ) ? SPH_FILTER_FLOATRANGE : SPH_FILTER_RANGE; + + if (!( p = strchr ( sValue, ',' ) )) + break; + *p++ = '\0'; + + tFilter.m_sAttrName = chop ( sValue ); + sValue = p; + + if (!( p = strchr ( sValue, ',' ) )) + break; + *p++ = '\0'; + + if ( tFilter.m_eType==SPH_FILTER_RANGE ) + { + tFilter.m_uMinValue = strtoll ( sValue, NULL, 0 ); + tFilter.m_uMaxValue = strtoll ( p, NULL, 0 ); + } else + { + tFilter.m_fMinValue = (float)atof(sValue); + tFilter.m_fMaxValue = (float)atof(p); + } + + // all ok + m_iFilters++; + break; + } + + } else if ( m_iFilters<SPHINXSE_MAX_FILTERS && + ( !strcmp ( sName, "filter" ) || !strcmp ( sName, "!filter" ) ) ) + { + for ( ;; ) + { + CSphSEFilter & tFilter = m_dFilters [ m_iFilters ]; + tFilter.m_eType = SPH_FILTER_VALUES; + tFilter.m_bExclude = ( strcmp ( sName, "!filter")==0 ); + + // get the attr name + while ( (*sValue) && !myisattr(*sValue) ) + sValue++; + if ( !*sValue ) + break; + + tFilter.m_sAttrName = sValue; + while ( (*sValue) && myisattr(*sValue) ) + sValue++; + if ( !*sValue ) + break; + *sValue++ = '\0'; + + // get the values + tFilter.m_iValues = ParseArray<longlong> ( &tFilter.m_pValues, sValue ); + if ( !tFilter.m_iValues ) + { + assert ( !tFilter.m_pValues ); + break; + } + + // all ok + m_iFilters++; + break; + } + + } else if ( !strcmp ( sName, "indexweights" ) || !strcmp ( sName, "fieldweights" ) ) + { + bool bIndex = !strcmp ( sName, "indexweights" ); + int * pCount = bIndex ? &m_iIndexWeights : &m_iFieldWeights; + char ** pNames = bIndex ? &m_sIndexWeight[0] : &m_sFieldWeight[0]; + int * pWeights = bIndex ? &m_iIndexWeight[0] : &m_iFieldWeight[0]; + + *pCount = 0; + + char * p = sValue; + while ( *p && *pCount<SPHINXSE_MAX_FILTERS ) + { + // extract attr name + if ( !myisattr(*p) ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "%s: index name expected near '%s'", sName, p ); + SPH_RET(false); + } + + pNames[*pCount] = p; + while ( myisattr(*p) ) p++; + + if ( *p!=',' ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "%s: comma expected near '%s'", sName, p ); + SPH_RET(false); + } + *p++ = '\0'; + + // extract attr value + char * sVal = p; + while ( isdigit(*p) ) p++; + if ( p==sVal ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "%s: integer weight expected near '%s'", sName, sVal ); + SPH_RET(false); + } + pWeights[*pCount] = atoi(sVal); + (*pCount)++; + + if ( !*p ) break; + if ( *p!=',' ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "%s: comma expected near '%s'", sName, p ); + SPH_RET(false); + } + p++; + } + + } else if ( !strcmp ( sName, "geoanchor" ) ) + { + m_bGeoAnchor = false; + for ( ;; ) + { + char * sLat = sValue; + char * p = sValue; + + if (!( p = strchr ( p, ',' ) )) break; *p++ = '\0'; + char * sLong = p; + + if (!( p = strchr ( p, ',' ) )) break; *p++ = '\0'; + char * sLatVal = p; + + if (!( p = strchr ( p, ',' ) )) break; *p++ = '\0'; + char * sLongVal = p; + + m_sGeoLatAttr = chop(sLat); + m_sGeoLongAttr = chop(sLong); + m_fGeoLatitude = (float)atof(sLatVal); + m_fGeoLongitude = (float)atof(sLongVal); + m_bGeoAnchor = true; + break; + } + if ( !m_bGeoAnchor ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "geoanchor: parse error, not enough comma-separated arguments" ); + SPH_RET(false); + } + } + else if ( !strcmp ( sName, "override" ) ) // name,type,id:value,id:value,... + { + char * sName = NULL; + int iType = 0; + CSphSEQuery::Override_t * pOverride = NULL; + + // get name and type + char * sRest = sValue; + for ( ;; ) + { + sName = sRest; + if ( !*sName ) + break; + + if (!( sRest = strchr ( sRest, ',' ) )) break; *sRest++ = '\0'; + char * sType = sRest; + if (!( sRest = strchr ( sRest, ',' ) )) break; + + static const struct + { + const char * m_sName; + int m_iType; + } + dAttrTypes[] = + { + { "int", SPH_ATTR_INTEGER }, + { "timestamp", SPH_ATTR_TIMESTAMP }, + { "bool", SPH_ATTR_BOOL }, + { "float", SPH_ATTR_FLOAT }, + { "bigint", SPH_ATTR_BIGINT } + }; + for ( uint i=0; i<sizeof(dAttrTypes)/sizeof(*dAttrTypes); i++ ) + if ( !strncmp( sType, dAttrTypes[i].m_sName, sRest - sType ) ) + { + iType = dAttrTypes[i].m_iType; + break; + } + break; + } + + // fail + if ( !sName || !*sName || !iType ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "override: malformed query" ); + SPH_RET(false); + } + + // grab id:value pairs + sRest++; + while ( sRest ) + { + char * sId = sRest; + if (!( sRest = strchr ( sRest, ':' ) )) break; *sRest++ = '\0'; + if (!( sRest - sId )) break; + + char * sValue = sRest; + if (( sRest = strchr ( sRest, ',' ) )) *sRest++ = '\0'; + if ( !*sValue ) + break; + + if ( !pOverride ) + { + pOverride = new CSphSEQuery::Override_t; + pOverride->m_sName = chop(sName); + pOverride->m_iType = iType; + m_dOverrides.append(pOverride); + } + + ulonglong uId = strtoull ( sId, NULL, 10 ); + CSphSEQuery::Override_t::Value_t tValue; + if ( iType == SPH_ATTR_FLOAT ) + tValue.m_fValue = (float)atof(sValue); + else if ( iType == SPH_ATTR_BIGINT ) + tValue.m_iValue64 = strtoll ( sValue, NULL, 10 ); + else + tValue.m_uValue = (uint32)strtoul ( sValue, NULL, 10 ); + + pOverride->m_dIds.append ( uId ); + pOverride->m_dValues.append ( tValue ); + } + + if ( !pOverride ) + { + snprintf ( m_sParseError, sizeof(m_sParseError), "override: id:value mapping expected" ); + SPH_RET(false); + } + SPH_RET(true); + } + else + { + snprintf ( m_sParseError, sizeof(m_sParseError), "unknown parameter '%s'", sName ); + SPH_RET(false); + } + + // !COMMIT handle syntax errors + + SPH_RET(true); +} + + +bool CSphSEQuery::Parse () +{ + SPH_ENTER_METHOD(); + SPH_DEBUG ( "query [[ %s ]]", m_sQueryBuffer ); + + m_bQuery = false; + char * pCur = m_sQueryBuffer; + char * pNext = pCur; + + while (( pNext = strchr ( pNext, ';' ) )) + { + // handle escaped semicolons + if ( pNext>m_sQueryBuffer && pNext[-1]=='\\' && pNext[1]!='\0' ) + { + pNext++; + continue; + } + + // handle semicolon-separated clauses + *pNext++ = '\0'; + if ( !ParseField ( pCur ) ) + SPH_RET(false); + pCur = pNext; + } + + SPH_RET(true); +} + + +void CSphSEQuery::SendBytes ( const void * pBytes, int iBytes ) +{ + SPH_ENTER_METHOD(); + if ( m_iBufLeft<iBytes ) + { + m_bBufOverrun = true; + SPH_VOID_RET(); + } + + memcpy ( m_pCur, pBytes, iBytes ); + + m_pCur += iBytes; + m_iBufLeft -= iBytes; + SPH_VOID_RET(); +} + + +int CSphSEQuery::BuildRequest ( char ** ppBuffer ) +{ + SPH_ENTER_METHOD(); + + // calc request length + int iReqSize = 124 + 4*m_iWeights + + strlen ( m_sSortBy ) + + strlen ( m_sQuery ) + + strlen ( m_sIndex ) + + strlen ( m_sGroupBy ) + + strlen ( m_sGroupSortBy ) + + strlen ( m_sGroupDistinct ) + + strlen ( m_sComment ); + for ( int i=0; i<m_iFilters; i++ ) + { + const CSphSEFilter & tFilter = m_dFilters[i]; + iReqSize += 12 + strlen ( tFilter.m_sAttrName ); // string attr-name; int type; int exclude-flag + switch ( tFilter.m_eType ) + { + case SPH_FILTER_VALUES: iReqSize += 4 + 8*tFilter.m_iValues; break; + case SPH_FILTER_RANGE: iReqSize += 16; break; + case SPH_FILTER_FLOATRANGE: iReqSize += 8; break; + } + } + if ( m_bGeoAnchor ) // 1.14+ + iReqSize += 16 + strlen ( m_sGeoLatAttr ) + strlen ( m_sGeoLongAttr ); + for ( int i=0; i<m_iIndexWeights; i++ ) // 1.15+ + iReqSize += 8 + strlen(m_sIndexWeight[i] ); + for ( int i=0; i<m_iFieldWeights; i++ ) // 1.18+ + iReqSize += 8 + strlen(m_sFieldWeight[i] ); + // overrides + iReqSize += 4; + for ( int i=0; i<m_dOverrides.elements(); i++ ) + { + CSphSEQuery::Override_t * pOverride = m_dOverrides.at(i); + const uint32 uSize = pOverride->m_iType == SPH_ATTR_BIGINT ? 16 : 12; // id64 + value + iReqSize += strlen ( pOverride->m_sName ) + 12 + uSize*pOverride->m_dIds.elements(); + } + // select + iReqSize += 4; + + m_iBufLeft = 0; + SafeDeleteArray ( m_pBuf ); + + m_pBuf = new char [ iReqSize ]; + if ( !m_pBuf ) + SPH_RET(-1); + + m_pCur = m_pBuf; + m_iBufLeft = iReqSize; + m_bBufOverrun = false; + (*ppBuffer) = m_pBuf; + + // build request + SendWord ( SEARCHD_COMMAND_SEARCH ); // command id + SendWord ( VER_COMMAND_SEARCH ); // command version + SendInt ( iReqSize-8 ); // packet body length + + SendInt ( 1 ); // number of queries + SendInt ( m_iOffset ); + SendInt ( m_iLimit ); + SendInt ( m_eMode ); + SendInt ( m_eRanker ); // 1.16+ + SendInt ( m_eSort ); + SendString ( m_sSortBy ); // sort attr + SendString ( m_sQuery ); // query + SendInt ( m_iWeights ); + for ( int j=0; j<m_iWeights; j++ ) + SendInt ( m_pWeights[j] ); // weights + SendString ( m_sIndex ); // indexes + SendInt ( 1 ); // id64 range follows + SendUint64 ( m_iMinID ); // id/ts ranges + SendUint64 ( m_iMaxID ); + + SendInt ( m_iFilters ); + for ( int j=0; j<m_iFilters; j++ ) + { + const CSphSEFilter & tFilter = m_dFilters[j]; + SendString ( tFilter.m_sAttrName ); + SendInt ( tFilter.m_eType ); + + switch ( tFilter.m_eType ) + { + case SPH_FILTER_VALUES: + SendInt ( tFilter.m_iValues ); + for ( int k=0; k<tFilter.m_iValues; k++ ) + SendUint64 ( tFilter.m_pValues[k] ); + break; + + case SPH_FILTER_RANGE: + SendUint64 ( tFilter.m_uMinValue ); + SendUint64 ( tFilter.m_uMaxValue ); + break; + + case SPH_FILTER_FLOATRANGE: + SendFloat ( tFilter.m_fMinValue ); + SendFloat ( tFilter.m_fMaxValue ); + break; + } + + SendInt ( tFilter.m_bExclude ); + } + + SendInt ( m_eGroupFunc ); + SendString ( m_sGroupBy ); + SendInt ( m_iMaxMatches ); + SendString ( m_sGroupSortBy ); + SendInt ( m_iCutoff ); // 1.9+ + SendInt ( m_iRetryCount ); // 1.10+ + SendInt ( m_iRetryDelay ); + SendString ( m_sGroupDistinct ); // 1.11+ + SendInt ( m_bGeoAnchor ); // 1.14+ + if ( m_bGeoAnchor ) + { + SendString ( m_sGeoLatAttr ); + SendString ( m_sGeoLongAttr ); + SendFloat ( m_fGeoLatitude ); + SendFloat ( m_fGeoLongitude ); + } + SendInt ( m_iIndexWeights ); // 1.15+ + for ( int i=0; i<m_iIndexWeights; i++ ) + { + SendString ( m_sIndexWeight[i] ); + SendInt ( m_iIndexWeight[i] ); + } + SendInt ( m_iMaxQueryTime ); // 1.17+ + SendInt ( m_iFieldWeights ); // 1.18+ + for ( int i=0; i<m_iFieldWeights; i++ ) + { + SendString ( m_sFieldWeight[i] ); + SendInt ( m_iFieldWeight[i] ); + } + SendString ( m_sComment ); + + // overrides + SendInt ( m_dOverrides.elements() ); + for ( int i=0; i<m_dOverrides.elements(); i++ ) + { + CSphSEQuery::Override_t * pOverride = m_dOverrides.at(i); + SendString ( pOverride->m_sName ); + SendDword ( pOverride->m_iType ); + SendInt ( pOverride->m_dIds.elements() ); + for ( int j=0; j<pOverride->m_dIds.elements(); j++ ) + { + SendUint64 ( pOverride->m_dIds.at(j) ); + if ( pOverride->m_iType == SPH_ATTR_FLOAT ) + SendFloat ( pOverride->m_dValues.at(j).m_fValue ); + else if ( pOverride->m_iType == SPH_ATTR_BIGINT ) + SendUint64 ( pOverride->m_dValues.at(j).m_iValue64 ); + else + SendDword ( pOverride->m_dValues.at(j).m_uValue ); + } + } + + // select + SendString ( "" ); + + // detect buffer overruns and underruns, and report internal error + if ( m_bBufOverrun || m_iBufLeft!=0 || m_pCur-m_pBuf!=iReqSize ) + SPH_RET(-1); + + // all fine + SPH_RET(iReqSize); +} + +////////////////////////////////////////////////////////////////////////////// +// SPHINX HANDLER +////////////////////////////////////////////////////////////////////////////// + +static const char * ha_sphinx_exts[] = { NullS }; + + +#if MYSQL_VERSION_ID<50100 +ha_sphinx::ha_sphinx ( TABLE_ARG * table ) + : handler ( &sphinx_hton, table ) +#else +ha_sphinx::ha_sphinx ( handlerton * hton, TABLE_ARG * table ) + : handler ( hton, table ) +#endif + , m_pShare ( NULL ) + , m_iMatchesTotal ( 0 ) + , m_iCurrentPos ( 0 ) + , m_pCurrentKey ( NULL ) + , m_iCurrentKeyLen ( 0 ) + , m_pResponse ( NULL ) + , m_pResponseEnd ( NULL ) + , m_pCur ( NULL ) + , m_bUnpackError ( false ) + , m_iFields ( 0 ) + , m_dFields ( NULL ) + , m_iAttrs ( 0 ) + , m_dAttrs ( NULL ) + , m_bId64 ( 0 ) + , m_dUnboundFields ( NULL ) +{ + SPH_ENTER_METHOD(); + SPH_VOID_RET(); +} + + +// If frm_error() is called then we will use this to to find out what file extentions +// exist for the storage engine. This is also used by the default rename_table and +// delete_table method in handler.cc. +const char ** ha_sphinx::bas_ext() const +{ + return ha_sphinx_exts; +} + + +// Used for opening tables. The name will be the name of the file. +// A table is opened when it needs to be opened. For instance +// when a request comes in for a select on the table (tables are not +// open and closed for each request, they are cached). +// +// Called from handler.cc by handler::ha_open(). The server opens all tables by +// calling ha_open() which then calls the handler specific open(). +int ha_sphinx::open ( const char * name, int, uint ) +{ + SPH_ENTER_METHOD(); + m_pShare = get_share ( name, table ); + if ( !m_pShare ) + SPH_RET(1); + + thr_lock_data_init ( &m_pShare->m_tLock, &m_tLock, NULL ); + + *thd_ha_data ( table->in_use, ht ) = NULL; + + SPH_RET(0); +} + + +int ha_sphinx::ConnectToSearchd ( const char * sQueryHost, int iQueryPort ) +{ + SPH_ENTER_METHOD(); + + struct sockaddr_in sin; +#ifndef __WIN__ + struct sockaddr_un saun; +#endif + + int iDomain = 0; + int iSockaddrSize = 0; + struct sockaddr * pSockaddr = NULL; + + in_addr_t ip_addr; + int version; + uint uClientVersion = htonl ( SPHINX_SEARCHD_PROTO ); + + const char * sHost = ( sQueryHost && *sQueryHost ) ? sQueryHost : m_pShare->m_sHost; + ushort iPort = iQueryPort ? (ushort)iQueryPort : m_pShare->m_iPort; + + if ( iPort ) + { + iDomain = AF_INET; + iSockaddrSize = sizeof(sin); + pSockaddr = (struct sockaddr *) &sin; + + memset ( &sin, 0, sizeof(sin) ); + sin.sin_family = AF_INET; + sin.sin_port = htons(iPort); + + // prepare host address + if ( (int)( ip_addr=inet_addr(sHost) ) != (int)INADDR_NONE ) + { + memcpy ( &sin.sin_addr, &ip_addr, sizeof(ip_addr) ); + } else + { + int tmp_errno; + struct hostent tmp_hostent, *hp; + char buff2 [ GETHOSTBYNAME_BUFF_SIZE ]; + + hp = my_gethostbyname_r ( sHost, &tmp_hostent, + buff2, sizeof(buff2), &tmp_errno ); + if ( !hp ) + { + my_gethostbyname_r_free(); + + char sError[256]; + my_snprintf ( sError, sizeof(sError), "failed to resolve searchd host (name=%s)", sHost ); + + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError ); + SPH_RET(-1); + } + + memcpy ( &sin.sin_addr, hp->h_addr, + Min ( sizeof(sin.sin_addr), (size_t)hp->h_length ) ); + my_gethostbyname_r_free(); + } + } else + { +#ifndef __WIN__ + iDomain = AF_UNIX; + iSockaddrSize = sizeof(saun); + pSockaddr = (struct sockaddr *) &saun; + + memset ( &saun, 0, sizeof(saun) ); + saun.sun_family = AF_UNIX; + strncpy ( saun.sun_path, sHost, sizeof(saun.sun_path)-1 ); +#else + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "UNIX sockets are not supported on Windows" ); + SPH_RET(-1); +#endif + } + + char sError[512]; + int iSocket = socket ( iDomain, SOCK_STREAM, 0 ); + + if ( iSocket<0 ) + { + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "failed to create client socket" ); + SPH_RET(-1); + } + + if ( connect ( iSocket, pSockaddr, iSockaddrSize )<0 ) + { + sphSockClose ( iSocket ); + my_snprintf ( sError, sizeof(sError), "failed to connect to searchd (host=%s, errno=%d, port=%d)", + sHost, errno, iPort ); + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError ); + SPH_RET(-1); + } + + if ( ::recv ( iSocket, (char *)&version, sizeof(version), 0 )!=sizeof(version) ) + { + sphSockClose ( iSocket ); + my_snprintf ( sError, sizeof(sError), "failed to receive searchd version (host=%s, port=%d)", + sHost, iPort ); + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError ); + SPH_RET(-1); + } + + if ( ::send ( iSocket, (char*)&uClientVersion, sizeof(uClientVersion), 0 )!=sizeof(uClientVersion) ) + { + sphSockClose ( iSocket ); + my_snprintf ( sError, sizeof(sError), "failed to send client version (host=%s, port=%d)", + sHost, iPort ); + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError ); + SPH_RET(-1); + } + + SPH_RET(iSocket); +} + + +// Closes a table. We call the free_share() function to free any resources +// that we have allocated in the "shared" structure. +// +// Called from sql_base.cc, sql_select.cc, and table.cc. +// In sql_select.cc it is only used to close up temporary tables or during +// the process where a temporary table is converted over to being a +// myisam table. +// For sql_base.cc look at close_data_tables(). +int ha_sphinx::close() +{ + SPH_ENTER_METHOD(); + SPH_RET ( free_share(m_pShare) ); +} + + +int ha_sphinx::write_row ( uchar * ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_WRONG_COMMAND ); +} + + +int ha_sphinx::update_row ( const uchar *, uchar * ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_WRONG_COMMAND ); +} + + +int ha_sphinx::delete_row ( const uchar * ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_WRONG_COMMAND ); +} + + +// keynr is key (index) number +// sorted is 1 if result MUST be sorted according to index +int ha_sphinx::index_init ( uint keynr, bool ) +{ + SPH_ENTER_METHOD(); + active_index = keynr; + SPH_RET(0); +} + + +int ha_sphinx::index_end() +{ + SPH_ENTER_METHOD(); + SPH_RET(0); +} + + +uint32 ha_sphinx::UnpackDword () +{ + if ( m_pCur+sizeof(uint32)>m_pResponseEnd ) + { + m_pCur = m_pResponseEnd; + m_bUnpackError = true; + return 0; + } + + uint32 uRes = ntohl ( sphUnalignedRead ( *(uint32*)m_pCur ) ); + m_pCur += sizeof(uint32); + return uRes; +} + + +char * ha_sphinx::UnpackString () +{ + uint32 iLen = UnpackDword (); + if ( !iLen ) + return NULL; + + if ( m_pCur+iLen>m_pResponseEnd ) + { + m_pCur = m_pResponseEnd; + m_bUnpackError = true; + return NULL; + } + + char * sRes = new char [ 1+iLen ]; + memcpy ( sRes, m_pCur, iLen ); + sRes[iLen] = '\0'; + m_pCur += iLen; + return sRes; +} + + +static inline const char * FixNull ( const char * s ) +{ + return s ? s : "(null)"; +} + + +bool ha_sphinx::UnpackSchema () +{ + SPH_ENTER_METHOD(); + + // cleanup + if ( m_dFields ) + for ( int i=0; i<(int)m_iFields; i++ ) + SafeDeleteArray ( m_dFields[i] ); + SafeDeleteArray ( m_dFields ); + + // unpack network packet + uint32 uStatus = UnpackDword (); + char * sMessage = NULL; + + if ( uStatus!=SEARCHD_OK ) + { + sMessage = UnpackString (); + CSphSEThreadData * pTls = GetTls (); + if ( pTls ) + { + strncpy ( pTls->m_tStats.m_sLastMessage, sMessage, sizeof(pTls->m_tStats.m_sLastMessage) ); + pTls->m_tStats.m_bLastError = ( uStatus==SEARCHD_ERROR ); + } + + if ( uStatus==SEARCHD_ERROR ) + { + char sError[1024]; + my_snprintf ( sError, sizeof(sError), "searchd error: %s", sMessage ); + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), sError ); + SafeDeleteArray ( sMessage ); + SPH_RET ( false ); + } + } + + m_iFields = UnpackDword (); + m_dFields = new char * [ m_iFields ]; + if ( !m_dFields ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: UnpackSchema() failed (fields alloc error)" ); + SPH_RET(false); + } + + for ( uint32 i=0; i<m_iFields; i++ ) + m_dFields[i] = UnpackString (); + + SafeDeleteArray ( m_dAttrs ); + m_iAttrs = UnpackDword (); + m_dAttrs = new CSphSEAttr [ m_iAttrs ]; + if ( !m_dAttrs ) + { + for ( int i=0; i<(int)m_iFields; i++ ) + SafeDeleteArray ( m_dFields[i] ); + SafeDeleteArray ( m_dFields ); + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: UnpackSchema() failed (attrs alloc error)" ); + SPH_RET(false); + } + + for ( uint32 i=0; i<m_iAttrs; i++ ) + { + m_dAttrs[i].m_sName = UnpackString (); + m_dAttrs[i].m_uType = UnpackDword (); + if ( m_bUnpackError ) // m_sName may be null + break; + + m_dAttrs[i].m_iField = -1; + for ( int j=SPHINXSE_SYSTEM_COLUMNS; j<m_pShare->m_iTableFields; j++ ) + { + const char * sTableField = m_pShare->m_sTableField[j]; + const char * sAttrField = m_dAttrs[i].m_sName; + if ( m_dAttrs[i].m_sName[0]=='@' ) + { + const char * sAtPrefix = "_sph_"; + if ( strncmp ( sTableField, sAtPrefix, strlen(sAtPrefix) ) ) + continue; + sTableField += strlen(sAtPrefix); + sAttrField++; + } + + if ( !strcasecmp ( sAttrField, sTableField ) ) + { + // we're almost good, but + // let's enforce that timestamp columns can only receive timestamp attributes + if ( m_pShare->m_eTableFieldType[j]!=MYSQL_TYPE_TIMESTAMP || m_dAttrs[i].m_uType==SPH_ATTR_TIMESTAMP ) + m_dAttrs[i].m_iField = j; + break; + } + } + } + + m_iMatchesTotal = UnpackDword (); + + m_bId64 = UnpackDword (); + if ( m_bId64 && m_pShare->m_eTableFieldType[0] != MYSQL_TYPE_LONGLONG ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: 1st column must be bigint to accept 64-bit DOCIDs" ); + SPH_RET(false); + } + + // network packet unpacked; build unbound fields map + SafeDeleteArray ( m_dUnboundFields ); + m_dUnboundFields = new int [ m_pShare->m_iTableFields ]; + + for ( int i=0; i<m_pShare->m_iTableFields; i++ ) + { + if ( i<SPHINXSE_SYSTEM_COLUMNS ) + m_dUnboundFields[i] = SPH_ATTR_NONE; + + else if ( m_pShare->m_eTableFieldType[i]==MYSQL_TYPE_TIMESTAMP ) + m_dUnboundFields[i] = SPH_ATTR_TIMESTAMP; + + else + m_dUnboundFields[i] = SPH_ATTR_INTEGER; + } + + for ( uint32 i=0; i<m_iAttrs; i++ ) + if ( m_dAttrs[i].m_iField>=0 ) + m_dUnboundFields [ m_dAttrs[i].m_iField ] = SPH_ATTR_NONE; + + if ( m_bUnpackError ) + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: UnpackSchema() failed (unpack error)" ); + + SPH_RET(!m_bUnpackError); +} + + +bool ha_sphinx::UnpackStats ( CSphSEStats * pStats ) +{ + assert ( pStats ); + + char * pCurSave = m_pCur; + for ( uint i=0; i<m_iMatchesTotal && m_pCur<m_pResponseEnd-sizeof(uint32); i++ ) + { + m_pCur += m_bId64 ? 12 : 8; // skip id+weight + for ( uint32 i=0; i<m_iAttrs && m_pCur<m_pResponseEnd-sizeof(uint32); i++ ) + { + if ( m_dAttrs[i].m_uType & SPH_ATTR_MULTI ) + { + // skip MVA list + uint32 uCount = UnpackDword (); + m_pCur += uCount*4; + } + else // skip normal value + m_pCur += m_dAttrs[i].m_uType == SPH_ATTR_BIGINT ? 8 : 4; + } + } + + pStats->m_iMatchesTotal = UnpackDword (); + pStats->m_iMatchesFound = UnpackDword (); + pStats->m_iQueryMsec = UnpackDword (); + pStats->m_iWords = UnpackDword (); + + if ( m_bUnpackError ) + return false; + + SafeDeleteArray ( pStats->m_dWords ); + if ( pStats->m_iWords<0 || pStats->m_iWords>=SPHINXSE_MAX_KEYWORDSTATS ) + return false; + pStats->m_dWords = new CSphSEWordStats [ pStats->m_iWords ]; + if ( !pStats->m_dWords ) + return false; + + for ( int i=0; i<pStats->m_iWords; i++ ) + { + CSphSEWordStats & tWord = pStats->m_dWords[i]; + tWord.m_sWord = UnpackString (); + tWord.m_iDocs = UnpackDword (); + tWord.m_iHits = UnpackDword (); + } + + if ( m_bUnpackError ) + return false; + + m_pCur = pCurSave; + return true; +} + + +/// condition pushdown implementation, to properly intercept WHERE clauses on my columns +const COND * ha_sphinx::cond_push ( const COND * cond ) +{ + // catch the simplest case: query_column="some text" + for ( ;; ) + { + if ( cond->type()!=COND::FUNC_ITEM ) + break; + + Item_func * condf = (Item_func *)cond; + if ( condf->functype()!=Item_func::EQ_FUNC || condf->argument_count()!=2 ) + break; + + Item ** args = condf->arguments(); + if ( args[0]->type()!=COND::FIELD_ITEM || args[1]->type()!=COND::STRING_ITEM ) + break; + + Item_field * pField = (Item_field *) args[0]; + if ( pField->field->field_index!=2 ) // FIXME! magic key index + break; + + // get my tls + CSphSEThreadData * pTls = GetTls (); + if ( !pTls ) + break; + + // copy the query, and let know that we intercepted this condition + Item_string * pString = (Item_string *) args[1]; + pTls->m_bQuery = true; + strncpy ( pTls->m_sQuery, pString->str_value.c_ptr(), sizeof(pTls->m_sQuery) ); + pTls->m_sQuery[sizeof(pTls->m_sQuery)-1] = '\0'; + pTls->m_pQueryCharset = pString->str_value.charset(); + return NULL; + } + + // don't change anything + return cond; +} + + +/// condition popup +void ha_sphinx::cond_pop () +{ + CSphSEThreadData * pTls = GetTls (); + if ( pTls && pTls->m_bQuery ) + pTls->m_bQuery = false; + return; +} + + +/// get TLS (maybe allocate it, too) +CSphSEThreadData * ha_sphinx::GetTls() +{ + // where do we store that pointer in today's version? + CSphSEThreadData ** ppTls; + ppTls = (CSphSEThreadData**) thd_ha_data ( ha_thd(), ht ); + + // allocate if needed + if ( !*ppTls ) + *ppTls = new CSphSEThreadData (); + + // errors will be handled by caller + return *ppTls; +} + + +// Positions an index cursor to the index specified in the handle. Fetches the +// row if available. If the key value is null, begin at the first key of the +// index. +int ha_sphinx::index_read ( byte * buf, const byte * key, uint key_len, enum ha_rkey_function ) +{ + SPH_ENTER_METHOD(); + char sError[256]; + + // set new data for thd->ha_data, it is used in show_status + CSphSEThreadData * pTls = GetTls(); + if ( !pTls ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: TLS malloc() failed" ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + pTls->m_tStats.Reset (); + + // parse query + if ( pTls->m_bQuery ) + { + // we have a query from condition pushdown + m_pCurrentKey = (const byte *) pTls->m_sQuery; + m_iCurrentKeyLen = strlen(pTls->m_sQuery); + } else + { + // just use the key (might be truncated) + m_pCurrentKey = key+HA_KEY_BLOB_LENGTH; + m_iCurrentKeyLen = uint2korr(key); // or maybe key_len? + pTls->m_pQueryCharset = m_pShare ? m_pShare->m_pTableQueryCharset : NULL; + } + + CSphSEQuery q ( (const char*)m_pCurrentKey, m_iCurrentKeyLen, m_pShare->m_sIndex ); + if ( !q.Parse () ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), q.m_sParseError ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + // do connect + int iSocket = ConnectToSearchd ( q.m_sHost, q.m_iPort ); + if ( iSocket<0 ) + SPH_RET ( HA_ERR_END_OF_FILE ); + + // my buffer + char * pBuffer; // will be free by CSphSEQuery dtor; do NOT free manually + int iReqLen = q.BuildRequest ( &pBuffer ); + + if ( iReqLen<=0 ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: q.BuildRequest() failed" ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + // send request + ::send ( iSocket, pBuffer, iReqLen, 0 ); + + // receive reply + char sHeader[8]; + int iGot = ::recv ( iSocket, sHeader, sizeof(sHeader), RECV_FLAGS ); + if ( iGot!=sizeof(sHeader) ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "failed to receive response header (searchd went away?)" ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + short int uRespStatus = ntohs ( sphUnalignedRead ( *(short int*)( &sHeader[0] ) ) ); + short int uRespVersion = ntohs ( sphUnalignedRead ( *(short int*)( &sHeader[2] ) ) ); + uint uRespLength = ntohl ( sphUnalignedRead ( *(uint *)( &sHeader[4] ) ) ); + SPH_DEBUG ( "got response header (status=%d version=%d length=%d)", + uRespStatus, uRespVersion, uRespLength ); + + SafeDeleteArray ( m_pResponse ); + if ( uRespLength<=SPHINXSE_MAX_ALLOC ) + m_pResponse = new char [ uRespLength+1 ]; + + if ( !m_pResponse ) + { + my_snprintf ( sError, sizeof(sError), "bad searchd response length (length=%u)", uRespLength ); + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), sError ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + int iRecvLength = 0; + while ( iRecvLength<(int)uRespLength ) + { + int iRecv = ::recv ( iSocket, m_pResponse+iRecvLength, uRespLength-iRecvLength, RECV_FLAGS ); + if ( iRecv<0 ) + break; + iRecvLength += iRecv; + } + + ::closesocket ( iSocket ); + iSocket = -1; + + if ( iRecvLength!=(int)uRespLength ) + { + my_snprintf ( sError, sizeof(sError), "net read error (expected=%d, got=%d)", uRespLength, iRecvLength ); + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), sError ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + // we'll have a message, at least + pTls->m_bStats = true; + + // parse reply + m_iCurrentPos = 0; + m_pCur = m_pResponse; + m_pResponseEnd = m_pResponse + uRespLength; + m_bUnpackError = false; + + if ( uRespStatus!=SEARCHD_OK ) + { + char * sMessage = UnpackString (); + if ( !sMessage ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "no valid response from searchd (status=%d, resplen=%d)", + uRespStatus, uRespLength ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + strncpy ( pTls->m_tStats.m_sLastMessage, sMessage, sizeof(pTls->m_tStats.m_sLastMessage) ); + SafeDeleteArray ( sMessage ); + + if ( uRespStatus!=SEARCHD_WARNING ) + { + my_snprintf ( sError, sizeof(sError), "searchd error: %s", pTls->m_tStats.m_sLastMessage ); + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), sError ); + + pTls->m_tStats.m_bLastError = true; + SPH_RET ( HA_ERR_END_OF_FILE ); + } + } + + if ( !UnpackSchema () ) + SPH_RET ( HA_ERR_END_OF_FILE ); + + if ( !UnpackStats ( &pTls->m_tStats ) ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: UnpackStats() failed" ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + SPH_RET ( get_rec ( buf, key, key_len ) ); +} + + +// Positions an index cursor to the index specified in key. Fetches the +// row if any. This is only used to read whole keys. +int ha_sphinx::index_read_idx ( byte *, uint, const byte *, uint, enum ha_rkey_function ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_WRONG_COMMAND ); +} + + +// Used to read forward through the index. +int ha_sphinx::index_next ( byte * buf ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( get_rec ( buf, m_pCurrentKey, m_iCurrentKeyLen ) ); +} + + +int ha_sphinx::index_next_same ( byte * buf, const byte * key, uint keylen ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( get_rec ( buf, key, keylen ) ); +} + + +int ha_sphinx::get_rec ( byte * buf, const byte *, uint ) +{ + SPH_ENTER_METHOD(); + + if ( m_iCurrentPos>=m_iMatchesTotal ) + { + SafeDeleteArray ( m_pResponse ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + #if MYSQL_VERSION_ID>50100 + my_bitmap_map * org_bitmap = dbug_tmp_use_all_columns ( table, table->write_set ); + #endif + Field ** field = table->field; + + // unpack and return the match + longlong uMatchID = UnpackDword (); + if ( m_bId64 ) + uMatchID = ( uMatchID<<32 ) + UnpackDword(); + uint32 uMatchWeight = UnpackDword (); + + field[0]->store ( uMatchID, 1 ); + field[1]->store ( uMatchWeight, 1 ); + field[2]->store ( (const char*)m_pCurrentKey, m_iCurrentKeyLen, &my_charset_bin ); + + for ( uint32 i=0; i<m_iAttrs; i++ ) + { + longlong iValue64= 0; + uint32 uValue = UnpackDword (); + if ( m_dAttrs[i].m_uType == SPH_ATTR_BIGINT ) + iValue64 = ( (longlong)uValue<<32 ) | UnpackDword(); + if ( m_dAttrs[i].m_iField<0 ) + { + // skip MVA + if ( m_dAttrs[i].m_uType & SPH_ATTR_MULTI ) + for ( ; uValue>0 && !m_bUnpackError; uValue-- ) + UnpackDword(); + continue; + } + + Field * af = field [ m_dAttrs[i].m_iField ]; + switch ( m_dAttrs[i].m_uType ) + { + case SPH_ATTR_INTEGER: + case SPH_ATTR_ORDINAL: + case SPH_ATTR_BOOL: + af->store ( uValue, 1 ); + break; + + case SPH_ATTR_FLOAT: + af->store ( sphDW2F(uValue) ); + break; + + case SPH_ATTR_TIMESTAMP: + if ( af->type()==MYSQL_TYPE_TIMESTAMP ) + longstore ( af->ptr, uValue ); // because store() does not accept timestamps + else + af->store ( uValue, 1 ); + break; + + case SPH_ATTR_BIGINT: + af->store ( iValue64, 0 ); + break; + + case ( SPH_ATTR_MULTI | SPH_ATTR_INTEGER ): + if ( uValue<=0 ) + { + // shortcut, empty MVA set + af->store ( "", 0, &my_charset_bin ); + + } else + { + // convert MVA set to comma-separated string + char sBuf[1024]; // FIXME! magic size + char * pCur = sBuf; + + for ( ; uValue>0 && !m_bUnpackError; uValue-- ) + { + uint32 uEntry = UnpackDword (); + if ( pCur < sBuf+sizeof(sBuf)-16 ) // 10 chars per 32bit value plus some safety bytes + { + sprintf ( pCur, "%u", uEntry ); + while ( *pCur ) pCur++; + if ( uValue>1 ) + *pCur++ = ','; // non-trailing commas + } + } + + af->store ( sBuf, pCur-sBuf, &my_charset_bin ); + } + break; + + default: + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: unhandled attr type" ); + SafeDeleteArray ( m_pResponse ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + } + + if ( m_bUnpackError ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: response unpacker failed" ); + SafeDeleteArray ( m_pResponse ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + // zero out unmapped fields + for ( int i=SPHINXSE_SYSTEM_COLUMNS; i<(int)table->s->fields; i++ ) + if ( m_dUnboundFields[i]!=SPH_ATTR_NONE ) + switch ( m_dUnboundFields[i] ) + { + case SPH_ATTR_INTEGER: table->field[i]->store ( 0, 1 ); break; + case SPH_ATTR_TIMESTAMP: longstore ( table->field[i]->ptr, 0 ); break; + default: + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), + "INTERNAL ERROR: unhandled unbound field type %d", m_dUnboundFields[i] ); + SafeDeleteArray ( m_pResponse ); + SPH_RET ( HA_ERR_END_OF_FILE ); + } + + memset ( buf, 0, table->s->null_bytes ); + m_iCurrentPos++; + + #if MYSQL_VERSION_ID > 50100 + dbug_tmp_restore_column_map(table->write_set, org_bitmap); + #endif + + SPH_RET(0); +} + + +// Used to read backwards through the index. +int ha_sphinx::index_prev ( byte * ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_WRONG_COMMAND ); +} + + +// index_first() asks for the first key in the index. +// +// Called from opt_range.cc, opt_sum.cc, sql_handler.cc, +// and sql_select.cc. +int ha_sphinx::index_first ( byte * ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_END_OF_FILE ); +} + +// index_last() asks for the last key in the index. +// +// Called from opt_range.cc, opt_sum.cc, sql_handler.cc, +// and sql_select.cc. +int ha_sphinx::index_last ( byte * ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_WRONG_COMMAND ); +} + + +int ha_sphinx::rnd_init ( bool ) +{ + SPH_ENTER_METHOD(); + SPH_RET(0); +} + + +int ha_sphinx::rnd_end() +{ + SPH_ENTER_METHOD(); + SPH_RET(0); +} + + +int ha_sphinx::rnd_next ( byte * ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_END_OF_FILE ); +} + + +void ha_sphinx::position ( const byte * ) +{ + SPH_ENTER_METHOD(); + SPH_VOID_RET(); +} + + +// This is like rnd_next, but you are given a position to use +// to determine the row. The position will be of the type that you stored in +// ref. You can use ha_get_ptr(pos,ref_length) to retrieve whatever key +// or position you saved when position() was called. +// Called from filesort.cc records.cc sql_insert.cc sql_select.cc sql_update.cc. +int ha_sphinx::rnd_pos ( byte *, byte * ) +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_WRONG_COMMAND ); +} + + +#if MYSQL_VERSION_ID>=50030 +int ha_sphinx::info ( uint ) +#else +void ha_sphinx::info ( uint ) +#endif +{ + SPH_ENTER_METHOD(); + + if ( table->s->keys>0 ) + table->key_info[0].rec_per_key[0] = 1; + + #if MYSQL_VERSION_ID>50100 + stats.records = 20; + #else + records = 20; + #endif + +#if MYSQL_VERSION_ID>=50030 + SPH_RET(0); +#else + SPH_VOID_RET(); +#endif +} + + +int ha_sphinx::reset () +{ + SPH_ENTER_METHOD(); + CSphSEThreadData * pTls = GetTls (); + if ( pTls ) + pTls->m_bQuery = false; + SPH_RET(0); +} + + +int ha_sphinx::delete_all_rows() +{ + SPH_ENTER_METHOD(); + SPH_RET ( HA_ERR_WRONG_COMMAND ); +} + + +// First you should go read the section "locking functions for mysql" in +// lock.cc to understand this. +// This create a lock on the table. If you are implementing a storage engine +// that can handle transacations look at ha_berkely.cc to see how you will +// want to go about doing this. Otherwise you should consider calling flock() +// here. +// +// Called from lock.cc by lock_external() and unlock_external(). Also called +// from sql_table.cc by copy_data_between_tables(). +int ha_sphinx::external_lock ( THD *, int ) +{ + SPH_ENTER_METHOD(); + SPH_RET(0); +} + + +THR_LOCK_DATA ** ha_sphinx::store_lock ( THD *, THR_LOCK_DATA ** to, + enum thr_lock_type lock_type ) +{ + SPH_ENTER_METHOD(); + + if ( lock_type!=TL_IGNORE && m_tLock.type==TL_UNLOCK ) + m_tLock.type=lock_type; + + *to++ = &m_tLock; + SPH_RET(to); +} + + +int ha_sphinx::delete_table ( const char * ) +{ + SPH_ENTER_METHOD(); + SPH_RET(0); +} + + +// Renames a table from one name to another from alter table call. +// +// If you do not implement this, the default rename_table() is called from +// handler.cc and it will delete all files with the file extentions returned +// by bas_ext(). +// +// Called from sql_table.cc by mysql_rename_table(). +int ha_sphinx::rename_table ( const char *, const char * ) +{ + SPH_ENTER_METHOD(); + SPH_RET(0); +} + + +// Given a starting key, and an ending key estimate the number of rows that +// will exist between the two. end_key may be empty which in case determine +// if start_key matches any rows. +// +// Called from opt_range.cc by check_quick_keys(). +ha_rows ha_sphinx::records_in_range ( uint, key_range *, key_range * ) +{ + SPH_ENTER_METHOD(); + SPH_RET(3); // low number to force index usage +} + + +static inline bool IsIntegerFieldType ( enum_field_types eType ) +{ + return eType==MYSQL_TYPE_LONG || eType==MYSQL_TYPE_LONGLONG; +} + + +// create() is called to create a database. The variable name will have the name +// of the table. When create() is called you do not need to worry about opening +// the table. Also, the FRM file will have already been created so adjusting +// create_info will not do you any good. You can overwrite the frm file at this +// point if you wish to change the table definition, but there are no methods +// currently provided for doing that. +// +// Called from handle.cc by ha_create_table(). +int ha_sphinx::create ( const char * name, TABLE * table, HA_CREATE_INFO * ) +{ + SPH_ENTER_METHOD(); + char sError[256]; + + if ( !ParseUrl ( NULL, table, true ) ) + SPH_RET(-1); + + for ( ;; ) + { + // check system fields (count and types) + if ( table->s->fields<SPHINXSE_SYSTEM_COLUMNS ) + { + my_snprintf ( sError, sizeof(sError), "%s: there MUST be at least %d columns", + name, SPHINXSE_SYSTEM_COLUMNS ); + break; + } + + if ( !IsIntegerFieldType ( table->field[0]->type() ) || !((Field_num *)table->field[0])->unsigned_flag ) + { + my_snprintf ( sError, sizeof(sError), "%s: 1st column (docid) MUST be unsigned integer or bigint", name ); + break; + } + + if ( !IsIntegerFieldType ( table->field[1]->type() ) ) + { + my_snprintf ( sError, sizeof(sError), "%s: 2nd column (weight) MUST be integer or bigint", name ); + break; + } + + enum_field_types f2 = table->field[2]->type(); + if ( f2!=MYSQL_TYPE_VARCHAR + && f2!=MYSQL_TYPE_BLOB && f2!=MYSQL_TYPE_MEDIUM_BLOB && f2!=MYSQL_TYPE_LONG_BLOB && f2!=MYSQL_TYPE_TINY_BLOB ) + { + my_snprintf ( sError, sizeof(sError), "%s: 3rd column (search query) MUST be varchar or text", name ); + break; + } + + // check attributes + int i; + for ( i=3; i<(int)table->s->fields; i++ ) + { + enum_field_types eType = table->field[i]->type(); + if ( eType!=MYSQL_TYPE_TIMESTAMP && !IsIntegerFieldType(eType) && eType!=MYSQL_TYPE_VARCHAR && eType!=MYSQL_TYPE_FLOAT ) + { + my_snprintf ( sError, sizeof(sError), "%s: %dth column (attribute %s) MUST be integer, bigint, timestamp, varchar, or float", + name, i+1, table->field[i]->field_name ); + break; + } + } + + if ( i!=(int)table->s->fields ) + break; + + // check index + if ( + table->s->keys!=1 || + table->key_info[0].key_parts!=1 || + strcasecmp ( table->key_info[0].key_part[0].field->field_name, table->field[2]->field_name ) ) + { + my_snprintf ( sError, sizeof(sError), "%s: there must be an index on '%s' column", + name, table->field[2]->field_name ); + break; + } + + // all good + sError[0] = '\0'; + break; + } + if ( sError[0] ) + { + my_error ( ER_CANT_CREATE_TABLE, MYF(0), sError, -1 ); + SPH_RET(-1); + } + + SPH_RET(0); +} + +//// show functions + +#if MYSQL_VERSION_ID<50100 +#define SHOW_VAR_FUNC_BUFF_SIZE 1024 +#endif + +static int sphinx_showfunc ( THD * thd, SHOW_VAR * out, char * sBuffer ) +{ + CSphSEThreadData *pTls = (CSphSEThreadData *) *thd_ha_data ( thd, sphinx_hton_ptr ); + CSphSEStats * pStats = ( pTls && pTls->m_bStats ) ? &pTls->m_tStats : 0; + SHOW_VAR *array = (SHOW_VAR*)thd_alloc(thd, sizeof(SHOW_VAR)*7); + out->type = SHOW_ARRAY; + out->value = (char*)array; + if (pStats) + { + array[0].name = "total"; + array[0].type = SHOW_INT; + array[0].value = (char *) &pStats->m_iMatchesTotal; + array[1].name = "total_found"; + array[1].type = SHOW_INT; + array[1].value = (char *) &pStats->m_iMatchesFound; + array[2].name = "time"; + array[2].type = SHOW_INT; + array[2].value = (char *) &pStats->m_iQueryMsec; + array[3].name = "word_count"; + array[3].type = SHOW_INT; + array[3].value = (char *) &pStats->m_iWords; + array[4].name = "error"; + array[4].type = SHOW_CHAR; + array[4].value = (char *) &pStats->m_sLastMessage; + array[5].name = "words"; + array[5].type = SHOW_CHAR; + array[5].value = sBuffer; + sBuffer[0] = 0; + + if ( pStats->m_iWords ) + { + uint uBuffLen = 0; + + // the following is partially based on code in sphinx_show_status() + for ( int i=0; i<pStats->m_iWords; i++ ) + { + CSphSEWordStats & tWord = pStats->m_dWords[i]; + uBuffLen = my_snprintf ( sBuffer, SHOW_VAR_FUNC_BUFF_SIZE, "%s%s:%d:%d ", sBuffer, + tWord.m_sWord, tWord.m_iDocs, tWord.m_iHits ); + } + + if ( uBuffLen > 0 ) + { + // trim last space + sBuffer [ --uBuffLen ] = 0; + + if ( pTls->m_pQueryCharset ) + { + // String::c_ptr() will nul-terminate the buffer. + // + // NOTE: It's not entirely clear whether this conversion is necessary at all. + + String sConvert; + uint iErrors; + sConvert.copy ( sBuffer, uBuffLen, pTls->m_pQueryCharset, system_charset_info, &iErrors ); + memcpy ( sBuffer, sConvert.c_ptr(), sConvert.length() + 1 ); + } + } + } + + array[6].name = 0; // terminate the array + } + else + array[0].name = 0; + return 0; +} + +#if MYSQL_VERSION_ID>50100 +struct st_mysql_storage_engine sphinx_storage_engine = +{ + MYSQL_HANDLERTON_INTERFACE_VERSION +}; + +struct st_mysql_show_var sphinx_status_vars[] = +{ + {"sphinx", (char *)sphinx_showfunc, SHOW_FUNC}, + {0, 0, (enum_mysql_show_type)0} +}; + + +mysql_declare_plugin(sphinx) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &sphinx_storage_engine, + sphinx_hton_name, + "Sphinx developers", + sphinx_hton_comment, + PLUGIN_LICENSE_GPL, + sphinx_init_func, // Plugin Init + sphinx_done_func, // Plugin Deinit + 0x0001, // 0.1 + sphinx_status_vars, + NULL, + NULL +} +mysql_declare_plugin_end; + +#ifdef maria_declare_plugin +maria_declare_plugin(sphinx) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &sphinx_storage_engine, + sphinx_hton_name, + "Sphinx developers", + sphinx_hton_comment, + PLUGIN_LICENSE_GPL, + sphinx_init_func, // Plugin Init + sphinx_done_func, // Plugin Deinit + 0x0001, // 0.1 + sphinx_status_vars, + NULL, + "0.1", // string version + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL +} +maria_declare_plugin_end; +#endif + +#endif // >50100 + +// +// $Id: ha_sphinx.cc 2058 2009-11-07 04:01:57Z shodan $ +// diff --git a/storage/sphinx/ha_sphinx.h b/storage/sphinx/ha_sphinx.h new file mode 100644 index 00000000000..3f517062cff --- /dev/null +++ b/storage/sphinx/ha_sphinx.h @@ -0,0 +1,159 @@ +// +// $Id: ha_sphinx.h 1428 2008-09-05 18:06:30Z xale $ +// + +#ifdef USE_PRAGMA_INTERFACE +#pragma interface // gcc class implementation +#endif + + +#if MYSQL_VERSION_ID>50100 +#define TABLE_ARG st_table_share +#else +#define TABLE_ARG st_table +#endif + + +#if MYSQL_VERSION_ID>=50120 +typedef uchar byte; +#endif + + +/// forward decls +class THD; +struct CSphReqQuery; +struct CSphSEShare; +struct CSphSEAttr; +struct CSphSEStats; +struct CSphSEThreadData; + +/// Sphinx SE handler class +class ha_sphinx : public handler +{ +protected: + THR_LOCK_DATA m_tLock; ///< MySQL lock + + CSphSEShare * m_pShare; ///< shared lock info + + uint m_iMatchesTotal; + uint m_iCurrentPos; + const byte * m_pCurrentKey; + uint m_iCurrentKeyLen; + + char * m_pResponse; ///< searchd response storage + char * m_pResponseEnd; ///< searchd response storage end (points to wilderness!) + char * m_pCur; ///< current position into response + bool m_bUnpackError; ///< any errors while unpacking response + +public: +#if MYSQL_VERSION_ID<50100 + ha_sphinx ( TABLE_ARG * table_arg ); +#else + ha_sphinx ( handlerton * hton, TABLE_ARG * table_arg ); +#endif + ~ha_sphinx () {} + + const char * table_type () const { return "SPHINX"; } ///< SE name for display purposes + const char * index_type ( uint ) { return "HASH"; } ///< index type name for display purposes + const char ** bas_ext () const; ///< my file extensions + + #if MYSQL_VERSION_ID>50100 + ulonglong table_flags () const { return HA_CAN_INDEX_BLOBS; } ///< bitmap of implemented flags (see handler.h for more info) + #else + ulong table_flags () const { return HA_CAN_INDEX_BLOBS; } ///< bitmap of implemented flags (see handler.h for more info) + #endif + + ulong index_flags ( uint, uint, bool ) const { return 0; } ///< bitmap of flags that says how SE implements indexes + uint max_supported_record_length () const { return HA_MAX_REC_LENGTH; } + uint max_supported_keys () const { return 1; } + uint max_supported_key_parts () const { return 1; } + uint max_supported_key_length () const { return MAX_KEY_LENGTH; } + uint max_supported_key_part_length () const { return MAX_KEY_LENGTH; } + + #if MYSQL_VERSION_ID>50100 + virtual double scan_time () { return (double)( stats.records+stats.deleted )/20.0 + 10; } ///< called in test_quick_select to determine if indexes should be used + #else + virtual double scan_time () { return (double)( records+deleted )/20.0 + 10; } ///< called in test_quick_select to determine if indexes should be used + #endif + + virtual double read_time(uint index, uint ranges, ha_rows rows) + { return (double)rows/20.0 + 1; } ///< index read time estimate + +public: + int open ( const char * name, int mode, uint test_if_locked ); + int close (); + + int write_row ( uchar * buf ); + int update_row ( const uchar * old_data, uchar * new_data ); + int delete_row ( const uchar * buf ); + + int index_init ( uint keynr, bool sorted ); // 5.1.x + int index_init ( uint keynr ) { return index_init ( keynr, false ); } // 5.0.x + + int index_end (); + int index_read ( byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag ); + int index_read_idx ( byte * buf, uint idx, const byte * key, uint key_len, enum ha_rkey_function find_flag ); + int index_next ( byte * buf ); + int index_next_same ( byte * buf, const byte * key, uint keylen ); + int index_prev ( byte * buf ); + int index_first ( byte * buf ); + int index_last ( byte * buf ); + + int get_rec ( byte * buf, const byte * key, uint keylen ); + + int rnd_init ( bool scan ); + int rnd_end (); + int rnd_next ( byte * buf ); + int rnd_pos ( byte * buf, byte * pos ); + void position ( const byte * record ); + +#if MYSQL_VERSION_ID>=50030 + int info ( uint ); +#else + void info ( uint ); +#endif + + int reset(); + int external_lock ( THD * thd, int lock_type ); + int delete_all_rows (); + ha_rows records_in_range ( uint inx, key_range * min_key, key_range * max_key ); + + int delete_table ( const char * from ); + int rename_table ( const char * from, const char * to ); + int create ( const char * name, TABLE * form, HA_CREATE_INFO * create_info ); + + THR_LOCK_DATA **store_lock ( THD * thd, THR_LOCK_DATA ** to, enum thr_lock_type lock_type ); + +public: + virtual const COND * cond_push ( const COND *cond ); + virtual void cond_pop (); + +private: + uint32 m_iFields; + char ** m_dFields; + + uint32 m_iAttrs; + CSphSEAttr * m_dAttrs; + int m_bId64; + + int * m_dUnboundFields; + +private: + int ConnectToSearchd ( const char * sQueryHost, int iQueryPort ); + + uint32 UnpackDword (); + char * UnpackString (); + bool UnpackSchema (); + bool UnpackStats ( CSphSEStats * pStats ); + + CSphSEThreadData * GetTls (); +}; + + +#if MYSQL_VERSION_ID < 50100 +bool sphinx_show_status ( THD * thd ); +#endif + +// +// $Id: ha_sphinx.h 1428 2008-09-05 18:06:30Z xale $ +// diff --git a/storage/sphinx/make-patch.sh b/storage/sphinx/make-patch.sh new file mode 100644 index 00000000000..6fca5838ded --- /dev/null +++ b/storage/sphinx/make-patch.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +OUT=$1 +ORIG=$2 +NEW=$3 + +if [ ! \( "$1" -a "$2" -a "$3" \) ]; then + echo "$0 <patch> <original> <new>" + exit 1 +fi + +FILES=' +/config/ac-macros/ha_sphinx.m4 +/configure.in +/libmysqld/Makefile.am +/sql/handler.cc +/sql/handler.h +/sql/Makefile.am +/sql/mysqld.cc +/sql/mysql_priv.h +/sql/set_var.cc +/sql/sql_lex.h +/sql/sql_parse.cc +/sql/sql_yacc.yy +/sql/structs.h +/sql/sql_show.cc +' + +rm -f $OUT +if [ -e $OUT ]; then + exit 1 +fi + +for name in $FILES; do + diff -BNru "$ORIG$name" "$NEW$name" >> $OUT +done diff --git a/storage/sphinx/plug.in b/storage/sphinx/plug.in new file mode 100644 index 00000000000..2c07584465e --- /dev/null +++ b/storage/sphinx/plug.in @@ -0,0 +1,6 @@ +MYSQL_STORAGE_ENGINE(sphinx,,[Sphinx Storage Engine], + [SE client for Sphinx search daemon], []) +MYSQL_PLUGIN_DIRECTORY(sphinx, [storage/sphinx]) +MYSQL_PLUGIN_STATIC(sphinx, [libsphinx.la]) +MYSQL_PLUGIN_DYNAMIC(sphinx, [ha_sphinx.la]) + diff --git a/storage/sphinx/snippets_udf.cc b/storage/sphinx/snippets_udf.cc new file mode 100644 index 00000000000..961d1a92ed1 --- /dev/null +++ b/storage/sphinx/snippets_udf.cc @@ -0,0 +1,766 @@ +// +// $Id: snippets_udf.cc 2058 2009-11-07 04:01:57Z shodan $ +// + +// +// Copyright (c) 2001-2008, Andrew Aksyonoff. 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. You should have +// received a copy of the GPL license along with this program; if you +// did not, you can find it at http://www.gnu.org/ +// + +#include <mysql_version.h> + +#if MYSQL_VERSION_ID>50100 +#include "mysql_priv.h" +#include <mysql/plugin.h> +#else +#include "../mysql_priv.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include <sys/un.h> +#include <netdb.h> + +#include <mysys_err.h> +#include <my_sys.h> + +#if MYSQL_VERSION_ID>=50120 +typedef uchar byte; +#endif + +/// partially copy-pasted stuff that should be moved elsewhere + +#if UNALIGNED_RAM_ACCESS + +/// pass-through wrapper +template < typename T > inline T sphUnalignedRead ( const T & tRef ) +{ + return tRef; +} + +/// pass-through wrapper +template < typename T > void sphUnalignedWrite ( void * pPtr, const T & tVal ) +{ + *(T*)pPtr = tVal; +} + +#else + +/// unaligned read wrapper for some architectures (eg. SPARC) +template < typename T > +inline T sphUnalignedRead ( const T & tRef ) +{ + T uTmp; + byte * pSrc = (byte *) &tRef; + byte * pDst = (byte *) &uTmp; + for ( int i=0; i<(int)sizeof(T); i++ ) + *pDst++ = *pSrc++; + return uTmp; +} + +/// unaligned write wrapper for some architectures (eg. SPARC) +template < typename T > +void sphUnalignedWrite ( void * pPtr, const T & tVal ) +{ + byte * pDst = (byte *) pPtr; + byte * pSrc = (byte *) &tVal; + for ( int i=0; i<(int)sizeof(T); i++ ) + *pDst++ = *pSrc++; +} + +#endif + +#define SPHINXSE_MAX_ALLOC (16*1024*1024) + +#define SafeDelete(_arg) { if ( _arg ) delete ( _arg ); (_arg) = NULL; } +#define SafeDeleteArray(_arg) { if ( _arg ) delete [] ( _arg ); (_arg) = NULL; } + +#define Min(a,b) ((a)<(b)?(a):(b)) + +typedef unsigned int DWORD; + +inline DWORD sphF2DW ( float f ) { union { float f; uint32 d; } u; u.f = f; return u.d; } + +static char * sphDup ( const char * sSrc, int iLen=-1 ) +{ + if ( !sSrc ) + return NULL; + + if ( iLen<0 ) + iLen = strlen(sSrc); + + char * sRes = new char [ 1+iLen ]; + memcpy ( sRes, sSrc, iLen ); + sRes[iLen] = '\0'; + return sRes; +} + +static inline void sphShowErrno ( const char * sCall ) +{ + char sError[256]; + snprintf ( sError, sizeof(sError), "%s() failed: [%d] %s", sCall, errno, strerror(errno) ); + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), sError ); +} + +static const bool sphReportErrors = true; + +static bool sphSend ( int iFd, const char * pBuffer, int iSize, bool bReportErrors = false ) +{ + assert ( pBuffer ); + assert ( iSize > 0 ); + + const int iResult = send ( iFd, pBuffer, iSize, 0 ); + if ( iResult != iSize ) + { + if ( bReportErrors ) sphShowErrno("send"); + return false; + } + return true; +} + +static bool sphRecv ( int iFd, char * pBuffer, int iSize, bool bReportErrors = false ) +{ + assert ( pBuffer ); + assert ( iSize > 0 ); + + while ( iSize ) + { + const int iResult = recv ( iFd, pBuffer, iSize, 0 ); + if ( iResult > 0 ) + { + iSize -= iResult; + pBuffer += iSize; + } + else if ( iResult == 0 ) + { + if ( bReportErrors ) + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "recv() failed: disconnected" ); + return false; + } + else + { + if ( bReportErrors ) sphShowErrno("recv"); + return false; + } + } + return true; +} + +enum +{ + SPHINX_SEARCHD_PROTO = 1, + + SEARCHD_COMMAND_SEARCH = 0, + SEARCHD_COMMAND_EXCERPT = 1, + + VER_COMMAND_SEARCH = 0x116, + VER_COMMAND_EXCERPT = 0x100, +}; + +/// known answers +enum +{ + SEARCHD_OK = 0, ///< general success, command-specific reply follows + SEARCHD_ERROR = 1, ///< general failure, error message follows + SEARCHD_RETRY = 2, ///< temporary failure, error message follows, client should retry later + SEARCHD_WARNING = 3 ///< general success, warning message and command-specific reply follow +}; + +#define SPHINXSE_DEFAULT_SCHEME "sphinx" +#define SPHINXSE_DEFAULT_HOST "127.0.0.1" +#define SPHINXSE_DEFAULT_PORT 9312 +#define SPHINXSE_DEFAULT_INDEX "*" + +class CSphBuffer +{ +private: + bool m_bOverrun; + int m_iSize; + int m_iLeft; + char * m_pBuffer; + char * m_pCurrent; + +public: + CSphBuffer ( const int iSize ) + : m_bOverrun ( false ) + , m_iSize ( iSize ) + , m_iLeft ( iSize ) + { + assert ( iSize > 0 ); + m_pBuffer = new char[iSize]; + m_pCurrent = m_pBuffer; + } + + ~CSphBuffer () + { + SafeDelete ( m_pBuffer ); + } + + const char * Ptr() const { return m_pBuffer; } + + bool Finalize() + { + return !( m_bOverrun || m_iLeft != 0 || m_pCurrent - m_pBuffer != m_iSize ); + } + + void SendBytes ( const void * pBytes, int iBytes ); + + void SendWord ( short int v ) { v = ntohs(v); SendBytes ( &v, sizeof(v) ); } + void SendInt ( int v ) { v = ntohl(v); SendBytes ( &v, sizeof(v) ); } + void SendDword ( DWORD v ) { v = ntohl(v) ;SendBytes ( &v, sizeof(v) ); } + void SendUint64 ( ulonglong v ) { SendDword ( uint(v>>32) ); SendDword ( uint(v&0xFFFFFFFFUL) ); } + void SendString ( const char * v ) { SendString ( v, strlen(v) ); } + void SendString ( const char * v, int iLen ) { SendDword(iLen); SendBytes ( v, iLen ); } + void SendFloat ( float v ) { SendDword ( sphF2DW(v) ); } +}; + +void CSphBuffer::SendBytes ( const void * pBytes, int iBytes ) +{ + if ( m_iLeft < iBytes ) + { + m_bOverrun = true; + return; + } + + memcpy ( m_pCurrent, pBytes, iBytes ); + + m_pCurrent += iBytes; + m_iLeft -= iBytes; +} + +struct CSphUrl +{ + char * m_sBuffer; + char * m_sFormatted; + + char * m_sScheme; + char * m_sHost; + char * m_sIndex; + + int m_iPort; + + CSphUrl() + : m_sBuffer ( NULL ) + , m_sFormatted ( NULL ) + , m_sScheme ( (char*) SPHINXSE_DEFAULT_SCHEME ) + , m_sHost ( (char*) SPHINXSE_DEFAULT_HOST ) + , m_sIndex ( (char*) SPHINXSE_DEFAULT_INDEX ) + , m_iPort ( SPHINXSE_DEFAULT_PORT ) + {} + + ~CSphUrl() + { + SafeDeleteArray ( m_sFormatted ); + SafeDeleteArray ( m_sBuffer ); + } + + bool Parse ( const char * sUrl, int iLen ); + int Connect(); + const char * Format(); +}; + +const char * CSphUrl::Format() +{ + if ( !m_sFormatted ) + { + int iSize = 15 + strlen(m_sHost) + strlen(m_sIndex); + m_sFormatted = new char [ iSize ]; + if ( m_iPort ) + snprintf ( m_sFormatted, iSize, "inet://%s:%d/%s", m_sHost, m_iPort, m_sIndex ); + else + snprintf ( m_sFormatted, iSize, "unix://%s/%s", m_sHost, m_sIndex ); + } + return m_sFormatted; +} + +// the following scheme variants are recognized +// +// inet://host/index +// inet://host:port/index +// unix://unix/domain/socket:index +// unix://unix/domain/socket +bool CSphUrl::Parse ( const char * sUrl, int iLen ) +{ + bool bOk = true; + while ( iLen ) + { + bOk = false; + + m_sBuffer = sphDup ( sUrl, iLen ); + m_sScheme = m_sBuffer; + + m_sHost = strstr ( m_sBuffer, "://" ); + if ( !m_sHost ) + break; + m_sHost[0] = '\0'; + m_sHost += 2; + + if ( !strcmp ( m_sScheme, "unix" ) ) + { + // unix-domain socket + m_iPort = 0; + if (!( m_sIndex = strrchr ( m_sHost, ':' ) )) + m_sIndex = (char*) SPHINXSE_DEFAULT_INDEX; + else + { + *m_sIndex++ = '\0'; + if ( !*m_sIndex ) + m_sIndex = (char*) SPHINXSE_DEFAULT_INDEX; + } + bOk = true; + break; + } + if( strcmp ( m_sScheme, "sphinx" ) != 0 && strcmp ( m_sScheme, "inet" ) != 0 ) + break; + + // inet + m_sHost++; + char * sPort = strchr ( m_sHost, ':' ); + if ( sPort ) + { + *sPort++ = '\0'; + if ( *sPort ) + { + m_sIndex = strchr ( sPort, '/' ); + if ( m_sIndex ) + *m_sIndex++ = '\0'; + else + m_sIndex = (char*) SPHINXSE_DEFAULT_INDEX; + + m_iPort = atoi(sPort); + if ( !m_iPort ) + m_iPort = SPHINXSE_DEFAULT_PORT; + } + } else + { + m_sIndex = strchr ( m_sHost, '/' ); + if ( m_sIndex ) + *m_sIndex++ = '\0'; + else + m_sIndex = (char*) SPHINXSE_DEFAULT_INDEX; + } + + bOk = true; + break; + } + + return bOk; +} + +int CSphUrl::Connect() +{ + struct sockaddr_in sin; +#ifndef __WIN__ + struct sockaddr_un saun; +#endif + + int iDomain = 0; + int iSockaddrSize = 0; + struct sockaddr * pSockaddr = NULL; + + in_addr_t ip_addr; + + if ( m_iPort ) + { + iDomain = AF_INET; + iSockaddrSize = sizeof(sin); + pSockaddr = (struct sockaddr *) &sin; + + memset ( &sin, 0, sizeof(sin) ); + sin.sin_family = AF_INET; + sin.sin_port = htons(m_iPort); + + // resolve address + if ( (int)( ip_addr=inet_addr(m_sHost) ) != (int)INADDR_NONE ) + memcpy ( &sin.sin_addr, &ip_addr, sizeof(ip_addr) ); + else + { + int tmp_errno; + struct hostent tmp_hostent, *hp; + char buff2 [ GETHOSTBYNAME_BUFF_SIZE ]; + + hp = my_gethostbyname_r ( m_sHost, &tmp_hostent, + buff2, sizeof(buff2), &tmp_errno ); + if ( !hp ) + { + my_gethostbyname_r_free(); + + char sError[256]; + snprintf ( sError, sizeof(sError), "failed to resolve searchd host (name=%s)", m_sHost ); + + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError ); + return -1; + } + + memcpy ( &sin.sin_addr, hp->h_addr, Min ( sizeof(sin.sin_addr), (size_t)hp->h_length ) ); + my_gethostbyname_r_free(); + } + } + else + { +#ifndef __WIN__ + iDomain = AF_UNIX; + iSockaddrSize = sizeof(saun); + pSockaddr = (struct sockaddr *) &saun; + + memset ( &saun, 0, sizeof(saun) ); + saun.sun_family = AF_UNIX; + strncpy ( saun.sun_path, m_sHost, sizeof(saun.sun_path)-1 ); +#else + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "Unix-domain sockets are not supported on Windows" ); + return -1; +#endif + } + + // connect to searchd and exchange versions + uint uServerVersion; + uint uClientVersion = htonl ( SPHINX_SEARCHD_PROTO ); + int iSocket = -1; + const char * pError = NULL; + do + { + iSocket = socket ( iDomain, SOCK_STREAM, 0 ); + if ( iSocket == -1 ) + { + pError = "Failed to create client socket"; + break; + } + + if ( connect ( iSocket, pSockaddr, iSockaddrSize ) == -1) + { + pError = "Failed to connect to searchd"; + break; + } + + if ( !sphRecv ( iSocket, (char *)&uServerVersion, sizeof(uServerVersion) ) ) + { + pError = "Failed to receive searchd version"; + break; + } + + if ( !sphSend ( iSocket, (char *)&uClientVersion, sizeof(uClientVersion) ) ) + { + pError = "Failed to send client version"; + break; + } + } + while(0); + + // fixme: compare versions? + + if ( pError ) + { + char sError[1024]; + snprintf ( sError, sizeof(sError), "%s [%d] %s", Format(), errno, strerror(errno) ); + my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError ); + + if ( iSocket != -1 ) + close ( iSocket ); + + return -1; + } + + return iSocket; +} + +struct CSphResponse +{ + char * m_pBuffer; + char * m_pBody; + + CSphResponse () + : m_pBuffer ( NULL ) + , m_pBody ( NULL ) + {} + + CSphResponse ( DWORD uSize ) + : m_pBody ( NULL ) + { + m_pBuffer = new char[uSize]; + } + + ~CSphResponse () + { + SafeDeleteArray ( m_pBuffer ); + } + + static CSphResponse * Read ( int iSocket, int iClientVersion ); +}; + +CSphResponse * +CSphResponse::Read ( int iSocket, int iClientVersion ) +{ + char sHeader[8]; + if ( !sphRecv ( iSocket, sHeader, sizeof(sHeader) ) ) + return NULL; + + int iStatus = ntohs ( sphUnalignedRead ( *(short int *) &sHeader[0] ) ); + int iVersion = ntohs ( sphUnalignedRead ( *(short int *) &sHeader[2] ) ); + DWORD uLength = ntohl ( sphUnalignedRead ( *(DWORD *) &sHeader[4] ) ); + + if ( iVersion < iClientVersion ) // fixme: warn + {} + + if ( uLength <= SPHINXSE_MAX_ALLOC ) + { + CSphResponse * pResponse = new CSphResponse ( uLength ); + if ( !sphRecv ( iSocket, pResponse->m_pBuffer, uLength ) ) + { + SafeDelete ( pResponse ); + return NULL; + } + + pResponse->m_pBody = pResponse->m_pBuffer; + if ( iStatus != SEARCHD_OK ) + { + DWORD uSize = ntohl ( *(DWORD *)pResponse->m_pBuffer ); + if ( iStatus == SEARCHD_WARNING ) + pResponse->m_pBody += uSize; // fixme: report the warning somehow + else + { + char * sMessage = sphDup ( pResponse->m_pBuffer + sizeof(DWORD), uSize ); + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), sMessage ); + SafeDelete ( sMessage ); + SafeDelete ( pResponse ); + return NULL; + } + } + return pResponse; + } + return NULL; +} + +/// udf + +extern "C" +{ + my_bool sphinx_snippets_init ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sMessage ); + void sphinx_snippets_deinit ( UDF_INIT * pUDF ); + char * sphinx_snippets ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sResult, unsigned long * pLength, char * pIsNull, char * sError ); +}; + +#define MAX_MESSAGE_LENGTH 255 +#define MAX_RESULT_LENGTH 255 + +struct CSphSnippets +{ + CSphUrl m_tUrl; + CSphResponse * m_pResponse; + + int m_iBeforeMatch; + int m_iAfterMatch; + int m_iChunkSeparator; + int m_iLimit; + int m_iAround; + int m_iFlags; + + CSphSnippets() + : m_pResponse(NULL) + , m_iBeforeMatch(0) + , m_iAfterMatch(0) + , m_iChunkSeparator(0) + // defaults + , m_iLimit(256) + , m_iAround(5) + , m_iFlags(1) + { + } + + ~CSphSnippets() + { + SafeDelete ( m_pResponse ); + } +}; + +#define KEYWORD(NAME) else if ( strncmp ( NAME, pArgs->attributes[i], pArgs->attribute_lengths[i] ) == 0 ) + +#define CHECK_TYPE(TYPE) \ + if ( pArgs->arg_type[i] != TYPE ) \ + { \ + snprintf ( sMessage, MAX_MESSAGE_LENGTH, \ + "%.*s argument must be a string", \ + (int)pArgs->attribute_lengths[i], \ + pArgs->attributes[i] ); \ + bFail = true; \ + break; \ + } \ + if ( TYPE == STRING_RESULT && !pArgs->args[i] ) \ + { \ + snprintf ( sMessage, MAX_MESSAGE_LENGTH, \ + "%.*s argument must be constant (and not NULL)", \ + (int)pArgs->attribute_lengths[i], \ + pArgs->attributes[i] ); \ + bFail = true; \ + break; \ + } + +#define STRING CHECK_TYPE(STRING_RESULT) +#define INT CHECK_TYPE(INT_RESULT); int iValue = *(long long *)pArgs->args[i] + +my_bool sphinx_snippets_init ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sMessage ) +{ + if ( pArgs->arg_count < 3 ) + { + strncpy ( sMessage, "insufficient arguments", MAX_MESSAGE_LENGTH ); + return 1; + } + + bool bFail = false; + CSphSnippets * pOpts = new CSphSnippets; + for ( uint i = 0; i < pArgs->arg_count; i++ ) + { + if ( i < 3 ) + { + if ( pArgs->arg_type[i] != STRING_RESULT ) + { + strncpy ( sMessage, "first three arguments must be of string type", MAX_MESSAGE_LENGTH ); + bFail = true; + break; + } + } + KEYWORD("sphinx") + { + STRING; + if ( !pOpts->m_tUrl.Parse ( pArgs->args[i], pArgs->lengths[i] ) ) + { + strncpy ( sMessage, "failed to parse connection string", MAX_MESSAGE_LENGTH ); + bFail = true; + break; + } + } + KEYWORD("before_match") { STRING; pOpts->m_iBeforeMatch = i; } + KEYWORD("after_match") { STRING; pOpts->m_iAfterMatch = i; } + KEYWORD("chunk_separator") { STRING; pOpts->m_iChunkSeparator = i; } + KEYWORD("limit") { INT; pOpts->m_iLimit = iValue; } + KEYWORD("around") { INT; pOpts->m_iAround = iValue; } + KEYWORD("exact_phrase") { INT; if ( iValue ) pOpts->m_iFlags |= 2; } + KEYWORD("single_passage") { INT; if ( iValue ) pOpts->m_iFlags |= 4; } + KEYWORD("use_boundaries") { INT; if ( iValue ) pOpts->m_iFlags |= 8; } + KEYWORD("weight_order") { INT; if ( iValue ) pOpts->m_iFlags |= 16; } + else + { + snprintf ( sMessage, MAX_MESSAGE_LENGTH, "unrecognized argument: %.*s", + (int)pArgs->attribute_lengths[i], pArgs->attributes[i] ); + bFail = true; + break; + } + } + + if ( bFail ) + { + SafeDelete ( pOpts ); + return 1; + } + pUDF->ptr = (char *)pOpts; + return 0; +} + +#undef STRING +#undef INT +#undef KEYWORD +#undef CHECK_TYPE + +#define ARG(i) pArgs->args[i], pArgs->lengths[i] +#define ARG_LEN(VAR, LEN) ( VAR ? pArgs->lengths[VAR] : LEN ) + +#define SEND_STRING(INDEX, DEFAULT) \ + if ( INDEX ) \ + tBuffer.SendString ( ARG(INDEX) ); \ + else \ + tBuffer.SendString ( DEFAULT, sizeof(DEFAULT) - 1 ); + + +char * sphinx_snippets ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sResult, unsigned long * pLength, char * pIsNull, char * pError ) +{ + CSphSnippets * pOpts = (CSphSnippets *)pUDF->ptr; + assert ( pOpts ); + + if ( !pArgs->args[0] || !pArgs->args[1] || !pArgs->args[2] ) + { + *pIsNull = 1; + return sResult; + } + + const int iSize = + 8 + // header + 8 + + 4 + pArgs->lengths[1] + // index + 4 + pArgs->lengths[2] + // words + 4 + ARG_LEN ( pOpts->m_iBeforeMatch, 3 ) + + 4 + ARG_LEN ( pOpts->m_iAfterMatch, 4 ) + + 4 + ARG_LEN ( pOpts->m_iChunkSeparator, 5 ) + + 12 + + 4 + pArgs->lengths[0]; // document + + CSphBuffer tBuffer(iSize); + + tBuffer.SendWord ( SEARCHD_COMMAND_EXCERPT ); + tBuffer.SendWord ( VER_COMMAND_EXCERPT ); + tBuffer.SendDword ( iSize - 8 ); + + tBuffer.SendDword ( 0 ); + tBuffer.SendDword ( pOpts->m_iFlags ); + + tBuffer.SendString ( ARG(1) ); // index + tBuffer.SendString ( ARG(2) ); // words + + SEND_STRING ( pOpts->m_iBeforeMatch, "<b>" ); + SEND_STRING ( pOpts->m_iAfterMatch, "</b>" ); + SEND_STRING ( pOpts->m_iChunkSeparator, " ... " ); + + tBuffer.SendInt ( pOpts->m_iLimit ); + tBuffer.SendInt ( pOpts->m_iAround ); + + // single document + tBuffer.SendInt ( 1 ); + tBuffer.SendString ( ARG(0) ); + + int iSocket = -1; + do + { + if ( !tBuffer.Finalize() ) + { + my_error ( ER_QUERY_ON_FOREIGN_DATA_SOURCE, MYF(0), "INTERNAL ERROR: failed to build request" ); + break; + } + + iSocket = pOpts->m_tUrl.Connect(); + if ( iSocket == -1 ) break; + if ( !sphSend ( iSocket, tBuffer.Ptr(), iSize, sphReportErrors ) ) break; + + CSphResponse * pResponse = CSphResponse::Read ( iSocket, 0x100 ); + if ( !pResponse ) break; + + close ( iSocket ); + pOpts->m_pResponse = pResponse; + *pLength = ntohl( *(DWORD *)pResponse->m_pBody ); + return pResponse->m_pBody + sizeof(DWORD); + } + while(0); + + if ( iSocket != -1 ) + close ( iSocket ); + + *pError = 1; + return sResult; +} + +#undef SEND_STRING +#undef ARG_LEN +#undef ARG + +void sphinx_snippets_deinit ( UDF_INIT * pUDF ) +{ + CSphSnippets * pOpts = (CSphSnippets *)pUDF->ptr; + SafeDelete ( pOpts ); +} + +// +// $Id: snippets_udf.cc 2058 2009-11-07 04:01:57Z shodan $ +// diff --git a/storage/sphinx/sphinx.5.0.22.diff b/storage/sphinx/sphinx.5.0.22.diff new file mode 100644 index 00000000000..7dd4ebf1410 --- /dev/null +++ b/storage/sphinx/sphinx.5.0.22.diff @@ -0,0 +1,284 @@ +diff -B -N -r -u mysql-5.0.22/config/ac-macros/ha_sphinx.m4 mysql-5.0.22.sx/config/ac-macros/ha_sphinx.m4 +--- mysql-5.0.22/config/ac-macros/ha_sphinx.m4 1970-01-01 01:00:00.000000000 +0100 ++++ mysql-5.0.22.sx/config/ac-macros/ha_sphinx.m4 2006-06-06 19:49:38.000000000 +0200 +@@ -0,0 +1,30 @@ ++dnl --------------------------------------------------------------------------- ++dnl Macro: MYSQL_CHECK_EXAMPLEDB ++dnl Sets HAVE_SPHINX_DB if --with-sphinx-storage-engine is used ++dnl --------------------------------------------------------------------------- ++AC_DEFUN([MYSQL_CHECK_SPHINXDB], [ ++ AC_ARG_WITH([sphinx-storage-engine], ++ [ ++ --with-sphinx-storage-engine ++ Enable the Sphinx Storage Engine], ++ [sphinxdb="$withval"], ++ [sphinxdb=no]) ++ AC_MSG_CHECKING([for example storage engine]) ++ ++ case "$sphinxdb" in ++ yes ) ++ AC_DEFINE([HAVE_SPHINX_DB], [1], [Builds Sphinx Engine]) ++ AC_MSG_RESULT([yes]) ++ [sphinxdb=yes] ++ ;; ++ * ) ++ AC_MSG_RESULT([no]) ++ [sphinxdb=no] ++ ;; ++ esac ++ ++]) ++dnl --------------------------------------------------------------------------- ++dnl END OF MYSQL_CHECK_EXAMPLE SECTION ++dnl --------------------------------------------------------------------------- ++ +diff -B -N -r -u mysql-5.0.22/configure.in mysql-5.0.22.sx/configure.in +--- mysql-5.0.22/configure.in 2006-05-25 10:56:45.000000000 +0200 ++++ mysql-5.0.22.sx/configure.in 2006-06-06 19:49:38.000000000 +0200 +@@ -41,6 +41,7 @@ + sinclude(config/ac-macros/ha_berkeley.m4) + sinclude(config/ac-macros/ha_blackhole.m4) + sinclude(config/ac-macros/ha_example.m4) ++sinclude(config/ac-macros/ha_sphinx.m4) + sinclude(config/ac-macros/ha_federated.m4) + sinclude(config/ac-macros/ha_innodb.m4) + sinclude(config/ac-macros/ha_ndbcluster.m4) +@@ -2450,6 +2451,7 @@ + MYSQL_CHECK_BDB + MYSQL_CHECK_INNODB + MYSQL_CHECK_EXAMPLEDB ++MYSQL_CHECK_SPHINXDB + MYSQL_CHECK_ARCHIVEDB + MYSQL_CHECK_CSVDB + MYSQL_CHECK_BLACKHOLEDB +diff -B -N -r -u mysql-5.0.22/libmysqld/Makefile.am mysql-5.0.22.sx/libmysqld/Makefile.am +--- mysql-5.0.22/libmysqld/Makefile.am 2006-05-25 10:56:55.000000000 +0200 ++++ mysql-5.0.22.sx/libmysqld/Makefile.am 2006-06-06 19:49:38.000000000 +0200 +@@ -27,7 +27,7 @@ + -DSHAREDIR="\"$(MYSQLSHAREdir)\"" + INCLUDES= @bdb_includes@ \ + -I$(top_builddir)/include -I$(top_srcdir)/include \ +- -I$(top_srcdir)/sql -I$(top_srcdir)/sql/examples \ ++ -I$(top_srcdir)/sql -I$(top_srcdir)/sql/examples -I$(top_srcdir)/sql/sphinx \ + -I$(top_srcdir)/regex \ + $(openssl_includes) $(yassl_includes) @ZLIB_INCLUDES@ + +@@ -38,6 +38,7 @@ + libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \ + my_time.c + sqlexamplessources = ha_example.cc ha_tina.cc ++sqlsphinxsources = ha_sphinx.cc + + noinst_HEADERS = embedded_priv.h emb_qcache.h + +@@ -65,7 +66,7 @@ + parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ + ha_blackhole.cc ha_archive.cc my_user.c + +-libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) ++libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) $(sqlsphinxsources) + libmysqld_a_SOURCES= + + # automake misses these +@@ -133,12 +134,16 @@ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/sql/examples/$$f $$f; \ + done; \ ++ for f in $(sqlsphinxsources); do \ ++ rm -f $$f; \ ++ @LN_CP_F@ $(top_srcdir)/sql/sphinx/$$f $$f; \ ++ done; \ + rm -f client_settings.h; \ + @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h client_settings.h + + + clean-local: +- rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlexamplessources) | sed "s;\.lo;.c;g"` \ ++ rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlexamplessources) $(sqlsphinxsources) | sed "s;\.lo;.c;g"` \ + $(top_srcdir)/linked_libmysqld_sources; \ + rm -f client_settings.h + +diff -B -N -r -u mysql-5.0.22/sql/handler.cc mysql-5.0.22.sx/sql/handler.cc +--- mysql-5.0.22/sql/handler.cc 2006-05-25 10:56:42.000000000 +0200 ++++ mysql-5.0.22.sx/sql/handler.cc 2006-06-06 19:49:38.000000000 +0200 +@@ -78,6 +78,15 @@ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + HTON_NO_FLAGS }; + #endif ++#ifdef HAVE_SPHINX_DB ++#include "sphinx/ha_sphinx.h" ++extern handlerton sphinx_hton; ++#else ++handlerton sphinx_hton = { "SPHINX", SHOW_OPTION_NO, "SPHINX storage engine", ++ DB_TYPE_SPHINX_DB, NULL, 0, 0, NULL, NULL, ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ++ HTON_NO_FLAGS }; ++#endif + #ifdef HAVE_INNOBASE_DB + #include "ha_innodb.h" + extern handlerton innobase_hton; +@@ -147,6 +156,7 @@ + &example_hton, + &archive_hton, + &tina_hton, ++ &sphinx_hton, + &ndbcluster_hton, + &federated_hton, + &myisammrg_hton, +@@ -345,6 +355,12 @@ + return new (alloc) ha_tina(table); + return NULL; + #endif ++#ifdef HAVE_SPHINX_DB ++ case DB_TYPE_SPHINX_DB: ++ if (have_sphinx_db == SHOW_OPTION_YES) ++ return new (alloc) ha_sphinx(table); ++ return NULL; ++#endif + #ifdef HAVE_NDBCLUSTER_DB + case DB_TYPE_NDBCLUSTER: + if (have_ndbcluster == SHOW_OPTION_YES) +diff -B -N -r -u mysql-5.0.22/sql/handler.h mysql-5.0.22.sx/sql/handler.h +--- mysql-5.0.22/sql/handler.h 2006-05-25 10:56:55.000000000 +0200 ++++ mysql-5.0.22.sx/sql/handler.h 2006-06-06 19:49:38.000000000 +0200 +@@ -183,8 +183,9 @@ + DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, + DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER, + DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB, +- DB_TYPE_FEDERATED_DB, ++ DB_TYPE_FEDERATED_DB, + DB_TYPE_BLACKHOLE_DB, ++ DB_TYPE_SPHINX_DB, + DB_TYPE_DEFAULT // Must be last + }; + +diff -B -N -r -u mysql-5.0.22/sql/Makefile.am mysql-5.0.22.sx/sql/Makefile.am +--- mysql-5.0.22/sql/Makefile.am 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/Makefile.am 2006-06-06 19:49:38.000000000 +0200 +@@ -66,6 +66,7 @@ + sql_array.h sql_cursor.h \ + examples/ha_example.h ha_archive.h \ + examples/ha_tina.h ha_blackhole.h \ ++ sphinx/ha_sphinx.h \ + ha_federated.h + mysqld_SOURCES = sql_lex.cc sql_handler.cc \ + item.cc item_sum.cc item_buff.cc item_func.cc \ +@@ -102,6 +103,7 @@ + sp_cache.cc parse_file.cc sql_trigger.cc \ + examples/ha_example.cc ha_archive.cc \ + examples/ha_tina.cc ha_blackhole.cc \ ++ sphinx/ha_sphinx.cc \ + ha_federated.cc + + gen_lex_hash_SOURCES = gen_lex_hash.cc +diff -B -N -r -u mysql-5.0.22/sql/mysqld.cc mysql-5.0.22.sx/sql/mysqld.cc +--- mysql-5.0.22/sql/mysqld.cc 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/mysqld.cc 2006-06-06 19:49:38.000000000 +0200 +@@ -6420,6 +6420,11 @@ + #else + have_csv_db= SHOW_OPTION_NO; + #endif ++#ifdef HAVE_SPHINX_DB ++ have_sphinx_db= SHOW_OPTION_YES; ++#else ++ have_sphinx_db= SHOW_OPTION_NO; ++#endif + #ifdef HAVE_NDBCLUSTER_DB + have_ndbcluster=SHOW_OPTION_DISABLED; + #else +@@ -7457,6 +7462,7 @@ + #undef have_example_db + #undef have_archive_db + #undef have_csv_db ++#undef have_sphinx_db + #undef have_federated_db + #undef have_partition_db + #undef have_blackhole_db +@@ -7467,6 +7473,7 @@ + SHOW_COMP_OPTION have_example_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_archive_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_csv_db= SHOW_OPTION_NO; ++SHOW_COMP_OPTION have_sphinx_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_federated_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_partition_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_blackhole_db= SHOW_OPTION_NO; +diff -B -N -r -u mysql-5.0.22/sql/mysql_priv.h mysql-5.0.22.sx/sql/mysql_priv.h +--- mysql-5.0.22/sql/mysql_priv.h 2006-05-25 10:56:43.000000000 +0200 ++++ mysql-5.0.22.sx/sql/mysql_priv.h 2006-06-06 19:49:38.000000000 +0200 +@@ -1279,6 +1279,12 @@ + #else + extern SHOW_COMP_OPTION have_csv_db; + #endif ++#ifdef HAVE_SPHINX_DB ++extern handlerton sphinx_hton; ++#define have_sphinx_db sphinx_hton.state ++#else ++extern SHOW_COMP_OPTION have_sphinx_db; ++#endif + #ifdef HAVE_FEDERATED_DB + extern handlerton federated_hton; + #define have_federated_db federated_hton.state +diff -B -N -r -u mysql-5.0.22/sql/set_var.cc mysql-5.0.22.sx/sql/set_var.cc +--- mysql-5.0.22/sql/set_var.cc 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/set_var.cc 2006-06-06 19:49:38.000000000 +0200 +@@ -809,6 +809,7 @@ + {"have_compress", (char*) &have_compress, SHOW_HAVE}, + {"have_crypt", (char*) &have_crypt, SHOW_HAVE}, + {"have_csv", (char*) &have_csv_db, SHOW_HAVE}, ++ {"have_sphinx", (char*) &have_sphinx_db, SHOW_HAVE}, + {"have_example_engine", (char*) &have_example_db, SHOW_HAVE}, + {"have_federated_engine", (char*) &have_federated_db, SHOW_HAVE}, + {"have_geometry", (char*) &have_geometry, SHOW_HAVE}, +diff -B -N -r -u mysql-5.0.22/sql/sql_lex.h mysql-5.0.22.sx/sql/sql_lex.h +--- mysql-5.0.22/sql/sql_lex.h 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/sql_lex.h 2006-06-06 19:49:38.000000000 +0200 +@@ -58,6 +58,7 @@ + SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS, + SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS, + SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_NDBCLUSTER_STATUS, SQLCOM_SHOW_MUTEX_STATUS, ++ SQLCOM_SHOW_SPHINX_STATUS, + SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, + SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, + SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS, +diff -B -N -r -u mysql-5.0.22/sql/sql_parse.cc mysql-5.0.22.sx/sql/sql_parse.cc +--- mysql-5.0.22/sql/sql_parse.cc 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/sql_parse.cc 2006-06-06 19:49:38.000000000 +0200 +@@ -25,6 +25,9 @@ + #ifdef HAVE_INNOBASE_DB + #include "ha_innodb.h" + #endif ++#ifdef HAVE_SPHINX_DB ++#include "sphinx/ha_sphinx.h" ++#endif + + #ifdef HAVE_NDBCLUSTER_DB + #include "ha_ndbcluster.h" +@@ -2722,6 +2725,15 @@ + break; + } + #endif ++#ifdef HAVE_SPHINX_DB ++ case SQLCOM_SHOW_SPHINX_STATUS: ++ { ++ if (check_global_access(thd, SUPER_ACL)) ++ goto error; ++ res = sphinx_show_status(thd); ++ break; ++ } ++#endif + #ifdef HAVE_REPLICATION + case SQLCOM_LOAD_MASTER_TABLE: + { +diff -B -N -r -u mysql-5.0.22/sql/sql_yacc.yy mysql-5.0.22.sx/sql/sql_yacc.yy +--- mysql-5.0.22/sql/sql_yacc.yy 2006-05-25 10:56:43.000000000 +0200 ++++ mysql-5.0.22.sx/sql/sql_yacc.yy 2006-06-06 19:49:38.000000000 +0200 +@@ -6584,6 +6584,9 @@ + case DB_TYPE_INNODB: + Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS; + break; ++ case DB_TYPE_SPHINX_DB: ++ Lex->sql_command = SQLCOM_SHOW_SPHINX_STATUS; ++ break; + default: + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "STATUS"); + YYABORT; diff --git a/storage/sphinx/sphinx.5.0.27.diff b/storage/sphinx/sphinx.5.0.27.diff new file mode 100644 index 00000000000..9ff6cf4fe48 --- /dev/null +++ b/storage/sphinx/sphinx.5.0.27.diff @@ -0,0 +1,284 @@ +diff -B -N -r -u mysql-5.0.22/config/ac-macros/ha_sphinx.m4 mysql-5.0.22.sx/config/ac-macros/ha_sphinx.m4 +--- mysql-5.0.22/config/ac-macros/ha_sphinx.m4 1970-01-01 01:00:00.000000000 +0100 ++++ mysql-5.0.22.sx/config/ac-macros/ha_sphinx.m4 2006-06-06 19:49:38.000000000 +0200 +@@ -0,0 +1,30 @@ ++dnl --------------------------------------------------------------------------- ++dnl Macro: MYSQL_CHECK_EXAMPLEDB ++dnl Sets HAVE_SPHINX_DB if --with-sphinx-storage-engine is used ++dnl --------------------------------------------------------------------------- ++AC_DEFUN([MYSQL_CHECK_SPHINXDB], [ ++ AC_ARG_WITH([sphinx-storage-engine], ++ [ ++ --with-sphinx-storage-engine ++ Enable the Sphinx Storage Engine], ++ [sphinxdb="$withval"], ++ [sphinxdb=no]) ++ AC_MSG_CHECKING([for example storage engine]) ++ ++ case "$sphinxdb" in ++ yes ) ++ AC_DEFINE([HAVE_SPHINX_DB], [1], [Builds Sphinx Engine]) ++ AC_MSG_RESULT([yes]) ++ [sphinxdb=yes] ++ ;; ++ * ) ++ AC_MSG_RESULT([no]) ++ [sphinxdb=no] ++ ;; ++ esac ++ ++]) ++dnl --------------------------------------------------------------------------- ++dnl END OF MYSQL_CHECK_EXAMPLE SECTION ++dnl --------------------------------------------------------------------------- ++ +diff -B -N -r -u mysql-5.0.22/configure.in mysql-5.0.22.sx/configure.in +--- mysql-5.0.22/configure.in 2006-05-25 10:56:45.000000000 +0200 ++++ mysql-5.0.22.sx/configure.in 2006-06-06 19:49:38.000000000 +0200 +@@ -41,6 +41,7 @@ + sinclude(config/ac-macros/ha_berkeley.m4) + sinclude(config/ac-macros/ha_blackhole.m4) + sinclude(config/ac-macros/ha_example.m4) ++sinclude(config/ac-macros/ha_sphinx.m4) + sinclude(config/ac-macros/ha_federated.m4) + sinclude(config/ac-macros/ha_innodb.m4) + sinclude(config/ac-macros/ha_ndbcluster.m4) +@@ -2450,6 +2451,7 @@ + MYSQL_CHECK_BDB + MYSQL_CHECK_INNODB + MYSQL_CHECK_EXAMPLEDB ++MYSQL_CHECK_SPHINXDB + MYSQL_CHECK_ARCHIVEDB + MYSQL_CHECK_CSVDB + MYSQL_CHECK_BLACKHOLEDB +diff -B -N -r -u mysql-5.0.22/libmysqld/Makefile.am mysql-5.0.22.sx/libmysqld/Makefile.am +--- mysql-5.0.22/libmysqld/Makefile.am 2006-05-25 10:56:55.000000000 +0200 ++++ mysql-5.0.22.sx/libmysqld/Makefile.am 2006-06-06 19:49:38.000000000 +0200 +@@ -27,7 +27,7 @@ + -DSHAREDIR="\"$(MYSQLSHAREdir)\"" + INCLUDES= @bdb_includes@ \ + -I$(top_builddir)/include -I$(top_srcdir)/include \ +- -I$(top_srcdir)/sql -I$(top_srcdir)/sql/examples \ ++ -I$(top_srcdir)/sql -I$(top_srcdir)/sql/examples -I$(top_srcdir)/sql/sphinx \ + -I$(top_srcdir)/regex \ + $(openssl_includes) $(yassl_includes) @ZLIB_INCLUDES@ + +@@ -38,6 +38,7 @@ + libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \ + my_time.c + sqlexamplessources = ha_example.cc ha_tina.cc ++sqlsphinxsources = ha_sphinx.cc + + noinst_HEADERS = embedded_priv.h emb_qcache.h + +@@ -65,7 +66,7 @@ + parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ + ha_blackhole.cc ha_archive.cc my_user.c + +-libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) ++libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) $(sqlsphinxsources) + libmysqld_a_SOURCES= + + # automake misses these +@@ -133,12 +134,16 @@ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/sql/examples/$$f $$f; \ + done; \ ++ for f in $(sqlsphinxsources); do \ ++ rm -f $$f; \ ++ @LN_CP_F@ $(top_srcdir)/sql/sphinx/$$f $$f; \ ++ done; \ + rm -f client_settings.h; \ + @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h client_settings.h + + + clean-local: +- rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlexamplessources) | sed "s;\.lo;.c;g"` \ ++ rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlexamplessources) $(sqlsphinxsources) | sed "s;\.lo;.c;g"` \ + $(top_srcdir)/linked_libmysqld_sources; \ + rm -f client_settings.h + +diff -B -N -r -u mysql-5.0.22/sql/handler.cc mysql-5.0.22.sx/sql/handler.cc +--- mysql-5.0.22/sql/handler.cc 2006-05-25 10:56:42.000000000 +0200 ++++ mysql-5.0.22.sx/sql/handler.cc 2006-06-06 19:49:38.000000000 +0200 +@@ -78,6 +78,15 @@ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + HTON_NO_FLAGS }; + #endif ++#ifdef HAVE_SPHINX_DB ++#include "sphinx/ha_sphinx.h" ++extern handlerton sphinx_hton; ++#else ++handlerton sphinx_hton = { "SPHINX", SHOW_OPTION_NO, "SPHINX storage engine", ++ DB_TYPE_SPHINX_DB, NULL, 0, 0, NULL, NULL, ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ++ HTON_NO_FLAGS }; ++#endif + #ifdef HAVE_INNOBASE_DB + #include "ha_innodb.h" + extern handlerton innobase_hton; +@@ -147,6 +156,7 @@ + &example_hton, + &archive_hton, + &tina_hton, ++ &sphinx_hton, + &ndbcluster_hton, + &federated_hton, + &myisammrg_hton, +@@ -345,6 +355,12 @@ + return new (alloc) ha_tina(table); + return NULL; + #endif ++#ifdef HAVE_SPHINX_DB ++ case DB_TYPE_SPHINX_DB: ++ if (have_sphinx_db == SHOW_OPTION_YES) ++ return new (alloc) ha_sphinx(table); ++ return NULL; ++#endif + #ifdef HAVE_NDBCLUSTER_DB + case DB_TYPE_NDBCLUSTER: + if (have_ndbcluster == SHOW_OPTION_YES) +diff -B -N -r -u mysql-5.0.22/sql/handler.h mysql-5.0.22.sx/sql/handler.h +--- mysql-5.0.22/sql/handler.h 2006-05-25 10:56:55.000000000 +0200 ++++ mysql-5.0.22.sx/sql/handler.h 2006-06-06 19:49:38.000000000 +0200 +@@ -183,8 +183,9 @@ + DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, + DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER, + DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB, +- DB_TYPE_FEDERATED_DB, ++ DB_TYPE_FEDERATED_DB, + DB_TYPE_BLACKHOLE_DB, ++ DB_TYPE_SPHINX_DB, + DB_TYPE_DEFAULT // Must be last + }; + +diff -B -N -r -u mysql-5.0.22/sql/Makefile.am mysql-5.0.22.sx/sql/Makefile.am +--- mysql-5.0.22/sql/Makefile.am 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/Makefile.am 2006-06-06 19:49:38.000000000 +0200 +@@ -66,6 +66,7 @@ + sql_array.h sql_cursor.h \ + examples/ha_example.h ha_archive.h \ + examples/ha_tina.h ha_blackhole.h \ ++ sphinx/ha_sphinx.h \ + ha_federated.h + mysqld_SOURCES = sql_lex.cc sql_handler.cc \ + item.cc item_sum.cc item_buff.cc item_func.cc \ +@@ -102,6 +103,7 @@ + sp_cache.cc parse_file.cc sql_trigger.cc \ + examples/ha_example.cc ha_archive.cc \ + examples/ha_tina.cc ha_blackhole.cc \ ++ sphinx/ha_sphinx.cc \ + ha_federated.cc + + gen_lex_hash_SOURCES = gen_lex_hash.cc +diff -B -N -r -u mysql-5.0.22/sql/mysqld.cc mysql-5.0.22.sx/sql/mysqld.cc +--- mysql-5.0.22/sql/mysqld.cc 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/mysqld.cc 2006-06-06 19:49:38.000000000 +0200 +@@ -6420,6 +6420,11 @@ + #else + have_csv_db= SHOW_OPTION_NO; + #endif ++#ifdef HAVE_SPHINX_DB ++ have_sphinx_db= SHOW_OPTION_YES; ++#else ++ have_sphinx_db= SHOW_OPTION_NO; ++#endif + #ifdef HAVE_NDBCLUSTER_DB + have_ndbcluster=SHOW_OPTION_DISABLED; + #else +@@ -7457,6 +7462,7 @@ + #undef have_example_db + #undef have_archive_db + #undef have_csv_db ++#undef have_sphinx_db + #undef have_federated_db + #undef have_partition_db + #undef have_blackhole_db +@@ -7467,6 +7473,7 @@ + SHOW_COMP_OPTION have_example_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_archive_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_csv_db= SHOW_OPTION_NO; ++SHOW_COMP_OPTION have_sphinx_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_federated_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_partition_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_blackhole_db= SHOW_OPTION_NO; +diff -B -N -r -u mysql-5.0.22/sql/mysql_priv.h mysql-5.0.22.sx/sql/mysql_priv.h +--- mysql-5.0.22/sql/mysql_priv.h 2006-05-25 10:56:43.000000000 +0200 ++++ mysql-5.0.22.sx/sql/mysql_priv.h 2006-06-06 19:49:38.000000000 +0200 +@@ -1279,6 +1279,12 @@ + #else + extern SHOW_COMP_OPTION have_csv_db; + #endif ++#ifdef HAVE_SPHINX_DB ++extern handlerton sphinx_hton; ++#define have_sphinx_db sphinx_hton.state ++#else ++extern SHOW_COMP_OPTION have_sphinx_db; ++#endif + #ifdef HAVE_FEDERATED_DB + extern handlerton federated_hton; + #define have_federated_db federated_hton.state +diff -B -N -r -u mysql-5.0.22/sql/set_var.cc mysql-5.0.22.sx/sql/set_var.cc +--- mysql-5.0.22/sql/set_var.cc 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/set_var.cc 2006-06-06 19:49:38.000000000 +0200 +@@ -864,6 +864,7 @@ + {"have_compress", (char*) &have_compress, SHOW_HAVE}, + {"have_crypt", (char*) &have_crypt, SHOW_HAVE}, + {"have_csv", (char*) &have_csv_db, SHOW_HAVE}, ++ {"have_sphinx", (char*) &have_sphinx_db, SHOW_HAVE}, + {"have_dynamic_loading", (char*) &have_dlopen, SHOW_HAVE}, + {"have_example_engine", (char*) &have_example_db, SHOW_HAVE}, + {"have_federated_engine", (char*) &have_federated_db, SHOW_HAVE}, +diff -B -N -r -u mysql-5.0.22/sql/sql_lex.h mysql-5.0.22.sx/sql/sql_lex.h +--- mysql-5.0.22/sql/sql_lex.h 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/sql_lex.h 2006-06-06 19:49:38.000000000 +0200 +@@ -58,6 +58,7 @@ + SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS, + SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS, + SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_NDBCLUSTER_STATUS, SQLCOM_SHOW_MUTEX_STATUS, ++ SQLCOM_SHOW_SPHINX_STATUS, + SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, + SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, + SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS, +diff -B -N -r -u mysql-5.0.22/sql/sql_parse.cc mysql-5.0.22.sx/sql/sql_parse.cc +--- mysql-5.0.22/sql/sql_parse.cc 2006-05-25 10:56:41.000000000 +0200 ++++ mysql-5.0.22.sx/sql/sql_parse.cc 2006-06-06 19:49:38.000000000 +0200 +@@ -25,6 +25,9 @@ + #ifdef HAVE_INNOBASE_DB + #include "ha_innodb.h" + #endif ++#ifdef HAVE_SPHINX_DB ++#include "sphinx/ha_sphinx.h" ++#endif + + #ifdef HAVE_NDBCLUSTER_DB + #include "ha_ndbcluster.h" +@@ -2722,6 +2725,15 @@ + break; + } + #endif ++#ifdef HAVE_SPHINX_DB ++ case SQLCOM_SHOW_SPHINX_STATUS: ++ { ++ if (check_global_access(thd, SUPER_ACL)) ++ goto error; ++ res = sphinx_show_status(thd); ++ break; ++ } ++#endif + #ifdef HAVE_REPLICATION + case SQLCOM_LOAD_MASTER_TABLE: + { +diff -B -N -r -u mysql-5.0.22/sql/sql_yacc.yy mysql-5.0.22.sx/sql/sql_yacc.yy +--- mysql-5.0.22/sql/sql_yacc.yy 2006-05-25 10:56:43.000000000 +0200 ++++ mysql-5.0.22.sx/sql/sql_yacc.yy 2006-06-06 19:49:38.000000000 +0200 +@@ -6584,6 +6584,9 @@ + case DB_TYPE_INNODB: + Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS; + break; ++ case DB_TYPE_SPHINX_DB: ++ Lex->sql_command = SQLCOM_SHOW_SPHINX_STATUS; ++ break; + default: + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "STATUS"); + YYABORT; diff --git a/storage/sphinx/sphinx.5.0.37.diff b/storage/sphinx/sphinx.5.0.37.diff new file mode 100644 index 00000000000..3f86e545b4d --- /dev/null +++ b/storage/sphinx/sphinx.5.0.37.diff @@ -0,0 +1,338 @@ +--- mysql-5.0.67/config/ac-macros/ha_sphinx.m4 1970-01-01 10:00:00.000000000 +1000 ++++ mysql-5.0.67-sphinx/config/ac-macros/ha_sphinx.m4 2009-02-14 09:15:48.000000000 +1000 +@@ -0,0 +1,30 @@ ++dnl --------------------------------------------------------------------------- ++dnl Macro: MYSQL_CHECK_EXAMPLEDB ++dnl Sets HAVE_SPHINX_DB if --with-sphinx-storage-engine is used ++dnl --------------------------------------------------------------------------- ++AC_DEFUN([MYSQL_CHECK_SPHINXDB], [ ++ AC_ARG_WITH([sphinx-storage-engine], ++ [ ++ --with-sphinx-storage-engine ++ Enable the Sphinx Storage Engine], ++ [sphinxdb="$withval"], ++ [sphinxdb=no]) ++ AC_MSG_CHECKING([for example storage engine]) ++ ++ case "$sphinxdb" in ++ yes ) ++ AC_DEFINE([HAVE_SPHINX_DB], [1], [Builds Sphinx Engine]) ++ AC_MSG_RESULT([yes]) ++ [sphinxdb=yes] ++ ;; ++ * ) ++ AC_MSG_RESULT([no]) ++ [sphinxdb=no] ++ ;; ++ esac ++ ++]) ++dnl --------------------------------------------------------------------------- ++dnl END OF MYSQL_CHECK_EXAMPLE SECTION ++dnl --------------------------------------------------------------------------- ++ +--- mysql-5.0.67/configure.in 2008-08-04 23:19:07.000000000 +1100 ++++ mysql-5.0.67-sphinx/configure.in 2009-02-14 09:15:48.000000000 +1000 +@@ -58,6 +58,7 @@ + sinclude(config/ac-macros/ha_berkeley.m4) + sinclude(config/ac-macros/ha_blackhole.m4) + sinclude(config/ac-macros/ha_example.m4) ++sinclude(config/ac-macros/ha_sphinx.m4) + sinclude(config/ac-macros/ha_federated.m4) + sinclude(config/ac-macros/ha_innodb.m4) + sinclude(config/ac-macros/ha_ndbcluster.m4) +@@ -2625,6 +2626,7 @@ + MYSQL_CHECK_BDB + MYSQL_CHECK_INNODB + MYSQL_CHECK_EXAMPLEDB ++MYSQL_CHECK_SPHINXDB + MYSQL_CHECK_ARCHIVEDB + MYSQL_CHECK_CSVDB + MYSQL_CHECK_BLACKHOLEDB +--- mysql-5.0.67/libmysqld/Makefile.am 2008-08-04 23:19:18.000000000 +1100 ++++ mysql-5.0.67-sphinx/libmysqld/Makefile.am 2009-02-14 09:15:48.000000000 +1000 +@@ -29,6 +29,7 @@ + -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_builddir)/sql -I$(top_srcdir)/sql \ + -I$(top_srcdir)/sql/examples \ ++ -I$(top_srcdir)/sql/sphinx \ + -I$(top_srcdir)/regex \ + $(openssl_includes) @ZLIB_INCLUDES@ + +@@ -39,6 +40,7 @@ + libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \ + my_time.c + sqlexamplessources = ha_example.cc ha_tina.cc ++sqlsphinxsources = ha_sphinx.cc + + noinst_HEADERS = embedded_priv.h emb_qcache.h + +@@ -67,7 +69,7 @@ + parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ + ha_blackhole.cc ha_archive.cc my_user.c + +-libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) ++libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) $(sqlsphinxsources) + libmysqld_a_SOURCES= + + # automake misses these +@@ -147,12 +149,16 @@ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/sql/examples/$$f $$f; \ + done; \ ++ for f in $(sqlsphinxsources); do \ ++ rm -f $$f; \ ++ @LN_CP_F@ $(top_srcdir)/sql/sphinx/$$f $$f; \ ++ done; \ + rm -f client_settings.h; \ + @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h client_settings.h + + + clean-local: +- rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlexamplessources) | sed "s;\.lo;.c;g"` \ ++ rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlexamplessources) $(sqlsphinxsources) | sed "s;\.lo;.c;g"` \ + $(top_srcdir)/linked_libmysqld_sources; \ + rm -f client_settings.h + +--- mysql-5.0.67/sql/handler.cc 2008-08-04 23:20:04.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/handler.cc 2009-02-14 09:15:48.000000000 +1000 +@@ -77,6 +77,15 @@ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + HTON_NO_FLAGS }; + #endif ++#ifdef HAVE_SPHINX_DB ++#include "sphinx/ha_sphinx.h" ++extern handlerton sphinx_hton; ++#else ++handlerton sphinx_hton = { "SPHINX", SHOW_OPTION_NO, "SPHINX storage engine", ++ DB_TYPE_SPHINX_DB, NULL, 0, 0, NULL, NULL, ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ++ HTON_NO_FLAGS }; ++#endif + #ifdef HAVE_INNOBASE_DB + #include "ha_innodb.h" + extern handlerton innobase_hton; +@@ -141,6 +150,7 @@ + &example_hton, + &archive_hton, + &tina_hton, ++ &sphinx_hton, + &ndbcluster_hton, + &federated_hton, + &myisammrg_hton, +@@ -341,6 +351,12 @@ + return new (alloc) ha_tina(table); + return NULL; + #endif ++#ifdef HAVE_SPHINX_DB ++ case DB_TYPE_SPHINX_DB: ++ if (have_sphinx_db == SHOW_OPTION_YES) ++ return new (alloc) ha_sphinx(table); ++ return NULL; ++#endif + #ifdef HAVE_NDBCLUSTER_DB + case DB_TYPE_NDBCLUSTER: + if (have_ndbcluster == SHOW_OPTION_YES) +--- mysql-5.0.67/sql/handler.h 2008-08-04 23:20:04.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/handler.h 2009-02-14 09:15:48.000000000 +1000 +@@ -186,8 +186,9 @@ + DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, + DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER, + DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB, +- DB_TYPE_FEDERATED_DB, ++ DB_TYPE_FEDERATED_DB, + DB_TYPE_BLACKHOLE_DB, ++ DB_TYPE_SPHINX_DB, + DB_TYPE_DEFAULT // Must be last + }; + +--- mysql-5.0.67/sql/Makefile.am 2008-08-04 23:20:02.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/Makefile.am 2009-02-14 09:23:28.000000000 +1000 +@@ -68,6 +68,7 @@ + sql_array.h sql_cursor.h \ + examples/ha_example.h ha_archive.h \ + examples/ha_tina.h ha_blackhole.h \ ++ sphinx/ha_sphinx.h \ + ha_federated.h + mysqld_SOURCES = sql_lex.cc sql_handler.cc \ + item.cc item_sum.cc item_buff.cc item_func.cc \ +@@ -105,6 +106,7 @@ + sp_cache.cc parse_file.cc sql_trigger.cc \ + examples/ha_example.cc ha_archive.cc \ + examples/ha_tina.cc ha_blackhole.cc \ ++ sphinx/ha_sphinx.cc \ + ha_federated.cc + + gen_lex_hash_SOURCES = gen_lex_hash.cc +@@ -174,6 +176,10 @@ + udf_example_la_SOURCES= udf_example.c + udf_example_la_LDFLAGS= -module -rpath $(pkglibdir) + ++pkglib_LTLIBRARIES = sphinx/sphinx.la ++sphinx_sphinx_la_SOURCES = sphinx/snippets_udf.cc ++sphinx_sphinx_la_LDFLAGS = -module ++ + + # Don't update the files from bitkeeper + %::SCCS/s.% +--- mysql-5.0.67/sql/mysqld.cc 2008-08-04 23:20:07.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/mysqld.cc 2009-02-14 09:15:48.000000000 +1000 +@@ -36,6 +36,10 @@ + #include <sys/prctl.h> + #endif + ++#ifdef HAVE_SPHINX_DB ++#include "sphinx/ha_sphinx.h" ++#endif ++ + #ifdef HAVE_INNOBASE_DB + #define OPT_INNODB_DEFAULT 1 + #else +@@ -6633,6 +6637,13 @@ + {"Threads_running", (char*) &thread_running, SHOW_INT_CONST}, + {"Uptime", (char*) 0, SHOW_STARTTIME}, + {"Uptime_since_flush_status",(char*) 0, SHOW_FLUSHTIME}, ++#ifdef HAVE_SPHINX_DB ++ {"sphinx_total", (char *)sphinx_showfunc_total, SHOW_SPHINX_FUNC}, ++ {"sphinx_total_found", (char *)sphinx_showfunc_total_found, SHOW_SPHINX_FUNC}, ++ {"sphinx_time", (char *)sphinx_showfunc_time, SHOW_SPHINX_FUNC}, ++ {"sphinx_word_count", (char *)sphinx_showfunc_word_count, SHOW_SPHINX_FUNC}, ++ {"sphinx_words", (char *)sphinx_showfunc_words, SHOW_SPHINX_FUNC}, ++#endif + {NullS, NullS, SHOW_LONG} + }; + +@@ -6875,6 +6886,11 @@ + #else + have_csv_db= SHOW_OPTION_NO; + #endif ++#ifdef HAVE_SPHINX_DB ++ have_sphinx_db= SHOW_OPTION_YES; ++#else ++ have_sphinx_db= SHOW_OPTION_NO; ++#endif + #ifdef HAVE_NDBCLUSTER_DB + have_ndbcluster=SHOW_OPTION_DISABLED; + #else +@@ -7983,6 +7999,7 @@ + #undef have_example_db + #undef have_archive_db + #undef have_csv_db ++#undef have_sphinx_db + #undef have_federated_db + #undef have_partition_db + #undef have_blackhole_db +@@ -7993,6 +8010,7 @@ + SHOW_COMP_OPTION have_example_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_archive_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_csv_db= SHOW_OPTION_NO; ++SHOW_COMP_OPTION have_sphinx_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_federated_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_partition_db= SHOW_OPTION_NO; + SHOW_COMP_OPTION have_blackhole_db= SHOW_OPTION_NO; +--- mysql-5.0.67/sql/mysql_priv.h 2008-08-04 23:20:07.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/mysql_priv.h 2009-02-14 09:15:48.000000000 +1000 +@@ -1439,6 +1439,12 @@ + #else + extern SHOW_COMP_OPTION have_csv_db; + #endif ++#ifdef HAVE_SPHINX_DB ++extern handlerton sphinx_hton; ++#define have_sphinx_db sphinx_hton.state ++#else ++extern SHOW_COMP_OPTION have_sphinx_db; ++#endif + #ifdef HAVE_FEDERATED_DB + extern handlerton federated_hton; + #define have_federated_db federated_hton.state +--- mysql-5.0.67/sql/set_var.cc 2008-08-04 23:20:08.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/set_var.cc 2009-02-14 09:15:48.000000000 +1000 +@@ -888,6 +888,7 @@ + {"have_compress", (char*) &have_compress, SHOW_HAVE}, + {"have_crypt", (char*) &have_crypt, SHOW_HAVE}, + {"have_csv", (char*) &have_csv_db, SHOW_HAVE}, ++ {"have_sphinx", (char*) &have_sphinx_db, SHOW_HAVE}, + {"have_dynamic_loading", (char*) &have_dlopen, SHOW_HAVE}, + {"have_example_engine", (char*) &have_example_db, SHOW_HAVE}, + {"have_federated_engine", (char*) &have_federated_db, SHOW_HAVE}, +--- mysql-5.0.67/sql/sql_lex.h 2008-08-04 23:20:10.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/sql_lex.h 2009-02-14 09:15:48.000000000 +1000 +@@ -57,6 +57,7 @@ + SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS, + SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS, + SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_NDBCLUSTER_STATUS, SQLCOM_SHOW_MUTEX_STATUS, ++ SQLCOM_SHOW_SPHINX_STATUS, + SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, + SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, + SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS, +--- mysql-5.0.67/sql/sql_parse.cc 2008-08-04 23:20:10.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/sql_parse.cc 2009-02-14 09:15:48.000000000 +1000 +@@ -24,6 +24,9 @@ + #ifdef HAVE_INNOBASE_DB + #include "ha_innodb.h" + #endif ++#ifdef HAVE_SPHINX_DB ++#include "sphinx/ha_sphinx.h" ++#endif + + #ifdef HAVE_NDBCLUSTER_DB + #include "ha_ndbcluster.h" +@@ -3006,6 +3009,15 @@ + break; + } + #endif ++#ifdef HAVE_SPHINX_DB ++ case SQLCOM_SHOW_SPHINX_STATUS: ++ { ++ if (check_global_access(thd, SUPER_ACL)) ++ goto error; ++ res = sphinx_show_status(thd); ++ break; ++ } ++#endif + #ifdef HAVE_REPLICATION + case SQLCOM_LOAD_MASTER_TABLE: + { +--- mysql-5.0.67/sql/sql_yacc.yy 2008-08-04 23:20:12.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/sql_yacc.yy 2009-02-14 09:15:48.000000000 +1000 +@@ -7393,6 +7393,9 @@ + case DB_TYPE_INNODB: + Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS; + break; ++ case DB_TYPE_SPHINX_DB: ++ Lex->sql_command = SQLCOM_SHOW_SPHINX_STATUS; ++ break; + default: + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "STATUS"); + MYSQL_YYABORT; +--- mysql-5.0.67/sql/structs.h 2008-08-04 23:20:12.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/structs.h 2009-02-14 09:15:48.000000000 +1000 +@@ -188,6 +188,9 @@ + SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL, + SHOW_SSL_GET_CIPHER_LIST, + #endif /* HAVE_OPENSSL */ ++#ifdef HAVE_SPHINX_DB ++ SHOW_SPHINX_FUNC, ++#endif + SHOW_NET_COMPRESSION, + SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING, SHOW_SLAVE_RETRIED_TRANS, + SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_CONST_LONG, SHOW_KEY_CACHE_LONGLONG, +--- mysql-5.0.67/sql/sql_show.cc 2008-08-04 23:20:11.000000000 +1100 ++++ mysql-5.0.67-sphinx/sql/sql_show.cc 2009-02-14 09:15:48.000000000 +1000 +@@ -1473,6 +1473,16 @@ + value= (char*) ((sys_var*) value)->value_ptr(thd, value_type, + &null_lex_str); + } ++ #ifdef HAVE_SPHINX_DB ++ else if (show_type == SHOW_SPHINX_FUNC) ++ { ++ SHOW_VAR var; ++ ((int (*)(THD *, SHOW_VAR *, char *))value)(thd, &var, buff); ++ ++ value = var.value; ++ show_type = var.type; ++ } ++ #endif /* HAVE_SPHINX_DB */ + + pos= end= buff; + switch (show_type) { diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt index 608d6865bf4..50f2dba5cf9 100644 --- a/storage/xtradb/CMakeLists.txt +++ b/storage/xtradb/CMakeLists.txt @@ -42,10 +42,11 @@ IF(MSVC) SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c PROPERTIES COMPILE_FLAGS -Od) ENDIF() - # Avoid "unreferenced label" warning in generated file - SET_SOURCE_FILES_PROPERTIES(pars/pars0grm.c + # Avoid "unreferenced label" warning in generated file + GET_FILENAME_COMPONENT(_SRC_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) + SET_SOURCE_FILES_PROPERTIES(${_SRC_DIR}/pars/pars0grm.c PROPERTIES COMPILE_FLAGS "/wd4102") - SET_SOURCE_FILES_PROPERTIES(pars/lexyy.c + SET_SOURCE_FILES_PROPERTIES(${_SRC_DIR}/pars/lexyy.c PROPERTIES COMPILE_FLAGS "/wd4003") ENDIF() diff --git a/storage/xtradb/Makefile.am b/storage/xtradb/Makefile.am index 4adcc5c45ff..02eeaa1e456 100644 --- a/storage/xtradb/Makefile.am +++ b/storage/xtradb/Makefile.am @@ -331,7 +331,7 @@ libxtradb_la_CFLAGS= $(AM_CFLAGS) EXTRA_LTLIBRARIES= libxtradb.la ha_xtradb.la pkgplugin_LTLIBRARIES= @plugin_xtradb_shared_target@ -ha_xtradb_la_LDFLAGS= -module -rpath $(pkgplugindir) +ha_xtradb_la_LDFLAGS= -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices ha_xtradb_la_CXXFLAGS= -shared $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS) ha_xtradb_la_CFLAGS= -shared $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) ha_xtradb_la_SOURCES= $(libxtradb_la_SOURCES) diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index b07f6f0b93d..66243ad2e34 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1505,7 +1505,7 @@ UNIV_INTERN ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), int_table_flags(HA_REC_NOT_IN_SEQ | - HA_NULL_IN_KEY | + HA_NULL_IN_KEY | HA_CAN_VIRTUAL_COLUMNS | HA_CAN_INDEX_BLOBS | HA_CAN_SQL_HANDLER | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | @@ -2586,11 +2586,11 @@ innobase_change_buffering_inited_ok: my_b_seek(&info_file, 0L); pos=strmov(buff, trx_sys_mysql_relay_log_name); *pos++='\n'; - pos=longlong2str(trx_sys_mysql_relay_log_pos, pos, 10); + pos=longlong10_to_str(trx_sys_mysql_relay_log_pos, pos, 10); *pos++='\n'; pos=strmov(pos, trx_sys_mysql_master_log_name); *pos++='\n'; - pos=longlong2str(trx_sys_mysql_master_log_pos, pos, 10); + pos=longlong10_to_str(trx_sys_mysql_master_log_pos, pos, 10); *pos='\n'; if (my_b_write(&info_file, (uchar*) buff, (size_t) (pos-buff)+1)) @@ -3064,7 +3064,7 @@ innobase_rollback_to_savepoint( /* TODO: use provided savepoint data area to store savepoint data */ - longlong2str((ulint)savepoint, name, 36); + longlong2str((ulint)savepoint, name, 36, 1); error = (int) trx_rollback_to_savepoint_for_mysql(trx, name, &mysql_binlog_cache_pos); @@ -3095,7 +3095,7 @@ innobase_release_savepoint( /* TODO: use provided savepoint data area to store savepoint data */ - longlong2str((ulint)savepoint, name, 36); + longlong2str((ulint)savepoint, name, 36, 1); error = (int) trx_release_savepoint_for_mysql(trx, name); @@ -3142,7 +3142,7 @@ innobase_savepoint( /* TODO: use provided savepoint data area to store savepoint data */ char name[64]; - longlong2str((ulint)savepoint,name,36); + longlong2str((ulint)savepoint,name,36,1); error = (int) trx_savepoint_for_mysql(trx, name, (ib_int64_t)0); @@ -3834,12 +3834,12 @@ ha_innobase::open( } /* Create buffers for packing the fields of a record. Why - table->reclength did not work here? Obviously, because char + table->stored_rec_length did not work here? Obviously, because char fields when packed actually became 1 byte longer, when we also stored the string length as the first byte. */ upd_and_key_val_buff_len = - table->s->reclength + table->s->max_key_length + table->s->stored_rec_length + table->s->max_key_length + MAX_REF_PARTS * 3; if (!(uchar*) my_multi_malloc(MYF(MY_WME), &upd_buff, upd_and_key_val_buff_len, @@ -3927,7 +3927,7 @@ retry: prebuilt = row_create_prebuilt(ib_table); - prebuilt->mysql_row_len = table->s->reclength; + prebuilt->mysql_row_len = table->s->stored_rec_length;; prebuilt->default_rec = table->s->default_values; ut_ad(prebuilt->default_rec); @@ -4686,11 +4686,11 @@ build_template( dict_index_t* clust_index; mysql_row_templ_t* templ; Field* field; - ulint n_fields; + ulint n_fields, n_stored_fields; ulint n_requested_fields = 0; ibool fetch_all_in_key = FALSE; ibool fetch_primary_key_cols = FALSE; - ulint i; + ulint sql_idx, innodb_idx=0; /* byte offset of the end of last requested column */ ulint mysql_prefix_len = 0; @@ -4751,10 +4751,11 @@ build_template( } n_fields = (ulint)table->s->fields; /* number of columns */ + n_stored_fields= (ulint)table->s->stored_fields; /* number of stored columns */ if (!prebuilt->mysql_template) { prebuilt->mysql_template = (mysql_row_templ_t*) - mem_alloc(n_fields * sizeof(mysql_row_templ_t)); + mem_alloc(n_stored_fields * sizeof(mysql_row_templ_t)); } prebuilt->template_type = templ_type; @@ -4764,15 +4765,17 @@ build_template( /* Note that in InnoDB, i is the column number. MySQL calls columns 'fields'. */ - for (i = 0; i < n_fields; i++) { + for (sql_idx = 0; sql_idx < n_fields; sql_idx++) { templ = prebuilt->mysql_template + n_requested_fields; - field = table->field[i]; + field = table->field[sql_idx]; + if (!field->stored_in_db) + goto skip_field; if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) { /* Decide which columns we should fetch and which we can skip. */ register const ibool index_contains_field = - dict_index_contains_col_or_prefix(index, i); + dict_index_contains_col_or_prefix(index, innodb_idx); if (!index_contains_field && prebuilt->read_just_key) { /* If this is a 'key read', we do not need @@ -4787,8 +4790,8 @@ build_template( goto include_field; } - if (bitmap_is_set(table->read_set, i) || - bitmap_is_set(table->write_set, i)) { + if (bitmap_is_set(table->read_set, sql_idx) || + bitmap_is_set(table->write_set, sql_idx)) { /* This field is needed in the query */ goto include_field; @@ -4796,7 +4799,7 @@ build_template( if (fetch_primary_key_cols && dict_table_col_in_clustered_key( - index->table, i)) { + index->table, innodb_idx)) { /* This field is needed in the query */ goto include_field; @@ -4809,16 +4812,16 @@ build_template( include_field: n_requested_fields++; - templ->col_no = i; + templ->col_no = innodb_idx; templ->clust_rec_field_no = dict_col_get_clust_pos( - &index->table->cols[i], clust_index); + &index->table->cols[innodb_idx], clust_index); ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED); if (index == clust_index) { templ->rec_field_no = templ->clust_rec_field_no; } else { templ->rec_field_no = dict_index_get_nth_col_pos( - index, i); + index, innodb_idx); if (templ->rec_field_no == ULINT_UNDEFINED) { prebuilt->need_to_access_clustered = TRUE; } @@ -4843,7 +4846,7 @@ include_field: mysql_prefix_len = templ->mysql_col_offset + templ->mysql_col_len; } - templ->type = index->table->cols[i].mtype; + templ->type = index->table->cols[innodb_idx].mtype; templ->mysql_type = (ulint)field->type(); if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) { @@ -4852,16 +4855,18 @@ include_field: } templ->charset = dtype_get_charset_coll( - index->table->cols[i].prtype); - templ->mbminlen = index->table->cols[i].mbminlen; - templ->mbmaxlen = index->table->cols[i].mbmaxlen; - templ->is_unsigned = index->table->cols[i].prtype + index->table->cols[innodb_idx].prtype); + templ->mbminlen = index->table->cols[innodb_idx].mbminlen; + templ->mbmaxlen = index->table->cols[innodb_idx].mbmaxlen; + templ->is_unsigned = index->table->cols[innodb_idx].prtype & DATA_UNSIGNED; if (templ->type == DATA_BLOB) { prebuilt->templ_contains_blob = TRUE; } skip_field: - ; + if (field->stored_in_db) { + innodb_idx++; + } } prebuilt->n_template = n_requested_fields; @@ -4870,7 +4875,7 @@ skip_field: if (index != clust_index && prebuilt->need_to_access_clustered) { /* Change rec_field_no's to correspond to the clustered index record */ - for (i = 0; i < n_requested_fields; i++) { + for (ulint i = 0; i < n_requested_fields; i++) { templ = prebuilt->mysql_template + i; templ->rec_field_no = templ->clust_rec_field_no; @@ -5282,7 +5287,7 @@ calc_row_difference( ulint n_changed = 0; dfield_t dfield; dict_index_t* clust_index; - uint i; + uint sql_idx, innodb_idx= 0; n_fields = table->s->fields; clust_index = dict_table_get_first_index(prebuilt->table); @@ -5290,8 +5295,10 @@ calc_row_difference( /* We use upd_buff to convert changed fields */ buf = (byte*) upd_buff; - for (i = 0; i < n_fields; i++) { - field = table->field[i]; + for (sql_idx = 0; sql_idx < n_fields; sql_idx++) { + field = table->field[sql_idx]; + if (!field->stored_in_db) + continue; o_ptr = (const byte*) old_row + get_field_offset(table, field); n_ptr = (const byte*) new_row + get_field_offset(table, field); @@ -5309,7 +5316,7 @@ calc_row_difference( field_mysql_type = field->type(); - col_type = prebuilt->table->cols[i].mtype; + col_type = prebuilt->table->cols[innodb_idx].mtype; switch (col_type) { @@ -5364,7 +5371,7 @@ calc_row_difference( /* Let us use a dummy dfield to make the conversion from the MySQL column format to the InnoDB format */ - dict_col_copy_type(prebuilt->table->cols + i, + dict_col_copy_type(prebuilt->table->cols + innodb_idx, dfield_get_type(&dfield)); if (n_len != UNIV_SQL_NULL) { @@ -5383,9 +5390,11 @@ calc_row_difference( ufield->exp = NULL; ufield->orig_len = 0; ufield->field_no = dict_col_get_clust_pos( - &prebuilt->table->cols[i], clust_index); + &prebuilt->table->cols[innodb_idx], clust_index); n_changed++; } + if (field->stored_in_db) + innodb_idx++; } uvect->n_fields = n_changed; @@ -6465,7 +6474,7 @@ create_table_def( /* We pass 0 as the space id, and determine at a lower level the space id where to store the table */ - table = dict_mem_table_create(table_name, 0, n_cols, flags); + table = dict_mem_table_create(table_name, 0, form->s->stored_fields, flags); if (path_of_temp_table) { table->dir_path_of_temp_table = @@ -6474,6 +6483,8 @@ create_table_def( for (i = 0; i < n_cols; i++) { field = form->field[i]; + if (!field->stored_in_db) + continue; col_type = get_innobase_type_from_mysql_type(&unsigned_type, field); @@ -6979,7 +6990,7 @@ ha_innobase::create( } #endif - if (form->s->fields > 1000) { + if (form->s->stored_fields > 1000) { /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020, but we play safe here */ @@ -7702,10 +7713,10 @@ ha_innobase::records_in_range( KEY* key; dict_index_t* index; uchar* key_val_buff2 = (uchar*) my_malloc( - table->s->reclength + table->s->stored_rec_length + table->s->max_key_length + 100, MYF(MY_FAE)); - ulint buff2_len = table->s->reclength + ulint buff2_len = table->s->stored_rec_length + table->s->max_key_length + 100; dtuple_t* range_start; dtuple_t* range_end; @@ -12028,6 +12039,42 @@ i_s_innodb_sys_indexes, i_s_innodb_sys_stats, i_s_innodb_patches mysql_declare_plugin_end; +maria_declare_plugin(xtradb) +{ /* InnoDB */ + MYSQL_STORAGE_ENGINE_PLUGIN, + &innobase_storage_engine, + innobase_hton_name, + "Percona", + "XtraDB engine based on InnoDB plugin. Supports transactions, row-level locking, and foreign keys", + PLUGIN_LICENSE_GPL, + innobase_init, /* Plugin Init */ + NULL, /* Plugin Deinit */ + INNODB_VERSION_SHORT, + innodb_status_variables_export,/* status variables */ + innobase_system_variables, /* system variables */ + INNODB_VERSION_STR, /* string version */ + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +}, +i_s_innodb_rseg_maria, +i_s_innodb_buffer_pool_pages_maria, +i_s_innodb_buffer_pool_pages_index_maria, +i_s_innodb_buffer_pool_pages_blob_maria, +i_s_innodb_trx_maria, +i_s_innodb_locks_maria, +i_s_innodb_lock_waits_maria, +i_s_innodb_cmp_maria, +i_s_innodb_cmp_reset_maria, +i_s_innodb_cmpmem_maria, +i_s_innodb_cmpmem_reset_maria, +i_s_innodb_table_stats_maria, +i_s_innodb_index_stats_maria, +i_s_innodb_admin_command_maria, +i_s_innodb_sys_tables_maria, +i_s_innodb_sys_indexes_maria, +i_s_innodb_sys_stats_maria, +i_s_innodb_patches_maria +maria_declare_plugin_end; + /** @brief Initialize the default value of innodb_commit_concurrency. diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index fc7cd1c9b8f..d8be00afa6f 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -385,6 +385,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_patches = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_patches_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "XTRADB_ENHANCEMENTS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "Enhancements applied to InnoDB plugin"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_patches_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_fields_info[] = { @@ -986,6 +1039,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB buffer pool pages"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, 0x0100 /* 1.0 */), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index = { /* the plugin type (a MYSQL_XXX_PLUGIN value) */ @@ -1035,6 +1141,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB buffer pool index pages"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, 0x0100 /* 1.0 */), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob = { /* the plugin type (a MYSQL_XXX_PLUGIN value) */ @@ -1084,6 +1243,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB buffer pool blob pages"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, 0x0100 /* 1.0 */), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */ static ST_FIELD_INFO innodb_trx_fields_info[] = @@ -1327,6 +1539,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_trx = STRUCT_FLD(__reserved1, NULL) }; + +UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_TRX"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB transactions"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_trx_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */ static ST_FIELD_INFO innodb_locks_fields_info[] = { @@ -1593,6 +1859,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_locks = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_LOCKS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB conflicting locks"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_locks_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */ static ST_FIELD_INFO innodb_lock_waits_fields_info[] = { @@ -1776,6 +2095,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_LOCK_WAITS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Innobase Oy"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB which lock is blocking which"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_lock_waits_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + /*******************************************************************//** Common function to fill any of the dynamic tables: INFORMATION_SCHEMA.innodb_trx @@ -2109,6 +2481,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_CMP"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "Statistics for the InnoDB compression"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_cmp_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset = { /* the plugin type (a MYSQL_XXX_PLUGIN value) */ @@ -2159,6 +2584,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_CMP_RESET"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "Statistics for the InnoDB compression;" + " reset cumulated counts"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_cmp_reset_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; /* Fields of the dynamic table information_schema.innodb_cmpmem. */ static ST_FIELD_INFO i_s_cmpmem_fields_info[] = { @@ -2377,6 +2855,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_CMPMEM"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_cmpmem_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset = { /* the plugin type (a MYSQL_XXX_PLUGIN value) */ @@ -2427,6 +2958,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_CMPMEM_RESET"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;" + " reset cumulated counts"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_cmpmem_reset_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + /*******************************************************************//** Unbind a dynamic INFORMATION_SCHEMA table. @return 0 on success */ @@ -2606,6 +3191,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_rseg = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_rseg_maria = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_RSEG"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB rollback segment information"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_innodb_rseg_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, 0x0100 /* 1.0 */), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* string version */ + /* const char * */ + STRUCT_FLD(version_info, "1.0"), + + /* Maturity */ + /* int */ + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + /*********************************************************************** */ static ST_FIELD_INFO i_s_innodb_admin_command_info[] = @@ -2772,6 +3410,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_admin_command = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_admin_command_maria = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "XtraDB specific command acceptor"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_admin_command_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + STRUCT_FLD(version_info, "1.0"), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + /*********************************************************************** */ static ST_FIELD_INFO i_s_innodb_table_stats_info[] = @@ -3100,6 +3755,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_table_stats = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_table_stats_maria = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "INNODB_TABLE_STATS"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "InnoDB table statistics in memory"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_table_stats_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + STRUCT_FLD(version_info, "1.0"), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats = { STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), @@ -3116,6 +3788,24 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_index_stats_maria = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "INNODB_INDEX_STATS"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "InnoDB index statistics in memory"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_index_stats_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + STRUCT_FLD(version_info, "1.0"), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) +}; + + static ST_FIELD_INFO i_s_innodb_sys_tables_info[] = { {STRUCT_FLD(field_name, "SCHEMA"), @@ -3752,6 +4442,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tables = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tables_maria = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "INNODB_SYS_TABLES"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "InnoDB SYS_TABLES table"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_sys_tables_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + STRUCT_FLD(version_info, "1.0"), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA) +}; + UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_indexes = { STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), @@ -3768,6 +4475,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_indexes = STRUCT_FLD(__reserved1, NULL) }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_indexes_maria = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "INNODB_SYS_INDEXES"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "InnoDB SYS_INDEXES table"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_sys_indexes_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + STRUCT_FLD(version_info, "1.0"), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA) +}; + UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_stats = { STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), @@ -3783,3 +4507,21 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_stats = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(__reserved1, NULL) }; + +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_stats_maria = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "INNODB_SYS_STATS"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "InnoDB SYS_STATS table"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_sys_stats_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + STRUCT_FLD(version_info, "1.0"), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA) +}; + diff --git a/storage/xtradb/handler/i_s.h b/storage/xtradb/handler/i_s.h index 3905fdc7b06..7a5c3ead5ed 100644 --- a/storage/xtradb/handler/i_s.h +++ b/storage/xtradb/handler/i_s.h @@ -45,4 +45,23 @@ extern struct st_mysql_plugin i_s_innodb_sys_tables; extern struct st_mysql_plugin i_s_innodb_sys_indexes; extern struct st_mysql_plugin i_s_innodb_sys_stats; +extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria; +extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria; +extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria; +extern struct st_maria_plugin i_s_innodb_trx_maria; +extern struct st_maria_plugin i_s_innodb_locks_maria; +extern struct st_maria_plugin i_s_innodb_lock_waits_maria; +extern struct st_maria_plugin i_s_innodb_cmp_maria; +extern struct st_maria_plugin i_s_innodb_cmp_reset_maria; +extern struct st_maria_plugin i_s_innodb_cmpmem_maria; +extern struct st_maria_plugin i_s_innodb_cmpmem_reset_maria; +extern struct st_maria_plugin i_s_innodb_patches_maria; +extern struct st_maria_plugin i_s_innodb_rseg_maria; +extern struct st_maria_plugin i_s_innodb_table_stats_maria; +extern struct st_maria_plugin i_s_innodb_index_stats_maria; +extern struct st_maria_plugin i_s_innodb_admin_command_maria; +extern struct st_maria_plugin i_s_innodb_sys_tables_maria; +extern struct st_maria_plugin i_s_innodb_sys_indexes_maria; +extern struct st_maria_plugin i_s_innodb_sys_stats_maria; + #endif /* i_s_h */ diff --git a/storage/xtradb/trx/trx0sys.c b/storage/xtradb/trx/trx0sys.c index 6a15d4261eb..b5bec64ee37 100644 --- a/storage/xtradb/trx/trx0sys.c +++ b/storage/xtradb/trx/trx0sys.c @@ -1668,7 +1668,7 @@ trx_sys_print_mysql_binlog_offset_from_page( /* THESE ARE COPIED FROM NON-HOTBACKUP PART OF THE INNODB SOURCE TREE - (This code duplicaton should be fixed at some point!) + (This code duplication should be fixed at some point!) */ #define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */ diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt index 683c8583869..29e986543fb 100755 --- a/strings/CMakeLists.txt +++ b/strings/CMakeLists.txt @@ -28,6 +28,4 @@ SET(STRINGS_SOURCES bchange.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ctype- IF(NOT SOURCE_SUBLIBS) ADD_LIBRARY(strings ${STRINGS_SOURCES}) - - INSTALL(TARGETS strings DESTINATION lib/opt COMPONENT runtime) # TODO: Component ENDIF(NOT SOURCE_SUBLIBS) diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c index fb634f5b07e..772ad74c664 100644 --- a/strings/conf_to_src.c +++ b/strings/conf_to_src.c @@ -25,15 +25,15 @@ #define ROW16_LEN 8 #define MAX_BUF 64*1024 -static CHARSET_INFO all_charsets[256]; +static struct charset_info_st all_charsets[256]; void -print_array(FILE *f, const char *set, const char *name, uchar *a, int n) +print_array(FILE *f, const char *set, const char *name, const uchar *a, int n) { int i; - fprintf(f,"uchar %s_%s[] = {\n", name, set); + fprintf(f,"static const uchar %s_%s[] = {\n", name, set); for (i=0 ;i<n ; i++) { @@ -46,11 +46,11 @@ print_array(FILE *f, const char *set, const char *name, uchar *a, int n) void -print_array16(FILE *f, const char *set, const char *name, uint16 *a, int n) +print_array16(FILE *f, const char *set, const char *name, const uint16 *a, int n) { int i; - fprintf(f,"uint16 %s_%s[] = {\n", name, set); + fprintf(f,"static const uint16 %s_%s[] = {\n", name, set); for (i=0 ;i<n ; i++) { @@ -82,7 +82,7 @@ char *mdup(const char *src, uint len) return dst; } -static void simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from) +static void simple_cs_copy_data(struct charset_info_st *to, CHARSET_INFO *from) { to->number= from->number ? from->number : to->number; to->state|= from->state; @@ -124,7 +124,7 @@ static my_bool simple_cs_is_full(CHARSET_INFO *cs) (cs->sort_order || (cs->state & MY_CS_BINSORT)))); } -static int add_collation(CHARSET_INFO *cs) +static int add_collation(struct charset_info_st *cs) { if (cs->name && (cs->number || (cs->number=get_charset_number(cs->name)))) { @@ -275,7 +275,7 @@ fprint_copyright(FILE *file) int main(int argc, char **argv __attribute__((unused))) { - CHARSET_INFO ncs; + struct charset_info_st ncs; CHARSET_INFO *cs; char filename[256]; FILE *f= stdout; @@ -333,7 +333,7 @@ main(int argc, char **argv __attribute__((unused))) } } - fprintf(f,"CHARSET_INFO compiled_charsets[] = {\n"); + fprintf(f,"struct charset_info_st compiled_charsets[] = {\n"); for (cs=all_charsets; cs < all_charsets+256; cs++) { if (simple_cs_is_full(cs)) diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index cbd29aac56d..4ae1fe2524a 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -48,7 +48,7 @@ #define big5head(e) ((uchar)(e>>8)) #define big5tail(e) ((uchar)(e&0xff)) -static uchar NEAR ctype_big5[257] = +static const uchar NEAR ctype_big5[257] = { 0, /* For standard library */ 32,32,32,32,32,32,32,32,32,40,40,40,40,40,32,32, @@ -69,7 +69,7 @@ static uchar NEAR ctype_big5[257] = 3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0, }; -static uchar NEAR to_lower_big5[]= +static const uchar NEAR to_lower_big5[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -105,7 +105,7 @@ static uchar NEAR to_lower_big5[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uchar NEAR to_upper_big5[]= +static const uchar NEAR to_upper_big5[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -141,7 +141,7 @@ static uchar NEAR to_upper_big5[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uchar NEAR sort_order_big5[]= +static const uchar NEAR sort_order_big5[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -392,7 +392,7 @@ static uint mbcharlen_big5(CHARSET_INFO *cs __attribute__((unused)), uint c) /* page 0 0xA140-0xC7FC */ -static uint16 tab_big5_uni0[]={ +static const uint16 tab_big5_uni0[]={ 0x3000,0xFF0C,0x3001,0x3002,0xFF0E,0x2022,0xFF1B,0xFF1A, 0xFF1F,0xFF01,0xFE30,0x2026,0x2025,0xFE50,0xFF64,0xFE52, 0x00B7,0xFE54,0xFE55,0xFE56,0xFE57,0xFF5C,0x2013,0xFE31, @@ -1635,7 +1635,7 @@ static uint16 tab_big5_uni0[]={ 0x2479,0x247A,0x247B,0x247C,0x247D}; /* page 1 0xC940-0xF9DC */ -static uint16 tab_big5_uni1[]={ +static const uint16 tab_big5_uni1[]={ 0x4E42,0x4E5C,0x51F5,0x531A,0x5382,0x4E07,0x4E0C,0x4E47, 0x4E8D,0x56D7,0xFA0C,0x5C6E,0x5F73,0x4E0F,0x5187,0x4E0E, 0x4E2E,0x4E93,0x4EC2,0x4EC9,0x4EC8,0x5198,0x52FC,0x536C, @@ -3203,7 +3203,7 @@ static int func_big5_uni_onechar(int code){ /* page 0 0x00A2-0x00F7 */ -static uint16 tab_uni_big50[]={ +static const uint16 tab_uni_big50[]={ 0xA246,0xA247, 0,0xA244, 0,0xA1B1, 0, 0, 0, 0, 0, 0, 0, 0,0xA258,0xA1D3, 0, 0, 0, 0, 0,0xA150, 0, 0, @@ -3217,7 +3217,7 @@ static uint16 tab_uni_big50[]={ 0, 0, 0, 0, 0,0xA1D2}; /* page 1 0x02C7-0x0451 */ -static uint16 tab_uni_big51[]={ +static const uint16 tab_uni_big51[]={ 0xA3BE, 0,0xA3BC,0xA3BD,0xA3BF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA3BB, 0, 0, 0, 0, 0, @@ -3270,7 +3270,7 @@ static uint16 tab_uni_big51[]={ 0xC7E8, 0,0xC7CE}; /* page 2 0x2013-0x22BF */ -static uint16 tab_uni_big52[]={ +static const uint16 tab_uni_big52[]={ 0xA156,0xA158, 0, 0, 0,0xA1A5,0xA1A6, 0, 0,0xA1A7,0xA1A8, 0, 0, 0, 0,0xA145, 0, 0,0xA14C,0xA14B, 0, 0, 0, 0, @@ -3359,7 +3359,7 @@ static uint16 tab_uni_big52[]={ 0, 0, 0, 0,0xA1E9}; /* page 3 0x2460-0x2642 */ -static uint16 tab_uni_big53[]={ +static const uint16 tab_uni_big53[]={ 0xC7E9,0xC7EA,0xC7EB,0xC7EC,0xC7ED,0xC7EE,0xC7EF,0xC7F0, 0xC7F1,0xC7F2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xC7F3,0xC7F4,0xC7F5,0xC7F6, @@ -3423,7 +3423,7 @@ static uint16 tab_uni_big53[]={ 0xA1F0,0xA1F2,0xA1F1}; /* page 4 0x3000-0x3129 */ -static uint16 tab_uni_big54[]={ +static const uint16 tab_uni_big54[]={ 0xA140,0xA142,0xA143,0xA1B2, 0,0xC6A4, 0, 0, 0xA171,0xA172,0xA16D,0xA16E,0xA175,0xA176,0xA179,0xA17A, 0xA169,0xA16A,0xA245, 0,0xA165,0xA166, 0, 0, @@ -3464,11 +3464,11 @@ static uint16 tab_uni_big54[]={ 0xA3B9,0xA3BA}; /* page 5 0x32A3-0x32A3 */ -static uint16 tab_uni_big55[]={ +static const uint16 tab_uni_big55[]={ 0xA1C0}; /* page 6 0x338E-0x33D5 */ -static uint16 tab_uni_big56[]={ +static const uint16 tab_uni_big56[]={ 0xA255,0xA256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA250,0xA251, 0xA252, 0, 0,0xA254, 0, 0, 0, 0, @@ -3481,7 +3481,7 @@ static uint16 tab_uni_big56[]={ }; /* page 7 0x4E00-0x9483 */ -static uint16 tab_uni_big57[]={ +static const uint16 tab_uni_big57[]={ 0xA440,0xA442, 0,0xA443, 0, 0, 0,0xC945, 0xA456,0xA454,0xA457,0xA455,0xC946,0xA4A3,0xC94F,0xC94D, 0xA4A2,0xA4A1, 0, 0,0xA542,0xA541,0xA540, 0, @@ -5741,7 +5741,7 @@ static uint16 tab_uni_big57[]={ 0xF9C0,0xF9C1,0xF9BF,0xF9C9}; /* page 8 0x9577-0x9FA4 */ -static uint16 tab_uni_big58[]={ +static const uint16 tab_uni_big58[]={ 0xAAF8, 0, 0,0xD844,0xDC78,0xE8A5,0xF376, 0, 0,0xAAF9, 0,0xADAC,0xB07B, 0, 0,0xD845, 0,0xD846,0xB3AC, 0,0xB67D,0xDC7A,0xDC79,0xB6A3, @@ -6070,11 +6070,11 @@ static uint16 tab_uni_big58[]={ 0,0xEFB6, 0,0xF7CF, 0,0xF9A1}; /* page 9 0xFA0C-0xFA0D */ -static uint16 tab_uni_big59[]={ +static const uint16 tab_uni_big59[]={ 0xC94A,0xDDFC}; /* page 10 0xFE30-0xFFFD */ -static uint16 tab_uni_big510[]={ +static const uint16 tab_uni_big510[]={ 0xA14A,0xA157, 0,0xA159,0xA15B,0xA15F,0xA160,0xA163, 0xA164,0xA167,0xA168,0xA16B,0xA16C,0xA16F,0xA170,0xA173, 0xA174,0xA177,0xA178,0xA17B,0xA17C, 0, 0, 0, @@ -6298,7 +6298,7 @@ static MY_CHARSET_HANDLER my_charset_big5_handler= my_scan_8bit }; -CHARSET_INFO my_charset_big5_chinese_ci= +struct charset_info_st my_charset_big5_chinese_ci= { 1,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ @@ -6331,7 +6331,7 @@ CHARSET_INFO my_charset_big5_chinese_ci= }; -CHARSET_INFO my_charset_big5_bin= +struct charset_info_st my_charset_big5_bin= { 84,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT, /* state */ diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 1929d18e10a..2140cd36129 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -23,7 +23,7 @@ #include "strings_def.h" #include <m_ctype.h> -static uchar ctype_bin[]= +static const uchar ctype_bin[]= { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, @@ -47,7 +47,7 @@ static uchar ctype_bin[]= /* Dummy array for toupper / tolower / sortorder */ -static uchar bin_char_array[] = +static const uchar bin_char_array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -69,7 +69,7 @@ static uchar bin_char_array[] = static my_bool -my_coll_init_8bit_bin(CHARSET_INFO *cs, +my_coll_init_8bit_bin(struct charset_info_st *cs, void *(*alloc)(size_t) __attribute__((unused))) { cs->max_sort_char=255; @@ -550,7 +550,7 @@ static MY_CHARSET_HANDLER my_charset_handler= }; -CHARSET_INFO my_charset_bin = +struct charset_info_st my_charset_bin = { 63,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_PRIMARY,/* state */ diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index 355c62285d5..ed4a72c6e0d 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -32,7 +32,7 @@ * .configure. mbmaxlen_cp932=2 */ -static uchar NEAR ctype_cp932[257] = +static const uchar NEAR ctype_cp932[257] = { 0, /* For standard library */ 0040, 0040, 0040, 0040, 0040, 0040, 0040, 0040, /* NUL ^A - ^G */ @@ -69,7 +69,7 @@ static uchar NEAR ctype_cp932[257] = 0020, 0020, 0020, 0020, 0020, 0000, 0000, 0000 }; -static uchar NEAR to_lower_cp932[]= +static const uchar NEAR to_lower_cp932[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -105,7 +105,7 @@ static uchar NEAR to_lower_cp932[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377' }; -static uchar NEAR to_upper_cp932[]= +static const uchar NEAR to_upper_cp932[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -141,7 +141,7 @@ static uchar NEAR to_upper_cp932[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377' }; -static uchar NEAR sort_order_cp932[]= +static const uchar NEAR sort_order_cp932[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -308,7 +308,7 @@ static size_t my_strnxfrm_cp932(CHARSET_INFO *cs __attribute__((unused)), /* page 0 0x00A1-0x00DF */ -static uint16 tab_cp932_uni0[]={ +static const uint16 tab_cp932_uni0[]={ 0xFF61,0xFF62,0xFF63,0xFF64,0xFF65,0xFF66,0xFF67,0xFF68, 0xFF69,0xFF6A,0xFF6B,0xFF6C,0xFF6D,0xFF6E,0xFF6F,0xFF70, 0xFF71,0xFF72,0xFF73,0xFF74,0xFF75,0xFF76,0xFF77,0xFF78, @@ -319,7 +319,7 @@ static uint16 tab_cp932_uni0[]={ 0xFF99,0xFF9A,0xFF9B,0xFF9C,0xFF9D,0xFF9E,0xFF9F}; /* page 1 0x8140-0x84BE */ -static uint16 tab_cp932_uni1[]={ +static const uint16 tab_cp932_uni1[]={ 0x3000,0x3001,0x3002,0xFF0C,0xFF0E,0x30FB,0xFF1A,0xFF1B, 0xFF1F,0xFF01,0x309B,0x309C,0x00B4,0xFF40,0x00A8,0xFF3E, 0xFFE3,0xFF3F,0x30FD,0x30FE,0x309D,0x309E,0x3003,0x4EDD, @@ -434,7 +434,7 @@ static uint16 tab_cp932_uni1[]={ 0x2537,0x253F,0x251D,0x2530,0x2525,0x2538,0x2542}; /* page 2 0x8740-0x879C - NEC Row 13 */ -static uint16 tab_cp932_uni2[]={ +static const uint16 tab_cp932_uni2[]={ 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467, 0x2468,0x2469,0x246A,0x246B,0x246C,0x246D,0x246E,0x246F, 0x2470,0x2471,0x2472,0x2473,0x2160,0x2161,0x2162,0x2163, @@ -449,7 +449,7 @@ static uint16 tab_cp932_uni2[]={ 0x221F,0x22BF,0x2235,0x2229,0x222A}; /* page 3 0x889F-0x9FFC */ -static uint16 tab_cp932_uni3[]={ +static const uint16 tab_cp932_uni3[]={ 0x4E9C,0x5516,0x5A03,0x963F,0x54C0,0x611B,0x6328,0x59F6, 0x9022,0x8475,0x831C,0x7A50,0x60AA,0x63E1,0x6E25,0x65ED, 0x8466,0x82A6,0x9BF5,0x6893,0x5727,0x65A1,0x6271,0x5B9B, @@ -1200,7 +1200,7 @@ static uint16 tab_cp932_uni3[]={ 0x6F3F,0x6EF2,0x6F31,0x6EEF,0x6F32,0x6ECC}; /* page 4 0xE040-0xEAA4 */ -static uint16 tab_cp932_uni4[]={ +static const uint16 tab_cp932_uni4[]={ 0x6F3E,0x6F13,0x6EF7,0x6F86,0x6F7A,0x6F78,0x6F81,0x6F80, 0x6F6F,0x6F5B,0x6FF3,0x6F6D,0x6F82,0x6F7C,0x6F58,0x6F8E, 0x6F91,0x6FC2,0x6F66,0x6FB3,0x6FA3,0x6FA1,0x6FA4,0x6FB9, @@ -1537,7 +1537,7 @@ static uint16 tab_cp932_uni4[]={ /* page 5 0xED40-0xEEFC - IBM Selected Kanji and Non-Kanji(NEC implementation) */ -static uint16 tab_cp932_uni5[]={ +static const uint16 tab_cp932_uni5[]={ 0x7E8A,0x891C,0x9348,0x9288,0x84DC,0x4FC9,0x70BB,0x6631, 0x68C8,0x92F9,0x66FB,0x5F45,0x4E28,0x4EE1,0x4EFC,0x4F00, 0x4F03,0x4F39,0x4F56,0x4F92,0x4F8A,0x4F9A,0x4F94,0x4FCD, @@ -1596,7 +1596,7 @@ static uint16 tab_cp932_uni5[]={ 0x2179,0xFFE2,0xFFE4,0xFF07,0xFF02}; /* page 6 0xF040-0xF9FC - User defined characters */ -static uint16 tab_cp932_uni6[]={ +static const uint16 tab_cp932_uni6[]={ 0xE000,0xE001,0xE002,0xE003,0xE004,0xE005,0xE006,0xE007, 0xE008,0xE009,0xE00A,0xE00B,0xE00C,0xE00D,0xE00E,0xE00F, 0xE010,0xE011,0xE012,0xE013,0xE014,0xE015,0xE016,0xE017, @@ -1912,7 +1912,7 @@ static uint16 tab_cp932_uni6[]={ /* page 7 0xFA40-0xFC4B - IBM Selected Kanji and Non-Kanji */ -static uint16 tab_cp932_uni7[]={ +static const uint16 tab_cp932_uni7[]={ 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177, 0x2178,0x2179,0x2160,0x2161,0x2162,0x2163,0x2164,0x2165, 0x2166,0x2167,0x2168,0x2169,0xFFE2,0xFFE4,0xFF07,0xFF02, @@ -2001,7 +2001,7 @@ static int func_cp932_uni_onechar(int code){ } /* page 0 0x005C-0x00F7 */ -static uint16 tab_uni_cp9320[]={ +static const uint16 tab_uni_cp9320[]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2024,7 +2024,7 @@ static uint16 tab_uni_cp9320[]={ 0, 0, 0,0x8180}; /* page 1 0x0391-0x0451 */ -static uint16 tab_uni_cp9321[]={ +static const uint16 tab_uni_cp9321[]={ 0x839F,0x83A0,0x83A1,0x83A2,0x83A3,0x83A4,0x83A5,0x83A6, 0x83A7,0x83A8,0x83A9,0x83AA,0x83AB,0x83AC,0x83AD,0x83AE, 0x83AF, 0,0x83B0,0x83B1,0x83B2,0x83B3,0x83B4,0x83B5, @@ -2052,7 +2052,7 @@ static uint16 tab_uni_cp9321[]={ 0x8476}; /* page 2 0x2010-0x2473 */ -static uint16 tab_uni_cp9322[]={ +static const uint16 tab_uni_cp9322[]={ 0x815D, 0, 0, 0, 0,0x815C, 0, 0, 0x8165,0x8166, 0, 0,0x8167,0x8168, 0, 0, 0x81F5,0x81F6, 0, 0, 0,0x8164,0x8163, 0, @@ -2196,7 +2196,7 @@ static uint16 tab_uni_cp9322[]={ 0x8750,0x8751,0x8752,0x8753}; /* page 3 0x2500-0x266F */ -static uint16 tab_uni_cp9323[]={ +static const uint16 tab_uni_cp9323[]={ 0x849F,0x84AA,0x84A0,0x84AB, 0, 0, 0, 0, 0, 0, 0, 0,0x84A1, 0, 0,0x84AC, 0x84A2, 0, 0,0x84AD,0x84A4, 0, 0,0x84AF, @@ -2246,7 +2246,7 @@ static uint16 tab_uni_cp9323[]={ }; /* page 4 0x3000-0x30FE */ -static uint16 tab_uni_cp9324[]={ +static const uint16 tab_uni_cp9324[]={ 0x8140,0x8141,0x8142,0x8156, 0,0x8158,0x8159,0x815A, 0x8171,0x8172,0x8173,0x8174,0x8175,0x8176,0x8177,0x8178, 0x8179,0x817A,0x81A7,0x81AC,0x816B,0x816C, 0, 0, @@ -2281,7 +2281,7 @@ static uint16 tab_uni_cp9324[]={ 0, 0, 0,0x8145,0x815B,0x8152,0x8153}; /* page 5 0x3230-0x33CD */ -static uint16 tab_uni_cp9325[]={ +static const uint16 tab_uni_cp9325[]={ 0,0x878A,0x878B, 0, 0, 0, 0, 0, 0,0x878C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2336,7 +2336,7 @@ static uint16 tab_uni_cp9325[]={ 0, 0, 0, 0, 0,0x8783}; /* page 6 0x4E00-0x9481 */ -static uint16 tab_uni_cp9326[]={ +static const uint16 tab_uni_cp9326[]={ 0x88EA,0x929A, 0,0x8EB5, 0, 0, 0,0x969C, 0x8FE4,0x8E4F,0x8FE3,0x89BA, 0,0x9573,0x975E, 0, 0x98A0,0x894E, 0, 0,0x8A8E,0x98A1,0x90A2,0x99C0, @@ -4596,7 +4596,7 @@ static uint16 tab_uni_cp9326[]={ 0,0xE876}; /* page 7 0x9577-0x9FA0 */ -static uint16 tab_uni_cp9327[]={ +static const uint16 tab_uni_cp9327[]={ 0x92B7, 0, 0, 0, 0, 0, 0, 0, 0,0x96E5, 0,0xE878,0x914D, 0, 0, 0, 0xE879, 0,0x95C2,0xE87A,0x8A4A, 0, 0, 0, @@ -4925,7 +4925,7 @@ static uint16 tab_uni_cp9327[]={ 0,0xEA9E}; /* page 8 0xE000-0xE757 - User defined characters */ -static uint16 tab_uni_cp9328[]={ +static const uint16 tab_uni_cp9328[]={ 0xF040,0xF041,0xF042,0xF043,0xF044,0xF045,0xF046,0xF047, 0xF048,0xF049,0xF04A,0xF04B,0xF04C,0xF04D,0xF04E,0xF04F, 0xF050,0xF051,0xF052,0xF053,0xF054,0xF055,0xF056,0xF057, @@ -5163,7 +5163,7 @@ static uint16 tab_uni_cp9328[]={ 0xF9F5,0xF9F6,0xF9F7,0xF9F8,0xF9F9,0xF9FA,0xF9FB,0xF9FC}; /* page 9 0xF920-0xFA2D */ -static uint16 tab_uni_cp9329[]={ +static const uint16 tab_uni_cp9329[]={ 0, 0, 0, 0, 0, 0, 0, 0, 0,0xFAE0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5200,7 +5200,7 @@ static uint16 tab_uni_cp9329[]={ 0xFBDA,0xFBEA,0xFBF6,0xFBF7,0xFBF9,0xFC49}; /* page 10 0xFF01-0xFFE5 */ -static uint16 tab_uni_cp93210[]={ +static const uint16 tab_uni_cp93210[]={ 0x8149,0xFA57,0x8194,0x8190,0x8193,0x8195,0xFA56,0x8169, 0x816A,0x8196,0x817B,0x8143,0x817C,0x8144,0x815E,0x824F, 0x8250,0x8251,0x8252,0x8253,0x8254,0x8255,0x8256,0x8257, @@ -5439,7 +5439,7 @@ static MY_CHARSET_HANDLER my_charset_handler= }; -CHARSET_INFO my_charset_cp932_japanese_ci= +struct charset_info_st my_charset_cp932_japanese_ci= { 95,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ @@ -5471,7 +5471,7 @@ CHARSET_INFO my_charset_cp932_japanese_ci= &my_collation_ci_handler }; -CHARSET_INFO my_charset_cp932_bin= +struct charset_info_st my_charset_cp932_bin= { 96,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT, /* state */ diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 4d92f56ae1f..3d0f85bb557 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -85,7 +85,7 @@ below for what are the "special values" */ -static uchar *CZ_SORT_TABLE[] = { +static const uchar *const CZ_SORT_TABLE[] = { (uchar*) "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\043\044\045\046\047\050\051\052\053\054\000\000\000\000\000\000\000\003\004\377\007\010\011\012\013\015\016\017\020\022\023\024\025\026\027\031\033\034\035\036\037\040\041\000\000\000\000\000\000\003\004\377\007\010\011\012\013\015\016\017\020\022\023\024\025\026\027\031\033\034\035\036\037\040\041\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\021\000\020\032\000\000\032\032\033\042\000\042\042\000\003\000\021\000\020\032\000\000\032\032\033\042\000\042\042\027\003\003\003\003\020\006\006\006\010\010\010\010\015\015\007\007\023\023\024\024\024\024\000\030\034\034\034\034\040\033\000\027\003\003\003\003\020\006\006\006\010\010\010\010\015\015\007\007\023\023\024\024\024\024\000\030\034\034\034\034\040\033\000", (uchar*) "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\106\107\110\111\112\113\114\115\116\117\000\000\000\000\000\000\000\003\011\377\016\021\026\027\030\032\035\036\037\043\044\047\054\055\056\061\065\070\075\076\077\100\102\000\000\000\000\000\000\003\011\377\016\021\026\027\030\032\035\036\037\043\044\047\054\055\056\061\065\070\075\076\077\100\102\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\042\000\041\063\000\000\062\064\066\104\000\103\105\000\010\000\042\000\041\063\000\000\062\064\066\104\000\103\105\057\004\005\007\006\040\014\015\013\022\025\024\023\033\034\017\020\046\045\050\051\053\052\000\060\072\071\074\073\101\067\000\057\004\005\007\006\040\014\015\013\022\025\024\023\033\034\017\020\046\045\050\051\053\052\000\060\072\071\074\073\101\067\000", (uchar*) "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\212\213\214\215\216\217\220\221\222\223\000\000\000\000\000\000\000\004\020\377\032\040\052\054\056\063\071\073\075\105\107\115\127\131\133\141\151\157\171\173\175\177\203\000\000\000\000\000\000\003\017\377\031\037\051\053\055\062\070\072\074\104\106\114\126\130\132\140\150\156\170\172\174\176\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\103\000\101\145\000\000\143\147\153\207\000\205\211\000\015\000\102\000\100\144\000\000\142\146\152\206\000\204\210\135\006\010\014\012\077\026\030\024\042\050\046\044\065\067\034\036\113\111\117\121\125\123\000\137\163\161\167\165\201\155\000\134\005\007\013\011\076\025\027\023\041\047\045\043\064\066\033\035\112\110\116\120\124\122\000\136\162\160\166\164\200\154\000", @@ -101,14 +101,14 @@ static uchar *CZ_SORT_TABLE[] = { struct wordvalue { const char * word; - uchar *outvalue; + const uchar *outvalue; }; -static struct wordvalue doubles[] = { - { "ch", (uchar*) "\014\031\057\057" }, - { "Ch", (uchar*) "\014\031\060\060" }, - { "CH", (uchar*) "\014\031\061\061" }, - { "c", (uchar*) "\005\012\021\021" }, - { "C", (uchar*) "\005\012\022\022" }, +static const struct wordvalue doubles[] = { + { "ch", (const uchar*) "\014\031\057\057" }, + { "Ch", (const uchar*) "\014\031\060\060" }, + { "CH", (const uchar*) "\014\031\061\061" }, + { "c", (const uchar*) "\005\012\021\021" }, + { "C", (const uchar*) "\005\012\022\022" }, }; /* @@ -431,7 +431,7 @@ static my_bool my_like_range_czech(CHARSET_INFO *cs __attribute__((unused)), */ #include "strings_def.h" -static uchar NEAR ctype_czech[257] = { +static const uchar NEAR ctype_czech[257] = { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, @@ -451,7 +451,7 @@ static uchar NEAR ctype_czech[257] = { 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 16, }; -static uchar NEAR to_lower_czech[] = { +static const uchar NEAR to_lower_czech[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -470,7 +470,7 @@ static uchar NEAR to_lower_czech[] = { 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, }; -static uchar NEAR to_upper_czech[] = { +static const uchar NEAR to_upper_czech[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -489,7 +489,7 @@ static uchar NEAR to_upper_czech[] = { 240,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255, }; -static uchar NEAR sort_order_czech[] = { +static const uchar NEAR sort_order_czech[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -508,7 +508,7 @@ static uchar NEAR sort_order_czech[] = { 255, 98, 99,101,102,103,104,255,109,119,118,120,121,126,116,255, }; -static uint16 tab_8859_2_uni[256]={ +static const uint16 tab_8859_2_uni[256]={ 0,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -545,7 +545,7 @@ static uint16 tab_8859_2_uni[256]={ /* 0000-00FD , 254 chars */ -static uchar tab_uni_8859_2_plane00[]={ +static const uchar tab_uni_8859_2_plane00[]={ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -564,7 +564,7 @@ static uchar tab_uni_8859_2_plane00[]={ 0x00,0x00,0x00,0xF3,0xF4,0x00,0xF6,0xF7,0x00,0x00,0xFA,0x00,0xFC,0xFD}; /* 0102-017E , 125 chars */ -static uchar tab_uni_8859_2_plane01[]={ +static const uchar tab_uni_8859_2_plane01[]={ 0xC3,0xE3,0xA1,0xB1,0xC6,0xE6,0x00,0x00,0x00,0x00,0xC8,0xE8,0xCF,0xEF,0xD0,0xF0, 0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0xCC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -575,7 +575,7 @@ static uchar tab_uni_8859_2_plane01[]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xBC,0xAF,0xBF,0xAE,0xBE}; /* 02C7-02DD , 23 chars */ -static uchar tab_uni_8859_2_plane02[]={ +static const uchar tab_uni_8859_2_plane02[]={ 0xB7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xA2,0xFF,0x00,0xB2,0x00,0xBD}; @@ -602,7 +602,7 @@ static MY_COLLATION_HANDLER my_collation_latin2_czech_ci_handler = my_propagate_simple }; -CHARSET_INFO my_charset_latin2_czech_ci = +struct charset_info_st my_charset_latin2_czech_ci = { 2,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_CSSORT, /* state */ diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 9266cad37e2..b796d385214 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -33,7 +33,7 @@ #ifdef HAVE_CHARSET_euckr -static uchar NEAR ctype_euc_kr[257] = +static const uchar NEAR ctype_euc_kr[257] = { 0, /* For standard library */ 0040, 0040, 0040, 0040, 0040, 0040, 0040, 0040, /* NUL ^A - ^G */ @@ -70,7 +70,7 @@ static uchar NEAR ctype_euc_kr[257] = 0020, 0020, 0020, 0020, 0020, 0020, 0020, 0000, }; -static uchar NEAR to_lower_euc_kr[]= +static const uchar NEAR to_lower_euc_kr[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -106,7 +106,7 @@ static uchar NEAR to_lower_euc_kr[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uchar NEAR to_upper_euc_kr[]= +static const uchar NEAR to_upper_euc_kr[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -142,7 +142,7 @@ static uchar NEAR to_upper_euc_kr[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uchar NEAR sort_order_euc_kr[]= +static const uchar NEAR sort_order_euc_kr[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -218,7 +218,7 @@ static uint mbcharlen_euc_kr(CHARSET_INFO *cs __attribute__((unused)),uint c) /* page 0 0x8141-0xC8FE */ -static uint16 tab_ksc5601_uni0[]={ +static const uint16 tab_ksc5601_uni0[]={ 0xAC02,0xAC03,0xAC05,0xAC06,0xAC0B,0xAC0C,0xAC0D,0xAC0E, 0xAC0F,0xAC18,0xAC1E,0xAC1F,0xAC21,0xAC22,0xAC23,0xAC25, 0xAC26,0xAC27,0xAC28,0xAC29,0xAC2A,0xAC2B,0xAC2E,0xAC32, @@ -2517,7 +2517,7 @@ static uint16 tab_ksc5601_uni0[]={ 0xD78C,0xD790,0xD798,0xD799,0xD79B,0xD79D}; /* page 1 0xCAA1-0xFDFE */ -static uint16 tab_ksc5601_uni1[]={ +static const uint16 tab_ksc5601_uni1[]={ 0x4F3D,0x4F73,0x5047,0x50F9,0x52A0,0x53EF,0x5475,0x54E5, 0x5609,0x5AC1,0x5BB6,0x6687,0x67B6,0x67B7,0x67EF,0x6B4C, 0x73C2,0x75C2,0x7A3C,0x82DB,0x8304,0x8857,0x8888,0x8A36, @@ -4171,7 +4171,7 @@ static int func_ksc5601_uni_onechar(int code){ return(0); } /* page 0 0x00A1-0x0167 */ -static uint16 tab_uni_ksc56010[]={ +static const uint16 tab_uni_ksc56010[]={ 0xA2AE, 0, 0,0xA2B4, 0, 0,0xA1D7,0xA1A7, 0,0xA8A3, 0, 0,0xA1A9,0xA2E7, 0,0xA1C6, 0xA1BE,0xA9F7,0xA9F8,0xA2A5, 0,0xA2D2,0xA1A4,0xA2AC, @@ -4199,7 +4199,7 @@ static uint16 tab_uni_ksc56010[]={ 0, 0, 0, 0, 0,0xA8AE,0xA9AE}; /* page 1 0x02C7-0x0451 */ -static uint16 tab_uni_ksc56011[]={ +static const uint16 tab_uni_ksc56011[]={ 0xA2A7, 0, 0, 0, 0, 0, 0, 0, 0,0xA2B0, 0, 0, 0, 0, 0, 0, 0,0xA2A8,0xA2AB,0xA2AA,0xA2AD, 0,0xA2A9, 0, @@ -4252,7 +4252,7 @@ static uint16 tab_uni_ksc56011[]={ 0xACF1, 0,0xACD7}; /* page 2 0x2015-0x2312 */ -static uint16 tab_uni_ksc56012[]={ +static const uint16 tab_uni_ksc56012[]={ 0xA1AA, 0, 0,0xA1AE,0xA1AF, 0, 0,0xA1B0, 0xA1B1, 0, 0,0xA2D3,0xA2D4, 0, 0, 0, 0xA1A5,0xA1A6, 0, 0, 0, 0, 0, 0, @@ -4351,7 +4351,7 @@ static uint16 tab_uni_ksc56012[]={ 0, 0, 0, 0, 0,0xA1D2}; /* page 3 0x2460-0x266D */ -static uint16 tab_uni_ksc56013[]={ +static const uint16 tab_uni_ksc56013[]={ 0xA8E7,0xA8E8,0xA8E9,0xA8EA,0xA8EB,0xA8EC,0xA8ED,0xA8EE, 0xA8EF,0xA8F0,0xA8F1,0xA8F2,0xA8F3,0xA8F4,0xA8F5, 0, 0, 0, 0, 0,0xA9E7,0xA9E8,0xA9E9,0xA9EA, @@ -4420,7 +4420,7 @@ static uint16 tab_uni_ksc56013[]={ 0xA2CD,0xA2DB,0xA2DC, 0,0xA2DD,0xA2DA}; /* page 4 0x3000-0x327F */ -static uint16 tab_uni_ksc56014[]={ +static const uint16 tab_uni_ksc56014[]={ 0xA1A1,0xA1A2,0xA1A3,0xA1A8, 0, 0, 0, 0, 0xA1B4,0xA1B5,0xA1B6,0xA1B7,0xA1B8,0xA1B9,0xA1BA,0xA1BB, 0xA1BC,0xA1BD, 0,0xA1EB,0xA1B2,0xA1B3, 0, 0, @@ -4504,7 +4504,7 @@ static uint16 tab_uni_ksc56014[]={ }; /* page 5 0x3380-0x33DD */ -static uint16 tab_uni_ksc56015[]={ +static const uint16 tab_uni_ksc56015[]={ 0xA7C9,0xA7CA,0xA7CB,0xA7CC,0xA7CD, 0, 0, 0, 0xA7BA,0xA7BB,0xA7DC,0xA7DD,0xA7DE,0xA7B6,0xA7B7,0xA7B8, 0xA7D4,0xA7D5,0xA7D6,0xA7D7,0xA7D8,0xA7A1,0xA7A2,0xA7A3, @@ -4519,7 +4519,7 @@ static uint16 tab_uni_ksc56015[]={ 0xA2E4, 0, 0,0xA7E4,0xA7EE,0xA7E9}; /* page 6 0x4E00-0x947F */ -static uint16 tab_uni_ksc56016[]={ +static const uint16 tab_uni_ksc56016[]={ 0xECE9,0xEFCB, 0,0xF6D2, 0, 0, 0,0xD8B2, 0xEDDB,0xDFB2,0xDFBE,0xF9BB, 0,0xDCF4, 0, 0, 0,0xF5E4, 0, 0,0xF3A6,0xDDE0,0xE1A6, 0, @@ -6779,7 +6779,7 @@ static uint16 tab_uni_ksc56016[]={ }; /* page 7 0x9577-0x9F9C */ -static uint16 tab_uni_ksc56017[]={ +static const uint16 tab_uni_ksc56017[]={ 0xEDFE, 0, 0, 0, 0, 0, 0, 0, 0,0xDAA6, 0, 0,0xE0EC, 0, 0, 0, 0, 0,0xF8CD, 0,0xCBD2, 0, 0, 0, @@ -7107,7 +7107,7 @@ static uint16 tab_uni_ksc56017[]={ 0, 0, 0, 0, 0,0xCFCF}; /* page 8 0xAC00-0xD7A3 */ -static uint16 tab_uni_ksc56018[]={ +static const uint16 tab_uni_ksc56018[]={ 0xB0A1,0xB0A2,0x8141,0x8142,0xB0A3,0x8143,0x8144,0xB0A4, 0xB0A5,0xB0A6,0xB0A7,0x8145,0x8146,0x8147,0x8148,0x8149, 0xB0A8,0xB0A9,0xB0AA,0xB0AB,0xB0AC,0xB0AD,0xB0AE,0xB0AF, @@ -8507,7 +8507,7 @@ static uint16 tab_uni_ksc56018[]={ 0xC64F,0xC650,0xC651,0xC652}; /* page 9 0xF900-0xFA0B */ -static uint16 tab_uni_ksc56019[]={ +static const uint16 tab_uni_ksc56019[]={ 0xCBD0,0xCBD6,0xCBE7,0xCDCF,0xCDE8,0xCEAD,0xCFFB,0xD0A2, 0xD0B8,0xD0D0,0xD0DD,0xD1D4,0xD1D5,0xD1D8,0xD1DB,0xD1DC, 0xD1DD,0xD1DE,0xD1DF,0xD1E0,0xD1E2,0xD1E3,0xD1E4,0xD1E5, @@ -8544,7 +8544,7 @@ static uint16 tab_uni_ksc56019[]={ 0xFAA1,0xFAA2,0xFAE6,0xFCA9}; /* page 10 0xFF01-0xFFE6 */ -static uint16 tab_uni_ksc560110[]={ +static const uint16 tab_uni_ksc560110[]={ 0xA3A1,0xA3A2,0xA3A3,0xA3A4,0xA3A5,0xA3A6,0xA3A7,0xA3A8, 0xA3A9,0xA3AA,0xA3AB,0xA3AC,0xA3AD,0xA3AE,0xA3AF,0xA3B0, 0xA3B1,0xA3B2,0xA3B3,0xA3B4,0xA3B5,0xA3B6,0xA3B7,0xA3B8, @@ -8738,7 +8738,7 @@ static MY_CHARSET_HANDLER my_charset_handler= }; -CHARSET_INFO my_charset_euckr_korean_ci= +struct charset_info_st my_charset_euckr_korean_ci= { 19,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ @@ -8771,7 +8771,7 @@ CHARSET_INFO my_charset_euckr_korean_ci= }; -CHARSET_INFO my_charset_euckr_bin= +struct charset_info_st my_charset_euckr_bin= { 85,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT, /* state */ diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c index f570ea3ff84..8f0e67186b1 100644 --- a/strings/ctype-eucjpms.c +++ b/strings/ctype-eucjpms.c @@ -35,7 +35,7 @@ ctype-ujis.c file. #ifdef HAVE_CHARSET_eucjpms -static uchar NEAR ctype_eucjpms[257] = +static const uchar NEAR ctype_eucjpms[257] = { 0, /* For standard library */ 0040, 0040, 0040, 0040, 0040, 0040, 0040, 0040, /* NUL ^A - ^G */ @@ -72,7 +72,7 @@ static uchar NEAR ctype_eucjpms[257] = 0020, 0020, 0020, 0020, 0020, 0020, 0020, 0000, }; -static uchar NEAR to_lower_eucjpms[]= +static const uchar NEAR to_lower_eucjpms[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -108,7 +108,7 @@ static uchar NEAR to_lower_eucjpms[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377' }; -static uchar NEAR to_upper_eucjpms[]= +static const uchar NEAR to_upper_eucjpms[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -144,7 +144,7 @@ static uchar NEAR to_upper_eucjpms[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377' }; -static uchar NEAR sort_order_eucjpms[]= +static const uchar NEAR sort_order_eucjpms[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -203,7 +203,7 @@ static uint mbcharlen_eucjpms(CHARSET_INFO *cs __attribute__((unused)),uint c) } -static uint16 tab_jisx0201_uni[256]={ +static const uint16 tab_jisx0201_uni[256]={ 0,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -272,7 +272,7 @@ my_wc_mb_jisx0201(CHARSET_INFO *cs __attribute__((unused)), /* page 0 0x2121-0x217E */ -static uint16 tab_jisx0208_uni0[]={ +static const uint16 tab_jisx0208_uni0[]={ 0x3000,0x3001,0x3002,0xFF0C,0xFF0E,0x30FB,0xFF1A,0xFF1B, 0xFF1F,0xFF01,0x309B,0x309C,0x00B4,0xFF40,0x00A8,0xFF3E, 0xFFE3,0xFF3F,0x30FD,0x30FE,0x309D,0x309E,0x3003,0x4EDD, @@ -287,7 +287,7 @@ static uint16 tab_jisx0208_uni0[]={ 0x2606,0x2605,0x25CB,0x25CF,0x25CE,0x25C7}; /* page 1 0x2221-0x227E */ -static uint16 tab_jisx0208_uni1[]={ +static const uint16 tab_jisx0208_uni1[]={ 0x25C6,0x25A1,0x25A0,0x25B3,0x25B2,0x25BD,0x25BC,0x203B, 0x3012,0x2192,0x2190,0x2191,0x2193,0x3013, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -302,7 +302,7 @@ static uint16 tab_jisx0208_uni1[]={ 0x00B6, 0, 0, 0, 0,0x25EF}; /* page 2 0x2330-0x237A */ -static uint16 tab_jisx0208_uni2[]={ +static const uint16 tab_jisx0208_uni2[]={ 0xFF10,0xFF11,0xFF12,0xFF13,0xFF14,0xFF15,0xFF16,0xFF17, 0xFF18,0xFF19, 0, 0, 0, 0, 0, 0, 0,0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27, @@ -315,7 +315,7 @@ static uint16 tab_jisx0208_uni2[]={ 0xFF58,0xFF59,0xFF5A}; /* page 3 0x2421-0x2473 */ -static uint16 tab_jisx0208_uni3[]={ +static const uint16 tab_jisx0208_uni3[]={ 0x3041,0x3042,0x3043,0x3044,0x3045,0x3046,0x3047,0x3048, 0x3049,0x304A,0x304B,0x304C,0x304D,0x304E,0x304F,0x3050, 0x3051,0x3052,0x3053,0x3054,0x3055,0x3056,0x3057,0x3058, @@ -329,7 +329,7 @@ static uint16 tab_jisx0208_uni3[]={ 0x3091,0x3092,0x3093}; /* page 4 0x2521-0x2576 */ -static uint16 tab_jisx0208_uni4[]={ +static const uint16 tab_jisx0208_uni4[]={ 0x30A1,0x30A2,0x30A3,0x30A4,0x30A5,0x30A6,0x30A7,0x30A8, 0x30A9,0x30AA,0x30AB,0x30AC,0x30AD,0x30AE,0x30AF,0x30B0, 0x30B1,0x30B2,0x30B3,0x30B4,0x30B5,0x30B6,0x30B7,0x30B8, @@ -343,7 +343,7 @@ static uint16 tab_jisx0208_uni4[]={ 0x30F1,0x30F2,0x30F3,0x30F4,0x30F5,0x30F6}; /* page 5 0x2621-0x2658 */ -static uint16 tab_jisx0208_uni5[]={ +static const uint16 tab_jisx0208_uni5[]={ 0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398, 0x0399,0x039A,0x039B,0x039C,0x039D,0x039E,0x039F,0x03A0, 0x03A1,0x03A3,0x03A4,0x03A5,0x03A6,0x03A7,0x03A8,0x03A9, @@ -354,7 +354,7 @@ static uint16 tab_jisx0208_uni5[]={ }; /* page 6 0x2721-0x2771 */ -static uint16 tab_jisx0208_uni6[]={ +static const uint16 tab_jisx0208_uni6[]={ 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0401,0x0416, 0x0417,0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E, 0x041F,0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426, @@ -368,7 +368,7 @@ static uint16 tab_jisx0208_uni6[]={ 0x044F}; /* page 7 0x2821-0x2840 */ -static uint16 tab_jisx0208_uni7[]={ +static const uint16 tab_jisx0208_uni7[]={ 0x2500,0x2502,0x250C,0x2510,0x2518,0x2514,0x251C,0x252C, 0x2524,0x2534,0x253C,0x2501,0x2503,0x250F,0x2513,0x251B, 0x2517,0x2523,0x2533,0x252B,0x253B,0x254B,0x2520,0x252F, @@ -376,7 +376,7 @@ static uint16 tab_jisx0208_uni7[]={ }; /* page 8 0x3021-0x307E */ -static uint16 tab_jisx0208_uni8[]={ +static const uint16 tab_jisx0208_uni8[]={ 0x4E9C,0x5516,0x5A03,0x963F,0x54C0,0x611B,0x6328,0x59F6, 0x9022,0x8475,0x831C,0x7A50,0x60AA,0x63E1,0x6E25,0x65ED, 0x8466,0x82A6,0x9BF5,0x6893,0x5727,0x65A1,0x6271,0x5B9B, @@ -391,7 +391,7 @@ static uint16 tab_jisx0208_uni8[]={ 0x59FB,0x5F15,0x98F2,0x6DEB,0x80E4,0x852D}; /* page 9 0x3121-0x317E */ -static uint16 tab_jisx0208_uni9[]={ +static const uint16 tab_jisx0208_uni9[]={ 0x9662,0x9670,0x96A0,0x97FB,0x540B,0x53F3,0x5B87,0x70CF, 0x7FBD,0x8FC2,0x96E8,0x536F,0x9D5C,0x7ABA,0x4E11,0x7893, 0x81FC,0x6E26,0x5618,0x5504,0x6B1D,0x851A,0x9C3B,0x59E5, @@ -406,7 +406,7 @@ static uint16 tab_jisx0208_uni9[]={ 0x7525,0x51F9,0x592E,0x5965,0x5F80,0x5FDC}; /* page 10 0x3221-0x327E */ -static uint16 tab_jisx0208_uni10[]={ +static const uint16 tab_jisx0208_uni10[]={ 0x62BC,0x65FA,0x6A2A,0x6B27,0x6BB4,0x738B,0x7FC1,0x8956, 0x9D2C,0x9D0E,0x9EC4,0x5CA1,0x6C96,0x837B,0x5104,0x5C4B, 0x61B6,0x81C6,0x6876,0x7261,0x4E59,0x4FFA,0x5378,0x6069, @@ -421,7 +421,7 @@ static uint16 tab_jisx0208_uni10[]={ 0x6094,0x6062,0x61D0,0x6212,0x62D0,0x6539}; /* page 11 0x3321-0x337E */ -static uint16 tab_jisx0208_uni11[]={ +static const uint16 tab_jisx0208_uni11[]={ 0x9B41,0x6666,0x68B0,0x6D77,0x7070,0x754C,0x7686,0x7D75, 0x82A5,0x87F9,0x958B,0x968E,0x8C9D,0x51F1,0x52BE,0x5916, 0x54B3,0x5BB3,0x5D16,0x6168,0x6982,0x6DAF,0x788D,0x84CB, @@ -436,7 +436,7 @@ static uint16 tab_jisx0208_uni11[]={ 0x938C,0x565B,0x9D28,0x6822,0x8305,0x8431}; /* page 12 0x3421-0x347E */ -static uint16 tab_jisx0208_uni12[]={ +static const uint16 tab_jisx0208_uni12[]={ 0x7CA5,0x5208,0x82C5,0x74E6,0x4E7E,0x4F83,0x51A0,0x5BD2, 0x520A,0x52D8,0x52E7,0x5DFB,0x559A,0x582A,0x59E6,0x5B8C, 0x5B98,0x5BDB,0x5E72,0x5E79,0x60A3,0x611F,0x6163,0x61BE, @@ -451,7 +451,7 @@ static uint16 tab_jisx0208_uni12[]={ 0x673A,0x65D7,0x65E2,0x671F,0x68CB,0x68C4}; /* page 13 0x3521-0x357E */ -static uint16 tab_jisx0208_uni13[]={ +static const uint16 tab_jisx0208_uni13[]={ 0x6A5F,0x5E30,0x6BC5,0x6C17,0x6C7D,0x757F,0x7948,0x5B63, 0x7A00,0x7D00,0x5FBD,0x898F,0x8A18,0x8CB4,0x8D77,0x8ECC, 0x8F1D,0x98E2,0x9A0E,0x9B3C,0x4E80,0x507D,0x5100,0x5993, @@ -466,7 +466,7 @@ static uint16 tab_jisx0208_uni13[]={ 0x6F01,0x79A6,0x9B5A,0x4EA8,0x4EAB,0x4EAC}; /* page 14 0x3621-0x367E */ -static uint16 tab_jisx0208_uni14[]={ +static const uint16 tab_jisx0208_uni14[]={ 0x4F9B,0x4FA0,0x50D1,0x5147,0x7AF6,0x5171,0x51F6,0x5354, 0x5321,0x537F,0x53EB,0x55AC,0x5883,0x5CE1,0x5F37,0x5F4A, 0x602F,0x6050,0x606D,0x631F,0x6559,0x6A4B,0x6CC1,0x72C2, @@ -481,7 +481,7 @@ static uint16 tab_jisx0208_uni14[]={ 0x9685,0x4E32,0x6ADB,0x91E7,0x5C51,0x5C48}; /* page 15 0x3721-0x377E */ -static uint16 tab_jisx0208_uni15[]={ +static const uint16 tab_jisx0208_uni15[]={ 0x6398,0x7A9F,0x6C93,0x9774,0x8F61,0x7AAA,0x718A,0x9688, 0x7C82,0x6817,0x7E70,0x6851,0x936C,0x52F2,0x541B,0x85AB, 0x8A13,0x7FA4,0x8ECD,0x90E1,0x5366,0x8888,0x7941,0x4FC2, @@ -496,7 +496,7 @@ static uint16 tab_jisx0208_uni15[]={ 0x5ACC,0x5EFA,0x61B2,0x61F8,0x62F3,0x6372}; /* page 16 0x3821-0x387E */ -static uint16 tab_jisx0208_uni16[]={ +static const uint16 tab_jisx0208_uni16[]={ 0x691C,0x6A29,0x727D,0x72AC,0x732E,0x7814,0x786F,0x7D79, 0x770C,0x80A9,0x898B,0x8B19,0x8CE2,0x8ED2,0x9063,0x9375, 0x967A,0x9855,0x9A13,0x9E78,0x5143,0x539F,0x53B3,0x5E7B, @@ -511,7 +511,7 @@ static uint16 tab_jisx0208_uni16[]={ 0x529F,0x52B9,0x52FE,0x539A,0x53E3,0x5411}; /* page 17 0x3921-0x397E */ -static uint16 tab_jisx0208_uni17[]={ +static const uint16 tab_jisx0208_uni17[]={ 0x540E,0x5589,0x5751,0x57A2,0x597D,0x5B54,0x5B5D,0x5B8F, 0x5DE5,0x5DE7,0x5DF7,0x5E78,0x5E83,0x5E9A,0x5EB7,0x5F18, 0x6052,0x614C,0x6297,0x62D8,0x63A7,0x653B,0x6602,0x6643, @@ -526,7 +526,7 @@ static uint16 tab_jisx0208_uni17[]={ 0x7511,0x5FFD,0x60DA,0x9AA8,0x72DB,0x8FBC}; /* page 18 0x3A21-0x3A7E */ -static uint16 tab_jisx0208_uni18[]={ +static const uint16 tab_jisx0208_uni18[]={ 0x6B64,0x9803,0x4ECA,0x56F0,0x5764,0x58BE,0x5A5A,0x6068, 0x61C7,0x660F,0x6606,0x6839,0x68B1,0x6DF7,0x75D5,0x7D3A, 0x826E,0x9B42,0x4E9B,0x4F50,0x53C9,0x5506,0x5D6F,0x5DE6, @@ -541,7 +541,7 @@ static uint16 tab_jisx0208_uni18[]={ 0x685C,0x9BAD,0x7B39,0x5319,0x518A,0x5237}; /* page 19 0x3B21-0x3B7E */ -static uint16 tab_jisx0208_uni19[]={ +static const uint16 tab_jisx0208_uni19[]={ 0x5BDF,0x62F6,0x64AE,0x64E6,0x672D,0x6BBA,0x85A9,0x96D1, 0x7690,0x9BD6,0x634C,0x9306,0x9BAB,0x76BF,0x6652,0x4E09, 0x5098,0x53C2,0x5C71,0x60E8,0x6492,0x6563,0x685F,0x71E6, @@ -556,7 +556,7 @@ static uint16 tab_jisx0208_uni19[]={ 0x5150,0x5B57,0x5BFA,0x6148,0x6301,0x6642}; /* page 20 0x3C21-0x3C7E */ -static uint16 tab_jisx0208_uni20[]={ +static const uint16 tab_jisx0208_uni20[]={ 0x6B21,0x6ECB,0x6CBB,0x723E,0x74BD,0x75D4,0x78C1,0x793A, 0x800C,0x8033,0x81EA,0x8494,0x8F9E,0x6C50,0x9E7F,0x5F0F, 0x8B58,0x9D2B,0x7AFA,0x8EF8,0x5B8D,0x96EB,0x4E03,0x53F1, @@ -571,7 +571,7 @@ static uint16 tab_jisx0208_uni20[]={ 0x6A39,0x7DAC,0x9700,0x56DA,0x53CE,0x5468}; /* page 21 0x3D21-0x3D7E */ -static uint16 tab_jisx0208_uni21[]={ +static const uint16 tab_jisx0208_uni21[]={ 0x5B97,0x5C31,0x5DDE,0x4FEE,0x6101,0x62FE,0x6D32,0x79C0, 0x79CB,0x7D42,0x7E4D,0x7FD2,0x81ED,0x821F,0x8490,0x8846, 0x8972,0x8B90,0x8E74,0x8F2F,0x9031,0x914B,0x916C,0x96C6, @@ -586,7 +586,7 @@ static uint16 tab_jisx0208_uni21[]={ 0x5F90,0x6055,0x92E4,0x9664,0x50B7,0x511F}; /* page 22 0x3E21-0x3E7E */ -static uint16 tab_jisx0208_uni22[]={ +static const uint16 tab_jisx0208_uni22[]={ 0x52DD,0x5320,0x5347,0x53EC,0x54E8,0x5546,0x5531,0x5617, 0x5968,0x59BE,0x5A3C,0x5BB5,0x5C06,0x5C0F,0x5C11,0x5C1A, 0x5E84,0x5E8A,0x5EE0,0x5F70,0x627F,0x6284,0x62DB,0x638C, @@ -601,7 +601,7 @@ static uint16 tab_jisx0208_uni22[]={ 0x8B72,0x91B8,0x9320,0x5631,0x57F4,0x98FE}; /* page 23 0x3F21-0x3F7E */ -static uint16 tab_jisx0208_uni23[]={ +static const uint16 tab_jisx0208_uni23[]={ 0x62ED,0x690D,0x6B96,0x71ED,0x7E54,0x8077,0x8272,0x89E6, 0x98DF,0x8755,0x8FB1,0x5C3B,0x4F38,0x4FE1,0x4FB5,0x5507, 0x5A20,0x5BDD,0x5BE9,0x5FC3,0x614E,0x632F,0x65B0,0x664B, @@ -616,7 +616,7 @@ static uint16 tab_jisx0208_uni23[]={ 0x6749,0x6919,0x83C5,0x9817,0x96C0,0x88FE}; /* page 24 0x4021-0x407E */ -static uint16 tab_jisx0208_uni24[]={ +static const uint16 tab_jisx0208_uni24[]={ 0x6F84,0x647A,0x5BF8,0x4E16,0x702C,0x755D,0x662F,0x51C4, 0x5236,0x52E2,0x59D3,0x5F81,0x6027,0x6210,0x653F,0x6574, 0x661F,0x6674,0x68F2,0x6816,0x6B63,0x6E05,0x7272,0x751F, @@ -631,7 +631,7 @@ static uint16 tab_jisx0208_uni24[]={ 0x714E,0x717D,0x65CB,0x7A7F,0x7BAD,0x7DDA}; /* page 25 0x4121-0x417E */ -static uint16 tab_jisx0208_uni25[]={ +static const uint16 tab_jisx0208_uni25[]={ 0x7E4A,0x7FA8,0x817A,0x821B,0x8239,0x85A6,0x8A6E,0x8CCE, 0x8DF5,0x9078,0x9077,0x92AD,0x9291,0x9583,0x9BAE,0x524D, 0x5584,0x6F38,0x7136,0x5168,0x7985,0x7E55,0x81B3,0x7CCE, @@ -646,7 +646,7 @@ static uint16 tab_jisx0208_uni25[]={ 0x9397,0x971C,0x9A12,0x50CF,0x5897,0x618E}; /* page 26 0x4221-0x427E */ -static uint16 tab_jisx0208_uni26[]={ +static const uint16 tab_jisx0208_uni26[]={ 0x81D3,0x8535,0x8D08,0x9020,0x4FC3,0x5074,0x5247,0x5373, 0x606F,0x6349,0x675F,0x6E2C,0x8DB3,0x901F,0x4FD7,0x5C5E, 0x8CCA,0x65CF,0x7D9A,0x5352,0x8896,0x5176,0x63C3,0x5B58, @@ -661,7 +661,7 @@ static uint16 tab_jisx0208_uni26[]={ 0x6FC1,0x8AFE,0x8338,0x51E7,0x86F8,0x53EA}; /* page 27 0x4321-0x437E */ -static uint16 tab_jisx0208_uni27[]={ +static const uint16 tab_jisx0208_uni27[]={ 0x53E9,0x4F46,0x9054,0x8FB0,0x596A,0x8131,0x5DFD,0x7AEA, 0x8FBF,0x68DA,0x8C37,0x72F8,0x9C48,0x6A3D,0x8AB0,0x4E39, 0x5358,0x5606,0x5766,0x62C5,0x63A2,0x65E6,0x6B4E,0x6DE1, @@ -676,7 +676,7 @@ static uint16 tab_jisx0208_uni27[]={ 0x8CAF,0x4E01,0x5146,0x51CB,0x558B,0x5BF5}; /* page 28 0x4421-0x447E */ -static uint16 tab_jisx0208_uni28[]={ +static const uint16 tab_jisx0208_uni28[]={ 0x5E16,0x5E33,0x5E81,0x5F14,0x5F35,0x5F6B,0x5FB4,0x61F2, 0x6311,0x66A2,0x671D,0x6F6E,0x7252,0x753A,0x773A,0x8074, 0x8139,0x8178,0x8776,0x8ABF,0x8ADC,0x8D85,0x8DF3,0x929A, @@ -691,7 +691,7 @@ static uint16 tab_jisx0208_uni28[]={ 0x7DE0,0x8247,0x8A02,0x8AE6,0x8E44,0x9013}; /* page 29 0x4521-0x457E */ -static uint16 tab_jisx0208_uni29[]={ +static const uint16 tab_jisx0208_uni29[]={ 0x90B8,0x912D,0x91D8,0x9F0E,0x6CE5,0x6458,0x64E2,0x6575, 0x6EF4,0x7684,0x7B1B,0x9069,0x93D1,0x6EBA,0x54F2,0x5FB9, 0x64A4,0x8F4D,0x8FED,0x9244,0x5178,0x586B,0x5929,0x5C55, @@ -706,7 +706,7 @@ static uint16 tab_jisx0208_uni29[]={ 0x7B49,0x7B54,0x7B52,0x7CD6,0x7D71,0x5230}; /* page 30 0x4621-0x467E */ -static uint16 tab_jisx0208_uni30[]={ +static const uint16 tab_jisx0208_uni30[]={ 0x8463,0x8569,0x85E4,0x8A0E,0x8B04,0x8C46,0x8E0F,0x9003, 0x900F,0x9419,0x9676,0x982D,0x9A30,0x95D8,0x50CD,0x52D5, 0x540C,0x5802,0x5C0E,0x61A7,0x649E,0x6D1E,0x77B3,0x7AE5, @@ -721,7 +721,7 @@ static uint16 tab_jisx0208_uni30[]={ 0x8089,0x8679,0x5EFF,0x65E5,0x4E73,0x5165}; /* page 31 0x4721-0x477E */ -static uint16 tab_jisx0208_uni31[]={ +static const uint16 tab_jisx0208_uni31[]={ 0x5982,0x5C3F,0x97EE,0x4EFB,0x598A,0x5FCD,0x8A8D,0x6FE1, 0x79B0,0x7962,0x5BE7,0x8471,0x732B,0x71B1,0x5E74,0x5FF5, 0x637B,0x649A,0x71C3,0x7C98,0x4E43,0x5EFC,0x4E4B,0x57DC, @@ -736,7 +736,7 @@ static uint16 tab_jisx0208_uni31[]={ 0x6F20,0x7206,0x7E1B,0x83AB,0x99C1,0x9EA6}; /* page 32 0x4821-0x487E */ -static uint16 tab_jisx0208_uni32[]={ +static const uint16 tab_jisx0208_uni32[]={ 0x51FD,0x7BB1,0x7872,0x7BB8,0x8087,0x7B48,0x6AE8,0x5E61, 0x808C,0x7551,0x7560,0x516B,0x9262,0x6E8C,0x767A,0x9197, 0x9AEA,0x4F10,0x7F70,0x629C,0x7B4F,0x95A5,0x9CE9,0x567A, @@ -751,7 +751,7 @@ static uint16 tab_jisx0208_uni32[]={ 0x5FAE,0x6787,0x6BD8,0x7435,0x7709,0x7F8E}; /* page 33 0x4921-0x497E */ -static uint16 tab_jisx0208_uni33[]={ +static const uint16 tab_jisx0208_uni33[]={ 0x9F3B,0x67CA,0x7A17,0x5339,0x758B,0x9AED,0x5F66,0x819D, 0x83F1,0x8098,0x5F3C,0x5FC5,0x7562,0x7B46,0x903C,0x6867, 0x59EB,0x5A9B,0x7D10,0x767E,0x8B2C,0x4FF5,0x5F6A,0x6A19, @@ -766,7 +766,7 @@ static uint16 tab_jisx0208_uni33[]={ 0x8557,0x4F0F,0x526F,0x5FA9,0x5E45,0x670D}; /* page 34 0x4A21-0x4A7E */ -static uint16 tab_jisx0208_uni34[]={ +static const uint16 tab_jisx0208_uni34[]={ 0x798F,0x8179,0x8907,0x8986,0x6DF5,0x5F17,0x6255,0x6CB8, 0x4ECF,0x7269,0x9B92,0x5206,0x543B,0x5674,0x58B3,0x61A4, 0x626E,0x711A,0x596E,0x7C89,0x7CDE,0x7D1B,0x96F0,0x6587, @@ -781,7 +781,7 @@ static uint16 tab_jisx0208_uni34[]={ 0x5E96,0x62B1,0x6367,0x653E,0x65B9,0x670B}; /* page 35 0x4B21-0x4B7E */ -static uint16 tab_jisx0208_uni35[]={ +static const uint16 tab_jisx0208_uni35[]={ 0x6CD5,0x6CE1,0x70F9,0x7832,0x7E2B,0x80DE,0x82B3,0x840C, 0x84EC,0x8702,0x8912,0x8A2A,0x8C4A,0x90A6,0x92D2,0x98FD, 0x9CF3,0x9D6C,0x4E4F,0x4EA1,0x508D,0x5256,0x574A,0x59A8, @@ -796,7 +796,7 @@ static uint16 tab_jisx0208_uni35[]={ 0x4FAD,0x7E6D,0x9EBF,0x4E07,0x6162,0x6E80}; /* page 36 0x4C21-0x4C7E */ -static uint16 tab_jisx0208_uni36[]={ +static const uint16 tab_jisx0208_uni36[]={ 0x6F2B,0x8513,0x5473,0x672A,0x9B45,0x5DF3,0x7B95,0x5CAC, 0x5BC6,0x871C,0x6E4A,0x84D1,0x7A14,0x8108,0x5999,0x7C8D, 0x6C11,0x7720,0x52D9,0x5922,0x7121,0x725F,0x77DB,0x9727, @@ -811,7 +811,7 @@ static uint16 tab_jisx0208_uni36[]={ 0x85AE,0x9453,0x6109,0x6108,0x6CB9,0x7652}; /* page 37 0x4D21-0x4D7E */ -static uint16 tab_jisx0208_uni37[]={ +static const uint16 tab_jisx0208_uni37[]={ 0x8AED,0x8F38,0x552F,0x4F51,0x512A,0x52C7,0x53CB,0x5BA5, 0x5E7D,0x60A0,0x6182,0x63D6,0x6709,0x67DA,0x6E67,0x6D8C, 0x7336,0x7337,0x7531,0x7950,0x88D5,0x8A98,0x904A,0x9091, @@ -826,7 +826,7 @@ static uint16 tab_jisx0208_uni37[]={ 0x540F,0x5C65,0x674E,0x68A8,0x7406,0x7483}; /* page 38 0x4E21-0x4E7E */ -static uint16 tab_jisx0208_uni38[]={ +static const uint16 tab_jisx0208_uni38[]={ 0x75E2,0x88CF,0x88E1,0x91CC,0x96E2,0x9678,0x5F8B,0x7387, 0x7ACB,0x844E,0x63A0,0x7565,0x5289,0x6D41,0x6E9C,0x7409, 0x7559,0x786B,0x7C92,0x9686,0x7ADC,0x9F8D,0x4FB6,0x616E, @@ -841,7 +841,7 @@ static uint16 tab_jisx0208_uni38[]={ 0x6190,0x6F23,0x7149,0x7C3E,0x7DF4,0x806F}; /* page 39 0x4F21-0x4F53 */ -static uint16 tab_jisx0208_uni39[]={ +static const uint16 tab_jisx0208_uni39[]={ 0x84EE,0x9023,0x932C,0x5442,0x9B6F,0x6AD3,0x7089,0x8CC2, 0x8DEF,0x9732,0x52B4,0x5A41,0x5ECA,0x5F04,0x6717,0x697C, 0x6994,0x6D6A,0x6F0F,0x7262,0x72FC,0x7BED,0x8001,0x807E, @@ -851,7 +851,7 @@ static uint16 tab_jisx0208_uni39[]={ 0x6E7E,0x7897,0x8155}; /* page 40 0x5021-0x507E */ -static uint16 tab_jisx0208_uni40[]={ +static const uint16 tab_jisx0208_uni40[]={ 0x5F0C,0x4E10,0x4E15,0x4E2A,0x4E31,0x4E36,0x4E3C,0x4E3F, 0x4E42,0x4E56,0x4E58,0x4E82,0x4E85,0x8C6B,0x4E8A,0x8212, 0x5F0D,0x4E8E,0x4E9E,0x4E9F,0x4EA0,0x4EA2,0x4EB0,0x4EB3, @@ -866,7 +866,7 @@ static uint16 tab_jisx0208_uni40[]={ 0x5078,0x5080,0x509A,0x5085,0x50B4,0x50B2}; /* page 41 0x5121-0x517E */ -static uint16 tab_jisx0208_uni41[]={ +static const uint16 tab_jisx0208_uni41[]={ 0x50C9,0x50CA,0x50B3,0x50C2,0x50D6,0x50DE,0x50E5,0x50ED, 0x50E3,0x50EE,0x50F9,0x50F5,0x5109,0x5101,0x5102,0x5116, 0x5115,0x5114,0x511A,0x5121,0x513A,0x5137,0x513C,0x513B, @@ -881,7 +881,7 @@ static uint16 tab_jisx0208_uni41[]={ 0x5294,0x5292,0x5271,0x5288,0x5291,0x8FA8}; /* page 42 0x5221-0x527E */ -static uint16 tab_jisx0208_uni42[]={ +static const uint16 tab_jisx0208_uni42[]={ 0x8FA7,0x52AC,0x52AD,0x52BC,0x52B5,0x52C1,0x52CD,0x52D7, 0x52DE,0x52E3,0x52E6,0x98ED,0x52E0,0x52F3,0x52F5,0x52F8, 0x52F9,0x5306,0x5308,0x7538,0x530D,0x5310,0x530F,0x5315, @@ -896,7 +896,7 @@ static uint16 tab_jisx0208_uni42[]={ 0x54B8,0x54A5,0x54AC,0x54C4,0x54C8,0x54A8}; /* page 43 0x5321-0x537E */ -static uint16 tab_jisx0208_uni43[]={ +static const uint16 tab_jisx0208_uni43[]={ 0x54AB,0x54C2,0x54A4,0x54BE,0x54BC,0x54D8,0x54E5,0x54E6, 0x550F,0x5514,0x54FD,0x54EE,0x54ED,0x54FA,0x54E2,0x5539, 0x5540,0x5563,0x554C,0x552E,0x555C,0x5545,0x5556,0x5557, @@ -911,7 +911,7 @@ static uint16 tab_jisx0208_uni43[]={ 0x56EE,0x56F9,0x5700,0x56FF,0x5704,0x5709}; /* page 44 0x5421-0x547E */ -static uint16 tab_jisx0208_uni44[]={ +static const uint16 tab_jisx0208_uni44[]={ 0x5708,0x570B,0x570D,0x5713,0x5718,0x5716,0x55C7,0x571C, 0x5726,0x5737,0x5738,0x574E,0x573B,0x5740,0x574F,0x5769, 0x57C0,0x5788,0x5761,0x577F,0x5789,0x5793,0x57A0,0x57B3, @@ -926,7 +926,7 @@ static uint16 tab_jisx0208_uni44[]={ 0x5958,0x5962,0x5960,0x5967,0x596C,0x5969}; /* page 45 0x5521-0x557E */ -static uint16 tab_jisx0208_uni45[]={ +static const uint16 tab_jisx0208_uni45[]={ 0x5978,0x5981,0x599D,0x4F5E,0x4FAB,0x59A3,0x59B2,0x59C6, 0x59E8,0x59DC,0x598D,0x59D9,0x59DA,0x5A25,0x5A1F,0x5A11, 0x5A1C,0x5A09,0x5A1A,0x5A40,0x5A6C,0x5A49,0x5A35,0x5A36, @@ -941,7 +941,7 @@ static uint16 tab_jisx0208_uni45[]={ 0x5C38,0x5C39,0x5C41,0x5C46,0x5C4E,0x5C53}; /* page 46 0x5621-0x567E */ -static uint16 tab_jisx0208_uni46[]={ +static const uint16 tab_jisx0208_uni46[]={ 0x5C50,0x5C4F,0x5B71,0x5C6C,0x5C6E,0x4E62,0x5C76,0x5C79, 0x5C8C,0x5C91,0x5C94,0x599B,0x5CAB,0x5CBB,0x5CB6,0x5CBC, 0x5CB7,0x5CC5,0x5CBE,0x5CC7,0x5CD9,0x5CE9,0x5CFD,0x5CFA, @@ -956,7 +956,7 @@ static uint16 tab_jisx0208_uni46[]={ 0x5EA0,0x5EC1,0x5EC2,0x5EC8,0x5ED0,0x5ECF}; /* page 47 0x5721-0x577E */ -static uint16 tab_jisx0208_uni47[]={ +static const uint16 tab_jisx0208_uni47[]={ 0x5ED6,0x5EE3,0x5EDD,0x5EDA,0x5EDB,0x5EE2,0x5EE1,0x5EE8, 0x5EE9,0x5EEC,0x5EF1,0x5EF3,0x5EF0,0x5EF4,0x5EF8,0x5EFE, 0x5F03,0x5F09,0x5F5D,0x5F5C,0x5F0B,0x5F11,0x5F16,0x5F29, @@ -971,7 +971,7 @@ static uint16 tab_jisx0208_uni47[]={ 0x6059,0x6081,0x608D,0x60E7,0x6083,0x609A}; /* page 48 0x5821-0x587E */ -static uint16 tab_jisx0208_uni48[]={ +static const uint16 tab_jisx0208_uni48[]={ 0x6084,0x609B,0x6096,0x6097,0x6092,0x60A7,0x608B,0x60E1, 0x60B8,0x60E0,0x60D3,0x60B4,0x5FF0,0x60BD,0x60C6,0x60B5, 0x60D8,0x614D,0x6115,0x6106,0x60F6,0x60F7,0x6100,0x60F4, @@ -986,7 +986,7 @@ static uint16 tab_jisx0208_uni48[]={ 0x6208,0x6209,0x620D,0x620C,0x6214,0x621B}; /* page 49 0x5921-0x597E */ -static uint16 tab_jisx0208_uni49[]={ +static const uint16 tab_jisx0208_uni49[]={ 0x621E,0x6221,0x622A,0x622E,0x6230,0x6232,0x6233,0x6241, 0x624E,0x625E,0x6263,0x625B,0x6260,0x6268,0x627C,0x6282, 0x6289,0x627E,0x6292,0x6293,0x6296,0x62D4,0x6283,0x6294, @@ -1001,7 +1001,7 @@ static uint16 tab_jisx0208_uni49[]={ 0x6495,0x6493,0x64A5,0x64A9,0x6488,0x64BC}; /* page 50 0x5A21-0x5A7E */ -static uint16 tab_jisx0208_uni50[]={ +static const uint16 tab_jisx0208_uni50[]={ 0x64DA,0x64D2,0x64C5,0x64C7,0x64BB,0x64D8,0x64C2,0x64F1, 0x64E7,0x8209,0x64E0,0x64E1,0x62AC,0x64E3,0x64EF,0x652C, 0x64F6,0x64F4,0x64F2,0x64FA,0x6500,0x64FD,0x6518,0x651C, @@ -1016,7 +1016,7 @@ static uint16 tab_jisx0208_uni50[]={ 0x669D,0x66C1,0x66B9,0x66C9,0x66BE,0x66BC}; /* page 51 0x5B21-0x5B7E */ -static uint16 tab_jisx0208_uni51[]={ +static const uint16 tab_jisx0208_uni51[]={ 0x66C4,0x66B8,0x66D6,0x66DA,0x66E0,0x663F,0x66E6,0x66E9, 0x66F0,0x66F5,0x66F7,0x670F,0x6716,0x671E,0x6726,0x6727, 0x9738,0x672E,0x673F,0x6736,0x6741,0x6738,0x6737,0x6746, @@ -1031,7 +1031,7 @@ static uint16 tab_jisx0208_uni51[]={ 0x68D8,0x6922,0x6926,0x68E1,0x690C,0x68CD}; /* page 52 0x5C21-0x5C7E */ -static uint16 tab_jisx0208_uni52[]={ +static const uint16 tab_jisx0208_uni52[]={ 0x68D4,0x68E7,0x68D5,0x6936,0x6912,0x6904,0x68D7,0x68E3, 0x6925,0x68F9,0x68E0,0x68EF,0x6928,0x692A,0x691A,0x6923, 0x6921,0x68C6,0x6979,0x6977,0x695C,0x6978,0x696B,0x6954, @@ -1046,7 +1046,7 @@ static uint16 tab_jisx0208_uni52[]={ 0x6A90,0x6A8D,0x6AA0,0x6A84,0x6AA2,0x6AA3}; /* page 53 0x5D21-0x5D7E */ -static uint16 tab_jisx0208_uni53[]={ +static const uint16 tab_jisx0208_uni53[]={ 0x6A97,0x8617,0x6ABB,0x6AC3,0x6AC2,0x6AB8,0x6AB3,0x6AAC, 0x6ADE,0x6AD1,0x6ADF,0x6AAA,0x6ADA,0x6AEA,0x6AFB,0x6B05, 0x8616,0x6AFA,0x6B12,0x6B16,0x9B31,0x6B1F,0x6B38,0x6B37, @@ -1061,7 +1061,7 @@ static uint16 tab_jisx0208_uni53[]={ 0x6CD7,0x6CC5,0x6CDD,0x6CAE,0x6CB1,0x6CBE}; /* page 54 0x5E21-0x5E7E */ -static uint16 tab_jisx0208_uni54[]={ +static const uint16 tab_jisx0208_uni54[]={ 0x6CBA,0x6CDB,0x6CEF,0x6CD9,0x6CEA,0x6D1F,0x884D,0x6D36, 0x6D2B,0x6D3D,0x6D38,0x6D19,0x6D35,0x6D33,0x6D12,0x6D0C, 0x6D63,0x6D93,0x6D64,0x6D5A,0x6D79,0x6D59,0x6D8E,0x6D95, @@ -1076,7 +1076,7 @@ static uint16 tab_jisx0208_uni54[]={ 0x6F3F,0x6EF2,0x6F31,0x6EEF,0x6F32,0x6ECC}; /* page 55 0x5F21-0x5F7E */ -static uint16 tab_jisx0208_uni55[]={ +static const uint16 tab_jisx0208_uni55[]={ 0x6F3E,0x6F13,0x6EF7,0x6F86,0x6F7A,0x6F78,0x6F81,0x6F80, 0x6F6F,0x6F5B,0x6FF3,0x6F6D,0x6F82,0x6F7C,0x6F58,0x6F8E, 0x6F91,0x6FC2,0x6F66,0x6FB3,0x6FA3,0x6FA1,0x6FA4,0x6FB9, @@ -1091,7 +1091,7 @@ static uint16 tab_jisx0208_uni55[]={ 0x71CE,0x71E0,0x71EC,0x71E7,0x71F5,0x71FC}; /* page 56 0x6021-0x607E */ -static uint16 tab_jisx0208_uni56[]={ +static const uint16 tab_jisx0208_uni56[]={ 0x71F9,0x71FF,0x720D,0x7210,0x721B,0x7228,0x722D,0x722C, 0x7230,0x7232,0x723B,0x723C,0x723F,0x7240,0x7246,0x724B, 0x7258,0x7274,0x727E,0x7282,0x7281,0x7287,0x7292,0x7296, @@ -1106,7 +1106,7 @@ static uint16 tab_jisx0208_uni56[]={ 0x749E,0x74A7,0x74CA,0x74CF,0x74D4,0x73F1}; /* page 57 0x6121-0x617E */ -static uint16 tab_jisx0208_uni57[]={ +static const uint16 tab_jisx0208_uni57[]={ 0x74E0,0x74E3,0x74E7,0x74E9,0x74EE,0x74F2,0x74F0,0x74F1, 0x74F8,0x74F7,0x7504,0x7503,0x7505,0x750C,0x750E,0x750D, 0x7515,0x7513,0x751E,0x7526,0x752C,0x753C,0x7544,0x754D, @@ -1121,7 +1121,7 @@ static uint16 tab_jisx0208_uni57[]={ 0x7668,0x7669,0x766A,0x7667,0x766C,0x7670}; /* page 58 0x6221-0x627E */ -static uint16 tab_jisx0208_uni58[]={ +static const uint16 tab_jisx0208_uni58[]={ 0x7672,0x7676,0x7678,0x767C,0x7680,0x7683,0x7688,0x768B, 0x768E,0x7696,0x7693,0x7699,0x769A,0x76B0,0x76B4,0x76B8, 0x76B9,0x76BA,0x76C2,0x76CD,0x76D6,0x76D2,0x76DE,0x76E1, @@ -1136,7 +1136,7 @@ static uint16 tab_jisx0208_uni58[]={ 0x78D4,0x78BE,0x78BC,0x78C5,0x78CA,0x78EC}; /* page 59 0x6321-0x637E */ -static uint16 tab_jisx0208_uni59[]={ +static const uint16 tab_jisx0208_uni59[]={ 0x78E7,0x78DA,0x78FD,0x78F4,0x7907,0x7912,0x7911,0x7919, 0x792C,0x792B,0x7940,0x7960,0x7957,0x795F,0x795A,0x7955, 0x7953,0x797A,0x797F,0x798A,0x799D,0x79A7,0x9F4B,0x79AA, @@ -1151,7 +1151,7 @@ static uint16 tab_jisx0208_uni59[]={ 0x7B19,0x7B1E,0x7B35,0x7B28,0x7B36,0x7B50}; /* page 60 0x6421-0x647E */ -static uint16 tab_jisx0208_uni60[]={ +static const uint16 tab_jisx0208_uni60[]={ 0x7B7A,0x7B04,0x7B4D,0x7B0B,0x7B4C,0x7B45,0x7B75,0x7B65, 0x7B74,0x7B67,0x7B70,0x7B71,0x7B6C,0x7B6E,0x7B9D,0x7B98, 0x7B9F,0x7B8D,0x7B9C,0x7B9A,0x7B8B,0x7B92,0x7B8F,0x7B5D, @@ -1166,7 +1166,7 @@ static uint16 tab_jisx0208_uni60[]={ 0x7CEF,0x7CF2,0x7CF4,0x7CF6,0x7CFA,0x7D06}; /* page 61 0x6521-0x657E */ -static uint16 tab_jisx0208_uni61[]={ +static const uint16 tab_jisx0208_uni61[]={ 0x7D02,0x7D1C,0x7D15,0x7D0A,0x7D45,0x7D4B,0x7D2E,0x7D32, 0x7D3F,0x7D35,0x7D46,0x7D73,0x7D56,0x7D4E,0x7D72,0x7D68, 0x7D6E,0x7D4F,0x7D63,0x7D93,0x7D89,0x7D5B,0x7D8F,0x7D7D, @@ -1181,7 +1181,7 @@ static uint16 tab_jisx0208_uni61[]={ 0x7E96,0x7E8E,0x7E9B,0x7E9C,0x7F38,0x7F3A}; /* page 62 0x6621-0x667E */ -static uint16 tab_jisx0208_uni62[]={ +static const uint16 tab_jisx0208_uni62[]={ 0x7F45,0x7F4C,0x7F4D,0x7F4E,0x7F50,0x7F51,0x7F55,0x7F54, 0x7F58,0x7F5F,0x7F60,0x7F68,0x7F69,0x7F67,0x7F78,0x7F82, 0x7F86,0x7F83,0x7F88,0x7F87,0x7F8C,0x7F94,0x7F9E,0x7F9D, @@ -1196,7 +1196,7 @@ static uint16 tab_jisx0208_uni62[]={ 0x80F1,0x811B,0x8129,0x8123,0x812F,0x814B}; /* page 63 0x6721-0x677E */ -static uint16 tab_jisx0208_uni63[]={ +static const uint16 tab_jisx0208_uni63[]={ 0x968B,0x8146,0x813E,0x8153,0x8151,0x80FC,0x8171,0x816E, 0x8165,0x8166,0x8174,0x8183,0x8188,0x818A,0x8180,0x8182, 0x81A0,0x8195,0x81A4,0x81A3,0x815F,0x8193,0x81A9,0x81B0, @@ -1211,7 +1211,7 @@ static uint16 tab_jisx0208_uni63[]={ 0x82F9,0x82DE,0x8306,0x82DC,0x8309,0x82D9}; /* page 64 0x6821-0x687E */ -static uint16 tab_jisx0208_uni64[]={ +static const uint16 tab_jisx0208_uni64[]={ 0x8335,0x8334,0x8316,0x8332,0x8331,0x8340,0x8339,0x8350, 0x8345,0x832F,0x832B,0x8317,0x8318,0x8385,0x839A,0x83AA, 0x839F,0x83A2,0x8396,0x8323,0x838E,0x8387,0x838A,0x837C, @@ -1226,7 +1226,7 @@ static uint16 tab_jisx0208_uni64[]={ 0x8514,0x84FC,0x8540,0x8563,0x8558,0x8548}; /* page 65 0x6921-0x697E */ -static uint16 tab_jisx0208_uni65[]={ +static const uint16 tab_jisx0208_uni65[]={ 0x8541,0x8602,0x854B,0x8555,0x8580,0x85A4,0x8588,0x8591, 0x858A,0x85A8,0x856D,0x8594,0x859B,0x85EA,0x8587,0x859C, 0x8577,0x857E,0x8590,0x85C9,0x85BA,0x85CF,0x85B9,0x85D0, @@ -1241,7 +1241,7 @@ static uint16 tab_jisx0208_uni65[]={ 0x874E,0x8774,0x8757,0x8768,0x876E,0x8759}; /* page 66 0x6A21-0x6A7E */ -static uint16 tab_jisx0208_uni66[]={ +static const uint16 tab_jisx0208_uni66[]={ 0x8753,0x8763,0x876A,0x8805,0x87A2,0x879F,0x8782,0x87AF, 0x87CB,0x87BD,0x87C0,0x87D0,0x96D6,0x87AB,0x87C4,0x87B3, 0x87C7,0x87C6,0x87BB,0x87EF,0x87F2,0x87E0,0x880F,0x880D, @@ -1256,7 +1256,7 @@ static uint16 tab_jisx0208_uni66[]={ 0x8936,0x8938,0x894C,0x891D,0x8960,0x895E}; /* page 67 0x6B21-0x6B7E */ -static uint16 tab_jisx0208_uni67[]={ +static const uint16 tab_jisx0208_uni67[]={ 0x8966,0x8964,0x896D,0x896A,0x896F,0x8974,0x8977,0x897E, 0x8983,0x8988,0x898A,0x8993,0x8998,0x89A1,0x89A9,0x89A6, 0x89AC,0x89AF,0x89B2,0x89BA,0x89BD,0x89BF,0x89C0,0x89DA, @@ -1271,7 +1271,7 @@ static uint16 tab_jisx0208_uni67[]={ 0x8B4E,0x8B49,0x8B56,0x8B5B,0x8B5A,0x8B6B}; /* page 68 0x6C21-0x6C7E */ -static uint16 tab_jisx0208_uni68[]={ +static const uint16 tab_jisx0208_uni68[]={ 0x8B5F,0x8B6C,0x8B6F,0x8B74,0x8B7D,0x8B80,0x8B8C,0x8B8E, 0x8B92,0x8B93,0x8B96,0x8B99,0x8B9A,0x8C3A,0x8C41,0x8C3F, 0x8C48,0x8C4C,0x8C4E,0x8C50,0x8C55,0x8C62,0x8C6C,0x8C78, @@ -1286,7 +1286,7 @@ static uint16 tab_jisx0208_uni68[]={ 0x8E1F,0x8E42,0x8E35,0x8E30,0x8E34,0x8E4A}; /* page 69 0x6D21-0x6D7E */ -static uint16 tab_jisx0208_uni69[]={ +static const uint16 tab_jisx0208_uni69[]={ 0x8E47,0x8E49,0x8E4C,0x8E50,0x8E48,0x8E59,0x8E64,0x8E60, 0x8E2A,0x8E63,0x8E55,0x8E76,0x8E72,0x8E7C,0x8E81,0x8E87, 0x8E85,0x8E84,0x8E8B,0x8E8A,0x8E93,0x8E91,0x8E94,0x8E99, @@ -1301,7 +1301,7 @@ static uint16 tab_jisx0208_uni69[]={ 0x900B,0x9027,0x9036,0x9035,0x9039,0x8FF8}; /* page 70 0x6E21-0x6E7E */ -static uint16 tab_jisx0208_uni70[]={ +static const uint16 tab_jisx0208_uni70[]={ 0x904F,0x9050,0x9051,0x9052,0x900E,0x9049,0x903E,0x9056, 0x9058,0x905E,0x9068,0x906F,0x9076,0x96A8,0x9072,0x9082, 0x907D,0x9081,0x9080,0x908A,0x9089,0x908F,0x90A8,0x90AF, @@ -1316,7 +1316,7 @@ static uint16 tab_jisx0208_uni70[]={ 0x92B7,0x92E9,0x930F,0x92FA,0x9344,0x932E}; /* page 71 0x6F21-0x6F7E */ -static uint16 tab_jisx0208_uni71[]={ +static const uint16 tab_jisx0208_uni71[]={ 0x9319,0x9322,0x931A,0x9323,0x933A,0x9335,0x933B,0x935C, 0x9360,0x937C,0x936E,0x9356,0x93B0,0x93AC,0x93AD,0x9394, 0x93B9,0x93D6,0x93D7,0x93E8,0x93E5,0x93D8,0x93C3,0x93DD, @@ -1331,7 +1331,7 @@ static uint16 tab_jisx0208_uni71[]={ 0x964C,0x964F,0x964B,0x9677,0x965C,0x965E}; /* page 72 0x7021-0x707E */ -static uint16 tab_jisx0208_uni72[]={ +static const uint16 tab_jisx0208_uni72[]={ 0x965D,0x965F,0x9666,0x9672,0x966C,0x968D,0x9698,0x9695, 0x9697,0x96AA,0x96A7,0x96B1,0x96B2,0x96B0,0x96B4,0x96B6, 0x96B8,0x96B9,0x96CE,0x96CB,0x96C9,0x96CD,0x894D,0x96DC, @@ -1346,7 +1346,7 @@ static uint16 tab_jisx0208_uni72[]={ 0x9846,0x984F,0x984B,0x986B,0x986F,0x9870}; /* page 73 0x7121-0x717E */ -static uint16 tab_jisx0208_uni73[]={ +static const uint16 tab_jisx0208_uni73[]={ 0x9871,0x9874,0x9873,0x98AA,0x98AF,0x98B1,0x98B6,0x98C4, 0x98C3,0x98C6,0x98E9,0x98EB,0x9903,0x9909,0x9912,0x9914, 0x9918,0x9921,0x991D,0x991E,0x9924,0x9920,0x992C,0x992E, @@ -1361,7 +1361,7 @@ static uint16 tab_jisx0208_uni73[]={ 0x9AEF,0x9AEB,0x9AEE,0x9AF4,0x9AF1,0x9AF7}; /* page 74 0x7221-0x727E */ -static uint16 tab_jisx0208_uni74[]={ +static const uint16 tab_jisx0208_uni74[]={ 0x9AFB,0x9B06,0x9B18,0x9B1A,0x9B1F,0x9B22,0x9B23,0x9B25, 0x9B27,0x9B28,0x9B29,0x9B2A,0x9B2E,0x9B2F,0x9B32,0x9B44, 0x9B43,0x9B4F,0x9B4D,0x9B4E,0x9B51,0x9B58,0x9B74,0x9B93, @@ -1376,7 +1376,7 @@ static uint16 tab_jisx0208_uni74[]={ 0x9D12,0x9D41,0x9D3F,0x9D3E,0x9D46,0x9D48}; /* page 75 0x7321-0x737E */ -static uint16 tab_jisx0208_uni75[]={ +static const uint16 tab_jisx0208_uni75[]={ 0x9D5D,0x9D5E,0x9D64,0x9D51,0x9D50,0x9D59,0x9D72,0x9D89, 0x9D87,0x9DAB,0x9D6F,0x9D7A,0x9D9A,0x9DA4,0x9DA9,0x9DB2, 0x9DC4,0x9DC1,0x9DBB,0x9DB8,0x9DBA,0x9DC6,0x9DCF,0x9DC2, @@ -1391,11 +1391,11 @@ static uint16 tab_jisx0208_uni75[]={ 0x9F77,0x9F72,0x9F76,0x9F95,0x9F9C,0x9FA0}; /* page 76 0x7421-0x7426 */ -static uint16 tab_jisx0208_uni76[]={ +static const uint16 tab_jisx0208_uni76[]={ 0x582F,0x69C7,0x9059,0x7464,0x51DC,0x7199}; /* page 77 0x2D21 - 0x2D7C */ -static uint16 tab_nec13_uni0[]={ +static const uint16 tab_nec13_uni0[]={ 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467, 0x2468,0x2469,0x246A,0x246B,0x246C,0x246D,0x246E,0x246F, 0x2470,0x2471,0x2472,0x2473,0x2160,0x2161,0x2162,0x2163, @@ -1571,25 +1571,25 @@ my_jisx0208_uni_onechar(int code){ } /* page 0 0x005C-0x005C */ -static uint16 tab_uni_jisx02080[]={ +static const uint16 tab_uni_jisx02080[]={ 0x5C}; /* page 1 0x00A2-0x00B6 */ -static uint16 tab_uni_jisx02081[]={ +static const uint16 tab_uni_jisx02081[]={ 0, 0, 0, 0, 0,0x2178,0x212F, 0, 0, 0, 0, 0, 0, 0,0x216B,0x215E, 0, 0,0x212D, 0,0x2279}; /* page 2 0x00D7-0x00D7 */ -static uint16 tab_uni_jisx02082[]={ +static const uint16 tab_uni_jisx02082[]={ 0x215F}; /* page 3 0x00F7-0x00F7 */ -static uint16 tab_uni_jisx02083[]={ +static const uint16 tab_uni_jisx02083[]={ 0x2160}; /* page 4 0x0391-0x03C9 */ -static uint16 tab_uni_jisx02084[]={ +static const uint16 tab_uni_jisx02084[]={ 0x2621,0x2622,0x2623,0x2624,0x2625,0x2626,0x2627,0x2628, 0x2629,0x262A,0x262B,0x262C,0x262D,0x262E,0x262F,0x2630, 0x2631, 0,0x2632,0x2633,0x2634,0x2635,0x2636,0x2637, @@ -1600,7 +1600,7 @@ static uint16 tab_uni_jisx02084[]={ 0x2658}; /* page 5 0x0401-0x0451 */ -static uint16 tab_uni_jisx02085[]={ +static const uint16 tab_uni_jisx02085[]={ 0x2727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2721, 0x2722,0x2723,0x2724,0x2725,0x2726,0x2728,0x2729,0x272A, @@ -1614,7 +1614,7 @@ static uint16 tab_uni_jisx02085[]={ 0x2757}; /* page 6 0x2010-0x203B */ -static uint16 tab_uni_jisx02086[]={ +static const uint16 tab_uni_jisx02086[]={ 0x213E, 0, 0, 0, 0,0x213D, 0, 0, 0x2146,0x2147, 0, 0,0x2148,0x2149, 0, 0, 0x2277,0x2278, 0, 0, 0,0x2145,0x2144, 0, @@ -1623,31 +1623,31 @@ static uint16 tab_uni_jisx02086[]={ 0, 0, 0,0x2228}; /* page 7 0x2100-0x2116 */ -static uint16 tab_uni_jisx02087[]={ +static const uint16 tab_uni_jisx02087[]={ 0, 0, 0,0x216E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2D62}; /* page 8 0x2120-0x212B */ -static uint16 tab_uni_jisx02088[]={ +static const uint16 tab_uni_jisx02088[]={ 0,0x2D64, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2272}; /* page 9 0x2160-0x2169 */ -static uint16 tab_uni_jisx02089[]={ +static const uint16 tab_uni_jisx02089[]={ 0x2D35,0x2D36,0x2D37,0x2D38,0x2D39,0x2D3A,0x2D3B,0x2D3C, 0x2D3D,0x2D3E}; /* page 10 0x2190-0x2193 */ -static uint16 tab_uni_jisx020810[]={ +static const uint16 tab_uni_jisx020810[]={ 0x222B,0x222C,0x222A,0x222D}; /* page 11 0x21D2-0x21D4 */ -static uint16 tab_uni_jisx020811[]={ +static const uint16 tab_uni_jisx020811[]={ 0x224D, 0,0x224E}; /* page 12 0x2200-0x223D */ -static uint16 tab_uni_jisx020812[]={ +static const uint16 tab_uni_jisx020812[]={ 0x224F, 0,0x225F,0x2250, 0, 0, 0,0x2260, 0x223A, 0, 0,0x223B, 0, 0, 0, 0, 0,0x2D74, 0, 0, 0, 0, 0, 0, @@ -1658,35 +1658,35 @@ static uint16 tab_uni_jisx020812[]={ 0, 0, 0, 0, 0,0x2266}; /* page 13 0x2252-0x226B */ -static uint16 tab_uni_jisx020813[]={ +static const uint16 tab_uni_jisx020813[]={ 0x2262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2162,0x2261, 0, 0, 0, 0,0x2165,0x2166, 0, 0, 0x2263,0x2264}; /* page 14 0x2282-0x2287 */ -static uint16 tab_uni_jisx020814[]={ +static const uint16 tab_uni_jisx020814[]={ 0x223E,0x223F, 0, 0,0x223C,0x223D}; /* page 15 0x22A0-0x22BF */ -static uint16 tab_uni_jisx020815[]={ +static const uint16 tab_uni_jisx020815[]={ 0, 0, 0, 0, 0,0x225D, 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,0x2D79}; /* page 16 0x2312-0x2312 */ -static uint16 tab_uni_jisx020816[]={ +static const uint16 tab_uni_jisx020816[]={ 0x225E}; /* page 17 0x2460-0x2473 */ -static uint16 tab_uni_jisx020817[]={ +static const uint16 tab_uni_jisx020817[]={ 0x2D21,0x2D22,0x2D23,0x2D24,0x2D25,0x2D26,0x2D27,0x2D28, 0x2D29,0x2D2A,0x2D2B,0x2D2C,0x2D2D,0x2D2E,0x2D2F,0x2D30, 0x2D31,0x2D32,0x2D33,0x2D34}; /* page 18 0x2500-0x254B */ -static uint16 tab_uni_jisx020818[]={ +static const uint16 tab_uni_jisx020818[]={ 0x2821,0x282C,0x2822,0x282D, 0, 0, 0, 0, 0, 0, 0, 0,0x2823, 0, 0,0x282E, 0x2824, 0, 0,0x282F,0x2826, 0, 0,0x2831, @@ -1699,7 +1699,7 @@ static uint16 tab_uni_jisx020818[]={ 0, 0, 0,0x2836}; /* page 19 0x25A0-0x25CF */ -static uint16 tab_uni_jisx020819[]={ +static const uint16 tab_uni_jisx020819[]={ 0x2223,0x2222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2225,0x2224, 0, 0, 0, 0, @@ -1709,30 +1709,30 @@ static uint16 tab_uni_jisx020819[]={ }; /* page 20 0x25EF-0x25EF */ -static uint16 tab_uni_jisx020820[]={ +static const uint16 tab_uni_jisx020820[]={ 0x227E}; /* page 21 0x2605-0x2606 */ -static uint16 tab_uni_jisx020821[]={ +static const uint16 tab_uni_jisx020821[]={ 0x217A,0x2179}; /* page 22 0x2640-0x2642 */ -static uint16 tab_uni_jisx020822[]={ +static const uint16 tab_uni_jisx020822[]={ 0x216A, 0,0x2169}; /* page 23 0x266A-0x266F */ -static uint16 tab_uni_jisx020823[]={ +static const uint16 tab_uni_jisx020823[]={ 0x2276, 0, 0,0x2275, 0,0x2274}; /* page 24 0x3000-0x301F */ -static uint16 tab_uni_jisx020824[]={ +static const uint16 tab_uni_jisx020824[]={ 0x2121,0x2122,0x2123,0x2137, 0,0x2139,0x213A,0x213B, 0x2152,0x2153,0x2154,0x2155,0x2156,0x2157,0x2158,0x2159, 0x215A,0x215B,0x2229,0x222E,0x214C,0x214D, 0, 0, 0, 0, 0, 0, 0,0x2D60, 0,0x2D61}; /* page 25 0x3041-0x30FE */ -static uint16 tab_uni_jisx020825[]={ +static const uint16 tab_uni_jisx020825[]={ 0x2421,0x2422,0x2423,0x2424,0x2425,0x2426,0x2427,0x2428, 0x2429,0x242A,0x242B,0x242C,0x242D,0x242E,0x242F,0x2430, 0x2431,0x2432,0x2433,0x2434,0x2435,0x2436,0x2437,0x2438, @@ -1759,17 +1759,17 @@ static uint16 tab_uni_jisx020825[]={ 0, 0,0x2126,0x213C,0x2133,0x2134}; /* page 26 0x3230-0x3239 */ -static uint16 tab_uni_jisx020826[]={ +static const uint16 tab_uni_jisx020826[]={ 0,0x2D6A,0x2D6B, 0, 0, 0, 0, 0, 0,0x2D6C}; /* page 27 0x32A0-0x32A8 */ -static uint16 tab_uni_jisx020827[]={ +static const uint16 tab_uni_jisx020827[]={ 0, 0, 0, 0,0x2D65,0x2D66,0x2D67,0x2D68, 0x2D69}; /* page 28 0x3300-0x33CD */ -static uint16 tab_uni_jisx020828[]={ +static const uint16 tab_uni_jisx020828[]={ 0, 0, 0,0x2D46, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2D4A, 0, 0, 0, 0, 0, 0,0x2D41, 0, 0, 0, @@ -1798,7 +1798,7 @@ static uint16 tab_uni_jisx020828[]={ 0, 0, 0, 0, 0,0x2D63}; /* page 29 0x4E00-0x5516 */ -static uint16 tab_uni_jisx020829[]={ +static const uint16 tab_uni_jisx020829[]={ 0x306C,0x437A, 0,0x3C37, 0, 0, 0,0x4B7C, 0x3E66,0x3B30,0x3E65,0x323C, 0,0x4954,0x4D3F, 0, 0x5022,0x312F, 0, 0,0x336E,0x5023,0x4024,0x5242, @@ -2028,7 +2028,7 @@ static uint16 tab_uni_jisx020829[]={ 0x4562, 0, 0, 0,0x532A, 0,0x3022}; /* page 30 0x552E-0x5563 */ -static uint16 tab_uni_jisx020830[]={ +static const uint16 tab_uni_jisx020830[]={ 0x5334,0x4D23, 0,0x3E27, 0,0x533A, 0, 0, 0, 0,0x5339,0x5330, 0, 0, 0, 0, 0x4243, 0,0x5331, 0, 0, 0,0x426F,0x5336, @@ -2038,7 +2038,7 @@ static uint16 tab_uni_jisx020830[]={ 0, 0, 0, 0, 0,0x5332}; /* page 31 0x557B-0x576A */ -static uint16 tab_uni_jisx020831[]={ +static const uint16 tab_uni_jisx020831[]={ 0x5341,0x5346, 0,0x5342, 0,0x533D, 0, 0, 0x5347,0x4131, 0, 0,0x5349, 0,0x3922,0x533F, 0x437D, 0, 0, 0, 0, 0, 0, 0, @@ -2104,7 +2104,7 @@ static uint16 tab_uni_jisx020831[]={ }; /* page 32 0x577F-0x5A9B */ -static uint16 tab_uni_jisx020832[]={ +static const uint16 tab_uni_jisx020832[]={ 0x5434, 0, 0,0x3F62, 0, 0, 0, 0, 0,0x5432,0x5435, 0,0x373F, 0, 0, 0, 0, 0, 0, 0,0x5436, 0, 0, 0, @@ -2207,7 +2207,7 @@ static uint16 tab_uni_jisx020832[]={ 0, 0, 0,0x553B,0x4932}; /* page 33 0x5ABC-0x5D29 */ -static uint16 tab_uni_jisx020833[]={ +static const uint16 tab_uni_jisx020833[]={ 0x553C,0x5540,0x553D, 0, 0,0x3247,0x553F, 0, 0, 0, 0, 0, 0,0x3C3B, 0,0x553E, 0x3779, 0, 0, 0,0x554C, 0, 0, 0, @@ -2288,7 +2288,7 @@ static uint16 tab_uni_jisx020833[]={ 0, 0, 0, 0, 0,0x4A78}; /* page 34 0x5D4B-0x6BF3 */ -static uint16 tab_uni_jisx020834[]={ +static const uint16 tab_uni_jisx020834[]={ 0x564B,0x5648, 0,0x564A, 0,0x4D72, 0,0x5649, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x563F, 0, 0, 0, 0, 0, 0, @@ -2761,7 +2761,7 @@ static uint16 tab_uni_jisx020834[]={ 0x5D5E}; /* page 35 0x6C08-0x6CF3 */ -static uint16 tab_uni_jisx020835[]={ +static const uint16 tab_uni_jisx020835[]={ 0x5D61, 0, 0, 0, 0, 0, 0,0x3B61, 0,0x4C31, 0,0x5D62,0x5D63, 0, 0,0x3524, 0, 0, 0,0x5D64, 0, 0, 0, 0, @@ -2794,7 +2794,7 @@ static uint16 tab_uni_jisx020835[]={ 0x4259,0x5D76, 0,0x314B}; /* page 36 0x6D0B-0x7409 */ -static uint16 tab_uni_jisx020836[]={ +static const uint16 tab_uni_jisx020836[]={ 0x4D4E,0x5E30, 0, 0, 0, 0, 0,0x5E2F, 0, 0, 0, 0,0x4076, 0,0x5E2C, 0, 0x4D6C, 0, 0,0x4636,0x5E26, 0, 0, 0, @@ -3021,7 +3021,7 @@ static uint16 tab_uni_jisx020836[]={ 0x3565, 0,0x6066,0x4D7D, 0, 0,0x4E30}; /* page 37 0x7422-0x7845 */ -static uint16 tab_uni_jisx020837[]={ +static const uint16 tab_uni_jisx020837[]={ 0x4276, 0, 0,0x6068, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x606A,0x4E56,0x3657,0x487C,0x474A, 0, 0, 0, @@ -3157,7 +3157,7 @@ static uint16 tab_uni_jisx020837[]={ 0, 0, 0,0x626B}; /* page 38 0x785D-0x7E9C */ -static uint16 tab_uni_jisx020838[]={ +static const uint16 tab_uni_jisx020838[]={ 0x3E4B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x4E32,0x3945, 0, 0,0x3827, 0, 0,0x4823, 0,0x626D, @@ -3361,7 +3361,7 @@ static uint16 tab_uni_jisx020838[]={ }; /* page 39 0x7F36-0x8358 */ -static uint16 tab_uni_jisx020839[]={ +static const uint16 tab_uni_jisx020839[]={ 0x344C, 0,0x657D, 0,0x657E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x6621, 0, 0, 0, 0, 0, 0,0x6622,0x6623, @@ -3497,7 +3497,7 @@ static uint16 tab_uni_jisx020839[]={ 0, 0,0x4171}; /* page 40 0x8373-0x8B9A */ -static uint16 tab_uni_jisx020840[]={ +static const uint16 tab_uni_jisx020840[]={ 0x683A, 0,0x683B, 0,0x3259, 0, 0, 0, 0x322E,0x6838, 0, 0, 0, 0, 0, 0, 0, 0,0x682E, 0,0x6836, 0,0x683D,0x6837, @@ -3762,7 +3762,7 @@ static uint16 tab_uni_jisx020840[]={ }; /* page 41 0x8C37-0x8D16 */ -static uint16 tab_uni_jisx020841[]={ +static const uint16 tab_uni_jisx020841[]={ 0x432B, 0, 0,0x6C2E, 0, 0, 0, 0, 0x6C30, 0,0x6C2F, 0, 0, 0, 0,0x4626, 0,0x6C31, 0,0x4B2D, 0,0x6C32, 0,0x6C33, @@ -3794,7 +3794,7 @@ static uint16 tab_uni_jisx020841[]={ }; /* page 42 0x8D64-0x8F64 */ -static uint16 tab_uni_jisx020842[]={ +static const uint16 tab_uni_jisx020842[]={ 0x4056, 0,0x3C4F,0x6C5F, 0, 0, 0,0x3352, 0,0x6C60, 0, 0,0x4176,0x6C61, 0,0x6C62, 0x496B, 0, 0,0x352F, 0, 0, 0, 0, @@ -3862,7 +3862,7 @@ static uint16 tab_uni_jisx020842[]={ 0x6D62}; /* page 43 0x8F9B-0x9132 */ -static uint16 tab_uni_jisx020843[]={ +static const uint16 tab_uni_jisx020843[]={ 0x3F49,0x6D63, 0,0x3C2D,0x6D64, 0, 0, 0, 0x6D65, 0, 0, 0,0x5221,0x517E, 0, 0, 0, 0,0x6D66,0x6570,0x6D67,0x4324,0x3F2B,0x4740, @@ -3917,7 +3917,7 @@ static uint16 tab_uni_jisx020843[]={ }; /* page 44 0x9149-0x92B9 */ -static uint16 tab_uni_jisx020844[]={ +static const uint16 tab_uni_jisx020844[]={ 0x4653,0x6E44,0x3D36,0x3C60,0x475B,0x4371, 0, 0, 0,0x3C72, 0,0x3F6C, 0,0x6E45, 0,0x6E46, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3967,7 +3967,7 @@ static uint16 tab_uni_jisx020844[]={ 0x6E78}; /* page 45 0x92CF-0x93E8 */ -static uint16 tab_uni_jisx020845[]={ +static const uint16 tab_uni_jisx020845[]={ 0x6E77, 0, 0,0x4B2F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3D7B, 0, 0, @@ -4006,7 +4006,7 @@ static uint16 tab_uni_jisx020845[]={ 0,0x6F34}; /* page 46 0x9403-0x9481 */ -static uint16 tab_uni_jisx020846[]={ +static const uint16 tab_uni_jisx020846[]={ 0x6F3F, 0, 0, 0,0x6F40, 0, 0, 0, 0, 0, 0, 0, 0,0x6F41, 0, 0, 0x6F3E,0x6F3D, 0, 0, 0,0x3E62,0x462A,0x6F3C, @@ -4025,7 +4025,7 @@ static uint16 tab_uni_jisx020846[]={ 0,0x6F55,0x6F53,0x6F56,0x6F58, 0,0x6F57}; /* page 47 0x9577-0x95E5 */ -static uint16 tab_uni_jisx020847[]={ +static const uint16 tab_uni_jisx020847[]={ 0x4439, 0, 0, 0, 0, 0, 0, 0, 0,0x4C67, 0,0x6F59,0x412E, 0, 0, 0, 0x6F5A, 0,0x4A44,0x6F5B,0x332B, 0, 0, 0, @@ -4042,7 +4042,7 @@ static uint16 tab_uni_jisx020847[]={ 0, 0,0x6F71,0x6F73, 0, 0,0x6F72}; /* page 48 0x961C-0x9874 */ -static uint16 tab_uni_jisx020848[]={ +static const uint16 tab_uni_jisx020848[]={ 0x496C, 0, 0, 0, 0,0x6F74, 0, 0, 0, 0, 0, 0,0x6F75, 0,0x3A65, 0, 0, 0,0x6F76,0x6F77, 0, 0,0x4B49, 0, @@ -4121,14 +4121,14 @@ static uint16 tab_uni_jisx020848[]={ 0x7122}; /* page 49 0x98A8-0x98C6 */ -static uint16 tab_uni_jisx020849[]={ +static const uint16 tab_uni_jisx020849[]={ 0x4977, 0,0x7124, 0, 0, 0, 0,0x7125, 0,0x7126, 0, 0, 0, 0,0x7127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x7129,0x7128, 0,0x712A}; /* page 50 0x98DB-0x9957 */ -static uint16 tab_uni_jisx020850[]={ +static const uint16 tab_uni_jisx020850[]={ 0x4874,0x664C, 0, 0,0x3F29, 0, 0,0x3532, 0, 0, 0, 0, 0, 0,0x712B, 0, 0x712C, 0,0x522C,0x5D3B,0x4853, 0, 0,0x307B, @@ -4147,7 +4147,7 @@ static uint16 tab_uni_jisx020850[]={ 0, 0,0x7143, 0,0x3642}; /* page 51 0x9996-0x9A6B */ -static uint16 tab_uni_jisx020851[]={ +static const uint16 tab_uni_jisx020851[]={ 0x3C73,0x7144,0x7145,0x3961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x7146, 0, 0,0x333E, 0, 0, 0,0x474F,0x7147, @@ -4177,7 +4177,7 @@ static uint16 tab_uni_jisx020851[]={ 0, 0, 0,0x7169,0x716B,0x716A}; /* page 52 0x9AA8-0x9B5A */ -static uint16 tab_uni_jisx020852[]={ +static const uint16 tab_uni_jisx020852[]={ 0x397C, 0, 0, 0, 0,0x716C, 0, 0, 0x716D, 0, 0, 0, 0, 0, 0, 0, 0x333C, 0, 0, 0,0x716E, 0, 0, 0, @@ -4203,7 +4203,7 @@ static uint16 tab_uni_jisx020852[]={ 0x7236, 0,0x357B}; /* page 53 0x9B6F-0x9C78 */ -static uint16 tab_uni_jisx020853[]={ +static const uint16 tab_uni_jisx020853[]={ 0x4F25, 0, 0, 0, 0,0x7237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x7239, 0, 0, 0, @@ -4240,7 +4240,7 @@ static uint16 tab_uni_jisx020853[]={ 0,0x7269}; /* page 54 0x9CE5-0x9DFD */ -static uint16 tab_uni_jisx020854[]={ +static const uint16 tab_uni_jisx020854[]={ 0x443B, 0,0x726A, 0,0x4837, 0,0x726F,0x726B, 0, 0, 0,0x726C, 0, 0,0x4B31,0x4C44, 0,0x4650, 0, 0, 0, 0, 0, 0, @@ -4279,11 +4279,11 @@ static uint16 tab_uni_jisx020854[]={ 0x733F}; /* page 55 0x9E1A-0x9E1E */ -static uint16 tab_uni_jisx020855[]={ +static const uint16 tab_uni_jisx020855[]={ 0x7340,0x7341, 0, 0,0x7342}; /* page 56 0x9E75-0x9F77 */ -static uint16 tab_uni_jisx020856[]={ +static const uint16 tab_uni_jisx020856[]={ 0x7343, 0, 0,0x3834,0x7344, 0, 0, 0, 0x7345, 0,0x3C2F, 0,0x7346, 0, 0, 0, 0, 0, 0,0x7347, 0, 0,0x7348,0x7349, @@ -4319,13 +4319,13 @@ static uint16 tab_uni_jisx020856[]={ 0,0x737B,0x7379}; /* page 57 0x9F8D-0x9FA0 */ -static uint16 tab_uni_jisx020857[]={ +static const uint16 tab_uni_jisx020857[]={ 0x4E36, 0, 0, 0, 0, 0, 0, 0, 0x737C, 0, 0, 0, 0, 0, 0,0x737D, 0x6354, 0, 0,0x737E}; /* page 58 0xFF01-0xFF5E */ -static uint16 tab_uni_jisx020858[]={ +static const uint16 tab_uni_jisx020858[]={ 0x212A, 0,0x2174,0x2170,0x2173,0x2175, 0,0x214A, 0x214B,0x2176,0x215C,0x2124,0x215D,0x2125,0x213F,0x2330, 0x2331,0x2332,0x2333,0x2334,0x2335,0x2336,0x2337,0x2338, @@ -4340,7 +4340,7 @@ static uint16 tab_uni_jisx020858[]={ 0x2379,0x237A,0x2150,0x2143,0x2151,0x2141}; /* page 59 0xFFE0-0xFFE5 */ -static uint16 tab_uni_jisx020859[]={ +static const uint16 tab_uni_jisx020859[]={ 0x2171,0x2172,0x224C,0x2131, 0,0x216F}; static int @@ -4470,11 +4470,11 @@ my_uni_jisx0208_onechar(int code){ /* page 0 0x007E-0x007E */ -static uint16 tab_uni_jisx02120[]={ +static const uint16 tab_uni_jisx02120[]={ 0}; /* page 1 0x00A1-0x017E */ -static uint16 tab_uni_jisx02121[]={ +static const uint16 tab_uni_jisx02121[]={ 0x2242, 0, 0,0x2270, 0, 0, 0, 0, 0x226D,0x226C, 0, 0, 0,0x226E,0x2234, 0, 0, 0, 0, 0, 0, 0, 0,0x2231, @@ -4505,28 +4505,28 @@ static uint16 tab_uni_jisx02121[]={ 0x2A75,0x2B75,0x2A77,0x2B77,0x2A76,0x2B76}; /* page 2 0x01CD-0x01DC */ -static uint16 tab_uni_jisx02122[]={ +static const uint16 tab_uni_jisx02122[]={ 0x2A26,0x2B26,0x2A43,0x2B43,0x2A55,0x2B55,0x2A67,0x2B67, 0x2A70,0x2B70,0x2A6D,0x2B6D,0x2A6F,0x2B6F,0x2A6E,0x2B6E }; /* page 3 0x01F5-0x01F5 */ -static uint16 tab_uni_jisx02123[]={ +static const uint16 tab_uni_jisx02123[]={ 0x2B39}; /* page 4 0x02C7-0x02DD */ -static uint16 tab_uni_jisx02124[]={ +static const uint16 tab_uni_jisx02124[]={ 0x2230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x222F,0x2232,0x2236,0x2235, 0,0x2233}; /* page 5 0x0384-0x0390 */ -static uint16 tab_uni_jisx02125[]={ +static const uint16 tab_uni_jisx02125[]={ 0x2238,0x2239,0x2661, 0,0x2662,0x2663,0x2664, 0, 0x2667, 0,0x2669,0x266C,0x2676}; /* page 6 0x03AA-0x03CE */ -static uint16 tab_uni_jisx02126[]={ +static const uint16 tab_uni_jisx02126[]={ 0x2665,0x266A,0x2671,0x2672,0x2673,0x2674,0x267B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4534,26 +4534,26 @@ static uint16 tab_uni_jisx02126[]={ 0x2675,0x267A,0x2677,0x2679,0x267C}; /* page 7 0x0402-0x040F */ -static uint16 tab_uni_jisx02127[]={ +static const uint16 tab_uni_jisx02127[]={ 0x2742,0x2743,0x2744,0x2745,0x2746,0x2747,0x2748,0x2749, 0x274A,0x274B,0x274C, 0,0x274D,0x274E}; /* page 8 0x0452-0x045F */ -static uint16 tab_uni_jisx02128[]={ +static const uint16 tab_uni_jisx02128[]={ 0x2772,0x2773,0x2774,0x2775,0x2776,0x2777,0x2778,0x2779, 0x277A,0x277B,0x277C, 0,0x277D,0x277E}; /* page 9 0x2122-0x2122 */ -static uint16 tab_uni_jisx02129[]={ +static const uint16 tab_uni_jisx02129[]={ 0x226F}; /* page 10 0x2170-0x2179 */ -static uint16 tab_uni_jisx021210[]={ +static const uint16 tab_uni_jisx021210[]={ 0x7373,0x7374,0x7375,0x7376,0x7377,0x7378,0x7379,0x737A, 0x737B,0x737C}; /* page 11 0x4E02-0x4F19 */ -static uint16 tab_uni_jisx021211[]={ +static const uint16 tab_uni_jisx021211[]={ 0x3021, 0,0x3022,0x3023, 0, 0, 0, 0, 0, 0,0x3024, 0, 0, 0, 0, 0, 0x3025, 0, 0, 0, 0, 0, 0, 0, @@ -4592,7 +4592,7 @@ static uint16 tab_uni_jisx021211[]={ }; /* page 12 0x4F2E-0x5166 */ -static uint16 tab_uni_jisx021212[]={ +static const uint16 tab_uni_jisx021212[]={ 0x305D, 0, 0,0x305E, 0,0x3060, 0,0x3061, 0,0x3062, 0,0x3063, 0,0x3064, 0, 0, 0x3065, 0,0x3066, 0,0x3067, 0, 0, 0, @@ -4667,7 +4667,7 @@ static uint16 tab_uni_jisx021212[]={ 0x326E}; /* page 13 0x517E-0x5515 */ -static uint16 tab_uni_jisx021213[]={ +static const uint16 tab_uni_jisx021213[]={ 0x326F, 0, 0, 0, 0,0x3270,0x3271, 0, 0, 0, 0, 0, 0,0x3272, 0, 0, 0x3273, 0, 0, 0, 0, 0, 0, 0, @@ -4786,7 +4786,7 @@ static uint16 tab_uni_jisx021213[]={ }; /* page 14 0x552A-0x5566 */ -static uint16 tab_uni_jisx021214[]={ +static const uint16 tab_uni_jisx021214[]={ 0x354E,0x354F, 0, 0, 0, 0, 0, 0, 0x3550, 0, 0,0x3551,0x3552, 0, 0, 0, 0,0x3553,0x3554,0x3555, 0, 0, 0,0x3556, @@ -4797,7 +4797,7 @@ static uint16 tab_uni_jisx021214[]={ 0, 0,0x3563, 0,0x3564}; /* page 15 0x557F-0x5C36 */ -static uint16 tab_uni_jisx021215[]={ +static const uint16 tab_uni_jisx021215[]={ 0x3565, 0,0x3566,0x3567, 0, 0, 0,0x3568, 0,0x3569, 0, 0, 0, 0, 0,0x356A, 0x356B, 0,0x356C,0x356D,0x356E,0x356F, 0, 0, @@ -5016,7 +5016,7 @@ static uint16 tab_uni_jisx021215[]={ }; /* page 16 0x5C59-0x5EEB */ -static uint16 tab_uni_jisx021216[]={ +static const uint16 tab_uni_jisx021216[]={ 0x3A77,0x3A78, 0,0x3A79, 0, 0, 0, 0, 0,0x3A7A,0x3A7B, 0, 0, 0,0x3A7C,0x3A7D, 0x3A7E, 0, 0, 0,0x3B21, 0, 0,0x3B22, @@ -5102,7 +5102,7 @@ static uint16 tab_uni_jisx021216[]={ 0, 0,0x3C5B}; /* page 17 0x5F02-0x6149 */ -static uint16 tab_uni_jisx021217[]={ +static const uint16 tab_uni_jisx021217[]={ 0x3C5C, 0, 0, 0,0x3C5D,0x3C5E,0x3C5F, 0, 0, 0, 0, 0,0x3C60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3C61, @@ -5179,7 +5179,7 @@ static uint16 tab_uni_jisx021217[]={ }; /* page 18 0x615E-0x6290 */ -static uint16 tab_uni_jisx021218[]={ +static const uint16 tab_uni_jisx021218[]={ 0x3E53, 0,0x3E54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3E55, 0, 0, 0, 0, 0,0x3E56, 0, 0, 0, @@ -5221,7 +5221,7 @@ static uint16 tab_uni_jisx021218[]={ 0x3F46,0x3F47,0x3F48}; /* page 19 0x62A6-0x679B */ -static uint16 tab_uni_jisx021219[]={ +static const uint16 tab_uni_jisx021219[]={ 0x3F49, 0,0x3F4A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3F4B, 0, 0, 0x3F4C,0x3F4D, 0, 0,0x3F4E, 0, 0, 0, @@ -5383,7 +5383,7 @@ static uint16 tab_uni_jisx021219[]={ 0x432D, 0,0x432E,0x432F, 0,0x4330}; /* page 20 0x67B0-0x6801 */ -static uint16 tab_uni_jisx021220[]={ +static const uint16 tab_uni_jisx021220[]={ 0x4331,0x4332,0x4333, 0, 0,0x4334, 0, 0, 0, 0, 0,0x4335,0x4336,0x4337, 0, 0, 0x4339, 0,0x433A,0x433B, 0,0x433C, 0, 0, @@ -5397,7 +5397,7 @@ static uint16 tab_uni_jisx021220[]={ 0,0x7446}; /* page 21 0x6814-0x6917 */ -static uint16 tab_uni_jisx021221[]={ +static const uint16 tab_uni_jisx021221[]={ 0x434A, 0, 0, 0, 0,0x434B, 0, 0, 0,0x434C, 0,0x434D, 0, 0, 0, 0, 0, 0, 0,0x434F,0x434E, 0, 0, 0, @@ -5433,7 +5433,7 @@ static uint16 tab_uni_jisx021221[]={ 0, 0,0x443B,0x443C}; /* page 22 0x6931-0x6D3F */ -static uint16 tab_uni_jisx021222[]={ +static const uint16 tab_uni_jisx021222[]={ 0x443D, 0,0x443E, 0,0x443F, 0, 0,0x4440, 0, 0,0x4441, 0, 0, 0, 0, 0, 0,0x4442, 0, 0,0x4443, 0, 0, 0, @@ -5566,7 +5566,7 @@ static uint16 tab_uni_jisx021222[]={ 0x473A, 0, 0,0x473B, 0, 0,0x473C}; /* page 23 0x6D57-0x6E04 */ -static uint16 tab_uni_jisx021223[]={ +static const uint16 tab_uni_jisx021223[]={ 0x473D, 0, 0, 0, 0, 0, 0,0x473E, 0x473F, 0,0x4740, 0, 0, 0,0x4741, 0, 0x4742, 0, 0, 0, 0, 0, 0, 0, @@ -5591,7 +5591,7 @@ static uint16 tab_uni_jisx021223[]={ 0,0x4767, 0, 0, 0,0x4768}; /* page 24 0x6E1E-0x6ECF */ -static uint16 tab_uni_jisx021224[]={ +static const uint16 tab_uni_jisx021224[]={ 0x4769, 0, 0, 0,0x476A, 0, 0, 0, 0,0x476B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x476C, 0, 0, 0, @@ -5617,7 +5617,7 @@ static uint16 tab_uni_jisx021224[]={ 0x4839,0x483A}; /* page 25 0x6EEB-0x70E4 */ -static uint16 tab_uni_jisx021225[]={ +static const uint16 tab_uni_jisx021225[]={ 0x483B, 0,0x483C,0x483D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x483E, 0, 0x483F, 0,0x4840, 0, 0, 0, 0, 0, @@ -5684,7 +5684,7 @@ static uint16 tab_uni_jisx021225[]={ 0,0x4960}; /* page 26 0x70FA-0x71DC */ -static uint16 tab_uni_jisx021226[]={ +static const uint16 tab_uni_jisx021226[]={ 0x4961, 0, 0, 0, 0, 0, 0, 0, 0,0x4962,0x4963,0x4964,0x4965,0x4966, 0, 0, 0,0x4967,0x4968, 0, 0,0x4969, 0, 0, @@ -5716,7 +5716,7 @@ static uint16 tab_uni_jisx021226[]={ 0x4A3A, 0,0x4A3B}; /* page 27 0x71F8-0x7E9E */ -static uint16 tab_uni_jisx021227[]={ +static const uint16 tab_uni_jisx021227[]={ 0x4A3C, 0, 0, 0, 0, 0,0x4A3D, 0, 0x4A3E, 0, 0, 0, 0, 0, 0,0x4A3F, 0x4A40,0x4A41, 0, 0, 0, 0, 0, 0, @@ -6124,7 +6124,7 @@ static uint16 tab_uni_jisx021227[]={ 0x5467, 0,0x5468, 0, 0,0x5469,0x546A}; /* page 28 0x7F3B-0x8044 */ -static uint16 tab_uni_jisx021228[]={ +static const uint16 tab_uni_jisx021228[]={ 0x546C,0x546B,0x546D,0x546E,0x546F, 0, 0, 0, 0x5470,0x5471, 0, 0,0x5472, 0, 0, 0, 0, 0, 0, 0,0x5473, 0, 0,0x5474, @@ -6161,7 +6161,7 @@ static uint16 tab_uni_jisx021228[]={ 0,0x5563}; /* page 29 0x8060-0x8362 */ -static uint16 tab_uni_jisx021229[]={ +static const uint16 tab_uni_jisx021229[]={ 0x5564, 0, 0, 0,0x5565, 0,0x5566, 0, 0, 0, 0, 0, 0,0x5567, 0, 0, 0,0x5568, 0, 0, 0,0x5569, 0, 0, @@ -6261,7 +6261,7 @@ static uint16 tab_uni_jisx021229[]={ 0, 0,0x745F}; /* page 30 0x8370-0x8419 */ -static uint16 tab_uni_jisx021230[]={ +static const uint16 tab_uni_jisx021230[]={ 0x577D, 0, 0, 0, 0, 0, 0, 0, 0x577E, 0, 0, 0, 0,0x5821, 0,0x5822, 0x5823, 0,0x5824, 0,0x5825, 0,0x5826, 0, @@ -6286,7 +6286,7 @@ static uint16 tab_uni_jisx021230[]={ 0,0x584B}; /* page 31 0x842F-0x8880 */ -static uint16 tab_uni_jisx021231[]={ +static const uint16 tab_uni_jisx021231[]={ 0x584D, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x584E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x584F, 0, @@ -6428,7 +6428,7 @@ static uint16 tab_uni_jisx021231[]={ 0,0x5C38}; /* page 32 0x8898-0x89BC */ -static uint16 tab_uni_jisx021232[]={ +static const uint16 tab_uni_jisx021232[]={ 0x5C39, 0,0x5C3A,0x5C3B,0x5C3C, 0, 0,0x5C3D, 0x5C3E, 0, 0, 0, 0, 0, 0, 0, 0x5C3F, 0,0x5C40, 0, 0, 0, 0, 0, @@ -6468,7 +6468,7 @@ static uint16 tab_uni_jisx021232[]={ 0, 0, 0, 0,0x5D33}; /* page 33 0x89D4-0x8B9F */ -static uint16 tab_uni_jisx021233[]={ +static const uint16 tab_uni_jisx021233[]={ 0x5D34,0x5D35,0x5D36,0x5D37,0x5D38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x5D39, 0, 0, 0,0x5D3A, 0,0x5D3B, @@ -6529,7 +6529,7 @@ static uint16 tab_uni_jisx021233[]={ 0x5E5F, 0,0x5E60,0x5E61}; /* page 34 0x8C38-0x8CA4 */ -static uint16 tab_uni_jisx021234[]={ +static const uint16 tab_uni_jisx021234[]={ 0x5E62,0x5E63, 0, 0, 0,0x5E64,0x5E65, 0, 0, 0, 0, 0, 0,0x5E66, 0,0x5E67, 0,0x5E68, 0,0x5E69, 0, 0, 0,0x5E6A, @@ -6546,7 +6546,7 @@ static uint16 tab_uni_jisx021234[]={ 0, 0, 0, 0,0x5F29}; /* page 35 0x8CB9-0x8D1B */ -static uint16 tab_uni_jisx021235[]={ +static const uint16 tab_uni_jisx021235[]={ 0x5F2A,0x5F2B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x5F2C,0x5F2D, 0, 0, 0x5F2E, 0,0x5F2F, 0, 0, 0,0x5F30, 0, @@ -6562,7 +6562,7 @@ static uint16 tab_uni_jisx021235[]={ 0, 0,0x5F45}; /* page 36 0x8D65-0x8F65 */ -static uint16 tab_uni_jisx021236[]={ +static const uint16 tab_uni_jisx021236[]={ 0x5F46, 0, 0, 0,0x5F47, 0, 0,0x5F48, 0,0x5F49, 0, 0, 0, 0, 0, 0, 0,0x7468, 0, 0, 0, 0, 0, 0, @@ -6630,7 +6630,7 @@ static uint16 tab_uni_jisx021236[]={ 0x612C}; /* page 37 0x8F9D-0x9484 */ -static uint16 tab_uni_jisx021237[]={ +static const uint16 tab_uni_jisx021237[]={ 0x612D, 0, 0,0x612E,0x612F, 0, 0,0x6130, 0x6131,0x6132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6791,7 +6791,7 @@ static uint16 tab_uni_jisx021237[]={ }; /* page 38 0x9578-0x95E6 */ -static uint16 tab_uni_jisx021238[]={ +static const uint16 tab_uni_jisx021238[]={ 0x657D,0x657E, 0, 0, 0, 0,0x6621, 0, 0, 0, 0, 0,0x6622, 0, 0, 0, 0x6623, 0, 0, 0,0x6624,0x6625,0x6626, 0, @@ -6808,7 +6808,7 @@ static uint16 tab_uni_jisx021238[]={ 0x6641, 0, 0, 0,0x6642, 0,0x6643}; /* page 39 0x961D-0x986C */ -static uint16 tab_uni_jisx021239[]={ +static const uint16 tab_uni_jisx021239[]={ 0x6644,0x6645, 0, 0, 0,0x6646, 0,0x6647, 0x6648,0x6649, 0, 0, 0, 0, 0,0x664A, 0, 0, 0, 0,0x664B, 0,0x664C, 0, @@ -6886,7 +6886,7 @@ static uint16 tab_uni_jisx021239[]={ }; /* page 40 0x98AB-0x98CC */ -static uint16 tab_uni_jisx021240[]={ +static const uint16 tab_uni_jisx021240[]={ 0x683A, 0,0x683B,0x683C, 0,0x683D, 0, 0, 0,0x683E, 0, 0,0x683F,0x6840, 0,0x6841, 0x6842, 0, 0, 0,0x6843, 0, 0,0x6844, @@ -6894,7 +6894,7 @@ static uint16 tab_uni_jisx021240[]={ 0,0x6847}; /* page 41 0x98E1-0x9960 */ -static uint16 tab_uni_jisx021241[]={ +static const uint16 tab_uni_jisx021241[]={ 0x6848, 0,0x6849, 0,0x684A,0x684B,0x684C, 0, 0,0x684D, 0, 0, 0, 0, 0, 0, 0, 0,0x684E, 0, 0,0x684F, 0, 0, @@ -6914,7 +6914,7 @@ static uint16 tab_uni_jisx021241[]={ }; /* page 42 0x999B-0x9A5D */ -static uint16 tab_uni_jisx021242[]={ +static const uint16 tab_uni_jisx021242[]={ 0x6877, 0,0x6878,0x747A,0x6879, 0, 0, 0, 0, 0, 0,0x687A, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x687B,0x687C,0x687D, @@ -6942,7 +6942,7 @@ static uint16 tab_uni_jisx021242[]={ 0, 0,0x6955}; /* page 43 0x9AAA-0x9C7B */ -static uint16 tab_uni_jisx021243[]={ +static const uint16 tab_uni_jisx021243[]={ 0x6956, 0,0x6957, 0,0x6958,0x6959, 0, 0, 0x695A, 0,0x695B,0x695C,0x695D, 0, 0,0x695E, 0,0x695F, 0, 0,0x6960,0x6961, 0,0x6962, @@ -7004,7 +7004,7 @@ static uint16 tab_uni_jisx021243[]={ 0,0x6B58}; /* page 44 0x9CE6-0x9E1D */ -static uint16 tab_uni_jisx021244[]={ +static const uint16 tab_uni_jisx021244[]={ 0x6B59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x6B5A, 0, 0, 0, 0,0x6B5B, 0,0x6B5C, 0, 0, 0, 0, @@ -7047,7 +7047,7 @@ static uint16 tab_uni_jisx021244[]={ }; /* page 45 0x9E7A-0x9FA5 */ -static uint16 tab_uni_jisx021245[]={ +static const uint16 tab_uni_jisx021245[]={ 0x6C59,0x6C5A,0x6C5B, 0, 0, 0,0x6C5C, 0, 0x6C5D,0x6C5E,0x6C5F,0x6C60, 0,0x6C61, 0, 0, 0, 0, 0, 0,0x6C62,0x6C63, 0, 0, @@ -7088,15 +7088,15 @@ static uint16 tab_uni_jisx021245[]={ 0x6D61,0x6D62, 0,0x6D63}; /* page 46 0xF929-0xF929 */ -static uint16 tab_uni_jisx021246[]={ +static const uint16 tab_uni_jisx021246[]={ 0x7445}; /* page 47 0xF9DC-0xF9DC */ -static uint16 tab_uni_jisx021247[]={ +static const uint16 tab_uni_jisx021247[]={ 0x7472}; /* page 48 0xFA00-0xFA2D */ -static uint16 tab_uni_jisx021248[]={ +static const uint16 tab_uni_jisx021248[]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x7434,0x7437, 0x7438,0x743D,0x7444,0x7447,0x7448,0x744E,0x744F,0x7453, @@ -7105,11 +7105,11 @@ static uint16 tab_uni_jisx021248[]={ 0x7470,0x7473,0x7477,0x7478,0x7479,0x747D}; /* page 49 0xFF00-0XFF07 */ -static uint16 tab_uni_jisx021249[]={ +static const uint16 tab_uni_jisx021249[]={ 0, 0,0x742A, 0, 0, 0, 0,0x7429}; /* page 50 0xFFE4-0xFFE4 */ -static uint16 tab_uni_jisx021250[]={ +static const uint16 tab_uni_jisx021250[]={ 0x2243}; static int @@ -7220,34 +7220,34 @@ my_uni_jisx0212_onechar(int code){ } /* page 0 0x222F-0x2244 */ -static uint16 tab_jisx0212_uni0[]={ +static const uint16 tab_jisx0212_uni0[]={ 0x02D8,0x02C7,0x00B8,0x02D9,0x02DD,0x00AF,0x02DB,0x02DA, 0xFF5E,0x0384,0x0385, 0, 0, 0, 0, 0, 0, 0, 0,0x00A1,0xFFE4,0x00BF}; /* page 1 0x226B-0x2271 */ -static uint16 tab_jisx0212_uni1[]={ +static const uint16 tab_jisx0212_uni1[]={ 0x00BA,0x00AA,0x00A9,0x00AE,0x2122,0x00A4,0x2116}; /* page 2 0x2661-0x267C */ -static uint16 tab_jisx0212_uni2[]={ +static const uint16 tab_jisx0212_uni2[]={ 0x0386,0x0388,0x0389,0x038A,0x03AA, 0,0x038C, 0, 0x038E,0x03AB, 0,0x038F, 0, 0, 0, 0, 0x03AC,0x03AD,0x03AE,0x03AF,0x03CA,0x0390,0x03CC,0x03C2, 0x03CD,0x03CB,0x03B0,0x03CE}; /* page 3 0x2742-0x274E */ -static uint16 tab_jisx0212_uni3[]={ +static const uint16 tab_jisx0212_uni3[]={ 0x0402,0x0403,0x0404,0x0405,0x0406,0x0407,0x0408,0x0409, 0x040A,0x040B,0x040C,0x040E,0x040F}; /* page 4 0x2772-0x277E */ -static uint16 tab_jisx0212_uni4[]={ +static const uint16 tab_jisx0212_uni4[]={ 0x0452,0x0453,0x0454,0x0455,0x0456,0x0457,0x0458,0x0459, 0x045A,0x045B,0x045C,0x045E,0x045F}; /* page 5 0x2921-0x2950 */ -static uint16 tab_jisx0212_uni5[]={ +static const uint16 tab_jisx0212_uni5[]={ 0x00C6,0x0110, 0,0x0126, 0,0x0132, 0,0x0141, 0x013F, 0,0x014A,0x00D8,0x0152, 0,0x0166,0x00DE, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7257,7 +7257,7 @@ static uint16 tab_jisx0212_uni5[]={ }; /* page 6 0x2A21-0x2A77 */ -static uint16 tab_jisx0212_uni6[]={ +static const uint16 tab_jisx0212_uni6[]={ 0x00C1,0x00C0,0x00C4,0x00C2,0x0102,0x01CD,0x0100,0x0104, 0x00C5,0x00C3,0x0106,0x0108,0x010C,0x00C7,0x010A,0x010E, 0x00C9,0x00C8,0x00CB,0x00CA,0x011A,0x0116,0x0112,0x0118, @@ -7271,7 +7271,7 @@ static uint16 tab_jisx0212_uni6[]={ 0x0174,0x00DD,0x0178,0x0176,0x0179,0x017D,0x017B}; /* page 7 0x2B21-0x2B77 */ -static uint16 tab_jisx0212_uni7[]={ +static const uint16 tab_jisx0212_uni7[]={ 0x00E1,0x00E0,0x00E4,0x00E2,0x0103,0x01CE,0x0101,0x0105, 0x00E5,0x00E3,0x0107,0x0109,0x010D,0x00E7,0x010B,0x010F, 0x00E9,0x00E8,0x00EB,0x00EA,0x011B,0x0117,0x0113,0x0119, @@ -7285,7 +7285,7 @@ static uint16 tab_jisx0212_uni7[]={ 0x0175,0x00FD,0x00FF,0x0177,0x017A,0x017E,0x017C}; /* page 8 0x3021-0x307E */ -static uint16 tab_jisx0212_uni8[]={ +static const uint16 tab_jisx0212_uni8[]={ 0x4E02,0x4E04,0x4E05,0x4E0C,0x4E12,0x4E1F,0x4E23,0x4E24, 0x4E28,0x4E2B,0x4E2E,0x4E2F,0x4E30,0x4E35,0x4E40,0x4E41, 0x4E44,0x4E47,0x4E51,0x4E5A,0x4E5C,0x4E63,0x4E68,0x4E69, @@ -7300,7 +7300,7 @@ static uint16 tab_jisx0212_uni8[]={ 0x4F7A,0x4F7D,0x4F7E,0x4F81,0x4F82,0x4F84}; /* page 9 0x3121-0x317E */ -static uint16 tab_jisx0212_uni9[]={ +static const uint16 tab_jisx0212_uni9[]={ 0x4F85,0x4F89,0x4F8A,0x4F8C,0x4F8E,0x4F90,0x4F92,0x4F93, 0x4F94,0x4F97,0x4F99,0x4F9A,0x4F9E,0x4F9F,0x4FB2,0x4FB7, 0x4FB9,0x4FBB,0x4FBC,0x4FBD,0x4FBE,0x4FC0,0x4FC1,0x4FC5, @@ -7315,7 +7315,7 @@ static uint16 tab_jisx0212_uni9[]={ 0x5084,0x5086,0x508A,0x508E,0x508F,0x5090}; /* page 10 0x3221-0x327E */ -static uint16 tab_jisx0212_uni10[]={ +static const uint16 tab_jisx0212_uni10[]={ 0x5092,0x5093,0x5094,0x5096,0x509B,0x509C,0x509E,0x509F, 0x50A0,0x50A1,0x50A2,0x50AA,0x50AF,0x50B0,0x50B9,0x50BA, 0x50BD,0x50C0,0x50C3,0x50C4,0x50C7,0x50CC,0x50CE,0x50D0, @@ -7330,7 +7330,7 @@ static uint16 tab_jisx0212_uni10[]={ 0x51B8,0x51BA,0x51BC,0x51BE,0x51BF,0x51C2}; /* page 11 0x3321-0x337E */ -static uint16 tab_jisx0212_uni11[]={ +static const uint16 tab_jisx0212_uni11[]={ 0x51C8,0x51CF,0x51D1,0x51D2,0x51D3,0x51D5,0x51D8,0x51DE, 0x51E2,0x51E5,0x51EE,0x51F2,0x51F3,0x51F4,0x51F7,0x5201, 0x5202,0x5205,0x5212,0x5213,0x5215,0x5216,0x5218,0x5222, @@ -7345,7 +7345,7 @@ static uint16 tab_jisx0212_uni11[]={ 0x52F6,0x52F7,0x5300,0x5303,0x530A,0x530B}; /* page 12 0x3421-0x347E */ -static uint16 tab_jisx0212_uni12[]={ +static const uint16 tab_jisx0212_uni12[]={ 0x530C,0x5311,0x5313,0x5318,0x531B,0x531C,0x531E,0x531F, 0x5325,0x5327,0x5328,0x5329,0x532B,0x532C,0x532D,0x5330, 0x5332,0x5335,0x533C,0x533D,0x533E,0x5342,0x534C,0x534B, @@ -7360,7 +7360,7 @@ static uint16 tab_jisx0212_uni12[]={ 0x5469,0x546B,0x546D,0x546E,0x5474,0x547F}; /* page 13 0x3521-0x357E */ -static uint16 tab_jisx0212_uni13[]={ +static const uint16 tab_jisx0212_uni13[]={ 0x5481,0x5483,0x5485,0x5488,0x5489,0x548D,0x5491,0x5495, 0x5496,0x549C,0x549F,0x54A1,0x54A6,0x54A7,0x54A9,0x54AA, 0x54AD,0x54AE,0x54B1,0x54B7,0x54B9,0x54BA,0x54BB,0x54BF, @@ -7375,7 +7375,7 @@ static uint16 tab_jisx0212_uni13[]={ 0x55C9,0x55CB,0x55CC,0x55CE,0x55D1,0x55D2}; /* page 14 0x3621-0x367E */ -static uint16 tab_jisx0212_uni14[]={ +static const uint16 tab_jisx0212_uni14[]={ 0x55D3,0x55D7,0x55D8,0x55DB,0x55DE,0x55E2,0x55E9,0x55F6, 0x55FF,0x5605,0x5608,0x560A,0x560D,0x560E,0x560F,0x5610, 0x5611,0x5612,0x5619,0x562C,0x5630,0x5633,0x5635,0x5637, @@ -7390,7 +7390,7 @@ static uint16 tab_jisx0212_uni14[]={ 0x56E6,0x56E7,0x56E8,0x56F1,0x56EB,0x56ED}; /* page 15 0x3721-0x377E */ -static uint16 tab_jisx0212_uni15[]={ +static const uint16 tab_jisx0212_uni15[]={ 0x56F6,0x56F7,0x5701,0x5702,0x5707,0x570A,0x570C,0x5711, 0x5715,0x571A,0x571B,0x571D,0x5720,0x5722,0x5723,0x5724, 0x5725,0x5729,0x572A,0x572C,0x572E,0x572F,0x5733,0x5734, @@ -7405,7 +7405,7 @@ static uint16 tab_jisx0212_uni15[]={ 0x57FF,0x5803,0x5804,0x5808,0x5809,0x57E1}; /* page 16 0x3821-0x387E */ -static uint16 tab_jisx0212_uni16[]={ +static const uint16 tab_jisx0212_uni16[]={ 0x580C,0x580D,0x581B,0x581E,0x581F,0x5820,0x5826,0x5827, 0x582D,0x5832,0x5839,0x583F,0x5849,0x584C,0x584D,0x584F, 0x5850,0x5855,0x585F,0x5861,0x5864,0x5867,0x5868,0x5878, @@ -7420,7 +7420,7 @@ static uint16 tab_jisx0212_uni16[]={ 0x595E,0x595F,0x5961,0x5963,0x596B,0x596D}; /* page 17 0x3921-0x397E */ -static uint16 tab_jisx0212_uni17[]={ +static const uint16 tab_jisx0212_uni17[]={ 0x596F,0x5972,0x5975,0x5976,0x5979,0x597B,0x597C,0x598B, 0x598C,0x598E,0x5992,0x5995,0x5997,0x599F,0x59A4,0x59A7, 0x59AD,0x59AE,0x59AF,0x59B0,0x59B3,0x59B7,0x59BA,0x59BC, @@ -7435,7 +7435,7 @@ static uint16 tab_jisx0212_uni17[]={ 0x5AB3,0x5AB5,0x5AB8,0x5ABA,0x5ABB,0x5ABF}; /* page 18 0x3A21-0x3A7E */ -static uint16 tab_jisx0212_uni18[]={ +static const uint16 tab_jisx0212_uni18[]={ 0x5AC4,0x5AC6,0x5AC8,0x5ACF,0x5ADA,0x5ADC,0x5AE0,0x5AE5, 0x5AEA,0x5AEE,0x5AF5,0x5AF6,0x5AFD,0x5B00,0x5B01,0x5B08, 0x5B17,0x5B34,0x5B19,0x5B1B,0x5B1D,0x5B21,0x5B25,0x5B2D, @@ -7450,7 +7450,7 @@ static uint16 tab_jisx0212_uni18[]={ 0x5C5C,0x5C62,0x5C63,0x5C67,0x5C68,0x5C69}; /* page 19 0x3B21-0x3B7E */ -static uint16 tab_jisx0212_uni19[]={ +static const uint16 tab_jisx0212_uni19[]={ 0x5C6D,0x5C70,0x5C74,0x5C75,0x5C7A,0x5C7B,0x5C7C,0x5C7D, 0x5C87,0x5C88,0x5C8A,0x5C8F,0x5C92,0x5C9D,0x5C9F,0x5CA0, 0x5CA2,0x5CA3,0x5CA6,0x5CAA,0x5CB2,0x5CB4,0x5CB5,0x5CBA, @@ -7465,7 +7465,7 @@ static uint16 tab_jisx0212_uni19[]={ 0x5DD0,0x5DCE,0x5DD8,0x5DD9,0x5DE0,0x5DE4}; /* page 20 0x3C21-0x3C7E */ -static uint16 tab_jisx0212_uni20[]={ +static const uint16 tab_jisx0212_uni20[]={ 0x5DE9,0x5DF8,0x5DF9,0x5E00,0x5E07,0x5E0D,0x5E12,0x5E14, 0x5E15,0x5E18,0x5E1F,0x5E20,0x5E2E,0x5E28,0x5E32,0x5E35, 0x5E3E,0x5E4B,0x5E50,0x5E49,0x5E51,0x5E56,0x5E58,0x5E5B, @@ -7480,7 +7480,7 @@ static uint16 tab_jisx0212_uni20[]={ 0x5F58,0x5F5B,0x5F60,0x5F63,0x5F64,0x5F67}; /* page 21 0x3D21-0x3D7E */ -static uint16 tab_jisx0212_uni21[]={ +static const uint16 tab_jisx0212_uni21[]={ 0x5F6F,0x5F72,0x5F74,0x5F75,0x5F78,0x5F7A,0x5F7D,0x5F7E, 0x5F89,0x5F8D,0x5F8F,0x5F96,0x5F9C,0x5F9D,0x5FA2,0x5FA7, 0x5FAB,0x5FA4,0x5FAC,0x5FAF,0x5FB0,0x5FB1,0x5FB8,0x5FC4, @@ -7495,7 +7495,7 @@ static uint16 tab_jisx0212_uni21[]={ 0x60A4,0x60A5,0x60A8,0x60B0,0x60B1,0x60B7}; /* page 22 0x3E21-0x3E7E */ -static uint16 tab_jisx0212_uni22[]={ +static const uint16 tab_jisx0212_uni22[]={ 0x60BB,0x60BE,0x60C2,0x60C4,0x60C8,0x60C9,0x60CA,0x60CB, 0x60CE,0x60CF,0x60D4,0x60D5,0x60D9,0x60DB,0x60DD,0x60DE, 0x60E2,0x60E5,0x60F2,0x60F5,0x60F8,0x60FC,0x60FD,0x6102, @@ -7510,7 +7510,7 @@ static uint16 tab_jisx0212_uni22[]={ 0x61DF,0x61E1,0x61E2,0x61E7,0x61E9,0x61E5}; /* page 23 0x3F21-0x3F7E */ -static uint16 tab_jisx0212_uni23[]={ +static const uint16 tab_jisx0212_uni23[]={ 0x61EC,0x61ED,0x61EF,0x6201,0x6203,0x6204,0x6207,0x6213, 0x6215,0x621C,0x6220,0x6222,0x6223,0x6227,0x6229,0x622B, 0x6239,0x623D,0x6242,0x6243,0x6244,0x6246,0x624C,0x6250, @@ -7525,7 +7525,7 @@ static uint16 tab_jisx0212_uni23[]={ 0x6366,0x636C,0x636D,0x6371,0x6374,0x6375}; /* page 24 0x4021-0x407E */ -static uint16 tab_jisx0212_uni24[]={ +static const uint16 tab_jisx0212_uni24[]={ 0x6378,0x637C,0x637D,0x637F,0x6382,0x6384,0x6387,0x638A, 0x6390,0x6394,0x6395,0x6399,0x639A,0x639E,0x63A4,0x63A6, 0x63AD,0x63AE,0x63AF,0x63BD,0x63C1,0x63C5,0x63C8,0x63CE, @@ -7540,7 +7540,7 @@ static uint16 tab_jisx0212_uni24[]={ 0x64A8,0x64AC,0x64B3,0x64BD,0x64BE,0x64BF}; /* page 25 0x4121-0x417E */ -static uint16 tab_jisx0212_uni25[]={ +static const uint16 tab_jisx0212_uni25[]={ 0x64C4,0x64C9,0x64CA,0x64CB,0x64CC,0x64CE,0x64D0,0x64D1, 0x64D5,0x64D7,0x64E4,0x64E5,0x64E9,0x64EA,0x64ED,0x64F0, 0x64F5,0x64F7,0x64FB,0x64FF,0x6501,0x6504,0x6508,0x6509, @@ -7555,7 +7555,7 @@ static uint16 tab_jisx0212_uni25[]={ 0x660D,0x6611,0x6612,0x6615,0x6616,0x661D}; /* page 26 0x4221-0x427E */ -static uint16 tab_jisx0212_uni26[]={ +static const uint16 tab_jisx0212_uni26[]={ 0x661E,0x6621,0x6622,0x6623,0x6624,0x6626,0x6629,0x662A, 0x662B,0x662C,0x662E,0x6630,0x6631,0x6633,0x6639,0x6637, 0x6640,0x6645,0x6646,0x664A,0x664C,0x6651,0x664E,0x6657, @@ -7570,7 +7570,7 @@ static uint16 tab_jisx0212_uni26[]={ 0x6747,0x6748,0x674C,0x6754,0x6755,0x675D}; /* page 27 0x4321-0x437E */ -static uint16 tab_jisx0212_uni27[]={ +static const uint16 tab_jisx0212_uni27[]={ 0x6766,0x676C,0x676E,0x6774,0x6776,0x677B,0x6781,0x6784, 0x678E,0x678F,0x6791,0x6793,0x6796,0x6798,0x6799,0x679B, 0x67B0,0x67B1,0x67B2,0x67B5,0x67BB,0x67BC,0x67BD,0x67F9, @@ -7585,7 +7585,7 @@ static uint16 tab_jisx0212_uni27[]={ 0x68B2,0x68BB,0x68C5,0x68C8,0x68CC,0x68CF}; /* page 28 0x4421-0x447E */ -static uint16 tab_jisx0212_uni28[]={ +static const uint16 tab_jisx0212_uni28[]={ 0x68D0,0x68D1,0x68D3,0x68D6,0x68D9,0x68DC,0x68DD,0x68E5, 0x68E8,0x68EA,0x68EB,0x68EC,0x68ED,0x68F0,0x68F1,0x68F5, 0x68F6,0x68FB,0x68FC,0x68FD,0x6906,0x6909,0x690A,0x6910, @@ -7600,7 +7600,7 @@ static uint16 tab_jisx0212_uni28[]={ 0x6A1D,0x6A20,0x6A24,0x6A28,0x6A30,0x6A32}; /* page 29 0x4521-0x457E */ -static uint16 tab_jisx0212_uni29[]={ +static const uint16 tab_jisx0212_uni29[]={ 0x6A34,0x6A37,0x6A3B,0x6A3E,0x6A3F,0x6A45,0x6A46,0x6A49, 0x6A4A,0x6A4E,0x6A50,0x6A51,0x6A52,0x6A55,0x6A56,0x6A5B, 0x6A64,0x6A67,0x6A6A,0x6A71,0x6A73,0x6A7E,0x6A81,0x6A83, @@ -7615,7 +7615,7 @@ static uint16 tab_jisx0212_uni29[]={ 0x6B67,0x6B6B,0x6B6E,0x6B70,0x6B75,0x6B7D}; /* page 30 0x4621-0x467E */ -static uint16 tab_jisx0212_uni30[]={ +static const uint16 tab_jisx0212_uni30[]={ 0x6B7E,0x6B82,0x6B85,0x6B97,0x6B9B,0x6B9F,0x6BA0,0x6BA2, 0x6BA3,0x6BA8,0x6BA9,0x6BAC,0x6BAD,0x6BAE,0x6BB0,0x6BB8, 0x6BB9,0x6BBD,0x6BBE,0x6BC3,0x6BC4,0x6BC9,0x6BCC,0x6BD6, @@ -7630,7 +7630,7 @@ static uint16 tab_jisx0212_uni30[]={ 0x6CCF,0x6CD0,0x6CD1,0x6CD2,0x6CD4,0x6CD6}; /* page 31 0x4721-0x477E */ -static uint16 tab_jisx0212_uni31[]={ +static const uint16 tab_jisx0212_uni31[]={ 0x6CDA,0x6CDC,0x6CE0,0x6CE7,0x6CE9,0x6CEB,0x6CEC,0x6CEE, 0x6CF2,0x6CF4,0x6D04,0x6D07,0x6D0A,0x6D0E,0x6D0F,0x6D11, 0x6D13,0x6D1A,0x6D26,0x6D27,0x6D28,0x6C67,0x6D2E,0x6D2F, @@ -7645,7 +7645,7 @@ static uint16 tab_jisx0212_uni31[]={ 0x6E53,0x6E54,0x6E57,0x6E5C,0x6E5D,0x6E5E}; /* page 32 0x4821-0x487E */ -static uint16 tab_jisx0212_uni32[]={ +static const uint16 tab_jisx0212_uni32[]={ 0x6E62,0x6E63,0x6E68,0x6E73,0x6E7B,0x6E7D,0x6E8D,0x6E93, 0x6E99,0x6EA0,0x6EA7,0x6EAD,0x6EAE,0x6EB1,0x6EB3,0x6EBB, 0x6EBF,0x6EC0,0x6EC1,0x6EC3,0x6EC7,0x6EC8,0x6ECA,0x6ECD, @@ -7660,7 +7660,7 @@ static uint16 tab_jisx0212_uni32[]={ 0x6FB6,0x6FBC,0x6FC5,0x6FC7,0x6FC8,0x6FCA}; /* page 33 0x4921-0x497E */ -static uint16 tab_jisx0212_uni33[]={ +static const uint16 tab_jisx0212_uni33[]={ 0x6FDA,0x6FDE,0x6FE8,0x6FE9,0x6FF0,0x6FF5,0x6FF9,0x6FFC, 0x6FFD,0x7000,0x7005,0x7006,0x7007,0x700D,0x7017,0x7020, 0x7023,0x702F,0x7034,0x7037,0x7039,0x703C,0x7043,0x7044, @@ -7675,7 +7675,7 @@ static uint16 tab_jisx0212_uni33[]={ 0x7152,0x7157,0x715A,0x715C,0x715E,0x7160}; /* page 34 0x4A21-0x4A7E */ -static uint16 tab_jisx0212_uni34[]={ +static const uint16 tab_jisx0212_uni34[]={ 0x7168,0x7179,0x7180,0x7185,0x7187,0x718C,0x7192,0x719A, 0x719B,0x71A0,0x71A2,0x71AF,0x71B0,0x71B2,0x71B3,0x71BA, 0x71BF,0x71C0,0x71C1,0x71C4,0x71CB,0x71CC,0x71D3,0x71D6, @@ -7690,7 +7690,7 @@ static uint16 tab_jisx0212_uni34[]={ 0x72DF,0x72E5,0x72F3,0x72F4,0x72FA,0x72FB}; /* page 35 0x4B21-0x4B7E */ -static uint16 tab_jisx0212_uni35[]={ +static const uint16 tab_jisx0212_uni35[]={ 0x72FE,0x7302,0x7304,0x7305,0x7307,0x730B,0x730D,0x7312, 0x7313,0x7318,0x7319,0x731E,0x7322,0x7324,0x7327,0x7328, 0x732C,0x7331,0x7332,0x7335,0x733A,0x733B,0x733D,0x7343, @@ -7705,7 +7705,7 @@ static uint16 tab_jisx0212_uni35[]={ 0x73F5,0x73F7,0x73F9,0x73FA,0x73FB,0x73FD}; /* page 36 0x4C21-0x4C7E */ -static uint16 tab_jisx0212_uni36[]={ +static const uint16 tab_jisx0212_uni36[]={ 0x73FF,0x7400,0x7401,0x7404,0x7407,0x740A,0x7411,0x741A, 0x741B,0x7424,0x7426,0x7428,0x7429,0x742A,0x742B,0x742C, 0x742D,0x742E,0x742F,0x7430,0x7431,0x7439,0x7440,0x7443, @@ -7720,7 +7720,7 @@ static uint16 tab_jisx0212_uni36[]={ 0x74F4,0x74FA,0x74FB,0x74FC,0x74FF,0x7506}; /* page 37 0x4D21-0x4D7E */ -static uint16 tab_jisx0212_uni37[]={ +static const uint16 tab_jisx0212_uni37[]={ 0x7512,0x7516,0x7517,0x7520,0x7521,0x7524,0x7527,0x7529, 0x752A,0x752F,0x7536,0x7539,0x753D,0x753E,0x753F,0x7540, 0x7543,0x7547,0x7548,0x754E,0x7550,0x7552,0x7557,0x755E, @@ -7735,7 +7735,7 @@ static uint16 tab_jisx0212_uni37[]={ 0x762D,0x7632,0x7633,0x7635,0x7638,0x7639}; /* page 38 0x4E21-0x4E7E */ -static uint16 tab_jisx0212_uni38[]={ +static const uint16 tab_jisx0212_uni38[]={ 0x763A,0x763C,0x764A,0x7640,0x7641,0x7643,0x7644,0x7645, 0x7649,0x764B,0x7655,0x7659,0x765F,0x7664,0x7665,0x766D, 0x766E,0x766F,0x7671,0x7674,0x7681,0x7685,0x768C,0x768D, @@ -7750,7 +7750,7 @@ static uint16 tab_jisx0212_uni38[]={ 0x7757,0x775C,0x775E,0x775F,0x7760,0x7762}; /* page 39 0x4F21-0x4F7E */ -static uint16 tab_jisx0212_uni39[]={ +static const uint16 tab_jisx0212_uni39[]={ 0x7764,0x7767,0x776A,0x776C,0x7770,0x7772,0x7773,0x7774, 0x777A,0x777D,0x7780,0x7784,0x778C,0x778D,0x7794,0x7795, 0x7796,0x779A,0x779F,0x77A2,0x77A7,0x77AA,0x77AE,0x77AF, @@ -7765,7 +7765,7 @@ static uint16 tab_jisx0212_uni39[]={ 0x78AC,0x78AD,0x78B0,0x78B1,0x78B2,0x78B3}; /* page 40 0x5021-0x507E */ -static uint16 tab_jisx0212_uni40[]={ +static const uint16 tab_jisx0212_uni40[]={ 0x78BB,0x78BD,0x78BF,0x78C7,0x78C8,0x78C9,0x78CC,0x78CE, 0x78D2,0x78D3,0x78D5,0x78D6,0x78E4,0x78DB,0x78DF,0x78E0, 0x78E1,0x78E6,0x78EA,0x78F2,0x78F3,0x7900,0x78F6,0x78F7, @@ -7780,7 +7780,7 @@ static uint16 tab_jisx0212_uni40[]={ 0x79CF,0x79D4,0x79D6,0x79DA,0x79DD,0x79DE}; /* page 41 0x5121-0x517E */ -static uint16 tab_jisx0212_uni41[]={ +static const uint16 tab_jisx0212_uni41[]={ 0x79E0,0x79E2,0x79E5,0x79EA,0x79EB,0x79ED,0x79F1,0x79F8, 0x79FC,0x7A02,0x7A03,0x7A07,0x7A09,0x7A0A,0x7A0C,0x7A11, 0x7A15,0x7A1B,0x7A1E,0x7A21,0x7A27,0x7A2B,0x7A2D,0x7A2F, @@ -7795,7 +7795,7 @@ static uint16 tab_jisx0212_uni41[]={ 0x7B2A,0x7B2B,0x7B2D,0x7B2E,0x7B2F,0x7B30}; /* page 42 0x5221-0x527E */ -static uint16 tab_jisx0212_uni42[]={ +static const uint16 tab_jisx0212_uni42[]={ 0x7B31,0x7B34,0x7B3D,0x7B3F,0x7B40,0x7B41,0x7B47,0x7B4E, 0x7B55,0x7B60,0x7B64,0x7B66,0x7B69,0x7B6A,0x7B6D,0x7B6F, 0x7B72,0x7B73,0x7B77,0x7B84,0x7B89,0x7B8E,0x7B90,0x7B91, @@ -7810,7 +7810,7 @@ static uint16 tab_jisx0212_uni42[]={ 0x7C59,0x7C5A,0x7C5B,0x7C5C,0x7C5D,0x7C5E}; /* page 43 0x5321-0x537E */ -static uint16 tab_jisx0212_uni43[]={ +static const uint16 tab_jisx0212_uni43[]={ 0x7C61,0x7C63,0x7C67,0x7C69,0x7C6D,0x7C6E,0x7C70,0x7C72, 0x7C79,0x7C7C,0x7C7D,0x7C86,0x7C87,0x7C8F,0x7C94,0x7C9E, 0x7CA0,0x7CA6,0x7CB0,0x7CB6,0x7CB7,0x7CBA,0x7CBB,0x7CBC, @@ -7825,7 +7825,7 @@ static uint16 tab_jisx0212_uni43[]={ 0x7D8C,0x7D8D,0x7D91,0x7D96,0x7D97,0x7D9D}; /* page 44 0x5421-0x547E */ -static uint16 tab_jisx0212_uni44[]={ +static const uint16 tab_jisx0212_uni44[]={ 0x7D9E,0x7DA6,0x7DA7,0x7DAA,0x7DB3,0x7DB6,0x7DB7,0x7DB9, 0x7DC2,0x7DC3,0x7DC4,0x7DC5,0x7DC6,0x7DCC,0x7DCD,0x7DCE, 0x7DD7,0x7DD9,0x7E00,0x7DE2,0x7DE5,0x7DE6,0x7DEA,0x7DEB, @@ -7840,7 +7840,7 @@ static uint16 tab_jisx0212_uni44[]={ 0x7F61,0x7F63,0x7F64,0x7F65,0x7F66,0x7F6D}; /* page 45 0x5521-0x557E */ -static uint16 tab_jisx0212_uni45[]={ +static const uint16 tab_jisx0212_uni45[]={ 0x7F71,0x7F7D,0x7F7E,0x7F7F,0x7F80,0x7F8B,0x7F8D,0x7F8F, 0x7F90,0x7F91,0x7F96,0x7F97,0x7F9C,0x7FA1,0x7FA2,0x7FA6, 0x7FAA,0x7FAD,0x7FB4,0x7FBC,0x7FBF,0x7FC0,0x7FC3,0x7FC8, @@ -7855,7 +7855,7 @@ static uint16 tab_jisx0212_uni45[]={ 0x80D5,0x80D7,0x80D8,0x80E0,0x80ED,0x80EE}; /* page 46 0x5621-0x567E */ -static uint16 tab_jisx0212_uni46[]={ +static const uint16 tab_jisx0212_uni46[]={ 0x80F0,0x80F2,0x80F3,0x80F6,0x80F9,0x80FA,0x80FE,0x8103, 0x810B,0x8116,0x8117,0x8118,0x811C,0x811E,0x8120,0x8124, 0x8127,0x812C,0x8130,0x8135,0x813A,0x813C,0x8145,0x8147, @@ -7870,7 +7870,7 @@ static uint16 tab_jisx0212_uni46[]={ 0x8234,0x823A,0x8243,0x8244,0x8245,0x8246}; /* page 47 0x5721-0x577E */ -static uint16 tab_jisx0212_uni47[]={ +static const uint16 tab_jisx0212_uni47[]={ 0x824B,0x824E,0x824F,0x8251,0x8256,0x825C,0x8260,0x8263, 0x8267,0x826D,0x8274,0x827B,0x827D,0x827F,0x8280,0x8281, 0x8283,0x8284,0x8287,0x8289,0x828A,0x828E,0x8291,0x8294, @@ -7885,7 +7885,7 @@ static uint16 tab_jisx0212_uni47[]={ 0x8351,0x8355,0x8356,0x8357,0x8370,0x8378}; /* page 48 0x5821-0x587E */ -static uint16 tab_jisx0212_uni48[]={ +static const uint16 tab_jisx0212_uni48[]={ 0x837D,0x837F,0x8380,0x8382,0x8384,0x8386,0x838D,0x8392, 0x8394,0x8395,0x8398,0x8399,0x839B,0x839C,0x839D,0x83A6, 0x83A7,0x83A9,0x83AC,0x83BE,0x83BF,0x83C0,0x83C7,0x83C9, @@ -7900,7 +7900,7 @@ static uint16 tab_jisx0212_uni48[]={ 0x84C2,0x84C7,0x84C8,0x84CC,0x84CF,0x84D3}; /* page 49 0x5921-0x597E */ -static uint16 tab_jisx0212_uni49[]={ +static const uint16 tab_jisx0212_uni49[]={ 0x84DC,0x84E7,0x84EA,0x84EF,0x84F0,0x84F1,0x84F2,0x84F7, 0x8532,0x84FA,0x84FB,0x84FD,0x8502,0x8503,0x8507,0x850C, 0x850E,0x8510,0x851C,0x851E,0x8522,0x8523,0x8524,0x8525, @@ -7915,7 +7915,7 @@ static uint16 tab_jisx0212_uni49[]={ 0x85E6,0x85E8,0x85ED,0x85F3,0x85F6,0x85FC}; /* page 50 0x5A21-0x5A7E */ -static uint16 tab_jisx0212_uni50[]={ +static const uint16 tab_jisx0212_uni50[]={ 0x85FF,0x8600,0x8604,0x8605,0x860D,0x860E,0x8610,0x8611, 0x8612,0x8618,0x8619,0x861B,0x861E,0x8621,0x8627,0x8629, 0x8636,0x8638,0x863A,0x863C,0x863D,0x8640,0x8642,0x8646, @@ -7930,7 +7930,7 @@ static uint16 tab_jisx0212_uni50[]={ 0x8714,0x8719,0x871E,0x871F,0x8721,0x8723}; /* page 51 0x5B21-0x5B7E */ -static uint16 tab_jisx0212_uni51[]={ +static const uint16 tab_jisx0212_uni51[]={ 0x8728,0x872E,0x872F,0x8731,0x8732,0x8739,0x873A,0x873C, 0x873D,0x873E,0x8740,0x8743,0x8745,0x874D,0x8758,0x875D, 0x8761,0x8764,0x8765,0x876F,0x8771,0x8772,0x877B,0x8783, @@ -7945,7 +7945,7 @@ static uint16 tab_jisx0212_uni51[]={ 0x8828,0x882D,0x882E,0x8830,0x8832,0x8835}; /* page 52 0x5C21-0x5C7E */ -static uint16 tab_jisx0212_uni52[]={ +static const uint16 tab_jisx0212_uni52[]={ 0x883A,0x883C,0x8841,0x8843,0x8845,0x8848,0x8849,0x884A, 0x884B,0x884E,0x8851,0x8855,0x8856,0x8858,0x885A,0x885C, 0x885F,0x8860,0x8864,0x8869,0x8871,0x8879,0x887B,0x8880, @@ -7960,7 +7960,7 @@ static uint16 tab_jisx0212_uni52[]={ 0x896B,0x896E,0x8970,0x8973,0x8975,0x897A}; /* page 53 0x5D21-0x5D7E */ -static uint16 tab_jisx0212_uni53[]={ +static const uint16 tab_jisx0212_uni53[]={ 0x897B,0x897C,0x897D,0x8989,0x898D,0x8990,0x8994,0x8995, 0x899B,0x899C,0x899F,0x89A0,0x89A5,0x89B0,0x89B4,0x89B5, 0x89B6,0x89B7,0x89BC,0x89D4,0x89D5,0x89D6,0x89D7,0x89D8, @@ -7975,7 +7975,7 @@ static uint16 tab_jisx0212_uni53[]={ 0x8A9F,0x8AA7,0x8AA9,0x8AAE,0x8AAF,0x8AB3}; /* page 54 0x5E21-0x5E7E */ -static uint16 tab_jisx0212_uni54[]={ +static const uint16 tab_jisx0212_uni54[]={ 0x8AB6,0x8AB7,0x8ABB,0x8ABE,0x8AC3,0x8AC6,0x8AC8,0x8AC9, 0x8ACA,0x8AD1,0x8AD3,0x8AD4,0x8AD5,0x8AD7,0x8ADD,0x8ADF, 0x8AEC,0x8AF0,0x8AF4,0x8AF5,0x8AF6,0x8AFC,0x8AFF,0x8B05, @@ -7990,7 +7990,7 @@ static uint16 tab_jisx0212_uni54[]={ 0x8C73,0x8C75,0x8C76,0x8C7B,0x8C7E,0x8C86}; /* page 55 0x5F21-0x5F7E */ -static uint16 tab_jisx0212_uni55[]={ +static const uint16 tab_jisx0212_uni55[]={ 0x8C87,0x8C8B,0x8C90,0x8C92,0x8C93,0x8C99,0x8C9B,0x8C9C, 0x8CA4,0x8CB9,0x8CBA,0x8CC5,0x8CC6,0x8CC9,0x8CCB,0x8CCF, 0x8CD6,0x8CD5,0x8CD9,0x8CDD,0x8CE1,0x8CE8,0x8CEC,0x8CEF, @@ -8005,7 +8005,7 @@ static uint16 tab_jisx0212_uni55[]={ 0x8E11,0x8E14,0x8E16,0x8E20,0x8E21,0x8E22}; /* page 56 0x6021-0x607E */ -static uint16 tab_jisx0212_uni56[]={ +static const uint16 tab_jisx0212_uni56[]={ 0x8E23,0x8E26,0x8E27,0x8E31,0x8E33,0x8E36,0x8E37,0x8E38, 0x8E39,0x8E3D,0x8E40,0x8E41,0x8E4B,0x8E4D,0x8E4E,0x8E4F, 0x8E54,0x8E5B,0x8E5C,0x8E5D,0x8E5E,0x8E61,0x8E62,0x8E69, @@ -8020,7 +8020,7 @@ static uint16 tab_jisx0212_uni56[]={ 0x8F35,0x8F36,0x8F37,0x8F3A,0x8F40,0x8F41}; /* page 57 0x6121-0x617E */ -static uint16 tab_jisx0212_uni57[]={ +static const uint16 tab_jisx0212_uni57[]={ 0x8F43,0x8F47,0x8F4F,0x8F51,0x8F52,0x8F53,0x8F54,0x8F55, 0x8F58,0x8F5D,0x8F5E,0x8F65,0x8F9D,0x8FA0,0x8FA1,0x8FA4, 0x8FA5,0x8FA6,0x8FB5,0x8FB6,0x8FB8,0x8FBE,0x8FC0,0x8FC1, @@ -8035,7 +8035,7 @@ static uint16 tab_jisx0212_uni57[]={ 0x90B4,0x90B6,0x90BD,0x90CC,0x90BE,0x90C3}; /* page 58 0x6221-0x627E */ -static uint16 tab_jisx0212_uni58[]={ +static const uint16 tab_jisx0212_uni58[]={ 0x90C4,0x90C5,0x90C7,0x90C8,0x90D5,0x90D7,0x90D8,0x90D9, 0x90DC,0x90DD,0x90DF,0x90E5,0x90D2,0x90F6,0x90EB,0x90EF, 0x90F0,0x90F4,0x90FE,0x90FF,0x9100,0x9104,0x9105,0x9106, @@ -8050,7 +8050,7 @@ static uint16 tab_jisx0212_uni58[]={ 0x91B3,0x91B6,0x91BB,0x91BC,0x91BD,0x91BF}; /* page 59 0x6321-0x637E */ -static uint16 tab_jisx0212_uni59[]={ +static const uint16 tab_jisx0212_uni59[]={ 0x91C2,0x91C3,0x91C5,0x91D3,0x91D4,0x91D7,0x91D9,0x91DA, 0x91DE,0x91E4,0x91E5,0x91E9,0x91EA,0x91EC,0x91ED,0x91EE, 0x91EF,0x91F0,0x91F1,0x91F7,0x91F9,0x91FB,0x91FD,0x9200, @@ -8065,7 +8065,7 @@ static uint16 tab_jisx0212_uni59[]={ 0x9289,0x928A,0x928D,0x928E,0x9292,0x9297}; /* page 60 0x6421-0x647E */ -static uint16 tab_jisx0212_uni60[]={ +static const uint16 tab_jisx0212_uni60[]={ 0x9299,0x929F,0x92A0,0x92A4,0x92A5,0x92A7,0x92A8,0x92AB, 0x92AF,0x92B2,0x92B6,0x92B8,0x92BA,0x92BB,0x92BC,0x92BD, 0x92BF,0x92C0,0x92C1,0x92C2,0x92C3,0x92C5,0x92C6,0x92C7, @@ -8080,7 +8080,7 @@ static uint16 tab_jisx0212_uni60[]={ 0x936F,0x9370,0x9371,0x9373,0x9374,0x9376}; /* page 61 0x6521-0x657E */ -static uint16 tab_jisx0212_uni61[]={ +static const uint16 tab_jisx0212_uni61[]={ 0x937A,0x937D,0x937F,0x9380,0x9381,0x9382,0x9388,0x938A, 0x938B,0x938D,0x938F,0x9392,0x9395,0x9398,0x939B,0x939E, 0x93A1,0x93A3,0x93A4,0x93A6,0x93A8,0x93AB,0x93B4,0x93B5, @@ -8095,7 +8095,7 @@ static uint16 tab_jisx0212_uni61[]={ 0x9471,0x9472,0x9484,0x9483,0x9578,0x9579}; /* page 62 0x6621-0x667E */ -static uint16 tab_jisx0212_uni62[]={ +static const uint16 tab_jisx0212_uni62[]={ 0x957E,0x9584,0x9588,0x958C,0x958D,0x958E,0x959D,0x959E, 0x959F,0x95A1,0x95A6,0x95A9,0x95AB,0x95AC,0x95B4,0x95B6, 0x95BA,0x95BD,0x95BF,0x95C6,0x95C8,0x95C9,0x95CB,0x95D0, @@ -8110,7 +8110,7 @@ static uint16 tab_jisx0212_uni62[]={ 0x96DF,0x96E9,0x96EF,0x96F1,0x96FA,0x9702}; /* page 63 0x6721-0x677E */ -static uint16 tab_jisx0212_uni63[]={ +static const uint16 tab_jisx0212_uni63[]={ 0x9703,0x9705,0x9709,0x971A,0x971B,0x971D,0x9721,0x9722, 0x9723,0x9728,0x9731,0x9733,0x9741,0x9743,0x974A,0x974E, 0x974F,0x9755,0x9757,0x9758,0x975A,0x975B,0x9763,0x9767, @@ -8125,7 +8125,7 @@ static uint16 tab_jisx0212_uni63[]={ 0x9816,0x981C,0x981E,0x9820,0x9823,0x9826}; /* page 64 0x6821-0x687E */ -static uint16 tab_jisx0212_uni64[]={ +static const uint16 tab_jisx0212_uni64[]={ 0x982B,0x982E,0x982F,0x9830,0x9832,0x9833,0x9835,0x9825, 0x983E,0x9844,0x9847,0x984A,0x9851,0x9852,0x9853,0x9856, 0x9857,0x9859,0x985A,0x9862,0x9863,0x9865,0x9866,0x986A, @@ -8140,7 +8140,7 @@ static uint16 tab_jisx0212_uni64[]={ 0x999F,0x99A6,0x99B0,0x99B1,0x99B2,0x99B5}; /* page 65 0x6921-0x697E */ -static uint16 tab_jisx0212_uni65[]={ +static const uint16 tab_jisx0212_uni65[]={ 0x99B9,0x99BA,0x99BD,0x99BF,0x99C3,0x99C9,0x99D3,0x99D4, 0x99D9,0x99DA,0x99DC,0x99DE,0x99E7,0x99EA,0x99EB,0x99EC, 0x99F0,0x99F4,0x99F5,0x99F9,0x99FD,0x99FE,0x9A02,0x9A03, @@ -8155,7 +8155,7 @@ static uint16 tab_jisx0212_uni65[]={ 0x9AFD,0x9AFF,0x9B00,0x9B01,0x9B02,0x9B03}; /* page 66 0x6A21-0x6A7E */ -static uint16 tab_jisx0212_uni66[]={ +static const uint16 tab_jisx0212_uni66[]={ 0x9B04,0x9B05,0x9B08,0x9B09,0x9B0B,0x9B0C,0x9B0D,0x9B0E, 0x9B10,0x9B12,0x9B16,0x9B19,0x9B1B,0x9B1C,0x9B20,0x9B26, 0x9B2B,0x9B2D,0x9B33,0x9B34,0x9B35,0x9B37,0x9B39,0x9B3A, @@ -8170,7 +8170,7 @@ static uint16 tab_jisx0212_uni66[]={ 0x9BEA,0x9BEB,0x9BEF,0x9BF3,0x9BF7,0x9BF8}; /* page 67 0x6B21-0x6B7E */ -static uint16 tab_jisx0212_uni67[]={ +static const uint16 tab_jisx0212_uni67[]={ 0x9BF9,0x9BFA,0x9BFD,0x9BFF,0x9C00,0x9C02,0x9C0B,0x9C0F, 0x9C11,0x9C16,0x9C18,0x9C19,0x9C1A,0x9C1C,0x9C1E,0x9C22, 0x9C23,0x9C26,0x9C27,0x9C28,0x9C29,0x9C2A,0x9C31,0x9C35, @@ -8185,7 +8185,7 @@ static uint16 tab_jisx0212_uni67[]={ 0x9D6A,0x9D6B,0x9D70,0x9D76,0x9D77,0x9D7B}; /* page 68 0x6C21-0x6C7E */ -static uint16 tab_jisx0212_uni68[]={ +static const uint16 tab_jisx0212_uni68[]={ 0x9D7C,0x9D7E,0x9D83,0x9D84,0x9D86,0x9D8A,0x9D8D,0x9D8E, 0x9D92,0x9D93,0x9D95,0x9D96,0x9D97,0x9D98,0x9DA1,0x9DAA, 0x9DAC,0x9DAE,0x9DB1,0x9DB5,0x9DB9,0x9DBC,0x9DBF,0x9DC3, @@ -8200,7 +8200,7 @@ static uint16 tab_jisx0212_uni68[]={ 0x9EED,0x9EEE,0x9EF0,0x9EF1,0x9EF2,0x9EF5}; /* page 69 0x6D21-0x6D63 */ -static uint16 tab_jisx0212_uni69[]={ +static const uint16 tab_jisx0212_uni69[]={ 0x9EF8,0x9EFF,0x9F02,0x9F03,0x9F09,0x9F0F,0x9F10,0x9F11, 0x9F12,0x9F14,0x9F16,0x9F17,0x9F19,0x9F1A,0x9F1B,0x9F1F, 0x9F22,0x9F26,0x9F2A,0x9F2B,0x9F2F,0x9F31,0x9F32,0x9F34, @@ -8212,12 +8212,12 @@ static uint16 tab_jisx0212_uni69[]={ 0x9FA2,0x9FA3,0x9FA5}; /* page 70 0x7371-0x737E IBM Kanji and Nonkanji */ -static uint16 tab_jisx0212_uni70[]={ +static const uint16 tab_jisx0212_uni70[]={ 0, 0,0x2170,0x2171,0x2172,0x2173,0x2174,0x2175, 0x2176,0x2177,0x2178,0x2179,0x2160,0x2161}; /* page 71 0x7421-0x747E IBM Kanji and Nonkanji*/ -static uint16 tab_jisx0212_uni71[]={ +static const uint16 tab_jisx0212_uni71[]={ 0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,0x2168,0x2169, 0xFF07,0xFF02,0x3231,0x2116,0x2121,0x70BB,0x4EFC,0x50F4, 0x51EC,0x5307,0x5324,0xFA0E,0x548A,0x5759,0xFA0F,0xFA10, @@ -8687,7 +8687,7 @@ static MY_CHARSET_HANDLER my_charset_handler= -CHARSET_INFO my_charset_eucjpms_japanese_ci= +struct charset_info_st my_charset_eucjpms_japanese_ci= { 97,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ @@ -8720,7 +8720,7 @@ CHARSET_INFO my_charset_eucjpms_japanese_ci= }; -CHARSET_INFO my_charset_eucjpms_bin= +struct charset_info_st my_charset_eucjpms_bin= { 98,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT, /* state */ diff --git a/strings/ctype-extra.c b/strings/ctype-extra.c index b116e3d218d..4b1109379d1 100644 --- a/strings/ctype-extra.c +++ b/strings/ctype-extra.c @@ -6,7 +6,8 @@ ./conf_to_src ../sql/share/charsets/ > FILE */ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. +/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. + Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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,7 +27,7 @@ #include <m_ctype.h> #ifdef HAVE_CHARSET_dec8 -uchar ctype_dec8_swedish_ci[] = { +static const uchar ctype_dec8_swedish_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -46,7 +47,7 @@ uchar ctype_dec8_swedish_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_dec8_swedish_ci[] = { +static const uchar to_lower_dec8_swedish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -65,7 +66,7 @@ uchar to_lower_dec8_swedish_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_dec8_swedish_ci[] = { +static const uchar to_upper_dec8_swedish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -84,7 +85,7 @@ uchar to_upper_dec8_swedish_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_dec8_swedish_ci[] = { +static const uchar sort_order_dec8_swedish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -103,7 +104,7 @@ uchar sort_order_dec8_swedish_ci[] = { 0x44,0x4E,0x4F,0x4F,0x4F,0x4F,0x5D,0xF7,0xD8,0x55,0x55,0x55,0x59,0x59,0xDE,0xFF }; -uint16 to_uni_dec8_swedish_ci[] = { +static const uint16 to_uni_dec8_swedish_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -141,7 +142,7 @@ uint16 to_uni_dec8_swedish_ci[] = { #endif #ifdef HAVE_CHARSET_cp850 -uchar ctype_cp850_general_ci[] = { +static const uchar ctype_cp850_general_ci[] = { 0x00, 0x20,0x30,0x30,0x30,0x30,0x30,0x30,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x30,0x30, 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x20,0x30,0x30,0x30,0x30,0x30, @@ -161,7 +162,7 @@ uchar ctype_cp850_general_ci[] = { 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20 }; -uchar to_lower_cp850_general_ci[] = { +static const uchar to_lower_cp850_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -180,7 +181,7 @@ uchar to_lower_cp850_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp850_general_ci[] = { +static const uchar to_upper_cp850_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -199,7 +200,7 @@ uchar to_upper_cp850_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_cp850_general_ci[] = { +static const uchar sort_order_cp850_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -218,7 +219,7 @@ uchar sort_order_cp850_general_ci[] = { 0xED,0xF1,0xC1,0xFE,0xF6,0xE7,0xBF,0xBC,0xF0,0xE8,0xF7,0xF9,0xF3,0xF2,0xDF,0xE0 }; -uint16 to_uni_cp850_general_ci[] = { +static const uint16 to_uni_cp850_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -256,7 +257,7 @@ uint16 to_uni_cp850_general_ci[] = { #endif #ifdef HAVE_CHARSET_latin1 -uchar ctype_latin1_german1_ci[] = { +static const uchar ctype_latin1_german1_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -276,7 +277,7 @@ uchar ctype_latin1_german1_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_latin1_german1_ci[] = { +static const uchar to_lower_latin1_german1_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -295,7 +296,7 @@ uchar to_lower_latin1_german1_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin1_german1_ci[] = { +static const uchar to_upper_latin1_german1_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -314,7 +315,7 @@ uchar to_upper_latin1_german1_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin1_german1_ci[] = { +static const uchar sort_order_latin1_german1_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -333,7 +334,7 @@ uchar sort_order_latin1_german1_ci[] = { 0xD0,0x4E,0x4F,0x4F,0x4F,0x4F,0x4F,0xF7,0x4F,0x55,0x55,0x55,0x55,0x59,0xDE,0xFF }; -uint16 to_uni_latin1_german1_ci[] = { +static const uint16 to_uni_latin1_german1_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -371,7 +372,7 @@ uint16 to_uni_latin1_german1_ci[] = { #endif #ifdef HAVE_CHARSET_hp8 -uchar ctype_hp8_english_ci[] = { +static const uchar ctype_hp8_english_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -391,7 +392,7 @@ uchar ctype_hp8_english_ci[] = { 0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20 }; -uchar to_lower_hp8_english_ci[] = { +static const uchar to_lower_hp8_english_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -410,7 +411,7 @@ uchar to_lower_hp8_english_ci[] = { 0xF1,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_hp8_english_ci[] = { +static const uchar to_upper_hp8_english_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -429,7 +430,7 @@ uchar to_upper_hp8_english_ci[] = { 0xF0,0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_hp8_english_ci[] = { +static const uchar sort_order_hp8_english_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -448,7 +449,7 @@ uchar sort_order_hp8_english_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_hp8_english_ci[] = { +static const uint16 to_uni_hp8_english_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -486,7 +487,7 @@ uint16 to_uni_hp8_english_ci[] = { #endif #ifdef HAVE_CHARSET_koi8r -uchar ctype_koi8r_general_ci[] = { +static const uchar ctype_koi8r_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -506,7 +507,7 @@ uchar ctype_koi8r_general_ci[] = { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }; -uchar to_lower_koi8r_general_ci[] = { +static const uchar to_lower_koi8r_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -525,7 +526,7 @@ uchar to_lower_koi8r_general_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF }; -uchar to_upper_koi8r_general_ci[] = { +static const uchar to_upper_koi8r_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -544,7 +545,7 @@ uchar to_upper_koi8r_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_koi8r_general_ci[] = { +static const uchar sort_order_koi8r_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -563,7 +564,7 @@ uchar sort_order_koi8r_general_ci[] = { 0xEF,0xFF,0xF0,0xF1,0xF2,0xF3,0xE6,0xE1,0xFC,0xFB,0xE7,0xF8,0xFD,0xF9,0xF7,0xFA }; -uint16 to_uni_koi8r_general_ci[] = { +static const uint16 to_uni_koi8r_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -601,7 +602,7 @@ uint16 to_uni_koi8r_general_ci[] = { #endif #ifdef HAVE_CHARSET_latin2 -uchar ctype_latin2_general_ci[] = { +static const uchar ctype_latin2_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -621,7 +622,7 @@ uchar ctype_latin2_general_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_latin2_general_ci[] = { +static const uchar to_lower_latin2_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -640,7 +641,7 @@ uchar to_lower_latin2_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin2_general_ci[] = { +static const uchar to_upper_latin2_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -659,7 +660,7 @@ uchar to_upper_latin2_general_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin2_general_ci[] = { +static const uchar sort_order_latin2_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -678,7 +679,7 @@ uchar sort_order_latin2_general_ci[] = { 0xFF,0x55,0x54,0x57,0x56,0x56,0x56,0xFF,0x5A,0x5F,0x5F,0x5F,0x5F,0x63,0x5E,0xFF }; -uint16 to_uni_latin2_general_ci[] = { +static const uint16 to_uni_latin2_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -716,7 +717,7 @@ uint16 to_uni_latin2_general_ci[] = { #endif #ifdef HAVE_CHARSET_swe7 -uchar ctype_swe7_swedish_ci[] = { +static const uchar ctype_swe7_swedish_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -736,7 +737,7 @@ uchar ctype_swe7_swedish_ci[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar to_lower_swe7_swedish_ci[] = { +static const uchar to_lower_swe7_swedish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -755,7 +756,7 @@ uchar to_lower_swe7_swedish_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_swe7_swedish_ci[] = { +static const uchar to_upper_swe7_swedish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -774,7 +775,7 @@ uchar to_upper_swe7_swedish_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_swe7_swedish_ci[] = { +static const uchar sort_order_swe7_swedish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -793,7 +794,7 @@ uchar sort_order_swe7_swedish_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_swe7_swedish_ci[] = { +static const uint16 to_uni_swe7_swedish_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -831,7 +832,7 @@ uint16 to_uni_swe7_swedish_ci[] = { #endif #ifdef HAVE_CHARSET_ascii -uchar ctype_ascii_general_ci[] = { +static const uchar ctype_ascii_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -851,7 +852,7 @@ uchar ctype_ascii_general_ci[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar to_lower_ascii_general_ci[] = { +static const uchar to_lower_ascii_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -870,7 +871,7 @@ uchar to_lower_ascii_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_ascii_general_ci[] = { +static const uchar to_upper_ascii_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -889,7 +890,7 @@ uchar to_upper_ascii_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_ascii_general_ci[] = { +static const uchar sort_order_ascii_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -908,7 +909,7 @@ uchar sort_order_ascii_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_ascii_general_ci[] = { +static const uint16 to_uni_ascii_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -946,7 +947,7 @@ uint16 to_uni_ascii_general_ci[] = { #endif #ifdef HAVE_CHARSET_cp1251 -uchar ctype_cp1251_bulgarian_ci[] = { +static const uchar ctype_cp1251_bulgarian_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -966,7 +967,7 @@ uchar ctype_cp1251_bulgarian_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_cp1251_bulgarian_ci[] = { +static const uchar to_lower_cp1251_bulgarian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -985,7 +986,7 @@ uchar to_lower_cp1251_bulgarian_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1251_bulgarian_ci[] = { +static const uchar to_upper_cp1251_bulgarian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1004,7 +1005,7 @@ uchar to_upper_cp1251_bulgarian_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF }; -uchar sort_order_cp1251_bulgarian_ci[] = { +static const uchar sort_order_cp1251_bulgarian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1023,7 +1024,7 @@ uchar sort_order_cp1251_bulgarian_ci[] = { 0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B }; -uint16 to_uni_cp1251_bulgarian_ci[] = { +static const uint16 to_uni_cp1251_bulgarian_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -1061,7 +1062,7 @@ uint16 to_uni_cp1251_bulgarian_ci[] = { #endif #ifdef HAVE_CHARSET_latin1 -uchar ctype_latin1_danish_ci[] = { +static const uchar ctype_latin1_danish_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -1081,7 +1082,7 @@ uchar ctype_latin1_danish_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_latin1_danish_ci[] = { +static const uchar to_lower_latin1_danish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1100,7 +1101,7 @@ uchar to_lower_latin1_danish_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin1_danish_ci[] = { +static const uchar to_upper_latin1_danish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1119,7 +1120,7 @@ uchar to_upper_latin1_danish_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin1_danish_ci[] = { +static const uchar sort_order_latin1_danish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1138,7 +1139,7 @@ uchar sort_order_latin1_danish_ci[] = { 0x44,0x4E,0x4F,0x4F,0x4F,0x4F,0x5C,0xF7,0x5C,0x55,0x55,0x55,0x59,0x59,0xDE,0xFF }; -uint16 to_uni_latin1_danish_ci[] = { +static const uint16 to_uni_latin1_danish_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -1176,7 +1177,7 @@ uint16 to_uni_latin1_danish_ci[] = { #endif #ifdef HAVE_CHARSET_hebrew -uchar ctype_hebrew_general_ci[] = { +static const uchar ctype_hebrew_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -1196,7 +1197,7 @@ uchar ctype_hebrew_general_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x20,0x20,0x00 }; -uchar to_lower_hebrew_general_ci[] = { +static const uchar to_lower_hebrew_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1215,7 +1216,7 @@ uchar to_lower_hebrew_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_hebrew_general_ci[] = { +static const uchar to_upper_hebrew_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1234,7 +1235,7 @@ uchar to_upper_hebrew_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_hebrew_general_ci[] = { +static const uchar sort_order_hebrew_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1253,7 +1254,7 @@ uchar sort_order_hebrew_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_hebrew_general_ci[] = { +static const uint16 to_uni_hebrew_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -1291,7 +1292,7 @@ uint16 to_uni_hebrew_general_ci[] = { #endif #ifdef HAVE_CHARSET_latin7 -uchar ctype_latin7_estonian_cs[] = { +static const uchar ctype_latin7_estonian_cs[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -1311,7 +1312,7 @@ uchar ctype_latin7_estonian_cs[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_latin7_estonian_cs[] = { +static const uchar to_lower_latin7_estonian_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1330,7 +1331,7 @@ uchar to_lower_latin7_estonian_cs[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin7_estonian_cs[] = { +static const uchar to_upper_latin7_estonian_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1349,7 +1350,7 @@ uchar to_upper_latin7_estonian_cs[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin7_estonian_cs[] = { +static const uchar sort_order_latin7_estonian_cs[] = { 0x00,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x2E,0x2F,0x30,0x31,0x32,0x0A,0x0B, 0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B, 0x2C,0x33,0x34,0x35,0x36,0x37,0x38,0x27,0x39,0x3A,0x3B,0x5D,0x3C,0x28,0x3D,0x3E, @@ -1368,7 +1369,7 @@ uchar sort_order_latin7_estonian_cs[] = { 0xDC,0xC3,0xC5,0xC9,0xCB,0xF3,0xF7,0x65,0xED,0xBD,0xD9,0xEB,0xF9,0xE2,0xE4,0x53 }; -uint16 to_uni_latin7_estonian_cs[] = { +static const uint16 to_uni_latin7_estonian_cs[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -1406,7 +1407,7 @@ uint16 to_uni_latin7_estonian_cs[] = { #endif #ifdef HAVE_CHARSET_latin2 -uchar ctype_latin2_hungarian_ci[] = { +static const uchar ctype_latin2_hungarian_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -1426,7 +1427,7 @@ uchar ctype_latin2_hungarian_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_latin2_hungarian_ci[] = { +static const uchar to_lower_latin2_hungarian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1445,7 +1446,7 @@ uchar to_lower_latin2_hungarian_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin2_hungarian_ci[] = { +static const uchar to_upper_latin2_hungarian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1464,7 +1465,7 @@ uchar to_upper_latin2_hungarian_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin2_hungarian_ci[] = { +static const uchar sort_order_latin2_hungarian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1483,7 +1484,7 @@ uchar sort_order_latin2_hungarian_ci[] = { 0xFF,0x62,0x63,0x64,0x66,0x67,0x67,0xFF,0x6D,0x77,0x75,0x78,0x78,0x7E,0x74,0xFF }; -uint16 to_uni_latin2_hungarian_ci[] = { +static const uint16 to_uni_latin2_hungarian_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -1521,7 +1522,7 @@ uint16 to_uni_latin2_hungarian_ci[] = { #endif #ifdef HAVE_CHARSET_koi8u -uchar ctype_koi8u_general_ci[] = { +static const uchar ctype_koi8u_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -1541,7 +1542,7 @@ uchar ctype_koi8u_general_ci[] = { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }; -uchar to_lower_koi8u_general_ci[] = { +static const uchar to_lower_koi8u_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1560,7 +1561,7 @@ uchar to_lower_koi8u_general_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF }; -uchar to_upper_koi8u_general_ci[] = { +static const uchar to_upper_koi8u_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1579,7 +1580,7 @@ uchar to_upper_koi8u_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_koi8u_general_ci[] = { +static const uchar sort_order_koi8u_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1598,7 +1599,7 @@ uchar sort_order_koi8u_general_ci[] = { 0x94,0xA4,0x95,0x96,0x97,0x98,0x89,0x82,0xA1,0xA0,0x8A,0x9D,0xA2,0x9E,0x9C,0x9F }; -uint16 to_uni_koi8u_general_ci[] = { +static const uint16 to_uni_koi8u_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -1636,7 +1637,7 @@ uint16 to_uni_koi8u_general_ci[] = { #endif #ifdef HAVE_CHARSET_cp1251 -uchar ctype_cp1251_ukrainian_ci[] = { +static const uchar ctype_cp1251_ukrainian_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -1656,7 +1657,7 @@ uchar ctype_cp1251_ukrainian_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_cp1251_ukrainian_ci[] = { +static const uchar to_lower_cp1251_ukrainian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1675,7 +1676,7 @@ uchar to_lower_cp1251_ukrainian_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1251_ukrainian_ci[] = { +static const uchar to_upper_cp1251_ukrainian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1694,7 +1695,7 @@ uchar to_upper_cp1251_ukrainian_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF }; -uchar sort_order_cp1251_ukrainian_ci[] = { +static const uchar sort_order_cp1251_ukrainian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1713,7 +1714,7 @@ uchar sort_order_cp1251_ukrainian_ci[] = { 0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4 }; -uint16 to_uni_cp1251_ukrainian_ci[] = { +static const uint16 to_uni_cp1251_ukrainian_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -1751,7 +1752,7 @@ uint16 to_uni_cp1251_ukrainian_ci[] = { #endif #ifdef HAVE_CHARSET_greek -uchar ctype_greek_general_ci[] = { +static const uchar ctype_greek_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -1771,7 +1772,7 @@ uchar ctype_greek_general_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00 }; -uchar to_lower_greek_general_ci[] = { +static const uchar to_lower_greek_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1790,7 +1791,7 @@ uchar to_lower_greek_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_greek_general_ci[] = { +static const uchar to_upper_greek_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1809,7 +1810,7 @@ uchar to_upper_greek_general_ci[] = { 0xD0,0xD1,0xD3,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xCF,0xD5,0xD9,0xFF }; -uchar sort_order_greek_general_ci[] = { +static const uchar sort_order_greek_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1828,7 +1829,7 @@ uchar sort_order_greek_general_ci[] = { 0xD0,0xD1,0xD3,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xC9,0xD5,0xCF,0xD5,0xD9,0xFF }; -uint16 to_uni_greek_general_ci[] = { +static const uint16 to_uni_greek_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -1866,7 +1867,7 @@ uint16 to_uni_greek_general_ci[] = { #endif #ifdef HAVE_CHARSET_cp1250 -uchar ctype_cp1250_general_ci[] = { +static const uchar ctype_cp1250_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -1886,7 +1887,7 @@ uchar ctype_cp1250_general_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_cp1250_general_ci[] = { +static const uchar to_lower_cp1250_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1905,7 +1906,7 @@ uchar to_lower_cp1250_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1250_general_ci[] = { +static const uchar to_upper_cp1250_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1924,7 +1925,7 @@ uchar to_upper_cp1250_general_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_cp1250_general_ci[] = { +static const uchar sort_order_cp1250_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -1943,7 +1944,7 @@ uchar sort_order_cp1250_general_ci[] = { 0x47,0x53,0x53,0x55,0x55,0x55,0x55,0xF7,0x58,0x5C,0x5C,0x5C,0x5C,0x60,0x5B,0xFF }; -uint16 to_uni_cp1250_general_ci[] = { +static const uint16 to_uni_cp1250_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -1981,7 +1982,7 @@ uint16 to_uni_cp1250_general_ci[] = { #endif #ifdef HAVE_CHARSET_latin2 -uchar ctype_latin2_croatian_ci[] = { +static const uchar ctype_latin2_croatian_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -2001,7 +2002,7 @@ uchar ctype_latin2_croatian_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_latin2_croatian_ci[] = { +static const uchar to_lower_latin2_croatian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2020,7 +2021,7 @@ uchar to_lower_latin2_croatian_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin2_croatian_ci[] = { +static const uchar to_upper_latin2_croatian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2039,7 +2040,7 @@ uchar to_upper_latin2_croatian_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin2_croatian_ci[] = { +static const uchar sort_order_latin2_croatian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2058,7 +2059,7 @@ uchar sort_order_latin2_croatian_ci[] = { 0x4A,0x57,0x57,0x59,0x59,0x59,0x59,0xFE,0x5D,0x64,0x64,0x64,0x64,0x69,0x62,0xFF }; -uint16 to_uni_latin2_croatian_ci[] = { +static const uint16 to_uni_latin2_croatian_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -2096,7 +2097,7 @@ uint16 to_uni_latin2_croatian_ci[] = { #endif #ifdef HAVE_CHARSET_cp1257 -uchar ctype_cp1257_lithuanian_ci[] = { +static const uchar ctype_cp1257_lithuanian_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -2116,7 +2117,7 @@ uchar ctype_cp1257_lithuanian_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00 }; -uchar to_lower_cp1257_lithuanian_ci[] = { +static const uchar to_lower_cp1257_lithuanian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2135,7 +2136,7 @@ uchar to_lower_cp1257_lithuanian_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1257_lithuanian_ci[] = { +static const uchar to_upper_cp1257_lithuanian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2154,7 +2155,7 @@ uchar to_upper_cp1257_lithuanian_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_cp1257_lithuanian_ci[] = { +static const uchar sort_order_cp1257_lithuanian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2173,7 +2174,7 @@ uchar sort_order_cp1257_lithuanian_ci[] = { 0x5A,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x5E,0xFF,0xFF,0x5D,0xFF,0xFF,0xFF,0xFF }; -uint16 to_uni_cp1257_lithuanian_ci[] = { +static const uint16 to_uni_cp1257_lithuanian_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -2211,7 +2212,7 @@ uint16 to_uni_cp1257_lithuanian_ci[] = { #endif #ifdef HAVE_CHARSET_latin5 -uchar ctype_latin5_turkish_ci[] = { +static const uchar ctype_latin5_turkish_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -2231,7 +2232,7 @@ uchar ctype_latin5_turkish_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_latin5_turkish_ci[] = { +static const uchar to_lower_latin5_turkish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2250,7 +2251,7 @@ uchar to_lower_latin5_turkish_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin5_turkish_ci[] = { +static const uchar to_upper_latin5_turkish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2269,7 +2270,7 @@ uchar to_upper_latin5_turkish_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0x49,0xDE,0xFF }; -uchar sort_order_latin5_turkish_ci[] = { +static const uchar sort_order_latin5_turkish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2288,7 +2289,7 @@ uchar sort_order_latin5_turkish_ci[] = { 0x49,0x51,0x52,0x52,0x52,0x52,0x53,0xFA,0x52,0x5A,0x5A,0x5A,0x5B,0x4B,0x58,0x5F }; -uint16 to_uni_latin5_turkish_ci[] = { +static const uint16 to_uni_latin5_turkish_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -2326,7 +2327,7 @@ uint16 to_uni_latin5_turkish_ci[] = { #endif #ifdef HAVE_CHARSET_armscii8 -uchar ctype_armscii8_general_ci[] = { +static const uchar ctype_armscii8_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -2346,7 +2347,7 @@ uchar ctype_armscii8_general_ci[] = { 0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x10,0x10 }; -uchar to_lower_armscii8_general_ci[] = { +static const uchar to_lower_armscii8_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2365,7 +2366,7 @@ uchar to_lower_armscii8_general_ci[] = { 0xF1,0xF1,0xF3,0xF3,0xF5,0xF5,0xF7,0xF7,0xF9,0xF9,0xFB,0xFB,0xFD,0xFD,0xFE,0xFF }; -uchar to_upper_armscii8_general_ci[] = { +static const uchar to_upper_armscii8_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2384,7 +2385,7 @@ uchar to_upper_armscii8_general_ci[] = { 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF }; -uchar sort_order_armscii8_general_ci[] = { +static const uchar sort_order_armscii8_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2403,7 +2404,7 @@ uchar sort_order_armscii8_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_armscii8_general_ci[] = { +static const uint16 to_uni_armscii8_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -2441,7 +2442,7 @@ uint16 to_uni_armscii8_general_ci[] = { #endif #ifdef HAVE_CHARSET_cp866 -uchar ctype_cp866_general_ci[] = { +static const uchar ctype_cp866_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -2461,7 +2462,7 @@ uchar ctype_cp866_general_ci[] = { 0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48 }; -uchar to_lower_cp866_general_ci[] = { +static const uchar to_lower_cp866_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2480,7 +2481,7 @@ uchar to_lower_cp866_general_ci[] = { 0xF1,0xF1,0xF3,0xF3,0xF5,0xF5,0xF7,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp866_general_ci[] = { +static const uchar to_upper_cp866_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2499,7 +2500,7 @@ uchar to_upper_cp866_general_ci[] = { 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_cp866_general_ci[] = { +static const uchar sort_order_cp866_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2518,7 +2519,7 @@ uchar sort_order_cp866_general_ci[] = { 0x81,0x81,0x83,0x83,0x8B,0x8B,0xA3,0xA3,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2 }; -uint16 to_uni_cp866_general_ci[] = { +static const uint16 to_uni_cp866_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -2556,7 +2557,7 @@ uint16 to_uni_cp866_general_ci[] = { #endif #ifdef HAVE_CHARSET_keybcs2 -uchar ctype_keybcs2_general_ci[] = { +static const uchar ctype_keybcs2_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -2576,7 +2577,7 @@ uchar ctype_keybcs2_general_ci[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48 }; -uchar to_lower_keybcs2_general_ci[] = { +static const uchar to_lower_keybcs2_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2595,7 +2596,7 @@ uchar to_lower_keybcs2_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_keybcs2_general_ci[] = { +static const uchar to_upper_keybcs2_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2614,7 +2615,7 @@ uchar to_upper_keybcs2_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_keybcs2_general_ci[] = { +static const uchar sort_order_keybcs2_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2633,7 +2634,7 @@ uchar sort_order_keybcs2_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_keybcs2_general_ci[] = { +static const uint16 to_uni_keybcs2_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -2671,7 +2672,7 @@ uint16 to_uni_keybcs2_general_ci[] = { #endif #ifdef HAVE_CHARSET_macce -uchar ctype_macce_general_ci[] = { +static const uchar ctype_macce_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -2691,7 +2692,7 @@ uchar ctype_macce_general_ci[] = { 0x02,0x01,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x02,0x01,0x01,0x02,0x01,0x00 }; -uchar to_lower_macce_general_ci[] = { +static const uchar to_lower_macce_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2710,7 +2711,7 @@ uchar to_lower_macce_general_ci[] = { 0xF0,0xF3,0x9C,0xF3,0xF5,0xF5,0xF7,0xF7,0xF9,0xF9,0xFA,0xFD,0xB8,0xFD,0xAE,0xFF }; -uchar to_upper_macce_general_ci[] = { +static const uchar to_upper_macce_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2729,7 +2730,7 @@ uchar to_upper_macce_general_ci[] = { 0xED,0xF1,0xF2,0xF1,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xB5,0xFB,0xFC,0xFB,0xFE,0xFF }; -uchar sort_order_macce_general_ci[] = { +static const uchar sort_order_macce_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2748,7 +2749,7 @@ uchar sort_order_macce_general_ci[] = { 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x8B,0x8B,0x5B,0x8D,0x5D,0x8D,0x53,0xFF }; -uint16 to_uni_macce_general_ci[] = { +static const uint16 to_uni_macce_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -2786,7 +2787,7 @@ uint16 to_uni_macce_general_ci[] = { #endif #ifdef HAVE_CHARSET_macroman -uchar ctype_macroman_general_ci[] = { +static const uchar ctype_macroman_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -2806,7 +2807,7 @@ uchar ctype_macroman_general_ci[] = { 0x00,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar to_lower_macroman_general_ci[] = { +static const uchar to_lower_macroman_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2825,7 +2826,7 @@ uchar to_lower_macroman_general_ci[] = { 0xF0,0x98,0x9C,0x9E,0x9D,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_macroman_general_ci[] = { +static const uchar to_upper_macroman_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2844,7 +2845,7 @@ uchar to_upper_macroman_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_macroman_general_ci[] = { +static const uchar sort_order_macroman_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2863,7 +2864,7 @@ uchar sort_order_macroman_general_ci[] = { 0xF0,0x72,0x85,0x85,0x85,0x61,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_macroman_general_ci[] = { +static const uint16 to_uni_macroman_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -2901,7 +2902,7 @@ uint16 to_uni_macroman_general_ci[] = { #endif #ifdef HAVE_CHARSET_cp852 -uchar ctype_cp852_general_ci[] = { +static const uchar ctype_cp852_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -2921,7 +2922,7 @@ uchar ctype_cp852_general_ci[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x02,0x00,0x48 }; -uchar to_lower_cp852_general_ci[] = { +static const uchar to_lower_cp852_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2940,7 +2941,7 @@ uchar to_lower_cp852_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp852_general_ci[] = { +static const uchar to_upper_cp852_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2959,7 +2960,7 @@ uchar to_upper_cp852_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF }; -uchar sort_order_cp852_general_ci[] = { +static const uchar sort_order_cp852_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -2978,7 +2979,7 @@ uchar sort_order_cp852_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0x74,0x69,0x69,0xFE,0xFF }; -uint16 to_uni_cp852_general_ci[] = { +static const uint16 to_uni_cp852_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -3016,7 +3017,7 @@ uint16 to_uni_cp852_general_ci[] = { #endif #ifdef HAVE_CHARSET_latin7 -uchar ctype_latin7_general_ci[] = { +static const uchar ctype_latin7_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -3036,7 +3037,7 @@ uchar ctype_latin7_general_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_latin7_general_ci[] = { +static const uchar to_lower_latin7_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3055,7 +3056,7 @@ uchar to_lower_latin7_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin7_general_ci[] = { +static const uchar to_upper_latin7_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3074,7 +3075,7 @@ uchar to_upper_latin7_general_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin7_general_ci[] = { +static const uchar sort_order_latin7_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x30,0x32,0x33,0x34,0x35,0x36,0x37,0x2B,0x38,0x39,0x3A,0x5C,0x3B,0x2C,0x3C,0x3D, @@ -3093,7 +3094,7 @@ uchar sort_order_latin7_general_ci[] = { 0xE1,0xC4,0xC6,0xCA,0xCE,0xD0,0xCC,0x64,0xEC,0xBC,0xDE,0xEA,0xE8,0xFA,0xFC,0x52 }; -uint16 to_uni_latin7_general_ci[] = { +static const uint16 to_uni_latin7_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -3131,7 +3132,7 @@ uint16 to_uni_latin7_general_ci[] = { #endif #ifdef HAVE_CHARSET_latin7 -uchar ctype_latin7_general_cs[] = { +static const uchar ctype_latin7_general_cs[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -3151,7 +3152,7 @@ uchar ctype_latin7_general_cs[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_latin7_general_cs[] = { +static const uchar to_lower_latin7_general_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3170,7 +3171,7 @@ uchar to_lower_latin7_general_cs[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin7_general_cs[] = { +static const uchar to_upper_latin7_general_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3189,7 +3190,7 @@ uchar to_upper_latin7_general_cs[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin7_general_cs[] = { +static const uchar sort_order_latin7_general_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x30,0x32,0x33,0x34,0x35,0x36,0x37,0x2B,0x38,0x39,0x3A,0x5C,0x3B,0x2C,0x3C,0x3D, @@ -3208,7 +3209,7 @@ uchar sort_order_latin7_general_cs[] = { 0xE2,0xC5,0xC7,0xCB,0xCF,0xD1,0xCD,0x64,0xED,0xBD,0xDF,0xEB,0xE9,0xFB,0xFD,0x52 }; -uint16 to_uni_latin7_general_cs[] = { +static const uint16 to_uni_latin7_general_cs[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -3246,7 +3247,7 @@ uint16 to_uni_latin7_general_cs[] = { #endif #ifdef HAVE_CHARSET_macce -uchar ctype_macce_bin[] = { +static const uchar ctype_macce_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -3266,7 +3267,7 @@ uchar ctype_macce_bin[] = { 0x02,0x01,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x02,0x01,0x01,0x02,0x01,0x00 }; -uchar to_lower_macce_bin[] = { +static const uchar to_lower_macce_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3285,7 +3286,7 @@ uchar to_lower_macce_bin[] = { 0xF0,0xF3,0x9C,0xF3,0xF5,0xF5,0xF7,0xF7,0xF9,0xF9,0xFA,0xFD,0xB8,0xFD,0xAE,0xFF }; -uchar to_upper_macce_bin[] = { +static const uchar to_upper_macce_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3304,7 +3305,7 @@ uchar to_upper_macce_bin[] = { 0xED,0xF1,0xF2,0xF1,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xB5,0xFB,0xFC,0xFB,0xFE,0xFF }; -uint16 to_uni_macce_bin[] = { +static const uint16 to_uni_macce_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -3342,7 +3343,7 @@ uint16 to_uni_macce_bin[] = { #endif #ifdef HAVE_CHARSET_cp1250 -uchar ctype_cp1250_croatian_ci[] = { +static const uchar ctype_cp1250_croatian_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -3362,7 +3363,7 @@ uchar ctype_cp1250_croatian_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_cp1250_croatian_ci[] = { +static const uchar to_lower_cp1250_croatian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3381,7 +3382,7 @@ uchar to_lower_cp1250_croatian_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1250_croatian_ci[] = { +static const uchar to_upper_cp1250_croatian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3400,7 +3401,7 @@ uchar to_upper_cp1250_croatian_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_cp1250_croatian_ci[] = { +static const uchar sort_order_cp1250_croatian_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3419,7 +3420,7 @@ uchar sort_order_cp1250_croatian_ci[] = { 0x4A,0x57,0x57,0x59,0x59,0x59,0x59,0xC9,0x5D,0x64,0x64,0x64,0x64,0x69,0x62,0xFF }; -uint16 to_uni_cp1250_croatian_ci[] = { +static const uint16 to_uni_cp1250_croatian_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -3457,7 +3458,7 @@ uint16 to_uni_cp1250_croatian_ci[] = { #endif #ifdef HAVE_CHARSET_latin1 -uchar ctype_latin1_general_ci[] = { +static const uchar ctype_latin1_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -3477,7 +3478,7 @@ uchar ctype_latin1_general_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_latin1_general_ci[] = { +static const uchar to_lower_latin1_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3496,7 +3497,7 @@ uchar to_lower_latin1_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin1_general_ci[] = { +static const uchar to_upper_latin1_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3515,7 +3516,7 @@ uchar to_upper_latin1_general_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin1_general_ci[] = { +static const uchar sort_order_latin1_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3534,7 +3535,7 @@ uchar sort_order_latin1_general_ci[] = { 0x59,0x7F,0x83,0x85,0x87,0x89,0x8B,0xBE,0x8D,0x9C,0x9E,0xA0,0xA2,0xAC,0xB1,0xAE }; -uint16 to_uni_latin1_general_ci[] = { +static const uint16 to_uni_latin1_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -3572,7 +3573,7 @@ uint16 to_uni_latin1_general_ci[] = { #endif #ifdef HAVE_CHARSET_latin1 -uchar ctype_latin1_general_cs[] = { +static const uchar ctype_latin1_general_cs[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -3592,7 +3593,7 @@ uchar ctype_latin1_general_cs[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_latin1_general_cs[] = { +static const uchar to_lower_latin1_general_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3611,7 +3612,7 @@ uchar to_lower_latin1_general_cs[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin1_general_cs[] = { +static const uchar to_upper_latin1_general_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3630,7 +3631,7 @@ uchar to_upper_latin1_general_cs[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin1_general_cs[] = { +static const uchar sort_order_latin1_general_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3649,7 +3650,7 @@ uchar sort_order_latin1_general_cs[] = { 0x5A,0x80,0x84,0x86,0x88,0x8A,0x8C,0xBE,0x8E,0x9D,0x9F,0xA1,0xA3,0xAD,0xB2,0xAE }; -uint16 to_uni_latin1_general_cs[] = { +static const uint16 to_uni_latin1_general_cs[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -3687,7 +3688,7 @@ uint16 to_uni_latin1_general_cs[] = { #endif #ifdef HAVE_CHARSET_cp1251 -uchar ctype_cp1251_bin[] = { +static const uchar ctype_cp1251_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -3707,7 +3708,7 @@ uchar ctype_cp1251_bin[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_cp1251_bin[] = { +static const uchar to_lower_cp1251_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3726,7 +3727,7 @@ uchar to_lower_cp1251_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1251_bin[] = { +static const uchar to_upper_cp1251_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3745,7 +3746,7 @@ uchar to_upper_cp1251_bin[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF }; -uint16 to_uni_cp1251_bin[] = { +static const uint16 to_uni_cp1251_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -3783,7 +3784,7 @@ uint16 to_uni_cp1251_bin[] = { #endif #ifdef HAVE_CHARSET_cp1251 -uchar ctype_cp1251_general_ci[] = { +static const uchar ctype_cp1251_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -3803,7 +3804,7 @@ uchar ctype_cp1251_general_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_cp1251_general_ci[] = { +static const uchar to_lower_cp1251_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3822,7 +3823,7 @@ uchar to_lower_cp1251_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1251_general_ci[] = { +static const uchar to_upper_cp1251_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3841,7 +3842,7 @@ uchar to_upper_cp1251_general_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF }; -uchar sort_order_cp1251_general_ci[] = { +static const uchar sort_order_cp1251_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3860,7 +3861,7 @@ uchar sort_order_cp1251_general_ci[] = { 0xAD,0xAF,0xB1,0xB5,0xB9,0xBB,0xBD,0xBF,0xC3,0xC5,0xC7,0xC9,0xCB,0xCD,0xCF,0xD1 }; -uint16 to_uni_cp1251_general_ci[] = { +static const uint16 to_uni_cp1251_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -3898,7 +3899,7 @@ uint16 to_uni_cp1251_general_ci[] = { #endif #ifdef HAVE_CHARSET_cp1251 -uchar ctype_cp1251_general_cs[] = { +static const uchar ctype_cp1251_general_cs[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -3918,7 +3919,7 @@ uchar ctype_cp1251_general_cs[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_cp1251_general_cs[] = { +static const uchar to_lower_cp1251_general_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3937,7 +3938,7 @@ uchar to_lower_cp1251_general_cs[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1251_general_cs[] = { +static const uchar to_upper_cp1251_general_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3956,7 +3957,7 @@ uchar to_upper_cp1251_general_cs[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF }; -uchar sort_order_cp1251_general_cs[] = { +static const uchar sort_order_cp1251_general_cs[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -3975,7 +3976,7 @@ uchar sort_order_cp1251_general_cs[] = { 0xAE,0xB0,0xB2,0xB6,0xBA,0xBC,0xBE,0xC0,0xC4,0xC6,0xC8,0xCA,0xCC,0xCE,0xD0,0xD2 }; -uint16 to_uni_cp1251_general_cs[] = { +static const uint16 to_uni_cp1251_general_cs[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4013,7 +4014,7 @@ uint16 to_uni_cp1251_general_cs[] = { #endif #ifdef HAVE_CHARSET_macroman -uchar ctype_macroman_bin[] = { +static const uchar ctype_macroman_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4033,7 +4034,7 @@ uchar ctype_macroman_bin[] = { 0x00,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar to_lower_macroman_bin[] = { +static const uchar to_lower_macroman_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4052,7 +4053,7 @@ uchar to_lower_macroman_bin[] = { 0xF0,0x98,0x9C,0x9E,0x9D,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_macroman_bin[] = { +static const uchar to_upper_macroman_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4071,7 +4072,7 @@ uchar to_upper_macroman_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_macroman_bin[] = { +static const uint16 to_uni_macroman_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4109,7 +4110,7 @@ uint16 to_uni_macroman_bin[] = { #endif #ifdef HAVE_CHARSET_cp1256 -uchar ctype_cp1256_general_ci[] = { +static const uchar ctype_cp1256_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4129,7 +4130,7 @@ uchar ctype_cp1256_general_ci[] = { 0x03,0x03,0x03,0x03,0x02,0x03,0x03,0x00,0x03,0x02,0x03,0x02,0x02,0x00,0x00,0x00 }; -uchar to_lower_cp1256_general_ci[] = { +static const uchar to_lower_cp1256_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4148,7 +4149,7 @@ uchar to_lower_cp1256_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1256_general_ci[] = { +static const uchar to_upper_cp1256_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4167,7 +4168,7 @@ uchar to_upper_cp1256_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_cp1256_general_ci[] = { +static const uchar sort_order_cp1256_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4186,7 +4187,7 @@ uchar sort_order_cp1256_general_ci[] = { 0xAE,0xAF,0xB0,0xB1,0x69,0xB2,0xB3,0xFC,0xB4,0x78,0xB5,0x79,0x7A,0xFD,0xFE,0xFF }; -uint16 to_uni_cp1256_general_ci[] = { +static const uint16 to_uni_cp1256_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4224,7 +4225,7 @@ uint16 to_uni_cp1256_general_ci[] = { #endif #ifdef HAVE_CHARSET_cp1257 -uchar ctype_cp1257_bin[] = { +static const uchar ctype_cp1257_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4244,7 +4245,7 @@ uchar ctype_cp1257_bin[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00 }; -uchar to_lower_cp1257_bin[] = { +static const uchar to_lower_cp1257_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4263,7 +4264,7 @@ uchar to_lower_cp1257_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1257_bin[] = { +static const uchar to_upper_cp1257_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4282,7 +4283,7 @@ uchar to_upper_cp1257_bin[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uint16 to_uni_cp1257_bin[] = { +static const uint16 to_uni_cp1257_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4320,7 +4321,7 @@ uint16 to_uni_cp1257_bin[] = { #endif #ifdef HAVE_CHARSET_cp1257 -uchar ctype_cp1257_general_ci[] = { +static const uchar ctype_cp1257_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4340,7 +4341,7 @@ uchar ctype_cp1257_general_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00 }; -uchar to_lower_cp1257_general_ci[] = { +static const uchar to_lower_cp1257_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4359,7 +4360,7 @@ uchar to_lower_cp1257_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1257_general_ci[] = { +static const uchar to_upper_cp1257_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4378,7 +4379,7 @@ uchar to_upper_cp1257_general_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_cp1257_general_ci[] = { +static const uchar sort_order_cp1257_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4397,7 +4398,7 @@ uchar sort_order_cp1257_general_ci[] = { 0x97,0x7D,0x7D,0x83,0x83,0x83,0x83,0xC3,0xA0,0x75,0x97,0xA0,0xA0,0xB0,0xB0,0xFF }; -uint16 to_uni_cp1257_general_ci[] = { +static const uint16 to_uni_cp1257_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4435,7 +4436,7 @@ uint16 to_uni_cp1257_general_ci[] = { #endif #ifdef HAVE_CHARSET_armscii8 -uchar ctype_armscii8_bin[] = { +static const uchar ctype_armscii8_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4455,7 +4456,7 @@ uchar ctype_armscii8_bin[] = { 0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x10,0x10 }; -uchar to_lower_armscii8_bin[] = { +static const uchar to_lower_armscii8_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4474,7 +4475,7 @@ uchar to_lower_armscii8_bin[] = { 0xF1,0xF1,0xF3,0xF3,0xF5,0xF5,0xF7,0xF7,0xF9,0xF9,0xFB,0xFB,0xFD,0xFD,0xFE,0xFF }; -uchar to_upper_armscii8_bin[] = { +static const uchar to_upper_armscii8_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4493,7 +4494,7 @@ uchar to_upper_armscii8_bin[] = { 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF }; -uint16 to_uni_armscii8_bin[] = { +static const uint16 to_uni_armscii8_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4531,7 +4532,7 @@ uint16 to_uni_armscii8_bin[] = { #endif #ifdef HAVE_CHARSET_ascii -uchar ctype_ascii_bin[] = { +static const uchar ctype_ascii_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4551,7 +4552,7 @@ uchar ctype_ascii_bin[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar to_lower_ascii_bin[] = { +static const uchar to_lower_ascii_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4570,7 +4571,7 @@ uchar to_lower_ascii_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_ascii_bin[] = { +static const uchar to_upper_ascii_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4589,7 +4590,7 @@ uchar to_upper_ascii_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_ascii_bin[] = { +static const uint16 to_uni_ascii_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4627,7 +4628,7 @@ uint16 to_uni_ascii_bin[] = { #endif #ifdef HAVE_CHARSET_cp1250 -uchar ctype_cp1250_bin[] = { +static const uchar ctype_cp1250_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4647,7 +4648,7 @@ uchar ctype_cp1250_bin[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_cp1250_bin[] = { +static const uchar to_lower_cp1250_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4666,7 +4667,7 @@ uchar to_lower_cp1250_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1250_bin[] = { +static const uchar to_upper_cp1250_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4685,7 +4686,7 @@ uchar to_upper_cp1250_bin[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uint16 to_uni_cp1250_bin[] = { +static const uint16 to_uni_cp1250_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4723,7 +4724,7 @@ uint16 to_uni_cp1250_bin[] = { #endif #ifdef HAVE_CHARSET_cp1256 -uchar ctype_cp1256_bin[] = { +static const uchar ctype_cp1256_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4743,7 +4744,7 @@ uchar ctype_cp1256_bin[] = { 0x03,0x03,0x03,0x03,0x02,0x03,0x03,0x00,0x03,0x02,0x03,0x02,0x02,0x00,0x00,0x00 }; -uchar to_lower_cp1256_bin[] = { +static const uchar to_lower_cp1256_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4762,7 +4763,7 @@ uchar to_lower_cp1256_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1256_bin[] = { +static const uchar to_upper_cp1256_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4781,7 +4782,7 @@ uchar to_upper_cp1256_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_cp1256_bin[] = { +static const uint16 to_uni_cp1256_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4819,7 +4820,7 @@ uint16 to_uni_cp1256_bin[] = { #endif #ifdef HAVE_CHARSET_cp866 -uchar ctype_cp866_bin[] = { +static const uchar ctype_cp866_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4839,7 +4840,7 @@ uchar ctype_cp866_bin[] = { 0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48 }; -uchar to_lower_cp866_bin[] = { +static const uchar to_lower_cp866_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4858,7 +4859,7 @@ uchar to_lower_cp866_bin[] = { 0xF1,0xF1,0xF3,0xF3,0xF5,0xF5,0xF7,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp866_bin[] = { +static const uchar to_upper_cp866_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4877,7 +4878,7 @@ uchar to_upper_cp866_bin[] = { 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_cp866_bin[] = { +static const uint16 to_uni_cp866_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -4915,7 +4916,7 @@ uint16 to_uni_cp866_bin[] = { #endif #ifdef HAVE_CHARSET_dec8 -uchar ctype_dec8_bin[] = { +static const uchar ctype_dec8_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -4935,7 +4936,7 @@ uchar ctype_dec8_bin[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_dec8_bin[] = { +static const uchar to_lower_dec8_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4954,7 +4955,7 @@ uchar to_lower_dec8_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_dec8_bin[] = { +static const uchar to_upper_dec8_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -4973,7 +4974,7 @@ uchar to_upper_dec8_bin[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uint16 to_uni_dec8_bin[] = { +static const uint16 to_uni_dec8_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5011,7 +5012,7 @@ uint16 to_uni_dec8_bin[] = { #endif #ifdef HAVE_CHARSET_greek -uchar ctype_greek_bin[] = { +static const uchar ctype_greek_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5031,7 +5032,7 @@ uchar ctype_greek_bin[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00 }; -uchar to_lower_greek_bin[] = { +static const uchar to_lower_greek_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5050,7 +5051,7 @@ uchar to_lower_greek_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_greek_bin[] = { +static const uchar to_upper_greek_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5069,7 +5070,7 @@ uchar to_upper_greek_bin[] = { 0xD0,0xD1,0xD3,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xCF,0xD5,0xD9,0xFF }; -uint16 to_uni_greek_bin[] = { +static const uint16 to_uni_greek_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5107,7 +5108,7 @@ uint16 to_uni_greek_bin[] = { #endif #ifdef HAVE_CHARSET_hebrew -uchar ctype_hebrew_bin[] = { +static const uchar ctype_hebrew_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5127,7 +5128,7 @@ uchar ctype_hebrew_bin[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x20,0x20,0x00 }; -uchar to_lower_hebrew_bin[] = { +static const uchar to_lower_hebrew_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5146,7 +5147,7 @@ uchar to_lower_hebrew_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_hebrew_bin[] = { +static const uchar to_upper_hebrew_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5165,7 +5166,7 @@ uchar to_upper_hebrew_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_hebrew_bin[] = { +static const uint16 to_uni_hebrew_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5203,7 +5204,7 @@ uint16 to_uni_hebrew_bin[] = { #endif #ifdef HAVE_CHARSET_hp8 -uchar ctype_hp8_bin[] = { +static const uchar ctype_hp8_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5223,7 +5224,7 @@ uchar ctype_hp8_bin[] = { 0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20 }; -uchar to_lower_hp8_bin[] = { +static const uchar to_lower_hp8_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5242,7 +5243,7 @@ uchar to_lower_hp8_bin[] = { 0xF1,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_hp8_bin[] = { +static const uchar to_upper_hp8_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5261,7 +5262,7 @@ uchar to_upper_hp8_bin[] = { 0xF0,0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_hp8_bin[] = { +static const uint16 to_uni_hp8_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5299,7 +5300,7 @@ uint16 to_uni_hp8_bin[] = { #endif #ifdef HAVE_CHARSET_keybcs2 -uchar ctype_keybcs2_bin[] = { +static const uchar ctype_keybcs2_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5319,7 +5320,7 @@ uchar ctype_keybcs2_bin[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48 }; -uchar to_lower_keybcs2_bin[] = { +static const uchar to_lower_keybcs2_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5338,7 +5339,7 @@ uchar to_lower_keybcs2_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_keybcs2_bin[] = { +static const uchar to_upper_keybcs2_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5357,7 +5358,7 @@ uchar to_upper_keybcs2_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_keybcs2_bin[] = { +static const uint16 to_uni_keybcs2_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5395,7 +5396,7 @@ uint16 to_uni_keybcs2_bin[] = { #endif #ifdef HAVE_CHARSET_koi8r -uchar ctype_koi8r_bin[] = { +static const uchar ctype_koi8r_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5415,7 +5416,7 @@ uchar ctype_koi8r_bin[] = { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }; -uchar to_lower_koi8r_bin[] = { +static const uchar to_lower_koi8r_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5434,7 +5435,7 @@ uchar to_lower_koi8r_bin[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF }; -uchar to_upper_koi8r_bin[] = { +static const uchar to_upper_koi8r_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5453,7 +5454,7 @@ uchar to_upper_koi8r_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_koi8r_bin[] = { +static const uint16 to_uni_koi8r_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5491,7 +5492,7 @@ uint16 to_uni_koi8r_bin[] = { #endif #ifdef HAVE_CHARSET_koi8u -uchar ctype_koi8u_bin[] = { +static const uchar ctype_koi8u_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5511,7 +5512,7 @@ uchar ctype_koi8u_bin[] = { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }; -uchar to_lower_koi8u_bin[] = { +static const uchar to_lower_koi8u_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5530,7 +5531,7 @@ uchar to_lower_koi8u_bin[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF }; -uchar to_upper_koi8u_bin[] = { +static const uchar to_upper_koi8u_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5549,7 +5550,7 @@ uchar to_upper_koi8u_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_koi8u_bin[] = { +static const uint16 to_uni_koi8u_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5587,7 +5588,7 @@ uint16 to_uni_koi8u_bin[] = { #endif #ifdef HAVE_CHARSET_latin2 -uchar ctype_latin2_bin[] = { +static const uchar ctype_latin2_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5607,7 +5608,7 @@ uchar ctype_latin2_bin[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_latin2_bin[] = { +static const uchar to_lower_latin2_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5626,7 +5627,7 @@ uchar to_lower_latin2_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin2_bin[] = { +static const uchar to_upper_latin2_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5645,7 +5646,7 @@ uchar to_upper_latin2_bin[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uint16 to_uni_latin2_bin[] = { +static const uint16 to_uni_latin2_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5683,7 +5684,7 @@ uint16 to_uni_latin2_bin[] = { #endif #ifdef HAVE_CHARSET_latin5 -uchar ctype_latin5_bin[] = { +static const uchar ctype_latin5_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5703,7 +5704,7 @@ uchar ctype_latin5_bin[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_latin5_bin[] = { +static const uchar to_lower_latin5_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5722,7 +5723,7 @@ uchar to_lower_latin5_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin5_bin[] = { +static const uchar to_upper_latin5_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5741,7 +5742,7 @@ uchar to_upper_latin5_bin[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0x49,0xDE,0xFF }; -uint16 to_uni_latin5_bin[] = { +static const uint16 to_uni_latin5_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5779,7 +5780,7 @@ uint16 to_uni_latin5_bin[] = { #endif #ifdef HAVE_CHARSET_latin7 -uchar ctype_latin7_bin[] = { +static const uchar ctype_latin7_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5799,7 +5800,7 @@ uchar ctype_latin7_bin[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_latin7_bin[] = { +static const uchar to_lower_latin7_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5818,7 +5819,7 @@ uchar to_lower_latin7_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin7_bin[] = { +static const uchar to_upper_latin7_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5837,7 +5838,7 @@ uchar to_upper_latin7_bin[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uint16 to_uni_latin7_bin[] = { +static const uint16 to_uni_latin7_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5875,7 +5876,7 @@ uint16 to_uni_latin7_bin[] = { #endif #ifdef HAVE_CHARSET_cp850 -uchar ctype_cp850_bin[] = { +static const uchar ctype_cp850_bin[] = { 0x00, 0x20,0x30,0x30,0x30,0x30,0x30,0x30,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x30,0x30, 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x20,0x30,0x30,0x30,0x30,0x30, @@ -5895,7 +5896,7 @@ uchar ctype_cp850_bin[] = { 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20 }; -uchar to_lower_cp850_bin[] = { +static const uchar to_lower_cp850_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5914,7 +5915,7 @@ uchar to_lower_cp850_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp850_bin[] = { +static const uchar to_upper_cp850_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -5933,7 +5934,7 @@ uchar to_upper_cp850_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_cp850_bin[] = { +static const uint16 to_uni_cp850_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -5971,7 +5972,7 @@ uint16 to_uni_cp850_bin[] = { #endif #ifdef HAVE_CHARSET_cp852 -uchar ctype_cp852_bin[] = { +static const uchar ctype_cp852_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -5991,7 +5992,7 @@ uchar ctype_cp852_bin[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x02,0x00,0x48 }; -uchar to_lower_cp852_bin[] = { +static const uchar to_lower_cp852_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6010,7 +6011,7 @@ uchar to_lower_cp852_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp852_bin[] = { +static const uchar to_upper_cp852_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6029,7 +6030,7 @@ uchar to_upper_cp852_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF }; -uint16 to_uni_cp852_bin[] = { +static const uint16 to_uni_cp852_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -6067,7 +6068,7 @@ uint16 to_uni_cp852_bin[] = { #endif #ifdef HAVE_CHARSET_swe7 -uchar ctype_swe7_bin[] = { +static const uchar ctype_swe7_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -6087,7 +6088,7 @@ uchar ctype_swe7_bin[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar to_lower_swe7_bin[] = { +static const uchar to_lower_swe7_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6106,7 +6107,7 @@ uchar to_lower_swe7_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_swe7_bin[] = { +static const uchar to_upper_swe7_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6125,7 +6126,7 @@ uchar to_upper_swe7_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_swe7_bin[] = { +static const uint16 to_uni_swe7_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -6163,7 +6164,7 @@ uint16 to_uni_swe7_bin[] = { #endif #ifdef HAVE_CHARSET_geostd8 -uchar ctype_geostd8_general_ci[] = { +static const uchar ctype_geostd8_general_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -6183,7 +6184,7 @@ uchar ctype_geostd8_general_ci[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar to_lower_geostd8_general_ci[] = { +static const uchar to_lower_geostd8_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6202,7 +6203,7 @@ uchar to_lower_geostd8_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_geostd8_general_ci[] = { +static const uchar to_upper_geostd8_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6221,7 +6222,7 @@ uchar to_upper_geostd8_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar sort_order_geostd8_general_ci[] = { +static const uchar sort_order_geostd8_general_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6240,7 +6241,7 @@ uchar sort_order_geostd8_general_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_geostd8_general_ci[] = { +static const uint16 to_uni_geostd8_general_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -6278,7 +6279,7 @@ uint16 to_uni_geostd8_general_ci[] = { #endif #ifdef HAVE_CHARSET_geostd8 -uchar ctype_geostd8_bin[] = { +static const uchar ctype_geostd8_bin[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -6298,7 +6299,7 @@ uchar ctype_geostd8_bin[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar to_lower_geostd8_bin[] = { +static const uchar to_lower_geostd8_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6317,7 +6318,7 @@ uchar to_lower_geostd8_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_geostd8_bin[] = { +static const uchar to_upper_geostd8_bin[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6336,7 +6337,7 @@ uchar to_upper_geostd8_bin[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uint16 to_uni_geostd8_bin[] = { +static const uint16 to_uni_geostd8_bin[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -6374,7 +6375,7 @@ uint16 to_uni_geostd8_bin[] = { #endif #ifdef HAVE_CHARSET_latin1 -uchar ctype_latin1_spanish_ci[] = { +static const uchar ctype_latin1_spanish_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -6394,7 +6395,7 @@ uchar ctype_latin1_spanish_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 }; -uchar to_lower_latin1_spanish_ci[] = { +static const uchar to_lower_latin1_spanish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6413,7 +6414,7 @@ uchar to_lower_latin1_spanish_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_latin1_spanish_ci[] = { +static const uchar to_upper_latin1_spanish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6432,7 +6433,7 @@ uchar to_upper_latin1_spanish_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_latin1_spanish_ci[] = { +static const uchar sort_order_latin1_spanish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6451,7 +6452,7 @@ uchar sort_order_latin1_spanish_ci[] = { 0x57,0x7F,0x81,0x81,0x81,0x81,0x81,0xBE,0x81,0x9A,0x9A,0x9A,0x9A,0xAA,0xB1,0xAA }; -uint16 to_uni_latin1_spanish_ci[] = { +static const uint16 to_uni_latin1_spanish_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -6489,7 +6490,7 @@ uint16 to_uni_latin1_spanish_ci[] = { #endif #ifdef HAVE_CHARSET_cp1250 -uchar ctype_cp1250_polish_ci[] = { +static const uchar ctype_cp1250_polish_ci[] = { 0x00, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, @@ -6509,7 +6510,7 @@ uchar ctype_cp1250_polish_ci[] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10 }; -uchar to_lower_cp1250_polish_ci[] = { +static const uchar to_lower_cp1250_polish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6528,7 +6529,7 @@ uchar to_lower_cp1250_polish_ci[] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar to_upper_cp1250_polish_ci[] = { +static const uchar to_upper_cp1250_polish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6547,7 +6548,7 @@ uchar to_upper_cp1250_polish_ci[] = { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF }; -uchar sort_order_cp1250_polish_ci[] = { +static const uchar sort_order_cp1250_polish_ci[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -6566,7 +6567,7 @@ uchar sort_order_cp1250_polish_ci[] = { 0x48,0x58,0x57,0x5A,0x59,0x59,0x59,0xC9,0x5D,0x64,0x64,0x64,0x64,0x69,0x62,0xFF }; -uint16 to_uni_cp1250_polish_ci[] = { +static const uint16 to_uni_cp1250_polish_ci[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -6603,7 +6604,7 @@ uint16 to_uni_cp1250_polish_ci[] = { #endif -CHARSET_INFO compiled_charsets[] = { +struct charset_info_st compiled_charsets[] = { #ifdef HAVE_CHARSET_dec8 { 3,0,0, diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index afe246397cb..bc1bb287c17 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -30,7 +30,7 @@ #ifdef HAVE_CHARSET_gb2312 -static uchar NEAR ctype_gb2312[257] = +static const uchar NEAR ctype_gb2312[257] = { 0, /* For standard library */ 32,32,32,32,32,32,32,32,32,40,40,40,40,40,32,32, @@ -51,7 +51,7 @@ static uchar NEAR ctype_gb2312[257] = 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, }; -static uchar NEAR to_lower_gb2312[]= +static const uchar NEAR to_lower_gb2312[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -87,7 +87,7 @@ static uchar NEAR to_lower_gb2312[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uchar NEAR to_upper_gb2312[]= +static const uchar NEAR to_upper_gb2312[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -123,7 +123,7 @@ static uchar NEAR to_upper_gb2312[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uchar NEAR sort_order_gb2312[]= +static const uchar NEAR sort_order_gb2312[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -179,7 +179,7 @@ static uint mbcharlen_gb2312(CHARSET_INFO *cs __attribute__((unused)),uint c) /* page 0 0x2121-0x2658 */ -static uint16 tab_gb2312_uni0[]={ +static const uint16 tab_gb2312_uni0[]={ 0x3000,0x3001,0x3002,0x30FB,0x02C9,0x02C7,0x00A8,0x3003, 0x3005,0x2015,0xFF5E,0x2016,0x2026,0x2018,0x2019,0x201C, 0x201D,0x3014,0x3015,0x3008,0x3009,0x300A,0x300B,0x300C, @@ -350,7 +350,7 @@ static uint16 tab_gb2312_uni0[]={ }; /* page 1 0x2721-0x296F */ -static uint16 tab_gb2312_uni1[]={ +static const uint16 tab_gb2312_uni1[]={ 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0401,0x0416, 0x0417,0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E, 0x041F,0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426, @@ -427,7 +427,7 @@ static uint16 tab_gb2312_uni1[]={ 0x2545,0x2546,0x2547,0x2548,0x2549,0x254A,0x254B}; /* page 2 0x3021-0x777E */ -static uint16 tab_gb2312_uni2[]={ +static const uint16 tab_gb2312_uni2[]={ 0x554A,0x963F,0x57C3,0x6328,0x54CE,0x5509,0x54C0,0x7691, 0x764C,0x853C,0x77EE,0x827E,0x788D,0x7231,0x9698,0x978D, 0x6C28,0x5B89,0x4FFA,0x6309,0x6697,0x5CB8,0x80FA,0x6848, @@ -2725,7 +2725,7 @@ static int func_gb2312_uni_onechar(int code){ /* page 0 0x00A4-0x01DC */ -static uint16 tab_uni_gb23120[]={ +static const uint16 tab_uni_gb23120[]={ 0x2168, 0, 0,0x216C,0x2127, 0, 0, 0, 0, 0, 0, 0,0x2163,0x2140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2768,7 +2768,7 @@ static uint16 tab_uni_gb23120[]={ 0x2838}; /* page 1 0x02C7-0x0451 */ -static uint16 tab_uni_gb23121[]={ +static const uint16 tab_uni_gb23121[]={ 0x2126, 0,0x2125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2821,7 +2821,7 @@ static uint16 tab_uni_gb23121[]={ 0x2771, 0,0x2757}; /* page 2 0x2015-0x2312 */ -static uint16 tab_uni_gb23122[]={ +static const uint16 tab_uni_gb23122[]={ 0x212A,0x212C, 0,0x212E,0x212F, 0, 0,0x2130, 0x2131, 0, 0, 0, 0, 0, 0, 0, 0,0x212D, 0, 0, 0, 0, 0, 0, @@ -2920,7 +2920,7 @@ static uint16 tab_uni_gb23122[]={ 0, 0, 0, 0, 0,0x2150}; /* page 3 0x2460-0x2642 */ -static uint16 tab_uni_gb23123[]={ +static const uint16 tab_uni_gb23123[]={ 0x2259,0x225A,0x225B,0x225C,0x225D,0x225E,0x225F,0x2260, 0x2261,0x2262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2245,0x2246,0x2247,0x2248, @@ -2984,7 +2984,7 @@ static uint16 tab_uni_gb23123[]={ 0x2162, 0,0x2161}; /* page 4 0x3000-0x3129 */ -static uint16 tab_uni_gb23124[]={ +static const uint16 tab_uni_gb23124[]={ 0x2121,0x2122,0x2123,0x2128, 0,0x2129, 0, 0, 0x2134,0x2135,0x2136,0x2137,0x2138,0x2139,0x213A,0x213B, 0x213E,0x213F, 0,0x217E,0x2132,0x2133,0x213C,0x213D, @@ -3025,12 +3025,12 @@ static uint16 tab_uni_gb23124[]={ 0x2868,0x2869}; /* page 5 0x3220-0x3229 */ -static uint16 tab_uni_gb23125[]={ +static const uint16 tab_uni_gb23125[]={ 0x2265,0x2266,0x2267,0x2268,0x2269,0x226A,0x226B,0x226C, 0x226D,0x226E}; /* page 6 0x4E00-0x9B54 */ -static uint16 tab_uni_gb23126[]={ +static const uint16 tab_uni_gb23126[]={ 0x523B,0x3621, 0,0x465F, 0, 0, 0,0x4D72, 0x5549,0x487D,0x494F,0x4F42,0x5822,0x323B,0x536B, 0, 0x5824,0x3373, 0,0x5728,0x4752,0x5827,0x4A40, 0, @@ -5508,7 +5508,7 @@ static uint16 tab_uni_gb23126[]={ 0,0x774E, 0, 0,0x4427}; /* page 7 0x9C7C-0x9CE2 */ -static uint16 tab_uni_gb23127[]={ +static const uint16 tab_uni_gb23127[]={ 0x5363, 0, 0,0x764F, 0,0x4233,0x7650, 0, 0,0x7651,0x7652,0x7653,0x7654, 0, 0,0x7656, 0,0x312B,0x7657, 0,0x7658,0x7659,0x765A, 0, @@ -5524,7 +5524,7 @@ static uint16 tab_uni_gb23127[]={ 0x772C,0x772D,0x415B,0x772E, 0, 0,0x772F}; /* page 8 0x9E1F-0x9FA0 */ -static uint16 tab_uni_gb23128[]={ +static const uint16 tab_uni_gb23128[]={ 0x4471,0x702F,0x3C26,0x7030,0x4379, 0,0x4538,0x513B, 0,0x7031,0x7032,0x7033,0x7034,0x7035,0x513C, 0, 0x516C, 0,0x7037,0x7036,0x5427, 0,0x4D52,0x7038, @@ -5576,7 +5576,7 @@ static uint16 tab_uni_gb23128[]={ 0x396A,0x595F}; /* page 9 0xFF01-0xFFE5 */ -static uint16 tab_uni_gb23129[]={ +static const uint16 tab_uni_gb23129[]={ 0x2321,0x2322,0x2323,0x2167,0x2325,0x2326,0x2327,0x2328, 0x2329,0x232A,0x232B,0x232C,0x232D,0x232E,0x232F,0x2330, 0x2331,0x2332,0x2333,0x2334,0x2335,0x2336,0x2337,0x2338, @@ -5766,7 +5766,7 @@ static MY_CHARSET_HANDLER my_charset_handler= }; -CHARSET_INFO my_charset_gb2312_chinese_ci= +struct charset_info_st my_charset_gb2312_chinese_ci= { 24,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ @@ -5798,7 +5798,7 @@ CHARSET_INFO my_charset_gb2312_chinese_ci= &my_collation_ci_handler }; -CHARSET_INFO my_charset_gb2312_bin= +struct charset_info_st my_charset_gb2312_bin= { 86,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT, /* state */ diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index b3b5dde3376..8e0ff6ee678 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -27,7 +27,6 @@ * .configure. mbmaxlen_gbk=2 */ - #include "strings_def.h" #include <m_ctype.h> @@ -45,7 +44,7 @@ #define gbkhead(e) ((uchar)(e>>8)) #define gbktail(e) ((uchar)(e&0xff)) -static uchar NEAR ctype_gbk[257] = +static const uchar NEAR ctype_gbk[257] = { 0, /* For standard library */ 32,32,32,32,32,32,32,32,32,40,40,40,40,40,32,32, @@ -66,7 +65,7 @@ static uchar NEAR ctype_gbk[257] = 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, }; -static uchar NEAR to_lower_gbk[]= +static const uchar NEAR to_lower_gbk[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -102,7 +101,7 @@ static uchar NEAR to_lower_gbk[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uchar NEAR to_upper_gbk[]= +static const uchar NEAR to_upper_gbk[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -138,7 +137,7 @@ static uchar NEAR to_upper_gbk[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uchar NEAR sort_order_gbk[]= +static const uchar NEAR sort_order_gbk[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -174,7 +173,7 @@ static uchar NEAR sort_order_gbk[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uint16 NEAR gbk_order[]= +static const uint16 NEAR gbk_order[]= { 8653,14277,17116,11482,11160,2751,14613,3913,13337,9827, 19496,1759,8105,7103,7836,5638,2223,21433,5878,8006, @@ -2703,7 +2702,7 @@ static uint mbcharlen_gbk(CHARSET_INFO *cs __attribute__((unused)),uint c) } /* page 0 0x8140-0xFE4F */ -static uint16 tab_gbk_uni0[]={ +static const uint16 tab_gbk_uni0[]={ 0x4E02,0x4E04,0x4E05,0x4E06,0x4E0F,0x4E12,0x4E17,0x4E1F, 0x4E20,0x4E21,0x4E23,0x4E26,0x4E29,0x4E2E,0x4E2F,0x4E31, 0x4E33,0x4E35,0x4E37,0x4E3C,0x4E40,0x4E41,0x4E42,0x4E44, @@ -6717,7 +6716,7 @@ static int func_gbk_uni_onechar(int code){ /* page 0 0x00A4-0x0451 */ -static uint16 tab_uni_gbk0[]={ +static const uint16 tab_uni_gbk0[]={ 0xA1E8, 0, 0,0xA1EC,0xA1A7, 0, 0, 0, 0, 0, 0, 0,0xA1E3,0xA1C0, 0, 0, 0, 0, 0,0xA1A4, 0, 0, 0, 0, @@ -6838,7 +6837,7 @@ static uint16 tab_uni_gbk0[]={ 0xA7EE,0xA7EF,0xA7F0,0xA7F1, 0,0xA7D7}; /* page 1 0x2010-0x2312 */ -static uint16 tab_uni_gbk1[]={ +static const uint16 tab_uni_gbk1[]={ 0xA95C, 0, 0,0xA843,0xA1AA,0xA844,0xA1AC, 0, 0xA1AE,0xA1AF, 0, 0,0xA1B0,0xA1B1, 0, 0, 0, 0, 0, 0, 0,0xA845,0xA1AD, 0, @@ -6938,7 +6937,7 @@ static uint16 tab_uni_gbk1[]={ 0, 0,0xA1D0}; /* page 2 0x2460-0x2642 */ -static uint16 tab_uni_gbk2[]={ +static const uint16 tab_uni_gbk2[]={ 0xA2D9,0xA2DA,0xA2DB,0xA2DC,0xA2DD,0xA2DE,0xA2DF,0xA2E0, 0xA2E1,0xA2E2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA2C5,0xA2C6,0xA2C7,0xA2C8, @@ -7002,7 +7001,7 @@ static uint16 tab_uni_gbk2[]={ 0xA1E2, 0,0xA1E1}; /* page 3 0x3000-0x3129 */ -static uint16 tab_uni_gbk3[]={ +static const uint16 tab_uni_gbk3[]={ 0xA1A1,0xA1A2,0xA1A3,0xA1A8, 0,0xA1A9,0xA965,0xA996, 0xA1B4,0xA1B5,0xA1B6,0xA1B7,0xA1B8,0xA1B9,0xA1BA,0xA1BB, 0xA1BE,0xA1BF,0xA893,0xA1FE,0xA1B2,0xA1B3,0xA1BC,0xA1BD, @@ -7043,7 +7042,7 @@ static uint16 tab_uni_gbk3[]={ 0xA8E8,0xA8E9}; /* page 4 0x3220-0x32A3 */ -static uint16 tab_uni_gbk4[]={ +static const uint16 tab_uni_gbk4[]={ 0xA2E5,0xA2E6,0xA2E7,0xA2E8,0xA2E9,0xA2EA,0xA2EB,0xA2EC, 0xA2ED,0xA2EE, 0, 0, 0, 0, 0, 0, 0,0xA95A, 0, 0, 0, 0, 0, 0, @@ -7063,7 +7062,7 @@ static uint16 tab_uni_gbk4[]={ 0, 0, 0,0xA949}; /* page 5 0x338E-0x33D5 */ -static uint16 tab_uni_gbk5[]={ +static const uint16 tab_uni_gbk5[]={ 0xA94A,0xA94B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA94C,0xA94D, 0xA94E, 0, 0,0xA94F, 0, 0, 0, 0, @@ -7076,7 +7075,7 @@ static uint16 tab_uni_gbk5[]={ }; /* page 6 0x4E00-0x9FA5 */ -static uint16 tab_uni_gbk6[]={ +static const uint16 tab_uni_gbk6[]={ 0xD2BB,0xB6A1,0x8140,0xC6DF,0x8141,0x8142,0x8143,0xCDF2, 0xD5C9,0xC8FD,0xC9CF,0xCFC2,0xD8A2,0xB2BB,0xD3EB,0x8144, 0xD8A4,0xB3F3,0x8145,0xD7A8,0xC7D2,0xD8A7,0xCAC0,0x8146, @@ -9692,7 +9691,7 @@ static uint16 tab_uni_gbk6[]={ 0xD9DF,0xFD97,0xFD98,0xFD99,0xFD9A,0xFD9B}; /* page 7 0xF92C-0xFA29 */ -static uint16 tab_uni_gbk7[]={ +static const uint16 tab_uni_gbk7[]={ 0xFD9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -9727,7 +9726,7 @@ static uint16 tab_uni_gbk7[]={ 0xFE4C, 0, 0,0xFE4D,0xFE4E,0xFE4F}; /* page 8 0xFE30-0xFFE5 */ -static uint16 tab_uni_gbk8[]={ +static const uint16 tab_uni_gbk8[]={ 0xA955,0xA6F2, 0,0xA6F4,0xA6F5,0xA6E0,0xA6E1,0xA6F0, 0xA6F1,0xA6E2,0xA6E3,0xA6EE,0xA6EF,0xA6E6,0xA6E7,0xA6E4, 0xA6E5,0xA6E8,0xA6E9,0xA6EA,0xA6EB, 0, 0, 0, @@ -9944,7 +9943,7 @@ static MY_CHARSET_HANDLER my_charset_handler= }; -CHARSET_INFO my_charset_gbk_chinese_ci= +struct charset_info_st my_charset_gbk_chinese_ci= { 28,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ @@ -9976,7 +9975,7 @@ CHARSET_INFO my_charset_gbk_chinese_ci= &my_collation_ci_handler }; -CHARSET_INFO my_charset_gbk_bin= +struct charset_info_st my_charset_gbk_bin= { 87,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT, /* state */ diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index 0207ed0ba56..dd9a1ec9f18 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -19,7 +19,7 @@ #include "strings_def.h" #include <m_ctype.h> -static uchar ctype_latin1[] = { +static const uchar ctype_latin1[] = { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, @@ -39,7 +39,7 @@ static uchar ctype_latin1[] = { 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2 }; -static uchar to_lower_latin1[] = { +static const uchar to_lower_latin1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -58,7 +58,7 @@ static uchar to_lower_latin1[] = { 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 }; -static uchar to_upper_latin1[] = { +static const uchar to_upper_latin1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -77,7 +77,7 @@ static uchar to_upper_latin1[] = { 208,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255 }; -static uchar sort_order_latin1[] = { +static const uchar sort_order_latin1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -118,7 +118,7 @@ static uchar sort_order_latin1[] = { output doesn't reproduce these undefined characters. */ -unsigned short cs_to_uni[256]={ +static unsigned const short cs_to_uni[256]={ 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -152,7 +152,7 @@ unsigned short cs_to_uni[256]={ 0x00F0,0x00F1,0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F7, 0x00F8,0x00F9,0x00FA,0x00FB,0x00FC,0x00FD,0x00FE,0x00FF }; -uchar pl00[256]={ +static const uchar pl00[256]={ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, @@ -186,7 +186,7 @@ uchar pl00[256]={ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7, 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; -uchar pl01[256]={ +static const uchar pl01[256]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -220,7 +220,7 @@ uchar pl01[256]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar pl02[256]={ +static const uchar pl02[256]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -254,7 +254,7 @@ uchar pl02[256]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar pl20[256]={ +static const uchar pl20[256]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x96,0x97,0x00,0x00,0x00, @@ -288,7 +288,7 @@ uchar pl20[256]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar pl21[256]={ +static const uchar pl21[256]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -322,7 +322,7 @@ uchar pl21[256]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uchar *uni_to_cs[256]={ +static const uchar *const uni_to_cs[256]={ pl00,pl01,pl02,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, @@ -376,7 +376,7 @@ int my_wc_mb_latin1(CHARSET_INFO *cs __attribute__((unused)), uchar *str, uchar *end __attribute__((unused))) { - uchar *pl; + const uchar *pl; if (str >= end) return MY_CS_TOOSMALL; @@ -418,7 +418,7 @@ static MY_CHARSET_HANDLER my_charset_handler= }; -CHARSET_INFO my_charset_latin1= +struct charset_info_st my_charset_latin1= { 8,0,0, /* number */ MY_CS_COMPILED | MY_CS_PRIMARY, /* state */ @@ -473,7 +473,7 @@ CHARSET_INFO my_charset_latin1= * Ü, ü, Ö, ö, Ä, ä */ -static uchar sort_order_latin1_de[] = { +static const uchar sort_order_latin1_de[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -497,7 +497,7 @@ static uchar sort_order_latin1_de[] = { same as sort_order_latin_de, but maps ALL accented chars to unaccented ones */ -uchar combo1map[]={ +static const uchar combo1map[]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -516,7 +516,7 @@ uchar combo1map[]={ 68, 78, 79, 79, 79, 79, 79,247,216, 85, 85, 85, 85, 89,222, 89 }; -uchar combo2map[]={ +static const uchar combo2map[]={ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -718,7 +718,7 @@ static MY_COLLATION_HANDLER my_collation_german2_ci_handler= }; -CHARSET_INFO my_charset_latin1_german2_ci= +struct charset_info_st my_charset_latin1_german2_ci= { 31,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM, /* state */ @@ -751,7 +751,7 @@ CHARSET_INFO my_charset_latin1_german2_ci= }; -CHARSET_INFO my_charset_latin1_bin= +struct charset_info_st my_charset_latin1_bin= { 47,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT, /* state */ diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index e54fabc039e..0b3f1a032d8 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -24,7 +24,7 @@ size_t my_caseup_str_mb(CHARSET_INFO * cs, char *str) { register uint32 l; - register uchar *map= cs->to_upper; + register const uchar *map= cs->to_upper; char *str_orig= str; while (*str) @@ -45,7 +45,7 @@ size_t my_caseup_str_mb(CHARSET_INFO * cs, char *str) size_t my_casedn_str_mb(CHARSET_INFO * cs, char *str) { register uint32 l; - register uchar *map= cs->to_lower; + register const uchar *map= cs->to_lower; char *str_orig= str; while (*str) @@ -69,7 +69,7 @@ size_t my_caseup_mb(CHARSET_INFO * cs, char *src, size_t srclen, { register uint32 l; register char *srcend= src + srclen; - register uchar *map= cs->to_upper; + register const uchar *map= cs->to_upper; DBUG_ASSERT(src == dst && srclen == dstlen); while (src < srcend) @@ -92,7 +92,7 @@ size_t my_casedn_mb(CHARSET_INFO * cs, char *src, size_t srclen, { register uint32 l; register char *srcend= src + srclen; - register uchar *map=cs->to_lower; + register const uchar *map=cs->to_lower; DBUG_ASSERT(src == dst && srclen == dstlen); while (src < srcend) @@ -116,7 +116,7 @@ size_t my_casedn_mb(CHARSET_INFO * cs, char *src, size_t srclen, int my_strcasecmp_mb(CHARSET_INFO * cs,const char *s, const char *t) { register uint32 l; - register uchar *map=cs->to_upper; + register const uchar *map=cs->to_upper; while (*s && *t) { @@ -805,7 +805,7 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs, Data was produced from EastAsianWidth.txt using utt11-dump utility. */ -static char pg11[256]= +static const char pg11[256]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -817,7 +817,7 @@ static char pg11[256]= 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 }; -static char pg23[256]= +static const char pg23[256]= { 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, 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -829,7 +829,7 @@ static char pg23[256]= 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 }; -static char pg2E[256]= +static const char pg2E[256]= { 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, 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, @@ -841,7 +841,7 @@ static char pg2E[256]= 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 }; -static char pg2F[256]= +static const char pg2F[256]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -853,7 +853,7 @@ static char pg2F[256]= 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0 }; -static char pg30[256]= +static const char pg30[256]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, @@ -865,7 +865,7 @@ static char pg30[256]= 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; -static char pg31[256]= +static const char pg31[256]= { 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -877,7 +877,7 @@ static char pg31[256]= 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; -static char pg32[256]= +static const char pg32[256]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -889,7 +889,7 @@ static char pg32[256]= 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 }; -static char pg4D[256]= +static const char pg4D[256]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -901,7 +901,7 @@ static char pg4D[256]= 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 }; -static char pg9F[256]= +static const char pg9F[256]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -913,7 +913,7 @@ static char pg9F[256]= 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 }; -static char pgA4[256]= +static const char pgA4[256]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -925,7 +925,7 @@ static char pgA4[256]= 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 }; -static char pgD7[256]= +static const char pgD7[256]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -937,7 +937,7 @@ static char pgD7[256]= 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 }; -static char pgFA[256]= +static const char pgFA[256]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -949,7 +949,7 @@ static char pgFA[256]= 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 }; -static char pgFE[256]= +static const char pgFE[256]= { 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, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -961,7 +961,7 @@ static char pgFE[256]= 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 }; -static char pgFF[256]= +static const char pgFF[256]= { 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -973,7 +973,7 @@ static char pgFF[256]= 1,1,1,1,1,1,1,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 }; -static struct {int page; char *p;} utr11_data[256]= +static const struct {int page; const char *p;} utr11_data[256]= { {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, {0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index fd3833e3e49..d671f425201 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -77,7 +77,7 @@ size_t my_strnxfrm_simple(CHARSET_INFO * cs, uchar *dest, size_t len, const uchar *src, size_t srclen) { - uchar *map= cs->sort_order; + const uchar *map= cs->sort_order; size_t dstlen= len; set_if_smaller(len, srclen); if (dest != src) @@ -103,7 +103,7 @@ int my_strnncoll_simple(CHARSET_INFO * cs, const uchar *s, size_t slen, my_bool t_is_prefix) { size_t len = ( slen > tlen ) ? tlen : slen; - uchar *map= cs->sort_order; + const uchar *map= cs->sort_order; if (t_is_prefix && slen > tlen) slen=tlen; while (len--) @@ -197,7 +197,7 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, size_t a_length, size_t my_caseup_str_8bit(CHARSET_INFO * cs,char *str) { - register uchar *map= cs->to_upper; + register const uchar *map= cs->to_upper; char *str_orig= str; while ((*str= (char) map[(uchar) *str]) != 0) str++; @@ -207,7 +207,7 @@ size_t my_caseup_str_8bit(CHARSET_INFO * cs,char *str) size_t my_casedn_str_8bit(CHARSET_INFO * cs,char *str) { - register uchar *map= cs->to_lower; + register const uchar *map= cs->to_lower; char *str_orig= str; while ((*str= (char) map[(uchar) *str]) != 0) str++; @@ -220,7 +220,7 @@ size_t my_caseup_8bit(CHARSET_INFO * cs, char *src, size_t srclen, size_t dstlen __attribute__((unused))) { char *end= src + srclen; - register uchar *map= cs->to_upper; + register const uchar *map= cs->to_upper; DBUG_ASSERT(src == dst && srclen == dstlen); for ( ; src != end ; src++) *src= (char) map[(uchar) *src]; @@ -233,7 +233,7 @@ size_t my_casedn_8bit(CHARSET_INFO * cs, char *src, size_t srclen, size_t dstlen __attribute__((unused))) { char *end= src + srclen; - register uchar *map=cs->to_lower; + register const uchar *map=cs->to_lower; DBUG_ASSERT(src == dst && srclen == dstlen); for ( ; src != end ; src++) *src= (char) map[(uchar) *src]; @@ -242,7 +242,7 @@ size_t my_casedn_8bit(CHARSET_INFO * cs, char *src, size_t srclen, int my_strcasecmp_8bit(CHARSET_INFO * cs,const char *s, const char *t) { - register uchar *map=cs->to_upper; + register const uchar *map=cs->to_upper; while (map[(uchar) *s] == map[(uchar) *t++]) if (!*s++) return 0; return ((int) map[(uchar) s[0]] - (int) map[(uchar) t[-1]]); @@ -305,7 +305,7 @@ void my_hash_sort_simple(CHARSET_INFO *cs, const uchar *key, size_t len, ulong *nr1, ulong *nr2) { - register uchar *sort_order=cs->sort_order; + register const uchar *sort_order=cs->sort_order; const uchar *end= key + len; /* @@ -1237,7 +1237,7 @@ skip: typedef struct { int nchars; - MY_UNI_IDX uidx; + struct my_uni_idx_st uidx; } uni_idx; #define PLANE_SIZE 0x100 @@ -1255,10 +1255,12 @@ static int pcmp(const void * f, const void * s) return res; } -static my_bool create_fromuni(CHARSET_INFO *cs, void *(*alloc)(size_t)) +static my_bool create_fromuni(struct charset_info_st *cs, + void *(*alloc)(size_t)) { uni_idx idx[PLANE_NUM]; int i,n; + struct my_uni_idx_st *tab_from_uni; /* Check that Unicode map is loaded. @@ -1299,16 +1301,18 @@ static my_bool create_fromuni(CHARSET_INFO *cs, void *(*alloc)(size_t)) for (i=0; i < PLANE_NUM; i++) { int ch,numchars; + uchar *tab; /* Skip empty plane */ if (!idx[i].nchars) break; numchars=idx[i].uidx.to-idx[i].uidx.from+1; - if (!(idx[i].uidx.tab=(uchar*) alloc(numchars * sizeof(*idx[i].uidx.tab)))) + if (!(idx[i].uidx.tab= tab= (uchar*) + alloc(numchars * sizeof(*idx[i].uidx.tab)))) return TRUE; - bzero(idx[i].uidx.tab,numchars*sizeof(*idx[i].uidx.tab)); + bzero(tab,numchars*sizeof(*tab)); for (ch=1; ch < PLANE_SIZE; ch++) { @@ -1316,25 +1320,27 @@ static my_bool create_fromuni(CHARSET_INFO *cs, void *(*alloc)(size_t)) if (wc >= idx[i].uidx.from && wc <= idx[i].uidx.to && wc) { int ofs= wc - idx[i].uidx.from; - idx[i].uidx.tab[ofs]= ch; + tab[ofs]= ch; } } } /* Allocate and fill reverse table for each plane */ n=i; - if (!(cs->tab_from_uni= (MY_UNI_IDX*) alloc(sizeof(MY_UNI_IDX)*(n+1)))) + if (!(cs->tab_from_uni= tab_from_uni= (struct my_uni_idx_st*) + alloc(sizeof(MY_UNI_IDX)*(n+1)))) return TRUE; for (i=0; i< n; i++) - cs->tab_from_uni[i]= idx[i].uidx; + tab_from_uni[i]= idx[i].uidx; /* Set end-of-list marker */ - bzero(&cs->tab_from_uni[i],sizeof(MY_UNI_IDX)); + bzero(&tab_from_uni[i],sizeof(MY_UNI_IDX)); return FALSE; } -static my_bool my_cset_init_8bit(CHARSET_INFO *cs, void *(*alloc)(size_t)) +static my_bool my_cset_init_8bit(struct charset_info_st *cs, + void *(*alloc)(size_t)) { cs->caseup_multiply= 1; cs->casedn_multiply= 1; @@ -1342,7 +1348,7 @@ static my_bool my_cset_init_8bit(CHARSET_INFO *cs, void *(*alloc)(size_t)) return create_fromuni(cs, alloc); } -static void set_max_sort_char(CHARSET_INFO *cs) +static void set_max_sort_char(struct charset_info_st *cs) { uchar max_char; uint i; @@ -1361,7 +1367,7 @@ static void set_max_sort_char(CHARSET_INFO *cs) } } -static my_bool my_coll_init_simple(CHARSET_INFO *cs, +static my_bool my_coll_init_simple(struct charset_info_st *cs, void *(*alloc)(size_t) __attribute__((unused))) { set_max_sort_char(cs); diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index d43def80c34..472eeea41c6 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -32,7 +32,7 @@ * .configure. mbmaxlen_sjis=2 */ -static uchar NEAR ctype_sjis[257] = +static const uchar NEAR ctype_sjis[257] = { 0, /* For standard library */ 0040, 0040, 0040, 0040, 0040, 0040, 0040, 0040, /* NUL ^A - ^G */ @@ -69,7 +69,7 @@ static uchar NEAR ctype_sjis[257] = 0020, 0020, 0020, 0020, 0020, 0000, 0000, 0000 }; -static uchar NEAR to_lower_sjis[]= +static const uchar NEAR to_lower_sjis[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -105,7 +105,7 @@ static uchar NEAR to_lower_sjis[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377' }; -static uchar NEAR to_upper_sjis[]= +static const uchar NEAR to_upper_sjis[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -141,7 +141,7 @@ static uchar NEAR to_upper_sjis[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377' }; -static uchar NEAR sort_order_sjis[]= +static const uchar NEAR sort_order_sjis[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -306,7 +306,7 @@ static size_t my_strnxfrm_sjis(CHARSET_INFO *cs __attribute__((unused)), /* page 0 0x00A1-0x00DF */ -static uint16 tab_sjis_uni0[]={ +static const uint16 tab_sjis_uni0[]={ 0xFF61,0xFF62,0xFF63,0xFF64,0xFF65,0xFF66,0xFF67,0xFF68, 0xFF69,0xFF6A,0xFF6B,0xFF6C,0xFF6D,0xFF6E,0xFF6F,0xFF70, 0xFF71,0xFF72,0xFF73,0xFF74,0xFF75,0xFF76,0xFF77,0xFF78, @@ -317,7 +317,7 @@ static uint16 tab_sjis_uni0[]={ 0xFF99,0xFF9A,0xFF9B,0xFF9C,0xFF9D,0xFF9E,0xFF9F}; /* page 1 0x8140-0x84BE */ -static uint16 tab_sjis_uni1[]={ +static const uint16 tab_sjis_uni1[]={ 0x3000,0x3001,0x3002,0xFF0C,0xFF0E,0x30FB,0xFF1A,0xFF1B, 0xFF1F,0xFF01,0x309B,0x309C,0x00B4,0xFF40,0x00A8,0xFF3E, 0xFFE3,0xFF3F,0x30FD,0x30FE,0x309D,0x309E,0x3003,0x4EDD, @@ -432,7 +432,7 @@ static uint16 tab_sjis_uni1[]={ 0x2537,0x253F,0x251D,0x2530,0x2525,0x2538,0x2542}; /* page 2 0x889F-0x9FFC */ -static uint16 tab_sjis_uni2[]={ +static const uint16 tab_sjis_uni2[]={ 0x4E9C,0x5516,0x5A03,0x963F,0x54C0,0x611B,0x6328,0x59F6, 0x9022,0x8475,0x831C,0x7A50,0x60AA,0x63E1,0x6E25,0x65ED, 0x8466,0x82A6,0x9BF5,0x6893,0x5727,0x65A1,0x6271,0x5B9B, @@ -1183,7 +1183,7 @@ static uint16 tab_sjis_uni2[]={ 0x6F3F,0x6EF2,0x6F31,0x6EEF,0x6F32,0x6ECC}; /* page 3 0xE040-0xEAA4 */ -static uint16 tab_sjis_uni3[]={ +static const uint16 tab_sjis_uni3[]={ 0x6F3E,0x6F13,0x6EF7,0x6F86,0x6F7A,0x6F78,0x6F81,0x6F80, 0x6F6F,0x6F5B,0x6FF3,0x6F6D,0x6F82,0x6F7C,0x6F58,0x6F8E, 0x6F91,0x6FC2,0x6F66,0x6FB3,0x6FA3,0x6FA1,0x6FA4,0x6FB9, @@ -1530,7 +1530,7 @@ static int func_sjis_uni_onechar(int code){ return(0); } /* page 0 0x005C-0x00F7 */ -static uint16 tab_uni_sjis0[]={ +static const uint16 tab_uni_sjis0[]={ 0x815F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1553,7 +1553,7 @@ static uint16 tab_uni_sjis0[]={ 0, 0, 0,0x8180}; /* page 1 0x0391-0x0451 */ -static uint16 tab_uni_sjis1[]={ +static const uint16 tab_uni_sjis1[]={ 0x839F,0x83A0,0x83A1,0x83A2,0x83A3,0x83A4,0x83A5,0x83A6, 0x83A7,0x83A8,0x83A9,0x83AA,0x83AB,0x83AC,0x83AD,0x83AE, 0x83AF, 0,0x83B0,0x83B1,0x83B2,0x83B3,0x83B4,0x83B5, @@ -1581,7 +1581,7 @@ static uint16 tab_uni_sjis1[]={ 0x8476}; /* page 2 0x2010-0x2312 */ -static uint16 tab_uni_sjis2[]={ +static const uint16 tab_uni_sjis2[]={ 0x815D, 0, 0, 0, 0,0x815C,0x8161, 0, 0x8165,0x8166, 0, 0,0x8167,0x8168, 0, 0, 0x81F5,0x81F6, 0, 0, 0,0x8164,0x8163, 0, @@ -1681,7 +1681,7 @@ static uint16 tab_uni_sjis2[]={ 0, 0,0x81DC}; /* page 3 0x2500-0x266F */ -static uint16 tab_uni_sjis3[]={ +static const uint16 tab_uni_sjis3[]={ 0x849F,0x84AA,0x84A0,0x84AB, 0, 0, 0, 0, 0, 0, 0, 0,0x84A1, 0, 0,0x84AC, 0x84A2, 0, 0,0x84AD,0x84A4, 0, 0,0x84AF, @@ -1731,7 +1731,7 @@ static uint16 tab_uni_sjis3[]={ }; /* page 4 0x3000-0x30FE */ -static uint16 tab_uni_sjis4[]={ +static const uint16 tab_uni_sjis4[]={ 0x8140,0x8141,0x8142,0x8156, 0,0x8158,0x8159,0x815A, 0x8171,0x8172,0x8173,0x8174,0x8175,0x8176,0x8177,0x8178, 0x8179,0x817A,0x81A7,0x81AC,0x816B,0x816C, 0, 0, @@ -1766,7 +1766,7 @@ static uint16 tab_uni_sjis4[]={ 0, 0, 0,0x8145,0x815B,0x8152,0x8153}; /* page 5 0x4E00-0x9481 */ -static uint16 tab_uni_sjis5[]={ +static const uint16 tab_uni_sjis5[]={ 0x88EA,0x929A, 0,0x8EB5, 0, 0, 0,0x969C, 0x8FE4,0x8E4F,0x8FE3,0x89BA, 0,0x9573,0x975E, 0, 0x98A0,0x894E, 0, 0,0x8A8E,0x98A1,0x90A2,0x99C0, @@ -4026,7 +4026,7 @@ static uint16 tab_uni_sjis5[]={ 0,0xE876}; /* page 6 0x9577-0x9FA0 */ -static uint16 tab_uni_sjis6[]={ +static const uint16 tab_uni_sjis6[]={ 0x92B7, 0, 0, 0, 0, 0, 0, 0, 0,0x96E5, 0,0xE878,0x914D, 0, 0, 0, 0xE879, 0,0x95C2,0xE87A,0x8A4A, 0, 0, 0, @@ -4355,7 +4355,7 @@ static uint16 tab_uni_sjis6[]={ 0,0xEA9E}; /* page 7 0xFF01-0xFFE5 */ -static uint16 tab_uni_sjis7[]={ +static const uint16 tab_uni_sjis7[]={ 0x8149, 0,0x8194,0x8190,0x8193,0x8195, 0,0x8169, 0x816A,0x8196,0x817B,0x8143, 0,0x8144,0x815E,0x824F, 0x8250,0x8251,0x8252,0x8253,0x8254,0x8255,0x8256,0x8257, @@ -4591,7 +4591,7 @@ static MY_CHARSET_HANDLER my_charset_handler= }; -CHARSET_INFO my_charset_sjis_japanese_ci= +struct charset_info_st my_charset_sjis_japanese_ci= { 13,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_NONASCII, /* state */ @@ -4623,7 +4623,7 @@ CHARSET_INFO my_charset_sjis_japanese_ci= &my_collation_ci_handler }; -CHARSET_INFO my_charset_sjis_bin= +struct charset_info_st my_charset_sjis_bin= { 88,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_NONASCII, /* state */ diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 80e3a4ec9f0..4350a0aa219 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -48,7 +48,7 @@ #define X L_MIDDLE -static int t_ctype[][TOT_LEVELS] = { +static const int t_ctype[][TOT_LEVELS] = { /*0x00*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0x01*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0x02*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, @@ -401,7 +401,7 @@ static uchar NEAR to_upper_tis620[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377', }; -static uchar NEAR sort_order_tis620[]= +static const uchar NEAR sort_order_tis620[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -461,7 +461,7 @@ static size_t thai2sortable(uchar *tstr, size_t len) if (isthai(c)) { - int *t_ctype0= t_ctype[c]; + const int *t_ctype0= t_ctype[c]; if (isconsnt(c)) l2bias -= 8; @@ -632,7 +632,7 @@ size_t my_strnxfrm_tis620(CHARSET_INFO *cs __attribute__((unused)), } -static unsigned short cs_to_uni[256]={ +static const unsigned short cs_to_uni[256]={ 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -666,7 +666,7 @@ static unsigned short cs_to_uni[256]={ 0x0E50,0x0E51,0x0E52,0x0E53,0x0E54,0x0E55,0x0E56,0x0E57, 0x0E58,0x0E59,0x0E5A,0x0E5B,0xFFFD,0xFFFD,0xFFFD,0xFFFD }; -static uchar pl00[256]={ +static const uchar pl00[256]={ 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -700,7 +700,7 @@ static uchar pl00[256]={ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }; -static uchar pl0E[256]={ +static const uchar pl0E[256]={ 0x0000,0x00A1,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7, 0x00A8,0x00A9,0x00AA,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF, 0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7, @@ -734,7 +734,7 @@ static uchar pl0E[256]={ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }; -static uchar plFF[256]={ +static const uchar plFF[256]={ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, @@ -768,7 +768,7 @@ static uchar plFF[256]={ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x00FF,0x0000,0x0000 }; -static uchar *uni_to_cs[256]={ +static const uchar *const uni_to_cs[256]={ pl00,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,pl0E,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, @@ -823,7 +823,7 @@ int my_wc_mb_tis620(CHARSET_INFO *cs __attribute__((unused)), uchar *str, uchar *end __attribute__((unused))) { - uchar *pl; + const uchar *pl; if (str >= end) return MY_CS_TOOSMALL; @@ -882,7 +882,7 @@ static MY_CHARSET_HANDLER my_charset_handler= -CHARSET_INFO my_charset_tis620_thai_ci= +struct charset_info_st my_charset_tis620_thai_ci= { 18,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ @@ -914,7 +914,7 @@ CHARSET_INFO my_charset_tis620_thai_ci= &my_collation_ci_handler }; -CHARSET_INFO my_charset_tis620_bin= +struct charset_info_st my_charset_tis620_bin= { 89,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT, /* state */ diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 268979d17ce..61a6096db17 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -34,7 +34,6 @@ - No combining marks processing is done */ - #include "strings_def.h" #include <m_ctype.h> @@ -50,7 +49,7 @@ #define MY_UCA_CMASK 255 #define MY_UCA_PSHIFT 8 -uint16 page000data[]= { /* 0000 (4 weights per char) */ +static const uint16 page000data[]= { /* 0000 (4 weights per char) */ 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, @@ -181,7 +180,7 @@ uint16 page000data[]= { /* 0000 (4 weights per char) */ 0x1094,0x0000,0x0000,0x0000, 0x105E,0x0000,0x0000,0x0000 }; -uint16 page001data[]= { /* 0100 (3 weights per char) */ +static const uint16 page001data[]= { /* 0100 (3 weights per char) */ 0x0E33,0x0000,0x0000, 0x0E33,0x0000,0x0000, 0x0E33,0x0000,0x0000, 0x0E33,0x0000,0x0000, 0x0E33,0x0000,0x0000, 0x0E33,0x0000,0x0000, 0x0E60,0x0000,0x0000, 0x0E60,0x0000,0x0000, 0x0E60,0x0000,0x0000, @@ -269,7 +268,7 @@ uint16 page001data[]= { /* 0100 (3 weights per char) */ 0x0E38,0x0000,0x0000, 0x0E38,0x0000,0x0000, 0x0F8D,0x0000,0x0000, 0x0F8D,0x0000,0x0000 }; -uint16 page002data[]= { /* 0200 (3 weights per char) */ +static const uint16 page002data[]= { /* 0200 (3 weights per char) */ 0x0E33,0x0000,0x0000, 0x0E33,0x0000,0x0000, 0x0E33,0x0000,0x0000, 0x0E33,0x0000,0x0000, 0x0E8B,0x0000,0x0000, 0x0E8B,0x0000,0x0000, 0x0E8B,0x0000,0x0000, 0x0E8B,0x0000,0x0000, 0x0EFB,0x0000,0x0000, @@ -357,7 +356,7 @@ uint16 page002data[]= { /* 0200 (3 weights per char) */ 0x0346,0x0000,0x0000, 0x0347,0x0000,0x0000, 0x0348,0x0000,0x0000, 0x0349,0x0000,0x0000 }; -uint16 page003data[]= { /* 0300 (4 weights per char) */ +static const uint16 page003data[]= { /* 0300 (4 weights per char) */ 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000, @@ -488,7 +487,7 @@ uint16 page003data[]= { /* 0300 (4 weights per char) */ 0xFBC0,0x83FE,0x0000,0x0000, 0xFBC0,0x83FF,0x0000,0x0000 }; -uint16 page004data[]= { /* 0400 (3 weights per char) */ +static const uint16 page004data[]= { /* 0400 (3 weights per char) */ 0x1152,0x0000,0x0000, 0x1152,0x0000,0x0000, 0x1145,0x0000,0x0000, 0x114A,0x0000,0x0000, 0x115A,0x0000,0x0000, 0x1173,0x0000,0x0000, 0x1188,0x0000,0x0000, 0x118C,0x0000,0x0000, 0x1194,0x0000,0x0000, @@ -576,7 +575,7 @@ uint16 page004data[]= { /* 0400 (3 weights per char) */ 0xFBC0,0x84FC,0x0000, 0xFBC0,0x84FD,0x0000, 0xFBC0,0x84FE,0x0000, 0xFBC0,0x84FF,0x0000 }; -uint16 page005data[]= { /* 0500 (3 weights per char) */ +static const uint16 page005data[]= { /* 0500 (3 weights per char) */ 0x1144,0x0000,0x0000, 0x1144,0x0000,0x0000, 0x1149,0x0000,0x0000, 0x1149,0x0000,0x0000, 0x116E,0x0000,0x0000, 0x116E,0x0000,0x0000, 0x117B,0x0000,0x0000, 0x117B,0x0000,0x0000, 0x11BD,0x0000,0x0000, @@ -664,7 +663,7 @@ uint16 page005data[]= { /* 0500 (3 weights per char) */ 0xFBC0,0x85FC,0x0000, 0xFBC0,0x85FD,0x0000, 0xFBC0,0x85FE,0x0000, 0xFBC0,0x85FF,0x0000 }; -uint16 page006data[]= { /* 0600 (3 weights per char) */ +static const uint16 page006data[]= { /* 0600 (3 weights per char) */ 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0xFBC0,0x8604,0x0000, 0xFBC0,0x8605,0x0000, 0xFBC0,0x8606,0x0000, 0xFBC0,0x8607,0x0000, 0xFBC0,0x8608,0x0000, @@ -752,7 +751,7 @@ uint16 page006data[]= { /* 0600 (3 weights per char) */ 0x1392,0x0000,0x0000, 0x1347,0x0000,0x0000, 0x13B0,0x0000,0x0000, 0x13BB,0x0000,0x0000 }; -uint16 page007data[]= { /* 0700 (3 weights per char) */ +static const uint16 page007data[]= { /* 0700 (3 weights per char) */ 0x0270,0x0000,0x0000, 0x0260,0x0000,0x0000, 0x0261,0x0000,0x0000, 0x023F,0x0000,0x0000, 0x0240,0x0000,0x0000, 0x0241,0x0000,0x0000, 0x0242,0x0000,0x0000, 0x0243,0x0000,0x0000, 0x0244,0x0000,0x0000, @@ -840,7 +839,7 @@ uint16 page007data[]= { /* 0700 (3 weights per char) */ 0xFBC0,0x87FC,0x0000, 0xFBC0,0x87FD,0x0000, 0xFBC0,0x87FE,0x0000, 0xFBC0,0x87FF,0x0000 }; -uint16 page009data[]= { /* 0900 (3 weights per char) */ +static const uint16 page009data[]= { /* 0900 (3 weights per char) */ 0xFBC0,0x8900,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x155A,0x0000,0x0000, 0x155B,0x0000,0x0000, 0x155C,0x0000,0x0000, 0x155D,0x0000,0x0000, 0x155E,0x0000,0x0000, @@ -928,7 +927,7 @@ uint16 page009data[]= { /* 0900 (3 weights per char) */ 0xFBC0,0x89FC,0x0000, 0xFBC0,0x89FD,0x0000, 0xFBC0,0x89FE,0x0000, 0xFBC0,0x89FF,0x0000 }; -uint16 page00Adata[]= { /* 0A00 (3 weights per char) */ +static const uint16 page00Adata[]= { /* 0A00 (3 weights per char) */ 0xFBC0,0x8A00,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0xFBC0,0x8A04,0x0000, 0x15E7,0x0000,0x0000, 0x15E8,0x0000,0x0000, 0x15EC,0x0000,0x0000, 0x15ED,0x0000,0x0000, @@ -1016,7 +1015,7 @@ uint16 page00Adata[]= { /* 0A00 (3 weights per char) */ 0xFBC0,0x8AFC,0x0000, 0xFBC0,0x8AFD,0x0000, 0xFBC0,0x8AFE,0x0000, 0xFBC0,0x8AFF,0x0000 }; -uint16 page00Bdata[]= { /* 0B00 (3 weights per char) */ +static const uint16 page00Bdata[]= { /* 0B00 (3 weights per char) */ 0xFBC0,0x8B00,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0xFBC0,0x8B04,0x0000, 0x165D,0x0000,0x0000, 0x165E,0x0000,0x0000, 0x165F,0x0000,0x0000, 0x1660,0x0000,0x0000, @@ -1104,7 +1103,7 @@ uint16 page00Bdata[]= { /* 0B00 (3 weights per char) */ 0xFBC0,0x8BFC,0x0000, 0xFBC0,0x8BFD,0x0000, 0xFBC0,0x8BFE,0x0000, 0xFBC0,0x8BFF,0x0000 }; -uint16 page00Cdata[]= { /* 0C00 (3 weights per char) */ +static const uint16 page00Cdata[]= { /* 0C00 (3 weights per char) */ 0xFBC0,0x8C00,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0xFBC0,0x8C04,0x0000, 0x16CD,0x0000,0x0000, 0x16CE,0x0000,0x0000, 0x16CF,0x0000,0x0000, 0x16D0,0x0000,0x0000, @@ -1192,7 +1191,7 @@ uint16 page00Cdata[]= { /* 0C00 (3 weights per char) */ 0xFBC0,0x8CFC,0x0000, 0xFBC0,0x8CFD,0x0000, 0xFBC0,0x8CFE,0x0000, 0xFBC0,0x8CFF,0x0000 }; -uint16 page00Ddata[]= { /* 0D00 (3 weights per char) */ +static const uint16 page00Ddata[]= { /* 0D00 (3 weights per char) */ 0xFBC0,0x8D00,0x0000, 0xFBC0,0x8D01,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0xFBC0,0x8D04,0x0000, 0x1755,0x0000,0x0000, 0x1756,0x0000,0x0000, 0x1757,0x0000,0x0000, 0x1758,0x0000,0x0000, @@ -1280,7 +1279,7 @@ uint16 page00Ddata[]= { /* 0D00 (3 weights per char) */ 0xFBC0,0x8DFC,0x0000, 0xFBC0,0x8DFD,0x0000, 0xFBC0,0x8DFE,0x0000, 0xFBC0,0x8DFF,0x0000 }; -uint16 page00Edata[]= { /* 0E00 (3 weights per char) */ +static const uint16 page00Edata[]= { /* 0E00 (3 weights per char) */ 0xFBC0,0x8E00,0x0000, 0x17E4,0x0000,0x0000, 0x17E5,0x0000,0x0000, 0x17E6,0x0000,0x0000, 0x17E7,0x0000,0x0000, 0x17E8,0x0000,0x0000, 0x17E9,0x0000,0x0000, 0x17EA,0x0000,0x0000, 0x17EB,0x0000,0x0000, @@ -1368,7 +1367,7 @@ uint16 page00Edata[]= { /* 0E00 (3 weights per char) */ 0xFBC0,0x8EFC,0x0000, 0xFBC0,0x8EFD,0x0000, 0xFBC0,0x8EFE,0x0000, 0xFBC0,0x8EFF,0x0000 }; -uint16 page00Fdata[]= { /* 0F00 (3 weights per char) */ +static const uint16 page00Fdata[]= { /* 0F00 (3 weights per char) */ 0x189A,0x18AD,0x0000, 0x035A,0x0000,0x0000, 0x035B,0x0000,0x0000, 0x035C,0x0000,0x0000, 0x02FE,0x0000,0x0000, 0x02FF,0x0000,0x0000, 0x0300,0x0000,0x0000, 0x0301,0x0000,0x0000, 0x0302,0x0000,0x0000, @@ -1456,7 +1455,7 @@ uint16 page00Fdata[]= { /* 0F00 (3 weights per char) */ 0xFBC0,0x8FFC,0x0000, 0xFBC0,0x8FFD,0x0000, 0xFBC0,0x8FFE,0x0000, 0xFBC0,0x8FFF,0x0000 }; -uint16 page010data[]= { /* 1000 (3 weights per char) */ +static const uint16 page010data[]= { /* 1000 (3 weights per char) */ 0x1931,0x0000,0x0000, 0x1932,0x0000,0x0000, 0x1933,0x0000,0x0000, 0x1934,0x0000,0x0000, 0x1935,0x0000,0x0000, 0x1936,0x0000,0x0000, 0x1937,0x0000,0x0000, 0x1938,0x0000,0x0000, 0x1939,0x0000,0x0000, @@ -1544,7 +1543,7 @@ uint16 page010data[]= { /* 1000 (3 weights per char) */ 0xFBC0,0x90FC,0x0000, 0xFBC0,0x90FD,0x0000, 0xFBC0,0x90FE,0x0000, 0xFBC0,0x90FF,0x0000 }; -uint16 page011data[]= { /* 1100 (3 weights per char) */ +static const uint16 page011data[]= { /* 1100 (3 weights per char) */ 0x1D62,0x0000,0x0000, 0x1D63,0x0000,0x0000, 0x1D64,0x0000,0x0000, 0x1D65,0x0000,0x0000, 0x1D66,0x0000,0x0000, 0x1D67,0x0000,0x0000, 0x1D68,0x0000,0x0000, 0x1D69,0x0000,0x0000, 0x1D6A,0x0000,0x0000, @@ -1632,7 +1631,7 @@ uint16 page011data[]= { /* 1100 (3 weights per char) */ 0xFBC0,0x91FC,0x0000, 0xFBC0,0x91FD,0x0000, 0xFBC0,0x91FE,0x0000, 0xFBC0,0x91FF,0x0000 }; -uint16 page012data[]= { /* 1200 (3 weights per char) */ +static const uint16 page012data[]= { /* 1200 (3 weights per char) */ 0x141C,0x0000,0x0000, 0x141D,0x0000,0x0000, 0x141E,0x0000,0x0000, 0x141F,0x0000,0x0000, 0x1420,0x0000,0x0000, 0x1421,0x0000,0x0000, 0x1422,0x0000,0x0000, 0xFBC0,0x9207,0x0000, 0x1423,0x0000,0x0000, @@ -1720,7 +1719,7 @@ uint16 page012data[]= { /* 1200 (3 weights per char) */ 0x1500,0x0000,0x0000, 0x1501,0x0000,0x0000, 0x1502,0x0000,0x0000, 0x1503,0x0000,0x0000 }; -uint16 page013data[]= { /* 1300 (3 weights per char) */ +static const uint16 page013data[]= { /* 1300 (3 weights per char) */ 0x1504,0x0000,0x0000, 0x1505,0x0000,0x0000, 0x1506,0x0000,0x0000, 0x1507,0x0000,0x0000, 0x1508,0x0000,0x0000, 0x1509,0x0000,0x0000, 0x150A,0x0000,0x0000, 0x150B,0x0000,0x0000, 0x150C,0x0000,0x0000, @@ -1808,7 +1807,7 @@ uint16 page013data[]= { /* 1300 (3 weights per char) */ 0xFBC0,0x93FC,0x0000, 0xFBC0,0x93FD,0x0000, 0xFBC0,0x93FE,0x0000, 0xFBC0,0x93FF,0x0000 }; -uint16 page014data[]= { /* 1400 (3 weights per char) */ +static const uint16 page014data[]= { /* 1400 (3 weights per char) */ 0xFBC0,0x9400,0x0000, 0x1AAE,0x0000,0x0000, 0x1AAF,0x0000,0x0000, 0x1AB0,0x0000,0x0000, 0x1AB1,0x0000,0x0000, 0x1AB2,0x0000,0x0000, 0x1AB3,0x0000,0x0000, 0x1AB4,0x0000,0x0000, 0x1AB5,0x0000,0x0000, @@ -1896,7 +1895,7 @@ uint16 page014data[]= { /* 1400 (3 weights per char) */ 0x1BA9,0x0000,0x0000, 0x1BAA,0x0000,0x0000, 0x1BAB,0x0000,0x0000, 0x1BAC,0x0000,0x0000 }; -uint16 page015data[]= { /* 1500 (2 weights per char) */ +static const uint16 page015data[]= { /* 1500 (2 weights per char) */ 0x1BAD,0x0000, 0x1BAE,0x0000, 0x1BAF,0x0000, 0x1BB0,0x0000, 0x1BB1,0x0000, 0x1BB2,0x0000, 0x1BB3,0x0000, 0x1BB4,0x0000, 0x1BB5,0x0000, 0x1BB6,0x0000, 0x1BB7,0x0000, 0x1BB8,0x0000, @@ -1963,7 +1962,7 @@ uint16 page015data[]= { /* 1500 (2 weights per char) */ 0x1CB1,0x0000, 0x1CB2,0x0000, 0x1CB3,0x0000, 0x1CB4,0x0000 }; -uint16 page016data[]= { /* 1600 (3 weights per char) */ +static const uint16 page016data[]= { /* 1600 (3 weights per char) */ 0x1CB5,0x0000,0x0000, 0x1CB6,0x0000,0x0000, 0x1CB7,0x0000,0x0000, 0x1CB8,0x0000,0x0000, 0x1CB9,0x0000,0x0000, 0x1CBA,0x0000,0x0000, 0x1CBB,0x0000,0x0000, 0x1CBC,0x0000,0x0000, 0x1CBD,0x0000,0x0000, @@ -2051,7 +2050,7 @@ uint16 page016data[]= { /* 1600 (3 weights per char) */ 0xFBC0,0x96FC,0x0000, 0xFBC0,0x96FD,0x0000, 0xFBC0,0x96FE,0x0000, 0xFBC0,0x96FF,0x0000 }; -uint16 page017data[]= { /* 1700 (3 weights per char) */ +static const uint16 page017data[]= { /* 1700 (3 weights per char) */ 0x18E2,0x0000,0x0000, 0x18E3,0x0000,0x0000, 0x18E4,0x0000,0x0000, 0x18E5,0x0000,0x0000, 0x18E6,0x0000,0x0000, 0x18E7,0x0000,0x0000, 0x18E8,0x0000,0x0000, 0x18E9,0x0000,0x0000, 0x18EA,0x0000,0x0000, @@ -2139,7 +2138,7 @@ uint16 page017data[]= { /* 1700 (3 weights per char) */ 0xFBC0,0x97FC,0x0000, 0xFBC0,0x97FD,0x0000, 0xFBC0,0x97FE,0x0000, 0xFBC0,0x97FF,0x0000 }; -uint16 page018data[]= { /* 1800 (3 weights per char) */ +static const uint16 page018data[]= { /* 1800 (3 weights per char) */ 0x02F8,0x0000,0x0000, 0x025E,0x0000,0x0000, 0x0235,0x0000,0x0000, 0x0263,0x0000,0x0000, 0x024A,0x0000,0x0000, 0x024B,0x0000,0x0000, 0x0223,0x0000,0x0000, 0x0224,0x0000,0x0000, 0x0236,0x0000,0x0000, @@ -2227,7 +2226,7 @@ uint16 page018data[]= { /* 1800 (3 weights per char) */ 0xFBC0,0x98FC,0x0000, 0xFBC0,0x98FD,0x0000, 0xFBC0,0x98FE,0x0000, 0xFBC0,0x98FF,0x0000 }; -uint16 page019data[]= { /* 1900 (3 weights per char) */ +static const uint16 page019data[]= { /* 1900 (3 weights per char) */ 0x18B0,0x0000,0x0000, 0x18B1,0x0000,0x0000, 0x18B2,0x0000,0x0000, 0x18B3,0x0000,0x0000, 0x18B4,0x0000,0x0000, 0x18B5,0x0000,0x0000, 0x18B6,0x0000,0x0000, 0x18B7,0x0000,0x0000, 0x18B8,0x0000,0x0000, @@ -2315,7 +2314,7 @@ uint16 page019data[]= { /* 1900 (3 weights per char) */ 0x0397,0x0000,0x0000, 0x0398,0x0000,0x0000, 0x0399,0x0000,0x0000, 0x039A,0x0000,0x0000 }; -uint16 page01Ddata[]= { /* 1D00 (3 weights per char) */ +static const uint16 page01Ddata[]= { /* 1D00 (3 weights per char) */ 0x0E37,0x0000,0x0000, 0x0E3C,0x0000,0x0000, 0x0E3D,0x0000,0x0000, 0x0E57,0x0000,0x0000, 0x0E64,0x0000,0x0000, 0x0E71,0x0000,0x0000, 0x0E8A,0x0000,0x0000, 0x0E8F,0x0000,0x0000, 0x0EA8,0x0000,0x0000, @@ -2403,7 +2402,7 @@ uint16 page01Ddata[]= { /* 1D00 (3 weights per char) */ 0xFBC0,0x9DFC,0x0000, 0xFBC0,0x9DFD,0x0000, 0xFBC0,0x9DFE,0x0000, 0xFBC0,0x9DFF,0x0000 }; -uint16 page01Edata[]= { /* 1E00 (3 weights per char) */ +static const uint16 page01Edata[]= { /* 1E00 (3 weights per char) */ 0x0E33,0x0000,0x0000, 0x0E33,0x0000,0x0000, 0x0E4A,0x0000,0x0000, 0x0E4A,0x0000,0x0000, 0x0E4A,0x0000,0x0000, 0x0E4A,0x0000,0x0000, 0x0E4A,0x0000,0x0000, 0x0E4A,0x0000,0x0000, 0x0E60,0x0000,0x0000, @@ -2491,7 +2490,7 @@ uint16 page01Edata[]= { /* 1E00 (3 weights per char) */ 0xFBC0,0x9EFC,0x0000, 0xFBC0,0x9EFD,0x0000, 0xFBC0,0x9EFE,0x0000, 0xFBC0,0x9EFF,0x0000 }; -uint16 page01Fdata[]= { /* 1F00 (3 weights per char) */ +static const uint16 page01Fdata[]= { /* 1F00 (3 weights per char) */ 0x10E8,0x0000,0x0000, 0x10E8,0x0000,0x0000, 0x10E8,0x0000,0x0000, 0x10E8,0x0000,0x0000, 0x10E8,0x0000,0x0000, 0x10E8,0x0000,0x0000, 0x10E8,0x0000,0x0000, 0x10E8,0x0000,0x0000, 0x10E8,0x0000,0x0000, @@ -2579,7 +2578,7 @@ uint16 page01Fdata[]= { /* 1F00 (3 weights per char) */ 0x1109,0x0000,0x0000, 0x020D,0x0000,0x0000, 0x0218,0x0000,0x0000, 0xFBC0,0x9FFF,0x0000 }; -uint16 page020data[]= { /* 2000 (5 weights per char) */ +static const uint16 page020data[]= { /* 2000 (5 weights per char) */ 0x0209,0x0000,0x0000,0x0000,0x0000, 0x0209,0x0000,0x0000,0x0000,0x0000, 0x0209,0x0000,0x0000,0x0000,0x0000, @@ -2838,7 +2837,7 @@ uint16 page020data[]= { /* 2000 (5 weights per char) */ 0xFBC0,0xA0FF,0x0000,0x0000,0x0000 }; -uint16 page021data[]= { /* 2100 (5 weights per char) */ +static const uint16 page021data[]= { /* 2100 (5 weights per char) */ 0x0E33,0x02CC,0x0E60,0x0000,0x0000, 0x0E33,0x02CC,0x0FEA,0x0000,0x0000, 0x0E60,0x0000,0x0000,0x0000,0x0000, @@ -3097,7 +3096,7 @@ uint16 page021data[]= { /* 2100 (5 weights per char) */ 0x0417,0x0000,0x0000,0x0000,0x0000 }; -uint16 page022data[]= { /* 2200 (4 weights per char) */ +static const uint16 page022data[]= { /* 2200 (4 weights per char) */ 0x0418,0x0000,0x0000,0x0000, 0x0419,0x0000,0x0000,0x0000, 0x041A,0x0000,0x0000,0x0000, 0x041B,0x0000,0x0000,0x0000, 0x041B,0x0000,0x0000,0x0000, 0x041C,0x0000,0x0000,0x0000, @@ -3228,7 +3227,7 @@ uint16 page022data[]= { /* 2200 (4 weights per char) */ 0x04F9,0x0000,0x0000,0x0000, 0x04FA,0x0000,0x0000,0x0000 }; -uint16 page023data[]= { /* 2300 (3 weights per char) */ +static const uint16 page023data[]= { /* 2300 (3 weights per char) */ 0x04FB,0x0000,0x0000, 0x04FC,0x0000,0x0000, 0x04FD,0x0000,0x0000, 0x04FE,0x0000,0x0000, 0x04FF,0x0000,0x0000, 0x0500,0x0000,0x0000, 0x0501,0x0000,0x0000, 0x0502,0x0000,0x0000, 0x0503,0x0000,0x0000, @@ -3316,7 +3315,7 @@ uint16 page023data[]= { /* 2300 (3 weights per char) */ 0xFBC0,0xA3FC,0x0000, 0xFBC0,0xA3FD,0x0000, 0xFBC0,0xA3FE,0x0000, 0xFBC0,0xA3FF,0x0000 }; -uint16 page024data[]= { /* 2400 (5 weights per char) */ +static const uint16 page024data[]= { /* 2400 (5 weights per char) */ 0x05CA,0x0000,0x0000,0x0000,0x0000, 0x05CB,0x0000,0x0000,0x0000,0x0000, 0x05CC,0x0000,0x0000,0x0000,0x0000, @@ -3575,7 +3574,7 @@ uint16 page024data[]= { /* 2400 (5 weights per char) */ 0x0E29,0x0000,0x0000,0x0000,0x0000 }; -uint16 page025data[]= { /* 2500 (2 weights per char) */ +static const uint16 page025data[]= { /* 2500 (2 weights per char) */ 0x05FC,0x0000, 0x05FD,0x0000, 0x05FE,0x0000, 0x05FF,0x0000, 0x0600,0x0000, 0x0601,0x0000, 0x0602,0x0000, 0x0603,0x0000, 0x0604,0x0000, 0x0605,0x0000, 0x0606,0x0000, 0x0607,0x0000, @@ -3642,7 +3641,7 @@ uint16 page025data[]= { /* 2500 (2 weights per char) */ 0x06F8,0x0000, 0x06F9,0x0000, 0x06FA,0x0000, 0x06FB,0x0000 }; -uint16 page026data[]= { /* 2600 (3 weights per char) */ +static const uint16 page026data[]= { /* 2600 (3 weights per char) */ 0x06FC,0x0000,0x0000, 0x06FD,0x0000,0x0000, 0x06FE,0x0000,0x0000, 0x06FF,0x0000,0x0000, 0x0700,0x0000,0x0000, 0x0701,0x0000,0x0000, 0x0702,0x0000,0x0000, 0x0703,0x0000,0x0000, 0x0704,0x0000,0x0000, @@ -3730,7 +3729,7 @@ uint16 page026data[]= { /* 2600 (3 weights per char) */ 0xFBC0,0xA6FC,0x0000, 0xFBC0,0xA6FD,0x0000, 0xFBC0,0xA6FE,0x0000, 0xFBC0,0xA6FF,0x0000 }; -uint16 page027data[]= { /* 2700 (3 weights per char) */ +static const uint16 page027data[]= { /* 2700 (3 weights per char) */ 0xFBC0,0xA700,0x0000, 0x077C,0x0000,0x0000, 0x077D,0x0000,0x0000, 0x077E,0x0000,0x0000, 0x077F,0x0000,0x0000, 0xFBC0,0xA705,0x0000, 0x0780,0x0000,0x0000, 0x0781,0x0000,0x0000, 0x0782,0x0000,0x0000, @@ -3818,7 +3817,7 @@ uint16 page027data[]= { /* 2700 (3 weights per char) */ 0x0834,0x0000,0x0000, 0x0835,0x0000,0x0000, 0x0836,0x0000,0x0000, 0x0837,0x0000,0x0000 }; -uint16 page028data[]= { /* 2800 (2 weights per char) */ +static const uint16 page028data[]= { /* 2800 (2 weights per char) */ 0x0A29,0x0000, 0x0A2A,0x0000, 0x0A2B,0x0000, 0x0A2C,0x0000, 0x0A2D,0x0000, 0x0A2E,0x0000, 0x0A2F,0x0000, 0x0A30,0x0000, 0x0A31,0x0000, 0x0A32,0x0000, 0x0A33,0x0000, 0x0A34,0x0000, @@ -3885,7 +3884,7 @@ uint16 page028data[]= { /* 2800 (2 weights per char) */ 0x0B25,0x0000, 0x0B26,0x0000, 0x0B27,0x0000, 0x0B28,0x0000 }; -uint16 page029data[]= { /* 2900 (2 weights per char) */ +static const uint16 page029data[]= { /* 2900 (2 weights per char) */ 0x0838,0x0000, 0x0839,0x0000, 0x083A,0x0000, 0x083B,0x0000, 0x083C,0x0000, 0x083D,0x0000, 0x083E,0x0000, 0x083F,0x0000, 0x0840,0x0000, 0x0841,0x0000, 0x0842,0x0000, 0x0843,0x0000, @@ -3952,7 +3951,7 @@ uint16 page029data[]= { /* 2900 (2 weights per char) */ 0x0296,0x0000, 0x0297,0x0000, 0x091E,0x0000, 0x091F,0x0000 }; -uint16 page02Adata[]= { /* 2A00 (5 weights per char) */ +static const uint16 page02Adata[]= { /* 2A00 (5 weights per char) */ 0x0920,0x0000,0x0000,0x0000,0x0000, 0x0921,0x0000,0x0000,0x0000,0x0000, 0x0922,0x0000,0x0000,0x0000,0x0000, @@ -4211,7 +4210,7 @@ uint16 page02Adata[]= { /* 2A00 (5 weights per char) */ 0x0A1A,0x0000,0x0000,0x0000,0x0000 }; -uint16 page02Bdata[]= { /* 2B00 (3 weights per char) */ +static const uint16 page02Bdata[]= { /* 2B00 (3 weights per char) */ 0x0A1B,0x0000,0x0000, 0x0A1C,0x0000,0x0000, 0x0A1D,0x0000,0x0000, 0x0A1E,0x0000,0x0000, 0x0A1F,0x0000,0x0000, 0x0A20,0x0000,0x0000, 0x0A21,0x0000,0x0000, 0x0A22,0x0000,0x0000, 0x0A23,0x0000,0x0000, @@ -4299,7 +4298,7 @@ uint16 page02Bdata[]= { /* 2B00 (3 weights per char) */ 0xFBC0,0xABFC,0x0000, 0xFBC0,0xABFD,0x0000, 0xFBC0,0xABFE,0x0000, 0xFBC0,0xABFF,0x0000 }; -uint16 page02Edata[]= { /* 2E00 (3 weights per char) */ +static const uint16 page02Edata[]= { /* 2E00 (3 weights per char) */ 0xFBC0,0xAE00,0x0000, 0xFBC0,0xAE01,0x0000, 0xFBC0,0xAE02,0x0000, 0xFBC0,0xAE03,0x0000, 0xFBC0,0xAE04,0x0000, 0xFBC0,0xAE05,0x0000, 0xFBC0,0xAE06,0x0000, 0xFBC0,0xAE07,0x0000, 0xFBC0,0xAE08,0x0000, @@ -4387,7 +4386,7 @@ uint16 page02Edata[]= { /* 2E00 (3 weights per char) */ 0xFBC0,0xAEFC,0x0000, 0xFBC0,0xAEFD,0x0000, 0xFBC0,0xAEFE,0x0000, 0xFBC0,0xAEFF,0x0000 }; -uint16 page02Fdata[]= { /* 2F00 (3 weights per char) */ +static const uint16 page02Fdata[]= { /* 2F00 (3 weights per char) */ 0xFB40,0xCE00,0x0000, 0xFB40,0xCE28,0x0000, 0xFB40,0xCE36,0x0000, 0xFB40,0xCE3F,0x0000, 0xFB40,0xCE59,0x0000, 0xFB40,0xCE85,0x0000, 0xFB40,0xCE8C,0x0000, 0xFB40,0xCEA0,0x0000, 0xFB40,0xCEBA,0x0000, @@ -4475,7 +4474,7 @@ uint16 page02Fdata[]= { /* 2F00 (3 weights per char) */ 0xFBC0,0xAFFC,0x0000, 0xFBC0,0xAFFD,0x0000, 0xFBC0,0xAFFE,0x0000, 0xFBC0,0xAFFF,0x0000 }; -uint16 page030data[]= { /* 3000 (3 weights per char) */ +static const uint16 page030data[]= { /* 3000 (3 weights per char) */ 0x0209,0x0000,0x0000, 0x0237,0x0000,0x0000, 0x0266,0x0000,0x0000, 0x02E2,0x0000,0x0000, 0x0DBB,0x0000,0x0000, 0x0E05,0x0000,0x0000, 0x1E5D,0x1E73,0x0000, 0x0E29,0x0000,0x0000, 0x02AE,0x0000,0x0000, @@ -4563,7 +4562,7 @@ uint16 page030data[]= { /* 3000 (3 weights per char) */ 0x0E0B,0x0000,0x0000, 0x0E0C,0x0000,0x0000, 0x0E0C,0x0000,0x0000, 0x1E5B,0x1E65,0x0000 }; -uint16 page031data[]= { /* 3100 (3 weights per char) */ +static const uint16 page031data[]= { /* 3100 (3 weights per char) */ 0xFBC0,0xB100,0x0000, 0xFBC0,0xB101,0x0000, 0xFBC0,0xB102,0x0000, 0xFBC0,0xB103,0x0000, 0xFBC0,0xB104,0x0000, 0x1E82,0x0000,0x0000, 0x1E83,0x0000,0x0000, 0x1E84,0x0000,0x0000, 0x1E85,0x0000,0x0000, @@ -4651,7 +4650,7 @@ uint16 page031data[]= { /* 3100 (3 weights per char) */ 0x1E79,0x0000,0x0000, 0x1E7A,0x0000,0x0000, 0x1E7B,0x0000,0x0000, 0x1E7C,0x0000,0x0000 }; -uint16 page032data[]= { /* 3200 (8 weights per char) */ +static const uint16 page032data[]= { /* 3200 (8 weights per char) */ 0x0288,0x1D62,0x0289,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0288,0x1D64,0x0289,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0288,0x1D65,0x0289,0x0000,0x0000,0x0000,0x0000,0x0000, @@ -4910,7 +4909,7 @@ uint16 page032data[]= { /* 3200 (8 weights per char) */ 0xFBC0,0xB2FF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }; -uint16 page033data[]= { /* 3300 (9 weights per char) */ +static const uint16 page033data[]= { /* 3300 (9 weights per char) */ 0x1E52,0x1E6B,0x0E0B,0x1E65,0x0000,0x0000,0x0000,0x0000,0x0000, 0x1E52,0x1E7A,0x1E6D,0x1E52,0x0000,0x0000,0x0000,0x0000,0x0000, 0x1E52,0x1E81,0x1E6E,0x1E52,0x0000,0x0000,0x0000,0x0000,0x0000, @@ -5169,7 +5168,7 @@ uint16 page033data[]= { /* 3300 (9 weights per char) */ 0x0EC1,0x0E33,0x0F2E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }; -uint16 page04Ddata[]= { /* 4D00 (3 weights per char) */ +static const uint16 page04Ddata[]= { /* 4D00 (3 weights per char) */ 0xFB80,0xCD00,0x0000, 0xFB80,0xCD01,0x0000, 0xFB80,0xCD02,0x0000, 0xFB80,0xCD03,0x0000, 0xFB80,0xCD04,0x0000, 0xFB80,0xCD05,0x0000, 0xFB80,0xCD06,0x0000, 0xFB80,0xCD07,0x0000, 0xFB80,0xCD08,0x0000, @@ -5257,7 +5256,7 @@ uint16 page04Ddata[]= { /* 4D00 (3 weights per char) */ 0x0B73,0x0000,0x0000, 0x0B74,0x0000,0x0000, 0x0B75,0x0000,0x0000, 0x0B76,0x0000,0x0000 }; -uint16 page0A0data[]= { /* A000 (2 weights per char) */ +static const uint16 page0A0data[]= { /* A000 (2 weights per char) */ 0x1EB1,0x0000, 0x1EB2,0x0000, 0x1EB3,0x0000, 0x1EB4,0x0000, 0x1EB5,0x0000, 0x1EB6,0x0000, 0x1EB7,0x0000, 0x1EB8,0x0000, 0x1EB9,0x0000, 0x1EBA,0x0000, 0x1EBB,0x0000, 0x1EBC,0x0000, @@ -5324,7 +5323,7 @@ uint16 page0A0data[]= { /* A000 (2 weights per char) */ 0x1FAD,0x0000, 0x1FAE,0x0000, 0x1FAF,0x0000, 0x1FB0,0x0000 }; -uint16 page0A1data[]= { /* A100 (2 weights per char) */ +static const uint16 page0A1data[]= { /* A100 (2 weights per char) */ 0x1FB1,0x0000, 0x1FB2,0x0000, 0x1FB3,0x0000, 0x1FB4,0x0000, 0x1FB5,0x0000, 0x1FB6,0x0000, 0x1FB7,0x0000, 0x1FB8,0x0000, 0x1FB9,0x0000, 0x1FBA,0x0000, 0x1FBB,0x0000, 0x1FBC,0x0000, @@ -5391,7 +5390,7 @@ uint16 page0A1data[]= { /* A100 (2 weights per char) */ 0x20AD,0x0000, 0x20AE,0x0000, 0x20AF,0x0000, 0x20B0,0x0000 }; -uint16 page0A2data[]= { /* A200 (2 weights per char) */ +static const uint16 page0A2data[]= { /* A200 (2 weights per char) */ 0x20B1,0x0000, 0x20B2,0x0000, 0x20B3,0x0000, 0x20B4,0x0000, 0x20B5,0x0000, 0x20B6,0x0000, 0x20B7,0x0000, 0x20B8,0x0000, 0x20B9,0x0000, 0x20BA,0x0000, 0x20BB,0x0000, 0x20BC,0x0000, @@ -5458,7 +5457,7 @@ uint16 page0A2data[]= { /* A200 (2 weights per char) */ 0x21AD,0x0000, 0x21AE,0x0000, 0x21AF,0x0000, 0x21B0,0x0000 }; -uint16 page0A3data[]= { /* A300 (2 weights per char) */ +static const uint16 page0A3data[]= { /* A300 (2 weights per char) */ 0x21B1,0x0000, 0x21B2,0x0000, 0x21B3,0x0000, 0x21B4,0x0000, 0x21B5,0x0000, 0x21B6,0x0000, 0x21B7,0x0000, 0x21B8,0x0000, 0x21B9,0x0000, 0x21BA,0x0000, 0x21BB,0x0000, 0x21BC,0x0000, @@ -5525,7 +5524,7 @@ uint16 page0A3data[]= { /* A300 (2 weights per char) */ 0x22AD,0x0000, 0x22AE,0x0000, 0x22AF,0x0000, 0x22B0,0x0000 }; -uint16 page0A4data[]= { /* A400 (3 weights per char) */ +static const uint16 page0A4data[]= { /* A400 (3 weights per char) */ 0x22B1,0x0000,0x0000, 0x22B2,0x0000,0x0000, 0x22B3,0x0000,0x0000, 0x22B4,0x0000,0x0000, 0x22B5,0x0000,0x0000, 0x22B6,0x0000,0x0000, 0x22B7,0x0000,0x0000, 0x22B8,0x0000,0x0000, 0x22B9,0x0000,0x0000, @@ -5613,7 +5612,7 @@ uint16 page0A4data[]= { /* A400 (3 weights per char) */ 0xFBC1,0xA4FC,0x0000, 0xFBC1,0xA4FD,0x0000, 0xFBC1,0xA4FE,0x0000, 0xFBC1,0xA4FF,0x0000 }; -uint16 page0F9data[]= { /* F900 (3 weights per char) */ +static const uint16 page0F9data[]= { /* F900 (3 weights per char) */ 0xFB41,0x8C48,0x0000, 0xFB40,0xE6F4,0x0000, 0xFB41,0x8ECA,0x0000, 0xFB41,0x8CC8,0x0000, 0xFB40,0xEED1,0x0000, 0xFB40,0xCE32,0x0000, 0xFB40,0xD3E5,0x0000, 0xFB41,0x9F9C,0x0000, 0xFB41,0x9F9C,0x0000, @@ -5701,7 +5700,7 @@ uint16 page0F9data[]= { /* F900 (3 weights per char) */ 0xFB41,0x8B58,0x0000, 0xFB40,0xCEC0,0x0000, 0xFB41,0x8336,0x0000, 0xFB40,0xD23A,0x0000 }; -uint16 page0FAdata[]= { /* FA00 (3 weights per char) */ +static const uint16 page0FAdata[]= { /* FA00 (3 weights per char) */ 0xFB40,0xD207,0x0000, 0xFB40,0xDEA6,0x0000, 0xFB40,0xE2D3,0x0000, 0xFB40,0xFCD6,0x0000, 0xFB40,0xDB85,0x0000, 0xFB40,0xED1E,0x0000, 0xFB40,0xE6B4,0x0000, 0xFB41,0x8F3B,0x0000, 0xFB41,0x884C,0x0000, @@ -5789,7 +5788,7 @@ uint16 page0FAdata[]= { /* FA00 (3 weights per char) */ 0xFBC1,0xFAFC,0x0000, 0xFBC1,0xFAFD,0x0000, 0xFBC1,0xFAFE,0x0000, 0xFBC1,0xFAFF,0x0000 }; -uint16 page0FBdata[]= { /* FB00 (4 weights per char) */ +static const uint16 page0FBdata[]= { /* FB00 (4 weights per char) */ 0x0EB9,0x0EB9,0x0000,0x0000, 0x0EB9,0x0EFB,0x0000,0x0000, 0x0EB9,0x0F2E,0x0000,0x0000, 0x0EB9,0x0EB9,0x0EFB,0x0000, 0x0EB9,0x0EB9,0x0F2E,0x0000, 0x0FEA,0x1002,0x0000,0x0000, @@ -5920,7 +5919,7 @@ uint16 page0FBdata[]= { /* FB00 (4 weights per char) */ 0x13C9,0x0000,0x0000,0x0000, 0x13C9,0x0000,0x0000,0x0000 }; -uint16 page0FCdata[]= { /* FC00 (3 weights per char) */ +static const uint16 page0FCdata[]= { /* FC00 (3 weights per char) */ 0x134F,0x135E,0x0000, 0x134F,0x1364,0x0000, 0x134F,0x13B0,0x0000, 0x134F,0x13C7,0x0000, 0x134F,0x13C8,0x0000, 0x1352,0x135E,0x0000, 0x1352,0x1364,0x0000, 0x1352,0x1365,0x0000, 0x1352,0x13B0,0x0000, @@ -6008,7 +6007,7 @@ uint16 page0FCdata[]= { /* FC00 (3 weights per char) */ 0x1381,0x13C8,0x0000, 0x1382,0x13C7,0x0000, 0x1382,0x13C8,0x0000, 0x1364,0x13C7,0x0000 }; -uint16 page0FDdata[]= { /* FD00 (9 weights per char) */ +static const uint16 page0FDdata[]= { /* FD00 (9 weights per char) */ 0x1364,0x13C8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x135E,0x13C7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x135E,0x13C8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, @@ -6267,7 +6266,7 @@ uint16 page0FDdata[]= { /* FD00 (9 weights per char) */ 0xFBC1,0xFDFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }; -uint16 page0FEdata[]= { /* FE00 (3 weights per char) */ +static const uint16 page0FEdata[]= { /* FE00 (3 weights per char) */ 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, @@ -6355,7 +6354,7 @@ uint16 page0FEdata[]= { /* FE00 (3 weights per char) */ 0x13AB,0x1350,0x0000, 0xFBC1,0xFEFD,0x0000, 0xFBC1,0xFEFE,0x0000, 0x0000,0x0000,0x0000 }; -uint16 page0FFdata[]= { /* FF00 (3 weights per char) */ +static const uint16 page0FFdata[]= { /* FF00 (3 weights per char) */ 0xFBC1,0xFF00,0x0000, 0x0251,0x0000,0x0000, 0x027E,0x0000,0x0000, 0x02D2,0x0000,0x0000, 0x0E0F,0x0000,0x0000, 0x02D3,0x0000,0x0000, 0x02CF,0x0000,0x0000, 0x0277,0x0000,0x0000, 0x0288,0x0000,0x0000, @@ -6443,7 +6442,7 @@ uint16 page0FFdata[]= { /* FF00 (3 weights per char) */ 0x0DC5,0x0000,0x0000, 0x0DC6,0x0000,0x0000, 0xFBC1,0xFFFE,0x0000, 0xFBC1,0xFFFF,0x0000 }; -uchar uca_length[256]={ +static const uchar uca_length[256]={ 4,3,3,4,3,3,3,3,0,3,3,3,3,3,3,3, 3,3,3,3,3,2,3,3,3,3,0,0,0,3,3,3, 5,5,4,3,5,2,3,3,2,2,5,3,0,0,3,3, @@ -6461,7 +6460,8 @@ uchar uca_length[256]={ 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,3,3,4,3,9,3,3 }; -uint16 *uca_weight[256]={ + +static const uint16 *const uca_weight[256]={ page000data,page001data,page002data,page003data, page004data,page005data,page006data,page007data, NULL ,page009data,page00Adata,page00Bdata, @@ -6741,9 +6741,9 @@ typedef struct my_uca_scanner_st const uint16 *wbeg; /* Beginning of the current weight string */ const uchar *sbeg; /* Beginning of the input string */ const uchar *send; /* End of the input string */ - uchar *uca_length; - uint16 **uca_weight; - MY_CONTRACTIONS *contractions; + const uchar *uca_length; + const uint16 * const *uca_weight; + const MY_CONTRACTIONS *contractions; uint16 implicit[2]; int page; int code; @@ -6761,7 +6761,7 @@ typedef struct my_uca_scanner_handler_st int (*next)(my_uca_scanner *scanner); } my_uca_scanner_handler; -static uint16 nochar[]= {0,0}; +static const uint16 nochar[]= {0,0}; /********** Helper functions to handle contraction ************/ @@ -6793,10 +6793,10 @@ my_uca_add_contraction_flag(CHARSET_INFO *cs, my_wc_t wc, int flag) */ static MY_CONTRACTION * -my_uca_add_contraction(CHARSET_INFO *cs, +my_uca_add_contraction(struct charset_info_st *cs, my_wc_t *wc, int len __attribute__((unused))) { - MY_CONTRACTIONS *list= cs->contractions; + MY_CONTRACTIONS *list= (MY_CONTRACTIONS*) cs->contractions; MY_CONTRACTION *next= &list->item[list->nitems]; DBUG_ASSERT(len == 2); /* We currently support only contraction2 */ next->ch[0]= wc[0]; @@ -6819,20 +6819,24 @@ my_uca_add_contraction(CHARSET_INFO *cs, */ static my_bool -my_uca_alloc_contractions(CHARSET_INFO *cs, void *(*alloc)(size_t), size_t n) +my_uca_alloc_contractions(struct charset_info_st *cs, + void *(*alloc)(size_t), size_t n) { uint size= n * sizeof(MY_CONTRACTION); - if (!(cs->contractions= (*alloc)(sizeof(MY_CONTRACTIONS)))) + MY_CONTRACTIONS *contractions; + + if (!(cs->contractions= contractions= (*alloc)(sizeof(MY_CONTRACTIONS)))) return 1; - bzero(cs->contractions, sizeof(MY_CONTRACTIONS)); - if (!(cs->contractions->item= (*alloc)(size)) || - !(cs->contractions->flags= (char*) (*alloc)(MY_UCA_CNT_FLAG_SIZE))) + bzero(contractions, sizeof(MY_CONTRACTIONS)); + if (!(contractions->item= (*alloc)(size)) || + !(contractions->flags= (char*) (*alloc)(MY_UCA_CNT_FLAG_SIZE))) return 1; - bzero((void*) cs->contractions->item, size); - bzero((void*) cs->contractions->flags, MY_UCA_CNT_FLAG_SIZE); + bzero(contractions->item, size); + bzero(contractions->flags, MY_UCA_CNT_FLAG_SIZE); return 0; } + #ifdef HAVE_CHARSET_ucs2 /* Initialize collation weight scanner @@ -6940,8 +6944,8 @@ static int my_uca_scanner_next_ucs2(my_uca_scanner *scanner) do { - uint16 **ucaw= scanner->uca_weight; - uchar *ucal= scanner->uca_length; + const uint16 *const *ucaw= scanner->uca_weight; + const uchar *ucal= scanner->uca_length; if (scanner->sbeg > scanner->send) return -1; @@ -6956,7 +6960,7 @@ static int my_uca_scanner_next_ucs2(my_uca_scanner *scanner) if (my_uca_can_be_contraction_head(scanner->cs, wc1)) { - uint16 *cweight; + const uint16 *cweight; my_wc_t wc2= (((my_wc_t) scanner->sbeg[0]) << 8) | scanner->sbeg[1]; if (my_uca_can_be_contraction_tail(scanner->cs, wc2) && (cweight= my_uca_contraction2_weight(scanner->cs, @@ -7037,8 +7041,8 @@ static int my_uca_scanner_next_any(my_uca_scanner *scanner) do { - uint16 **ucaw= scanner->uca_weight; - uchar *ucal= scanner->uca_length; + const uint16 *const *ucaw= scanner->uca_weight; + const uchar *ucal= scanner->uca_length; my_wc_t wc; int mb_len; @@ -7055,7 +7059,7 @@ static int my_uca_scanner_next_any(my_uca_scanner *scanner) my_uca_can_be_contraction_head(scanner->cs, wc)) { my_wc_t wc2; - uint16 *cweight; + const uint16 *cweight; if (((mb_len= scanner->cs->cset->mb_wc(scanner->cs, &wc2, scanner->sbeg, @@ -7118,14 +7122,14 @@ static my_uca_scanner_handler my_any_uca_scanner_handler= or NULL if this page does not have implicit weights. */ -static inline uint16 * +static inline const uint16 * my_char_weight_addr(CHARSET_INFO *cs, uint wc) { uint page= (wc >> 8); uint ofst= wc & 0xFF; - return cs->sort_order_big[page] ? - cs->sort_order_big[page] + ofst * cs->sort_order[page] : - NULL; + return (cs->sort_order_big[page] ? + cs->sort_order_big[page] + ofst * cs->sort_order[page] : + 0); } @@ -7415,12 +7419,12 @@ static int my_uca_charcmp(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2) { size_t page1= wc1 >> MY_UCA_PSHIFT; size_t page2= wc2 >> MY_UCA_PSHIFT; - uchar *ucal= cs->sort_order; - uint16 **ucaw= cs->sort_order_big; + const uchar *ucal= cs->sort_order; + const uint16 *const *ucaw= cs->sort_order_big; size_t length1= ucal[page1]; size_t length2= ucal[page2]; - uint16 *weight1= ucaw[page1] + (wc1 & MY_UCA_CMASK) * ucal[page1]; - uint16 *weight2= ucaw[page2] + (wc2 & MY_UCA_CMASK) * ucal[page2]; + const uint16 *weight1= ucaw[page1] + (wc1 & MY_UCA_CMASK) * ucal[page1]; + const uint16 *weight2= ucaw[page2] + (wc2 & MY_UCA_CMASK) * ucal[page2]; if (!weight1 || !weight2) return wc1 != wc2; @@ -7452,9 +7456,7 @@ int my_wildcmp_uca(CHARSET_INFO *cs, int result= -1; /* Not found, using wildcards */ my_wc_t s_wc, w_wc; int scan; - int (*mb_wc)(struct charset_info_st *, my_wc_t *, - const uchar *, const uchar *); - mb_wc= cs->cset->mb_wc; + my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc; while (wildstr != wildend) { @@ -7949,7 +7951,8 @@ static int my_coll_rule_parse(MY_COLL_RULE *rule, size_t mitems, default weights. */ -static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t)) +static my_bool create_tailoring(struct charset_info_st *cs, + void *(*alloc)(size_t)) { MY_COLL_RULE rule[MY_MAX_COLL_RULE]; MY_COLL_RULE *r, *rfirst, *rlast; @@ -7957,7 +7960,7 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t)) uchar *newlengths; uint16 **newweights; const uchar *deflengths= uca_length; - uint16 **defweights= uca_weight; + const uint16 *const *defweights= uca_weight; int rc, i; int ncontractions= 0; @@ -8053,11 +8056,11 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t)) for (i= 0; i < 256 ; i++) { if (!newweights[i]) - newweights[i]= defweights[i]; + ((const uint16**) newweights)[i]= defweights[i]; } cs->sort_order= newlengths; - cs->sort_order_big= newweights; + cs->sort_order_big= (const uint16**) newweights; cs->contractions= NULL; /* Now process contractions */ @@ -8091,7 +8094,8 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t)) Should work for any character set. */ -static my_bool my_coll_init_uca(CHARSET_INFO *cs, void *(*alloc)(size_t)) +static my_bool my_coll_init_uca(struct charset_info_st *cs, + void *(*alloc)(size_t)) { cs->pad_char= ' '; cs->ctype= my_charset_utf8_unicode_ci.ctype; @@ -8186,7 +8190,7 @@ MY_COLLATION_HANDLER my_collation_ucs2_uca_handler = my_propagate_complex }; -CHARSET_INFO my_charset_ucs2_unicode_ci= +struct charset_info_st my_charset_ucs2_unicode_ci= { 128,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8218,7 +8222,7 @@ CHARSET_INFO my_charset_ucs2_unicode_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_icelandic_uca_ci= +struct charset_info_st my_charset_ucs2_icelandic_uca_ci= { 129,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8250,7 +8254,7 @@ CHARSET_INFO my_charset_ucs2_icelandic_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_latvian_uca_ci= +struct charset_info_st my_charset_ucs2_latvian_uca_ci= { 130,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8282,7 +8286,7 @@ CHARSET_INFO my_charset_ucs2_latvian_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_romanian_uca_ci= +struct charset_info_st my_charset_ucs2_romanian_uca_ci= { 131,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8314,7 +8318,7 @@ CHARSET_INFO my_charset_ucs2_romanian_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_slovenian_uca_ci= +struct charset_info_st my_charset_ucs2_slovenian_uca_ci= { 132,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8346,7 +8350,7 @@ CHARSET_INFO my_charset_ucs2_slovenian_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_polish_uca_ci= +struct charset_info_st my_charset_ucs2_polish_uca_ci= { 133,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8378,7 +8382,7 @@ CHARSET_INFO my_charset_ucs2_polish_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_estonian_uca_ci= +struct charset_info_st my_charset_ucs2_estonian_uca_ci= { 134,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8410,7 +8414,7 @@ CHARSET_INFO my_charset_ucs2_estonian_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_spanish_uca_ci= +struct charset_info_st my_charset_ucs2_spanish_uca_ci= { 135,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8442,7 +8446,7 @@ CHARSET_INFO my_charset_ucs2_spanish_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_swedish_uca_ci= +struct charset_info_st my_charset_ucs2_swedish_uca_ci= { 136,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8474,7 +8478,7 @@ CHARSET_INFO my_charset_ucs2_swedish_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_turkish_uca_ci= +struct charset_info_st my_charset_ucs2_turkish_uca_ci= { 137,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8506,7 +8510,7 @@ CHARSET_INFO my_charset_ucs2_turkish_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_czech_uca_ci= +struct charset_info_st my_charset_ucs2_czech_uca_ci= { 138,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8539,7 +8543,7 @@ CHARSET_INFO my_charset_ucs2_czech_uca_ci= }; -CHARSET_INFO my_charset_ucs2_danish_uca_ci= +struct charset_info_st my_charset_ucs2_danish_uca_ci= { 139,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8571,7 +8575,7 @@ CHARSET_INFO my_charset_ucs2_danish_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_lithuanian_uca_ci= +struct charset_info_st my_charset_ucs2_lithuanian_uca_ci= { 140,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8603,7 +8607,7 @@ CHARSET_INFO my_charset_ucs2_lithuanian_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_slovak_uca_ci= +struct charset_info_st my_charset_ucs2_slovak_uca_ci= { 141,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8635,7 +8639,7 @@ CHARSET_INFO my_charset_ucs2_slovak_uca_ci= &my_collation_ucs2_uca_handler }; -CHARSET_INFO my_charset_ucs2_spanish2_uca_ci= +struct charset_info_st my_charset_ucs2_spanish2_uca_ci= { 142,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8668,7 +8672,7 @@ CHARSET_INFO my_charset_ucs2_spanish2_uca_ci= }; -CHARSET_INFO my_charset_ucs2_roman_uca_ci= +struct charset_info_st my_charset_ucs2_roman_uca_ci= { 143,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8701,7 +8705,7 @@ CHARSET_INFO my_charset_ucs2_roman_uca_ci= }; -CHARSET_INFO my_charset_ucs2_persian_uca_ci= +struct charset_info_st my_charset_ucs2_persian_uca_ci= { 144,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8734,7 +8738,7 @@ CHARSET_INFO my_charset_ucs2_persian_uca_ci= }; -CHARSET_INFO my_charset_ucs2_esperanto_uca_ci= +struct charset_info_st my_charset_ucs2_esperanto_uca_ci= { 145,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8767,7 +8771,7 @@ CHARSET_INFO my_charset_ucs2_esperanto_uca_ci= }; -CHARSET_INFO my_charset_ucs2_hungarian_uca_ci= +struct charset_info_st my_charset_ucs2_hungarian_uca_ci= { 146,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -8800,7 +8804,7 @@ CHARSET_INFO my_charset_ucs2_hungarian_uca_ci= }; -CHARSET_INFO my_charset_ucs2_croatian_uca_ci= +struct charset_info_st my_charset_ucs2_croatian_uca_ci= { 149,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -8880,7 +8884,7 @@ static uchar ctype_utf8[] = { extern MY_CHARSET_HANDLER my_charset_utf8_handler; -CHARSET_INFO my_charset_utf8_unicode_ci= +struct charset_info_st my_charset_utf8_unicode_ci= { 192,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -8913,7 +8917,7 @@ CHARSET_INFO my_charset_utf8_unicode_ci= }; -CHARSET_INFO my_charset_utf8_icelandic_uca_ci= +struct charset_info_st my_charset_utf8_icelandic_uca_ci= { 193,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -8945,7 +8949,7 @@ CHARSET_INFO my_charset_utf8_icelandic_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_latvian_uca_ci= +struct charset_info_st my_charset_utf8_latvian_uca_ci= { 194,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -8977,7 +8981,7 @@ CHARSET_INFO my_charset_utf8_latvian_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_romanian_uca_ci= +struct charset_info_st my_charset_utf8_romanian_uca_ci= { 195,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9009,7 +9013,7 @@ CHARSET_INFO my_charset_utf8_romanian_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_slovenian_uca_ci= +struct charset_info_st my_charset_utf8_slovenian_uca_ci= { 196,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9041,7 +9045,7 @@ CHARSET_INFO my_charset_utf8_slovenian_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_polish_uca_ci= +struct charset_info_st my_charset_utf8_polish_uca_ci= { 197,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9073,7 +9077,7 @@ CHARSET_INFO my_charset_utf8_polish_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_estonian_uca_ci= +struct charset_info_st my_charset_utf8_estonian_uca_ci= { 198,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9105,7 +9109,7 @@ CHARSET_INFO my_charset_utf8_estonian_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_spanish_uca_ci= +struct charset_info_st my_charset_utf8_spanish_uca_ci= { 199,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9137,7 +9141,7 @@ CHARSET_INFO my_charset_utf8_spanish_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_swedish_uca_ci= +struct charset_info_st my_charset_utf8_swedish_uca_ci= { 200,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9169,7 +9173,7 @@ CHARSET_INFO my_charset_utf8_swedish_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_turkish_uca_ci= +struct charset_info_st my_charset_utf8_turkish_uca_ci= { 201,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9201,7 +9205,7 @@ CHARSET_INFO my_charset_utf8_turkish_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_czech_uca_ci= +struct charset_info_st my_charset_utf8_czech_uca_ci= { 202,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9234,7 +9238,7 @@ CHARSET_INFO my_charset_utf8_czech_uca_ci= }; -CHARSET_INFO my_charset_utf8_danish_uca_ci= +struct charset_info_st my_charset_utf8_danish_uca_ci= { 203,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9266,7 +9270,7 @@ CHARSET_INFO my_charset_utf8_danish_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_lithuanian_uca_ci= +struct charset_info_st my_charset_utf8_lithuanian_uca_ci= { 204,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9298,7 +9302,7 @@ CHARSET_INFO my_charset_utf8_lithuanian_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_slovak_uca_ci= +struct charset_info_st my_charset_utf8_slovak_uca_ci= { 205,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9330,7 +9334,7 @@ CHARSET_INFO my_charset_utf8_slovak_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_spanish2_uca_ci= +struct charset_info_st my_charset_utf8_spanish2_uca_ci= { 206,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9362,7 +9366,7 @@ CHARSET_INFO my_charset_utf8_spanish2_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_roman_uca_ci= +struct charset_info_st my_charset_utf8_roman_uca_ci= { 207,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9394,7 +9398,7 @@ CHARSET_INFO my_charset_utf8_roman_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_persian_uca_ci= +struct charset_info_st my_charset_utf8_persian_uca_ci= { 208,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9426,7 +9430,7 @@ CHARSET_INFO my_charset_utf8_persian_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_esperanto_uca_ci= +struct charset_info_st my_charset_utf8_esperanto_uca_ci= { 209,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9458,7 +9462,7 @@ CHARSET_INFO my_charset_utf8_esperanto_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_hungarian_uca_ci= +struct charset_info_st my_charset_utf8_hungarian_uca_ci= { 210,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9490,7 +9494,7 @@ CHARSET_INFO my_charset_utf8_hungarian_uca_ci= &my_collation_any_uca_handler }; -CHARSET_INFO my_charset_utf8_croatian_uca_ci= +struct charset_info_st my_charset_utf8_croatian_uca_ci= { 213,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, @@ -9585,11 +9589,11 @@ my_uca_can_be_contraction_tail(CHARSET_INFO *cs, my_wc_t wc) @retval ptr - contraction weight array */ -uint16 * +const uint16 * my_uca_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2) { - MY_CONTRACTIONS *list= cs->contractions; - MY_CONTRACTION *c, *last; + const MY_CONTRACTIONS *list= cs->contractions; + const MY_CONTRACTION *c, *last; for (c= list->item, last= &list->item[list->nitems]; c < last; c++) { if (c->ch[0] == wc1 && c->ch[1] == wc2) diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 0e36742cb3f..6c2d1cf2fb1 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -32,7 +32,7 @@ #endif -static uchar ctype_ucs2[] = { +static const uchar ctype_ucs2[] = { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, @@ -52,7 +52,7 @@ static uchar ctype_ucs2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static uchar to_lower_ucs2[] = { +static const uchar to_lower_ucs2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -71,7 +71,7 @@ static uchar to_lower_ucs2[] = { 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 }; -static uchar to_upper_ucs2[] = { +static const uchar to_upper_ucs2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -120,7 +120,7 @@ static size_t my_caseup_ucs2(CHARSET_INFO *cs, char *src, size_t srclen, my_wc_t wc; int res; char *srcend= src + srclen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; DBUG_ASSERT(src == dst && srclen == dstlen); while ((src < srcend) && @@ -142,7 +142,7 @@ static void my_hash_sort_ucs2(CHARSET_INFO *cs, const uchar *s, size_t slen, my_wc_t wc; int res; const uchar *e=s+slen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; while (e > s+1 && e[-1] == ' ' && e[-2] == '\0') e-= 2; @@ -174,7 +174,7 @@ static size_t my_casedn_ucs2(CHARSET_INFO *cs, char *src, size_t srclen, my_wc_t wc; int res; char *srcend= src + srclen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; DBUG_ASSERT(src == dst && srclen == dstlen); while ((src < srcend) && @@ -206,7 +206,7 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs, my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se=s+slen; const uchar *te=t+tlen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; while ( s < se && t < te ) { @@ -270,7 +270,7 @@ static int my_strnncollsp_ucs2(CHARSET_INFO *cs __attribute__((unused)), { const uchar *se, *te; size_t minlen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; /* extra safety to make sure the lengths are even numbers */ slen&= ~1; @@ -320,7 +320,7 @@ static int my_strncasecmp_ucs2(CHARSET_INFO *cs, my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const char *se=s+len; const char *te=t+len; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; while ( s < se && t < te ) { @@ -369,7 +369,7 @@ static size_t my_strnxfrm_ucs2(CHARSET_INFO *cs, int plane; uchar *de = dst + dstlen; const uchar *se = src + srclen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; while( src < se && dst < de ) { @@ -1360,7 +1360,7 @@ int my_wildcmp_ucs2_ci(CHARSET_INFO *cs, const char *wildstr,const char *wildend, int escape, int w_one, int w_many) { - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; return my_wildcmp_unicode(cs,str,str_end,wildstr,wildend, escape,w_one,w_many,uni_plane); } @@ -1708,7 +1708,7 @@ MY_CHARSET_HANDLER my_charset_ucs2_handler= }; -CHARSET_INFO my_charset_ucs2_general_ci= +struct charset_info_st my_charset_ucs2_general_ci= { 35,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, @@ -1740,7 +1740,7 @@ CHARSET_INFO my_charset_ucs2_general_ci= &my_collation_ucs2_general_ci_handler }; -CHARSET_INFO my_charset_ucs2_bin= +struct charset_info_st my_charset_ucs2_bin= { 90,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_UNICODE|MY_CS_NONASCII, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 3f296eb3ab2..65b17970a04 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -34,7 +34,7 @@ #ifdef HAVE_CHARSET_ujis -static uchar NEAR ctype_ujis[257] = +static const uchar NEAR ctype_ujis[257] = { 0, /* For standard library */ 0040, 0040, 0040, 0040, 0040, 0040, 0040, 0040, /* NUL ^A - ^G */ @@ -71,7 +71,7 @@ static uchar NEAR ctype_ujis[257] = 0020, 0020, 0020, 0020, 0020, 0020, 0020, 0000, }; -static uchar NEAR to_lower_ujis[]= +static const uchar NEAR to_lower_ujis[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -107,7 +107,7 @@ static uchar NEAR to_lower_ujis[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377' }; -static uchar NEAR to_upper_ujis[]= +static const uchar NEAR to_upper_ujis[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -143,7 +143,7 @@ static uchar NEAR to_upper_ujis[]= (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377' }; -static uchar NEAR sort_order_ujis[]= +static const uchar NEAR sort_order_ujis[]= { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -202,7 +202,7 @@ static uint mbcharlen_ujis(CHARSET_INFO *cs __attribute__((unused)),uint c) } -static uint16 tab_jisx0201_uni[256]={ +static const uint16 tab_jisx0201_uni[256]={ 0,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -271,7 +271,7 @@ my_wc_mb_jisx0201(CHARSET_INFO *cs __attribute__((unused)), /* page 0 0x2121-0x217E */ -static uint16 tab_jisx0208_uni0[]={ +static const uint16 tab_jisx0208_uni0[]={ 0x3000,0x3001,0x3002,0xFF0C,0xFF0E,0x30FB,0xFF1A,0xFF1B, 0xFF1F,0xFF01,0x309B,0x309C,0x00B4,0xFF40,0x00A8,0xFF3E, 0xFFE3,0xFF3F,0x30FD,0x30FE,0x309D,0x309E,0x3003,0x4EDD, @@ -286,7 +286,7 @@ static uint16 tab_jisx0208_uni0[]={ 0x2606,0x2605,0x25CB,0x25CF,0x25CE,0x25C7}; /* page 1 0x2221-0x227E */ -static uint16 tab_jisx0208_uni1[]={ +static const uint16 tab_jisx0208_uni1[]={ 0x25C6,0x25A1,0x25A0,0x25B3,0x25B2,0x25BD,0x25BC,0x203B, 0x3012,0x2192,0x2190,0x2191,0x2193,0x3013, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -301,7 +301,7 @@ static uint16 tab_jisx0208_uni1[]={ 0x00B6, 0, 0, 0, 0,0x25EF}; /* page 2 0x2330-0x237A */ -static uint16 tab_jisx0208_uni2[]={ +static const uint16 tab_jisx0208_uni2[]={ 0xFF10,0xFF11,0xFF12,0xFF13,0xFF14,0xFF15,0xFF16,0xFF17, 0xFF18,0xFF19, 0, 0, 0, 0, 0, 0, 0,0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27, @@ -314,7 +314,7 @@ static uint16 tab_jisx0208_uni2[]={ 0xFF58,0xFF59,0xFF5A}; /* page 3 0x2421-0x2473 */ -static uint16 tab_jisx0208_uni3[]={ +static const uint16 tab_jisx0208_uni3[]={ 0x3041,0x3042,0x3043,0x3044,0x3045,0x3046,0x3047,0x3048, 0x3049,0x304A,0x304B,0x304C,0x304D,0x304E,0x304F,0x3050, 0x3051,0x3052,0x3053,0x3054,0x3055,0x3056,0x3057,0x3058, @@ -328,7 +328,7 @@ static uint16 tab_jisx0208_uni3[]={ 0x3091,0x3092,0x3093}; /* page 4 0x2521-0x2576 */ -static uint16 tab_jisx0208_uni4[]={ +static const uint16 tab_jisx0208_uni4[]={ 0x30A1,0x30A2,0x30A3,0x30A4,0x30A5,0x30A6,0x30A7,0x30A8, 0x30A9,0x30AA,0x30AB,0x30AC,0x30AD,0x30AE,0x30AF,0x30B0, 0x30B1,0x30B2,0x30B3,0x30B4,0x30B5,0x30B6,0x30B7,0x30B8, @@ -342,7 +342,7 @@ static uint16 tab_jisx0208_uni4[]={ 0x30F1,0x30F2,0x30F3,0x30F4,0x30F5,0x30F6}; /* page 5 0x2621-0x2658 */ -static uint16 tab_jisx0208_uni5[]={ +static const uint16 tab_jisx0208_uni5[]={ 0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398, 0x0399,0x039A,0x039B,0x039C,0x039D,0x039E,0x039F,0x03A0, 0x03A1,0x03A3,0x03A4,0x03A5,0x03A6,0x03A7,0x03A8,0x03A9, @@ -353,7 +353,7 @@ static uint16 tab_jisx0208_uni5[]={ }; /* page 6 0x2721-0x2771 */ -static uint16 tab_jisx0208_uni6[]={ +static const uint16 tab_jisx0208_uni6[]={ 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0401,0x0416, 0x0417,0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E, 0x041F,0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426, @@ -367,7 +367,7 @@ static uint16 tab_jisx0208_uni6[]={ 0x044F}; /* page 7 0x2821-0x2840 */ -static uint16 tab_jisx0208_uni7[]={ +static const uint16 tab_jisx0208_uni7[]={ 0x2500,0x2502,0x250C,0x2510,0x2518,0x2514,0x251C,0x252C, 0x2524,0x2534,0x253C,0x2501,0x2503,0x250F,0x2513,0x251B, 0x2517,0x2523,0x2533,0x252B,0x253B,0x254B,0x2520,0x252F, @@ -375,7 +375,7 @@ static uint16 tab_jisx0208_uni7[]={ }; /* page 8 0x3021-0x307E */ -static uint16 tab_jisx0208_uni8[]={ +static const uint16 tab_jisx0208_uni8[]={ 0x4E9C,0x5516,0x5A03,0x963F,0x54C0,0x611B,0x6328,0x59F6, 0x9022,0x8475,0x831C,0x7A50,0x60AA,0x63E1,0x6E25,0x65ED, 0x8466,0x82A6,0x9BF5,0x6893,0x5727,0x65A1,0x6271,0x5B9B, @@ -390,7 +390,7 @@ static uint16 tab_jisx0208_uni8[]={ 0x59FB,0x5F15,0x98F2,0x6DEB,0x80E4,0x852D}; /* page 9 0x3121-0x317E */ -static uint16 tab_jisx0208_uni9[]={ +static const uint16 tab_jisx0208_uni9[]={ 0x9662,0x9670,0x96A0,0x97FB,0x540B,0x53F3,0x5B87,0x70CF, 0x7FBD,0x8FC2,0x96E8,0x536F,0x9D5C,0x7ABA,0x4E11,0x7893, 0x81FC,0x6E26,0x5618,0x5504,0x6B1D,0x851A,0x9C3B,0x59E5, @@ -405,7 +405,7 @@ static uint16 tab_jisx0208_uni9[]={ 0x7525,0x51F9,0x592E,0x5965,0x5F80,0x5FDC}; /* page 10 0x3221-0x327E */ -static uint16 tab_jisx0208_uni10[]={ +static const uint16 tab_jisx0208_uni10[]={ 0x62BC,0x65FA,0x6A2A,0x6B27,0x6BB4,0x738B,0x7FC1,0x8956, 0x9D2C,0x9D0E,0x9EC4,0x5CA1,0x6C96,0x837B,0x5104,0x5C4B, 0x61B6,0x81C6,0x6876,0x7261,0x4E59,0x4FFA,0x5378,0x6069, @@ -420,7 +420,7 @@ static uint16 tab_jisx0208_uni10[]={ 0x6094,0x6062,0x61D0,0x6212,0x62D0,0x6539}; /* page 11 0x3321-0x337E */ -static uint16 tab_jisx0208_uni11[]={ +static const uint16 tab_jisx0208_uni11[]={ 0x9B41,0x6666,0x68B0,0x6D77,0x7070,0x754C,0x7686,0x7D75, 0x82A5,0x87F9,0x958B,0x968E,0x8C9D,0x51F1,0x52BE,0x5916, 0x54B3,0x5BB3,0x5D16,0x6168,0x6982,0x6DAF,0x788D,0x84CB, @@ -435,7 +435,7 @@ static uint16 tab_jisx0208_uni11[]={ 0x938C,0x565B,0x9D28,0x6822,0x8305,0x8431}; /* page 12 0x3421-0x347E */ -static uint16 tab_jisx0208_uni12[]={ +static const uint16 tab_jisx0208_uni12[]={ 0x7CA5,0x5208,0x82C5,0x74E6,0x4E7E,0x4F83,0x51A0,0x5BD2, 0x520A,0x52D8,0x52E7,0x5DFB,0x559A,0x582A,0x59E6,0x5B8C, 0x5B98,0x5BDB,0x5E72,0x5E79,0x60A3,0x611F,0x6163,0x61BE, @@ -450,7 +450,7 @@ static uint16 tab_jisx0208_uni12[]={ 0x673A,0x65D7,0x65E2,0x671F,0x68CB,0x68C4}; /* page 13 0x3521-0x357E */ -static uint16 tab_jisx0208_uni13[]={ +static const uint16 tab_jisx0208_uni13[]={ 0x6A5F,0x5E30,0x6BC5,0x6C17,0x6C7D,0x757F,0x7948,0x5B63, 0x7A00,0x7D00,0x5FBD,0x898F,0x8A18,0x8CB4,0x8D77,0x8ECC, 0x8F1D,0x98E2,0x9A0E,0x9B3C,0x4E80,0x507D,0x5100,0x5993, @@ -465,7 +465,7 @@ static uint16 tab_jisx0208_uni13[]={ 0x6F01,0x79A6,0x9B5A,0x4EA8,0x4EAB,0x4EAC}; /* page 14 0x3621-0x367E */ -static uint16 tab_jisx0208_uni14[]={ +static const uint16 tab_jisx0208_uni14[]={ 0x4F9B,0x4FA0,0x50D1,0x5147,0x7AF6,0x5171,0x51F6,0x5354, 0x5321,0x537F,0x53EB,0x55AC,0x5883,0x5CE1,0x5F37,0x5F4A, 0x602F,0x6050,0x606D,0x631F,0x6559,0x6A4B,0x6CC1,0x72C2, @@ -480,7 +480,7 @@ static uint16 tab_jisx0208_uni14[]={ 0x9685,0x4E32,0x6ADB,0x91E7,0x5C51,0x5C48}; /* page 15 0x3721-0x377E */ -static uint16 tab_jisx0208_uni15[]={ +static const uint16 tab_jisx0208_uni15[]={ 0x6398,0x7A9F,0x6C93,0x9774,0x8F61,0x7AAA,0x718A,0x9688, 0x7C82,0x6817,0x7E70,0x6851,0x936C,0x52F2,0x541B,0x85AB, 0x8A13,0x7FA4,0x8ECD,0x90E1,0x5366,0x8888,0x7941,0x4FC2, @@ -495,7 +495,7 @@ static uint16 tab_jisx0208_uni15[]={ 0x5ACC,0x5EFA,0x61B2,0x61F8,0x62F3,0x6372}; /* page 16 0x3821-0x387E */ -static uint16 tab_jisx0208_uni16[]={ +static const uint16 tab_jisx0208_uni16[]={ 0x691C,0x6A29,0x727D,0x72AC,0x732E,0x7814,0x786F,0x7D79, 0x770C,0x80A9,0x898B,0x8B19,0x8CE2,0x8ED2,0x9063,0x9375, 0x967A,0x9855,0x9A13,0x9E78,0x5143,0x539F,0x53B3,0x5E7B, @@ -510,7 +510,7 @@ static uint16 tab_jisx0208_uni16[]={ 0x529F,0x52B9,0x52FE,0x539A,0x53E3,0x5411}; /* page 17 0x3921-0x397E */ -static uint16 tab_jisx0208_uni17[]={ +static const uint16 tab_jisx0208_uni17[]={ 0x540E,0x5589,0x5751,0x57A2,0x597D,0x5B54,0x5B5D,0x5B8F, 0x5DE5,0x5DE7,0x5DF7,0x5E78,0x5E83,0x5E9A,0x5EB7,0x5F18, 0x6052,0x614C,0x6297,0x62D8,0x63A7,0x653B,0x6602,0x6643, @@ -525,7 +525,7 @@ static uint16 tab_jisx0208_uni17[]={ 0x7511,0x5FFD,0x60DA,0x9AA8,0x72DB,0x8FBC}; /* page 18 0x3A21-0x3A7E */ -static uint16 tab_jisx0208_uni18[]={ +static const uint16 tab_jisx0208_uni18[]={ 0x6B64,0x9803,0x4ECA,0x56F0,0x5764,0x58BE,0x5A5A,0x6068, 0x61C7,0x660F,0x6606,0x6839,0x68B1,0x6DF7,0x75D5,0x7D3A, 0x826E,0x9B42,0x4E9B,0x4F50,0x53C9,0x5506,0x5D6F,0x5DE6, @@ -540,7 +540,7 @@ static uint16 tab_jisx0208_uni18[]={ 0x685C,0x9BAD,0x7B39,0x5319,0x518A,0x5237}; /* page 19 0x3B21-0x3B7E */ -static uint16 tab_jisx0208_uni19[]={ +static const uint16 tab_jisx0208_uni19[]={ 0x5BDF,0x62F6,0x64AE,0x64E6,0x672D,0x6BBA,0x85A9,0x96D1, 0x7690,0x9BD6,0x634C,0x9306,0x9BAB,0x76BF,0x6652,0x4E09, 0x5098,0x53C2,0x5C71,0x60E8,0x6492,0x6563,0x685F,0x71E6, @@ -555,7 +555,7 @@ static uint16 tab_jisx0208_uni19[]={ 0x5150,0x5B57,0x5BFA,0x6148,0x6301,0x6642}; /* page 20 0x3C21-0x3C7E */ -static uint16 tab_jisx0208_uni20[]={ +static const uint16 tab_jisx0208_uni20[]={ 0x6B21,0x6ECB,0x6CBB,0x723E,0x74BD,0x75D4,0x78C1,0x793A, 0x800C,0x8033,0x81EA,0x8494,0x8F9E,0x6C50,0x9E7F,0x5F0F, 0x8B58,0x9D2B,0x7AFA,0x8EF8,0x5B8D,0x96EB,0x4E03,0x53F1, @@ -570,7 +570,7 @@ static uint16 tab_jisx0208_uni20[]={ 0x6A39,0x7DAC,0x9700,0x56DA,0x53CE,0x5468}; /* page 21 0x3D21-0x3D7E */ -static uint16 tab_jisx0208_uni21[]={ +static const uint16 tab_jisx0208_uni21[]={ 0x5B97,0x5C31,0x5DDE,0x4FEE,0x6101,0x62FE,0x6D32,0x79C0, 0x79CB,0x7D42,0x7E4D,0x7FD2,0x81ED,0x821F,0x8490,0x8846, 0x8972,0x8B90,0x8E74,0x8F2F,0x9031,0x914B,0x916C,0x96C6, @@ -585,7 +585,7 @@ static uint16 tab_jisx0208_uni21[]={ 0x5F90,0x6055,0x92E4,0x9664,0x50B7,0x511F}; /* page 22 0x3E21-0x3E7E */ -static uint16 tab_jisx0208_uni22[]={ +static const uint16 tab_jisx0208_uni22[]={ 0x52DD,0x5320,0x5347,0x53EC,0x54E8,0x5546,0x5531,0x5617, 0x5968,0x59BE,0x5A3C,0x5BB5,0x5C06,0x5C0F,0x5C11,0x5C1A, 0x5E84,0x5E8A,0x5EE0,0x5F70,0x627F,0x6284,0x62DB,0x638C, @@ -600,7 +600,7 @@ static uint16 tab_jisx0208_uni22[]={ 0x8B72,0x91B8,0x9320,0x5631,0x57F4,0x98FE}; /* page 23 0x3F21-0x3F7E */ -static uint16 tab_jisx0208_uni23[]={ +static const uint16 tab_jisx0208_uni23[]={ 0x62ED,0x690D,0x6B96,0x71ED,0x7E54,0x8077,0x8272,0x89E6, 0x98DF,0x8755,0x8FB1,0x5C3B,0x4F38,0x4FE1,0x4FB5,0x5507, 0x5A20,0x5BDD,0x5BE9,0x5FC3,0x614E,0x632F,0x65B0,0x664B, @@ -615,7 +615,7 @@ static uint16 tab_jisx0208_uni23[]={ 0x6749,0x6919,0x83C5,0x9817,0x96C0,0x88FE}; /* page 24 0x4021-0x407E */ -static uint16 tab_jisx0208_uni24[]={ +static const uint16 tab_jisx0208_uni24[]={ 0x6F84,0x647A,0x5BF8,0x4E16,0x702C,0x755D,0x662F,0x51C4, 0x5236,0x52E2,0x59D3,0x5F81,0x6027,0x6210,0x653F,0x6574, 0x661F,0x6674,0x68F2,0x6816,0x6B63,0x6E05,0x7272,0x751F, @@ -630,7 +630,7 @@ static uint16 tab_jisx0208_uni24[]={ 0x714E,0x717D,0x65CB,0x7A7F,0x7BAD,0x7DDA}; /* page 25 0x4121-0x417E */ -static uint16 tab_jisx0208_uni25[]={ +static const uint16 tab_jisx0208_uni25[]={ 0x7E4A,0x7FA8,0x817A,0x821B,0x8239,0x85A6,0x8A6E,0x8CCE, 0x8DF5,0x9078,0x9077,0x92AD,0x9291,0x9583,0x9BAE,0x524D, 0x5584,0x6F38,0x7136,0x5168,0x7985,0x7E55,0x81B3,0x7CCE, @@ -645,7 +645,7 @@ static uint16 tab_jisx0208_uni25[]={ 0x9397,0x971C,0x9A12,0x50CF,0x5897,0x618E}; /* page 26 0x4221-0x427E */ -static uint16 tab_jisx0208_uni26[]={ +static const uint16 tab_jisx0208_uni26[]={ 0x81D3,0x8535,0x8D08,0x9020,0x4FC3,0x5074,0x5247,0x5373, 0x606F,0x6349,0x675F,0x6E2C,0x8DB3,0x901F,0x4FD7,0x5C5E, 0x8CCA,0x65CF,0x7D9A,0x5352,0x8896,0x5176,0x63C3,0x5B58, @@ -660,7 +660,7 @@ static uint16 tab_jisx0208_uni26[]={ 0x6FC1,0x8AFE,0x8338,0x51E7,0x86F8,0x53EA}; /* page 27 0x4321-0x437E */ -static uint16 tab_jisx0208_uni27[]={ +static const uint16 tab_jisx0208_uni27[]={ 0x53E9,0x4F46,0x9054,0x8FB0,0x596A,0x8131,0x5DFD,0x7AEA, 0x8FBF,0x68DA,0x8C37,0x72F8,0x9C48,0x6A3D,0x8AB0,0x4E39, 0x5358,0x5606,0x5766,0x62C5,0x63A2,0x65E6,0x6B4E,0x6DE1, @@ -675,7 +675,7 @@ static uint16 tab_jisx0208_uni27[]={ 0x8CAF,0x4E01,0x5146,0x51CB,0x558B,0x5BF5}; /* page 28 0x4421-0x447E */ -static uint16 tab_jisx0208_uni28[]={ +static const uint16 tab_jisx0208_uni28[]={ 0x5E16,0x5E33,0x5E81,0x5F14,0x5F35,0x5F6B,0x5FB4,0x61F2, 0x6311,0x66A2,0x671D,0x6F6E,0x7252,0x753A,0x773A,0x8074, 0x8139,0x8178,0x8776,0x8ABF,0x8ADC,0x8D85,0x8DF3,0x929A, @@ -690,7 +690,7 @@ static uint16 tab_jisx0208_uni28[]={ 0x7DE0,0x8247,0x8A02,0x8AE6,0x8E44,0x9013}; /* page 29 0x4521-0x457E */ -static uint16 tab_jisx0208_uni29[]={ +static const uint16 tab_jisx0208_uni29[]={ 0x90B8,0x912D,0x91D8,0x9F0E,0x6CE5,0x6458,0x64E2,0x6575, 0x6EF4,0x7684,0x7B1B,0x9069,0x93D1,0x6EBA,0x54F2,0x5FB9, 0x64A4,0x8F4D,0x8FED,0x9244,0x5178,0x586B,0x5929,0x5C55, @@ -705,7 +705,7 @@ static uint16 tab_jisx0208_uni29[]={ 0x7B49,0x7B54,0x7B52,0x7CD6,0x7D71,0x5230}; /* page 30 0x4621-0x467E */ -static uint16 tab_jisx0208_uni30[]={ +static const uint16 tab_jisx0208_uni30[]={ 0x8463,0x8569,0x85E4,0x8A0E,0x8B04,0x8C46,0x8E0F,0x9003, 0x900F,0x9419,0x9676,0x982D,0x9A30,0x95D8,0x50CD,0x52D5, 0x540C,0x5802,0x5C0E,0x61A7,0x649E,0x6D1E,0x77B3,0x7AE5, @@ -720,7 +720,7 @@ static uint16 tab_jisx0208_uni30[]={ 0x8089,0x8679,0x5EFF,0x65E5,0x4E73,0x5165}; /* page 31 0x4721-0x477E */ -static uint16 tab_jisx0208_uni31[]={ +static const uint16 tab_jisx0208_uni31[]={ 0x5982,0x5C3F,0x97EE,0x4EFB,0x598A,0x5FCD,0x8A8D,0x6FE1, 0x79B0,0x7962,0x5BE7,0x8471,0x732B,0x71B1,0x5E74,0x5FF5, 0x637B,0x649A,0x71C3,0x7C98,0x4E43,0x5EFC,0x4E4B,0x57DC, @@ -735,7 +735,7 @@ static uint16 tab_jisx0208_uni31[]={ 0x6F20,0x7206,0x7E1B,0x83AB,0x99C1,0x9EA6}; /* page 32 0x4821-0x487E */ -static uint16 tab_jisx0208_uni32[]={ +static const uint16 tab_jisx0208_uni32[]={ 0x51FD,0x7BB1,0x7872,0x7BB8,0x8087,0x7B48,0x6AE8,0x5E61, 0x808C,0x7551,0x7560,0x516B,0x9262,0x6E8C,0x767A,0x9197, 0x9AEA,0x4F10,0x7F70,0x629C,0x7B4F,0x95A5,0x9CE9,0x567A, @@ -750,7 +750,7 @@ static uint16 tab_jisx0208_uni32[]={ 0x5FAE,0x6787,0x6BD8,0x7435,0x7709,0x7F8E}; /* page 33 0x4921-0x497E */ -static uint16 tab_jisx0208_uni33[]={ +static const uint16 tab_jisx0208_uni33[]={ 0x9F3B,0x67CA,0x7A17,0x5339,0x758B,0x9AED,0x5F66,0x819D, 0x83F1,0x8098,0x5F3C,0x5FC5,0x7562,0x7B46,0x903C,0x6867, 0x59EB,0x5A9B,0x7D10,0x767E,0x8B2C,0x4FF5,0x5F6A,0x6A19, @@ -765,7 +765,7 @@ static uint16 tab_jisx0208_uni33[]={ 0x8557,0x4F0F,0x526F,0x5FA9,0x5E45,0x670D}; /* page 34 0x4A21-0x4A7E */ -static uint16 tab_jisx0208_uni34[]={ +static const uint16 tab_jisx0208_uni34[]={ 0x798F,0x8179,0x8907,0x8986,0x6DF5,0x5F17,0x6255,0x6CB8, 0x4ECF,0x7269,0x9B92,0x5206,0x543B,0x5674,0x58B3,0x61A4, 0x626E,0x711A,0x596E,0x7C89,0x7CDE,0x7D1B,0x96F0,0x6587, @@ -780,7 +780,7 @@ static uint16 tab_jisx0208_uni34[]={ 0x5E96,0x62B1,0x6367,0x653E,0x65B9,0x670B}; /* page 35 0x4B21-0x4B7E */ -static uint16 tab_jisx0208_uni35[]={ +static const uint16 tab_jisx0208_uni35[]={ 0x6CD5,0x6CE1,0x70F9,0x7832,0x7E2B,0x80DE,0x82B3,0x840C, 0x84EC,0x8702,0x8912,0x8A2A,0x8C4A,0x90A6,0x92D2,0x98FD, 0x9CF3,0x9D6C,0x4E4F,0x4EA1,0x508D,0x5256,0x574A,0x59A8, @@ -795,7 +795,7 @@ static uint16 tab_jisx0208_uni35[]={ 0x4FAD,0x7E6D,0x9EBF,0x4E07,0x6162,0x6E80}; /* page 36 0x4C21-0x4C7E */ -static uint16 tab_jisx0208_uni36[]={ +static const uint16 tab_jisx0208_uni36[]={ 0x6F2B,0x8513,0x5473,0x672A,0x9B45,0x5DF3,0x7B95,0x5CAC, 0x5BC6,0x871C,0x6E4A,0x84D1,0x7A14,0x8108,0x5999,0x7C8D, 0x6C11,0x7720,0x52D9,0x5922,0x7121,0x725F,0x77DB,0x9727, @@ -810,7 +810,7 @@ static uint16 tab_jisx0208_uni36[]={ 0x85AE,0x9453,0x6109,0x6108,0x6CB9,0x7652}; /* page 37 0x4D21-0x4D7E */ -static uint16 tab_jisx0208_uni37[]={ +static const uint16 tab_jisx0208_uni37[]={ 0x8AED,0x8F38,0x552F,0x4F51,0x512A,0x52C7,0x53CB,0x5BA5, 0x5E7D,0x60A0,0x6182,0x63D6,0x6709,0x67DA,0x6E67,0x6D8C, 0x7336,0x7337,0x7531,0x7950,0x88D5,0x8A98,0x904A,0x9091, @@ -825,7 +825,7 @@ static uint16 tab_jisx0208_uni37[]={ 0x540F,0x5C65,0x674E,0x68A8,0x7406,0x7483}; /* page 38 0x4E21-0x4E7E */ -static uint16 tab_jisx0208_uni38[]={ +static const uint16 tab_jisx0208_uni38[]={ 0x75E2,0x88CF,0x88E1,0x91CC,0x96E2,0x9678,0x5F8B,0x7387, 0x7ACB,0x844E,0x63A0,0x7565,0x5289,0x6D41,0x6E9C,0x7409, 0x7559,0x786B,0x7C92,0x9686,0x7ADC,0x9F8D,0x4FB6,0x616E, @@ -840,7 +840,7 @@ static uint16 tab_jisx0208_uni38[]={ 0x6190,0x6F23,0x7149,0x7C3E,0x7DF4,0x806F}; /* page 39 0x4F21-0x4F53 */ -static uint16 tab_jisx0208_uni39[]={ +static const uint16 tab_jisx0208_uni39[]={ 0x84EE,0x9023,0x932C,0x5442,0x9B6F,0x6AD3,0x7089,0x8CC2, 0x8DEF,0x9732,0x52B4,0x5A41,0x5ECA,0x5F04,0x6717,0x697C, 0x6994,0x6D6A,0x6F0F,0x7262,0x72FC,0x7BED,0x8001,0x807E, @@ -850,7 +850,7 @@ static uint16 tab_jisx0208_uni39[]={ 0x6E7E,0x7897,0x8155}; /* page 40 0x5021-0x507E */ -static uint16 tab_jisx0208_uni40[]={ +static const uint16 tab_jisx0208_uni40[]={ 0x5F0C,0x4E10,0x4E15,0x4E2A,0x4E31,0x4E36,0x4E3C,0x4E3F, 0x4E42,0x4E56,0x4E58,0x4E82,0x4E85,0x8C6B,0x4E8A,0x8212, 0x5F0D,0x4E8E,0x4E9E,0x4E9F,0x4EA0,0x4EA2,0x4EB0,0x4EB3, @@ -865,7 +865,7 @@ static uint16 tab_jisx0208_uni40[]={ 0x5078,0x5080,0x509A,0x5085,0x50B4,0x50B2}; /* page 41 0x5121-0x517E */ -static uint16 tab_jisx0208_uni41[]={ +static const uint16 tab_jisx0208_uni41[]={ 0x50C9,0x50CA,0x50B3,0x50C2,0x50D6,0x50DE,0x50E5,0x50ED, 0x50E3,0x50EE,0x50F9,0x50F5,0x5109,0x5101,0x5102,0x5116, 0x5115,0x5114,0x511A,0x5121,0x513A,0x5137,0x513C,0x513B, @@ -880,7 +880,7 @@ static uint16 tab_jisx0208_uni41[]={ 0x5294,0x5292,0x5271,0x5288,0x5291,0x8FA8}; /* page 42 0x5221-0x527E */ -static uint16 tab_jisx0208_uni42[]={ +static const uint16 tab_jisx0208_uni42[]={ 0x8FA7,0x52AC,0x52AD,0x52BC,0x52B5,0x52C1,0x52CD,0x52D7, 0x52DE,0x52E3,0x52E6,0x98ED,0x52E0,0x52F3,0x52F5,0x52F8, 0x52F9,0x5306,0x5308,0x7538,0x530D,0x5310,0x530F,0x5315, @@ -895,7 +895,7 @@ static uint16 tab_jisx0208_uni42[]={ 0x54B8,0x54A5,0x54AC,0x54C4,0x54C8,0x54A8}; /* page 43 0x5321-0x537E */ -static uint16 tab_jisx0208_uni43[]={ +static const uint16 tab_jisx0208_uni43[]={ 0x54AB,0x54C2,0x54A4,0x54BE,0x54BC,0x54D8,0x54E5,0x54E6, 0x550F,0x5514,0x54FD,0x54EE,0x54ED,0x54FA,0x54E2,0x5539, 0x5540,0x5563,0x554C,0x552E,0x555C,0x5545,0x5556,0x5557, @@ -910,7 +910,7 @@ static uint16 tab_jisx0208_uni43[]={ 0x56EE,0x56F9,0x5700,0x56FF,0x5704,0x5709}; /* page 44 0x5421-0x547E */ -static uint16 tab_jisx0208_uni44[]={ +static const uint16 tab_jisx0208_uni44[]={ 0x5708,0x570B,0x570D,0x5713,0x5718,0x5716,0x55C7,0x571C, 0x5726,0x5737,0x5738,0x574E,0x573B,0x5740,0x574F,0x5769, 0x57C0,0x5788,0x5761,0x577F,0x5789,0x5793,0x57A0,0x57B3, @@ -925,7 +925,7 @@ static uint16 tab_jisx0208_uni44[]={ 0x5958,0x5962,0x5960,0x5967,0x596C,0x5969}; /* page 45 0x5521-0x557E */ -static uint16 tab_jisx0208_uni45[]={ +static const uint16 tab_jisx0208_uni45[]={ 0x5978,0x5981,0x599D,0x4F5E,0x4FAB,0x59A3,0x59B2,0x59C6, 0x59E8,0x59DC,0x598D,0x59D9,0x59DA,0x5A25,0x5A1F,0x5A11, 0x5A1C,0x5A09,0x5A1A,0x5A40,0x5A6C,0x5A49,0x5A35,0x5A36, @@ -940,7 +940,7 @@ static uint16 tab_jisx0208_uni45[]={ 0x5C38,0x5C39,0x5C41,0x5C46,0x5C4E,0x5C53}; /* page 46 0x5621-0x567E */ -static uint16 tab_jisx0208_uni46[]={ +static const uint16 tab_jisx0208_uni46[]={ 0x5C50,0x5C4F,0x5B71,0x5C6C,0x5C6E,0x4E62,0x5C76,0x5C79, 0x5C8C,0x5C91,0x5C94,0x599B,0x5CAB,0x5CBB,0x5CB6,0x5CBC, 0x5CB7,0x5CC5,0x5CBE,0x5CC7,0x5CD9,0x5CE9,0x5CFD,0x5CFA, @@ -955,7 +955,7 @@ static uint16 tab_jisx0208_uni46[]={ 0x5EA0,0x5EC1,0x5EC2,0x5EC8,0x5ED0,0x5ECF}; /* page 47 0x5721-0x577E */ -static uint16 tab_jisx0208_uni47[]={ +static const uint16 tab_jisx0208_uni47[]={ 0x5ED6,0x5EE3,0x5EDD,0x5EDA,0x5EDB,0x5EE2,0x5EE1,0x5EE8, 0x5EE9,0x5EEC,0x5EF1,0x5EF3,0x5EF0,0x5EF4,0x5EF8,0x5EFE, 0x5F03,0x5F09,0x5F5D,0x5F5C,0x5F0B,0x5F11,0x5F16,0x5F29, @@ -970,7 +970,7 @@ static uint16 tab_jisx0208_uni47[]={ 0x6059,0x6081,0x608D,0x60E7,0x6083,0x609A}; /* page 48 0x5821-0x587E */ -static uint16 tab_jisx0208_uni48[]={ +static const uint16 tab_jisx0208_uni48[]={ 0x6084,0x609B,0x6096,0x6097,0x6092,0x60A7,0x608B,0x60E1, 0x60B8,0x60E0,0x60D3,0x60B4,0x5FF0,0x60BD,0x60C6,0x60B5, 0x60D8,0x614D,0x6115,0x6106,0x60F6,0x60F7,0x6100,0x60F4, @@ -985,7 +985,7 @@ static uint16 tab_jisx0208_uni48[]={ 0x6208,0x6209,0x620D,0x620C,0x6214,0x621B}; /* page 49 0x5921-0x597E */ -static uint16 tab_jisx0208_uni49[]={ +static const uint16 tab_jisx0208_uni49[]={ 0x621E,0x6221,0x622A,0x622E,0x6230,0x6232,0x6233,0x6241, 0x624E,0x625E,0x6263,0x625B,0x6260,0x6268,0x627C,0x6282, 0x6289,0x627E,0x6292,0x6293,0x6296,0x62D4,0x6283,0x6294, @@ -1000,7 +1000,7 @@ static uint16 tab_jisx0208_uni49[]={ 0x6495,0x6493,0x64A5,0x64A9,0x6488,0x64BC}; /* page 50 0x5A21-0x5A7E */ -static uint16 tab_jisx0208_uni50[]={ +static const uint16 tab_jisx0208_uni50[]={ 0x64DA,0x64D2,0x64C5,0x64C7,0x64BB,0x64D8,0x64C2,0x64F1, 0x64E7,0x8209,0x64E0,0x64E1,0x62AC,0x64E3,0x64EF,0x652C, 0x64F6,0x64F4,0x64F2,0x64FA,0x6500,0x64FD,0x6518,0x651C, @@ -1015,7 +1015,7 @@ static uint16 tab_jisx0208_uni50[]={ 0x669D,0x66C1,0x66B9,0x66C9,0x66BE,0x66BC}; /* page 51 0x5B21-0x5B7E */ -static uint16 tab_jisx0208_uni51[]={ +static const uint16 tab_jisx0208_uni51[]={ 0x66C4,0x66B8,0x66D6,0x66DA,0x66E0,0x663F,0x66E6,0x66E9, 0x66F0,0x66F5,0x66F7,0x670F,0x6716,0x671E,0x6726,0x6727, 0x9738,0x672E,0x673F,0x6736,0x6741,0x6738,0x6737,0x6746, @@ -1030,7 +1030,7 @@ static uint16 tab_jisx0208_uni51[]={ 0x68D8,0x6922,0x6926,0x68E1,0x690C,0x68CD}; /* page 52 0x5C21-0x5C7E */ -static uint16 tab_jisx0208_uni52[]={ +static const uint16 tab_jisx0208_uni52[]={ 0x68D4,0x68E7,0x68D5,0x6936,0x6912,0x6904,0x68D7,0x68E3, 0x6925,0x68F9,0x68E0,0x68EF,0x6928,0x692A,0x691A,0x6923, 0x6921,0x68C6,0x6979,0x6977,0x695C,0x6978,0x696B,0x6954, @@ -1045,7 +1045,7 @@ static uint16 tab_jisx0208_uni52[]={ 0x6A90,0x6A8D,0x6AA0,0x6A84,0x6AA2,0x6AA3}; /* page 53 0x5D21-0x5D7E */ -static uint16 tab_jisx0208_uni53[]={ +static const uint16 tab_jisx0208_uni53[]={ 0x6A97,0x8617,0x6ABB,0x6AC3,0x6AC2,0x6AB8,0x6AB3,0x6AAC, 0x6ADE,0x6AD1,0x6ADF,0x6AAA,0x6ADA,0x6AEA,0x6AFB,0x6B05, 0x8616,0x6AFA,0x6B12,0x6B16,0x9B31,0x6B1F,0x6B38,0x6B37, @@ -1060,7 +1060,7 @@ static uint16 tab_jisx0208_uni53[]={ 0x6CD7,0x6CC5,0x6CDD,0x6CAE,0x6CB1,0x6CBE}; /* page 54 0x5E21-0x5E7E */ -static uint16 tab_jisx0208_uni54[]={ +static const uint16 tab_jisx0208_uni54[]={ 0x6CBA,0x6CDB,0x6CEF,0x6CD9,0x6CEA,0x6D1F,0x884D,0x6D36, 0x6D2B,0x6D3D,0x6D38,0x6D19,0x6D35,0x6D33,0x6D12,0x6D0C, 0x6D63,0x6D93,0x6D64,0x6D5A,0x6D79,0x6D59,0x6D8E,0x6D95, @@ -1075,7 +1075,7 @@ static uint16 tab_jisx0208_uni54[]={ 0x6F3F,0x6EF2,0x6F31,0x6EEF,0x6F32,0x6ECC}; /* page 55 0x5F21-0x5F7E */ -static uint16 tab_jisx0208_uni55[]={ +static const uint16 tab_jisx0208_uni55[]={ 0x6F3E,0x6F13,0x6EF7,0x6F86,0x6F7A,0x6F78,0x6F81,0x6F80, 0x6F6F,0x6F5B,0x6FF3,0x6F6D,0x6F82,0x6F7C,0x6F58,0x6F8E, 0x6F91,0x6FC2,0x6F66,0x6FB3,0x6FA3,0x6FA1,0x6FA4,0x6FB9, @@ -1090,7 +1090,7 @@ static uint16 tab_jisx0208_uni55[]={ 0x71CE,0x71E0,0x71EC,0x71E7,0x71F5,0x71FC}; /* page 56 0x6021-0x607E */ -static uint16 tab_jisx0208_uni56[]={ +static const uint16 tab_jisx0208_uni56[]={ 0x71F9,0x71FF,0x720D,0x7210,0x721B,0x7228,0x722D,0x722C, 0x7230,0x7232,0x723B,0x723C,0x723F,0x7240,0x7246,0x724B, 0x7258,0x7274,0x727E,0x7282,0x7281,0x7287,0x7292,0x7296, @@ -1105,7 +1105,7 @@ static uint16 tab_jisx0208_uni56[]={ 0x749E,0x74A7,0x74CA,0x74CF,0x74D4,0x73F1}; /* page 57 0x6121-0x617E */ -static uint16 tab_jisx0208_uni57[]={ +static const uint16 tab_jisx0208_uni57[]={ 0x74E0,0x74E3,0x74E7,0x74E9,0x74EE,0x74F2,0x74F0,0x74F1, 0x74F8,0x74F7,0x7504,0x7503,0x7505,0x750C,0x750E,0x750D, 0x7515,0x7513,0x751E,0x7526,0x752C,0x753C,0x7544,0x754D, @@ -1120,7 +1120,7 @@ static uint16 tab_jisx0208_uni57[]={ 0x7668,0x7669,0x766A,0x7667,0x766C,0x7670}; /* page 58 0x6221-0x627E */ -static uint16 tab_jisx0208_uni58[]={ +static const uint16 tab_jisx0208_uni58[]={ 0x7672,0x7676,0x7678,0x767C,0x7680,0x7683,0x7688,0x768B, 0x768E,0x7696,0x7693,0x7699,0x769A,0x76B0,0x76B4,0x76B8, 0x76B9,0x76BA,0x76C2,0x76CD,0x76D6,0x76D2,0x76DE,0x76E1, @@ -1135,7 +1135,7 @@ static uint16 tab_jisx0208_uni58[]={ 0x78D4,0x78BE,0x78BC,0x78C5,0x78CA,0x78EC}; /* page 59 0x6321-0x637E */ -static uint16 tab_jisx0208_uni59[]={ +static const uint16 tab_jisx0208_uni59[]={ 0x78E7,0x78DA,0x78FD,0x78F4,0x7907,0x7912,0x7911,0x7919, 0x792C,0x792B,0x7940,0x7960,0x7957,0x795F,0x795A,0x7955, 0x7953,0x797A,0x797F,0x798A,0x799D,0x79A7,0x9F4B,0x79AA, @@ -1150,7 +1150,7 @@ static uint16 tab_jisx0208_uni59[]={ 0x7B19,0x7B1E,0x7B35,0x7B28,0x7B36,0x7B50}; /* page 60 0x6421-0x647E */ -static uint16 tab_jisx0208_uni60[]={ +static const uint16 tab_jisx0208_uni60[]={ 0x7B7A,0x7B04,0x7B4D,0x7B0B,0x7B4C,0x7B45,0x7B75,0x7B65, 0x7B74,0x7B67,0x7B70,0x7B71,0x7B6C,0x7B6E,0x7B9D,0x7B98, 0x7B9F,0x7B8D,0x7B9C,0x7B9A,0x7B8B,0x7B92,0x7B8F,0x7B5D, @@ -1165,7 +1165,7 @@ static uint16 tab_jisx0208_uni60[]={ 0x7CEF,0x7CF2,0x7CF4,0x7CF6,0x7CFA,0x7D06}; /* page 61 0x6521-0x657E */ -static uint16 tab_jisx0208_uni61[]={ +static const uint16 tab_jisx0208_uni61[]={ 0x7D02,0x7D1C,0x7D15,0x7D0A,0x7D45,0x7D4B,0x7D2E,0x7D32, 0x7D3F,0x7D35,0x7D46,0x7D73,0x7D56,0x7D4E,0x7D72,0x7D68, 0x7D6E,0x7D4F,0x7D63,0x7D93,0x7D89,0x7D5B,0x7D8F,0x7D7D, @@ -1180,7 +1180,7 @@ static uint16 tab_jisx0208_uni61[]={ 0x7E96,0x7E8E,0x7E9B,0x7E9C,0x7F38,0x7F3A}; /* page 62 0x6621-0x667E */ -static uint16 tab_jisx0208_uni62[]={ +static const uint16 tab_jisx0208_uni62[]={ 0x7F45,0x7F4C,0x7F4D,0x7F4E,0x7F50,0x7F51,0x7F55,0x7F54, 0x7F58,0x7F5F,0x7F60,0x7F68,0x7F69,0x7F67,0x7F78,0x7F82, 0x7F86,0x7F83,0x7F88,0x7F87,0x7F8C,0x7F94,0x7F9E,0x7F9D, @@ -1195,7 +1195,7 @@ static uint16 tab_jisx0208_uni62[]={ 0x80F1,0x811B,0x8129,0x8123,0x812F,0x814B}; /* page 63 0x6721-0x677E */ -static uint16 tab_jisx0208_uni63[]={ +static const uint16 tab_jisx0208_uni63[]={ 0x968B,0x8146,0x813E,0x8153,0x8151,0x80FC,0x8171,0x816E, 0x8165,0x8166,0x8174,0x8183,0x8188,0x818A,0x8180,0x8182, 0x81A0,0x8195,0x81A4,0x81A3,0x815F,0x8193,0x81A9,0x81B0, @@ -1210,7 +1210,7 @@ static uint16 tab_jisx0208_uni63[]={ 0x82F9,0x82DE,0x8306,0x82DC,0x8309,0x82D9}; /* page 64 0x6821-0x687E */ -static uint16 tab_jisx0208_uni64[]={ +static const uint16 tab_jisx0208_uni64[]={ 0x8335,0x8334,0x8316,0x8332,0x8331,0x8340,0x8339,0x8350, 0x8345,0x832F,0x832B,0x8317,0x8318,0x8385,0x839A,0x83AA, 0x839F,0x83A2,0x8396,0x8323,0x838E,0x8387,0x838A,0x837C, @@ -1225,7 +1225,7 @@ static uint16 tab_jisx0208_uni64[]={ 0x8514,0x84FC,0x8540,0x8563,0x8558,0x8548}; /* page 65 0x6921-0x697E */ -static uint16 tab_jisx0208_uni65[]={ +static const uint16 tab_jisx0208_uni65[]={ 0x8541,0x8602,0x854B,0x8555,0x8580,0x85A4,0x8588,0x8591, 0x858A,0x85A8,0x856D,0x8594,0x859B,0x85EA,0x8587,0x859C, 0x8577,0x857E,0x8590,0x85C9,0x85BA,0x85CF,0x85B9,0x85D0, @@ -1240,7 +1240,7 @@ static uint16 tab_jisx0208_uni65[]={ 0x874E,0x8774,0x8757,0x8768,0x876E,0x8759}; /* page 66 0x6A21-0x6A7E */ -static uint16 tab_jisx0208_uni66[]={ +static const uint16 tab_jisx0208_uni66[]={ 0x8753,0x8763,0x876A,0x8805,0x87A2,0x879F,0x8782,0x87AF, 0x87CB,0x87BD,0x87C0,0x87D0,0x96D6,0x87AB,0x87C4,0x87B3, 0x87C7,0x87C6,0x87BB,0x87EF,0x87F2,0x87E0,0x880F,0x880D, @@ -1255,7 +1255,7 @@ static uint16 tab_jisx0208_uni66[]={ 0x8936,0x8938,0x894C,0x891D,0x8960,0x895E}; /* page 67 0x6B21-0x6B7E */ -static uint16 tab_jisx0208_uni67[]={ +static const uint16 tab_jisx0208_uni67[]={ 0x8966,0x8964,0x896D,0x896A,0x896F,0x8974,0x8977,0x897E, 0x8983,0x8988,0x898A,0x8993,0x8998,0x89A1,0x89A9,0x89A6, 0x89AC,0x89AF,0x89B2,0x89BA,0x89BD,0x89BF,0x89C0,0x89DA, @@ -1270,7 +1270,7 @@ static uint16 tab_jisx0208_uni67[]={ 0x8B4E,0x8B49,0x8B56,0x8B5B,0x8B5A,0x8B6B}; /* page 68 0x6C21-0x6C7E */ -static uint16 tab_jisx0208_uni68[]={ +static const uint16 tab_jisx0208_uni68[]={ 0x8B5F,0x8B6C,0x8B6F,0x8B74,0x8B7D,0x8B80,0x8B8C,0x8B8E, 0x8B92,0x8B93,0x8B96,0x8B99,0x8B9A,0x8C3A,0x8C41,0x8C3F, 0x8C48,0x8C4C,0x8C4E,0x8C50,0x8C55,0x8C62,0x8C6C,0x8C78, @@ -1285,7 +1285,7 @@ static uint16 tab_jisx0208_uni68[]={ 0x8E1F,0x8E42,0x8E35,0x8E30,0x8E34,0x8E4A}; /* page 69 0x6D21-0x6D7E */ -static uint16 tab_jisx0208_uni69[]={ +static const uint16 tab_jisx0208_uni69[]={ 0x8E47,0x8E49,0x8E4C,0x8E50,0x8E48,0x8E59,0x8E64,0x8E60, 0x8E2A,0x8E63,0x8E55,0x8E76,0x8E72,0x8E7C,0x8E81,0x8E87, 0x8E85,0x8E84,0x8E8B,0x8E8A,0x8E93,0x8E91,0x8E94,0x8E99, @@ -1300,7 +1300,7 @@ static uint16 tab_jisx0208_uni69[]={ 0x900B,0x9027,0x9036,0x9035,0x9039,0x8FF8}; /* page 70 0x6E21-0x6E7E */ -static uint16 tab_jisx0208_uni70[]={ +static const uint16 tab_jisx0208_uni70[]={ 0x904F,0x9050,0x9051,0x9052,0x900E,0x9049,0x903E,0x9056, 0x9058,0x905E,0x9068,0x906F,0x9076,0x96A8,0x9072,0x9082, 0x907D,0x9081,0x9080,0x908A,0x9089,0x908F,0x90A8,0x90AF, @@ -1315,7 +1315,7 @@ static uint16 tab_jisx0208_uni70[]={ 0x92B7,0x92E9,0x930F,0x92FA,0x9344,0x932E}; /* page 71 0x6F21-0x6F7E */ -static uint16 tab_jisx0208_uni71[]={ +static const uint16 tab_jisx0208_uni71[]={ 0x9319,0x9322,0x931A,0x9323,0x933A,0x9335,0x933B,0x935C, 0x9360,0x937C,0x936E,0x9356,0x93B0,0x93AC,0x93AD,0x9394, 0x93B9,0x93D6,0x93D7,0x93E8,0x93E5,0x93D8,0x93C3,0x93DD, @@ -1330,7 +1330,7 @@ static uint16 tab_jisx0208_uni71[]={ 0x964C,0x964F,0x964B,0x9677,0x965C,0x965E}; /* page 72 0x7021-0x707E */ -static uint16 tab_jisx0208_uni72[]={ +static const uint16 tab_jisx0208_uni72[]={ 0x965D,0x965F,0x9666,0x9672,0x966C,0x968D,0x9698,0x9695, 0x9697,0x96AA,0x96A7,0x96B1,0x96B2,0x96B0,0x96B4,0x96B6, 0x96B8,0x96B9,0x96CE,0x96CB,0x96C9,0x96CD,0x894D,0x96DC, @@ -1345,7 +1345,7 @@ static uint16 tab_jisx0208_uni72[]={ 0x9846,0x984F,0x984B,0x986B,0x986F,0x9870}; /* page 73 0x7121-0x717E */ -static uint16 tab_jisx0208_uni73[]={ +static const uint16 tab_jisx0208_uni73[]={ 0x9871,0x9874,0x9873,0x98AA,0x98AF,0x98B1,0x98B6,0x98C4, 0x98C3,0x98C6,0x98E9,0x98EB,0x9903,0x9909,0x9912,0x9914, 0x9918,0x9921,0x991D,0x991E,0x9924,0x9920,0x992C,0x992E, @@ -1360,7 +1360,7 @@ static uint16 tab_jisx0208_uni73[]={ 0x9AEF,0x9AEB,0x9AEE,0x9AF4,0x9AF1,0x9AF7}; /* page 74 0x7221-0x727E */ -static uint16 tab_jisx0208_uni74[]={ +static const uint16 tab_jisx0208_uni74[]={ 0x9AFB,0x9B06,0x9B18,0x9B1A,0x9B1F,0x9B22,0x9B23,0x9B25, 0x9B27,0x9B28,0x9B29,0x9B2A,0x9B2E,0x9B2F,0x9B32,0x9B44, 0x9B43,0x9B4F,0x9B4D,0x9B4E,0x9B51,0x9B58,0x9B74,0x9B93, @@ -1375,7 +1375,7 @@ static uint16 tab_jisx0208_uni74[]={ 0x9D12,0x9D41,0x9D3F,0x9D3E,0x9D46,0x9D48}; /* page 75 0x7321-0x737E */ -static uint16 tab_jisx0208_uni75[]={ +static const uint16 tab_jisx0208_uni75[]={ 0x9D5D,0x9D5E,0x9D64,0x9D51,0x9D50,0x9D59,0x9D72,0x9D89, 0x9D87,0x9DAB,0x9D6F,0x9D7A,0x9D9A,0x9DA4,0x9DA9,0x9DB2, 0x9DC4,0x9DC1,0x9DBB,0x9DB8,0x9DBA,0x9DC6,0x9DCF,0x9DC2, @@ -1390,7 +1390,7 @@ static uint16 tab_jisx0208_uni75[]={ 0x9F77,0x9F72,0x9F76,0x9F95,0x9F9C,0x9FA0}; /* page 76 0x7421-0x7426 */ -static uint16 tab_jisx0208_uni76[]={ +static const uint16 tab_jisx0208_uni76[]={ 0x582F,0x69C7,0x9059,0x7464,0x51DC,0x7199}; static int @@ -1554,25 +1554,25 @@ my_jisx0208_uni_onechar(int code){ /* page 0 0x005C-0x005C */ -static uint16 tab_uni_jisx02080[]={ +static const uint16 tab_uni_jisx02080[]={ 0x2140}; /* page 1 0x00A2-0x00B6 */ -static uint16 tab_uni_jisx02081[]={ +static const uint16 tab_uni_jisx02081[]={ 0x2171,0x2172, 0, 0, 0,0x2178,0x212F, 0, 0, 0,0x224C, 0, 0, 0,0x216B,0x215E, 0, 0,0x212D, 0,0x2279}; /* page 2 0x00D7-0x00D7 */ -static uint16 tab_uni_jisx02082[]={ +static const uint16 tab_uni_jisx02082[]={ 0x215F}; /* page 3 0x00F7-0x00F7 */ -static uint16 tab_uni_jisx02083[]={ +static const uint16 tab_uni_jisx02083[]={ 0x2160}; /* page 4 0x0391-0x03C9 */ -static uint16 tab_uni_jisx02084[]={ +static const uint16 tab_uni_jisx02084[]={ 0x2621,0x2622,0x2623,0x2624,0x2625,0x2626,0x2627,0x2628, 0x2629,0x262A,0x262B,0x262C,0x262D,0x262E,0x262F,0x2630, 0x2631, 0,0x2632,0x2633,0x2634,0x2635,0x2636,0x2637, @@ -1583,7 +1583,7 @@ static uint16 tab_uni_jisx02084[]={ 0x2658}; /* page 5 0x0401-0x0451 */ -static uint16 tab_uni_jisx02085[]={ +static const uint16 tab_uni_jisx02085[]={ 0x2727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2721, 0x2722,0x2723,0x2724,0x2725,0x2726,0x2728,0x2729,0x272A, @@ -1597,7 +1597,7 @@ static uint16 tab_uni_jisx02085[]={ 0x2757}; /* page 6 0x2010-0x203B */ -static uint16 tab_uni_jisx02086[]={ +static const uint16 tab_uni_jisx02086[]={ 0x213E, 0, 0, 0, 0,0x213D,0x2142, 0, 0x2146,0x2147, 0, 0,0x2148,0x2149, 0, 0, 0x2277,0x2278, 0, 0, 0,0x2145,0x2144, 0, @@ -1606,23 +1606,23 @@ static uint16 tab_uni_jisx02086[]={ 0, 0, 0,0x2228}; /* page 7 0x2103-0x2103 */ -static uint16 tab_uni_jisx02087[]={ +static const uint16 tab_uni_jisx02087[]={ 0x216E}; /* page 8 0x212B-0x212B */ -static uint16 tab_uni_jisx02088[]={ +static const uint16 tab_uni_jisx02088[]={ 0x2272}; /* page 9 0x2190-0x2193 */ -static uint16 tab_uni_jisx02089[]={ +static const uint16 tab_uni_jisx02089[]={ 0x222B,0x222C,0x222A,0x222D}; /* page 10 0x21D2-0x21D4 */ -static uint16 tab_uni_jisx020810[]={ +static const uint16 tab_uni_jisx020810[]={ 0x224D, 0,0x224E}; /* page 11 0x2200-0x223D */ -static uint16 tab_uni_jisx020811[]={ +static const uint16 tab_uni_jisx020811[]={ 0x224F, 0,0x225F,0x2250, 0, 0, 0,0x2260, 0x223A, 0, 0,0x223B, 0, 0, 0, 0, 0, 0,0x215D, 0, 0, 0, 0, 0, @@ -1633,26 +1633,26 @@ static uint16 tab_uni_jisx020811[]={ 0, 0, 0, 0, 0,0x2266}; /* page 12 0x2252-0x226B */ -static uint16 tab_uni_jisx020812[]={ +static const uint16 tab_uni_jisx020812[]={ 0x2262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2162,0x2261, 0, 0, 0, 0,0x2165,0x2166, 0, 0, 0x2263,0x2264}; /* page 13 0x2282-0x2287 */ -static uint16 tab_uni_jisx020813[]={ +static const uint16 tab_uni_jisx020813[]={ 0x223E,0x223F, 0, 0,0x223C,0x223D}; /* page 14 0x22A5-0x22A5 */ -static uint16 tab_uni_jisx020814[]={ +static const uint16 tab_uni_jisx020814[]={ 0x225D}; /* page 15 0x2312-0x2312 */ -static uint16 tab_uni_jisx020815[]={ +static const uint16 tab_uni_jisx020815[]={ 0x225E}; /* page 16 0x2500-0x254B */ -static uint16 tab_uni_jisx020816[]={ +static const uint16 tab_uni_jisx020816[]={ 0x2821,0x282C,0x2822,0x282D, 0, 0, 0, 0, 0, 0, 0, 0,0x2823, 0, 0,0x282E, 0x2824, 0, 0,0x282F,0x2826, 0, 0,0x2831, @@ -1665,7 +1665,7 @@ static uint16 tab_uni_jisx020816[]={ 0, 0, 0,0x2836}; /* page 17 0x25A0-0x25CF */ -static uint16 tab_uni_jisx020817[]={ +static const uint16 tab_uni_jisx020817[]={ 0x2223,0x2222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2225,0x2224, 0, 0, 0, 0, @@ -1675,30 +1675,30 @@ static uint16 tab_uni_jisx020817[]={ }; /* page 18 0x25EF-0x25EF */ -static uint16 tab_uni_jisx020818[]={ +static const uint16 tab_uni_jisx020818[]={ 0x227E}; /* page 19 0x2605-0x2606 */ -static uint16 tab_uni_jisx020819[]={ +static const uint16 tab_uni_jisx020819[]={ 0x217A,0x2179}; /* page 20 0x2640-0x2642 */ -static uint16 tab_uni_jisx020820[]={ +static const uint16 tab_uni_jisx020820[]={ 0x216A, 0,0x2169}; /* page 21 0x266A-0x266F */ -static uint16 tab_uni_jisx020821[]={ +static const uint16 tab_uni_jisx020821[]={ 0x2276, 0, 0,0x2275, 0,0x2274}; /* page 22 0x3000-0x301C */ -static uint16 tab_uni_jisx020822[]={ +static const uint16 tab_uni_jisx020822[]={ 0x2121,0x2122,0x2123,0x2137, 0,0x2139,0x213A,0x213B, 0x2152,0x2153,0x2154,0x2155,0x2156,0x2157,0x2158,0x2159, 0x215A,0x215B,0x2229,0x222E,0x214C,0x214D, 0, 0, 0, 0, 0, 0,0x2141}; /* page 23 0x3041-0x30FE */ -static uint16 tab_uni_jisx020823[]={ +static const uint16 tab_uni_jisx020823[]={ 0x2421,0x2422,0x2423,0x2424,0x2425,0x2426,0x2427,0x2428, 0x2429,0x242A,0x242B,0x242C,0x242D,0x242E,0x242F,0x2430, 0x2431,0x2432,0x2433,0x2434,0x2435,0x2436,0x2437,0x2438, @@ -1725,7 +1725,7 @@ static uint16 tab_uni_jisx020823[]={ 0, 0,0x2126,0x213C,0x2133,0x2134}; /* page 24 0x4E00-0x5516 */ -static uint16 tab_uni_jisx020824[]={ +static const uint16 tab_uni_jisx020824[]={ 0x306C,0x437A, 0,0x3C37, 0, 0, 0,0x4B7C, 0x3E66,0x3B30,0x3E65,0x323C, 0,0x4954,0x4D3F, 0, 0x5022,0x312F, 0, 0,0x336E,0x5023,0x4024,0x5242, @@ -1955,7 +1955,7 @@ static uint16 tab_uni_jisx020824[]={ 0x4562, 0, 0, 0,0x532A, 0,0x3022}; /* page 25 0x552E-0x5563 */ -static uint16 tab_uni_jisx020825[]={ +static const uint16 tab_uni_jisx020825[]={ 0x5334,0x4D23, 0,0x3E27, 0,0x533A, 0, 0, 0, 0,0x5339,0x5330, 0, 0, 0, 0, 0x4243, 0,0x5331, 0, 0, 0,0x426F,0x5336, @@ -1965,7 +1965,7 @@ static uint16 tab_uni_jisx020825[]={ 0, 0, 0, 0, 0,0x5332}; /* page 26 0x557B-0x576A */ -static uint16 tab_uni_jisx020826[]={ +static const uint16 tab_uni_jisx020826[]={ 0x5341,0x5346, 0,0x5342, 0,0x533D, 0, 0, 0x5347,0x4131, 0, 0,0x5349, 0,0x3922,0x533F, 0x437D, 0, 0, 0, 0, 0, 0, 0, @@ -2031,7 +2031,7 @@ static uint16 tab_uni_jisx020826[]={ }; /* page 27 0x577F-0x5A9B */ -static uint16 tab_uni_jisx020827[]={ +static const uint16 tab_uni_jisx020827[]={ 0x5434, 0, 0,0x3F62, 0, 0, 0, 0, 0,0x5432,0x5435, 0,0x373F, 0, 0, 0, 0, 0, 0, 0,0x5436, 0, 0, 0, @@ -2134,7 +2134,7 @@ static uint16 tab_uni_jisx020827[]={ 0, 0, 0,0x553B,0x4932}; /* page 28 0x5ABC-0x5D29 */ -static uint16 tab_uni_jisx020828[]={ +static const uint16 tab_uni_jisx020828[]={ 0x553C,0x5540,0x553D, 0, 0,0x3247,0x553F, 0, 0, 0, 0, 0, 0,0x3C3B, 0,0x553E, 0x3779, 0, 0, 0,0x554C, 0, 0, 0, @@ -2215,7 +2215,7 @@ static uint16 tab_uni_jisx020828[]={ 0, 0, 0, 0, 0,0x4A78}; /* page 29 0x5D4B-0x6BF3 */ -static uint16 tab_uni_jisx020829[]={ +static const uint16 tab_uni_jisx020829[]={ 0x564B,0x5648, 0,0x564A, 0,0x4D72, 0,0x5649, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x563F, 0, 0, 0, 0, 0, 0, @@ -2688,7 +2688,7 @@ static uint16 tab_uni_jisx020829[]={ 0x5D5E}; /* page 30 0x6C08-0x6CF3 */ -static uint16 tab_uni_jisx020830[]={ +static const uint16 tab_uni_jisx020830[]={ 0x5D61, 0, 0, 0, 0, 0, 0,0x3B61, 0,0x4C31, 0,0x5D62,0x5D63, 0, 0,0x3524, 0, 0, 0,0x5D64, 0, 0, 0, 0, @@ -2721,7 +2721,7 @@ static uint16 tab_uni_jisx020830[]={ 0x4259,0x5D76, 0,0x314B}; /* page 31 0x6D0B-0x7409 */ -static uint16 tab_uni_jisx020831[]={ +static const uint16 tab_uni_jisx020831[]={ 0x4D4E,0x5E30, 0, 0, 0, 0, 0,0x5E2F, 0, 0, 0, 0,0x4076, 0,0x5E2C, 0, 0x4D6C, 0, 0,0x4636,0x5E26, 0, 0, 0, @@ -2948,7 +2948,7 @@ static uint16 tab_uni_jisx020831[]={ 0x3565, 0,0x6066,0x4D7D, 0, 0,0x4E30}; /* page 32 0x7422-0x7845 */ -static uint16 tab_uni_jisx020832[]={ +static const uint16 tab_uni_jisx020832[]={ 0x4276, 0, 0,0x6068, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x606A,0x4E56,0x3657,0x487C,0x474A, 0, 0, 0, @@ -3084,7 +3084,7 @@ static uint16 tab_uni_jisx020832[]={ 0, 0, 0,0x626B}; /* page 33 0x785D-0x7E9C */ -static uint16 tab_uni_jisx020833[]={ +static const uint16 tab_uni_jisx020833[]={ 0x3E4B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x4E32,0x3945, 0, 0,0x3827, 0, 0,0x4823, 0,0x626D, @@ -3288,7 +3288,7 @@ static uint16 tab_uni_jisx020833[]={ }; /* page 34 0x7F36-0x8358 */ -static uint16 tab_uni_jisx020834[]={ +static const uint16 tab_uni_jisx020834[]={ 0x344C, 0,0x657D, 0,0x657E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x6621, 0, 0, 0, 0, 0, 0,0x6622,0x6623, @@ -3424,7 +3424,7 @@ static uint16 tab_uni_jisx020834[]={ 0, 0,0x4171}; /* page 35 0x8373-0x8B9A */ -static uint16 tab_uni_jisx020835[]={ +static const uint16 tab_uni_jisx020835[]={ 0x683A, 0,0x683B, 0,0x3259, 0, 0, 0, 0x322E,0x6838, 0, 0, 0, 0, 0, 0, 0, 0,0x682E, 0,0x6836, 0,0x683D,0x6837, @@ -3689,7 +3689,7 @@ static uint16 tab_uni_jisx020835[]={ }; /* page 36 0x8C37-0x8D16 */ -static uint16 tab_uni_jisx020836[]={ +static const uint16 tab_uni_jisx020836[]={ 0x432B, 0, 0,0x6C2E, 0, 0, 0, 0, 0x6C30, 0,0x6C2F, 0, 0, 0, 0,0x4626, 0,0x6C31, 0,0x4B2D, 0,0x6C32, 0,0x6C33, @@ -3721,7 +3721,7 @@ static uint16 tab_uni_jisx020836[]={ }; /* page 37 0x8D64-0x8F64 */ -static uint16 tab_uni_jisx020837[]={ +static const uint16 tab_uni_jisx020837[]={ 0x4056, 0,0x3C4F,0x6C5F, 0, 0, 0,0x3352, 0,0x6C60, 0, 0,0x4176,0x6C61, 0,0x6C62, 0x496B, 0, 0,0x352F, 0, 0, 0, 0, @@ -3789,7 +3789,7 @@ static uint16 tab_uni_jisx020837[]={ 0x6D62}; /* page 38 0x8F9B-0x9132 */ -static uint16 tab_uni_jisx020838[]={ +static const uint16 tab_uni_jisx020838[]={ 0x3F49,0x6D63, 0,0x3C2D,0x6D64, 0, 0, 0, 0x6D65, 0, 0, 0,0x5221,0x517E, 0, 0, 0, 0,0x6D66,0x6570,0x6D67,0x4324,0x3F2B,0x4740, @@ -3844,7 +3844,7 @@ static uint16 tab_uni_jisx020838[]={ }; /* page 39 0x9149-0x92B9 */ -static uint16 tab_uni_jisx020839[]={ +static const uint16 tab_uni_jisx020839[]={ 0x4653,0x6E44,0x3D36,0x3C60,0x475B,0x4371, 0, 0, 0,0x3C72, 0,0x3F6C, 0,0x6E45, 0,0x6E46, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3894,7 +3894,7 @@ static uint16 tab_uni_jisx020839[]={ 0x6E78}; /* page 40 0x92CF-0x93E8 */ -static uint16 tab_uni_jisx020840[]={ +static const uint16 tab_uni_jisx020840[]={ 0x6E77, 0, 0,0x4B2F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3D7B, 0, 0, @@ -3933,7 +3933,7 @@ static uint16 tab_uni_jisx020840[]={ 0,0x6F34}; /* page 41 0x9403-0x9481 */ -static uint16 tab_uni_jisx020841[]={ +static const uint16 tab_uni_jisx020841[]={ 0x6F3F, 0, 0, 0,0x6F40, 0, 0, 0, 0, 0, 0, 0, 0,0x6F41, 0, 0, 0x6F3E,0x6F3D, 0, 0, 0,0x3E62,0x462A,0x6F3C, @@ -3952,7 +3952,7 @@ static uint16 tab_uni_jisx020841[]={ 0,0x6F55,0x6F53,0x6F56,0x6F58, 0,0x6F57}; /* page 42 0x9577-0x95E5 */ -static uint16 tab_uni_jisx020842[]={ +static const uint16 tab_uni_jisx020842[]={ 0x4439, 0, 0, 0, 0, 0, 0, 0, 0,0x4C67, 0,0x6F59,0x412E, 0, 0, 0, 0x6F5A, 0,0x4A44,0x6F5B,0x332B, 0, 0, 0, @@ -3969,7 +3969,7 @@ static uint16 tab_uni_jisx020842[]={ 0, 0,0x6F71,0x6F73, 0, 0,0x6F72}; /* page 43 0x961C-0x9874 */ -static uint16 tab_uni_jisx020843[]={ +static const uint16 tab_uni_jisx020843[]={ 0x496C, 0, 0, 0, 0,0x6F74, 0, 0, 0, 0, 0, 0,0x6F75, 0,0x3A65, 0, 0, 0,0x6F76,0x6F77, 0, 0,0x4B49, 0, @@ -4048,14 +4048,14 @@ static uint16 tab_uni_jisx020843[]={ 0x7122}; /* page 44 0x98A8-0x98C6 */ -static uint16 tab_uni_jisx020844[]={ +static const uint16 tab_uni_jisx020844[]={ 0x4977, 0,0x7124, 0, 0, 0, 0,0x7125, 0,0x7126, 0, 0, 0, 0,0x7127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x7129,0x7128, 0,0x712A}; /* page 45 0x98DB-0x9957 */ -static uint16 tab_uni_jisx020845[]={ +static const uint16 tab_uni_jisx020845[]={ 0x4874,0x664C, 0, 0,0x3F29, 0, 0,0x3532, 0, 0, 0, 0, 0, 0,0x712B, 0, 0x712C, 0,0x522C,0x5D3B,0x4853, 0, 0,0x307B, @@ -4074,7 +4074,7 @@ static uint16 tab_uni_jisx020845[]={ 0, 0,0x7143, 0,0x3642}; /* page 46 0x9996-0x9A6B */ -static uint16 tab_uni_jisx020846[]={ +static const uint16 tab_uni_jisx020846[]={ 0x3C73,0x7144,0x7145,0x3961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x7146, 0, 0,0x333E, 0, 0, 0,0x474F,0x7147, @@ -4104,7 +4104,7 @@ static uint16 tab_uni_jisx020846[]={ 0, 0, 0,0x7169,0x716B,0x716A}; /* page 47 0x9AA8-0x9B5A */ -static uint16 tab_uni_jisx020847[]={ +static const uint16 tab_uni_jisx020847[]={ 0x397C, 0, 0, 0, 0,0x716C, 0, 0, 0x716D, 0, 0, 0, 0, 0, 0, 0, 0x333C, 0, 0, 0,0x716E, 0, 0, 0, @@ -4130,7 +4130,7 @@ static uint16 tab_uni_jisx020847[]={ 0x7236, 0,0x357B}; /* page 48 0x9B6F-0x9C78 */ -static uint16 tab_uni_jisx020848[]={ +static const uint16 tab_uni_jisx020848[]={ 0x4F25, 0, 0, 0, 0,0x7237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x7239, 0, 0, 0, @@ -4167,7 +4167,7 @@ static uint16 tab_uni_jisx020848[]={ 0,0x7269}; /* page 49 0x9CE5-0x9DFD */ -static uint16 tab_uni_jisx020849[]={ +static const uint16 tab_uni_jisx020849[]={ 0x443B, 0,0x726A, 0,0x4837, 0,0x726F,0x726B, 0, 0, 0,0x726C, 0, 0,0x4B31,0x4C44, 0,0x4650, 0, 0, 0, 0, 0, 0, @@ -4206,11 +4206,11 @@ static uint16 tab_uni_jisx020849[]={ 0x733F}; /* page 50 0x9E1A-0x9E1E */ -static uint16 tab_uni_jisx020850[]={ +static const uint16 tab_uni_jisx020850[]={ 0x7340,0x7341, 0, 0,0x7342}; /* page 51 0x9E75-0x9F77 */ -static uint16 tab_uni_jisx020851[]={ +static const uint16 tab_uni_jisx020851[]={ 0x7343, 0, 0,0x3834,0x7344, 0, 0, 0, 0x7345, 0,0x3C2F, 0,0x7346, 0, 0, 0, 0, 0, 0,0x7347, 0, 0,0x7348,0x7349, @@ -4246,13 +4246,13 @@ static uint16 tab_uni_jisx020851[]={ 0,0x737B,0x7379}; /* page 52 0x9F8D-0x9FA0 */ -static uint16 tab_uni_jisx020852[]={ +static const uint16 tab_uni_jisx020852[]={ 0x4E36, 0, 0, 0, 0, 0, 0, 0, 0x737C, 0, 0, 0, 0, 0, 0,0x737D, 0x6354, 0, 0,0x737E}; /* page 53 0xFF01-0xFF5D */ -static uint16 tab_uni_jisx020853[]={ +static const uint16 tab_uni_jisx020853[]={ 0x212A, 0,0x2174,0x2170,0x2173,0x2175, 0,0x214A, 0x214B,0x2176,0x215C,0x2124, 0,0x2125,0x213F,0x2330, 0x2331,0x2332,0x2333,0x2334,0x2335,0x2336,0x2337,0x2338, @@ -4267,7 +4267,7 @@ static uint16 tab_uni_jisx020853[]={ 0x2379,0x237A,0x2150,0x2143,0x2151}; /* page 54 0xFFE3-0xFFE5 */ -static uint16 tab_uni_jisx020854[]={ +static const uint16 tab_uni_jisx020854[]={ 0x2131, 0,0x216F}; static int @@ -4388,11 +4388,11 @@ my_uni_jisx0208_onechar(int code){ /* page 0 0x007E-0x007E */ -static uint16 tab_uni_jisx02120[]={ +static const uint16 tab_uni_jisx02120[]={ 0x2237}; /* page 1 0x00A1-0x017E */ -static uint16 tab_uni_jisx02121[]={ +static const uint16 tab_uni_jisx02121[]={ 0x2242, 0, 0,0x2270, 0,0x2243, 0, 0, 0x226D,0x226C, 0, 0, 0,0x226E,0x2234, 0, 0, 0, 0, 0, 0, 0, 0,0x2231, @@ -4423,28 +4423,28 @@ static uint16 tab_uni_jisx02121[]={ 0x2A75,0x2B75,0x2A77,0x2B77,0x2A76,0x2B76}; /* page 2 0x01CD-0x01DC */ -static uint16 tab_uni_jisx02122[]={ +static const uint16 tab_uni_jisx02122[]={ 0x2A26,0x2B26,0x2A43,0x2B43,0x2A55,0x2B55,0x2A67,0x2B67, 0x2A70,0x2B70,0x2A6D,0x2B6D,0x2A6F,0x2B6F,0x2A6E,0x2B6E }; /* page 3 0x01F5-0x01F5 */ -static uint16 tab_uni_jisx02123[]={ +static const uint16 tab_uni_jisx02123[]={ 0x2B39}; /* page 4 0x02C7-0x02DD */ -static uint16 tab_uni_jisx02124[]={ +static const uint16 tab_uni_jisx02124[]={ 0x2230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x222F,0x2232,0x2236,0x2235, 0,0x2233}; /* page 5 0x0384-0x0390 */ -static uint16 tab_uni_jisx02125[]={ +static const uint16 tab_uni_jisx02125[]={ 0x2238,0x2239,0x2661, 0,0x2662,0x2663,0x2664, 0, 0x2667, 0,0x2669,0x266C,0x2676}; /* page 6 0x03AA-0x03CE */ -static uint16 tab_uni_jisx02126[]={ +static const uint16 tab_uni_jisx02126[]={ 0x2665,0x266A,0x2671,0x2672,0x2673,0x2674,0x267B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4452,22 +4452,22 @@ static uint16 tab_uni_jisx02126[]={ 0x2675,0x267A,0x2677,0x2679,0x267C}; /* page 7 0x0402-0x040F */ -static uint16 tab_uni_jisx02127[]={ +static const uint16 tab_uni_jisx02127[]={ 0x2742,0x2743,0x2744,0x2745,0x2746,0x2747,0x2748,0x2749, 0x274A,0x274B,0x274C, 0,0x274D,0x274E}; /* page 8 0x0452-0x045F */ -static uint16 tab_uni_jisx02128[]={ +static const uint16 tab_uni_jisx02128[]={ 0x2772,0x2773,0x2774,0x2775,0x2776,0x2777,0x2778,0x2779, 0x277A,0x277B,0x277C, 0,0x277D,0x277E}; /* page 9 0x2116-0x2122 */ -static uint16 tab_uni_jisx02129[]={ +static const uint16 tab_uni_jisx02129[]={ 0x2271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x226F}; /* page 10 0x4E02-0x4F19 */ -static uint16 tab_uni_jisx021210[]={ +static const uint16 tab_uni_jisx021210[]={ 0x3021, 0,0x3022,0x3023, 0, 0, 0, 0, 0, 0,0x3024, 0, 0, 0, 0, 0, 0x3025, 0, 0, 0, 0, 0, 0, 0, @@ -4506,7 +4506,7 @@ static uint16 tab_uni_jisx021210[]={ }; /* page 11 0x4F2E-0x5166 */ -static uint16 tab_uni_jisx021211[]={ +static const uint16 tab_uni_jisx021211[]={ 0x305D, 0, 0,0x305E, 0,0x3060, 0,0x3061, 0,0x3062, 0,0x3063, 0,0x3064, 0, 0, 0x3065, 0,0x3066, 0,0x3067, 0, 0, 0, @@ -4581,7 +4581,7 @@ static uint16 tab_uni_jisx021211[]={ 0x326E}; /* page 12 0x517E-0x5515 */ -static uint16 tab_uni_jisx021212[]={ +static const uint16 tab_uni_jisx021212[]={ 0x326F, 0, 0, 0, 0,0x3270,0x3271, 0, 0, 0, 0, 0, 0,0x3272, 0, 0, 0x3273, 0, 0, 0, 0, 0, 0, 0, @@ -4700,7 +4700,7 @@ static uint16 tab_uni_jisx021212[]={ }; /* page 13 0x552A-0x5566 */ -static uint16 tab_uni_jisx021213[]={ +static const uint16 tab_uni_jisx021213[]={ 0x354E,0x354F, 0, 0, 0, 0, 0, 0, 0x3550, 0, 0,0x3551,0x3552, 0, 0, 0, 0,0x3553,0x3554,0x3555, 0, 0, 0,0x3556, @@ -4711,7 +4711,7 @@ static uint16 tab_uni_jisx021213[]={ 0, 0,0x3563, 0,0x3564}; /* page 14 0x557F-0x5C36 */ -static uint16 tab_uni_jisx021214[]={ +static const uint16 tab_uni_jisx021214[]={ 0x3565, 0,0x3566,0x3567, 0, 0, 0,0x3568, 0,0x3569, 0, 0, 0, 0, 0,0x356A, 0x356B, 0,0x356C,0x356D,0x356E,0x356F, 0, 0, @@ -4930,7 +4930,7 @@ static uint16 tab_uni_jisx021214[]={ }; /* page 15 0x5C59-0x5EEB */ -static uint16 tab_uni_jisx021215[]={ +static const uint16 tab_uni_jisx021215[]={ 0x3A77,0x3A78, 0,0x3A79, 0, 0, 0, 0, 0,0x3A7A,0x3A7B, 0, 0, 0,0x3A7C,0x3A7D, 0x3A7E, 0, 0, 0,0x3B21, 0, 0,0x3B22, @@ -5016,7 +5016,7 @@ static uint16 tab_uni_jisx021215[]={ 0, 0,0x3C5B}; /* page 16 0x5F02-0x6149 */ -static uint16 tab_uni_jisx021216[]={ +static const uint16 tab_uni_jisx021216[]={ 0x3C5C, 0, 0, 0,0x3C5D,0x3C5E,0x3C5F, 0, 0, 0, 0, 0,0x3C60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3C61, @@ -5093,7 +5093,7 @@ static uint16 tab_uni_jisx021216[]={ }; /* page 17 0x615E-0x6290 */ -static uint16 tab_uni_jisx021217[]={ +static const uint16 tab_uni_jisx021217[]={ 0x3E53, 0,0x3E54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3E55, 0, 0, 0, 0, 0,0x3E56, 0, 0, 0, @@ -5135,7 +5135,7 @@ static uint16 tab_uni_jisx021217[]={ 0x3F46,0x3F47,0x3F48}; /* page 18 0x62A6-0x679B */ -static uint16 tab_uni_jisx021218[]={ +static const uint16 tab_uni_jisx021218[]={ 0x3F49, 0,0x3F4A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3F4B, 0, 0, 0x3F4C,0x3F4D, 0, 0,0x3F4E, 0, 0, 0, @@ -5297,7 +5297,7 @@ static uint16 tab_uni_jisx021218[]={ 0x432D, 0,0x432E,0x432F, 0,0x4330}; /* page 19 0x67B0-0x67F9 */ -static uint16 tab_uni_jisx021219[]={ +static const uint16 tab_uni_jisx021219[]={ 0x4331,0x4332,0x4333, 0, 0,0x4334, 0, 0, 0, 0, 0,0x4335,0x4336,0x4337, 0, 0, 0x4339, 0,0x433A,0x433B, 0,0x433C, 0, 0, @@ -5310,7 +5310,7 @@ static uint16 tab_uni_jisx021219[]={ 0,0x4338}; /* page 20 0x6814-0x6917 */ -static uint16 tab_uni_jisx021220[]={ +static const uint16 tab_uni_jisx021220[]={ 0x434A, 0, 0, 0, 0,0x434B, 0, 0, 0,0x434C, 0,0x434D, 0, 0, 0, 0, 0, 0, 0,0x434F,0x434E, 0, 0, 0, @@ -5346,7 +5346,7 @@ static uint16 tab_uni_jisx021220[]={ 0, 0,0x443B,0x443C}; /* page 21 0x6931-0x6D3F */ -static uint16 tab_uni_jisx021221[]={ +static const uint16 tab_uni_jisx021221[]={ 0x443D, 0,0x443E, 0,0x443F, 0, 0,0x4440, 0, 0,0x4441, 0, 0, 0, 0, 0, 0,0x4442, 0, 0,0x4443, 0, 0, 0, @@ -5479,7 +5479,7 @@ static uint16 tab_uni_jisx021221[]={ 0x473A, 0, 0,0x473B, 0, 0,0x473C}; /* page 22 0x6D57-0x6E04 */ -static uint16 tab_uni_jisx021222[]={ +static const uint16 tab_uni_jisx021222[]={ 0x473D, 0, 0, 0, 0, 0, 0,0x473E, 0x473F, 0,0x4740, 0, 0, 0,0x4741, 0, 0x4742, 0, 0, 0, 0, 0, 0, 0, @@ -5504,7 +5504,7 @@ static uint16 tab_uni_jisx021222[]={ 0,0x4767, 0, 0, 0,0x4768}; /* page 23 0x6E1E-0x6ECF */ -static uint16 tab_uni_jisx021223[]={ +static const uint16 tab_uni_jisx021223[]={ 0x4769, 0, 0, 0,0x476A, 0, 0, 0, 0,0x476B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x476C, 0, 0, 0, @@ -5530,7 +5530,7 @@ static uint16 tab_uni_jisx021223[]={ 0x4839,0x483A}; /* page 24 0x6EEB-0x70E4 */ -static uint16 tab_uni_jisx021224[]={ +static const uint16 tab_uni_jisx021224[]={ 0x483B, 0,0x483C,0x483D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x483E, 0, 0x483F, 0,0x4840, 0, 0, 0, 0, 0, @@ -5597,7 +5597,7 @@ static uint16 tab_uni_jisx021224[]={ 0,0x4960}; /* page 25 0x70FA-0x71DC */ -static uint16 tab_uni_jisx021225[]={ +static const uint16 tab_uni_jisx021225[]={ 0x4961, 0, 0, 0, 0, 0, 0, 0, 0,0x4962,0x4963,0x4964,0x4965,0x4966, 0, 0, 0,0x4967,0x4968, 0, 0,0x4969, 0, 0, @@ -5629,7 +5629,7 @@ static uint16 tab_uni_jisx021225[]={ 0x4A3A, 0,0x4A3B}; /* page 26 0x71F8-0x7E9E */ -static uint16 tab_uni_jisx021226[]={ +static const uint16 tab_uni_jisx021226[]={ 0x4A3C, 0, 0, 0, 0, 0,0x4A3D, 0, 0x4A3E, 0, 0, 0, 0, 0, 0,0x4A3F, 0x4A40,0x4A41, 0, 0, 0, 0, 0, 0, @@ -6037,7 +6037,7 @@ static uint16 tab_uni_jisx021226[]={ 0x5467, 0,0x5468, 0, 0,0x5469,0x546A}; /* page 27 0x7F3B-0x8044 */ -static uint16 tab_uni_jisx021227[]={ +static const uint16 tab_uni_jisx021227[]={ 0x546C,0x546B,0x546D,0x546E,0x546F, 0, 0, 0, 0x5470,0x5471, 0, 0,0x5472, 0, 0, 0, 0, 0, 0, 0,0x5473, 0, 0,0x5474, @@ -6074,7 +6074,7 @@ static uint16 tab_uni_jisx021227[]={ 0,0x5563}; /* page 28 0x8060-0x8357 */ -static uint16 tab_uni_jisx021228[]={ +static const uint16 tab_uni_jisx021228[]={ 0x5564, 0, 0, 0,0x5565, 0,0x5566, 0, 0, 0, 0, 0, 0,0x5567, 0, 0, 0,0x5568, 0, 0, 0,0x5569, 0, 0, @@ -6173,7 +6173,7 @@ static uint16 tab_uni_jisx021228[]={ }; /* page 29 0x8370-0x8419 */ -static uint16 tab_uni_jisx021229[]={ +static const uint16 tab_uni_jisx021229[]={ 0x577D, 0, 0, 0, 0, 0, 0, 0, 0x577E, 0, 0, 0, 0,0x5821, 0,0x5822, 0x5823, 0,0x5824, 0,0x5825, 0,0x5826, 0, @@ -6198,7 +6198,7 @@ static uint16 tab_uni_jisx021229[]={ 0,0x584B}; /* page 30 0x842F-0x8880 */ -static uint16 tab_uni_jisx021230[]={ +static const uint16 tab_uni_jisx021230[]={ 0x584D, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x584E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x584F, 0, @@ -6340,7 +6340,7 @@ static uint16 tab_uni_jisx021230[]={ 0,0x5C38}; /* page 31 0x8898-0x89BC */ -static uint16 tab_uni_jisx021231[]={ +static const uint16 tab_uni_jisx021231[]={ 0x5C39, 0,0x5C3A,0x5C3B,0x5C3C, 0, 0,0x5C3D, 0x5C3E, 0, 0, 0, 0, 0, 0, 0, 0x5C3F, 0,0x5C40, 0, 0, 0, 0, 0, @@ -6380,7 +6380,7 @@ static uint16 tab_uni_jisx021231[]={ 0, 0, 0, 0,0x5D33}; /* page 32 0x89D4-0x8B9F */ -static uint16 tab_uni_jisx021232[]={ +static const uint16 tab_uni_jisx021232[]={ 0x5D34,0x5D35,0x5D36,0x5D37,0x5D38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x5D39, 0, 0, 0,0x5D3A, 0,0x5D3B, @@ -6441,7 +6441,7 @@ static uint16 tab_uni_jisx021232[]={ 0x5E5F, 0,0x5E60,0x5E61}; /* page 33 0x8C38-0x8CA4 */ -static uint16 tab_uni_jisx021233[]={ +static const uint16 tab_uni_jisx021233[]={ 0x5E62,0x5E63, 0, 0, 0,0x5E64,0x5E65, 0, 0, 0, 0, 0, 0,0x5E66, 0,0x5E67, 0,0x5E68, 0,0x5E69, 0, 0, 0,0x5E6A, @@ -6458,7 +6458,7 @@ static uint16 tab_uni_jisx021233[]={ 0, 0, 0, 0,0x5F29}; /* page 34 0x8CB9-0x8D1B */ -static uint16 tab_uni_jisx021234[]={ +static const uint16 tab_uni_jisx021234[]={ 0x5F2A,0x5F2B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x5F2C,0x5F2D, 0, 0, 0x5F2E, 0,0x5F2F, 0, 0, 0,0x5F30, 0, @@ -6474,7 +6474,7 @@ static uint16 tab_uni_jisx021234[]={ 0, 0,0x5F45}; /* page 35 0x8D65-0x8F65 */ -static uint16 tab_uni_jisx021235[]={ +static const uint16 tab_uni_jisx021235[]={ 0x5F46, 0, 0, 0,0x5F47, 0, 0,0x5F48, 0,0x5F49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6542,7 +6542,7 @@ static uint16 tab_uni_jisx021235[]={ 0x612C}; /* page 36 0x8F9D-0x9484 */ -static uint16 tab_uni_jisx021236[]={ +static const uint16 tab_uni_jisx021236[]={ 0x612D, 0, 0,0x612E,0x612F, 0, 0,0x6130, 0x6131,0x6132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6703,7 +6703,7 @@ static uint16 tab_uni_jisx021236[]={ }; /* page 37 0x9578-0x95E6 */ -static uint16 tab_uni_jisx021237[]={ +static const uint16 tab_uni_jisx021237[]={ 0x657D,0x657E, 0, 0, 0, 0,0x6621, 0, 0, 0, 0, 0,0x6622, 0, 0, 0, 0x6623, 0, 0, 0,0x6624,0x6625,0x6626, 0, @@ -6720,7 +6720,7 @@ static uint16 tab_uni_jisx021237[]={ 0x6641, 0, 0, 0,0x6642, 0,0x6643}; /* page 38 0x961D-0x986C */ -static uint16 tab_uni_jisx021238[]={ +static const uint16 tab_uni_jisx021238[]={ 0x6644,0x6645, 0, 0, 0,0x6646, 0,0x6647, 0x6648,0x6649, 0, 0, 0, 0, 0,0x664A, 0, 0, 0, 0,0x664B, 0,0x664C, 0, @@ -6798,7 +6798,7 @@ static uint16 tab_uni_jisx021238[]={ }; /* page 39 0x98AB-0x98CC */ -static uint16 tab_uni_jisx021239[]={ +static const uint16 tab_uni_jisx021239[]={ 0x683A, 0,0x683B,0x683C, 0,0x683D, 0, 0, 0,0x683E, 0, 0,0x683F,0x6840, 0,0x6841, 0x6842, 0, 0, 0,0x6843, 0, 0,0x6844, @@ -6806,7 +6806,7 @@ static uint16 tab_uni_jisx021239[]={ 0,0x6847}; /* page 40 0x98E1-0x9960 */ -static uint16 tab_uni_jisx021240[]={ +static const uint16 tab_uni_jisx021240[]={ 0x6848, 0,0x6849, 0,0x684A,0x684B,0x684C, 0, 0,0x684D, 0, 0, 0, 0, 0, 0, 0, 0,0x684E, 0, 0,0x684F, 0, 0, @@ -6826,7 +6826,7 @@ static uint16 tab_uni_jisx021240[]={ }; /* page 41 0x999B-0x9A5D */ -static uint16 tab_uni_jisx021241[]={ +static const uint16 tab_uni_jisx021241[]={ 0x6877, 0,0x6878, 0,0x6879, 0, 0, 0, 0, 0, 0,0x687A, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x687B,0x687C,0x687D, @@ -6854,7 +6854,7 @@ static uint16 tab_uni_jisx021241[]={ 0, 0,0x6955}; /* page 42 0x9AAA-0x9C7B */ -static uint16 tab_uni_jisx021242[]={ +static const uint16 tab_uni_jisx021242[]={ 0x6956, 0,0x6957, 0,0x6958,0x6959, 0, 0, 0x695A, 0,0x695B,0x695C,0x695D, 0, 0,0x695E, 0,0x695F, 0, 0,0x6960,0x6961, 0,0x6962, @@ -6916,7 +6916,7 @@ static uint16 tab_uni_jisx021242[]={ 0,0x6B58}; /* page 43 0x9CE6-0x9E1D */ -static uint16 tab_uni_jisx021243[]={ +static const uint16 tab_uni_jisx021243[]={ 0x6B59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x6B5A, 0, 0, 0, 0,0x6B5B, 0,0x6B5C, 0, 0, 0, 0, @@ -6959,7 +6959,7 @@ static uint16 tab_uni_jisx021243[]={ }; /* page 44 0x9E7A-0x9FA5 */ -static uint16 tab_uni_jisx021244[]={ +static const uint16 tab_uni_jisx021244[]={ 0x6C59,0x6C5A,0x6C5B, 0, 0, 0,0x6C5C, 0, 0x6C5D,0x6C5E,0x6C5F,0x6C60, 0,0x6C61, 0, 0, 0, 0, 0, 0,0x6C62,0x6C63, 0, 0, @@ -7096,34 +7096,34 @@ my_uni_jisx0212_onechar(int code){ /* page 0 0x222F-0x2244 */ -static uint16 tab_jisx0212_uni0[]={ +static const uint16 tab_jisx0212_uni0[]={ 0x02D8,0x02C7,0x00B8,0x02D9,0x02DD,0x00AF,0x02DB,0x02DA, 0x007E,0x0384,0x0385, 0, 0, 0, 0, 0, 0, 0, 0,0x00A1,0x00A6,0x00BF}; /* page 1 0x226B-0x2271 */ -static uint16 tab_jisx0212_uni1[]={ +static const uint16 tab_jisx0212_uni1[]={ 0x00BA,0x00AA,0x00A9,0x00AE,0x2122,0x00A4,0x2116}; /* page 2 0x2661-0x267C */ -static uint16 tab_jisx0212_uni2[]={ +static const uint16 tab_jisx0212_uni2[]={ 0x0386,0x0388,0x0389,0x038A,0x03AA, 0,0x038C, 0, 0x038E,0x03AB, 0,0x038F, 0, 0, 0, 0, 0x03AC,0x03AD,0x03AE,0x03AF,0x03CA,0x0390,0x03CC,0x03C2, 0x03CD,0x03CB,0x03B0,0x03CE}; /* page 3 0x2742-0x274E */ -static uint16 tab_jisx0212_uni3[]={ +static const uint16 tab_jisx0212_uni3[]={ 0x0402,0x0403,0x0404,0x0405,0x0406,0x0407,0x0408,0x0409, 0x040A,0x040B,0x040C,0x040E,0x040F}; /* page 4 0x2772-0x277E */ -static uint16 tab_jisx0212_uni4[]={ +static const uint16 tab_jisx0212_uni4[]={ 0x0452,0x0453,0x0454,0x0455,0x0456,0x0457,0x0458,0x0459, 0x045A,0x045B,0x045C,0x045E,0x045F}; /* page 5 0x2921-0x2950 */ -static uint16 tab_jisx0212_uni5[]={ +static const uint16 tab_jisx0212_uni5[]={ 0x00C6,0x0110, 0,0x0126, 0,0x0132, 0,0x0141, 0x013F, 0,0x014A,0x00D8,0x0152, 0,0x0166,0x00DE, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7133,7 +7133,7 @@ static uint16 tab_jisx0212_uni5[]={ }; /* page 6 0x2A21-0x2A77 */ -static uint16 tab_jisx0212_uni6[]={ +static const uint16 tab_jisx0212_uni6[]={ 0x00C1,0x00C0,0x00C4,0x00C2,0x0102,0x01CD,0x0100,0x0104, 0x00C5,0x00C3,0x0106,0x0108,0x010C,0x00C7,0x010A,0x010E, 0x00C9,0x00C8,0x00CB,0x00CA,0x011A,0x0116,0x0112,0x0118, @@ -7147,7 +7147,7 @@ static uint16 tab_jisx0212_uni6[]={ 0x0174,0x00DD,0x0178,0x0176,0x0179,0x017D,0x017B}; /* page 7 0x2B21-0x2B77 */ -static uint16 tab_jisx0212_uni7[]={ +static const uint16 tab_jisx0212_uni7[]={ 0x00E1,0x00E0,0x00E4,0x00E2,0x0103,0x01CE,0x0101,0x0105, 0x00E5,0x00E3,0x0107,0x0109,0x010D,0x00E7,0x010B,0x010F, 0x00E9,0x00E8,0x00EB,0x00EA,0x011B,0x0117,0x0113,0x0119, @@ -7161,7 +7161,7 @@ static uint16 tab_jisx0212_uni7[]={ 0x0175,0x00FD,0x00FF,0x0177,0x017A,0x017E,0x017C}; /* page 8 0x3021-0x307E */ -static uint16 tab_jisx0212_uni8[]={ +static const uint16 tab_jisx0212_uni8[]={ 0x4E02,0x4E04,0x4E05,0x4E0C,0x4E12,0x4E1F,0x4E23,0x4E24, 0x4E28,0x4E2B,0x4E2E,0x4E2F,0x4E30,0x4E35,0x4E40,0x4E41, 0x4E44,0x4E47,0x4E51,0x4E5A,0x4E5C,0x4E63,0x4E68,0x4E69, @@ -7176,7 +7176,7 @@ static uint16 tab_jisx0212_uni8[]={ 0x4F7A,0x4F7D,0x4F7E,0x4F81,0x4F82,0x4F84}; /* page 9 0x3121-0x317E */ -static uint16 tab_jisx0212_uni9[]={ +static const uint16 tab_jisx0212_uni9[]={ 0x4F85,0x4F89,0x4F8A,0x4F8C,0x4F8E,0x4F90,0x4F92,0x4F93, 0x4F94,0x4F97,0x4F99,0x4F9A,0x4F9E,0x4F9F,0x4FB2,0x4FB7, 0x4FB9,0x4FBB,0x4FBC,0x4FBD,0x4FBE,0x4FC0,0x4FC1,0x4FC5, @@ -7191,7 +7191,7 @@ static uint16 tab_jisx0212_uni9[]={ 0x5084,0x5086,0x508A,0x508E,0x508F,0x5090}; /* page 10 0x3221-0x327E */ -static uint16 tab_jisx0212_uni10[]={ +static const uint16 tab_jisx0212_uni10[]={ 0x5092,0x5093,0x5094,0x5096,0x509B,0x509C,0x509E,0x509F, 0x50A0,0x50A1,0x50A2,0x50AA,0x50AF,0x50B0,0x50B9,0x50BA, 0x50BD,0x50C0,0x50C3,0x50C4,0x50C7,0x50CC,0x50CE,0x50D0, @@ -7206,7 +7206,7 @@ static uint16 tab_jisx0212_uni10[]={ 0x51B8,0x51BA,0x51BC,0x51BE,0x51BF,0x51C2}; /* page 11 0x3321-0x337E */ -static uint16 tab_jisx0212_uni11[]={ +static const uint16 tab_jisx0212_uni11[]={ 0x51C8,0x51CF,0x51D1,0x51D2,0x51D3,0x51D5,0x51D8,0x51DE, 0x51E2,0x51E5,0x51EE,0x51F2,0x51F3,0x51F4,0x51F7,0x5201, 0x5202,0x5205,0x5212,0x5213,0x5215,0x5216,0x5218,0x5222, @@ -7221,7 +7221,7 @@ static uint16 tab_jisx0212_uni11[]={ 0x52F6,0x52F7,0x5300,0x5303,0x530A,0x530B}; /* page 12 0x3421-0x347E */ -static uint16 tab_jisx0212_uni12[]={ +static const uint16 tab_jisx0212_uni12[]={ 0x530C,0x5311,0x5313,0x5318,0x531B,0x531C,0x531E,0x531F, 0x5325,0x5327,0x5328,0x5329,0x532B,0x532C,0x532D,0x5330, 0x5332,0x5335,0x533C,0x533D,0x533E,0x5342,0x534C,0x534B, @@ -7236,7 +7236,7 @@ static uint16 tab_jisx0212_uni12[]={ 0x5469,0x546B,0x546D,0x546E,0x5474,0x547F}; /* page 13 0x3521-0x357E */ -static uint16 tab_jisx0212_uni13[]={ +static const uint16 tab_jisx0212_uni13[]={ 0x5481,0x5483,0x5485,0x5488,0x5489,0x548D,0x5491,0x5495, 0x5496,0x549C,0x549F,0x54A1,0x54A6,0x54A7,0x54A9,0x54AA, 0x54AD,0x54AE,0x54B1,0x54B7,0x54B9,0x54BA,0x54BB,0x54BF, @@ -7251,7 +7251,7 @@ static uint16 tab_jisx0212_uni13[]={ 0x55C9,0x55CB,0x55CC,0x55CE,0x55D1,0x55D2}; /* page 14 0x3621-0x367E */ -static uint16 tab_jisx0212_uni14[]={ +static const uint16 tab_jisx0212_uni14[]={ 0x55D3,0x55D7,0x55D8,0x55DB,0x55DE,0x55E2,0x55E9,0x55F6, 0x55FF,0x5605,0x5608,0x560A,0x560D,0x560E,0x560F,0x5610, 0x5611,0x5612,0x5619,0x562C,0x5630,0x5633,0x5635,0x5637, @@ -7266,7 +7266,7 @@ static uint16 tab_jisx0212_uni14[]={ 0x56E6,0x56E7,0x56E8,0x56F1,0x56EB,0x56ED}; /* page 15 0x3721-0x377E */ -static uint16 tab_jisx0212_uni15[]={ +static const uint16 tab_jisx0212_uni15[]={ 0x56F6,0x56F7,0x5701,0x5702,0x5707,0x570A,0x570C,0x5711, 0x5715,0x571A,0x571B,0x571D,0x5720,0x5722,0x5723,0x5724, 0x5725,0x5729,0x572A,0x572C,0x572E,0x572F,0x5733,0x5734, @@ -7281,7 +7281,7 @@ static uint16 tab_jisx0212_uni15[]={ 0x57FF,0x5803,0x5804,0x5808,0x5809,0x57E1}; /* page 16 0x3821-0x387E */ -static uint16 tab_jisx0212_uni16[]={ +static const uint16 tab_jisx0212_uni16[]={ 0x580C,0x580D,0x581B,0x581E,0x581F,0x5820,0x5826,0x5827, 0x582D,0x5832,0x5839,0x583F,0x5849,0x584C,0x584D,0x584F, 0x5850,0x5855,0x585F,0x5861,0x5864,0x5867,0x5868,0x5878, @@ -7296,7 +7296,7 @@ static uint16 tab_jisx0212_uni16[]={ 0x595E,0x595F,0x5961,0x5963,0x596B,0x596D}; /* page 17 0x3921-0x397E */ -static uint16 tab_jisx0212_uni17[]={ +static const uint16 tab_jisx0212_uni17[]={ 0x596F,0x5972,0x5975,0x5976,0x5979,0x597B,0x597C,0x598B, 0x598C,0x598E,0x5992,0x5995,0x5997,0x599F,0x59A4,0x59A7, 0x59AD,0x59AE,0x59AF,0x59B0,0x59B3,0x59B7,0x59BA,0x59BC, @@ -7311,7 +7311,7 @@ static uint16 tab_jisx0212_uni17[]={ 0x5AB3,0x5AB5,0x5AB8,0x5ABA,0x5ABB,0x5ABF}; /* page 18 0x3A21-0x3A7E */ -static uint16 tab_jisx0212_uni18[]={ +static const uint16 tab_jisx0212_uni18[]={ 0x5AC4,0x5AC6,0x5AC8,0x5ACF,0x5ADA,0x5ADC,0x5AE0,0x5AE5, 0x5AEA,0x5AEE,0x5AF5,0x5AF6,0x5AFD,0x5B00,0x5B01,0x5B08, 0x5B17,0x5B34,0x5B19,0x5B1B,0x5B1D,0x5B21,0x5B25,0x5B2D, @@ -7326,7 +7326,7 @@ static uint16 tab_jisx0212_uni18[]={ 0x5C5C,0x5C62,0x5C63,0x5C67,0x5C68,0x5C69}; /* page 19 0x3B21-0x3B7E */ -static uint16 tab_jisx0212_uni19[]={ +static const uint16 tab_jisx0212_uni19[]={ 0x5C6D,0x5C70,0x5C74,0x5C75,0x5C7A,0x5C7B,0x5C7C,0x5C7D, 0x5C87,0x5C88,0x5C8A,0x5C8F,0x5C92,0x5C9D,0x5C9F,0x5CA0, 0x5CA2,0x5CA3,0x5CA6,0x5CAA,0x5CB2,0x5CB4,0x5CB5,0x5CBA, @@ -7341,7 +7341,7 @@ static uint16 tab_jisx0212_uni19[]={ 0x5DD0,0x5DCE,0x5DD8,0x5DD9,0x5DE0,0x5DE4}; /* page 20 0x3C21-0x3C7E */ -static uint16 tab_jisx0212_uni20[]={ +static const uint16 tab_jisx0212_uni20[]={ 0x5DE9,0x5DF8,0x5DF9,0x5E00,0x5E07,0x5E0D,0x5E12,0x5E14, 0x5E15,0x5E18,0x5E1F,0x5E20,0x5E2E,0x5E28,0x5E32,0x5E35, 0x5E3E,0x5E4B,0x5E50,0x5E49,0x5E51,0x5E56,0x5E58,0x5E5B, @@ -7356,7 +7356,7 @@ static uint16 tab_jisx0212_uni20[]={ 0x5F58,0x5F5B,0x5F60,0x5F63,0x5F64,0x5F67}; /* page 21 0x3D21-0x3D7E */ -static uint16 tab_jisx0212_uni21[]={ +static const uint16 tab_jisx0212_uni21[]={ 0x5F6F,0x5F72,0x5F74,0x5F75,0x5F78,0x5F7A,0x5F7D,0x5F7E, 0x5F89,0x5F8D,0x5F8F,0x5F96,0x5F9C,0x5F9D,0x5FA2,0x5FA7, 0x5FAB,0x5FA4,0x5FAC,0x5FAF,0x5FB0,0x5FB1,0x5FB8,0x5FC4, @@ -7371,7 +7371,7 @@ static uint16 tab_jisx0212_uni21[]={ 0x60A4,0x60A5,0x60A8,0x60B0,0x60B1,0x60B7}; /* page 22 0x3E21-0x3E7E */ -static uint16 tab_jisx0212_uni22[]={ +static const uint16 tab_jisx0212_uni22[]={ 0x60BB,0x60BE,0x60C2,0x60C4,0x60C8,0x60C9,0x60CA,0x60CB, 0x60CE,0x60CF,0x60D4,0x60D5,0x60D9,0x60DB,0x60DD,0x60DE, 0x60E2,0x60E5,0x60F2,0x60F5,0x60F8,0x60FC,0x60FD,0x6102, @@ -7386,7 +7386,7 @@ static uint16 tab_jisx0212_uni22[]={ 0x61DF,0x61E1,0x61E2,0x61E7,0x61E9,0x61E5}; /* page 23 0x3F21-0x3F7E */ -static uint16 tab_jisx0212_uni23[]={ +static const uint16 tab_jisx0212_uni23[]={ 0x61EC,0x61ED,0x61EF,0x6201,0x6203,0x6204,0x6207,0x6213, 0x6215,0x621C,0x6220,0x6222,0x6223,0x6227,0x6229,0x622B, 0x6239,0x623D,0x6242,0x6243,0x6244,0x6246,0x624C,0x6250, @@ -7401,7 +7401,7 @@ static uint16 tab_jisx0212_uni23[]={ 0x6366,0x636C,0x636D,0x6371,0x6374,0x6375}; /* page 24 0x4021-0x407E */ -static uint16 tab_jisx0212_uni24[]={ +static const uint16 tab_jisx0212_uni24[]={ 0x6378,0x637C,0x637D,0x637F,0x6382,0x6384,0x6387,0x638A, 0x6390,0x6394,0x6395,0x6399,0x639A,0x639E,0x63A4,0x63A6, 0x63AD,0x63AE,0x63AF,0x63BD,0x63C1,0x63C5,0x63C8,0x63CE, @@ -7416,7 +7416,7 @@ static uint16 tab_jisx0212_uni24[]={ 0x64A8,0x64AC,0x64B3,0x64BD,0x64BE,0x64BF}; /* page 25 0x4121-0x417E */ -static uint16 tab_jisx0212_uni25[]={ +static const uint16 tab_jisx0212_uni25[]={ 0x64C4,0x64C9,0x64CA,0x64CB,0x64CC,0x64CE,0x64D0,0x64D1, 0x64D5,0x64D7,0x64E4,0x64E5,0x64E9,0x64EA,0x64ED,0x64F0, 0x64F5,0x64F7,0x64FB,0x64FF,0x6501,0x6504,0x6508,0x6509, @@ -7431,7 +7431,7 @@ static uint16 tab_jisx0212_uni25[]={ 0x660D,0x6611,0x6612,0x6615,0x6616,0x661D}; /* page 26 0x4221-0x427E */ -static uint16 tab_jisx0212_uni26[]={ +static const uint16 tab_jisx0212_uni26[]={ 0x661E,0x6621,0x6622,0x6623,0x6624,0x6626,0x6629,0x662A, 0x662B,0x662C,0x662E,0x6630,0x6631,0x6633,0x6639,0x6637, 0x6640,0x6645,0x6646,0x664A,0x664C,0x6651,0x664E,0x6657, @@ -7446,7 +7446,7 @@ static uint16 tab_jisx0212_uni26[]={ 0x6747,0x6748,0x674C,0x6754,0x6755,0x675D}; /* page 27 0x4321-0x437E */ -static uint16 tab_jisx0212_uni27[]={ +static const uint16 tab_jisx0212_uni27[]={ 0x6766,0x676C,0x676E,0x6774,0x6776,0x677B,0x6781,0x6784, 0x678E,0x678F,0x6791,0x6793,0x6796,0x6798,0x6799,0x679B, 0x67B0,0x67B1,0x67B2,0x67B5,0x67BB,0x67BC,0x67BD,0x67F9, @@ -7461,7 +7461,7 @@ static uint16 tab_jisx0212_uni27[]={ 0x68B2,0x68BB,0x68C5,0x68C8,0x68CC,0x68CF}; /* page 28 0x4421-0x447E */ -static uint16 tab_jisx0212_uni28[]={ +static const uint16 tab_jisx0212_uni28[]={ 0x68D0,0x68D1,0x68D3,0x68D6,0x68D9,0x68DC,0x68DD,0x68E5, 0x68E8,0x68EA,0x68EB,0x68EC,0x68ED,0x68F0,0x68F1,0x68F5, 0x68F6,0x68FB,0x68FC,0x68FD,0x6906,0x6909,0x690A,0x6910, @@ -7476,7 +7476,7 @@ static uint16 tab_jisx0212_uni28[]={ 0x6A1D,0x6A20,0x6A24,0x6A28,0x6A30,0x6A32}; /* page 29 0x4521-0x457E */ -static uint16 tab_jisx0212_uni29[]={ +static const uint16 tab_jisx0212_uni29[]={ 0x6A34,0x6A37,0x6A3B,0x6A3E,0x6A3F,0x6A45,0x6A46,0x6A49, 0x6A4A,0x6A4E,0x6A50,0x6A51,0x6A52,0x6A55,0x6A56,0x6A5B, 0x6A64,0x6A67,0x6A6A,0x6A71,0x6A73,0x6A7E,0x6A81,0x6A83, @@ -7491,7 +7491,7 @@ static uint16 tab_jisx0212_uni29[]={ 0x6B67,0x6B6B,0x6B6E,0x6B70,0x6B75,0x6B7D}; /* page 30 0x4621-0x467E */ -static uint16 tab_jisx0212_uni30[]={ +static const uint16 tab_jisx0212_uni30[]={ 0x6B7E,0x6B82,0x6B85,0x6B97,0x6B9B,0x6B9F,0x6BA0,0x6BA2, 0x6BA3,0x6BA8,0x6BA9,0x6BAC,0x6BAD,0x6BAE,0x6BB0,0x6BB8, 0x6BB9,0x6BBD,0x6BBE,0x6BC3,0x6BC4,0x6BC9,0x6BCC,0x6BD6, @@ -7506,7 +7506,7 @@ static uint16 tab_jisx0212_uni30[]={ 0x6CCF,0x6CD0,0x6CD1,0x6CD2,0x6CD4,0x6CD6}; /* page 31 0x4721-0x477E */ -static uint16 tab_jisx0212_uni31[]={ +static const uint16 tab_jisx0212_uni31[]={ 0x6CDA,0x6CDC,0x6CE0,0x6CE7,0x6CE9,0x6CEB,0x6CEC,0x6CEE, 0x6CF2,0x6CF4,0x6D04,0x6D07,0x6D0A,0x6D0E,0x6D0F,0x6D11, 0x6D13,0x6D1A,0x6D26,0x6D27,0x6D28,0x6C67,0x6D2E,0x6D2F, @@ -7521,7 +7521,7 @@ static uint16 tab_jisx0212_uni31[]={ 0x6E53,0x6E54,0x6E57,0x6E5C,0x6E5D,0x6E5E}; /* page 32 0x4821-0x487E */ -static uint16 tab_jisx0212_uni32[]={ +static const uint16 tab_jisx0212_uni32[]={ 0x6E62,0x6E63,0x6E68,0x6E73,0x6E7B,0x6E7D,0x6E8D,0x6E93, 0x6E99,0x6EA0,0x6EA7,0x6EAD,0x6EAE,0x6EB1,0x6EB3,0x6EBB, 0x6EBF,0x6EC0,0x6EC1,0x6EC3,0x6EC7,0x6EC8,0x6ECA,0x6ECD, @@ -7536,7 +7536,7 @@ static uint16 tab_jisx0212_uni32[]={ 0x6FB6,0x6FBC,0x6FC5,0x6FC7,0x6FC8,0x6FCA}; /* page 33 0x4921-0x497E */ -static uint16 tab_jisx0212_uni33[]={ +static const uint16 tab_jisx0212_uni33[]={ 0x6FDA,0x6FDE,0x6FE8,0x6FE9,0x6FF0,0x6FF5,0x6FF9,0x6FFC, 0x6FFD,0x7000,0x7005,0x7006,0x7007,0x700D,0x7017,0x7020, 0x7023,0x702F,0x7034,0x7037,0x7039,0x703C,0x7043,0x7044, @@ -7551,7 +7551,7 @@ static uint16 tab_jisx0212_uni33[]={ 0x7152,0x7157,0x715A,0x715C,0x715E,0x7160}; /* page 34 0x4A21-0x4A7E */ -static uint16 tab_jisx0212_uni34[]={ +static const uint16 tab_jisx0212_uni34[]={ 0x7168,0x7179,0x7180,0x7185,0x7187,0x718C,0x7192,0x719A, 0x719B,0x71A0,0x71A2,0x71AF,0x71B0,0x71B2,0x71B3,0x71BA, 0x71BF,0x71C0,0x71C1,0x71C4,0x71CB,0x71CC,0x71D3,0x71D6, @@ -7566,7 +7566,7 @@ static uint16 tab_jisx0212_uni34[]={ 0x72DF,0x72E5,0x72F3,0x72F4,0x72FA,0x72FB}; /* page 35 0x4B21-0x4B7E */ -static uint16 tab_jisx0212_uni35[]={ +static const uint16 tab_jisx0212_uni35[]={ 0x72FE,0x7302,0x7304,0x7305,0x7307,0x730B,0x730D,0x7312, 0x7313,0x7318,0x7319,0x731E,0x7322,0x7324,0x7327,0x7328, 0x732C,0x7331,0x7332,0x7335,0x733A,0x733B,0x733D,0x7343, @@ -7581,7 +7581,7 @@ static uint16 tab_jisx0212_uni35[]={ 0x73F5,0x73F7,0x73F9,0x73FA,0x73FB,0x73FD}; /* page 36 0x4C21-0x4C7E */ -static uint16 tab_jisx0212_uni36[]={ +static const uint16 tab_jisx0212_uni36[]={ 0x73FF,0x7400,0x7401,0x7404,0x7407,0x740A,0x7411,0x741A, 0x741B,0x7424,0x7426,0x7428,0x7429,0x742A,0x742B,0x742C, 0x742D,0x742E,0x742F,0x7430,0x7431,0x7439,0x7440,0x7443, @@ -7596,7 +7596,7 @@ static uint16 tab_jisx0212_uni36[]={ 0x74F4,0x74FA,0x74FB,0x74FC,0x74FF,0x7506}; /* page 37 0x4D21-0x4D7E */ -static uint16 tab_jisx0212_uni37[]={ +static const uint16 tab_jisx0212_uni37[]={ 0x7512,0x7516,0x7517,0x7520,0x7521,0x7524,0x7527,0x7529, 0x752A,0x752F,0x7536,0x7539,0x753D,0x753E,0x753F,0x7540, 0x7543,0x7547,0x7548,0x754E,0x7550,0x7552,0x7557,0x755E, @@ -7611,7 +7611,7 @@ static uint16 tab_jisx0212_uni37[]={ 0x762D,0x7632,0x7633,0x7635,0x7638,0x7639}; /* page 38 0x4E21-0x4E7E */ -static uint16 tab_jisx0212_uni38[]={ +static const uint16 tab_jisx0212_uni38[]={ 0x763A,0x763C,0x764A,0x7640,0x7641,0x7643,0x7644,0x7645, 0x7649,0x764B,0x7655,0x7659,0x765F,0x7664,0x7665,0x766D, 0x766E,0x766F,0x7671,0x7674,0x7681,0x7685,0x768C,0x768D, @@ -7626,7 +7626,7 @@ static uint16 tab_jisx0212_uni38[]={ 0x7757,0x775C,0x775E,0x775F,0x7760,0x7762}; /* page 39 0x4F21-0x4F7E */ -static uint16 tab_jisx0212_uni39[]={ +static const uint16 tab_jisx0212_uni39[]={ 0x7764,0x7767,0x776A,0x776C,0x7770,0x7772,0x7773,0x7774, 0x777A,0x777D,0x7780,0x7784,0x778C,0x778D,0x7794,0x7795, 0x7796,0x779A,0x779F,0x77A2,0x77A7,0x77AA,0x77AE,0x77AF, @@ -7641,7 +7641,7 @@ static uint16 tab_jisx0212_uni39[]={ 0x78AC,0x78AD,0x78B0,0x78B1,0x78B2,0x78B3}; /* page 40 0x5021-0x507E */ -static uint16 tab_jisx0212_uni40[]={ +static const uint16 tab_jisx0212_uni40[]={ 0x78BB,0x78BD,0x78BF,0x78C7,0x78C8,0x78C9,0x78CC,0x78CE, 0x78D2,0x78D3,0x78D5,0x78D6,0x78E4,0x78DB,0x78DF,0x78E0, 0x78E1,0x78E6,0x78EA,0x78F2,0x78F3,0x7900,0x78F6,0x78F7, @@ -7656,7 +7656,7 @@ static uint16 tab_jisx0212_uni40[]={ 0x79CF,0x79D4,0x79D6,0x79DA,0x79DD,0x79DE}; /* page 41 0x5121-0x517E */ -static uint16 tab_jisx0212_uni41[]={ +static const uint16 tab_jisx0212_uni41[]={ 0x79E0,0x79E2,0x79E5,0x79EA,0x79EB,0x79ED,0x79F1,0x79F8, 0x79FC,0x7A02,0x7A03,0x7A07,0x7A09,0x7A0A,0x7A0C,0x7A11, 0x7A15,0x7A1B,0x7A1E,0x7A21,0x7A27,0x7A2B,0x7A2D,0x7A2F, @@ -7671,7 +7671,7 @@ static uint16 tab_jisx0212_uni41[]={ 0x7B2A,0x7B2B,0x7B2D,0x7B2E,0x7B2F,0x7B30}; /* page 42 0x5221-0x527E */ -static uint16 tab_jisx0212_uni42[]={ +static const uint16 tab_jisx0212_uni42[]={ 0x7B31,0x7B34,0x7B3D,0x7B3F,0x7B40,0x7B41,0x7B47,0x7B4E, 0x7B55,0x7B60,0x7B64,0x7B66,0x7B69,0x7B6A,0x7B6D,0x7B6F, 0x7B72,0x7B73,0x7B77,0x7B84,0x7B89,0x7B8E,0x7B90,0x7B91, @@ -7686,7 +7686,7 @@ static uint16 tab_jisx0212_uni42[]={ 0x7C59,0x7C5A,0x7C5B,0x7C5C,0x7C5D,0x7C5E}; /* page 43 0x5321-0x537E */ -static uint16 tab_jisx0212_uni43[]={ +static const uint16 tab_jisx0212_uni43[]={ 0x7C61,0x7C63,0x7C67,0x7C69,0x7C6D,0x7C6E,0x7C70,0x7C72, 0x7C79,0x7C7C,0x7C7D,0x7C86,0x7C87,0x7C8F,0x7C94,0x7C9E, 0x7CA0,0x7CA6,0x7CB0,0x7CB6,0x7CB7,0x7CBA,0x7CBB,0x7CBC, @@ -7701,7 +7701,7 @@ static uint16 tab_jisx0212_uni43[]={ 0x7D8C,0x7D8D,0x7D91,0x7D96,0x7D97,0x7D9D}; /* page 44 0x5421-0x547E */ -static uint16 tab_jisx0212_uni44[]={ +static const uint16 tab_jisx0212_uni44[]={ 0x7D9E,0x7DA6,0x7DA7,0x7DAA,0x7DB3,0x7DB6,0x7DB7,0x7DB9, 0x7DC2,0x7DC3,0x7DC4,0x7DC5,0x7DC6,0x7DCC,0x7DCD,0x7DCE, 0x7DD7,0x7DD9,0x7E00,0x7DE2,0x7DE5,0x7DE6,0x7DEA,0x7DEB, @@ -7716,7 +7716,7 @@ static uint16 tab_jisx0212_uni44[]={ 0x7F61,0x7F63,0x7F64,0x7F65,0x7F66,0x7F6D}; /* page 45 0x5521-0x557E */ -static uint16 tab_jisx0212_uni45[]={ +static const uint16 tab_jisx0212_uni45[]={ 0x7F71,0x7F7D,0x7F7E,0x7F7F,0x7F80,0x7F8B,0x7F8D,0x7F8F, 0x7F90,0x7F91,0x7F96,0x7F97,0x7F9C,0x7FA1,0x7FA2,0x7FA6, 0x7FAA,0x7FAD,0x7FB4,0x7FBC,0x7FBF,0x7FC0,0x7FC3,0x7FC8, @@ -7731,7 +7731,7 @@ static uint16 tab_jisx0212_uni45[]={ 0x80D5,0x80D7,0x80D8,0x80E0,0x80ED,0x80EE}; /* page 46 0x5621-0x567E */ -static uint16 tab_jisx0212_uni46[]={ +static const uint16 tab_jisx0212_uni46[]={ 0x80F0,0x80F2,0x80F3,0x80F6,0x80F9,0x80FA,0x80FE,0x8103, 0x810B,0x8116,0x8117,0x8118,0x811C,0x811E,0x8120,0x8124, 0x8127,0x812C,0x8130,0x8135,0x813A,0x813C,0x8145,0x8147, @@ -7746,7 +7746,7 @@ static uint16 tab_jisx0212_uni46[]={ 0x8234,0x823A,0x8243,0x8244,0x8245,0x8246}; /* page 47 0x5721-0x577E */ -static uint16 tab_jisx0212_uni47[]={ +static const uint16 tab_jisx0212_uni47[]={ 0x824B,0x824E,0x824F,0x8251,0x8256,0x825C,0x8260,0x8263, 0x8267,0x826D,0x8274,0x827B,0x827D,0x827F,0x8280,0x8281, 0x8283,0x8284,0x8287,0x8289,0x828A,0x828E,0x8291,0x8294, @@ -7761,7 +7761,7 @@ static uint16 tab_jisx0212_uni47[]={ 0x8351,0x8355,0x8356,0x8357,0x8370,0x8378}; /* page 48 0x5821-0x587E */ -static uint16 tab_jisx0212_uni48[]={ +static const uint16 tab_jisx0212_uni48[]={ 0x837D,0x837F,0x8380,0x8382,0x8384,0x8386,0x838D,0x8392, 0x8394,0x8395,0x8398,0x8399,0x839B,0x839C,0x839D,0x83A6, 0x83A7,0x83A9,0x83AC,0x83BE,0x83BF,0x83C0,0x83C7,0x83C9, @@ -7776,7 +7776,7 @@ static uint16 tab_jisx0212_uni48[]={ 0x84C2,0x84C7,0x84C8,0x84CC,0x84CF,0x84D3}; /* page 49 0x5921-0x597E */ -static uint16 tab_jisx0212_uni49[]={ +static const uint16 tab_jisx0212_uni49[]={ 0x84DC,0x84E7,0x84EA,0x84EF,0x84F0,0x84F1,0x84F2,0x84F7, 0x8532,0x84FA,0x84FB,0x84FD,0x8502,0x8503,0x8507,0x850C, 0x850E,0x8510,0x851C,0x851E,0x8522,0x8523,0x8524,0x8525, @@ -7791,7 +7791,7 @@ static uint16 tab_jisx0212_uni49[]={ 0x85E6,0x85E8,0x85ED,0x85F3,0x85F6,0x85FC}; /* page 50 0x5A21-0x5A7E */ -static uint16 tab_jisx0212_uni50[]={ +static const uint16 tab_jisx0212_uni50[]={ 0x85FF,0x8600,0x8604,0x8605,0x860D,0x860E,0x8610,0x8611, 0x8612,0x8618,0x8619,0x861B,0x861E,0x8621,0x8627,0x8629, 0x8636,0x8638,0x863A,0x863C,0x863D,0x8640,0x8642,0x8646, @@ -7806,7 +7806,7 @@ static uint16 tab_jisx0212_uni50[]={ 0x8714,0x8719,0x871E,0x871F,0x8721,0x8723}; /* page 51 0x5B21-0x5B7E */ -static uint16 tab_jisx0212_uni51[]={ +static const uint16 tab_jisx0212_uni51[]={ 0x8728,0x872E,0x872F,0x8731,0x8732,0x8739,0x873A,0x873C, 0x873D,0x873E,0x8740,0x8743,0x8745,0x874D,0x8758,0x875D, 0x8761,0x8764,0x8765,0x876F,0x8771,0x8772,0x877B,0x8783, @@ -7821,7 +7821,7 @@ static uint16 tab_jisx0212_uni51[]={ 0x8828,0x882D,0x882E,0x8830,0x8832,0x8835}; /* page 52 0x5C21-0x5C7E */ -static uint16 tab_jisx0212_uni52[]={ +static const uint16 tab_jisx0212_uni52[]={ 0x883A,0x883C,0x8841,0x8843,0x8845,0x8848,0x8849,0x884A, 0x884B,0x884E,0x8851,0x8855,0x8856,0x8858,0x885A,0x885C, 0x885F,0x8860,0x8864,0x8869,0x8871,0x8879,0x887B,0x8880, @@ -7836,7 +7836,7 @@ static uint16 tab_jisx0212_uni52[]={ 0x896B,0x896E,0x8970,0x8973,0x8975,0x897A}; /* page 53 0x5D21-0x5D7E */ -static uint16 tab_jisx0212_uni53[]={ +static const uint16 tab_jisx0212_uni53[]={ 0x897B,0x897C,0x897D,0x8989,0x898D,0x8990,0x8994,0x8995, 0x899B,0x899C,0x899F,0x89A0,0x89A5,0x89B0,0x89B4,0x89B5, 0x89B6,0x89B7,0x89BC,0x89D4,0x89D5,0x89D6,0x89D7,0x89D8, @@ -7851,7 +7851,7 @@ static uint16 tab_jisx0212_uni53[]={ 0x8A9F,0x8AA7,0x8AA9,0x8AAE,0x8AAF,0x8AB3}; /* page 54 0x5E21-0x5E7E */ -static uint16 tab_jisx0212_uni54[]={ +static const uint16 tab_jisx0212_uni54[]={ 0x8AB6,0x8AB7,0x8ABB,0x8ABE,0x8AC3,0x8AC6,0x8AC8,0x8AC9, 0x8ACA,0x8AD1,0x8AD3,0x8AD4,0x8AD5,0x8AD7,0x8ADD,0x8ADF, 0x8AEC,0x8AF0,0x8AF4,0x8AF5,0x8AF6,0x8AFC,0x8AFF,0x8B05, @@ -7866,7 +7866,7 @@ static uint16 tab_jisx0212_uni54[]={ 0x8C73,0x8C75,0x8C76,0x8C7B,0x8C7E,0x8C86}; /* page 55 0x5F21-0x5F7E */ -static uint16 tab_jisx0212_uni55[]={ +static const uint16 tab_jisx0212_uni55[]={ 0x8C87,0x8C8B,0x8C90,0x8C92,0x8C93,0x8C99,0x8C9B,0x8C9C, 0x8CA4,0x8CB9,0x8CBA,0x8CC5,0x8CC6,0x8CC9,0x8CCB,0x8CCF, 0x8CD6,0x8CD5,0x8CD9,0x8CDD,0x8CE1,0x8CE8,0x8CEC,0x8CEF, @@ -7881,7 +7881,7 @@ static uint16 tab_jisx0212_uni55[]={ 0x8E11,0x8E14,0x8E16,0x8E20,0x8E21,0x8E22}; /* page 56 0x6021-0x607E */ -static uint16 tab_jisx0212_uni56[]={ +static const uint16 tab_jisx0212_uni56[]={ 0x8E23,0x8E26,0x8E27,0x8E31,0x8E33,0x8E36,0x8E37,0x8E38, 0x8E39,0x8E3D,0x8E40,0x8E41,0x8E4B,0x8E4D,0x8E4E,0x8E4F, 0x8E54,0x8E5B,0x8E5C,0x8E5D,0x8E5E,0x8E61,0x8E62,0x8E69, @@ -7896,7 +7896,7 @@ static uint16 tab_jisx0212_uni56[]={ 0x8F35,0x8F36,0x8F37,0x8F3A,0x8F40,0x8F41}; /* page 57 0x6121-0x617E */ -static uint16 tab_jisx0212_uni57[]={ +static const uint16 tab_jisx0212_uni57[]={ 0x8F43,0x8F47,0x8F4F,0x8F51,0x8F52,0x8F53,0x8F54,0x8F55, 0x8F58,0x8F5D,0x8F5E,0x8F65,0x8F9D,0x8FA0,0x8FA1,0x8FA4, 0x8FA5,0x8FA6,0x8FB5,0x8FB6,0x8FB8,0x8FBE,0x8FC0,0x8FC1, @@ -7911,7 +7911,7 @@ static uint16 tab_jisx0212_uni57[]={ 0x90B4,0x90B6,0x90BD,0x90CC,0x90BE,0x90C3}; /* page 58 0x6221-0x627E */ -static uint16 tab_jisx0212_uni58[]={ +static const uint16 tab_jisx0212_uni58[]={ 0x90C4,0x90C5,0x90C7,0x90C8,0x90D5,0x90D7,0x90D8,0x90D9, 0x90DC,0x90DD,0x90DF,0x90E5,0x90D2,0x90F6,0x90EB,0x90EF, 0x90F0,0x90F4,0x90FE,0x90FF,0x9100,0x9104,0x9105,0x9106, @@ -7926,7 +7926,7 @@ static uint16 tab_jisx0212_uni58[]={ 0x91B3,0x91B6,0x91BB,0x91BC,0x91BD,0x91BF}; /* page 59 0x6321-0x637E */ -static uint16 tab_jisx0212_uni59[]={ +static const uint16 tab_jisx0212_uni59[]={ 0x91C2,0x91C3,0x91C5,0x91D3,0x91D4,0x91D7,0x91D9,0x91DA, 0x91DE,0x91E4,0x91E5,0x91E9,0x91EA,0x91EC,0x91ED,0x91EE, 0x91EF,0x91F0,0x91F1,0x91F7,0x91F9,0x91FB,0x91FD,0x9200, @@ -7941,7 +7941,7 @@ static uint16 tab_jisx0212_uni59[]={ 0x9289,0x928A,0x928D,0x928E,0x9292,0x9297}; /* page 60 0x6421-0x647E */ -static uint16 tab_jisx0212_uni60[]={ +static const uint16 tab_jisx0212_uni60[]={ 0x9299,0x929F,0x92A0,0x92A4,0x92A5,0x92A7,0x92A8,0x92AB, 0x92AF,0x92B2,0x92B6,0x92B8,0x92BA,0x92BB,0x92BC,0x92BD, 0x92BF,0x92C0,0x92C1,0x92C2,0x92C3,0x92C5,0x92C6,0x92C7, @@ -7956,7 +7956,7 @@ static uint16 tab_jisx0212_uni60[]={ 0x936F,0x9370,0x9371,0x9373,0x9374,0x9376}; /* page 61 0x6521-0x657E */ -static uint16 tab_jisx0212_uni61[]={ +static const uint16 tab_jisx0212_uni61[]={ 0x937A,0x937D,0x937F,0x9380,0x9381,0x9382,0x9388,0x938A, 0x938B,0x938D,0x938F,0x9392,0x9395,0x9398,0x939B,0x939E, 0x93A1,0x93A3,0x93A4,0x93A6,0x93A8,0x93AB,0x93B4,0x93B5, @@ -7971,7 +7971,7 @@ static uint16 tab_jisx0212_uni61[]={ 0x9471,0x9472,0x9484,0x9483,0x9578,0x9579}; /* page 62 0x6621-0x667E */ -static uint16 tab_jisx0212_uni62[]={ +static const uint16 tab_jisx0212_uni62[]={ 0x957E,0x9584,0x9588,0x958C,0x958D,0x958E,0x959D,0x959E, 0x959F,0x95A1,0x95A6,0x95A9,0x95AB,0x95AC,0x95B4,0x95B6, 0x95BA,0x95BD,0x95BF,0x95C6,0x95C8,0x95C9,0x95CB,0x95D0, @@ -7986,7 +7986,7 @@ static uint16 tab_jisx0212_uni62[]={ 0x96DF,0x96E9,0x96EF,0x96F1,0x96FA,0x9702}; /* page 63 0x6721-0x677E */ -static uint16 tab_jisx0212_uni63[]={ +static const uint16 tab_jisx0212_uni63[]={ 0x9703,0x9705,0x9709,0x971A,0x971B,0x971D,0x9721,0x9722, 0x9723,0x9728,0x9731,0x9733,0x9741,0x9743,0x974A,0x974E, 0x974F,0x9755,0x9757,0x9758,0x975A,0x975B,0x9763,0x9767, @@ -8001,7 +8001,7 @@ static uint16 tab_jisx0212_uni63[]={ 0x9816,0x981C,0x981E,0x9820,0x9823,0x9826}; /* page 64 0x6821-0x687E */ -static uint16 tab_jisx0212_uni64[]={ +static const uint16 tab_jisx0212_uni64[]={ 0x982B,0x982E,0x982F,0x9830,0x9832,0x9833,0x9835,0x9825, 0x983E,0x9844,0x9847,0x984A,0x9851,0x9852,0x9853,0x9856, 0x9857,0x9859,0x985A,0x9862,0x9863,0x9865,0x9866,0x986A, @@ -8016,7 +8016,7 @@ static uint16 tab_jisx0212_uni64[]={ 0x999F,0x99A6,0x99B0,0x99B1,0x99B2,0x99B5}; /* page 65 0x6921-0x697E */ -static uint16 tab_jisx0212_uni65[]={ +static const uint16 tab_jisx0212_uni65[]={ 0x99B9,0x99BA,0x99BD,0x99BF,0x99C3,0x99C9,0x99D3,0x99D4, 0x99D9,0x99DA,0x99DC,0x99DE,0x99E7,0x99EA,0x99EB,0x99EC, 0x99F0,0x99F4,0x99F5,0x99F9,0x99FD,0x99FE,0x9A02,0x9A03, @@ -8031,7 +8031,7 @@ static uint16 tab_jisx0212_uni65[]={ 0x9AFD,0x9AFF,0x9B00,0x9B01,0x9B02,0x9B03}; /* page 66 0x6A21-0x6A7E */ -static uint16 tab_jisx0212_uni66[]={ +static const uint16 tab_jisx0212_uni66[]={ 0x9B04,0x9B05,0x9B08,0x9B09,0x9B0B,0x9B0C,0x9B0D,0x9B0E, 0x9B10,0x9B12,0x9B16,0x9B19,0x9B1B,0x9B1C,0x9B20,0x9B26, 0x9B2B,0x9B2D,0x9B33,0x9B34,0x9B35,0x9B37,0x9B39,0x9B3A, @@ -8046,7 +8046,7 @@ static uint16 tab_jisx0212_uni66[]={ 0x9BEA,0x9BEB,0x9BEF,0x9BF3,0x9BF7,0x9BF8}; /* page 67 0x6B21-0x6B7E */ -static uint16 tab_jisx0212_uni67[]={ +static const uint16 tab_jisx0212_uni67[]={ 0x9BF9,0x9BFA,0x9BFD,0x9BFF,0x9C00,0x9C02,0x9C0B,0x9C0F, 0x9C11,0x9C16,0x9C18,0x9C19,0x9C1A,0x9C1C,0x9C1E,0x9C22, 0x9C23,0x9C26,0x9C27,0x9C28,0x9C29,0x9C2A,0x9C31,0x9C35, @@ -8061,7 +8061,7 @@ static uint16 tab_jisx0212_uni67[]={ 0x9D6A,0x9D6B,0x9D70,0x9D76,0x9D77,0x9D7B}; /* page 68 0x6C21-0x6C7E */ -static uint16 tab_jisx0212_uni68[]={ +static const uint16 tab_jisx0212_uni68[]={ 0x9D7C,0x9D7E,0x9D83,0x9D84,0x9D86,0x9D8A,0x9D8D,0x9D8E, 0x9D92,0x9D93,0x9D95,0x9D96,0x9D97,0x9D98,0x9DA1,0x9DAA, 0x9DAC,0x9DAE,0x9DB1,0x9DB5,0x9DB9,0x9DBC,0x9DBF,0x9DC3, @@ -8076,7 +8076,7 @@ static uint16 tab_jisx0212_uni68[]={ 0x9EED,0x9EEE,0x9EF0,0x9EF1,0x9EF2,0x9EF5}; /* page 69 0x6D21-0x6D63 */ -static uint16 tab_jisx0212_uni69[]={ +static const uint16 tab_jisx0212_uni69[]={ 0x9EF8,0x9EFF,0x9F02,0x9F03,0x9F09,0x9F0F,0x9F10,0x9F11, 0x9F12,0x9F14,0x9F16,0x9F17,0x9F19,0x9F1A,0x9F1B,0x9F1F, 0x9F22,0x9F26,0x9F2A,0x9F2B,0x9F2F,0x9F31,0x9F32,0x9F34, @@ -8544,7 +8544,7 @@ static MY_CHARSET_HANDLER my_charset_handler= -CHARSET_INFO my_charset_ujis_japanese_ci= +struct charset_info_st my_charset_ujis_japanese_ci= { 12,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ @@ -8577,7 +8577,7 @@ CHARSET_INFO my_charset_ujis_japanese_ci= }; -CHARSET_INFO my_charset_ujis_bin= +struct charset_info_st my_charset_ujis_bin= { 91,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT, /* state */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 6703e489617..160052e3ce7 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1487,7 +1487,7 @@ static MY_UNICASE_INFO planeFF[]={ {0xFFFE,0xFFFE,0xFFFE}, {0xFFFF,0xFFFF,0xFFFF} }; -MY_UNICASE_INFO *my_unicase_default[256]={ +MY_UNICASE_INFO *const my_unicase_default[256]={ plane00, plane01, plane02, plane03, plane04, plane05, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -1666,7 +1666,7 @@ static MY_UNICASE_INFO turk00[]= -MY_UNICASE_INFO *my_unicase_turkish[256]= +MY_UNICASE_INFO *const my_unicase_turkish[256]= { turk00, plane01, plane02, plane03, plane04, plane05, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -1717,14 +1717,12 @@ int my_wildcmp_unicode(CHARSET_INFO *cs, const char *str,const char *str_end, const char *wildstr,const char *wildend, int escape, int w_one, int w_many, - MY_UNICASE_INFO **weights) + MY_UNICASE_INFO *const *weights) { int result= -1; /* Not found, using wildcards */ my_wc_t s_wc, w_wc; int scan, plane; - int (*mb_wc)(struct charset_info_st *, my_wc_t *, - const uchar *, const uchar *); - mb_wc= cs->cset->mb_wc; + my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc; while (wildstr != wildend) { @@ -1874,7 +1872,7 @@ int my_wildcmp_unicode(CHARSET_INFO *cs, expressions. Note, there is no need to mark byte 255 as a letter, it is illegal byte in UTF8. */ -static uchar ctype_utf8[] = { +static const uchar ctype_utf8[] = { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, @@ -1896,7 +1894,7 @@ static uchar ctype_utf8[] = { /* The below are taken from usa7 implementation */ -static uchar to_lower_utf8[] = { +static const uchar to_lower_utf8[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -1915,7 +1913,7 @@ static uchar to_lower_utf8[] = { 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 }; -static uchar to_upper_utf8[] = { +static const uchar to_upper_utf8[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -2175,7 +2173,7 @@ static size_t my_caseup_utf8(CHARSET_INFO *cs, char *src, size_t srclen, my_wc_t wc; int srcres, dstres; char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->caseup_multiply == 1); while ((src < srcend) && @@ -2198,7 +2196,7 @@ static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, size_t slen, my_wc_t wc; int res; const uchar *e=s+slen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; /* Remove end space. We have to do this to be able to compare @@ -2225,7 +2223,7 @@ static size_t my_caseup_str_utf8(CHARSET_INFO *cs, char *src) my_wc_t wc; int srcres, dstres; char *dst= src, *dst0= src; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; DBUG_ASSERT(cs->caseup_multiply == 1); while (*src && @@ -2249,7 +2247,7 @@ static size_t my_casedn_utf8(CHARSET_INFO *cs, char *src, size_t srclen, my_wc_t wc; int srcres, dstres; char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->casedn_multiply == 1); while ((src < srcend) && @@ -2271,7 +2269,7 @@ static size_t my_casedn_str_utf8(CHARSET_INFO *cs, char *src) my_wc_t wc; int srcres, dstres; char *dst= src, *dst0= src; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; DBUG_ASSERT(cs->casedn_multiply == 1); while (*src && @@ -2314,7 +2312,7 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se=s+slen; const uchar *te=t+tlen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; while ( s < se && t < te ) { @@ -2383,7 +2381,7 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs, int s_res, t_res, res; my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se= s+slen, *te= t+tlen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE diff_if_only_endspace_difference= 0; @@ -2471,7 +2469,7 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs, static int my_strcasecmp_utf8(CHARSET_INFO *cs, const char *s, const char *t) { - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; while (s[0] && t[0]) { my_wc_t s_wc,t_wc; @@ -2556,7 +2554,7 @@ int my_wildcmp_utf8(CHARSET_INFO *cs, const char *wildstr,const char *wildend, int escape, int w_one, int w_many) { - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; return my_wildcmp_unicode(cs,str,str_end,wildstr,wildend, escape,w_one,w_many,uni_plane); } @@ -2580,7 +2578,7 @@ static size_t my_strnxfrm_utf8(CHARSET_INFO *cs, uchar *de= dst + dstlen; uchar *de_beg= de - 1; const uchar *se = src + srclen; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; while (dst < de_beg) { @@ -2686,7 +2684,7 @@ MY_CHARSET_HANDLER my_charset_utf8_handler= -CHARSET_INFO my_charset_utf8_general_ci= +struct charset_info_st my_charset_utf8_general_ci= { 33,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_UNICODE, /* state */ @@ -2719,7 +2717,7 @@ CHARSET_INFO my_charset_utf8_general_ci= }; -CHARSET_INFO my_charset_utf8_bin= +struct charset_info_st my_charset_utf8_bin= { 83,0,0, /* number */ MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_UNICODE, /* state */ @@ -2771,7 +2769,7 @@ static int my_strnncoll_utf8_cs(CHARSET_INFO *cs, const uchar *te=t+tlen; int save_diff = 0; int diff; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; while ( s < se && t < te ) { @@ -2816,7 +2814,7 @@ static int my_strnncollsp_utf8_cs(CHARSET_INFO *cs, const uchar *se= s + slen; const uchar *te= t + tlen; int save_diff= 0; - MY_UNICASE_INFO **uni_plane= cs->caseinfo; + MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE diff_if_only_endspace_difference= 0; @@ -2902,7 +2900,7 @@ static MY_COLLATION_HANDLER my_collation_cs_handler = my_propagate_simple }; -CHARSET_INFO my_charset_utf8_general_cs= +struct charset_info_st my_charset_utf8_general_cs= { 254,0,0, /* number */ MY_CS_COMPILED|MY_CS_UNICODE, /* state */ @@ -2960,7 +2958,7 @@ All other characters are encoded using five bytes: */ -static uint16 touni[5994]= +static const uint16 touni[5994]= { 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, @@ -3716,7 +3714,7 @@ static uint16 touni[5994]= /* 00C0-05FF */ -static uint16 uni_0C00_05FF[1344]= +static const uint16 uni_0C00_05FF[1344]= { 0x0017,0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E, 0x001F,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026, @@ -3960,7 +3958,7 @@ static uint16 uni_1E00_1FFF[512]= /* 2160-217F */ -static uint16 uni_2160_217F[32]= +static const uint16 uni_2160_217F[32]= { 0x0739,0x0789,0x07D9,0x0829,0x0879,0x08C9,0x0919,0x0969, 0x09B9,0x0A09,0x0A59,0x0AA9,0x0AF9,0x0B49,0x0B99,0x0BE9, @@ -3970,7 +3968,7 @@ static uint16 uni_2160_217F[32]= /* 24B0-24EF */ -static uint16 uni_24B0_24EF[64]= +static const uint16 uni_24B0_24EF[64]= { 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0511,0x0512, 0x0513,0x0514,0x0515,0x0516,0x0517,0x0518,0x0519,0x051A, @@ -3984,7 +3982,7 @@ static uint16 uni_24B0_24EF[64]= /* FF20-FF5F */ -static uint16 uni_FF20_FF5F[64]= +static const uint16 uni_FF20_FF5F[64]= { 0x0000,0x0560,0x05B0,0x0600,0x0650,0x06A0,0x06F0,0x0740, 0x0790,0x07E0,0x0830,0x0880,0x08D0,0x0920,0x0970,0x09C0, @@ -4008,7 +4006,7 @@ static uint16 uni_FF20_FF5F[64]= static int hexlo(int x) { - static char hex_lo_digit[256]= + static const char hex_lo_digit[256]= { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* ................ */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* ................ */ @@ -4039,7 +4037,7 @@ static int hexlo(int x) 0..9 digits _ underscore */ -static char filename_safe_char[128]= +static const char filename_safe_char[128]= { 1,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, /* ................ */ @@ -4202,7 +4200,7 @@ static MY_CHARSET_HANDLER my_charset_filename_handler= -CHARSET_INFO my_charset_filename= +struct charset_info_st my_charset_filename= { 17,0,0, /* number */ MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_HIDDEN|MY_CS_NONASCII, diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 9d82d9d6e01..611d06d2b2f 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -55,7 +55,7 @@ #ifdef HAVE_CHARSET_cp1250 -static uint16 tab_cp1250_uni[256]={ +static const uint16 tab_cp1250_uni[256]={ 0,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, @@ -92,7 +92,7 @@ static uint16 tab_cp1250_uni[256]={ /* 0000-00FD , 254 chars */ -static uchar tab_uni_cp1250_plane00[]={ +static const uchar tab_uni_cp1250_plane00[]={ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -111,7 +111,7 @@ static uchar tab_uni_cp1250_plane00[]={ 0x00,0x00,0x00,0xF3,0xF4,0x00,0xF6,0xF7,0x00,0x00,0xFA,0x00,0xFC,0xFD}; /* 0102-017E , 125 chars */ -static uchar tab_uni_cp1250_plane01[]={ +static const uchar tab_uni_cp1250_plane01[]={ 0xC3,0xE3,0xA5,0xB9,0xC6,0xE6,0x00,0x00,0x00,0x00,0xC8,0xE8,0xCF,0xEF,0xD0,0xF0, 0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0xCC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -122,7 +122,7 @@ static uchar tab_uni_cp1250_plane01[]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x9F,0xAF,0xBF,0x8E,0x9E}; /* 2013-20AC , 154 chars */ -static uchar tab_uni_cp1250_plane20[]={ +static const uchar tab_uni_cp1250_plane20[]={ 0x96,0x97,0x00,0x00,0x00,0x91,0x92,0x82,0x00,0x93,0x94,0x84,0x00,0x86,0x87,0x95, 0x00,0x00,0x00,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x8B,0x9B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -135,12 +135,12 @@ static uchar tab_uni_cp1250_plane20[]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80}; /* 02C7-02DD , 23 chars */ -static uchar tab_uni_cp1250_plane02[]={ +static const uchar tab_uni_cp1250_plane02[]={ 0xA1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xA2,0xFF,0x00,0xB2,0x00,0xBD}; /* 2122-2122 , 1 chars */ -static uchar tab_uni_cp1250_plane21[]={ +static const uchar tab_uni_cp1250_plane21[]={ 0x99}; @@ -154,7 +154,7 @@ static MY_UNI_IDX idx_uni_cp1250[]={ }; -static uchar NEAR ctype_win1250ch[] = { +static const uchar NEAR ctype_win1250ch[] = { 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x20, 0x20, @@ -190,7 +190,7 @@ static uchar NEAR ctype_win1250ch[] = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10 }; -static uchar NEAR to_lower_win1250ch[] = { +static const uchar NEAR to_lower_win1250ch[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, @@ -225,7 +225,7 @@ static uchar NEAR to_lower_win1250ch[] = { 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -static uchar NEAR to_upper_win1250ch[] = { +static const uchar NEAR to_upper_win1250ch[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, @@ -262,7 +262,7 @@ static uchar NEAR to_upper_win1250ch[] = { -static uchar NEAR sort_order_win1250ch[] = { +static const uchar NEAR sort_order_win1250ch[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -281,7 +281,7 @@ static uchar NEAR sort_order_win1250ch[] = { 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 }; -static uchar NEAR _sort_order_win1250ch1[] = { +static const uchar NEAR _sort_order_win1250ch1[] = { 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, @@ -406,7 +406,7 @@ struct wordvalue { uchar pass1; uchar pass2; }; -static struct wordvalue doubles[] = { +static const struct wordvalue doubles[] = { { (uchar*) "ch", 0xad, 0x03 }, { (uchar*) "c", 0xa6, 0x02 }, { (uchar*) "Ch", 0xad, 0x02 }, @@ -515,7 +515,7 @@ static size_t my_strnxfrm_win1250ch(CHARSET_INFO * cs __attribute__((unused)), #ifdef REAL_MYSQL -static uchar NEAR like_range_prefix_min_win1250ch[]= +static const uchar NEAR like_range_prefix_min_win1250ch[]= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, @@ -679,7 +679,7 @@ static MY_COLLATION_HANDLER my_collation_czech_ci_handler = }; -CHARSET_INFO my_charset_cp1250_czech_ci = +struct charset_info_st my_charset_cp1250_czech_ci = { 34,0,0, /* number */ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_CSSORT, /* state */ diff --git a/strings/ctype.c b/strings/ctype.c index 4830c83df99..b1809eccac1 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -75,7 +75,7 @@ struct my_cs_file_section_st #define _CS_DIFF3 21 -static struct my_cs_file_section_st sec[] = +static const struct my_cs_file_section_st sec[] = { {_CS_MISC, "xml"}, {_CS_MISC, "xml/version"}, @@ -110,9 +110,10 @@ static struct my_cs_file_section_st sec[] = {0, NULL} }; -static struct my_cs_file_section_st * cs_file_sec(const char *attr, size_t len) +static const struct my_cs_file_section_st +*cs_file_sec(const char *attr, size_t len) { - struct my_cs_file_section_st *s; + const struct my_cs_file_section_st *s; for (s=sec; s->str; s++) { if (!strncmp(attr,s->str,len)) @@ -136,8 +137,8 @@ typedef struct my_cs_file_info char comment[MY_CS_CSDESCR_SIZE]; char tailoring[MY_CS_TAILORING_SIZE]; size_t tailoring_length; - CHARSET_INFO cs; - int (*add_collation)(CHARSET_INFO *cs); + struct charset_info_st cs; + int (*add_collation)(struct charset_info_st *cs); } MY_CHARSET_LOADER; @@ -180,7 +181,7 @@ static int fill_uint16(uint16 *a,uint size,const char *str, size_t len) static int cs_enter(MY_XML_PARSER *st,const char *attr, size_t len) { struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data; - struct my_cs_file_section_st *s= cs_file_sec(attr,len); + const struct my_cs_file_section_st *s= cs_file_sec(attr,len); if ( s && (s->state == _CS_CHARSET)) bzero(&i->cs,sizeof(i->cs)); @@ -195,7 +196,7 @@ static int cs_enter(MY_XML_PARSER *st,const char *attr, size_t len) static int cs_leave(MY_XML_PARSER *st,const char *attr, size_t len) { struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data; - struct my_cs_file_section_st *s= cs_file_sec(attr,len); + const struct my_cs_file_section_st *s= cs_file_sec(attr,len); int state= s ? s->state : 0; int rc; @@ -213,9 +214,9 @@ static int cs_leave(MY_XML_PARSER *st,const char *attr, size_t len) static int cs_value(MY_XML_PARSER *st,const char *attr, size_t len) { struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data; - struct my_cs_file_section_st *s; - int state= (int)((s=cs_file_sec(st->attr, strlen(st->attr))) ? s->state : - 0); + const struct my_cs_file_section_st *s; + int state= (int)((s= cs_file_sec(st->attr, strlen(st->attr))) ? s->state : + 0); switch (state) { case _CS_ID: @@ -290,7 +291,7 @@ static int cs_value(MY_XML_PARSER *st,const char *attr, size_t len) my_bool my_parse_charset_xml(const char *buf, size_t len, - int (*add_collation)(CHARSET_INFO *cs)) + int (*add_collation)(struct charset_info_st *cs)) { MY_XML_PARSER p; struct my_cs_file_info i; diff --git a/strings/decimal.c b/strings/decimal.c index 8e30308d359..b1bd86f3f29 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -348,7 +348,7 @@ int decimal2string(decimal_t *from, char *to, int *to_len, char *s=to; dec1 *buf, *buf0=from->buf, tmp; - DBUG_ASSERT(*to_len >= 2+from->sign); + DBUG_ASSERT(*to_len >= 2+ (int) from->sign); /* removing leading zeroes */ buf0= remove_leading_zeroes(from, &intg); @@ -1815,7 +1815,8 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to) int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg), frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac); int frac0=max(frac1, frac2), error; - dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0; + dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2; + my_bool carry=0; /* let carry:=1 if from2 > from1 */ start1=buf1=from1->buf; stop1=buf1+intg1; @@ -1883,7 +1884,7 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to) swap_variables(dec1 *,start1, start2); swap_variables(int,intg1,intg2); swap_variables(int,frac1,frac2); - to->sign= 1 - to->sign; + to->sign= !to->sign; } FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error); diff --git a/strings/int2str.c b/strings/int2str.c index 2710236f78d..f2a5c15f32c 100644 --- a/strings/int2str.c +++ b/strings/int2str.c @@ -31,9 +31,9 @@ /* _dig_vec arrays are public because they are used in several outer places. */ -char NEAR _dig_vec_upper[] = +const char NEAR _dig_vec_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -char NEAR _dig_vec_lower[] = +const char NEAR _dig_vec_lower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; @@ -68,7 +68,7 @@ int2str(register long int val, register char *dst, register int radix, char buffer[65]; register char *p; long int new_val; - char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower; + const char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower; ulong uval= (ulong) val; if (radix < 0) diff --git a/strings/longlong2str.c b/strings/longlong2str.c index 76d6c099729..a30eca40f2f 100644 --- a/strings/longlong2str.c +++ b/strings/longlong2str.c @@ -58,11 +58,12 @@ This assumes that longlong multiplication is faster than longlong division. */ -char *longlong2str(longlong val,char *dst,int radix) +char *longlong2str(longlong val,char *dst,int radix, int upcase) { char buffer[65]; register char *p; long long_val; + const char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower; ulonglong uval= (ulonglong) val; if (radix < 0) @@ -92,14 +93,14 @@ char *longlong2str(longlong val,char *dst,int radix) { ulonglong quo= uval/(uint) radix; uint rem= (uint) (uval- quo* (uint) radix); - *--p = _dig_vec_upper[rem]; + *--p = dig_vec[rem]; uval= quo; } long_val= (long) uval; while (long_val != 0) { long quo= long_val/radix; - *--p = _dig_vec_upper[(uchar) (long_val - quo*radix)]; + *--p = dig_vec[(uchar) (long_val - quo*radix)]; long_val= quo; } while ((*dst++ = *p++) != 0) ; diff --git a/strings/longlong2str_asm.c b/strings/longlong2str_asm.c index d33ba30ba59..237d1d15052 100644 --- a/strings/longlong2str_asm.c +++ b/strings/longlong2str_asm.c @@ -38,7 +38,7 @@ extern char *longlong2str_with_dig_vector(longlong val,char *dst,int radix, const char *dig_vector); -char *longlong2str(longlong val,char *dst,int radix) +char *longlong2str(longlong val,char *dst,int radix, int upcase) { - return longlong2str_with_dig_vector(val, dst, radix, _dig_vec_upper); + return longlong2str_with_dig_vector(val, dst, radix, upcase ? _dig_vec_upper : _dig_vec_lower); } diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 508670dbad9..f2dd3f8e525 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -19,61 +19,533 @@ #include <m_ctype.h> #include <stdarg.h> -/* - Limited snprintf() implementations - SYNOPSIS - my_vsnprintf() - to Store result here - n Store up to n-1 characters, followed by an end 0 - fmt printf format - ap Arguments - - IMPLEMENTION: - Supports following formats: - %#[l]d - %#[l]u - %#[l]x - %#.#b Local format; note first # is ignored and second is REQUIRED - %#.#s Note first # is ignored +#define MAX_ARGS 32 /* max positional args count*/ +#define MAX_PRINT_INFO 32 /* max print position count */ + +#define LENGTH_ARG 1 +#define WIDTH_ARG 2 +#define PREZERO_ARG 4 +#define ESCAPED_ARG 8 + +typedef struct pos_arg_info ARGS_INFO; +typedef struct print_info PRINT_INFO; + +struct pos_arg_info +{ + char arg_type; /* argument type */ + uint have_longlong; /* used from integer values */ + char *str_arg; /* string value of the arg */ + longlong longlong_arg; /* integer value of the arg */ + double double_arg; /* double value of the arg */ +}; + + +struct print_info +{ + char arg_type; /* argument type */ + size_t arg_idx; /* index of the positional arg */ + size_t length; /* print width or arg index */ + size_t width; /* print width or arg index */ + uint flags; + const char *begin; /**/ + const char *end; /**/ +}; + + +/** + Calculates print length or index of positional argument + + @param fmt processed string + @param length print length or index of positional argument + @param pre_zero returns flags with PREZERO_ARG set if necessary + + @retval + string position right after length digits +*/ + +static const char *get_length(const char *fmt, size_t *length, uint *pre_zero) +{ + for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) + { + *length= *length * 10 + (uint)(*fmt - '0'); + if (!*length) + *pre_zero|= PREZERO_ARG; /* first digit was 0 */ + } + return fmt; +} + + +/** + Calculates print width or index of positional argument + + @param fmt processed string + @param width print width or index of positional argument + + @retval + string position right after width digits +*/ + +static const char *get_width(const char *fmt, size_t *width) +{ + for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) + { + *width= *width * 10 + (uint)(*fmt - '0'); + } + return fmt; +} + +/** + Calculates print width or index of positional argument + + @param fmt processed string + @param have_longlong TRUE if longlong is required + + @retval + string position right after modifier symbol +*/ + +static const char *check_longlong(const char *fmt, uint *have_longlong) +{ + *have_longlong= 0; + if (*fmt == 'l') + { + fmt++; + if (*fmt != 'l') + *have_longlong= (sizeof(long) == sizeof(longlong)); + else + { + fmt++; + *have_longlong= 1; + } + } + else if (*fmt == 'z') + { + fmt++; + *have_longlong= (sizeof(size_t) == sizeof(longlong)); + } + return fmt; +} + + +/** + Returns escaped string + + @param cs string charset + @param to buffer where escaped string will be placed + @param end end of buffer + @param par string to escape + @param par_len string length + @param quote_char character for quoting + + @retval + position in buffer which points on the end of escaped string +*/ + +static char *backtick_string(CHARSET_INFO *cs, char *to, char *end, + char *par, size_t par_len, char quote_char) +{ + uint char_len; + char *start= to; + char *par_end= par + par_len; + size_t buff_length= (size_t) (end - to); + + if (buff_length <= par_len) + goto err; + *start++= quote_char; + + for ( ; par < par_end; par+= char_len) + { + uchar c= *(uchar *) par; + if (!(char_len= my_mbcharlen(cs, c))) + char_len= 1; + if (char_len == 1 && c == (uchar) quote_char ) + { + if (start + 1 >= end) + goto err; + *start++= quote_char; + } + if (start + char_len >= end) + goto err; + start= strnmov(start, par, char_len); + } - RETURN + if (start + 1 >= end) + goto err; + *start++= quote_char; + return start; + +err: + *to='\0'; + return to; +} + + +/** + Prints string argument +*/ + +static char *process_str_arg(CHARSET_INFO *cs, char *to, char *end, + size_t width, char *par, uint print_type) +{ + int well_formed_error; + size_t plen, left_len= (size_t) (end - to) + 1; + if (!par) + par = (char*) "(null)"; + + plen= strnlen(par, width); + if (left_len <= plen) + plen = left_len - 1; + plen= cs->cset->well_formed_len(cs, par, par + plen, + width, &well_formed_error); + if (print_type & ESCAPED_ARG) + to= backtick_string(cs, to, end, par, plen, '`'); + else + to= strnmov(to,par,plen); + return to; +} + + +/** + Prints binary argument +*/ + +static char *process_bin_arg(char *to, char *end, size_t width, char *par) +{ + DBUG_ASSERT(to <= end); + if (to + width + 1 > end) + width= end - to - 1; /* sign doesn't matter */ + memmove(to, par, width); + to+= width; + return to; +} + + +/** + Prints integer argument +*/ + +static char *process_int_arg(char *to, char *end, size_t length, + longlong par, char arg_type, uint print_type) +{ + size_t res_length, to_length; + char *store_start= to, *store_end; + char buff[32]; + + if ((to_length= (size_t) (end-to)) < 16 || length) + store_start= buff; + + if (arg_type == 'd') + store_end= longlong10_to_str(par, store_start, -10); + else if (arg_type == 'u') + store_end= longlong10_to_str(par, store_start, 10); + else if (arg_type == 'p') + { + store_start[0]= '0'; + store_start[1]= 'x'; + store_end= longlong2str(par, store_start + 2, 16, 0); + } + else + { + DBUG_ASSERT(arg_type == 'X' || arg_type =='x'); + store_end= longlong2str(par, store_start, 16, (arg_type == 'X')); + } + + if ((res_length= (size_t) (store_end - store_start)) > to_length) + return to; /* num doesn't fit in output */ + /* If %#d syntax was used, we have to pre-zero/pre-space the string */ + if (store_start == buff) + { + length= min(length, to_length); + if (res_length < length) + { + size_t diff= (length- res_length); + bfill(to, diff, (print_type & PREZERO_ARG) ? '0' : ' '); + if (arg_type == 'p' && print_type & PREZERO_ARG) + { + if (diff > 1) + to[1]= 'x'; + else + store_start[0]= 'x'; + store_start[1]= '0'; + } + to+= diff; + } + bmove(to, store_start, res_length); + } + to+= res_length; + return to; +} + + +/** + Procesed positional arguments. + + @param cs string charset + @param to buffer where processed string will be place + @param end end of buffer + @param par format string + @param arg_index arg index of the first occurrence of positional arg + @param ap list of parameters + + @retval + end of buffer where processed string is placed +*/ + +static char *process_args(CHARSET_INFO *cs, char *to, char *end, + const char* fmt, size_t arg_index, va_list ap) +{ + ARGS_INFO args_arr[MAX_ARGS]; + PRINT_INFO print_arr[MAX_PRINT_INFO]; + uint idx= 0, arg_count= arg_index; + +start: + /* Here we are at the beginning of positional argument, right after $ */ + arg_index--; + print_arr[idx].flags= 0; + if (*fmt == '`') + { + print_arr[idx].flags|= ESCAPED_ARG; + fmt++; + } + if (*fmt == '-') + fmt++; + print_arr[idx].length= print_arr[idx].width= 0; + /* Get print length */ + if (*fmt == '*') + { + fmt++; + fmt= get_length(fmt, &print_arr[idx].length, &print_arr[idx].flags); + print_arr[idx].length--; + DBUG_ASSERT(*fmt == '$' && print_arr[idx].length < MAX_ARGS); + args_arr[print_arr[idx].length].arg_type= 'd'; + print_arr[idx].flags|= LENGTH_ARG; + arg_count= max(arg_count, print_arr[idx].length + 1); + fmt++; + } + else + fmt= get_length(fmt, &print_arr[idx].length, &print_arr[idx].flags); + + if (*fmt == '.') + { + fmt++; + /* Get print width */ + if (*fmt == '*') + { + fmt++; + fmt= get_width(fmt, &print_arr[idx].width); + print_arr[idx].width--; + DBUG_ASSERT(*fmt == '$' && print_arr[idx].width < MAX_ARGS); + args_arr[print_arr[idx].width].arg_type= 'd'; + print_arr[idx].flags|= WIDTH_ARG; + arg_count= max(arg_count, print_arr[idx].width + 1); + fmt++; + } + else + fmt= get_width(fmt, &print_arr[idx].width); + } + else + print_arr[idx].width= SIZE_T_MAX; + + fmt= check_longlong(fmt, &args_arr[arg_index].have_longlong); + if (*fmt == 'p') + args_arr[arg_index].have_longlong= (sizeof(void *) == sizeof(longlong)); + args_arr[arg_index].arg_type= print_arr[idx].arg_type= *fmt; + + print_arr[idx].arg_idx= arg_index; + print_arr[idx].begin= ++fmt; + + while (*fmt && *fmt != '%') + fmt++; + + if (!*fmt) /* End of format string */ + { + uint i; + print_arr[idx].end= fmt; + /* Obtain parameters from the list */ + for (i= 0 ; i < arg_count; i++) + { + switch (args_arr[i].arg_type) { + case 's': + case 'b': + args_arr[i].str_arg= va_arg(ap, char *); + break; + case 'f': + case 'g': + args_arr[i].double_arg= va_arg(ap, double); + break; + case 'd': + case 'u': + case 'x': + case 'X': + case 'p': + if (args_arr[i].have_longlong) + args_arr[i].longlong_arg= va_arg(ap,longlong); + else if (args_arr[i].arg_type == 'd') + args_arr[i].longlong_arg= va_arg(ap, int); + else + args_arr[i].longlong_arg= va_arg(ap, uint); + break; + case 'c': + args_arr[i].longlong_arg= va_arg(ap, int); + break; + default: + DBUG_ASSERT(0); + } + } + /* Print result string */ + for (i= 0; i <= idx; i++) + { + uint width= 0, length= 0; + switch (print_arr[i].arg_type) { + case 's': + { + char *par= args_arr[print_arr[i].arg_idx].str_arg; + width= ((print_arr[i].flags & WIDTH_ARG) ? + (uint) args_arr[print_arr[i].width].longlong_arg : + (uint) print_arr[i].width); + to= process_str_arg(cs, to, end, width, par, print_arr[i].flags); + break; + } + case 'b': + { + char *par = args_arr[print_arr[i].arg_idx].str_arg; + width= ((print_arr[i].flags & WIDTH_ARG) ? + (uint) args_arr[print_arr[i].width].longlong_arg : + (uint) print_arr[i].width); + to= process_bin_arg(to, end, width, par); + break; + } + case 'c': + { + if (to == end) + break; + *to++= (char) args_arr[print_arr[i].arg_idx].longlong_arg; + break; + } + case 'd': + case 'u': + case 'x': + case 'X': + case 'p': + { + /* Integer parameter */ + longlong larg; + length= (int) ((print_arr[i].flags & LENGTH_ARG) ? + args_arr[print_arr[i].length].longlong_arg : + (longlong) print_arr[i].length); + + if (args_arr[print_arr[i].arg_idx].have_longlong) + larg = args_arr[print_arr[i].arg_idx].longlong_arg; + else if (print_arr[i].arg_type == 'd') + larg = (int) args_arr[print_arr[i].arg_idx].longlong_arg; + else + larg= (uint) args_arr[print_arr[i].arg_idx].longlong_arg; + + to= process_int_arg(to, end, length, larg, print_arr[i].arg_type, + print_arr[i].flags); + break; + } + default: + break; + } + + if (to == end) + break; + + length= min(end - to , print_arr[i].end - print_arr[i].begin); + if (to + length < end) + length++; + to= strnmov(to, print_arr[i].begin, length); + } + DBUG_ASSERT(to <= end); + *to='\0'; /* End of errmessage */ + return to; + } + else + { + /* Process next positional argument*/ + DBUG_ASSERT(*fmt == '%'); + print_arr[idx].end= fmt - 1; + idx++; + fmt++; + arg_index= 0; + fmt= get_width(fmt, &arg_index); + DBUG_ASSERT(*fmt == '$'); + fmt++; + arg_count= max(arg_count, arg_index); + goto start; + } + DBUG_ASSERT(0); + return 0; +} + + + +/** + Produces output string according to a format string + + See the detailed documentation around my_snprintf_service_st + + @param cs string charset + @param to buffer where processed string will be place + @param n size of buffer + @param par format string + @param ap list of parameters + + @retval length of result string */ -size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) +size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n, + const char* fmt, va_list ap) { char *start=to, *end=to+n-1; size_t length, width; - uint pre_zero, have_long; + uint print_type, have_longlong; for (; *fmt ; fmt++) { if (*fmt != '%') { - if (to == end) /* End of buffer */ + if (to == end) /* End of buffer */ break; - *to++= *fmt; /* Copy ordinary char */ + *to++= *fmt; /* Copy ordinary char */ continue; } fmt++; /* skip '%' */ - /* Read max fill size (only used with %d and %u) */ - if (*fmt == '-') - fmt++; + length= width= 0; - pre_zero= have_long= 0; - if (*fmt == '*') + print_type= 0; + + /* Read max fill size (only used with %d and %u) */ + if (my_isdigit(&my_charset_latin1, *fmt)) { - fmt++; - length= va_arg(ap, int); + fmt= get_length(fmt, &length, &print_type); + if (*fmt == '$') + { + to= process_args(cs, to, end, (fmt+1), length, ap); + return (size_t) (to - start); + } } else - for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) + { + if (*fmt == '`') + { + print_type|= ESCAPED_ARG; + fmt++; + } + if (*fmt == '-') + fmt++; + if (*fmt == '*') { - length= length * 10 + (uint)(*fmt - '0'); - if (!length) - pre_zero= 1; /* first digit was 0 */ + fmt++; + length= va_arg(ap, int); } + else + fmt= get_length(fmt, &length, &print_type); + } + if (*fmt == '.') { fmt++; @@ -83,75 +555,41 @@ size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) width= va_arg(ap, int); } else - for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) - width= width * 10 + (uint)(*fmt - '0'); + fmt= get_width(fmt, &width); } else - width= ~0; - if (*fmt == 'l') - { - fmt++; - have_long= 1; - } + width= SIZE_T_MAX; + + fmt= check_longlong(fmt, &have_longlong); + if (*fmt == 's') /* String parameter */ { - reg2 char *par = va_arg(ap, char *); - size_t plen,left_len = (size_t) (end - to) + 1; - if (!par) par = (char*)"(null)"; - plen= (uint) strnlen(par, width); - if (left_len <= plen) - plen = left_len - 1; - to=strnmov(to,par,plen); + reg2 char *par= va_arg(ap, char *); + to= process_str_arg(cs, to, end, width, par, print_type); continue; } else if (*fmt == 'b') /* Buffer parameter */ { char *par = va_arg(ap, char *); - DBUG_ASSERT(to <= end); - if (to + abs(width) + 1 > end) - width= (uint) (end - to - 1); /* sign doesn't matter */ - memmove(to, par, abs(width)); - to+= width; + to= process_bin_arg(to, end, width, par); continue; } - else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */ + else if (*fmt == 'd' || *fmt == 'u' || *fmt == 'x' || *fmt == 'X' || + *fmt == 'p') { - register long larg; - size_t res_length, to_length; - char *store_start= to, *store_end; - char buff[32]; - - if ((to_length= (size_t) (end-to)) < 16 || length) - store_start= buff; - if (have_long) - larg = va_arg(ap, long); - else - if (*fmt == 'd') - larg = va_arg(ap, int); - else - larg= (long) (uint) va_arg(ap, int); - if (*fmt == 'd') - store_end= int10_to_str(larg, store_start, -10); + /* Integer parameter */ + longlong larg; + if (*fmt == 'p') + have_longlong= (sizeof(void *) == sizeof(longlong)); + + if (have_longlong) + larg = va_arg(ap,longlong); + else if (*fmt == 'd') + larg = va_arg(ap, int); else - if (*fmt== 'u') - store_end= int10_to_str(larg, store_start, 10); - else - store_end= int2str(larg, store_start, 16, 0); - if ((res_length= (size_t) (store_end - store_start)) > to_length) - break; /* num doesn't fit in output */ - /* If %#d syntax was used, we have to pre-zero/pre-space the string */ - if (store_start == buff) - { - length= min(length, to_length); - if (res_length < length) - { - size_t diff= (length- res_length); - bfill(to, diff, pre_zero ? '0' : ' '); - to+= diff; - } - bmove(to, store_start, res_length); - } - to+= res_length; + larg= va_arg(ap, uint); + + to= process_int_arg(to, end, length, larg, *fmt, print_type); continue; } else if (*fmt == 'c') /* Character parameter */ @@ -175,6 +613,19 @@ size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) } +/* + Limited snprintf() implementations + + exported to plugins as a service, see the detailed documentation + around my_snprintf_service_st +*/ + +size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) +{ + return my_vsnprintf_ex(&my_charset_latin1, to, n, fmt, ap); +} + + size_t my_snprintf(char* to, size_t n, const char* fmt, ...) { size_t result; @@ -185,42 +636,3 @@ size_t my_snprintf(char* to, size_t n, const char* fmt, ...) return result; } -#ifdef MAIN -#define OVERRUN_SENTRY 250 -static void my_printf(const char * fmt, ...) -{ - char buf[33]; - int n; - va_list ar; - va_start(ar, fmt); - buf[sizeof(buf)-1]=OVERRUN_SENTRY; - n = my_vsnprintf(buf, sizeof(buf)-1,fmt, ar); - printf(buf); - printf("n=%d, strlen=%d\n", n, strlen(buf)); - if ((uchar) buf[sizeof(buf)-1] != OVERRUN_SENTRY) - { - fprintf(stderr, "Buffer overrun\n"); - abort(); - } - va_end(ar); -} - - -int main() -{ - - my_printf("Hello\n"); - my_printf("Hello int, %d\n", 1); - my_printf("Hello string '%s'\n", "I am a string"); - my_printf("Hello hack hack hack hack hack hack hack %d\n", 1); - my_printf("Hello %d hack %d\n", 1, 4); - my_printf("Hello %d hack hack hack hack hack %d\n", 1, 4); - my_printf("Hello '%s' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n", "hack"); - my_printf("Hello hhhhhhhhhhhhhh %d sssssssssssssss\n", 1); - my_printf("Hello %u\n", 1); - my_printf("Hex: %lx '%6lx'\n", 32, 65); - my_printf("conn %ld to: '%-.64s' user: '%-.32s' host:\ - `%-.64s' (%-.64s)", 1, 0,0,0,0); - return 0; -} -#endif diff --git a/support-files/compiler_warnings.supp b/support-files/compiler_warnings.supp index a56c39b51a0..0a0f08eac16 100644 --- a/support-files/compiler_warnings.supp +++ b/support-files/compiler_warnings.supp @@ -126,7 +126,7 @@ signal\.c : .*unused parameter.* .*/ndb/.* : .*defined but not used.* # -# Maria warning that is ok in debug builds +# Aria warning that is ok in debug builds # storage/maria/ma_pagecache.c: .*'info_check_pin' defined but not used @@ -183,3 +183,10 @@ ctype-simple\.c : .*unary minus operator applied to unsigned type, result still regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000 storage/xtradb/dict/dict0dict\.c : passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500 + +# +# Strange things from autoconf that is probably safe to ignore +# + +configure.in : warning: AC_LANG_CONFTEST: no AC_LANG_SOURCE call detected in body +configure.in : config/ac-macros/character_sets.m4.*prefer named diversions diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 30afebb46bd..967ebae2e22 100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -20,9 +20,9 @@ ADD_DEFINITIONS("-DMYSQL_CLIENT") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) ADD_EXECUTABLE(mysql_client_test mysql_client_test.c ../mysys/my_memmem.c) -TARGET_LINK_LIBRARIES(mysql_client_test mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(mysql_client_test mysqlclient wsock32) ADD_EXECUTABLE(bug25714 bug25714.c) -TARGET_LINK_LIBRARIES(bug25714 mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(bug25714 mysqlclient wsock32) -INSTALL(TARGETS mysql_client_test bug25714 DESTINATION bin COMPONENT runtime) +INSTALL(TARGETS mysql_client_test DESTINATION bin COMPONENT Test) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index a67b5a80cfb..6c1b638ce81 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -35,6 +35,7 @@ #include <m_string.h> #include <mysqld_error.h> #include <my_handler.h> +#include <sql_common.h> #define VER "2.1" #define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */ @@ -18642,7 +18643,8 @@ static void test_bug13001491() Read and parse arguments and MySQL options from my.cnf */ -static const char *client_test_load_default_groups[]= { "client", 0 }; +static const char *client_test_load_default_groups[]= +{ "client", "client-server", "client-mariadb", 0 }; static char **defaults_argv; static struct my_option client_test_long_options[] = diff --git a/tests/thread_test.c b/tests/thread_test.c index 8e1c58ebbec..0944cbc0970 100644 --- a/tests/thread_test.c +++ b/tests/thread_test.c @@ -123,7 +123,8 @@ static struct my_option my_long_options[] = }; -static const char *load_default_groups[]= { "client",0 }; +static const char *load_default_groups[]= +{ "client", "client-server", "client-mariadb", 0 }; static void usage() { diff --git a/unittest/mysys/Makefile.am b/unittest/mysys/Makefile.am index be01e7da217..250aadfd2e8 100644 --- a/unittest/mysys/Makefile.am +++ b/unittest/mysys/Makefile.am @@ -24,4 +24,5 @@ LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ $(top_builddir)/strings/libmystrings.a EXTRA_DIST = CMakeLists.txt -noinst_PROGRAMS = bitmap-t base64-t my_atomic-t lf-t waiting_threads-t +noinst_PROGRAMS = bitmap-t base64-t my_atomic-t lf-t waiting_threads-t \ + my_vsnprintf-t diff --git a/unittest/mysys/my_vsnprintf-t.c b/unittest/mysys/my_vsnprintf-t.c new file mode 100644 index 00000000000..f3a6b5700da --- /dev/null +++ b/unittest/mysys/my_vsnprintf-t.c @@ -0,0 +1,155 @@ +/* Copyright (C) 2003 MySQL AB + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <my_global.h> +#include <m_string.h> +#include <tap.h> + +char buf[1024]; /* let's hope that's enough */ + +void test1(const char *res, const char *fmt, ...) +{ + va_list args; + size_t len; + va_start(args,fmt); + len= my_vsnprintf(buf, sizeof(buf)-1, fmt, args); + va_end(args); + ok(strlen(res) == len && strcmp(buf, res) == 0, "\"%s\"", buf); +} + +int main(void) +{ + plan(47); + + test1("Constant string", + "Constant string"); + + test1("Format specifier s works", + "Format specifier s %s", "works"); + test1("Format specifier b works (mysql extension)", + "Format specifier b %.5b (mysql extension)", "works!!!"); + test1("Format specifier c !", + "Format specifier c %c", '!'); + test1("Format specifier d 1", + "Format specifier d %d", 1); + test1("Format specifier u 2", + "Format specifier u %u", 2); + test1("Format specifier x a", + "Format specifier x %x", 10); + test1("Format specifier X B", + "Format specifier X %X", 11); + test1("Format specifier p 0x5", + "Format specifier p %p", 5); + + test1("Flag '-' is ignored < 1>", + "Flag '-' is ignored <%-4d>", 1); + test1("Flag '0' works <0006>", + "Flag '0' works <%04d>", 6); + + test1("Width is ignored for strings <x> <y>", + "Width is ignored for strings <%04s> <%5s>", "x", "y"); + + test1("Precision works for strings <abcde>", + "Precision works for strings <%.5s>", "abcdef!"); + + test1("Flag '`' (backtick) works: `abcd` `op``q` (mysql extension)", + "Flag '`' (backtick) works: %`s %`.4s (mysql extension)", + "abcd", "op`qrst"); + + test1("Length modifiers work: 1 * -1 * 2 * 3", + "Length modifiers work: %d * %ld * %lld * %zd", 1, -1L, 2LL, (size_t)3); + + test1("(null) pointer is fine", + "%s pointer is fine", NULL); + + test1("Positional arguments work: on the dark side they are", + "Positional arguments work: %3$s %1$s %2$s", + "they", "are", "on the dark side"); + + test1("Asterisk '*' as a width works: < 4>", + "Asterisk '*' as a width works: <%*d>", 5, 4); + + test1("Asterisk '*' as a precision works: <qwerty>", + "Asterisk '*' as a precision works: <%.*s>", 6, "qwertyuiop"); + + test1("Positional arguments for a width: < 4>", + "Positional arguments for a width: <%1$*2$d>", 4, 5); + + test1("Positional arguments for a precision: <qwerty>", + "Positional arguments for a precision: <%1$.*2$s>", "qwertyuiop", 6); + + test1("Positional arguments and a width: <0000ab>", + "Positional arguments and a width: <%1$06x>", 0xab); + + test1("Padding and %p <0x12> <0x034> <0x0000ab> < 0xcd>", + "Padding and %%p <%04p> <%05p> <%08p> <%8p>", 0x12, 0x34, 0xab, 0xcd); + +#if MYSQL_VERSION_ID > 60000 +#error %f/%g tests go here +#endif + + test1("Hello", + "Hello"); + test1("Hello int, 1", + "Hello int, %d", 1); + test1("Hello int, -1", + "Hello int, %d", -1); + test1("Hello string 'I am a string'", + "Hello string '%s'", "I am a string"); + test1("Hello hack hack hack hack hack hack hack 1", + "Hello hack hack hack hack hack hack hack %d", 1); + test1("Hello 1 hack 4", + "Hello %d hack %d", 1, 4); + test1("Hello 1 hack hack hack hack hack 4", + "Hello %d hack hack hack hack hack %d", 1, 4); + test1("Hello 'hack' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", + "Hello '%s' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hack"); + test1("Hello hhhhhhhhhhhhhh 1 sssssssssssssss", + "Hello hhhhhhhhhhhhhh %d sssssssssssssss", 1); + test1("Hello 1", + "Hello %u", 1); + test1("Hello 4294967295", + "Hello %u", -1); + test1("Hex: 20 ' 41'", + "Hex: %lx '%6lx'", 32, 65); + test1("conn 1 to: '(null)' user: '(null)' host: '(null)' ((null))", + "conn %ld to: '%-.64s' user: '%-.32s' host: '%-.64s' (%-.64s)", + 1L, NULL, NULL, NULL, NULL); + test1("Hello string `I am a string`", + "Hello string %`s", "I am a string"); + test1("Hello TEST", + "Hello %05s", "TEST"); + test1("My `Q` test", + "My %1$`-.1s test", "QQQQ"); + test1("My AAAA test done DDDD", + "My %2$s test done %1$s", "DDDD", "AAAA"); + test1("My DDDD test CCCC, DDD", + "My %1$s test %2$s, %1$-.3s", "DDDD", "CCCC"); + test1("My QQQQ test", + "My %1$`-.4b test", "QQQQ"); + test1("My X test", + "My %1$c test", 'X'); + test1("My <0000000010> test1 < a> test2 < A>", + "My <%010d> test1 <%4x> test2 <%4X>", 10, 10, 10); + test1("My <0000000010> test1 < a> test2 < a>", + "My <%1$010d> test1 <%2$4x> test2 <%2$4x>", 10, 10); + test1("My 00010 test", + "My %1$*02$d test", 10, 5); + test1("My `DDDD` test CCCC, `DDD`", + "My %1$`s test %2$s, %1$`-.3s", "DDDD", "CCCC"); + + return exit_status(); +} + diff --git a/unittest/unit.pl b/unittest/unit.pl index 9900f47f374..4eaf4cd2f9b 100644 --- a/unittest/unit.pl +++ b/unittest/unit.pl @@ -103,6 +103,7 @@ sub run_cmd (@) { # Removing the first './' from the file names foreach (@files) { s!^\./!! } $ENV{'HARNESS_PERL_SWITCHES'} .= ' -e "exec @ARGV"'; + $ENV{'HARNESS_OPTIONS'}="j4"; $Test::Harness::Timer = 1; runtests @files; } diff --git a/vio/viosocket.c b/vio/viosocket.c index 381d028d6a0..7f1ef718d96 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -196,6 +196,11 @@ int vio_fastsend(Vio * vio __attribute__((unused))) int r=0; DBUG_ENTER("vio_fastsend"); + if (vio->type == VIO_TYPE_NAMEDPIPE ||vio->type == VIO_TYPE_SHARED_MEMORY) + { + DBUG_RETURN(0); + } + #if defined(IPTOS_THROUGHPUT) { int tos = IPTOS_THROUGHPUT; @@ -231,7 +236,7 @@ int vio_keepalive(Vio* vio, my_bool set_keep_alive) DBUG_ENTER("vio_keepalive"); DBUG_PRINT("enter", ("sd: %d set_keep_alive: %d", vio->sd, (int) set_keep_alive)); - if (vio->type != VIO_TYPE_NAMEDPIPE) + if (vio->type != VIO_TYPE_NAMEDPIPE && vio->type != VIO_TYPE_SHARED_MEMORY) { if (set_keep_alive) opt = 1; diff --git a/win/Makefile.am b/win/Makefile.am index e226f0bcbb3..6f2b92fb5bf 100644 --- a/win/Makefile.am +++ b/win/Makefile.am @@ -18,4 +18,43 @@ EXTRA_DIST = build-vs71.bat build-vs8.bat build-vs8_x64.bat build-vs9.bat \ build-vs9_x64.bat configure.js README mysql_manifest.cmake \ create_manifest.js create_def_file.js build-nmake.bat \ - build-nmake-x64.bat configure-mariadb.sh make_mariadb_win_dist + build-nmake-x64.bat configure-mariadb.sh make_mariadb_win_dist \ + build-vs10.bat build-vs10_x64.bat \ + cmake/cmake_parse_arguments.cmake \ + cmake/cpack_source_ignore_files.cmake \ + cmake/create_initial_db.cmake.in \ + cmake/install_layout.cmake \ + cmake/install_macros.cmake \ + cmake/mysql_add_executable.cmake \ + cmake/mysql_version.cmake \ + cmake/package_name.cmake \ + cmake/versioninfo.rc.in \ + cmake/dummy.in \ + packaging/CMakeLists.txt \ + packaging/CPackWixConfig.cmake \ + packaging/create_msi.cmake.in \ + packaging/custom_ui.wxs \ + packaging/extra.wxs.in \ + packaging/COPYING.rtf \ + packaging/mysql_server.wxs.in \ + packaging/ca/CMakeLists.txt \ + packaging/ca/CustomAction.cpp \ + packaging/ca/CustomAction.def \ + packaging/ca/CustomAction.rc \ + packaging/WixUIBannerBmp.jpg \ + packaging/WixUIDialogBmp.jpg \ + packaging/heidisql.cmake \ + packaging/heidisql.wxi.in \ + packaging/heidisql_feature.wxi.in\ + upgrade_wizard/resource.h \ + upgrade_wizard/stdafx.h \ + upgrade_wizard/targetver.h \ + upgrade_wizard/upgrade.cpp \ + upgrade_wizard/upgrade.h \ + upgrade_wizard/upgrade.rc \ + upgrade_wizard/upgradeDlg.cpp \ + upgrade_wizard/upgradeDlg.h \ + upgrade_wizard/upgrade_wizard.exe.manifest \ + upgrade_wizard/CMakeLists.txt \ + upgrade_wizard/res/upgrade.ico \ + upgrade_wizard/res/upgrade.rc2 diff --git a/win/build-vs10.bat b/win/build-vs10.bat index adda0651246..b67ac7e9753 100644 --- a/win/build-vs10.bat +++ b/win/build-vs10.bat @@ -1,6 +1,6 @@ @echo off -REM Copyright (c) 2011, Oracle and/or its affiliates +REM Copyright (C) 2010 Monty Program AB REM REM This program is free software; you can redistribute it and/or modify REM it under the terms of the GNU General Public License as published by diff --git a/win/build-vs10_x64.bat b/win/build-vs10_x64.bat index 0d1424930fc..f84e826ac65 100644 --- a/win/build-vs10_x64.bat +++ b/win/build-vs10_x64.bat @@ -1,6 +1,6 @@ @echo off -REM Copyright (c) 2011, Oracle and/or its affiliates +REM Copyright (C) 2010 Monty Program AB REM REM This program is free software; you can redistribute it and/or modify REM it under the terms of the GNU General Public License as published by diff --git a/win/build_maria_release.bat b/win/build_maria_release.bat new file mode 100644 index 00000000000..c5b1bb915c2 --- /dev/null +++ b/win/build_maria_release.bat @@ -0,0 +1,47 @@ +set build_64_bit=
+set build_msi=
+set generator=
+set scriptdir=%~dp0
+
+:: Process all the arguments from the command line
+::
+:process_arguments
+ if "%~1"=="" goto :do_work
+ if "%~1"=="-h" goto :help
+ if "%~1"=="-msi" set build_msi=1
+ if "%~1"=="-G" set generator=-G "%~2"
+ shift
+ goto :process_arguments
+
+:help
+ echo "build_maria_release [-h] [-msi] [-G <Generator>]"
+
+:die
+ echo error occured.
+ popd
+ exit /b 1
+
+:do_work
+:: We're doing out-of-source build to ensure nobody has broken it:)
+
+ pushd %scriptdir%
+ cd ..
+ rd /s /q xxx
+ mkdir xxx
+ cd xxx
+
+ cmake .. -DWITH_EMBEDDED_SERVER=1 %generator%
+ if %ERRORLEVEL% NEQ 0 goto :die
+ cmake --build . --config Debug
+ if %ERRORLEVEL% NEQ 0 goto :die
+ cmake --build . --config RelWithDebInfo --target package
+ if %ERRORLEVEL% NEQ 0 goto :die
+
+
+ if "%build_msi%"=="1" (
+ cmake --build . --config RelWithDebInfo --target win\packaging\msi
+ if %ERRORLEVEL% NEQ 0 goto :die
+ )
+ xcopy /y *.zip ..
+ xcopy /y *.msi ..
+ popd
\ No newline at end of file diff --git a/win/cmake/cmake_parse_arguments.cmake b/win/cmake/cmake_parse_arguments.cmake new file mode 100644 index 00000000000..db540ae9020 --- /dev/null +++ b/win/cmake/cmake_parse_arguments.cmake @@ -0,0 +1,47 @@ + +# Copyright (C) 2007 MySQL AB, 2009 Sun Microsystems,Inc +# +# 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 + +# Handy macro to parse macro arguments +MACRO(MYSQL_PARSE_ARGUMENTS prefix arg_names option_names) + SET(DEFAULT_ARGS) + FOREACH(arg_name ${arg_names}) + SET(${prefix}_${arg_name}) + ENDFOREACH(arg_name) + FOREACH(option ${option_names}) + SET(${prefix}_${option} FALSE) + ENDFOREACH(option) + + SET(current_arg_name DEFAULT_ARGS) + SET(current_arg_list) + FOREACH(arg ${ARGN}) + SET(larg_names ${arg_names}) + LIST(FIND larg_names "${arg}" is_arg_name) + IF (is_arg_name GREATER -1) + SET(${prefix}_${current_arg_name} ${current_arg_list}) + SET(current_arg_name ${arg}) + SET(current_arg_list) + ELSE (is_arg_name GREATER -1) + SET(loption_names ${option_names}) + LIST(FIND loption_names "${arg}" is_option) + IF (is_option GREATER -1) + SET(${prefix}_${arg} TRUE) + ELSE (is_option GREATER -1) + SET(current_arg_list ${current_arg_list} ${arg}) + ENDIF (is_option GREATER -1) + ENDIF (is_arg_name GREATER -1) + ENDFOREACH(arg) + SET(${prefix}_${current_arg_name} ${current_arg_list}) +ENDMACRO()
\ No newline at end of file diff --git a/win/cmake/cpack_source_ignore_files.cmake b/win/cmake/cpack_source_ignore_files.cmake new file mode 100644 index 00000000000..5eef20dccc6 --- /dev/null +++ b/win/cmake/cpack_source_ignore_files.cmake @@ -0,0 +1,40 @@ +SET(CPACK_SOURCE_IGNORE_FILES +\\\\.bzr/ +\\\\.bzr-mysql +\\\\.bzrignore +CMakeCache\\\\.txt +cmake_dist\\\\.cmake +CPackSourceConfig\\\\.cmake +CPackConfig.cmake +/cmake_install\\\\.cmake +/CTestTestfile\\\\.cmake +/CMakeFiles/ +/version_resources/ +/_CPack_Packages/ +$\\\\.gz +$\\\\.zip +/CMakeFiles/ +/version_resources/ +/_CPack_Packages/ +scripts/make_binary_distribution$ +scripts/msql2mysql$ +scripts/mysql_config$ +scripts/mysql_convert_table_format$ +scripts/mysql_find_rows$ +scripts/mysql_fix_extensions$ +scripts/mysql_install_db$ +scripts/mysql_secure_installation$ +scripts/mysql_setpermission$ +scripts/mysql_zap$ +scripts/mysqlaccess$ +scripts/mysqld_multi$ +scripts/mysqld_safe$ +scripts/mysqldumpslow$ +scripts/mysqlhotcopy$ +Makefile$ +include/config\\\\.h$ +include/my_config\\\\.h$ +/autom4te\\\\.cache/ +errmsg\\\\.sys$ +# +) diff --git a/win/cmake/create_initial_db.cmake.in b/win/cmake/create_initial_db.cmake.in new file mode 100644 index 00000000000..d4721b7bac4 --- /dev/null +++ b/win/cmake/create_initial_db.cmake.in @@ -0,0 +1,85 @@ +# Copyright (C) 2009 Sun Microsystems, Inc +# +# 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 + +# This script creates initial database for packaging on Windows +SET(CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@") +SET(CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@") +SET(MYSQLD_EXECUTABLE "@MYSQLD_EXECUTABLE@") +SET(CMAKE_CFG_INTDIR "@CMAKE_CFG_INTDIR@") +SET(WIN32 "@WIN32@") +# Force Visual Studio to output to stdout +IF(ENV{VS_UNICODE_OUTPUT}) + SET ($ENV{VS_UNICODE_OUTPUT}) +ENDIF() +IF(CMAKE_CFG_INTDIR AND CONFIG) + #Resolve build configuration variables + STRING(REPLACE "${CMAKE_CFG_INTDIR}" ${CONFIG} MYSQLD_EXECUTABLE + "${MYSQLD_EXECUTABLE}") +ENDIF() + +# Create bootstrapper SQL script +FILE(WRITE bootstrap.sql "use mysql;\n" ) +FOREACH(FILENAME mysql_system_tables.sql mysql_system_tables_data.sql) + FILE(STRINGS ${CMAKE_SOURCE_DIR}/scripts/${FILENAME} CONTENTS) + FOREACH(STR ${CONTENTS}) + IF(NOT STR MATCHES "@current_hostname") + FILE(APPEND bootstrap.sql "${STR}\n") + ENDIF() + ENDFOREACH() +ENDFOREACH() +FILE(READ ${CMAKE_SOURCE_DIR}/scripts/fill_help_tables.sql CONTENTS) +FILE(APPEND bootstrap.sql ${CONTENTS}) + + +FILE(REMOVE_RECURSE mysql) +MAKE_DIRECTORY(mysql) +IF(WIN32) + SET(CONSOLE --console) +ENDIF() + +SET(BOOTSTRAP_COMMAND + ${MYSQLD_EXECUTABLE} + --no-defaults + ${CONSOLE} + --bootstrap + --language=${CMAKE_CURRENT_BINARY_DIR}/share/english + --basedir=. + --datadir=. + --tmpdir=. + --default-storage-engine=MyISAM + --loose-skip-innodb + --loose-skip-pbxt + --loose-skip-ndbcluster + --max_allowed_packet=8M + --net_buffer_length=16K +) + +GET_FILENAME_COMPONENT(CWD . ABSOLUTE) +EXECUTE_PROCESS( + COMMAND "@CMAKE_COMMAND@" -E echo Executing ${BOOTSTRAP_COMMAND} +) +EXECUTE_PROCESS ( + COMMAND "@CMAKE_COMMAND@" -E echo input file bootstrap.sql, current directory ${CWD} +) +EXECUTE_PROCESS ( + COMMAND ${BOOTSTRAP_COMMAND} INPUT_FILE bootstrap.sql OUTPUT_VARIABLE OUT + ERROR_VARIABLE ERR + RESULT_VARIABLE RESULT + ) + +IF(NOT RESULT EQUAL 0) + MESSAGE(FATAL_ERROR "Could not create initial database \n ${OUT} \n ${ERR}") +ENDIF() + diff --git a/win/cmake/dummy.in b/win/cmake/dummy.in new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/win/cmake/dummy.in diff --git a/win/cmake/install_layout.cmake b/win/cmake/install_layout.cmake new file mode 100644 index 00000000000..601e208d96d --- /dev/null +++ b/win/cmake/install_layout.cmake @@ -0,0 +1,223 @@ +# Copyright (C) 2010 Sun Microsystems, Inc +# +# 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 + +# The purpose of this file is to set the default installation layout. +# +# The current choices of installation layout are: +# +# STANDALONE +# Build with prefix=/usr/local/mysql, create tarball with install prefix="." +# and relative links. Windows zip uses the same tarball layout but without +# the build prefix. +# +# RPM +# Build as per default RPM layout, with prefix=/usr +# +# DEB +# Build as per STANDALONE, prefix=/opt/mysql/server-$major.$minor +# +# SVR4 +# Solaris package layout suitable for pkg* tools, prefix=/opt/mysql/mysql +# +# To force a directory layout, use -DINSTALL_LAYOUT=<layout>. +# +# The default is STANDALONE. +# +# There is the possibility to further fine-tune installation directories. +# Several variables can be overwritten: +# +# - INSTALL_BINDIR (directory with client executables and scripts) +# - INSTALL_SBINDIR (directory with mysqld) +# - INSTALL_SCRIPTDIR (several scripts, rarely used) +# +# - INSTALL_LIBDIR (directory with client end embedded libraries) +# - INSTALL_PLUGINDIR (directory for plugins) +# +# - INSTALL_INCLUDEDIR (directory for MySQL headers) +# +# - INSTALL_DOCDIR (documentation) +# - INSTALL_DOCREADMEDIR (readme and similar) +# - INSTALL_MANDIR (man pages) +# - INSTALL_INFODIR (info pages) +# +# - INSTALL_SHAREDIR (location of aclocal/mysql.m4) +# - INSTALL_MYSQLSHAREDIR (MySQL character sets and localized error messages) +# - INSTALL_MYSQLTESTDIR (mysql-test) +# - INSTALL_SQLBENCHDIR (sql-bench) +# - INSTALL_SUPPORTFILESDIR (various extra support files) +# +# - INSTALL_MYSQLDATADIR (data directory) +# +# When changing this page, _please_ do not forget to update public Wiki +# http://forge.mysql.com/wiki/CMake#Fine-tuning_installation_paths + +IF(NOT INSTALL_LAYOUT) + SET(DEFAULT_INSTALL_LAYOUT "STANDALONE") +ENDIF() + +SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}" +CACHE STRING "Installation directory layout. Options are: STANDALONE (as in zip or tar.gz installer), RPM, DEB, SVR4") + +IF(UNIX) + IF(INSTALL_LAYOUT MATCHES "RPM") + SET(default_prefix "/usr") + ELSEIF(INSTALL_LAYOUT MATCHES "DEB") + SET(default_prefix "/opt/mysql/server-${MYSQL_BASE_VERSION}") + # This is required to avoid "cpack -GDEB" default of prefix=/usr + SET(CPACK_SET_DESTDIR ON) + ELSEIF(INSTALL_LAYOUT MATCHES "SVR4") + SET(default_prefix "/opt/mysql/mysql") + ELSE() + SET(default_prefix "/usr/local/mysql") + ENDIF() + IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + SET(CMAKE_INSTALL_PREFIX ${default_prefix} + CACHE PATH "install prefix" FORCE) + ENDIF() + SET(VALID_INSTALL_LAYOUTS "RPM" "STANDALONE" "DEB" "SVR4") + LIST(FIND VALID_INSTALL_LAYOUTS "${INSTALL_LAYOUT}" ind) + IF(ind EQUAL -1) + MESSAGE(FATAL_ERROR "Invalid INSTALL_LAYOUT parameter:${INSTALL_LAYOUT}." + " Choose between ${VALID_INSTALL_LAYOUTS}" ) + ENDIF() + + SET(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/etc" + CACHE PATH "config directory (for my.cnf)") + MARK_AS_ADVANCED(SYSCONFDIR) +ENDIF() + +# +# STANDALONE layout +# +SET(INSTALL_BINDIR_STANDALONE "bin") +SET(INSTALL_SBINDIR_STANDALONE "bin") +SET(INSTALL_SCRIPTDIR_STANDALONE "scripts") +# +SET(INSTALL_LIBDIR_STANDALONE "lib") +SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin") +# +SET(INSTALL_INCLUDEDIR_STANDALONE "include") +# +SET(INSTALL_DOCDIR_STANDALONE "docs") +SET(INSTALL_DOCREADMEDIR_STANDALONE ".") +SET(INSTALL_MANDIR_STANDALONE "man") +SET(INSTALL_INFODIR_STANDALONE "docs") +# +SET(INSTALL_SHAREDIR_STANDALONE "share") +SET(INSTALL_MYSQLSHAREDIR_STANDALONE "share") +SET(INSTALL_MYSQLTESTDIR_STANDALONE "mysql-test") +SET(INSTALL_SQLBENCHDIR_STANDALONE ".") +SET(INSTALL_SUPPORTFILESDIR_STANDALONE "support-files") +# +SET(INSTALL_MYSQLDATADIR_STANDALONE "data") + +# +# RPM layout +# +SET(INSTALL_BINDIR_RPM "bin") +SET(INSTALL_SBINDIR_RPM "sbin") +SET(INSTALL_SCRIPTDIR_RPM "bin") +# +IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + SET(INSTALL_LIBDIR_RPM "lib64") + SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin") +ELSE() + SET(INSTALL_LIBDIR_RPM "lib") + SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin") +ENDIF() +# +SET(INSTALL_INCLUDEDIR_RPM "include/mysql") +# +#SET(INSTALL_DOCDIR_RPM unset - installed directly by RPM) +#SET(INSTALL_DOCREADMEDIR_RPM unset - installed directly by RPM) +SET(INSTALL_INFODIR_RPM "share/info") +SET(INSTALL_MANDIR_RPM "share/man") +# +SET(INSTALL_SHAREDIR_RPM "share") +SET(INSTALL_MYSQLSHAREDIR_RPM "share/mysql") +SET(INSTALL_MYSQLTESTDIR_RPM "share/mysql-test") +SET(INSTALL_SQLBENCHDIR_RPM "") +SET(INSTALL_SUPPORTFILESDIR_RPM "share/mysql") +# +SET(INSTALL_MYSQLDATADIR_RPM "/var/lib/mysql") + +# +# DEB layout +# +SET(INSTALL_BINDIR_DEB "bin") +SET(INSTALL_SBINDIR_DEB "bin") +SET(INSTALL_SCRIPTDIR_DEB "scripts") +# +SET(INSTALL_LIBDIR_DEB "lib") +SET(INSTALL_PLUGINDIR_DEB "lib/plugin") +# +SET(INSTALL_INCLUDEDIR_DEB "include") +# +SET(INSTALL_DOCDIR_DEB "docs") +SET(INSTALL_DOCREADMEDIR_DEB ".") +SET(INSTALL_MANDIR_DEB "man") +SET(INSTALL_INFODIR_DEB "docs") +# +SET(INSTALL_SHAREDIR_DEB "share") +SET(INSTALL_MYSQLSHAREDIR_DEB "share") +SET(INSTALL_MYSQLTESTDIR_DEB "mysql-test") +SET(INSTALL_SQLBENCHDIR_DEB ".") +SET(INSTALL_SUPPORTFILESDIR_DEB "support-files") +# +SET(INSTALL_MYSQLDATADIR_DEB "data") + +# +# SVR4 layout +# +SET(INSTALL_BINDIR_SVR4 "bin") +SET(INSTALL_SBINDIR_SVR4 "bin") +SET(INSTALL_SCRIPTDIR_SVR4 "scripts") +# +SET(INSTALL_LIBDIR_SVR4 "lib") +SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin") +# +SET(INSTALL_INCLUDEDIR_SVR4 "include") +# +SET(INSTALL_DOCDIR_SVR4 "docs") +SET(INSTALL_DOCREADMEDIR_SVR4 ".") +SET(INSTALL_MANDIR_SVR4 "man") +SET(INSTALL_INFODIR_SVR4 "docs") +# +SET(INSTALL_SHAREDIR_SVR4 "share") +SET(INSTALL_MYSQLSHAREDIR_SVR4 "share") +SET(INSTALL_MYSQLTESTDIR_SVR4 "mysql-test") +SET(INSTALL_SQLBENCHDIR_SVR4 ".") +SET(INSTALL_SUPPORTFILESDIR_SVR4 "support-files") +# +SET(INSTALL_MYSQLDATADIR_SVR4 "/var/lib/mysql") + + +# Clear cached variables if install layout was changed +IF(OLD_INSTALL_LAYOUT) + IF(NOT OLD_INSTALL_LAYOUT STREQUAL INSTALL_LAYOUT) + SET(FORCE FORCE) + ENDIF() +ENDIF() +SET(OLD_INSTALL_LAYOUT ${INSTALL_LAYOUT} CACHE INTERNAL "") + +# Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR +# will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE +# layout is chosen) +FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN + INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA) + SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}} + CACHE STRING "${var} installation directory" ${FORCE}) + MARK_AS_ADVANCED(INSTALL_${var}DIR) +ENDFOREACH() diff --git a/win/cmake/install_macros.cmake b/win/cmake/install_macros.cmake new file mode 100644 index 00000000000..a5357204950 --- /dev/null +++ b/win/cmake/install_macros.cmake @@ -0,0 +1,328 @@ +# Copyright (C) 2009 Sun Microsystems, Inc +# +# 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 + +GET_FILENAME_COMPONENT(MYSQL_CMAKE_SCRIPT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) +INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_parse_arguments.cmake) +MACRO (INSTALL_DEBUG_SYMBOLS targets) + IF(MSVC) + FOREACH(target ${targets}) + GET_TARGET_PROPERTY(location ${target} LOCATION) + GET_TARGET_PROPERTY(type ${target} TYPE) + IF(NOT INSTALL_LOCATION) + IF(type MATCHES "STATIC_LIBRARY" OR type MATCHES "MODULE_LIBRARY" OR type MATCHES "SHARED_LIBRARY") + SET(INSTALL_LOCATION "lib") + ELSEIF(type MATCHES "EXECUTABLE") + SET(INSTALL_LOCATION "bin") + ELSE() + MESSAGE(FATAL_ERROR "cannot determine type of ${target}. Don't now where to install") + ENDIF() + ENDIF() + STRING(REPLACE ".exe" ".pdb" pdb_location ${location}) + STRING(REPLACE ".dll" ".pdb" pdb_location ${pdb_location}) + STRING(REPLACE ".lib" ".pdb" pdb_location ${pdb_location}) + IF(CMAKE_GENERATOR MATCHES "Visual Studio") + STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}" pdb_location ${pdb_location}) + ENDIF() + IF(target STREQUAL "mysqld") + SET(comp Server) + ELSEIF(pdb_location MATCHES "mysql-test") + SET(comp Tests) + ELSE() + SET(comp Debuginfo) + ENDIF() + INSTALL(FILES ${pdb_location} DESTINATION ${INSTALL_LOCATION} COMPONENT ${comp}) + ENDFOREACH() + ENDIF() +ENDMACRO() + +# Installs manpage for given file (either script or executable) +# +FUNCTION(INSTALL_MANPAGE file) + IF(NOT UNIX) + RETURN() + ENDIF() + GET_FILENAME_COMPONENT(file_name "${file}" NAME) + SET(GLOB_EXPR + ${CMAKE_SOURCE_DIR}/man/*${file}man.1* + ${CMAKE_SOURCE_DIR}/man/*${file}man.8* + ${CMAKE_BINARY_DIR}/man/*${file}man.1* + ${CMAKE_BINARY_DIR}/man/*${file}man.8* + ) + IF(MYSQL_DOC_DIR) + SET(GLOB_EXPR + ${MYSQL_DOC_DIR}/man/*${file}man.1* + ${MYSQL_DOC_DIR}/man/*${file}man.8* + ${MYSQL_DOC_DIR}/man/*${file}.1* + ${MYSQL_DOC_DIR}/man/*${file}.8* + ${GLOB_EXPR} + ) + ENDIF() + + FILE(GLOB_RECURSE MANPAGES ${GLOB_EXPR}) + IF(MANPAGES) + LIST(GET MANPAGES 0 MANPAGE) + STRING(REPLACE "${file}man.1" "${file}.1" MANPAGE "${MANPAGE}") + STRING(REPLACE "${file}man.8" "${file}.8" MANPAGE "${MANPAGE}") + IF(MANPAGE MATCHES "${file}.1") + SET(SECTION man1) + ELSE() + SET(SECTION man8) + ENDIF() + INSTALL(FILES "${MANPAGE}" DESTINATION "${INSTALL_MANDIR}/${SECTION}" + COMPONENT ManPages) + ENDIF() +ENDFUNCTION() + +FUNCTION(INSTALL_SCRIPT) + MYSQL_PARSE_ARGUMENTS(ARG + "DESTINATION;COMPONENT" + "" + ${ARGN} + ) + + SET(script ${ARG_DEFAULT_ARGS}) + IF(NOT ARG_DESTINATION) + SET(ARG_DESTINATION ${INSTALL_BINDIR}) + ENDIF() + IF(ARG_COMPONENT) + SET(COMP COMPONENT ${ARG_COMPONENT}) + ELSE() + SET(COMP) + ENDIF() + + INSTALL(FILES + ${script} + DESTINATION ${ARG_DESTINATION} + PERMISSIONS OWNER_READ OWNER_WRITE + OWNER_EXECUTE GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE ${COMP} + ) + INSTALL_MANPAGE(${script}) +ENDFUNCTION() + +# Install symbolic link to CMake target. +# the link is created in the same directory as target +# and extension will be the same as for target file. +MACRO(INSTALL_SYMLINK linkname target destination component) +IF(UNIX) + GET_TARGET_PROPERTY(location ${target} LOCATION) + GET_FILENAME_COMPONENT(path ${location} PATH) + GET_FILENAME_COMPONENT(name ${location} NAME) + SET(output ${path}/${linkname}) + ADD_CUSTOM_COMMAND( + OUTPUT ${output} + COMMAND ${CMAKE_COMMAND} ARGS -E remove -f ${output} + COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink + ${name} + ${linkname} + WORKING_DIRECTORY ${path} + DEPENDS ${target} + ) + + ADD_CUSTOM_TARGET(symlink_${linkname} + ALL + DEPENDS ${output}) + SET_TARGET_PROPERTIES(symlink_${linkname} PROPERTIES CLEAN_DIRECT_OUTPUT 1) + IF(CMAKE_GENERATOR MATCHES "Xcode") + # For Xcode, replace project config with install config + STRING(REPLACE "${CMAKE_CFG_INTDIR}" + "\${CMAKE_INSTALL_CONFIG_NAME}" output ${output}) + ENDIF() + INSTALL(FILES ${output} DESTINATION ${destination} COMPONENT ${component}) +ENDIF() +ENDMACRO() + +IF(WIN32) + OPTION(SIGNCODE "Sign executables and dlls with digital certificate" OFF) + MARK_AS_ADVANCED(SIGNCODE) + IF(SIGNCODE) + SET(SIGNTOOL_PARAMETERS + /a /t http://timestamp.verisign.com/scripts/timstamp.dll + CACHE STRING "parameters for signtool (list)") + FIND_PROGRAM(SIGNTOOL_EXECUTABLE signtool + PATHS "$ENV{ProgramFiles}/Microsoft SDKs/Windows/v7.0A/bin" + "$ENV{ProgramFiles}/Windows Kits/8.0/bin/x86" + ) + IF(NOT SIGNTOOL_EXECUTABLE) + MESSAGE(FATAL_ERROR + "signtool is not found. Signing executables not possible") + ENDIF() + MARK_AS_ADVANCED(SIGNTOOL_EXECUTABLE SIGNTOOL_PARAMETERS) + ENDIF() +ENDIF() + +MACRO(SIGN_TARGET) + MYSQL_PARSE_ARGUMENTS(ARG "COMPONENT" "" ${ARGN}) + SET(target ${ARG_DEFAULT_ARGS}) + IF(ARG_COMPONENT) + SET(comp COMPONENT ${ARG_COMPONENT}) + ELSE() + SET(comp) + ENDIF() + GET_TARGET_PROPERTY(target_type ${target} TYPE) + IF(target_type AND NOT target_type MATCHES "STATIC") + GET_TARGET_PROPERTY(target_location ${target} LOCATION) + IF(CMAKE_GENERATOR MATCHES "Visual Studio") + STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}" + target_location ${target_location}) + ENDIF() + INSTALL(CODE + "EXECUTE_PROCESS(COMMAND + \"${SIGNTOOL_EXECUTABLE}\" verify /pa /q \"${target_location}\" + RESULT_VARIABLE ERR) + IF(NOT \${ERR} EQUAL 0) + EXECUTE_PROCESS(COMMAND + \"${SIGNTOOL_EXECUTABLE}\" sign ${SIGNTOOL_PARAMETERS} \"${target_location}\" + RESULT_VARIABLE ERR) + ENDIF() + IF(NOT \${ERR} EQUAL 0) + MESSAGE(FATAL_ERROR \"Error signing '${target_location}'\") + ENDIF() + " ${comp}) + ENDIF() +ENDMACRO() + + +# Installs targets, also installs pdbs on Windows. +# +# + +FUNCTION(MYSQL_INSTALL_TARGETS) + MYSQL_PARSE_ARGUMENTS(ARG + "DESTINATION;COMPONENT" + "" + ${ARGN} + ) + IF(ARG_COMPONENT) + SET(COMP COMPONENT ${ARG_COMPONENT}) + ENDIF() + + SET(TARGETS ${ARG_DEFAULT_ARGS}) + IF(NOT TARGETS) + MESSAGE(FATAL_ERROR "Need target list for MYSQL_INSTALL_TARGETS") + ENDIF() + IF(NOT ARG_DESTINATION) + MESSAGE(FATAL_ERROR "Need DESTINATION parameter for MYSQL_INSTALL_TARGETS") + ENDIF() + + FOREACH(target ${TARGETS}) + # If signing is required, sign executables before installing + IF(SIGNCODE) + SIGN_TARGET(${target} ${COMP}) + ENDIF() + # Install man pages on Unix + IF(UNIX) + GET_TARGET_PROPERTY(target_location ${target} LOCATION) + INSTALL_MANPAGE(${target_location}) + ENDIF() + ENDFOREACH() + + INSTALL(TARGETS ${TARGETS} DESTINATION ${ARG_DESTINATION} ${COMP}) + SET(INSTALL_LOCATION ${ARG_DESTINATION} ) + INSTALL_DEBUG_SYMBOLS("${TARGETS}") + SET(INSTALL_LOCATION) +ENDFUNCTION() + +# Optionally install mysqld/client/embedded from debug build run. outside of the current build dir +# (unless multi-config generator is used like Visual Studio or Xcode). +# For Makefile generators we default Debug build directory to ${buildroot}/../debug. +GET_FILENAME_COMPONENT(BINARY_PARENTDIR ${CMAKE_BINARY_DIR} PATH) +SET(DEBUGBUILDDIR "${BINARY_PARENTDIR}/debug" CACHE INTERNAL "Directory of debug build") + + +FUNCTION(INSTALL_DEBUG_TARGET target) + MYSQL_PARSE_ARGUMENTS(ARG + "DESTINATION;RENAME;PDB_DESTINATION;COMPONENT" + "" + ${ARGN} + ) + GET_TARGET_PROPERTY(target_type ${target} TYPE) + IF(ARG_RENAME) + SET(RENAME_PARAM RENAME ${ARG_RENAME}${CMAKE_${target_type}_SUFFIX}) + ELSE() + SET(RENAME_PARAM) + ENDIF() + IF(NOT ARG_DESTINATION) + MESSAGE(FATAL_ERROR "Need DESTINATION parameter for INSTALL_DEBUG_TARGET") + ENDIF() + GET_TARGET_PROPERTY(target_location ${target} LOCATION) + IF(CMAKE_GENERATOR MATCHES "Makefiles") + STRING(REPLACE "${CMAKE_BINARY_DIR}" "${DEBUGBUILDDIR}" debug_target_location "${target_location}") + ELSE() + STRING(REPLACE "${CMAKE_CFG_INTDIR}" "Debug" debug_target_location "${target_location}" ) + ENDIF() + IF(NOT ARG_COMPONENT) + SET(ARG_COMPONENT DebugBinaries) + ENDIF() + + # Define permissions + # For executable files + SET(PERMISSIONS_EXECUTABLE + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) + + # Permissions for shared library (honors CMAKE_INSTALL_NO_EXE which is + # typically set on Debian) + IF(CMAKE_INSTALL_SO_NO_EXE) + SET(PERMISSIONS_SHARED_LIBRARY + PERMISSIONS + OWNER_READ OWNER_WRITE + GROUP_READ + WORLD_READ) + ELSE() + SET(PERMISSIONS_SHARED_LIBRARY ${PERMISSIONS_EXECUTABLE}) + ENDIF() + + # Shared modules get the same permissions as shared libraries + SET(PERMISSIONS_MODULE_LIBRARY ${PERMISSIONS_SHARED_LIBRARY}) + + # Define permissions for static library + SET(PERMISSIONS_STATIC_LIBRARY + PERMISSIONS + OWNER_READ OWNER_WRITE + GROUP_READ + WORLD_READ) + + INSTALL(FILES ${debug_target_location} + DESTINATION ${ARG_DESTINATION} + ${RENAME_PARAM} + ${PERMISSIONS_${target_type}} + CONFIGURATIONS Release RelWithDebInfo + COMPONENT ${ARG_COMPONENT} + OPTIONAL) + + IF(MSVC) + GET_FILENAME_COMPONENT(ext ${debug_target_location} EXT) + STRING(REPLACE "${ext}" ".pdb" debug_pdb_target_location "${debug_target_location}" ) + IF (RENAME_PARAM) + IF(NOT ARG_PDB_DESTINATION) + STRING(REPLACE "${ext}" ".pdb" "${ARG_RENAME}" pdb_rename) + SET(PDB_RENAME_PARAM RENAME "${pdb_rename}") + ENDIF() + ENDIF() + IF(NOT ARG_PDB_DESTINATION) + SET(ARG_PDB_DESTINATION "${ARG_DESTINATION}") + ENDIF() + INSTALL(FILES ${debug_pdb_target_location} + DESTINATION ${ARG_PDB_DESTINATION} + ${PDB_RENAME_PARAM} + CONFIGURATIONS Release RelWithDebInfo + COMPONENT ${ARG_COMPONENT} + OPTIONAL) + ENDIF() +ENDFUNCTION() + diff --git a/win/cmake/mysql_add_executable.cmake b/win/cmake/mysql_add_executable.cmake new file mode 100644 index 00000000000..ac812fbcdfd --- /dev/null +++ b/win/cmake/mysql_add_executable.cmake @@ -0,0 +1,56 @@ +# Copyright (C) 2009 Sun Microsystems, Inc
+#
+# 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
+
+# Add executable plus some additional MySQL specific stuff
+# Usage (same as for standard CMake's ADD_EXECUTABLE)
+#
+# MYSQL_ADD_EXECUTABLE(target source1...sourceN)
+#
+# MySQL specifics:
+# - instruct CPack to install executable under ${CMAKE_INSTALL_PREFIX}/bin directory
+# On Windows :
+# - add version resource
+# - instruct CPack to do autenticode signing if SIGNCODE is set
+
+INCLUDE(cmake_parse_arguments)
+
+FUNCTION (MYSQL_ADD_EXECUTABLE)
+ # Pass-through arguments for ADD_EXECUTABLE
+ MYSQL_PARSE_ARGUMENTS(ARG
+ "WIN32;MACOSX_BUNDLE;EXCLUDE_FROM_ALL;DESTINATION;COMPONENT"
+ ""
+ ${ARGN}
+ )
+ LIST(GET ARG_DEFAULT_ARGS 0 target)
+ LIST(REMOVE_AT ARG_DEFAULT_ARGS 0)
+
+ SET(sources ${ARG_DEFAULT_ARGS})
+ ADD_VERSION_INFO(${target} EXECUTABLE sources)
+ ADD_EXECUTABLE(${target} ${ARG_WIN32} ${ARG_MACOSX_BUNDLE} ${ARG_EXCLUDE_FROM_ALL} ${sources})
+ # tell CPack where to install
+ IF(NOT ARG_EXCLUDE_FROM_ALL)
+ IF(NOT ARG_DESTINATION)
+ SET(ARG_DESTINATION ${INSTALL_BINDIR})
+ ENDIF() + IF(ARG_COMPONENT) + SET(COMP COMPONENT ${ARG_COMPONENT}) + ELSEIF(MYSQL_INSTALL_COMPONENT) + SET(COMP COMPONENT ${MYSQL_INSTALL_COMPONENT}) + ELSE() + SET(COMP COMPONENT Client) + ENDIF()
+ MYSQL_INSTALL_TARGETS(${target} DESTINATION ${ARG_DESTINATION} ${COMP})
+ ENDIF()
+ENDFUNCTION() diff --git a/win/cmake/mysql_version.cmake b/win/cmake/mysql_version.cmake new file mode 100644 index 00000000000..79e6a18ee1d --- /dev/null +++ b/win/cmake/mysql_version.cmake @@ -0,0 +1,144 @@ + +MACRO(MYSQL_GET_CONFIG_VALUE keyword var) + IF(NOT ${var}) + IF (EXISTS ${CMAKE_SOURCE_DIR}/configure.in) + FILE (STRINGS ${CMAKE_SOURCE_DIR}/configure.in str REGEX "^[ ]*${keyword}=") + IF(str) + STRING(REPLACE "${keyword}=" "" str ${str}) + STRING(REGEX REPLACE "[ ].*" "" str ${str}) + SET(${var} ${str} CACHE INTERNAL "Config variable") + ENDIF() + ENDIF() + ENDIF() +ENDMACRO() + + +# Read mysql version for configure script + +MACRO(GET_MYSQL_VERSION) + + IF(NOT VERSION_STRING) + IF(EXISTS ${CMAKE_SOURCE_DIR}/configure.in) + FILE(STRINGS ${CMAKE_SOURCE_DIR}/configure.in str REGEX "AM_INIT_AUTOMAKE") + STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+[-][^ \\)]+" VERSION_STRING "${str}") + IF(NOT VERSION_STRING) + STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION_STRING "${str}") + IF(NOT VERSION_STRING) + FILE(STRINGS configure.in str REGEX "AC_INIT\\(") + STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+[-][a-zA-Z0-9]+" VERSION_STRING "${str}") + IF(NOT VERSION_STRING) + STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION_STRING "${str}") + ENDIF() + ENDIF() + ENDIF() + ENDIF() + ENDIF() + + IF(NOT VERSION_STRING) + MESSAGE(FATAL_ERROR + "VERSION_STRING cannot be parsed, please specify -DVERSION_STRING=major.minor.patch-extra" + "when calling cmake") + ENDIF() + + SET(VERSION ${VERSION_STRING}) + STRING(REPLACE "-" "_" MYSQL_U_SCORE_VERSION "${VERSION_STRING}") + + # Remove trailing (non-numeric) part of the version string + STRING(REGEX REPLACE "[^\\.0-9].*" "" VERSION_STRING ${VERSION_STRING}) + + STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" MAJOR_VERSION "${VERSION_STRING}") + STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" MINOR_VERSION "${VERSION_STRING}") + STRING(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" PATCH "${VERSION_STRING}") + SET(MYSQL_BASE_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}" CACHE INTERNAL "MySQL Base version") + SET(MYSQL_NO_DASH_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH}") + MATH(EXPR MYSQL_VERSION_ID "10000*${MAJOR_VERSION} + 100*${MINOR_VERSION} + ${PATCH}") + MARK_AS_ADVANCED(VERSION MYSQL_VERSION_ID MYSQL_BASE_VERSION) + SET(CPACK_PACKAGE_VERSION_MAJOR ${MAJOR_VERSION}) + SET(CPACK_PACKAGE_VERSION_MINOR ${MINOR_VERSION}) + SET(CPACK_PACKAGE_VERSION_PATCH ${PATCH}) +ENDMACRO() + +# Get mysql version and other interesting variables +GET_MYSQL_VERSION() + +MYSQL_GET_CONFIG_VALUE("PROTOCOL_VERSION" PROTOCOL_VERSION) +MYSQL_GET_CONFIG_VALUE("DOT_FRM_VERSION" DOT_FRM_VERSION) +MYSQL_GET_CONFIG_VALUE("MYSQL_TCP_PORT_DEFAULT" MYSQL_TCP_PORT_DEFAULT) +MYSQL_GET_CONFIG_VALUE("MYSQL_UNIX_ADDR_DEFAULT" MYSQL_UNIX_ADDR_DEFAULT) +MYSQL_GET_CONFIG_VALUE("SHARED_LIB_MAJOR_VERSION" SHARED_LIB_MAJOR_VERSION) +IF(NOT MYSQL_TCP_PORT_DEFAULT) + SET(MYSQL_TCP_PORT_DEFAULT "3306") +ENDIF() +IF(NOT MYSQL_TCP_PORT) + SET(MYSQL_TCP_PORT ${MYSQL_TCP_PORT_DEFAULT}) + SET(MYSQL_TCP_PORT_DEFAULT "0") +ELSEIF(MYSQL_TCP_PORT EQUAL MYSQL_TCP_PORT_DEFAULT) + SET(MYSQL_TCP_PORT_DEFAULT "0") +ENDIF() + + +IF(NOT MYSQL_UNIX_ADDR) + SET(MYSQL_UNIX_ADDR "/tmp/mysql.sock") +ENDIF() +IF(NOT COMPILATION_COMMENT) + SET(COMPILATION_COMMENT "Source distribution") +ENDIF() + + +INCLUDE(package_name) +IF(NOT CPACK_PACKAGE_FILE_NAME) + GET_PACKAGE_FILE_NAME(CPACK_PACKAGE_FILE_NAME) +ENDIF() + +IF(NOT CPACK_SOURCE_PACKAGE_FILE_NAME) + SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-${VERSION}") +ENDIF() +SET(CPACK_PACKAGE_CONTACT "MariaDB team <build@mysql.com>") +SET(CPACK_PACKAGE_VENDOR "Monty Program AB") +SET(CPACK_SOURCE_GENERATOR "TGZ") +INCLUDE(cpack_source_ignore_files) + +# Defintions for windows version resources +SET(PRODUCTNAME "MariaDB Server") +SET(COMPANYNAME ${CPACK_PACKAGE_VENDOR}) + +# Windows 'date' command has unpredictable output, so cannot rely on it to +# set MYSQL_COPYRIGHT_YEAR - if someone finds a portable way to do so then +# it might be useful +#IF (WIN32) +# EXECUTE_PROCESS(COMMAND "date" "/T" OUTPUT_VARIABLE TMP_DATE) +# STRING(REGEX REPLACE "(..)/(..)/..(..).*" "\\3\\2\\1" MYSQL_COPYRIGHT_YEAR ${TMP_DATE}) +IF(UNIX) + EXECUTE_PROCESS(COMMAND "date" "+%Y" OUTPUT_VARIABLE MYSQL_COPYRIGHT_YEAR OUTPUT_STRIP_TRAILING_WHITESPACE) +ENDIF() + +# Add version information to the exe and dll files +# Refer to http://msdn.microsoft.com/en-us/library/aa381058(VS.85).aspx +# for more info. +IF(MSVC) + # Tiny version is used to identify the build, it can be set with cmake -DTINY_VERSION=<number> + # to bzr revno for example (in the CI builds) + SET(TINY_VERSION "0" CACHE INTERNAL "") + + GET_FILENAME_COMPONENT(MYSQL_CMAKE_SCRIPT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) + + SET(FILETYPE VFT_APP) + CONFIGURE_FILE(${MYSQL_CMAKE_SCRIPT_DIR}/versioninfo.rc.in + ${CMAKE_BINARY_DIR}/versioninfo_exe.rc) + + SET(FILETYPE VFT_DLL) + CONFIGURE_FILE(${MYSQL_CMAKE_SCRIPT_DIR}/versioninfo.rc.in + ${CMAKE_BINARY_DIR}/versioninfo_dll.rc) + + FUNCTION(ADD_VERSION_INFO target target_type sources_var) + IF("${target_type}" MATCHES "SHARED" OR "${target_type}" MATCHES "MODULE") + SET(rcfile ${CMAKE_BINARY_DIR}/versioninfo_dll.rc) + ELSEIF("${target_type}" MATCHES "EXE") + SET(rcfile ${CMAKE_BINARY_DIR}/versioninfo_exe.rc) + ENDIF() + SET(${sources_var} ${${sources_var}} ${rcfile} PARENT_SCOPE) + ENDFUNCTION() +ELSE() + FUNCTION(ADD_VERSION_INFO) + ENDFUNCTION() +ENDIF() diff --git a/win/cmake/package_name.cmake b/win/cmake/package_name.cmake new file mode 100644 index 00000000000..1bbe68a0336 --- /dev/null +++ b/win/cmake/package_name.cmake @@ -0,0 +1,134 @@ +# Copyright (C) 2010 Sun Microsystems, Inc +# +# 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 + +# Produce meaningful package name for the binary package +# The logic is rather involved with special cases for different OSes +INCLUDE(CheckTypeSize) +CHECK_TYPE_SIZE("void *" SIZEOF_VOIDP) +MACRO(GET_PACKAGE_FILE_NAME Var) +IF(NOT VERSION) + MESSAGE(FATAL_ERROR + "Variable VERSION needs to be set prior to calling GET_PACKAGE_FILE_NAME") + ENDIF() + IF(NOT SYSTEM_NAME_AND_PROCESSOR) + SET(NEED_DASH_BETWEEN_PLATFORM_AND_MACHINE 1) + SET(DEFAULT_PLATFORM ${CMAKE_SYSTEM_NAME}) + SET(DEFAULT_MACHINE ${CMAKE_SYSTEM_PROCESSOR}) + IF(SIZEOF_VOIDP EQUAL 8) + SET(64BIT 1) + ENDIF() + + IF(CMAKE_SYSTEM_NAME MATCHES "Windows") + SET(NEED_DASH_BETWEEN_PLATFORM_AND_MACHINE 0) + SET(DEFAULT_PLATFORM "win") + IF(64BIT) + SET(DEFAULT_MACHINE "x64") + ELSE() + SET(DEFAULT_MACHINE "32") + ENDIF() + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Linux") + IF(NOT 64BIT AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + SET(DEFAULT_MACHINE "i686") + ENDIF() + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "SunOS") + # SunOS 5.10=> solaris10 + STRING(REPLACE "5." "" VER "${CMAKE_SYSTEM_VERSION}") + SET(DEFAULT_PLATFORM "solaris${VER}") + IF(64BIT) + IF(CMAKE_SYSTEM_PROCESSOR MATCHES "i386") + SET(DEFAULT_MACHINE "x86_64") + ELSE() + SET(DEFAULT_MACHINE "${CMAKE_SYSTEM_PROCESSOR}-64bit") + ENDIF() + ENDIF() + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "HP-UX") + STRING(REPLACE "B." "" VER "${CMAKE_SYSTEM_VERSION}") + SET(DEFAULT_PLATFORM "hpux${VER}") + IF(64BIT) + SET(DEFAULT_MACHINE "${CMAKE_SYSTEM_PROCESSOR}-64bit") + ENDIF() + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "AIX") + SET(DEFAULT_PLATFORM "${CMAKE_SYSTEM_NAME}5.${CMAKE_SYSTEM_VERSION}") + IF(64BIT) + SET(DEFAULT_MACHINE "${CMAKE_SYSTEM_PROCESSOR}-64bit") + ENDIF() + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + STRING(REGEX MATCH "[0-9]+\\.[0-9]+" VER "${CMAKE_SYSTEM_VERSION}") + SET(DEFAULT_PLATFORM "${CMAKE_SYSTEM_NAME}${VER}") + IF(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64") + SET(DEFAULT_MACHINE "x86_64") + IF(NOT 64BIT) + SET(DEFAULT_MACHINE "i386") + ENDIF() + ENDIF() + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Darwin") + IF(CMAKE_OSX_DEPLOYMENT_TARGET) + SET(DEFAULT_PLATFORM "osx${CMAKE_OSX_DEPLOYMENT_TARGET}") + ELSE() + SET(VER "${CMAKE_SYSTEM_VERSION}") + STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" VER "${VER}") + # Subtract 4 from Darwin version to get correct osx10.X + MATH(EXPR VER "${VER} -4") + SET(DEFAULT_PLATFORM "osx10.${VER}") + ENDIF() + LIST(LENGTH CMAKE_OSX_ARCHITECTURES LEN) + IF(LEN GREATER 1) + SET(DEFAULT_MACHINE "universal") + ELSE() + SET(DEFAULT_MACHINE "${CMAKE_OSX_ARCHITECTURES}") + IF(NOT DEFAULT_MACHINE) + IF(CMAKE_SIZEOF_VOIPD EQUAL 4) + SET(DEFAULT_MACHINE "i386") + ELSE() + SET(DEFAULT_MACHINE "x86_64") + ENDIF() + ENDIF() + ENDIF() + IF(DEFAULT_MACHINE MATCHES "i386") + SET(DEFAULT_MACHINE "x86") + ENDIF() + ENDIF() + + IF(NOT PLATFORM) + SET(PLATFORM ${DEFAULT_PLATFORM}) + ENDIF() + IF(NOT MACHINE) + SET(MACHINE ${DEFAULT_MACHINE}) + ENDIF() + + IF(NEED_DASH_BETWEEN_PLATFORM_AND_MACHINE) + SET(SYSTEM_NAME_AND_PROCESSOR "${PLATFORM}-${MACHINE}") + ELSE() + SET(SYSTEM_NAME_AND_PROCESSOR "${PLATFORM}${MACHINE}") + ENDIF() + ENDIF() + + IF(SHORT_PRODUCT_TAG) + SET(PRODUCT_TAG "-${SHORT_PRODUCT_TAG}") + ELSEIF(MYSQL_SERVER_SUFFIX) + SET(PRODUCT_TAG "${MYSQL_SERVER_SUFFIX}") # Already has a leading dash + ELSE() + SET(PRODUCT_TAG) + ENDIF() + + SET(package_name "mariadb${PRODUCT_TAG}-${MYSQL_NO_DASH_VERSION}-${SYSTEM_NAME_AND_PROCESSOR}") + + # Sometimes package suffix is added (something like "-icc-glibc23") + IF(PACKAGE_SUFFIX) + SET(package_name "${package_name}${PACKAGE_SUFFIX}") + ENDIF() + STRING(TOLOWER ${package_name} package_name) + SET(${Var} ${package_name}) +ENDMACRO() diff --git a/win/cmake/versioninfo.rc.in b/win/cmake/versioninfo.rc.in new file mode 100644 index 00000000000..b570eb2f8e0 --- /dev/null +++ b/win/cmake/versioninfo.rc.in @@ -0,0 +1,23 @@ +#include <windows.h>
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION @MAJOR_VERSION@,@MINOR_VERSION@,@PATCH@,@TINY_VERSION@
+PRODUCTVERSION @MAJOR_VERSION@,@MINOR_VERSION@,@PATCH@,@TINY_VERSION@
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEFLAGS 0
+FILEOS VOS__WINDOWS32
+FILETYPE @FILETYPE@
+FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ BEGIN
+ VALUE "FileVersion", "@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH@.@TINY_VERSION@\0"
+ VALUE "ProductVersion", "@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH@.@TINY_VERSION@\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
diff --git a/win/configure-mariadb.bat b/win/configure-mariadb.bat index 158d22c9aca..dc5b59819a3 100644 --- a/win/configure-mariadb.bat +++ b/win/configure-mariadb.bat @@ -3,7 +3,7 @@ cscript win\configure.js ^ WITH_FEDERATEDX_STORAGE_ENGINE ^ WITH_MERGE_STORAGE_ENGINE ^ WITH_PARTITION_STORAGE_ENGINE ^ - WITH_MARIA_STORAGE_ENGINE ^ + WITH_ARIA_STORAGE_ENGINE ^ WITH_PBXT_STORAGE_ENGINE ^ WITH_XTRADB_STORAGE_ENGINE ^ WITH_FEEDBACK_STORAGE_ENGINE diff --git a/win/configure-mariadb.sh b/win/configure-mariadb.sh index c6324bfd259..67bfe293639 100644 --- a/win/configure-mariadb.sh +++ b/win/configure-mariadb.sh @@ -7,9 +7,16 @@ set -e -cscript win/configure.js --with-plugin-archive --with-plugin-blackhole \ - --with-plugin-csv --with-plugin-example --with-plugin-federatedx \ - --with-plugin-merge --with-plugin-partition --with-plugin-maria \ - --with-plugin-pbxt --with-plugin-xtradb --with-plugin-feedback \ +cscript win/configure.js \ + WITH_ARCHIVE_STORAGE_ENGINE \ + WITH_BLACKHOLE_STORAGE_ENGINE \ + WITH_CSV_STORAGE_ENGINE \ + WITH_EXAMPLE_STORAGE_ENGINE \ + WITH_FEDERATEDX_STORAGE_ENGINE \ + WITH_MERGE_STORAGE_ENGINE \ + WITH_PARTITION_STORAGE_ENGINE \ + WITH_ARIA_STORAGE_ENGINE \ + WITH_PBXT_STORAGE_ENGINE \ + WITH_XTRADB_STORAGE_ENGINE \ + WITH_FEEDBACK_STORAGE_ENGINE \ WITH_EMBEDDED_SERVER - diff --git a/win/configure.js b/win/configure.js index c3e5429a620..7e2cb3cd3d9 100644 --- a/win/configure.js +++ b/win/configure.js @@ -44,17 +44,17 @@ try case "EMBED_MANIFESTS": case "EXTRA_DEBUG": case "WITH_EMBEDDED_SERVER": - case "WITHOUT_MARIA_TEMP_TABLES": + case "WITHOUT_ARIA_TEMP_TABLES": configfile.WriteLine("SET (" + args.Item(i) + " TRUE)"); break; - case "WITH_MARIA_STORAGE_ENGINE": + case "WITH_ARIA_STORAGE_ENGINE": configfile.WriteLine("SET (" + args.Item(i) + " TRUE)"); if(with_maria_tmp_tables == -1) { with_maria_tmp_tables = 1; } break; - case "WITH_MARIA_TMP_TABLES": + case "WITH_ARIA_TMP_TABLES": with_maria_tmp_tables = ( parts.length == 1 || parts[1] == "YES" || parts[1] == "TRUE"); break; @@ -73,7 +73,7 @@ try } if (with_maria_tmp_tables == 1) { - configfile.WriteLine("SET (WITH_MARIA_TMP_TABLES TRUE)"); + configfile.WriteLine("SET (WITH_ARIA_TMP_TABLES TRUE)"); } if (actual_port == 0) { diff --git a/win/make_mariadb_win_dist b/win/make_mariadb_win_dist index a7ca8f2c9df..f6d961ea866 100644 --- a/win/make_mariadb_win_dist +++ b/win/make_mariadb_win_dist @@ -19,6 +19,13 @@ The default is to the builds and create 32 bit packages. EOF } + +if test -f win/build_maria_release.bat +then + cmd /c win\\build_maria_release.bat "$@" + exit $? +fi + # The default settings CMAKE_GENERATOR="Visual Studio 9 2008" ARCH="win32" diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt new file mode 100644 index 00000000000..795732e946b --- /dev/null +++ b/win/packaging/CMakeLists.txt @@ -0,0 +1,173 @@ +# Copyright 2010, 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 + +IF(NOT WIN32) + RETURN() +ENDIF() + +SET(MANUFACTURER "Monty Program AB") +FIND_PATH(WIX_DIR heat.exe + $ENV{WIX_DIR}/bin + $ENV{ProgramFiles}/wix/bin + "$ENV{ProgramFiles}/Windows Installer XML v3/bin" + "$ENV{ProgramFiles}/Windows Installer XML v3.5/bin" + "$ENV{ProgramFiles}/Windows Installer XML v3.6/bin" +) + +SET(CPACK_WIX_PACKAGE_BASE_NAME "MariaDB") +IF(CMAKE_SIZEOF_VOID_P EQUAL 4) + SET(CPACK_WIX_UPGRADE_CODE "49EB7A6A-1CEF-4A1E-9E89-B9A4993963E3") + SET(CPACK_WIX_PACKAGE_NAME "MariaDB @MAJOR_VERSION@.@MINOR_VERSION@") +ELSE() + SET(CPACK_WIX_UPGRADE_CODE "2331E7BD-EE58-431B-9E18-B2B918BCEB1B") + SET(CPACK_WIX_PACKAGE_NAME "MariaDB @MAJOR_VERSION@.@MINOR_VERSION@ (x64)") +ENDIF() + + +IF(NOT WIX_DIR) + IF(NOT _WIX_DIR_CHECKED) + SET(_WIX_DIR_CHECKED 1 CACHE INTERNAL "") + MESSAGE(STATUS "Cannot find wix 3, installer project will not be generated") + IF(BUILD_RELEASE) + MESSAGE(FATAL_ERROR + "Can't find Wix. It is necessary for producing official package" + ) + ENDIF() + ENDIF() + RETURN() +ENDIF() + +ADD_SUBDIRECTORY(ca) + +# extra.wxs.in needs DATADIR_MYSQL_FILES and DATADIR_PERFORMANCE_SCHEMA_FILES, i.e +# Wix-compatible file lists for ${builddir}\sql\data\{mysql,performance_schema} + +FOREACH(dir mysql performance_schema) + FILE(GLOB files ${CMAKE_BINARY_DIR}/sql/data/${dir}/*) + SET(filelist) + FOREACH(f ${files}) + IF(NOT f MATCHES ".rule") + FILE(TO_NATIVE_PATH "${f}" file_native_path) + GET_FILENAME_COMPONENT(file_name "${f}" NAME) + SET(filelist +"${filelist} +<File Id='${file_name}' Source='${file_native_path}'/>") + ENDIF() + ENDFOREACH() + STRING(TOUPPER ${dir} DIR_UPPER) + SET(DATADIR_${DIR_UPPER}_FILES "${filelist}") +ENDFOREACH() + + +FIND_PROGRAM(CANDLE_EXECUTABLE candle ${WIX_DIR}) +FIND_PROGRAM(LIGHT_EXECUTABLE light ${WIX_DIR}) + +# WiX wants the license text as rtf; if there is no rtf license, +# we create a fake one from the plain text COPYING file. +IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.rtf") + SET(COPYING_RTF "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.rtf") +ELSE() + IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../LICENSE.mysql") + SET(LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../../LICENSE.mysql") + ELSE() + SET(LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../../COPYING") + ENDIF() + FILE(READ ${LICENSE_FILE} CONTENTS) + STRING(REGEX REPLACE "\n" "\\\\par\n" CONTENTS "${CONTENTS}") + STRING(REGEX REPLACE "\t" "\\\\tab" CONTENTS "${CONTENTS}") + FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/COPYING.rtf" "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}\\viewkind4\\uc1\\pard\\lang1031\\f0\\fs15") + FILE(APPEND "${CMAKE_CURRENT_BINARY_DIR}/COPYING.rtf" "${CONTENTS}") + FILE(APPEND "${CMAKE_CURRENT_BINARY_DIR}/COPYING.rtf" "\n}\n") + SET(COPYING_RTF "${CMAKE_CURRENT_BINARY_DIR}/COPYING.rtf") +ENDIF() +GET_TARGET_PROPERTY(WIXCA_LOCATION wixca LOCATION) +SET(CPACK_WIX_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake) + +GET_TARGET_PROPERTY(upgrade_wizard_location mysql_upgrade_wizard LOCATION) +IF(NOT upgrade_wizard_location) + SET(EXTRA_WIX_PREPROCESSOR_FLAGS "-dHaveUpgradeWizard=0") +ENDIF() +IF(WITH_INNOBASE_STORAGE_ENGINE OR WITH_INNODB_STORAGE_ENGINE OR WITH_XTRADB_STORAGE_ENGINE) + SET(EXTRA_WIX_PREPROCESSOR_FLAGS ${EXTRA_WIX_PREPROCESSOR_FLAGS} "-dHaveInnodb=1") +ENDIF() + +SET(THIRD_PARTY_FEATURE_CONDITION "") + +IF(WITH_THIRD_PARTY) + SET(THIRD_PARTY_DOWNLOAD_LOCATION "$ENV{TEMP}") + IF(THIRD_PARTY_DOWNLOAD_LOCATION) + FILE(TO_CMAKE_PATH "${THIRD_PARTY_DOWNLOAD_LOCATION}" THIRD_PARTY_DOWNLOAD_LOCATION) + ELSE() + SET(THIRD_PARTY_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}") + ENDIF() +ENDIF() + +GET_TARGET_PROPERTY(LIBMYSQL_LOCATION libmysql LOCATION) +FOREACH(third_party ${WITH_THIRD_PARTY}) + SET(third_party_install_plugin ${CMAKE_CURRENT_SOURCE_DIR}/${third_party}.cmake) + IF(NOT EXISTS ${third_party_install_plugin}) + MESSAGE(FATAL_ERROR +"Third party MSI installation plugin ${third_party_install_plugin} does not exist. +It was expected due to WITH_THIRD_PARTY=${WITH_THIRD_PARTY}" +) + ENDIF() + STRING(TOUPPER "${third_party}" upper_third_party) + IF(NOT THIRD_PARTY_FEATURE_CONDITION ) + SET(THIRD_PARTY_FEATURE_CONDITION "<Condition Level='0'>${upper_third_party}INSTALLED") + ELSE() + SET(THIRD_PARTY_FEATURE_CONDITION "AND ${upper_third_party}INSTALLED") + ENDIF() +ENDFOREACH() + +IF(THIRD_PARTY_FEATURE_CONDITION) + SET(THIRD_PARTY_FEATURE_CONDITION "${THIRD_PARTY_FEATURE_CONDITION}</Condition>") +ENDIF() + +IF(NOT CPACK_WIX_UI) + SET(CPACK_WIX_UI "MyWixUI_Mondo") +ENDIF() +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/create_msi.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake + @ONLY) + + +IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(WixWin64 " Win64='yes'") +ELSE() + SET(WixWin64) +ENDIF() + + +IF(CMAKE_GENERATOR MATCHES "Visual Studio") + SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR}") +ENDIF() + + +ADD_CUSTOM_TARGET( + MSI + COMMAND ${CMAKE_COMMAND} + ${CONFIG_PARAM} + -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake +) +ADD_DEPENDENCIES(MSI wixca) + +ADD_CUSTOM_TARGET( + MSI_ESSENTIALS + COMMAND ${CMAKE_COMMAND} -DESSENTIALS=1 + ${CONFIG_PARAM} + -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake +) +ADD_DEPENDENCIES(MSI_ESSENTIALS wixca) + diff --git a/win/packaging/COPYING.rtf b/win/packaging/COPYING.rtf new file mode 100644 index 00000000000..de1f0bbefde --- /dev/null +++ b/win/packaging/COPYING.rtf @@ -0,0 +1,61 @@ +{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fcharset0 Arial;}}
+{\stylesheet{ Normal;}{\s1 heading 1;}{\s2 heading 2;}}
+\viewkind4\uc1\pard\s2\sb100\sa100\b\f0\fs24 GNU GENERAL PUBLIC LICENSE\par
+\pard\sb100\sa100\b0\fs20 Version 2, June 1991 \par
+\pard Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.\fs24 \par
+\pard\s2\sb100\sa100\b Preamble\par
+\pard\sb100\sa100\b0\fs20 The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. \par
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. \par
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. \par
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. \par
+We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. \par
+Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. \par
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. \par
+The precise terms and conditions for copying, distribution and modification follow.\fs24 \par
+\pard\s2\sb100\sa100\b TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\par
+\pard\sb100\sa100\b0\fs20 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". \par
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. \par
+1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. \par
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. \par
+2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: \par
+\pard\fi-360\li720\sb100\sa100\tx720\f1\'b7\tab\f0 a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. \par
+\pard\fi-360\li720\sb100\sa100\f1\'b7\tab\f0 b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. \par
+\f1\'b7\tab\f0 c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) \par
+\pard These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. \par
+\pard\sb100\sa100 Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. \par
+In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. \par
+3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: \par
+\pard\fi-360\li720\sb100\sa100\tx720\f1\'b7\tab\f0 a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, \par
+\pard\fi-360\li720\sb100\sa100\f1\'b7\tab\f0 b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, \par
+\f1\'b7\tab\f0 c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) \par
+\pard The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. \par
+\pard\sb100\sa100 If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. \par
+4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. \par
+5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. \par
+6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. \par
+7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. \par
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. \par
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. \par
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. \par
+8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. \par
+9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. \par
+Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. \par
+10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. \par
+NO WARRANTY \par
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. \par
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. \par
+\pard\s2\sb100\sa100\b\fs24 END OF TERMS AND CONDITIONS \par
+How to Apply These Terms to Your New Programs\fs20\par
+\pard\sb100\sa100\b0 If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. \par
+To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. \par
+\pard one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author 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; either version 2 of the License, or (at your option) any later version. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. \par
+\pard\sb100\sa100 Also add information on how to contact you by electronic and paper mail. \par
+If the program is interactive, make it output a short notice like this when it starts in an interactive mode: \par
+\pard Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. \par
+\pard\sb100\sa100 The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c' ; they could even be mouse-clicks or menu items--whatever suits your program. \par
+You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: \par
+\pard Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon , 1 April 1989 Ty Coon, President of Vice \par
+\pard\sb100\sa100 This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.\par
+\pard\f2\par
+}
+
diff --git a/win/packaging/CPackWixConfig.cmake b/win/packaging/CPackWixConfig.cmake new file mode 100644 index 00000000000..34f661b393e --- /dev/null +++ b/win/packaging/CPackWixConfig.cmake @@ -0,0 +1,114 @@ +
+IF(ESSENTIALS)
+ SET(CPACK_COMPONENTS_USED "Server;Client")
+ SET(CPACK_WIX_UI "MyWixUI_Mondo")
+ IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
+ SET(CPACK_PACKAGE_FILE_NAME "mariadb-essential-${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}-winx64")
+ ELSE()
+ SET(CPACK_PACKAGE_FILE_NAME "mariadb-essential-${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}-win32")
+ ENDIF()
+ELSE()
+ SET(CPACK_COMPONENTS_USED
+ "Server;Client;Development;SharedLibraries;Embedded;Debuginfo;Documentation;IniFiles;Readme;Server_Scripts;scripts;DebugBinaries")
+ENDIF()
+
+SET( WIX_FEATURE_MySQLServer_EXTRA_FEATURES "DBInstance;SharedClientServerComponents")
+# Some components like Embedded are optional
+# We will build MSI without embedded if it was not selected for build
+#(need to modify CPACK_COMPONENTS_ALL for that)
+SET(CPACK_ALL)
+FOREACH(comp1 ${CPACK_COMPONENTS_USED})
+ SET(found)
+ FOREACH(comp2 ${CPACK_COMPONENTS_ALL})
+ IF(comp1 STREQUAL comp2)
+ SET(found 1)
+ BREAK()
+ ENDIF()
+ ENDFOREACH()
+ IF(found)
+ SET(CPACK_ALL ${CPACK_ALL} ${comp1})
+ ENDIF()
+ENDFOREACH()
+SET(CPACK_COMPONENTS_ALL ${CPACK_ALL})
+
+# Always install (hidden), includes Readme files
+SET(CPACK_COMPONENT_GROUP_ALWAYSINSTALL_HIDDEN 1)
+SET(CPACK_COMPONENT_README_GROUP "AlwaysInstall")
+
+# Feature MySQL Server
+SET(CPACK_COMPONENT_GROUP_MYSQLSERVER_DISPLAY_NAME "MariaDB Server")
+SET(CPACK_COMPONENT_GROUP_MYSQLSERVER_EXPANDED "1")
+SET(CPACK_COMPONENT_GROUP_MYSQLSERVER_DESCRIPTION "Install server")
+ # Subfeature "Server" (hidden)
+ SET(CPACK_COMPONENT_SERVER_GROUP "MySQLServer")
+ SET(CPACK_COMPONENT_SERVER_HIDDEN 1)
+ # Subfeature "Client"
+ SET(CPACK_COMPONENT_CLIENT_GROUP "MySQLServer")
+ SET(CPACK_COMPONENT_CLIENT_DISPLAY_NAME "Client Programs")
+ SET(CPACK_COMPONENT_CLIENT_DESCRIPTION
+ "Various helpful (commandline) tools including the mysql command line client" )
+ # Subfeature "Debug binaries"
+ SET(CPACK_COMPONENT_DEBUGBINARIES_GROUP "MySQLServer")
+ SET(CPACK_COMPONENT_DEBUGBINARIES_DISPLAY_NAME "Debug binaries")
+ SET(CPACK_COMPONENT_DEBUGBINARIES_DESCRIPTION
+ "Debug/trace versions of executables and libraries" )
+ #SET(CPACK_COMPONENT_DEBUGBINARIES_WIX_LEVEL 2)
+
+
+ #Subfeature "Data Files"
+ SET(CPACK_COMPONENT_DATAFILES_GROUP "MySQLServer")
+ SET(CPACK_COMPONENT_DATAFILES_DISPLAY_NAME "Server data files")
+ SET(CPACK_COMPONENT_DATAFILES_DESCRIPTION "Server data files" )
+ SET(CPACK_COMPONENT_DATAFILES_HIDDEN 1)
+
+
+#Feature "Devel"
+SET(CPACK_COMPONENT_GROUP_DEVEL_DISPLAY_NAME "Development Components")
+SET(CPACK_COMPONENT_GROUP_DEVEL_DESCRIPTION "Installs C/C++ header files and libraries")
+ #Subfeature "Development"
+ SET(CPACK_COMPONENT_DEVELOPMENT_GROUP "Devel")
+ SET(CPACK_COMPONENT_DEVELOPMENT_HIDDEN 1)
+
+ #Subfeature "Shared libraries"
+ SET(CPACK_COMPONENT_SHAREDLIBRARIES_GROUP "Devel")
+ SET(CPACK_COMPONENT_SHAREDLIBRARIES_DISPLAY_NAME "Client C API library (shared)")
+ SET(CPACK_COMPONENT_SHAREDLIBRARIES_DESCRIPTION "Installs shared client library")
+
+ #Subfeature "Embedded"
+ SET(CPACK_COMPONENT_EMBEDDED_GROUP "Devel")
+ SET(CPACK_COMPONENT_EMBEDDED_DISPLAY_NAME "Embedded server library")
+ SET(CPACK_COMPONENT_EMBEDDED_DESCRIPTION "Installs embedded server library")
+ SET(CPACK_COMPONENT_EMBEDDED_WIX_LEVEL 2)
+
+#Feature Debug Symbols
+SET(CPACK_COMPONENT_GROUP_DEBUGSYMBOLS_DISPLAY_NAME "Debug Symbols")
+SET(CPACK_COMPONENT_GROUP_DEBUGSYMBOLS_DESCRIPTION "Installs Debug Symbols")
+SET(CPACK_COMPONENT_DEBUGSYMBOLS_WIX_LEVEL 2)
+ SET(CPACK_COMPONENT_DEBUGINFO_GROUP "DebugSymbols")
+ SET(CPACK_COMPONENT_DEBUGINFO_HIDDEN 1)
+
+#Feature Documentation
+SET(CPACK_COMPONENT_DOCUMENTATION_DISPLAY_NAME "Documentation")
+SET(CPACK_COMPONENT_DOCUMENTATION_DESCRIPTION "Installs documentation")
+SET(CPACK_COMPONENT_DOCUMENTATION_WIX_LEVEL 2)
+
+#Feature tests
+SET(CPACK_COMPONENT_TEST_DISPLAY_NAME "Tests")
+SET(CPACK_COMPONENT_TEST_DESCRIPTION "Installs unittests (requires Perl to run)")
+SET(CPACK_COMPONENT_TEST_WIX_LEVEL 2)
+
+
+#Feature Misc (hidden, installs only if everything is installed)
+SET(CPACK_COMPONENT_GROUP_MISC_HIDDEN 1)
+SET(CPACK_COMPONENT_GROUP_MISC_WIX_LEVEL 100)
+ SET(CPACK_COMPONENT_INIFILES_GROUP "Misc")
+ SET(CPACK_COMPONENT_SERVER_SCRIPTS_GROUP "Misc")
+
+#Add Firewall exception for mysqld.exe
+SET(bin.mysqld.exe.FILE_EXTRA "
+ <FirewallException Id='firewallexception.mysqld.exe' Name='[ProductName]' Scope='any'
+ IgnoreFailure='yes' xmlns='http://schemas.microsoft.com/wix/FirewallExtension'
+ />
+ "
+)
+
diff --git a/win/packaging/WixUIBannerBmp.jpg b/win/packaging/WixUIBannerBmp.jpg Binary files differnew file mode 100644 index 00000000000..a04177bed9d --- /dev/null +++ b/win/packaging/WixUIBannerBmp.jpg diff --git a/win/packaging/WixUIDialogBmp.jpg b/win/packaging/WixUIDialogBmp.jpg Binary files differnew file mode 100644 index 00000000000..466cdc461c8 --- /dev/null +++ b/win/packaging/WixUIDialogBmp.jpg diff --git a/win/packaging/ca/CMakeLists.txt b/win/packaging/ca/CMakeLists.txt new file mode 100644 index 00000000000..7dd30123587 --- /dev/null +++ b/win/packaging/ca/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright 2010, 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 + +INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/inc) +LINK_DIRECTORIES(${WIX_DIR}/../SDK/lib) + +SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) + +IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(WIX_ARCH_SUFFIX "_x64") +ELSE() + SET(WIX_ARCH_SUFFIX) +ENDIF() + +IF(MSVC_VERSION EQUAL 1400) + SET(WIX35_MSVC_SUFFIX "_2005") +ELSEIF(MSVC_VERSION EQUAL 1500) + SET(WIX35_MSVC_SUFFIX "_2008") +ELSEIF(MSVC_VERSION EQUAL 1600) + SET(WIX35_MSVC_SUFFIX "_2010") +ELSE() + # When next VS is out, add the correct version here + MESSAGE(FATAL_ERROR "Unknown VS version") +ENDIF() + +FIND_LIBRARY(WIX_WCAUTIL_LIBRARY + NAMES wcautil${WIX_ARCH_SUFFIX} wcautil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} + HINTS ${WIX_DIR}/../SDK/lib) + +FIND_LIBRARY(WIX_DUTIL_LIBRARY + NAMES dutil${WIX_ARCH_SUFFIX} dutil${WIX35_MSVC_SUFFIX}${WIX_ARCH_SUFFIX} + PATHS ${WIX_DIR}/../SDK/lib) + +ADD_VERSION_INFO(wixca SHARED WIXCA_SOURCES) +ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES}) +TARGET_LINK_LIBRARIES(wixca ${WIX_WCAUTIL_LIBRARY} ${WIX_DUTIL_LIBRARY} + msi version winservice) diff --git a/win/packaging/ca/CustomAction.cpp b/win/packaging/ca/CustomAction.cpp new file mode 100644 index 00000000000..81c9f7eea92 --- /dev/null +++ b/win/packaging/ca/CustomAction.cpp @@ -0,0 +1,863 @@ +/* Copyright 2010, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef UNICODE +#define UNICODE +#endif + +#include <windows.h> +#include <winreg.h> +#include <msi.h> +#include <msiquery.h> +#include <wcautil.h> +#include <strutil.h> +#include <string.h> +#include <strsafe.h> +#include <assert.h> + +#include <winservice.h> + +#define ONE_MB 1048576 +UINT ExecRemoveDataDirectory(wchar_t *dir) +{ + /* Strip stray backslash */ + DWORD len = (DWORD)wcslen(dir); + if(len > 0 && dir[len-1]==L'\\') + dir[len-1] = 0; + + SHFILEOPSTRUCTW fileop; + fileop.hwnd= NULL; /* no status display */ + fileop.wFunc= FO_DELETE; /* delete operation */ + fileop.pFrom= dir; /* source file name as double null terminated string */ + fileop.pTo= NULL; /* no destination needed */ + fileop.fFlags= FOF_NOCONFIRMATION|FOF_SILENT; /* do not prompt the user */ + + fileop.fAnyOperationsAborted= FALSE; + fileop.lpszProgressTitle= NULL; + fileop.hNameMappings= NULL; + + return SHFileOperationW(&fileop); +} + + +extern "C" UINT __stdcall RemoveDataDirectory(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + hr = WcaInitialize(hInstall, __FUNCTION__); + ExitOnFailure(hr, "Failed to initialize"); + WcaLog(LOGMSG_STANDARD, "Initialized."); + + wchar_t dir[MAX_PATH]; + DWORD len = MAX_PATH; + MsiGetPropertyW(hInstall, L"CustomActionData", dir, &len); + + er= ExecRemoveDataDirectory(dir); + WcaLog(LOGMSG_STANDARD, "SHFileOperation returned %d", er); +LExit: + return WcaFinalize(er); +} + +/* + Check for if directory is empty during install, + sets "<PROPERTY>_NOT_EMPTY" otherise +*/ +extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall, + const wchar_t *PropertyName) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + hr = WcaInitialize(hInstall, __FUNCTION__); + ExitOnFailure(hr, "Failed to initialize"); + WcaLog(LOGMSG_STANDARD, "Initialized."); + + + wchar_t buf[MAX_PATH]; + DWORD len = MAX_PATH; + MsiGetPropertyW(hInstall, PropertyName, buf, &len); + wcscat_s(buf, MAX_PATH, L"*.*"); + + WcaLog(LOGMSG_STANDARD, "Checking files in %S", buf); + WIN32_FIND_DATAW data; + HANDLE h; + bool empty; + h= FindFirstFile(buf, &data); + if (h != INVALID_HANDLE_VALUE) + { + empty= true; + for(;;) + { + if (wcscmp(data.cFileName, L".") || wcscmp(data.cFileName, L"..")) + { + empty= false; + break; + } + if (!FindNextFile(h, &data)) + break; + } + FindClose(h); + } + else + { + /* Non-existent directory, we handle it as empty */ + empty = true; + } + + if(empty) + WcaLog(LOGMSG_STANDARD, "Directory %S is empty or non-existent", + PropertyName); + else + WcaLog(LOGMSG_STANDARD, "Directory %S is NOT empty", PropertyName); + + wcscpy_s(buf, MAX_PATH, PropertyName); + wcscat_s(buf, L"NOTEMPTY"); + WcaSetProperty(buf, empty? L"":L"1"); + +LExit: + return WcaFinalize(er); +} + +extern "C" UINT __stdcall CheckDataDirectoryEmpty(MSIHANDLE hInstall) +{ + return CheckDirectoryEmpty(hInstall, L"DATADIR"); +} + +bool CheckServiceExists(const wchar_t *name) +{ + SC_HANDLE manager =0, service=0; + manager = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT); + if (!manager) + { + return false; + } + + service = OpenService(manager, name, SC_MANAGER_CONNECT); + if(service) + CloseServiceHandle(service); + CloseServiceHandle(manager); + + return service?true:false; +} + +/* User in rollback of create database custom action */ +bool ExecRemoveService(const wchar_t *name) +{ + SC_HANDLE manager =0, service=0; + manager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); + bool ret; + if (!manager) + { + return false; + } + service = OpenService(manager, name, DELETE); + if(service) + { + ret= DeleteService(service); + } + else + { + ret= false; + } + CloseServiceHandle(manager); + return ret; +} + +/* + Check if port is free by trying to bind to the port +*/ +bool IsPortFree(short port) +{ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 2); + + WSAStartup(wVersionRequested, &wsaData); + + struct sockaddr_in sin; + SOCKET sock; + sock = socket(AF_INET, SOCK_STREAM, 0); + if(sock == -1) + { + return false; + } + sin.sin_port = htons(port); + sin.sin_addr.s_addr = 0; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_family = AF_INET; + if(bind(sock, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) == -1) + { + return false; + } + closesocket(sock); + WSACleanup(); + return true; +} + + +/* + Helper function used in filename normalization. + Removes leading quote and terminates string at the position of the next one + (if applicable, does not change string otherwise). Returns modified string +*/ +wchar_t *strip_quotes(wchar_t *s) +{ + if (s && (*s == L'"')) + { + s++; + wchar_t *p = wcschr(s, L'"'); + if(p) + *p = 0; + } + return s; +} + + +/* + Checks for consistency of service configuration. + + It can happen that SERVICENAME or DATADIR + MSI properties are in inconsistent state after somebody upgraded database + We catch this case during uninstall. In particular, either service is not + removed even if SERVICENAME was set (but this name is reused by someone else) + or data directory is not removed (if it is used by someone else). To find out + whether service name and datadirectory are in use For every service, + configuration is read and checked as follows: + + - look if a service has to do something with mysql + - If so, check its name against SERVICENAME. if match, check binary path + against INSTALLDIR\bin. If binary path does not match, then service runs + under different installation and won't be removed. + - Check options file for datadir and look if this is inside this + installation's datadir don't remove datadir if this is the case. + + "Don't remove" in this context means that custom action is removing + SERVICENAME property or CLEANUPDATA property, which later on in course of + installation mean, that either datadir or service is kept. +*/ + +void CheckServiceConfig( + wchar_t *my_servicename, /* SERVICENAME property in this installation*/ + wchar_t *datadir, /* DATADIR property in this installation*/ + wchar_t *bindir, /* INSTALLDIR\bin */ + wchar_t *other_servicename, /* Service to check against */ + QUERY_SERVICE_CONFIGW * config /* Other service's config */ + ) +{ + + bool same_bindir = false; + wchar_t * commandline= config->lpBinaryPathName; + int numargs; + wchar_t **argv= CommandLineToArgvW(commandline, &numargs); + WcaLog(LOGMSG_VERBOSE, "CommandLine= %S", commandline); + if(!argv || !argv[0] || ! wcsstr(argv[0], L"mysqld")) + { + goto end; + } + + WcaLog(LOGMSG_STANDARD, "MySQL service %S found: CommandLine= %S", + other_servicename, commandline); + if (wcsstr(argv[0], bindir)) + { + WcaLog(LOGMSG_STANDARD, "executable under bin directory"); + same_bindir = true; + } + + bool is_my_service = (_wcsicmp(my_servicename, other_servicename) == 0); + if(!is_my_service) + { + WcaLog(LOGMSG_STANDARD, "service does not match current service"); + /* + TODO probably the best thing possible would be to add temporary + row to MSI ServiceConfig table with remove on uninstall + */ + } + else if (!same_bindir) + { + WcaLog(LOGMSG_STANDARD, + "Service name matches, but not the executable path directory, mine is %S", + bindir); + WcaSetProperty(L"SERVICENAME", L""); + } + + /* Check if data directory is used */ + if(!datadir || numargs <= 1 || wcsncmp(argv[1],L"--defaults-file=",16) != 0) + { + goto end; + } + + wchar_t current_datadir_buf[MAX_PATH]={0}; + wchar_t normalized_current_datadir[MAX_PATH+1]; + wchar_t *current_datadir= current_datadir_buf; + wchar_t *defaults_file= argv[1]+16; + defaults_file= strip_quotes(defaults_file); + + WcaLog(LOGMSG_STANDARD, "parsed defaults file is %S", defaults_file); + + if (GetPrivateProfileStringW(L"mysqld", L"datadir", NULL, current_datadir, + MAX_PATH, defaults_file) == 0) + { + WcaLog(LOGMSG_STANDARD, + "Cannot find datadir in ini file '%S'", defaults_file); + goto end; + } + + WcaLog(LOGMSG_STANDARD, "datadir from defaults-file is %S", current_datadir); + strip_quotes(current_datadir); + + /* Convert to Windows path */ + if (GetFullPathNameW(current_datadir, MAX_PATH, normalized_current_datadir, + NULL)) + { + /* Add backslash to be compatible with directory formats in MSI */ + wcsncat(normalized_current_datadir, L"\\", MAX_PATH+1); + WcaLog(LOGMSG_STANDARD, "normalized current datadir is '%S'", + normalized_current_datadir); + } + + if (_wcsicmp(datadir, normalized_current_datadir) == 0 && !same_bindir) + { + WcaLog(LOGMSG_STANDARD, + "database directory from current installation, but different mysqld.exe"); + WcaSetProperty(L"CLEANUPDATA", L""); + } + +end: + LocalFree((HLOCAL)argv); +} + +/* + Checks if database directory or service are modified by user + For example, service may point to different mysqld.exe that it was originally + installed, or some different service might use this database directory. This + would normally mean user has done an upgrade of the database and in this case + uninstall should neither delete service nor database directory. + + If this function find that service is modified by user (mysqld.exe used by + service does not point to the installation bin directory), MSI public variable + SERVICENAME is removed, if DATADIR is used by some other service, variables + DATADIR and CLEANUPDATA are removed. + + The effect of variable removal is that service does not get uninstalled and + datadir is not touched by uninstallation. + + Note that this function is running without elevation and does not use anything + that would require special privileges. + +*/ +extern "C" UINT CheckDBInUse(MSIHANDLE hInstall) +{ + static BYTE buf[256*1024]; /* largest possible buffer for EnumServices */ + static char config_buffer[8*1024]; /*largest buffer for QueryServiceConfig */ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + wchar_t *servicename= NULL; + wchar_t *datadir= NULL; + wchar_t *bindir=NULL; + + SC_HANDLE scm = NULL; + ULONG bufsize = sizeof(buf); + ULONG bufneed = 0x00; + ULONG num_services = 0x00; + LPENUM_SERVICE_STATUS_PROCESS info = NULL; + + hr = WcaInitialize(hInstall, __FUNCTION__); + ExitOnFailure(hr, "Failed to initialize"); + WcaLog(LOGMSG_STANDARD, "Initialized."); + + WcaGetProperty(L"SERVICENAME", &servicename); + WcaGetProperty(L"DATADIR", &datadir); + WcaGetFormattedString(L"[INSTALLDIR]bin\\", &bindir); + WcaLog(LOGMSG_STANDARD,"SERVICENAME=%S, DATADIR=%S, bindir=%S", + servicename, datadir, bindir); + + scm = OpenSCManager(NULL, NULL, + SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT); + if (scm == NULL) + { + ExitOnFailure(E_FAIL, "OpenSCManager failed"); + } + + BOOL ok= EnumServicesStatusExW( scm, + SC_ENUM_PROCESS_INFO, + SERVICE_WIN32, + SERVICE_STATE_ALL, + buf, + bufsize, + &bufneed, + &num_services, + NULL, + NULL); + if(!ok) + { + WcaLog(LOGMSG_STANDARD, "last error %d", GetLastError()); + ExitOnFailure(E_FAIL, "EnumServicesStatusExW failed"); + } + info = (LPENUM_SERVICE_STATUS_PROCESS)buf; + for (ULONG i=0; i < num_services; i++) + { + SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName, + SERVICE_QUERY_CONFIG); + if (!service) + continue; + WcaLog(LOGMSG_VERBOSE, "Checking Service %S", info[i].lpServiceName); + QUERY_SERVICE_CONFIGW *config= + (QUERY_SERVICE_CONFIGW *)(void *)config_buffer; + DWORD needed; + BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer), + &needed); + CloseServiceHandle(service); + if (ok) + { + CheckServiceConfig(servicename, datadir, bindir, info[i].lpServiceName, + config); + } + } + +LExit: + if(scm) + CloseServiceHandle(scm); + + ReleaseStr(servicename); + ReleaseStr(datadir); + ReleaseStr(bindir); + return WcaFinalize(er); +} + +/* + Get maximum size of the buffer process can allocate. + this is calculated as min(RAM,virtualmemorylimit) + For 32bit processes, virtual address memory is 2GB (x86 OS) + or 4GB(x64 OS). + + Fragmentation due to loaded modules, heap and stack + limit maximum size of continous memory block further, + so that limit for 32 bit process is about 1200 on 32 bit OS + or 2000 MB on 64 bit OS(found experimentally). +*/ +unsigned long long GetMaxBufferSize(unsigned long long totalPhys) +{ +#ifdef _M_IX86 + BOOL wow64; + if (IsWow64Process(GetCurrentProcess(), &wow64)) + return min(totalPhys, 2000ULL*ONE_MB); + else + return min(totalPhys, 1200ULL*ONE_MB); +#else + return totalPhys; +#endif +} +/* + Checks SERVICENAME, PORT and BUFFERSIZE parameters +*/ +extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall) +{ + wchar_t ServiceName[MAX_PATH]={0}; + wchar_t SkipNetworking[MAX_PATH]={0}; + wchar_t QuickConfig[MAX_PATH]={0}; + wchar_t Port[6]; + wchar_t BufferPoolSize[16]; + DWORD PortLen=6; + bool haveInvalidPort=false; + const wchar_t *ErrorMsg=0; + HRESULT hr= S_OK; + UINT er= ERROR_SUCCESS; + + + hr = WcaInitialize(hInstall, __FUNCTION__); + ExitOnFailure(hr, "Failed to initialize"); + WcaLog(LOGMSG_STANDARD, "Initialized."); + + DWORD ServiceNameLen = MAX_PATH; + MsiGetPropertyW (hInstall, L"SERVICENAME", ServiceName, &ServiceNameLen); + if(ServiceName[0]) + { + if(ServiceNameLen > 256) + { + ErrorMsg= L"Invalid service name. The maximum length is 256 characters."; + goto LExit; + } + for(DWORD i=0; i< ServiceNameLen;i++) + { + if(ServiceName[i] == L'\\' || ServiceName[i] == L'/' + || ServiceName[i]=='\'' || ServiceName[i] ==L'"') + { + ErrorMsg = + L"Invalid service name. Forward slash and back slash are forbidden." + L"Single and double quotes are also not permitted."; + goto LExit; + } + } + if(CheckServiceExists(ServiceName)) + { + ErrorMsg= + L"A service with the same name already exists. " + L"Please use a different name."; + goto LExit; + } + } + + DWORD SkipNetworkingLen= MAX_PATH; + + MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking, + &SkipNetworkingLen); + MsiGetPropertyW(hInstall, L"PORT", Port, &PortLen); + + if(SkipNetworking[0]==0 && Port[0] != 0) + { + /* Strip spaces */ + for(DWORD i=PortLen-1; i > 0; i--) + { + if(Port[i]== ' ') + Port[i] = 0; + } + + if(PortLen > 5 || PortLen <= 3) + haveInvalidPort = true; + else + { + for (DWORD i=0; i< PortLen && Port[i] != 0;i++) + { + if(Port[i] < '0' || Port[i] >'9') + { + haveInvalidPort=true; + break; + } + } + } + if (haveInvalidPort) + { + ErrorMsg = + L"Invalid port number. Please use a number between 1025 and 65535."; + goto LExit; + } + + short port = (short)_wtoi(Port); + if (!IsPortFree(port)) + { + ErrorMsg = + L"The TCP Port you selected is already in use. " + L"Please choose a different port."; + goto LExit; + } + } + + + DWORD QuickConfigLen = MAX_PATH; + MsiGetPropertyW (hInstall, L"STDCONFIG", QuickConfig, &QuickConfigLen); + if(QuickConfig[0] !=0) + { + MEMORYSTATUSEX memstatus; + memstatus.dwLength =sizeof(memstatus); + wchar_t invalidValueMsg[256]; + + if (!GlobalMemoryStatusEx(&memstatus)) + { + WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx", + GetLastError()); + er= ERROR_INSTALL_FAILURE; + goto LExit; + } + DWORD BufferPoolSizeLen= 16; + MsiGetPropertyW(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize, &BufferPoolSizeLen); + /* Strip spaces */ + for(DWORD i=BufferPoolSizeLen-1; i > 0; i--) + { + if(BufferPoolSize[i]== ' ') + BufferPoolSize[i] = 0; + } + unsigned long long availableMemory= + GetMaxBufferSize(memstatus.ullTotalPhys)/ONE_MB; + swprintf_s(invalidValueMsg, + L"Invalid buffer pool size. Please use a number between 1 and %llu", + availableMemory); + if(BufferPoolSizeLen == 0 || BufferPoolSizeLen > 15) + { + ErrorMsg= invalidValueMsg; + goto LExit; + } + for (DWORD i=0; i < BufferPoolSizeLen && BufferPoolSize[BufferPoolSizeLen]; + i++) + { + if(BufferPoolSize[i]< '0' || BufferPoolSize[i] > '9') + { + ErrorMsg= invalidValueMsg; + goto LExit; + } + } + BufferPoolSize[BufferPoolSizeLen]=0; + MsiSetPropertyW(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize); + long long sz = _wtoi64(BufferPoolSize); + if(sz <= 0 || sz > (long long)availableMemory) + { + if(sz > 0) + { + swprintf_s(invalidValueMsg, + L"Value for buffer pool size is too large." + L"Only approximately %llu MB is available for allocation." + L"Please use a number between 1 and %llu.", + availableMemory, availableMemory); + } + ErrorMsg= invalidValueMsg; + goto LExit; + } + } +LExit: + MsiSetPropertyW (hInstall, L"WarningText", ErrorMsg); + return WcaFinalize(er); +} + +/* + Sets Innodb buffer pool size (1/8 of RAM by default), if not already specified + via command line. + Calculates innodb log file size as min(50, innodb buffer pool size/8) +*/ +extern "C" UINT __stdcall PresetDatabaseProperties(MSIHANDLE hInstall) +{ + unsigned long long InnodbBufferPoolSize= 256; + unsigned long long InnodbLogFileSize= 50; + wchar_t buff[MAX_PATH]; + UINT er = ERROR_SUCCESS; + HRESULT hr= S_OK; + MEMORYSTATUSEX memstatus; + hr = WcaInitialize(hInstall, __FUNCTION__); + ExitOnFailure(hr, "Failed to initialize"); + WcaLog(LOGMSG_STANDARD, "Initialized."); + + /* Check if bufferpoolsize parameter was given on the command line*/ + DWORD BufferPoolsizeParamLen = MAX_PATH; + MsiGetPropertyW(hInstall, L"BUFFERPOOLSIZE", buff, &BufferPoolsizeParamLen); + + if (BufferPoolsizeParamLen && buff[0]) + { + WcaLog(LOGMSG_STANDARD, "BUFFERPOOLSIZE=%s, len=%u",buff, BufferPoolsizeParamLen); + InnodbBufferPoolSize= _wtoi64(buff); + } + else + { + memstatus.dwLength = sizeof(memstatus); + if (!GlobalMemoryStatusEx(&memstatus)) + { + WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx", + GetLastError()); + er= ERROR_INSTALL_FAILURE; + goto LExit; + } + unsigned long long totalPhys= memstatus.ullTotalPhys; + /* Give innodb 12.5% of available physical memory. */ + InnodbBufferPoolSize= totalPhys/ONE_MB/8; + #ifdef _M_IX86 + /* + For 32 bit processes, take virtual address space limitation into account. + Do not try to use more than 3/4 of virtual address space, even if there + is plenty of physical memory. + */ + InnodbBufferPoolSize= min(GetMaxBufferSize(totalPhys)/ONE_MB*3/4, + InnodbBufferPoolSize); + #endif + swprintf_s(buff, L"%llu",InnodbBufferPoolSize); + MsiSetPropertyW(hInstall, L"BUFFERPOOLSIZE", buff); + } + InnodbLogFileSize = min(50, InnodbBufferPoolSize); + swprintf_s(buff, L"%llu",InnodbLogFileSize); + MsiSetPropertyW(hInstall, L"LOGFILESIZE", buff); + +LExit: + return WcaFinalize(er); +} +/* Remove service and data directory created by CreateDatabase operation */ +extern "C" UINT __stdcall CreateDatabaseRollback(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + wchar_t* service= 0; + wchar_t* dir= 0; + + hr = WcaInitialize(hInstall, __FUNCTION__); + ExitOnFailure(hr, "Failed to initialize"); + WcaLog(LOGMSG_STANDARD, "Initialized."); + wchar_t data[2*MAX_PATH]; + DWORD len= MAX_PATH; + MsiGetPropertyW(hInstall, L"CustomActionData", data, &len); + + /* Property is encoded as [SERVICENAME]\[DBLOCATION] */ + if(data[0] == L'\\') + { + dir= data+1; + } + else + { + service= data; + dir= wcschr(data, '\\'); + if (dir) + { + *dir=0; + dir++; + } + } + + if(service) + { + ExecRemoveService(service); + } + if(dir) + { + ExecRemoveDataDirectory(dir); + } +LExit: + return WcaFinalize(er); +} + + +/* + Enables/disables optional "Launch upgrade wizard" checkbox at the end of + installation +*/ +#define MAX_VERSION_PROPERTY_SIZE 64 + +extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + wchar_t* service= 0; + wchar_t* dir= 0; + wchar_t installerVersion[MAX_VERSION_PROPERTY_SIZE]; + char installDir[MAX_PATH]; + DWORD size =MAX_VERSION_PROPERTY_SIZE; + int installerMajorVersion, installerMinorVersion, installerPatchVersion; + bool upgradableServiceFound=false; + + hr = WcaInitialize(hInstall, __FUNCTION__); + WcaLog(LOGMSG_STANDARD, "Initialized."); + if (MsiGetPropertyW(hInstall, L"ProductVersion", installerVersion, &size) + != ERROR_SUCCESS) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + ExitOnFailure(hr, "MsiGetPropertyW failed"); + } + if (swscanf(installerVersion,L"%d.%d.%d", + &installerMajorVersion, &installerMinorVersion, &installerPatchVersion) !=3) + { + assert(FALSE); + } + + size= MAX_PATH; + if (MsiGetPropertyA(hInstall,"INSTALLDIR", installDir, &size) + != ERROR_SUCCESS) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + ExitOnFailure(hr, "MsiGetPropertyW failed"); + } + + + SC_HANDLE scm = OpenSCManager(NULL, NULL, + SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT); + if (scm == NULL) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + ExitOnFailure(hr,"OpenSCManager failed"); + } + + static BYTE buf[64*1024]; + static BYTE config_buffer[8*1024]; + + DWORD bufsize= sizeof(buf); + DWORD bufneed; + DWORD num_services; + BOOL ok= EnumServicesStatusExW(scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, + SERVICE_STATE_ALL, buf, bufsize, &bufneed, &num_services, NULL, NULL); + if(!ok) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + ExitOnFailure(hr,"EnumServicesStatusEx failed"); + } + LPENUM_SERVICE_STATUS_PROCESSW info = + (LPENUM_SERVICE_STATUS_PROCESSW)buf; + int index=-1; + for (ULONG i=0; i < num_services; i++) + { + SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName, + SERVICE_QUERY_CONFIG); + if (!service) + continue; + QUERY_SERVICE_CONFIGW *config= + (QUERY_SERVICE_CONFIGW*)(void *)config_buffer; + DWORD needed; + BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer), + &needed); + CloseServiceHandle(service); + if (ok) + { + mysqld_service_properties props; + if (get_mysql_service_properties(config->lpBinaryPathName, &props)) + continue; + /* + Only look for services that have mysqld.exe outside of the current + installation directory. + */ + if(strstr(props.mysqld_exe,installDir) == 0) + { + WcaLog(LOGMSG_STANDARD, "found service %S, major=%d, minor=%d", + info[i].lpServiceName, props.version_major, props.version_minor); + if(props.version_major < installerMajorVersion + || (props.version_major == installerMajorVersion && + props.version_minor <= installerMinorVersion)) + { + upgradableServiceFound= true; + break; + } + } + } + } + + if(!upgradableServiceFound) + { + /* Disable optional checkbox at the end of installation */ + MsiSetPropertyW(hInstall, L"WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT", L""); + MsiSetPropertyW(hInstall, L"WIXUI_EXITDIALOGOPTIONALCHECKBOX",L""); + } + else + { + MsiSetPropertyW(hInstall, L"UpgradableServiceFound", L"1"); + MsiSetPropertyW(hInstall, L"WIXUI_EXITDIALOGOPTIONALCHECKBOX",L"1"); + } +LExit: + if(scm) + CloseServiceHandle(scm); + return WcaFinalize(er); +} + + +/* DllMain - Initialize and cleanup WiX custom action utils */ +extern "C" BOOL WINAPI DllMain( + __in HINSTANCE hInst, + __in ULONG ulReason, + __in LPVOID + ) +{ + switch(ulReason) + { + case DLL_PROCESS_ATTACH: + WcaGlobalInitialize(hInst); + break; + + case DLL_PROCESS_DETACH: + WcaGlobalFinalize(); + break; + } + + return TRUE; +} diff --git a/win/packaging/ca/CustomAction.def b/win/packaging/ca/CustomAction.def new file mode 100644 index 00000000000..0be77a97a08 --- /dev/null +++ b/win/packaging/ca/CustomAction.def @@ -0,0 +1,10 @@ +LIBRARY "wixca" +VERSION 1.0 +EXPORTS +PresetDatabaseProperties +RemoveDataDirectory +CreateDatabaseRollback +CheckDatabaseProperties +CheckDataDirectoryEmpty +CheckDBInUse +CheckServiceUpgrades diff --git a/win/packaging/ca/CustomAction.rc b/win/packaging/ca/CustomAction.rc new file mode 100644 index 00000000000..3f37126ee77 --- /dev/null +++ b/win/packaging/ca/CustomAction.rc @@ -0,0 +1,18 @@ +#include "afxres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN +END + diff --git a/win/packaging/create_msi.cmake.in b/win/packaging/create_msi.cmake.in new file mode 100644 index 00000000000..d291d06161c --- /dev/null +++ b/win/packaging/create_msi.cmake.in @@ -0,0 +1,445 @@ +SET(CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@") +SET(CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@") +SET(CANDLE_EXECUTABLE "@CANDLE_EXECUTABLE@") +SET(LIGHT_EXECUTABLE "@LIGHT_EXECUTABLE@") +SET(CMAKE_COMMAND "@CMAKE_COMMAND@") +SET(CMAKE_CFG_INTDIR "@CMAKE_CFG_INTDIR@") +SET(VERSION "@VERSION@") +SET(MAJOR_VERSION "@MAJOR_VERSION@") +SET(MINOR_VERSION "@MINOR_VERSION@") +SET(PATCH_VERSION "@PATCH@") +SET(CMAKE_SIZEOF_VOID_P @CMAKE_SIZEOF_VOID_P@) +SET(MANUFACTURER "@MANUFACTURER@") +SET(WIXCA_LOCATION "@WIXCA_LOCATION@") +SET(COPYING_RTF "@COPYING_RTF@") +SET(CPACK_WIX_CONFIG "@CPACK_WIX_CONFIG@") +SET(CPACK_WIX_INCLUDE "@CPACK_WIX_INCLUDE@") +SET(CPACK_WIX_UPGRADE_CODE "@CPACK_WIX_UPGRADE_CODE@") +SET(CPACK_WIX_PACKAGE_NAME "@CPACK_WIX_PACKAGE_NAME@") +SET(CPACK_WIX_PACKAGE_BASE_NAME "@CPACK_WIX_PACKAGE_BASE_NAME@") +SET(SIGNCODE "@SIGNCODE@") +SET(SIGNTOOL_EXECUTABLE "@SIGNTOOL_EXECUTABLE@") +SET(SIGNTOOL_PARAMETERS "@SIGNTOOL_PARAMETERS@") +SET(CMAKE_FULL_VER + "@CMAKE_MAJOR_VERSION@.@CMAKE_MINOR_VERSION@.@CMAKE_PATCH_VERSION@") +SET(EXTRA_WIX_PREPROCESSOR_FLAGS "@EXTRA_WIX_PREPROCESSOR_FLAGS@") +SET(WITH_THIRD_PARTY "@WITH_THIRD_PARTY@") +SET(THIRD_PARTY_DOWNLOAD_LOCATION "@THIRD_PARTY_DOWNLOAD_LOCATION@") +SET(THIRD_PARTY_FEATURE_CONDITION "@THIRD_PARTY_FEATURE_CONDITION@") +SET(LIBMYSQL_LOCATION "@LIBMYSQL_LOCATION@") + +SET($ENV{VS_UNICODE_OUTPUT} "") +IF(LIBMYSQL_LOCATION AND CMAKE_CFG_INTDIR) + # resolve libmysql full path + STRING(REPLACE "${CMAKE_CFG_INTDIR}" "${CMAKE_INSTALL_CONFIG_NAME}" LIBMYSQL_LOCATION "${LIBMYSQL_LOCATION}") +ENDIF() + +FOREACH(third_party ${WITH_THIRD_PARTY}) + INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/${third_party}.cmake) + + # Check than above script produced ${third_party}.wxi and ${third_party}_feature.wxi + FOREACH(outfile ${third_party}.wxi ${third_party}_feature.wxi) + IF(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${outfile}) + MESSAGE(FATAL_ERROR + "${CMAKE_CURRENT_SOURCE_DIR}/${third_party}.cmake did not produce " + "${CMAKE_CURRENT_BINARY_DIR}/${outfile}" + ) + ENDIF() + ENDFOREACH() +ENDFOREACH() + + +IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(CANDLE_ARCH -arch x64) + SET(Win64 " Win64='yes'") + SET(Platform x64) + SET(PlatformProgramFilesFolder ProgramFiles64Folder) +ELSE() + SET(CANDLE_ARCH -arch x86) + SET(Platform x86) + SET(PlatformProgramFilesFolder ProgramFilesFolder) + SET(Win64) +ENDIF() + +SET(ENV{VS_UNICODE_OUTPUT}) +# Workaround for CMake bug#11452 +# Switch off the monolithic install +EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} -DCPACK_MONOLITHIC_INSTALL=0 ${CMAKE_BINARY_DIR} + OUTPUT_QUIET +) + + +INCLUDE(${CMAKE_BINARY_DIR}/CPackConfig.cmake) + +IF(CPACK_WIX_CONFIG) + INCLUDE(${CPACK_WIX_CONFIG}) +ENDIF() + +IF(NOT CPACK_WIX_UI) + SET(CPACK_WIX_UI "MyWixUI_Mondo") +ENDIF() + +IF(CMAKE_INSTALL_CONFIG_NAME) + STRING(REPLACE "${CMAKE_CFG_INTDIR}" "${CMAKE_INSTALL_CONFIG_NAME}" + WIXCA_LOCATION "${WIXCA_LOCATION}") + SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_INSTALL_CONFIG_NAME}") +ENDIF() + + +SET(COMPONENTS_ALL "${CPACK_COMPONENTS_ALL}") +FOREACH(comp ${COMPONENTS_ALL}) + SET(ENV{DESTDIR} testinstall/${comp}) + EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} -DCMAKE_INSTALL_COMPONENT=${comp} + -DCMAKE_INSTALL_PREFIX= -P ${CMAKE_BINARY_DIR}/cmake_install.cmake + OUTPUT_QUIET + + ) + # Exclude empty install components + SET(INCLUDE_THIS_COMPONENT 1) + SET(MANIFEST_FILENAME "${CMAKE_BINARY_DIR}/install_manifest_${comp}.txt") + IF(EXISTS ${MANIFEST_FILENAME}) + FILE(READ ${MANIFEST_FILENAME} content) + STRING(LENGTH "${content}" content_length) + IF (content_length EQUAL 0) + MESSAGE(STATUS "Excluding empty component ${comp}") + SET(INCLUDE_THIS_COMPONENT 0) + ENDIF() + ENDIF() + IF(NOT INCLUDE_THIS_COMPONENT) + LIST(REMOVE_ITEM CPACK_COMPONENTS_ALL "${comp}") + ELSE() + SET(DIRS ${DIRS} testinstall/${comp}) + ENDIF() +ENDFOREACH() + +SET(WIX_FEATURES) +FOREACH(comp ${CPACK_COMPONENTS_ALL}) + STRING(TOUPPER "${comp}" comp_upper) + IF(NOT CPACK_COMPONENT_${comp_upper}_GROUP) + SET(WIX_FEATURE_${comp_upper}_COMPONENTS "${comp}") + SET(CPACK_COMPONENT_${comp_upper}_HIDDEN 1) + SET(CPACK_COMPONENT_GROUP_${comp_upper}_DISPLAY_NAME + ${CPACK_COMPONENT_${comp_upper}_DISPLAY_NAME}) + SET(CPACK_COMPONENT_GROUP_${comp_upper}_DESCRIPTION + ${CPACK_COMPONENT_${comp_upper}_DESCRIPTION}) + SET(CPACK_COMPONENT_GROUP_${comp_upper}_WIX_LEVEL + ${CPACK_COMPONENT_${comp_upper}_WIX_LEVEL}) + SET(WIX_FEATURES ${WIX_FEATURES} WIX_FEATURE_${comp_upper}) + ELSE() + SET(FEATURE_NAME WIX_FEATURE_${CPACK_COMPONENT_${comp_upper}_GROUP}) + SET(WIX_FEATURES ${WIX_FEATURES} ${FEATURE_NAME}) + LIST(APPEND ${FEATURE_NAME}_COMPONENTS ${comp}) + ENDIF() +ENDFOREACH() + +IF(WIX_FEATURES) + LIST(REMOVE_DUPLICATES WIX_FEATURES) +ENDIF() + +SET(CPACK_WIX_FEATURES) + +FOREACH(f ${WIX_FEATURES}) + STRING(TOUPPER "${f}" f_upper) + STRING(REPLACE "WIX_FEATURE_" "" f_upper ${f_upper}) + IF (CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME) + SET(TITLE ${CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME}) + ELSE() + SET(TITLE CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME) + ENDIF() + + IF (CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION) + SET(DESCRIPTION ${CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION}) + ELSE() + SET(DESCRIPTION CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION) + ENDIF() + IF(CPACK_COMPONENT_${f_upper}_WIX_LEVEL) + SET(Level ${CPACK_COMPONENT_${f_upper}_WIX_LEVEL}) + ELSE() + SET(Level 1) + ENDIF() + IF(CPACK_COMPONENT_GROUP_${f_upper}_HIDDEN) + SET(DISPLAY "Display='hidden'") + SET(TITLE ${f_upper}) + SET(DESCRIPTION ${f_upper}) + ELSE() + SET(DISPLAY) + IF(CPACK_COMPONENT_GROUP_${f_upper}_EXPANDED) + SET(DISPLAY "Display='expand'") + ENDIF() + IF (CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME) + SET(TITLE ${CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME}) + ELSE() + SET(TITLE CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME) + ENDIF() + IF (CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION) + SET(DESCRIPTION ${CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION}) + ELSE() + SET(DESCRIPTION CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION) + ENDIF() + ENDIF() + + SET(CPACK_WIX_FEATURES + "${CPACK_WIX_FEATURES} + <Feature Id='${f_upper}' + Title='${TITLE}' + Description='${DESCRIPTION}' + ConfigurableDirectory='INSTALLDIR' + AllowAdvertise='no' + Level='${Level}' ${DISPLAY} >" + ) + FOREACH(c ${${f}_COMPONENTS}) + STRING(TOUPPER "${c}" c_upper) + IF (CPACK_COMPONENT_${c_upper}_DISPLAY_NAME) + SET(TITLE ${CPACK_COMPONENT_${c_upper}_DISPLAY_NAME}) + ELSE() + SET(TITLE CPACK_COMPONENT_${c_upper}_DISPLAY_NAME) + ENDIF() + + IF (CPACK_COMPONENT_${c_upper}_DESCRIPTION) + SET(DESCRIPTION ${CPACK_COMPONENT_${c_upper}_DESCRIPTION}) + ELSE() + SET(DESCRIPTION CPACK_COMPONENT_${c_upper}_DESCRIPTION) + ENDIF() + IF(CPACK_COMPONENT_${c_upper}_WIX_LEVEL) + SET(Level ${CPACK_COMPONENT_${c_upper}_WIX_LEVEL}) + ELSE() + SET(Level 1) + ENDIF() + IF(CPACK_COMPONENT_${c_upper}_HIDDEN) + SET(CPACK_WIX_FEATURES + "${CPACK_WIX_FEATURES} + <ComponentGroupRef Id='componentgroup.${c}'/>") + ELSE() + SET(CPACK_WIX_FEATURES + "${CPACK_WIX_FEATURES} + <Feature Id='${c}' + Title='${TITLE}' + Description='${DESCRIPTION}' + ConfigurableDirectory='INSTALLDIR' + AllowAdvertise='no' + Level='${Level}'> + <ComponentGroupRef Id='componentgroup.${c}'/> + </Feature>") + ENDIF() + + ENDFOREACH() + IF(${f}_EXTRA_FEATURES) + FOREACH(extra_feature ${${f}_EXTRA_FEATURES}) + SET(CPACK_WIX_FEATURES + "${CPACK_WIX_FEATURES} + <FeatureRef Id='${extra_feature}' /> + ") + ENDFOREACH() + ENDIF() + SET(CPACK_WIX_FEATURES + "${CPACK_WIX_FEATURES} + </Feature> + ") +ENDFOREACH() + + + +MACRO(GENERATE_GUID VarName) + EXECUTE_PROCESS(COMMAND uuidgen -c + OUTPUT_VARIABLE ${VarName} + OUTPUT_STRIP_TRAILING_WHITESPACE) +ENDMACRO() + +MACRO(MAKE_WIX_IDENTIFIER str varname) + STRING(REPLACE "/" "." ${varname} "${str}") + STRING(REGEX REPLACE "[^a-zA-Z_0-9.]" "_" ${varname} "${${varname}}") + STRING(LENGTH "${${varname}}" len) + # Identifier should be smaller than 72 character + # We have to cut down the length to 70 chars, since we add 2 char prefix + # pretty often + IF(len GREATER 70) + MATH(EXPR diff "${len}-67") + STRING(SUBSTRING "${${varname}}" ${diff} 67 shortstr) + SET(${varname} "___${shortstr}") + ENDIF() +ENDMACRO() + + + +FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) + FILE(GLOB all_files ${dir}/*) + IF(NOT all_files) + RETURN() + ENDIF() + FILE(RELATIVE_PATH dir_rel ${topdir} ${dir}) + IF(dir_rel) + MAKE_DIRECTORY(${dir_root}/${dir_rel}) + MAKE_WIX_IDENTIFIER("${dir_rel}" id) + SET(DirectoryRefId "D.${id}") + ELSE() + SET(DirectoryRefId "INSTALLDIR") + ENDIF() + FILE(APPEND ${file} "<DirectoryRef Id='${DirectoryRefId}'>\n") + + SET(NONEXEFILES) + FOREACH(f ${all_files}) + IF(NOT IS_DIRECTORY ${f}) + FILE(RELATIVE_PATH rel ${topdir} ${f}) + MAKE_WIX_IDENTIFIER("${rel}" id) + FILE(TO_NATIVE_PATH ${f} f_native) + GET_FILENAME_COMPONENT(f_ext "${f}" EXT) + GET_FILENAME_COMPONENT(name "${f}" NAME) + + IF(name STREQUAL ".empty") + # Create an empty directory + GENERATE_GUID(guid) + FILE(APPEND ${file} " <Component Id='C.${id}' Guid='${guid}' ${Win64}> <CreateFolder/> </Component>\n") + FILE(APPEND ${file_comp} "<ComponentRef Id='C.${id}'/>\n") + ELSEIF(NOT ${file}.COMPONENT_EXCLUDE) + FILE(APPEND ${file} " <Component Id='C.${id}' Guid='*' ${Win64} >\n") + IF(${id}.COMPONENT_CONDITION) + FILE(APPEND ${file} " <Condition>${${id}.COMPONENT_CONDITION}</Condition>\n") + ENDIF() + FILE(APPEND ${file} " <File Id='F.${id}' KeyPath='yes' Source='${f_native}'") + IF(${id}.FILE_EXTRA) + FILE(APPEND ${file} ">\n${${id}.FILE_EXTRA}</File>") + ELSE() + FILE(APPEND ${file} "/>\n") + ENDIF() + FILE(APPEND ${file} " </Component>\n") + FILE(APPEND ${file_comp} " <ComponentRef Id='C.${id}'/>\n") + ENDIF() + ENDIF() + ENDFOREACH() + FILE(APPEND ${file} "</DirectoryRef>\n") + IF(NONEXEFILES) + GENERATE_GUID(guid) + SET(ComponentId "C._files_${COMP_NAME}.${DirectoryRefId}") + MAKE_WIX_IDENTIFIER("${ComponentId}" ComponentId) + FILE(APPEND ${file} + "<DirectoryRef Id='${DirectoryRefId}'>\n<Component Guid='${guid}' + Id='${ComponentId}' ${Win64}>${NONEXEFILES}\n</Component></DirectoryRef>\n") + FILE(APPEND ${file_comp} " <ComponentRef Id='${ComponentId}'/>\n") + ENDIF() + FOREACH(f ${all_files}) + IF(IS_DIRECTORY ${f}) + TRAVERSE_FILES(${f} ${topdir} ${file} ${file_comp} ${dir_root}) + ENDIF() + ENDFOREACH() +ENDFUNCTION() + +FUNCTION(TRAVERSE_DIRECTORIES dir topdir file prefix) + FILE(RELATIVE_PATH rel ${topdir} ${dir}) + IF(rel) + IF (IS_DIRECTORY "${f}") + MAKE_WIX_IDENTIFIER("${rel}" id) + GET_FILENAME_COMPONENT(name ${dir} NAME) + FILE(APPEND ${file} "${prefix}<Directory Id='D.${id}' Name='${name}'>\n") + ENDIF() + ENDIF() + FILE(GLOB all_files ${dir}/*) + FOREACH(f ${all_files}) + IF(IS_DIRECTORY ${f}) + TRAVERSE_DIRECTORIES(${f} ${topdir} ${file} "${prefix} ") + ENDIF() + ENDFOREACH() + IF(rel) + IF(IS_DIRECTORY "${f}") + FILE(APPEND ${file} "${prefix}</Directory>\n") + ENDIF() + ENDIF() +ENDFUNCTION() + +SET(CPACK_WIX_COMPONENTS) +SET(CPACK_WIX_COMPONENT_GROUPS) +GET_FILENAME_COMPONENT(abs . ABSOLUTE) +FOREACH(d ${DIRS}) + GET_FILENAME_COMPONENT(d ${d} ABSOLUTE) + GET_FILENAME_COMPONENT(d_name ${d} NAME) + FILE(WRITE ${abs}/${d_name}_component_group.wxs + "<ComponentGroup Id='componentgroup.${d_name}'>") + SET(COMP_NAME ${d_name}) + TRAVERSE_FILES(${d} ${d} ${abs}/${d_name}.wxs + ${abs}/${d_name}_component_group.wxs "${abs}/dirs") + FILE(APPEND ${abs}/${d_name}_component_group.wxs "</ComponentGroup>") + IF(EXISTS ${d_name}.wxs) + FILE(READ ${d_name}.wxs WIX_TMP) + SET(CPACK_WIX_COMPONENTS "${CPACK_WIX_COMPONENTS}\n${WIX_TMP}") + FILE(REMOVE ${d_name}.wxs) + ENDIF() + + FILE(READ ${d_name}_component_group.wxs WIX_TMP) + + SET(CPACK_WIX_COMPONENT_GROUPS "${CPACK_WIX_COMPONENT_GROUPS}\n${WIX_TMP}") + FILE(REMOVE ${d_name}_component_group.wxs) +ENDFOREACH() + +FILE(WRITE directories.wxs "<DirectoryRef Id='INSTALLDIR'>\n") +TRAVERSE_DIRECTORIES(${abs}/dirs ${abs}/dirs directories.wxs "") +FILE(APPEND directories.wxs "</DirectoryRef>\n") + +FILE(READ directories.wxs CPACK_WIX_DIRECTORIES) +FILE(REMOVE directories.wxs) + + +FOREACH(src ${CPACK_WIX_INCLUDE}) +SET(CPACK_WIX_INCLUDES +"${CPACK_WIX_INCLUDES} + <?include ${src}?>" +) +ENDFOREACH() + + +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql_server.wxs.in + ${CMAKE_CURRENT_BINARY_DIR}/mysql_server.wxs) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/extra.wxs.in + ${CMAKE_CURRENT_BINARY_DIR}/extra.wxs) + +SET(EXTRA_CANDLE_ARGS "$ENV{EXTRA_CANDLE_ARGS}") + +SET(EXTRA_LIGHT_ARGS -cc . -reusecab) +IF("$ENV{EXTRA_LIGHT_ARGS}") + SET(EXTRA_LIGHT_ARGS "$ENV{EXTRA_LIGHT_ARGS}") +ENDIF() + +FILE(REMOVE mysql_server.wixobj extra.wixobj) +EXECUTE_PROCESS( + COMMAND ${CANDLE_EXECUTABLE} + ${EXTRA_WIX_PREPROCESSOR_FLAGS} + ${CANDLE_ARCH} + -ext WixUtilExtension + -ext WixFirewallExtension + mysql_server.wxs + ${EXTRA_CANDLE_ARGS} +) + +EXECUTE_PROCESS( + COMMAND ${CANDLE_EXECUTABLE} ${CANDLE_ARCH} + ${EXTRA_WIX_PREPROCESSOR_FLAGS} + -ext WixUtilExtension + -ext WixFirewallExtension + ${CMAKE_CURRENT_BINARY_DIR}/extra.wxs + ${EXTRA_CANDLE_ARGS} +) + +EXECUTE_PROCESS( + COMMAND ${LIGHT_EXECUTABLE} -ext WixUIExtension -ext WixUtilExtension + -ext WixFirewallExtension + mysql_server.wixobj extra.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi + ${EXTRA_LIGHT_ARGS} +) + +IF(SIGNCODE) + EXECUTE_PROCESS( + COMMAND ${SIGNTOOL_EXECUTABLE} sign ${SIGNTOOL_PARAMETERS} + ${CPACK_PACKAGE_FILE_NAME}.msi +) +ENDIF() +CONFIGURE_FILE(${CPACK_PACKAGE_FILE_NAME}.msi + ${CMAKE_BINARY_DIR}/${CPACK_PACKAGE_FILE_NAME}.msi + COPYONLY) + +# Workaround for CMake bug#11452 +# Switch monolithic install on again +EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} -DCPACK_MONOLITHIC_INSTALL=1 ${CMAKE_BINARY_DIR} + OUTPUT_QUIET +) + diff --git a/win/packaging/custom_ui.wxs b/win/packaging/custom_ui.wxs new file mode 100644 index 00000000000..8a87fb4d246 --- /dev/null +++ b/win/packaging/custom_ui.wxs @@ -0,0 +1,183 @@ +<?xml version="1.0" encoding="UTF-8"?>
+
+
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <Property Id="PortTemplate" Value="####" />
+ <Property Id="PORT" Value="3306"></Property>
+ <Property Id="MSIRESTARTMANAGERCONTROL" Value="Disable"/>
+ <Property Id="CREATEDBINSTANCE"><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Property>
+ <UI>
+ <Dialog Id="DatabaseCreationDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
+ <Control Id="ServiceNameLabel" Type="Text" X="20" Y="73" Width="70" Height="15" TabSkip="no" Text="Service Name:" />
+ <Control Id="ServiceName" Type="Edit" X="90" Y="73" Width="120" Height="15" Property="SERVICENAME" Text="{20}" />
+
+ <Control Id="RootPasswordLabel" Type="Text" X="20" Y="90" Width="120" Height="15" TabSkip="no" Text="&Root password:" />
+ <Control Id="RootPassword" Type="Edit" X="20" Y="105" Width="120" Height="18" Property="ROOT_PASSWORD" Password="yes" Text="{20}" />
+
+ <Control Id="RootPasswordConfirmLabel" Type="Text" X="150" Y="90" Width="150" Height="15" TabSkip="no" Text="&Confirm Root password:" />
+ <Control Id="RootPasswordConfirm" Type="Edit" X="150" Y="105" Width="120" Height="18" Property="ROOT_PASSWORD_CONFIRM" Password="yes" Text="{20}" />
+ <Control Id="BannerLine0" Type="Line" X="0" Y="128" Width="370" Height="0" />
+
+ <Control Id="PortLabel" Type="Text" X="20" Y="137" Width="40" Height="15" TabSkip="no" Text="TCP port:" />
+
+ <Control Id="Port" Type="MaskedEdit" X="60" Y="136" Width="30" Height="15" Property="PORT" Text="[PortTemplate]"/>
+ <!--<Control Id="FirewallExceptionCheckBox" Type="CheckBox" X="150" Y="136" Height="15" Property="FIREWALL_EXCEPTION" Width="200" CheckBoxValue="1"
+ Text="Create Firewall exception for this port"/>-->
+
+ <Control Id="BannerLine2" Type="Line" X="0" Y="155" Width="370" Height="0" />
+
+ <Control Id="FolderLabel" Type="Text" X="20" Y="181" Width="100" Height="15" TabSkip="no" Text="Database location:" />
+ <Control Id="Folder" Type="PathEdit" X="20" Y="204" Width="200" Height="18" Property="DATABASELOCATION" Indirect="no" />
+
+ <!-- Navigation buttons-->
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
+ <Publish Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
+ </Control>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&Next">
+ <!--
+ <Publish Event="ValidateProductID" Value="0">1</Publish>
+ <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">CostingComplete = 1</Publish>
+ -->
+ <!--<Publish Event="NewDialog" Value="SetupTypeDlg">ProductID</Publish>-->
+ </Control>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>Create default [ProductName] instance</Text>
+ </Control>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>{\WixUI_Font_Title}Default instance properties</Text>
+ </Control>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
+ </Dialog>
+
+ <Dialog Id="ConfirmDataCleanupDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
+ <Control Id="ServiceRemoveText" Type="Text" X="20" Y="73" Width="300" Height="15" TabSkip="no">
+ <Text>Service '[SERVICENAME]' will be removed</Text>
+ </Control>
+ <Control Id="CleanupDataCheckBox" Type="CheckBox" X="20" Y="100" Height="15" Property="CLEANUP_DATA" Width="15" CheckBoxValue="0"/>
+ <Control Id="RemoveDataText" Type="Text" X="37" Y="101" Width="300" Height="200" TabSkip="no">
+ <Text>Remove default database directory '[DATABASELOCATION]'</Text>
+ </Control>
+
+ <!-- Navigation buttons-->
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
+ <Publish Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
+ </Control>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&Next">
+ <Publish Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ </Control>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>Remove default [ProductName] database</Text>
+ </Control>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>{\WixUI_Font_Title}Default instance properties</Text>
+ </Control>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
+ </Dialog>
+ </UI>
+ <UI Id="MyWixUI_Mondo">
+ <UIRef Id="WixUI_FeatureTree" />
+ <UIRef Id="WixUI_ErrorProgressText" />
+ <DialogRef Id="DatabaseCreationDlg" />
+ <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="DatabaseCreationDlg" Order="999"><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Publish>
+ <Publish Dialog="DatabaseCreationDlg" Control="Back" Event="NewDialog" Value="CustomizeDlg" Order="3">1</Publish>
+ <Publish Dialog="DatabaseCreationDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="3">1</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="DatabaseCreationDlg" Order="3" ><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="3" ><![CDATA[(&DBInstance=2) AND (!DBInstance=3)]]></Publish>
+ <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="999"><![CDATA[(&DBInstance=2) AND (!DBInstance=3)]]></Publish>
+ <Publish Dialog="ConfirmDataCleanupDlg" Control="Back" Event="NewDialog" Value="CustomizeDlg">WixUI_InstallMode = "Change"</Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="999">!DBInstance=3</Publish>
+ <Publish Dialog="ConfirmDataCleanupDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg">WixUI_InstallMode = "Remove"</Publish>
+ </UI>
+
+ <DirectoryRef Id='TARGETDIR'>
+ <Directory Id="CommonAppDataFolder">
+ <Directory Id="DatabasesRoot" Name="MariaDB">
+ <Directory Id="DATABASELOCATION" Name="MariaDB Server 5.1">
+ </Directory>
+ </Directory>
+ </Directory>
+ </DirectoryRef>
+
+ <Feature Id='DBInstance'
+ Title='Database instance'
+ Description='Install database instance'
+ ConfigurableDirectory='DATABASELOCATION'
+ AllowAdvertise='no'
+ Level='1'>
+ <Component Id="C.datadir" Guid="*" Directory="DATABASELOCATION">
+ <RegistryValue Root='HKLM'
+ Key='SOFTWARE\[Manufacturer]\[ProductName]'
+ Name='DatabaseLocation' Value='[DATABASELOCATION]' Type='string' KeyPath='yes'/>
+ <CreateFolder />
+ </Component>
+ <Component Id="C.service" Guid="*" Directory="DATABASELOCATION">
+ <Condition>SERVICENAME</Condition>
+ <RegistryValue Root='HKLM'
+ Key='SOFTWARE\[Manufacturer]\[ProductName]'
+ Name='ServiceName' Value='[SERVICENAME]' Type='string' KeyPath='yes'/>
+ <ServiceControl Id='DBInstanceServiceStop' Name='[SERVICENAME]' Stop='uninstall' Wait='yes'></ServiceControl>
+ <ServiceControl Id='DBInstanceServiceStart' Name='[SERVICENAME]' Start='install' Wait='no'></ServiceControl>
+ <ServiceControl Id='DBInstanceServiceRemove' Name='[SERVICENAME]' Remove='uninstall' Wait='yes'></ServiceControl>
+ </Component>
+ </Feature>
+
+ <CustomAction Id="QtExecDeferredExampleWithProperty_Cmd" Property="QtExecDeferredExampleWithProperty"
+ Value=""[#F.bin.mysql_install_db.exe]" "--service=[SERVICENAME]" "--password=[ROOT_PASSWORD]" "--datadir=[DATABASELOCATION]""
+ Execute="immediate"/>
+ <CustomAction Id="QtExecDeferredExampleWithProperty" BinaryKey="WixCA" DllEntry="CAQuietExec"
+ Execute="deferred" Return="check" Impersonate="no"/>
+
+ <UI>
+ <ProgressText Action="QtExecDeferredExampleWithProperty">Running mysql_install_db.exe</ProgressText>
+ </UI>
+
+ <!-- Use Wix toolset "remember property" pattern to store properties between major upgrades etc -->
+ <InstallExecuteSequence>
+ <Custom Action="QtExecDeferredExampleWithProperty_Cmd" After="CostFinalize"><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Custom>
+ <Custom Action="QtExecDeferredExampleWithProperty" After="InstallFiles"><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Custom>
+ </InstallExecuteSequence>
+
+ <Property Id='SERVICENAME'>
+ <RegistrySearch Id='ServiceNameProperty' Root='HKLM'
+ Key='SOFTWARE\[Manufacturer]\[ProductName]'
+ Name='ServiceName' Type='raw' />
+ </Property>
+ <SetProperty After='AppSearch' Id="SERVICENAME" Value="MariaDB_51"><![CDATA[NOT SERVICENAME]]></SetProperty>
+ <Property Id="DATABASELOCATION">
+ <RegistrySearch Id='DatabaseLocationProperty' Root='HKLM'
+ Key='SOFTWARE\[Manufacturer]\[ProductName]'
+ Name='´DatabaseLocation' Type='raw' />
+ </Property>
+ <SetProperty After='AppSearch' Id="DATABASELOCATION" Value="[CommonAppDataFolder]\MariaDB\[ProductName]"><![CDATA[NOT DATABASELOCATION]]></SetProperty>
+ <CustomAction Id='SaveCmdLineValue_SERVICENAME' Property='CMDLINE_SERVICENAME'
+ Value='[SERVICENAME]' Execute='firstSequence' />
+ <CustomAction Id='SetFromCmdLineValue_SERVICENAME' Property='SERVICENAME' Value='[CMDLINE_SERVICENAME]' Execute='firstSequence' />
+ <CustomAction Id='SaveCmdLineValue_DATABASELOCATION' Property='CMDLINE_DATABASELOCATION'
+ Value='[DATABASELOCATION]' Execute='firstSequence' />
+ <CustomAction Id='SetFromCmdLineValue_DATABASELOCATION' Property='DATABASELOCATION' Value='[CMDLINE_DATABASELOCATION]' Execute='firstSequence' />
+
+ <InstallUISequence>
+ <Custom Action='SaveCmdLineValue_SERVICENAME' Before='AppSearch' />
+ <Custom Action='SetFromCmdLineValue_SERVICENAME' After='AppSearch'>CMDLINE_SERVICENAME</Custom>
+ <Custom Action='SaveCmdLineValue_DATABASELOCATION' Before='AppSearch' />
+ <Custom Action='SetFromCmdLineValue_DATABASELOCATION' After='AppSearch'>CMDLINE_DATABASELOCATION</Custom>
+ </InstallUISequence>
+ <InstallExecuteSequence>
+ <Custom Action='SaveCmdLineValue_SERVICENAME' Before='AppSearch' />
+ <Custom Action='SetFromCmdLineValue_SERVICENAME' After='AppSearch'>CMDLINE_SERVICENAME</Custom>
+ <Custom Action='SaveCmdLineValue_DATABASELOCATION' Before='AppSearch' />
+ <Custom Action='SetFromCmdLineValue_DATABASELOCATION' After='AppSearch'>CMDLINE_DATABASELOCATION</Custom>
+ </InstallExecuteSequence>
+ </Fragment>
+</Wix>
\ No newline at end of file diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in new file mode 100644 index 00000000000..37b12575328 --- /dev/null +++ b/win/packaging/extra.wxs.in @@ -0,0 +1,887 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
+ <Fragment>
+ <!--
+ Check, if upgrade wizard was built
+ It currently requires MFC, which is not in SDK
+ neither in express edÃtions of VS.
+ -->
+ <?ifndef HaveUpgradeWizard ?>
+ <?define HaveUpgradeWizard="1"?>
+ <?endif?>
+
+ <!-- If Innodb is compiled in, enable "optimize for transactions" checkbox -->
+ <?ifndef HaveInnodb ?>
+ <?define HaveInnodb="0"?>
+ <?endif?>
+
+ <Property Id="PortTemplate" Value="#####" />
+ <?if $(var.HaveInnodb) = "1" ?>
+ <Property Id="BufferPoolSizeTemplate" Value="#######" />
+ <?endif?>
+ <!--
+ Installation parameters that can be passed via msiexec command line
+ For "booleans" (like skip networking), just providing any value means property set to "yes".
+ -->
+ <!-- instalation directory (default under program files)-->
+ <!--- (defined elsewhere) <Property Id="INSTALLDIR" Secure="yes" /> -->
+
+ <!-- Database data directory (default under INSTALLDIR\data) -->
+ <!--- (defined elsewhere) <Property Id="DATADIR" Secure="yes"/> -->
+
+ <!-- Service name of database instanced (default MySQL in GUI, nothing with command line) -->
+ <!-- (defined elsewhere) <Property Id="SERVICENAME" Secure="yes" /> -->
+
+ <!-- Root password -->
+ <Property Id="PASSWORD" Hidden="yes" Secure="yes" />
+ <!-- Database port -->
+ <Property Id="PORT" Value="3306" Secure="yes"/>
+ <!-- Whether to allow remote access for root user -->
+ <Property Id="ALLOWREMOTEROOTACCESS" Secure="yes" />
+ <!-- Skip networking. This will switch configuration to use named pipe-->
+ <Property Id="SKIPNETWORKING" Secure="yes"/>
+ <!-- Whether to keep default (unauthenticated) user. Default is no-->
+ <Property Id="DEFAULTUSER" Secure="yes"/>
+ <!-- Whether to data on uninstall (default yes, after asking user consent) -->
+ <Property Id="CLEANUPDATA" Secure="yes" Value="1"/>
+ <!-- Force per machine installation -->
+ <Property Id="ALLUSERS" Secure="yes" Value="1"/>
+ <!-- Disable advertised shortcuts weirdness -->
+ <Property Id="DISABLEADVTSHORTCUTS" Secure="yes" Value="1"/>
+
+ <!-- Activate feedback plugin-->
+ <Property Id="FEEDBACK" Secure="yes"/>
+
+ <?if $(var.HaveInnodb) = "1" ?>
+ <!-- Quick configuration : set default storage engine to innodb, use strict sql_mode -->
+ <Property Id="STDCONFIG" Secure="yes" Value="1"/>
+ <?endif?>
+ <!-- Innodb Buffer pool size in MB-->
+ <Property Id="BUFFERPOOLSIZE" Secure="yes"/>
+
+
+ <CustomAction Id="LaunchUrl" BinaryKey="WixCA" DllEntry="WixShellExec" Execute="immediate" Return="check" Impersonate="yes" />
+
+
+ <!--
+ User interface dialogs
+ -->
+ <WixVariable Id='WixUIBannerBmp' Value='@CMAKE_CURRENT_SOURCE_DIR@\WixUIBannerBmp.jpg' />
+ <WixVariable Id='WixUIDialogBmp' Value='@CMAKE_CURRENT_SOURCE_DIR@\WixUIDialogBmp.jpg' />
+ <UI>
+
+ <!-- Dialog on uninstall of the database -->
+ <Dialog Id="ConfirmDataCleanupDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
+
+ <!--<Control Id="CleanupDataCheckBox" Type="CheckBox" X="20" Y="100" Height="30" Property="CLEANUPDATA" Width="300" CheckBoxValue="1"
+ Text="{\Font1}Remove default database directory 
'[DATADIR]'"/>
+ -->
+ <Control Id="RemoveDatadirButton" Type="PushButton" X="40" Y="65" Width="80" Height="18"
+ Text="Remove data">
+ <Publish Property="CLEANUPDATA" Value="1">1</Publish>
+ <Publish Event="NewDialog" Value="VerifyReadyDlg">WixUI_InstallMode</Publish>
+ <Publish Event="EndDialog" Value="Return">NOT WixUI_InstallMode</Publish>
+
+ </Control>
+ <Control Id="RemoveDatadirText" Type="Text" X="60" Y="85" Width="280" Height="20">
+ <Text>Remove default database directory [DATADIR]. Ensures proper cleanup on uninstall.</Text>
+ </Control>
+
+ <Control Id="KeepDatadirButton" Type="PushButton" X="40" Y="118" Width="80" Height="18"
+ Text="Keep data">
+ <Publish Property="CLEANUPDATA">1</Publish>
+ <Publish Event="NewDialog" Value="VerifyReadyDlg">WixUI_InstallMode</Publish>
+ <Publish Event="EndDialog" Value="Return">NOT WixUI_InstallMode</Publish>
+ </Control>
+ <Control Id="KeepDataDirText" Type="Text" X="60" Y="138" Width="280" Height="70" >
+ <Text>Do not remove [DATADIR]. Choose this option if you intend to use data in the future</Text>
+ </Control>
+
+
+ <!-- Navigation buttons-->
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
+ <Publish Event="NewDialog" Value="CustomizeDlg">WixUI_InstallMode="Change"</Publish>
+ <Condition Action="disable">NOT WixUI_InstallMode</Condition>
+ </Control>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Disabled="yes" Text="&Next">
+ <Publish Event="NewDialog" Value="VerifyReadyDlg">WixUI_InstallMode</Publish>
+ <Publish Event="EndDialog" Value="Return">NOT WixUI_InstallMode</Publish>
+ </Control>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>Remove default [ProductName] database</Text>
+ </Control>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>{\WixUI_Font_Title}Default instance properties</Text>
+ </Control>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
+ </Dialog>
+
+ <!-- Dialog new or upgrade instance -->
+
+ <Property Id="CreateOrUpgradeChoice" Value="Create"/>
+
+ <Dialog Id="NewOrUpgradeInstanceDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
+ <Control Id="Text" Type="Text" X="40" Y="65" Width="270" Height="30">
+ <Text>Setup found existing database instances that can be upgraded to [ProductName].You can create a new instance and/or upgrade existing one.
+ </Text>
+ </Control>
+
+ <Control Id="CreateOrUpgradeButton"
+ Type="RadioButtonGroup" X="40" Y="100" Width="300" Height="70"
+ Property="CreateOrUpgradeChoice" Text="Specify what to do">
+ <RadioButtonGroup Property="CreateOrUpgradeChoice">
+ <RadioButton Value="Create" X="0" Y="0" Width="300" Height="25"
+ Text="{\Font1}Create new database instance."/>
+ <RadioButton Value="Upgrade" X="0" Y="30" Width="300" Height="25"
+ Text="{\Font1}Do not create a new database. Optionally upgrade existing instances." />
+ </RadioButtonGroup>
+ </Control>
+
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
+ <Publish Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
+ </Control>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Text="&Next">
+ <Publish Event="Remove" Value="DBInstance">CreateOrUpgradeChoice = "Upgrade" </Publish>
+ <Publish Event="AddLocal" Value="DBInstance">CreateOrUpgradeChoice = "Create"</Publish>
+ <Publish Event="NewDialog" Value="CustomizeDlg">1</Publish>
+ </Control>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>Create or upgrade database instance</Text>
+ </Control>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>{\WixUI_Font_Title}[ProductName] setup</Text>
+ </Control>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
+ </Dialog>
+
+ <!-- Feedback dialog -->
+ <Dialog Id="Feedback" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
+
+ <Control Id="CheckBoxFeedback" Type="CheckBox" X="8" Y="61" Width="360" Height="12" Property="FEEDBACK" CheckBoxValue="1" TabSkip="no">
+ <Text>{\Font1}Enable the Feedback plugin and submit anonymous usage information</Text>
+ </Control>
+
+ <Control Id="Text" Type="Text" X="23" Y="82" Width="290" Height="55">
+ <Text>Monty Program has created a Feedback plugin for MariaDB which, if enabled, collects basic anonymous statistical information. This information is used by the developers to improve MariaDB. Enabling this plugin is an easy way to help with MariaDB development. Collected statistics, and more information on the plugin, can be viewed at http://mariadb.org/feedback_plugin </Text>
+ </Control>
+
+ <Control Id="MoreInfo" Type="PushButton" X="23" Y="140" Width="56" Height="17" Text="More Info" ToolTip="http://mariadb.org/feedback_plugin" >
+ <Publish Property="WixShellExecTarget" Value="http://mariadb.org/feedback_plugin" Order="1">1</Publish>
+ <Publish Event="DoAction" Value="LaunchUrl" Order="2">1</Publish>
+ </Control>
+
+
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
+ <Publish Event="NewDialog" Value="ServicePortDlg">1</Publish>
+ </Control>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Text="&Next">
+ <Publish Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ </Control>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>Submit usage information</Text>
+ </Control>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>{\WixUI_Font_Title}[ProductName] setup</Text>
+ </Control>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
+ </Dialog>
+
+ <!-- Error popup dialog -->
+ <Dialog Id="WarningDlg" Width="320" Height="85" Title="[ProductName] Setup" NoMinimize="yes">
+ <Control Id="Icon" Type="Icon" X="15" Y="15" Width="24" Height="24"
+ ToolTip="Information icon" FixedSize="yes" IconSize="32" Text="WixUI_Ico_Info" />
+ <Control Id="Ok" Type="PushButton" X="132" Y="57" Width="56" Height="17"
+ Default="yes" Cancel="yes" Text="OK">
+ <Publish Property="WarningText">1</Publish>
+ <Publish Event="EndDialog" Value="Return">1</Publish>
+ </Control>
+ <Control Id="Text" Type="Text" X="48" Y="15" Width="260" Height="30">
+ <Text>[WarningText]</Text>
+ </Control>
+ </Dialog>
+
+
+ <Property Id="ModifyRootPassword" Value="1"/>
+ <TextStyle Id="Font1" FaceName="Tahoma" Size="8" Red="0" Green="0" Blue="0" Bold="yes" />
+
+ <!-- Root password plus default user dialog -->
+ <Dialog Id="UserSettingsDlg" X="50" Y="50" Width="370" Height="270" Title="User settings">
+ <Control Id="EditRootPassword" Type="Edit" X="104" Y="82" Width="91" Height="15" Property="PASSWORD" Password="yes" TabSkip="no">
+ <Text>{100}</Text>
+ <Condition Action="enable">ModifyRootPassword</Condition>
+ <Condition Action="disable">NOT ModifyRootPassword</Condition>
+ </Control>
+ <Control Id="EditRootPasswordConfirm" Type="Edit" X="104" Y="103" Width="91" Height="15" Property="RootPasswordConfirm" Password="yes" TabSkip="no">
+ <Text>{100}</Text>
+ <Condition Action="enable">ModifyRootPassword</Condition>
+ <Condition Action="disable">NOT ModifyRootPassword</Condition>
+ </Control>
+
+ <Control Id="CheckBoxModifyRootPassword" Type="CheckBox" X="8" Y="62" Width="222" Height="18" Property="ModifyRootPassword" CheckBoxValue="1" TabSkip="no">
+ <Text>{\Font1}Modify root password</Text>
+ <Publish Property="PASSWORD" >NOT ModifyRootPassword</Publish>
+ <Publish Property="RootPasswordConfirm">NOT ModifyRootPassword</Publish>
+ <Publish Property="ALLOWREMOTEROOTACCESS">NOT ModifyRootPassword</Publish>
+ <Publish Property="ALLOWREMOTEROOTACCESS" Value="1">ModifyRootPassword</Publish>
+ </Control>
+
+ <Control Id="Text5" Type="Text" X="23" Y="82" Width="77" Height="14" TabSkip="yes">
+ <Text>New root password:</Text>
+ </Control>
+ <Control Id="Text6" Type="Text" X="201" Y="85" Width="100" Height="17" TabSkip="yes">
+ <Text>Enter new root password</Text>
+ </Control>
+ <Control Id="Text8" Type="Text" X="23" Y="105" Width="75" Height="17" TabSkip="yes">
+ <Text>Confirm:</Text>
+ </Control>
+
+ <Control Id="Text10" Type="Text" X="201" Y="104" Width="100" Height="17" TabSkip="yes">
+ <Text>Retype the password</Text>
+ </Control>
+ <Control Id="CheckBoxALLOWREMOTEROOTACCESS" Type="CheckBox" X="23" Y="122" Width="196" Height="18" Property="ALLOWREMOTEROOTACCESS"
+ CheckBoxValue="--allow-remote-root-access" TabSkip="no">
+ <Text>{\Font1}Enable root access from remote machines</Text>
+ <Condition Action="enable">ModifyRootPassword</Condition>
+ <Condition Action="disable">NOT ModifyRootPassword</Condition>
+ </Control>
+
+ <Control Id="CheckBoxCreateDefaultUser" Type="CheckBox" X="8" Y="154" Width="200" Height="18" Property="DEFAULTUSER"
+ CheckBoxValue="--default-user" TabSkip="no">
+ <Text>{\Font1}Create An Anonymous Account</Text>
+ </Control>
+ <Control Id="Text14" Type="Text" X="21" Y="174" Width="268" Height="16" TabSkip="yes">
+ <Text>This option will create an anonymous account on this server. </Text>
+ </Control>
+ <Control Id="Text13" Type="Text" X="21" Y="190" Width="254" Height="24" TabSkip="yes">
+ <Text>Please note: this setting can lead to insecure systems.</Text>
+ </Control>
+
+ <!-- Navigation buttons-->
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
+ <Publish Event="NewDialog" Value="CustomizeDlg">1</Publish>
+ </Control>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&Next">
+ <Publish Property="WarningText" Value="Passwords do not match."><![CDATA[PASSWORD <> RootPasswordConfirm]]></Publish>
+ <Publish Event="SpawnDialog" Value="WarningDlg"><![CDATA[WarningText <>""]]></Publish>
+ <Publish Property="SERVICENAME" Value="MySQL">NOT SERVICENAME AND NOT WarningText</Publish>
+ <Publish Event="NewDialog" Value="ServicePortDlg"><![CDATA[WarningText=""]]></Publish>
+ <Condition Action="enable"><![CDATA[NOT ModifyRootPassword OR PASSWORD]]> </Condition>
+ <Condition Action="disable"><![CDATA[ModifyRootPassword AND (NOT PASSWORD)]]> </Condition>
+ </Control>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text> [ProductName] database configuration</Text>
+ </Control>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>{\WixUI_Font_Title}Default instance properties</Text>
+ </Control>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
+ </Dialog>
+
+ <Property Id="InstallService" Value="1"/>
+ <Property Id="EnableNetworking" Value="1"/>
+
+ <!-- Service and port configuration -->
+ <Dialog Id="ServicePortDlg" Width="370" Height="270" Title="Database settings">
+ <Control Id="InstallAsService" Type="CheckBox" X="9" Y="61" Width="222" Height="19" Property="InstallService" CheckBoxValue="1" TabSkip="no">
+ <Text>{\Font1}Install as service</Text>
+ </Control>
+ <Control Id="EditServiceName" Type="Edit" X="104" Y="82" Width="91" Height="15" Property="SERVICENAME" TabSkip="no">
+ <Text>{20}</Text>
+ <Condition Action="enable">InstallService</Condition>
+ <Condition Action="disable">Not InstallService</Condition>
+ </Control>
+ <Control Id="Text5" Type="Text" X="25" Y="82" Width="77" Height="14" TabSkip="yes">
+ <Text>Service Name:</Text>
+ </Control>
+ <Control Id="CheckBoxEnableNetworking" Type="CheckBox" Height="18" Width="102" X="9" Y="117" Property="EnableNetworking" CheckBoxValue="1">
+ <Text>{\Font1}Enable networking</Text>
+ <!--<Publish Property="PORT">NOT EnableNetworking</Publish>-->
+ <Publish Property="SKIPNETWORKING" Value="--skip-networking">NOT EnableNetworking</Publish>
+ <Publish Property="SKIPNETWORKING">EnableNetworking</Publish>
+ </Control>
+ <Control Id="LabelTCPPort" Type="Text" Height="17" Width="75" X="25" Y="142" Text="TCP port:" />
+ <Control Id="Port" Type="MaskedEdit" X="104" Y="140" Width="28" Height="15" Property="PORT" Sunken="yes" Text="[PortTemplate]">
+ <Condition Action="enable" >EnableNetworking</Condition>
+ <Condition Action="disable">Not EnableNetworking</Condition>
+ </Control>
+
+ <?if $(var.HaveInnodb) = "1" ?>
+ <Control Id="CheckBoxStandardConfig" Type="CheckBox" Height="18" Width="220" X="9" Y="171" Property="STDCONFIG" CheckBoxValue="1">
+ <Text>{\Font1}Optimize for transactions</Text>
+ </Control>
+
+ <Control Id="StandardConfigExplain" Type="Text" X="25" Y="190" Width="270" Height="14" TabSkip="yes">
+ <Text>(Uses transactional storage engine and "strict" SQL mode)</Text>
+ <Condition Action="enable" >STDCONFIG</Condition>
+ <Condition Action="disable">Not STDCONFIG</Condition>
+ </Control>
+ <Control Id="LabelInnodbBufferpool" Type="Text" Height="17" Width="77" X="25" Y="210" Text="Buffer pool size:" >
+ <Condition Action="enable" >STDCONFIG</Condition>
+ <Condition Action="disable">Not STDCONFIG</Condition>
+ </Control>
+ <Control Id="BPSize" Type="MaskedEdit" X="104" Y="208" Width="40" Height="15" Property="BUFFERPOOLSIZE" Sunken="yes" Text="[BufferPoolSizeTemplate]">
+ <Condition Action="enable" >STDCONFIG</Condition>
+ <Condition Action="disable">Not STDCONFIG</Condition>
+ </Control>
+ <Control Id="LabelMB" Type="Text" Height="17" Width="15" X="150" Y="210" Text="MB" >
+ <Condition Action="enable" >STDCONFIG</Condition>
+ <Condition Action="disable">Not STDCONFIG</Condition>
+ </Control>
+ <?endif?>
+
+ <!-- Navigation buttons-->
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
+ <Publish Event="NewDialog" Value="UserSettingsDlg">1</Publish>
+ </Control>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="no" Text="&Next">
+ <Publish Property="SERVICENAME">NOT InstallService</Publish>
+ <Publish Property="WarningText" Value="Please enter valid port or uncheck 'Enable Networking' checkbox">
+ <![CDATA[EnableNetworking AND NOT PORT AND NOT WarningText]]>
+ </Publish>
+ <Publish Property="WarningText" Value="Please enter valid service name port or uncheck 'Install Service' checkbox">
+ <![CDATA[InstallService AND NOT SERVICENAME AND NOT WarningText]]>
+ </Publish>
+ <Publish Event="DoAction" Value="CheckDatabaseProperties">NOT WarningText</Publish>
+ <Publish Event="SpawnDialog" Value="WarningDlg">WarningText</Publish>
+ <Publish Event="NewDialog" Value="Feedback">Not WarningText</Publish>
+ </Control>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="no" Text="Cancel">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>[ProductName] database configuration</Text>
+ </Control>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="2" />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>{\WixUI_Font_Title}Default instance properties</Text>
+ </Control>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="2" />
+ </Dialog>
+ </UI>
+
+ <Property Id="CRLF" Value="
" />
+ <CustomAction Id="CheckDataDirectoryEmpty" BinaryKey="wixca.dll" DllEntry="CheckDataDirectoryEmpty" Execute="immediate" Impersonate="yes"/>
+ <!-- What to do when navigation buttons are clicked -->
+ <UI Id="MyWixUI_Mondo">
+ <UIRef Id="WixUI_FeatureTree" />
+ <UIRef Id="WixUI_ErrorProgressText" />
+ <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="999">
+ OLDERVERSIONBEINGUPGRADED
+ </Publish>
+ <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="NewOrUpgradeInstanceDlg" Order="999">
+ NOT Installed AND UpgradableServiceFound
+ </Publish>
+
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="Feedback" Order="3" ><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="3"> <![CDATA[OLDERVERSIONBEINGUPGRADED <>""]]></Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="1" ><![CDATA[(&DBInstance=2) AND (!DBInstance=3)]]></Publish>
+
+
+ <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="NewOrUpgradeInstanceDlg" Order="999">
+ NOT Installed AND UpgradableServiceFound
+ </Publish>
+ <Publish Dialog="CustomizeDlg" Control="Next" Event="DoAction" Value="CheckDataDirectoryEmpty" Order="1"><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Publish>
+ <Publish Dialog="CustomizeDlg" Property="DATADIRNOTEMPTY" Control="Next" Order="1"><![CDATA[NOT(&DBInstance=3 AND NOT !DBInstance=3)]]></Publish>
+ <Publish Dialog="CustomizeDlg" Control="Next" Property="WarningText" Order="2"
+ Value="Selected data directory [DATADIR] is not empty. Either clean it, or choose another location for 'Database Instance' feature.">
+ DATADIRNOTEMPTY
+ </Publish>
+ <Publish Dialog="CustomizeDlg" Control="Next" Event="SpawnDialog" Value="WarningDlg" Order="3">WarningText</Publish>
+ <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="4">
+ <![CDATA[(&DBInstance=2) AND (!DBInstance=3)]]>
+ </Publish>
+ <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="UserSettingsDlg" Order="5">
+ <![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND NOT WarningText]]>
+ </Publish>
+
+ <Publish Dialog="ConfirmDataCleanupDlg" Control="Back" Event="NewDialog" Value="CustomizeDlg">WixUI_InstallMode = "Change"</Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="999">
+ !DBInstance=3 AND (CLEANUPDATA Or USECONFIRMDATACLEANUPDLG)
+ </Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Property="USECONFIRMDATACLEANUPDLG" Value="1" Order="999">
+ !DBInstance=3 AND CLEANUPDATA
+ </Publish>
+ <Publish Dialog="ConfirmDataCleanupDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg">WixUI_InstallMode = "Remove"</Publish>
+ </UI>
+
+ <!-- End of UI section -->
+
+ <!-- Extra folders we need (DATADIR and shortcut folder) -->
+ <DirectoryRef Id='INSTALLDIR'>
+ <Directory Id="DATADIR" Name="data">
+ </Directory>
+ <Directory Id="ProgramMenuFolder">
+ <Directory Id="ShortcutFolder" Name="@CPACK_WIX_PACKAGE_NAME@">
+ </Directory>
+ </Directory>
+ </DirectoryRef>
+
+
+ <!-- Extra feature (database instance). This could be split to several subfeatures if desired (e.g firewall exception)-->
+ <Feature Id='DBInstance'
+ Title='Database instance'
+ Description=
+ 'Install database instance. Only new database can be installed with this feature.'
+ ConfigurableDirectory='DATADIR'
+ AllowAdvertise='no'
+ Level='1'>
+
+ <!-- Data directory with some reasonable security settings -->
+ <Component Id="C.datadir" Guid="*" Directory="DATADIR">
+ <RegistryValue Root='HKLM'
+ Key='SOFTWARE\@MANUFACTURER@\@CPACK_WIX_PACKAGE_NAME@'
+ Name='DATADIR' Value='[DATADIR]' Type='string' KeyPath='yes'/>
+ <CreateFolder>
+ <util:PermissionEx User="[LogonUser]" GenericAll="yes" />
+ <util:PermissionEx User="NetworkService" GenericAll="yes" />
+ </CreateFolder>
+ </Component>
+
+ <!-- Database service conditioned on SERVICENAME property-->
+ <Component Id="C.service" Guid="*" Directory="DATADIR">
+ <Condition>SERVICENAME</Condition>
+ <RegistryValue Root='HKLM'
+ Key='SOFTWARE\@MANUFACTURER@\@CPACK_WIX_PACKAGE_NAME@'
+ Name='SERVICENAME' Value='[SERVICENAME]' Type='string' KeyPath='yes'/>
+ <ServiceControl Id='DBInstanceServiceStop' Name='[SERVICENAME]' Stop='both' Remove='uninstall' Wait='yes'/>
+ <ServiceControl Id='DBInstanceServiceStart' Name='[SERVICENAME]' Start='install' Wait='yes'/>
+ </Component>
+ <?if $(var.HaveInnodb) = "1" ?>
+ <Component Id="C.myiniconfig" Guid="*" Directory="DATADIR">
+ <Condition>STDCONFIG</Condition>
+ <RegistryValue Root='HKLM'
+ Key='SOFTWARE\@MANUFACTURER@\@CPACK_WIX_PACKAGE_NAME@'
+ Name='STDCONFIG' Value='1' Type='string' KeyPath='yes'/>
+ <IniFile Id="Ini1"
+ Action="createLine"
+ Directory="DATADIR"
+ Section="mysqld"
+ Name="my.ini"
+ Key="sql_mode"
+ Value=""STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"" />
+ <IniFile Id="Ini2"
+ Action="createLine"
+ Directory="DATADIR"
+ Section="mysqld"
+ Name="my.ini"
+ Key="default_storage_engine"
+ Value="innodb" />
+ <IniFile Id="Ini3"
+ Action="createLine"
+ Directory="DATADIR"
+ Section="mysqld"
+ Name="my.ini"
+ Key="innodb_buffer_pool_size"
+ Value="[BUFFERPOOLSIZE]M" />
+ <IniFile Id="Ini4"
+ Action="createLine"
+ Directory="DATADIR"
+ Section="mysqld"
+ Name="my.ini"
+ Key="innodb_log_file_size"
+ Value="[LOGFILESIZE]M" />
+ </Component>
+ <?endif?>
+
+ <Component Id="C.feedback" Guid="*" Directory="DATADIR">
+ <Condition>FEEDBACK</Condition>
+ <RegistryValue Root='HKLM'
+ Key='SOFTWARE\@MANUFACTURER@\@CPACK_WIX_PACKAGE_NAME@'
+ Name='FEEDBACK' Value='1' Type='string' KeyPath='yes'/>
+ <IniFile Id="Ini5"
+ Action="createLine"
+ Directory="DATADIR"
+ Section="mysqld"
+ Name="my.ini"
+ Key="feedback"
+ Value="ON" />
+ </Component>
+
+ <!--- Grant service account permission to the database folder (Windows 7 and later) -->
+ <Component Id="C.serviceaccount.permission" Guid="*" Directory='DATADIR' Transitive='yes'>
+ <Condition><![CDATA[SERVICENAME AND (VersionNT > 600)]]></Condition>
+ <RegistryValue Root='HKLM'
+ Key='SOFTWARE\@MANUFACTURER@\@CPACK_WIX_PACKAGE_NAME@'
+ Name='servicepermission' Value='1' Type='string' KeyPath='yes'/>
+ <CreateFolder>
+ <util:PermissionEx User="NT SERVICE\[SERVICENAME]" GenericAll="yes" />
+ </CreateFolder>
+ </Component>
+
+ <!-- Shortcuts in program menu (mysql client etc) -->
+ <Component Id="c.shortcuts" Guid="*" Directory="ShortcutFolder">
+ <!-- shortcut to my.ini-->
+ <RegistryValue Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\Uninstall" Name="shortcuts" Value="1" Type="string" KeyPath="yes" />
+ <RemoveFolder Id="RemoveShorcutFolder" On="uninstall" />
+ <Shortcut Id="shortcut.my.ini"
+ Name="my.ini (@CPACK_WIX_PACKAGE_NAME@)"
+ Target="[System64Folder]notepad.exe"
+ Arguments=""[DATADIR]my.ini""
+ Directory="ShortcutFolder"
+ Description="Edit database configuration" />
+ <Shortcut Id="shortcut.errorlog"
+ Name="Error log (@CPACK_WIX_PACKAGE_NAME@)"
+ Target="[System64Folder]notepad.exe"
+ Arguments=""[DATADIR][ComputerName].err""
+ Directory="ShortcutFolder"
+ Description="View Database Error log" />
+ <Shortcut Id="shortcut.dbfolder" Name="Database directory (@CPACK_WIX_PACKAGE_NAME@)"
+ Target="[DATADIR]" />
+ </Component>
+
+ <!-- add reference so mysql client won't get uninstalled and we have a shortcut pointing to nowhere-->
+ <ComponentRef Id="C.bin.mysql.exe"/>
+
+ <Component Id="c.shortcuts.commandline" Guid="*" Directory="ShortcutFolder">
+ <RegistryValue
+ Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\Uninstall"
+ Name="shortcuts.commandline"
+ Value="1" Type="string" KeyPath="yes" />
+ <!-- shortcut to client-->
+ <Shortcut Id="shortcut.mysql.exe"
+ Name="MySQL Client (@CPACK_WIX_PACKAGE_NAME@)"
+ Target="[System64Folder]cmd.exe"
+ Arguments="/k " "[D.bin]mysql.exe" "--defaults-file=[DATADIR]my.ini" -uroot -p""
+ Directory="ShortcutFolder"
+ WorkingDirectory="D.bin"
+ Description="Starts mysql.exe for root user" />
+ </Component>
+ <Component Id="c.shortcuts.commandprompt.db" Guid="*" Directory="ShortcutFolder" Transitive="yes">
+ <Condition>SERVICENAME</Condition>
+ <RegistryValue
+ Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\Uninstall"
+ Name="shortcuts.commandprompt.db"
+ Value="1" Type="string" KeyPath="yes" />
+ <!-- just command prompt in the bin directory (so all utilities can be called) -->
+ <Shortcut Id="shortcut.commandprompt.exe.db"
+ Name="Command Prompt (@CPACK_WIX_PACKAGE_NAME@)"
+ Target="[System64Folder]cmd.exe"
+ Directory="ShortcutFolder"
+ Arguments="/k "set MYSQL_HOME=[DATADIR]&& set PATH=[D.bin];%PATH%;&&echo Setting environment for [ProductName] ""
+ Description="Opens command line in the installation bin directory" />
+ </Component>
+
+
+ </Feature>
+
+ <Feature Id="SharedClientServerComponents"
+ Title='Utilities used by both server and client.'
+ Description=
+ 'Client utilities that are also used with server.Required for upgrade.'
+ ConfigurableDirectory='INSTALLDIR'
+ AllowAdvertise='no'
+ Level='1'
+ Display='hidden'>
+ <ComponentRef Id='C.bin.mysql.exe'/>
+ <ComponentRef Id='C.bin.mysqladmin.exe'/>
+ <ComponentRef Id='C.bin.mysql_upgrade.exe'/>
+ <ComponentRef Id='C.bin.mysqlcheck.exe'/>
+ <Component Id="c.shortcuts.commandprompt.nodb" Guid="*" Directory="ShortcutFolder" Transitive="yes">
+ <Condition>NOT SERVICENAME</Condition>
+ <RegistryValue
+ Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\Uninstall"
+ Name="shortcuts.commandprompt.nodb"
+ Value="1" Type="string" KeyPath="yes" />
+ <!-- just command prompt in the bin directory (so all utilities can be called) -->
+ <Shortcut Id="shortcut.commandprompt.exe.nodb"
+ Name="Command Prompt (@CPACK_WIX_PACKAGE_NAME@)"
+ Target="[System64Folder]cmd.exe"
+ Directory="ShortcutFolder"
+ Arguments="/k "set PATH=[D.bin];%PATH%;&&echo Setting environment for [ProductName] ""
+ Description="Opens command line in the installation bin directory" />
+ </Component>
+ <?if $(var.HaveUpgradeWizard) != "0" ?>
+ <ComponentRef Id='C.bin.mysql_upgrade_wizard.exe'/>
+ <Component Id="c.shortcuts.upgrade_wizard" Guid="*" Directory="ShortcutFolder" Transitive="yes">
+ <RegistryValue
+ Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\Uninstall"
+ Name="shortcuts.upgrade_wizard"
+ Value="1" Type="string" KeyPath="yes" />
+ <Shortcut Id="shortcut.upgrade_wizard"
+ Name="Upgrade Wizard (@CPACK_WIX_PACKAGE_NAME@)"
+ Target="[INSTALLDIR]bin\mysql_upgrade_wizard.exe"
+ Directory="ShortcutFolder"
+ Description="Upgrades older instances of MariaDB/MySQL services to version @MAJOR_VERSION@.@MINOR_VERSION@"
+ Advertise="no"/>
+ </Component>
+ <?endif?>
+ </Feature>
+
+ <!-- Optional 3rd party tools -->
+ <DirectoryRef Id='TARGETDIR'>
+ <Directory Id='CommonFilesFolder'>
+ <Directory Id='MariaDBShared' Name='MariaDBShared'/>
+ </Directory>
+ <Directory Id='DesktopFolder'/>
+ </DirectoryRef>
+
+
+ <?if "@WITH_THIRD_PARTY@" != "" ?>
+
+ <!-- Include definition of 3party components -->
+ <?foreach tool in @WITH_THIRD_PARTY@ ?>
+ <?include "${CMAKE_CURRENT_BINARY_DIR}\$(var.tool).wxi" ?>
+ <?endforeach ?>
+
+ <Feature Id="ThirdPartyTools"
+ Title='Third party tools'
+ Description= 'Third party tools'
+ AllowAdvertise='no'
+ Level='1'
+ Display='expand'>
+ @THIRD_PARTY_FEATURE_CONDITION@
+ <!-- Include definition of 3rd party features -->
+ <?foreach tool in @WITH_THIRD_PARTY@ ?>
+ <?include "${CMAKE_CURRENT_BINARY_DIR}\$(var.tool)_feature.wxi" ?>
+ <?endforeach ?>
+
+ </Feature>
+
+ <?endif ?>
+
+ <!-- Custom action, call mysql_install_db -->
+ <SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="SKIPNETWORKING" Value="--skip-networking" >SKIPNETWORKING</SetProperty>
+ <SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="ALLOWREMOTEROOTACCESS" Value="--allow-remote-root-access">ALLOWREMOTEROOTACCESS</SetProperty>
+ <SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="DEFAULTUSER" Value="--default-user">DEFAULTUSER</SetProperty>
+ <CustomAction Id='CheckDatabaseProperties' BinaryKey='wixca.dll' DllEntry='CheckDatabaseProperties' />
+ <CustomAction Id='PresetDatabaseProperties' BinaryKey='wixca.dll' DllEntry='PresetDatabaseProperties' />
+ <CustomAction Id="CreateDatabaseCommand" Property="CreateDatabase"
+ Value=
+ ""[#F.bin.mysql_install_db.exe]" "--service=[SERVICENAME]" --port=[PORT] "--password=[PASSWORD]" "--datadir=[DATADIR]\" [SKIPNETWORKING] [ALLOWREMOTEROOTACCESS] [DEFAULTUSER]"
+ Execute="immediate"
+ HideTarget="yes"
+ />
+ <CustomAction Id="CreateDatabaseRollbackCommand" Property="CreateDatabaseRollback"
+ Value="[SERVICENAME]\[DATADIR]"
+ Execute="immediate"/>
+ <CustomAction Id="CreateDatabase" BinaryKey="WixCA" DllEntry="CAQuietExec"
+ Execute="deferred" Return="check" Impersonate="no" />
+ <CustomAction Id="CreateDatabaseRollback" BinaryKey="wixca.dll" DllEntry="CreateDatabaseRollback"
+ Execute="rollback" Return="check" Impersonate="no"/>
+ <UI>
+ <ProgressText Action="CreateDatabase">Running mysql_install_db.exe</ProgressText>
+ </UI>
+
+ <!-- Error injection script activated by TEST_FAIL=1 passed to msiexec (to see how good custom action rollback works) -->
+ <Property Id="FailureProgram">
+ <![CDATA[
+ Function Main()
+ Main = 3
+ End Function
+ ]]>
+ </Property>
+ <CustomAction Id="FakeFailure"
+ VBScriptCall="Main"
+ Property="FailureProgram"
+ Execute="deferred" />
+
+ <CustomAction Id='ErrorDataDirNotEmpty'
+ Error='Chosen data directory [DATADIR] is not empty. It must be empty prior to installation.'/>
+ <InstallExecuteSequence>
+ <Custom Action="CheckDataDirectoryEmpty" After="CostFinalize">
+ <![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
+ </Custom>
+ <Custom Action="ErrorDataDirNotEmpty" After="CheckDataDirectoryEmpty" >DATADIRNOTEMPTY</Custom>
+
+ <Custom Action="CreateDatabaseCommand" After="CostFinalize" >
+ <![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
+ </Custom>
+ <Custom Action="CreateDatabase" After="InstallFiles">
+ <![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
+ </Custom>
+ <Custom Action="CreateDatabaseRollbackCommand" After="CostFinalize">
+ <![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
+ </Custom>
+ <Custom Action="CreateDatabaseRollback" Before="CreateDatabase">
+ <![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
+ </Custom>
+ <Custom Action='FakeFailure' Before='InstallFinalize'>
+ <![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED="" AND TESTFAIL]]>
+ </Custom>
+ </InstallExecuteSequence>
+
+
+ <!-- Custom action to remove data on uninstall -->
+ <Binary Id='wixca.dll' SourceFile='@WIXCA_LOCATION@' />
+ <CustomAction Id="RemoveDataDirectory.SetProperty" Return="check"
+ Property="RemoveDataDirectory" Value="[DATADIR]" />
+ <CustomAction Id="RemoveDataDirectory" BinaryKey="wixca.dll"
+ DllEntry="RemoveDataDirectory"
+ Execute="deferred"
+ Impersonate="no"
+ Return="ignore" />
+ <InstallExecuteSequence>
+ <Custom Action="RemoveDataDirectory.SetProperty" After="CreateDatabaseCommand" >
+ <![CDATA[($C.datadir=2) AND (CLEANUPDATA) AND NOT UPGRADINGPRODUCTCODE]]>
+ </Custom>
+ <Custom Action="RemoveDataDirectory" Before="RemoveFiles">
+ <![CDATA[($C.datadir=2) AND (CLEANUPDATA) AND NOT UPGRADINGPRODUCTCODE]]>
+ </Custom>
+ </InstallExecuteSequence>
+
+ <InstallExecuteSequence>
+ <StopServices>SERVICENAME</StopServices>
+ <DeleteServices>SERVICENAME</DeleteServices>
+ </InstallExecuteSequence>
+ <CustomAction Id="CheckDBInUse" Return="ignore"
+ BinaryKey="wixca.dll" DllEntry="CheckDBInUse" Execute="firstSequence"/>
+ <InstallExecuteSequence>
+ <Custom Action="CheckDBInUse" Before="LaunchConditions">Installed</Custom>
+ <Custom Action="PresetDatabaseProperties" After="CheckDBInUse"></Custom>
+ </InstallExecuteSequence>
+ <InstallUISequence>
+ <Custom Action="CheckDBInUse" Before="LaunchConditions">Installed</Custom>
+ <Custom Action="PresetDatabaseProperties" After="CheckDBInUse"></Custom>
+ </InstallUISequence>
+
+ <!-- Store some properties persistently in registry, mainly for upgrades -->
+
+ <Feature Id='StoreInstallLocation' Level='1' Absent='disallow' Display='hidden'>
+ <Component Directory='INSTALLDIR' Guid='*' Id='C.storeinstalllocation'>
+ <RegistryValue Root='HKLM' Key='SOFTWARE\@MANUFACTURER@\@CPACK_WIX_PACKAGE_NAME@'
+ Name='INSTALLDIR' Value='[INSTALLDIR]' Type='string' KeyPath='yes'/>
+ </Component>
+ </Feature>
+
+ <?foreach STOREDVAR in SERVICENAME;DATADIR;INSTALLDIR?>
+
+ <Property Id='$(var.STOREDVAR)' Secure='yes'>
+ <RegistrySearch Id='$(var.STOREDVAR)Property' Root='HKLM'
+ Key='SOFTWARE\@MANUFACTURER@\@CPACK_WIX_PACKAGE_NAME@'
+ Name='$(var.STOREDVAR)' Type='raw' />
+ </Property>
+ <CustomAction Id='SaveCmdLineValue_$(var.STOREDVAR)' Property='CMDLINE_$(var.STOREDVAR)'
+ Value='[$(var.STOREDVAR)]' Execute='firstSequence' />
+ <CustomAction Id='SetFromCmdLineValue_$(var.STOREDVAR)' Property='$(var.STOREDVAR)'
+ Value='[CMDLINE_$(var.STOREDVAR)]' Execute='firstSequence' />
+ <InstallUISequence>
+ <Custom Action='SaveCmdLineValue_$(var.STOREDVAR)' Before='AppSearch' />
+ <Custom Action='SetFromCmdLineValue_$(var.STOREDVAR)' After='AppSearch'>CMDLINE_$(var.STOREDVAR)</Custom>
+ </InstallUISequence>
+ <InstallExecuteSequence>
+ <Custom Action='SaveCmdLineValue_$(var.STOREDVAR)' Before='AppSearch' />
+ <Custom Action='SetFromCmdLineValue_$(var.STOREDVAR)' After='AppSearch'>CMDLINE_$(var.STOREDVAR)</Custom>
+ </InstallExecuteSequence>
+
+ <?endforeach?>
+
+ <!--
+ Optionally, start upgrade wizard on exit.
+ -->
+
+
+
+ <?if $(var.HaveUpgradeWizard) != "0" ?>
+ <UI>
+ <Publish Dialog="ExitDialog"
+ Control="Finish"
+ Event="DoAction"
+ Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
+ </UI>
+ <Property
+ Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT"
+ Value="Launch wizard to upgrade existing MariaDB or MySQL services." />
+ <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1"/>
+ <Property Id="WixShellExecTarget" Value="[#F.bin.mysql_upgrade_wizard.exe]" />
+ <CustomAction Id="LaunchApplication"
+ BinaryKey="WixCA"
+ DllEntry="WixShellExec"
+ Impersonate="yes" />
+ <CustomAction
+ Id="CheckServiceUpgrades" Return="ignore" BinaryKey="wixca.dll"
+ DllEntry="CheckServiceUpgrades"
+ Execute="immediate" />
+ <InstallUISequence>
+ <Custom Action="CheckServiceUpgrades" After="CostFinalize">
+ $C.bin.mysql_upgrade_wizard.exe = 3 AND NOT Installed
+ </Custom>
+ </InstallUISequence>
+ <SetProperty Before="ExecuteAction" Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT"
+ Sequence="ui" Value="[NonExistentProperty]">
+ <![CDATA[($C.bin.mysql_upgrade_wizard.exe <> 3) AND NOT Installed]]>
+ </SetProperty>
+ <SetProperty Before="ExecuteAction" Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX"
+ Sequence="ui" Value="[NonExistentProperty]">
+ <![CDATA[($C.bin.mysql_upgrade_wizard.exe <> 3) AND NOT Installed]]>
+ </SetProperty>
+
+ <?endif ?> <!-- HaveUpgradeWizard -->
+
+ <!--
+ Author the registry entries for "add or remove programs"
+ We choose to define ARPSYSTEMCOMPONENT to 1 because we want to show
+ "do you want to remove data directory" on uninstall
+ -->
+ <Property Id="ARPSYSTEMCOMPONENT" Value="1" Secure="yes" />
+ <Property Id="ARPINSTALLLOCATION" Secure="yes"/>
+ <SetProperty Id="ARPINSTALLLOCATION" Value="[INSTALLDIR]" After="InstallValidate" Sequence="execute"/>
+ <Feature Id='ARPRegistryEntries'
+ Title='Add or remove program entries'
+ Description='Add or remove program entries'
+ AllowAdvertise='no'
+ Absent='disallow' Display='hidden'
+ Level='1'>
+ <Component Id="C.arp_entries" Guid="*" Directory="INSTALLDIR">
+ <RemoveFolder Id="RemoveINSTALLDIR" On="uninstall"/>
+ <RegistryValue Root='HKLM'
+ Key='Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_WIX_PACKAGE_NAME@'
+ Name='DisplayName' Value='[ProductName]' Type='string' KeyPath='yes'/>
+ <RegistryValue Root='HKLM'
+ Key='Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_WIX_PACKAGE_NAME@'
+ Name='Publisher' Value='@MANUFACTURER@' Type='string'/>
+ <RegistryValue Root='HKLM'
+ Key='Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_WIX_PACKAGE_NAME@'
+ Name='DisplayVersion' Value='[ProductVersion]' Type='string'/>
+ <RegistryValue Root='HKLM'
+ Key='Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_WIX_PACKAGE_NAME@'
+ Name='InstallLocation' Value='[INSTALLDIR]' Type='string'/>
+ <RegistryValue Root='HKLM'
+ Key='Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_WIX_PACKAGE_NAME@'
+ Name='UninstallString' Value='msiexec.exe /I [ProductCode]' Type='string'/>
+ <RegistryValue Root='HKLM'
+ Key='Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_WIX_PACKAGE_NAME@'
+ Name='MajorVersion' Value='@MAJOR_VERSION@' Type='string'/>
+ <RegistryValue Root='HKLM'
+ Key='Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_WIX_PACKAGE_NAME@'
+ Name='MinorVersion' Value='@MINOR_VERSION@' Type='string'/>
+ </Component>
+ </Feature>
+
+ <!-- Extra condition to block the installer if NSIS based installation is detected-->
+ <Property Id="NSISINSTALLKEY">
+ <RegistrySearch Id='NSISKey' Type='raw'
+ Root='HKLM' Key='Software\Microsoft\Windows\CurrentVersion\Uninstall\MariaDB' Name='DisplayName' />
+ </Property>
+ <Condition
+ Message=
+ 'Previous version of MariaDB was found, that used incompatible installer.
Please remove "[NSISINSTALLKEY]" before you proceed with this installation.'
+ >
+ <![CDATA[ NOT(NSISINSTALLKEY << "MariaDB @MAJOR_VERSION@.@MINOR_VERSION@.") OR Installed]]>
+ </Condition>
+ <Condition Message=
+ 'Setting the ALLUSERS property is not allowed because [ProductName] is a per-machine application. Setup will now exit.'>
+ <![CDATA[ALLUSERS = "1"]]>
+ </Condition>
+ </Fragment>
+</Wix>
diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake new file mode 100644 index 00000000000..94a287cba08 --- /dev/null +++ b/win/packaging/heidisql.cmake @@ -0,0 +1,23 @@ +SET(HEIDISQL_BASE_NAME "HeidiSQL_6.0_Portable")
+SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip")
+SET(HEIDISQL_URL "http://heidisql.googlecode.com/files/${HEIDISQL_ZIP}")
+SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME})
+
+IF(NOT EXISTS ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP})
+ MAKE_DIRECTORY(${HEIDISQL_DOWNLOAD_DIR})
+ MESSAGE(STATUS "Downloading ${HEIDISQL_URL} to ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP}")
+ FILE(DOWNLOAD ${HEIDISQL_URL} ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP} TIMEOUT 60)
+ EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E chdir ${HEIDISQL_DOWNLOAD_DIR}
+ ${CMAKE_COMMAND} -E tar xfz ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP}
+ )
+ENDIF()
+
+SET(LIBMYSQLDLL_SOURCE ${HEIDISQL_DOWNLOAD_DIR}/libmysql.dll)
+IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ # Use our libmysql if it is 32 bit.
+ IF(LIBMYSQL_LOCATION)
+ SET(LIBMYSQLDLL_SOURCE "${LIBMYSQL_LOCATION}")
+ ENDIF()
+ENDIF()
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/heidisql.wxi.in ${CMAKE_CURRENT_BINARY_DIR}/heidisql.wxi)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/heidisql_feature.wxi.in ${CMAKE_CURRENT_BINARY_DIR}/heidisql_feature.wxi)
diff --git a/win/packaging/heidisql.wxi.in b/win/packaging/heidisql.wxi.in new file mode 100644 index 00000000000..2af52862e06 --- /dev/null +++ b/win/packaging/heidisql.wxi.in @@ -0,0 +1,46 @@ +<Include>
+<Property Id="HEIDISQLINSTALLED" Secure="yes">
+<RegistrySearch Id="HeidiSQL"
+ Root="HKLM"
+ Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\HeidiSQL_is1"
+ Name="Install"
+ Type="raw"
+ Win64="no"
+/>
+</Property>
+<DirectoryRef Id="MariaDBShared">
+ <Directory Id="D.HeidiSQL" Name="HeidiSQL">
+ <Component Id="component.HeidiSQL" Guid="96ea3879-5320-4098-8f26-2f655d2f716c" Win64="no">
+
+ <File Id="heidisql.gpl.txt" Name="gpl.txt" Source="${HEIDISQL_DOWNLOAD_DIR}\gpl.txt" />
+ <File Id="heidisql.heidisql.exe" Name="heidisql.exe" Source="${HEIDISQL_DOWNLOAD_DIR}\heidisql.exe" KeyPath="yes">
+ <Shortcut Id="desktopHeidiSQL" Directory="DesktopFolder" Name="HeidiSQL" Advertise="yes"/>
+ </File>
+ <!--
+ Forced file removal for heidisql.exe might be required.
+ HeidiSQL is self-updating, thus the version that was installed by MSI not necessarily matches
+ the version of the file on uninstall. MSI would not touch such file by default and leave it after
+ uninstallation. We use RemoveFile to force delete in any case.
+ -->
+ <RemoveFile Id="Remove_HeidiSQL_exe" Name="heidisql.exe" On="uninstall" />
+
+ <File Id="heidisql.license.txt" Name="license.txt" Source="${HEIDISQL_DOWNLOAD_DIR}\license.txt" />
+ <File Id="heidisql.readme.txt" Name="readme.txt" Source="${HEIDISQL_DOWNLOAD_DIR}\readme.txt" />
+ </Component>
+ <Component Id="component.HeidiSQL_MenuShortcut" Guid="*" Win64="no">
+ <RegistryValue Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\Uninstall" Name="shortcuts.heidisql" Value="1" Type="string" KeyPath="yes" />
+ <Shortcut Id="startmenuHeidiSQL" Directory="ShortcutFolder" Name="HeidiSQL" Target="[D.HeidiSQL]\heidisql.exe"/>
+ <RemoveRegistryKey Id="HeidiSQL_RegistryCleanup" Root="HKCU" Key="SOFTWARE\HeidiSQL" Action="removeOnUninstall" />
+ </Component>
+ <Component Id="component.HeidiSQL_libmysql.dll" Guid="*" Win64="no">
+ <File Id="heidisql.libmysql.dll" Name="libmysql.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libmysql.dll" />
+ </Component>
+ </Directory>
+</DirectoryRef>
+
+<ComponentGroup Id="HeidiSQL">
+ <ComponentRef Id="component.HeidiSQL"/>
+ <ComponentRef Id="component.HeidiSQL_MenuShortcut"/>
+ <ComponentRef Id="component.HeidiSQL_libmysql.dll"/>
+</ComponentGroup>
+</Include>
diff --git a/win/packaging/heidisql_feature.wxi.in b/win/packaging/heidisql_feature.wxi.in new file mode 100644 index 00000000000..9fceb4689d0 --- /dev/null +++ b/win/packaging/heidisql_feature.wxi.in @@ -0,0 +1,10 @@ +<Include>
+<Feature Id="HeidiSQL"
+ Title='HeidiSQL'
+ Description= 'Powerful, easy and free MySQL/MariaDB GUI client by Ansgar Becker'
+ AllowAdvertise='no'
+ Level='1'>
+ <Condition Level="0">HEIDISQLINSTALLED</Condition>
+ <ComponentGroupRef Id='HeidiSQL'/>
+</Feature>
+</Include>
diff --git a/win/packaging/mysql_server.wxs.in b/win/packaging/mysql_server.wxs.in new file mode 100644 index 00000000000..82c17d7577c --- /dev/null +++ b/win/packaging/mysql_server.wxs.in @@ -0,0 +1,87 @@ +<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
+ xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
+ <Product
+ Id="*"
+ UpgradeCode="@CPACK_WIX_UPGRADE_CODE@"
+ Name="@CPACK_WIX_PACKAGE_NAME@"
+ Version="@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH_VERSION@"
+ Language="1033"
+ Manufacturer="@MANUFACTURER@">
+
+ <Package Id='*'
+ Keywords='Installer'
+ Description='MariaDB Server'
+ Manufacturer='@MANUFACTURER@'
+ InstallerVersion='200'
+ Languages='1033'
+ Compressed='yes'
+ SummaryCodepage='1252'
+ Platform='@Platform@'/>
+
+ <Media Id='1' Cabinet='product.cab' EmbedCab='yes' CompressionLevel='high' />
+
+ <!-- Upgrade -->
+ <Upgrade Id="@CPACK_WIX_UPGRADE_CODE@">
+ <?if "@PATCH_VERSION@" != "0"?>
+ <UpgradeVersion
+ Minimum="@MAJOR_VERSION@.@MINOR_VERSION@.0"
+ IncludeMinimum="yes"
+ Maximum="@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH_VERSION@"
+ Property="OLDERVERSIONBEINGUPGRADED"
+ MigrateFeatures="yes"
+ />
+ <?endif?>
+ <UpgradeVersion
+ Minimum="@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH_VERSION@"
+ Maximum="@MAJOR_VERSION@.@MINOR_VERSION@.999"
+ OnlyDetect="yes"
+ Property="NEWERVERSIONDETECTED" />
+ </Upgrade>
+ <Condition Message="A more recent version of [ProductName] is already installed. Setup will now exit.">
+ NOT NEWERVERSIONDETECTED OR Installed
+ </Condition>
+ <InstallExecuteSequence>
+ <RemoveExistingProducts After="InstallFinalize"/>
+ </InstallExecuteSequence>
+
+
+ <InstallUISequence>
+ <AppSearch After="FindRelatedProducts"/>
+ </InstallUISequence>
+
+ <!-- UI -->
+ <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR"></Property>
+ <UIRef Id="WixUI_ErrorProgressText" />
+ <UIRef Id="@CPACK_WIX_UI@" />
+
+
+ <!-- License -->
+ <WixVariable
+ Id="WixUILicenseRtf"
+ Value="@COPYING_RTF@"/>
+
+ <!-- Installation root-->
+ <Directory Id='TARGETDIR' Name='SourceDir'>
+ <Directory Id='@PlatformProgramFilesFolder@'>
+ <Directory Id='INSTALLDIR' Name='@CPACK_WIX_PACKAGE_BASE_NAME@ @MAJOR_VERSION@.@MINOR_VERSION@'>
+ </Directory>
+ </Directory>
+ </Directory>
+
+ <!-- CPACK_WIX_FEATURES -->
+ @CPACK_WIX_FEATURES@
+
+ <!-- CPACK_WIX_DIRECTORIES -->
+ @CPACK_WIX_DIRECTORIES@
+
+ <!--CPACK_WIX_COMPONENTS-->
+ @CPACK_WIX_COMPONENTS@
+
+ <!--CPACK_WIX_COMPONENTS_GROUPS -->
+ @CPACK_WIX_COMPONENT_GROUPS@
+
+ <!--CPACK_WIX_INCLUDES -->
+ @CPACK_WIX_INCLUDES@
+ </Product>
+
+</Wix>
diff --git a/win/upgrade_wizard/CMakeLists.txt b/win/upgrade_wizard/CMakeLists.txt new file mode 100644 index 00000000000..44d6249ea1e --- /dev/null +++ b/win/upgrade_wizard/CMakeLists.txt @@ -0,0 +1,44 @@ +IF(NOT MSVC) + RETURN() +ENDIF() +IF(CMAKE_USING_VC_FREE_TOOLS) + # No MFC, so it cannot be built + RETURN() +ENDIF() + +# We need MFC +FIND_PACKAGE(MFC) +IF(NOT MFC_FOUND) + IF(BUILD_RELEASE) + MESSAGE(FATAL_ERROR + "Can't find MFC. It is necessary for producing official package" + ) + ENDIF() + RETURN() +ENDIF() + +# MFC should be statically linked +SET(CMAKE_MFC_FLAG 1) + +# Enable exception handling (avoids warnings) +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) +MYSQL_ADD_EXECUTABLE(mysql_upgrade_wizard + upgrade.cpp upgradeDlg.cpp upgrade.rc + COMPONENT Server) +TARGET_LINK_LIBRARIES(mysql_upgrade_wizard winservice) +# upgrade_wizard is Windows executable, set WIN32_EXECUTABLE so it does not +# create a console. +SET_TARGET_PROPERTIES(mysql_upgrade_wizard PROPERTIES WIN32_EXECUTABLE 1) + +# Embed Vista "admin" manifest, since upgrade_wizard needs admin privileges +# to change service configuration. Due to a CMake bug http://www.vtk.org/Bug/view.php?id=11171 +# it is not possible currenly to do it with linker flags. Work around is to use +# manifest tool mt.exe and embed the manifest post-build. +GET_TARGET_PROPERTY(upgrade_wizard_location mysql_upgrade_wizard LOCATION) +ADD_CUSTOM_COMMAND( + TARGET mysql_upgrade_wizard POST_BUILD + COMMAND mt.exe -manifest ${CMAKE_CURRENT_SOURCE_DIR}/upgrade_wizard.exe.manifest + "-outputresource:${upgrade_wizard_location};#1" +) diff --git a/win/upgrade_wizard/res/upgrade.ico b/win/upgrade_wizard/res/upgrade.ico Binary files differnew file mode 100644 index 00000000000..33a6178346a --- /dev/null +++ b/win/upgrade_wizard/res/upgrade.ico diff --git a/win/upgrade_wizard/res/upgrade.rc2 b/win/upgrade_wizard/res/upgrade.rc2 new file mode 100644 index 00000000000..8a1da4177c5 --- /dev/null +++ b/win/upgrade_wizard/res/upgrade.rc2 @@ -0,0 +1,13 @@ +// +// zzz.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/win/upgrade_wizard/resource.h b/win/upgrade_wizard/resource.h new file mode 100644 index 00000000000..4c05cea2fd0 --- /dev/null +++ b/win/upgrade_wizard/resource.h @@ -0,0 +1,27 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by upgrade.rc +// +#define IDD_UPGRADE_DIALOG 102 +#define IDR_MAINFRAME 128 +#define IDC_LIST1 1000 +#define IDC_PROGRESS1 1004 +#define IDC_EDIT1 1005 +#define IDC_EDIT2 1006 +#define IDC_EDIT3 1007 +#define IDC_EDIT7 1011 +#define IDC_EDIT8 1012 +#define IDC_EDIT9 1013 +#define IDC_BUTTON1 1014 +#define IDC_BUTTON2 1015 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1016 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/win/upgrade_wizard/stdafx.h b/win/upgrade_wizard/stdafx.h new file mode 100644 index 00000000000..87db7036005 --- /dev/null +++ b/win/upgrade_wizard/stdafx.h @@ -0,0 +1,47 @@ +
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#ifndef _SECURE_ATL
+#define _SECURE_ATL 1
+#endif
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+
+
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/win/upgrade_wizard/targetver.h b/win/upgrade_wizard/targetver.h new file mode 100644 index 00000000000..90e767bfce7 --- /dev/null +++ b/win/upgrade_wizard/targetver.h @@ -0,0 +1,8 @@ +#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>
diff --git a/win/upgrade_wizard/upgrade.cpp b/win/upgrade_wizard/upgrade.cpp new file mode 100644 index 00000000000..aa9efa15ecc --- /dev/null +++ b/win/upgrade_wizard/upgrade.cpp @@ -0,0 +1,57 @@ +
+// upgrade.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "upgrade.h"
+#include "upgradeDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CUpgradeApp
+
+BEGIN_MESSAGE_MAP(CUpgradeApp, CWinApp)
+ ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CUpgradeApp construction
+
+CUpgradeApp::CUpgradeApp()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+}
+
+
+// The one and only CUpgradeApp object
+
+CUpgradeApp theApp;
+
+
+// CUpgradeApp initialization
+
+BOOL CUpgradeApp::InitInstance()
+{
+ // InitCommonControlsEx() is required on Windows XP if an application
+ // manifest specifies use of ComCtl32.dll version 6 or later to enable
+ // visual styles. Otherwise, any window creation will fail.
+ INITCOMMONCONTROLSEX InitCtrls;
+ InitCtrls.dwSize = sizeof(InitCtrls);
+ // Set this to include all the common control classes you want to use
+ // in your application.
+ InitCtrls.dwICC = ICC_WIN95_CLASSES;
+
+ InitCommonControlsEx(&InitCtrls);
+ CWinApp::InitInstance();
+ CUpgradeDlg dlg;
+ m_pMainWnd = &dlg;
+ dlg.DoModal();
+ // Since the dialog has been closed, return FALSE so that we exit the
+ // application, rather than start the application's message pump.
+ return FALSE;
+}
+
diff --git a/win/upgrade_wizard/upgrade.h b/win/upgrade_wizard/upgrade.h new file mode 100644 index 00000000000..26c107b6ee8 --- /dev/null +++ b/win/upgrade_wizard/upgrade.h @@ -0,0 +1,32 @@ +
+// zzz.h : main header file for the PROJECT_NAME application
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error "include 'stdafx.h' before including this file for PCH"
+#endif
+
+#include "resource.h" // main symbols
+
+
+// CzzzApp:
+// See zzz.cpp for the implementation of this class
+//
+
+class CUpgradeApp : public CWinApp
+{
+public:
+ CUpgradeApp();
+
+// Overrides
+public:
+ virtual BOOL InitInstance();
+
+// Implementation
+
+ DECLARE_MESSAGE_MAP()
+};
+
+extern CUpgradeApp theApp;
\ No newline at end of file diff --git a/win/upgrade_wizard/upgrade.rc b/win/upgrade_wizard/upgrade.rc new file mode 100644 index 00000000000..30656651b79 --- /dev/null +++ b/win/upgrade_wizard/upgrade.rc @@ -0,0 +1,148 @@ +// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#ifndef APSTUDIO_INVOKED
+#include "targetver.h"
+#endif
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#ifndef APSTUDIO_INVOKED\r\n"
+ "#include ""targetver.h""\r\n"
+ "#endif\r\n"
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#include ""res\\upgrade.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "res\\upgrade.ico"
+#endif // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_UPGRADE_DIALOG DIALOGEX 0, 0, 320, 200
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "MariaDB Upgrade Wizard"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,113,169,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,191,169,50,14
+ LISTBOX IDC_LIST1,24,39,216,80,LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_EDIT1,97,124,193,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_EDIT2,98,138,181,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ CONTROL "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,26,153,243,14
+ EDITTEXT IDC_EDIT3,98,151,40,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_EDIT7,27,124,65,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_EDIT8,27,137,62,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ EDITTEXT IDC_EDIT9,27,151,62,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+ PUSHBUTTON "Select all",IDC_BUTTON1,245,61,50,14
+ PUSHBUTTON "Clear all",IDC_BUTTON2,246,88,50,14
+ LTEXT "Select services you want to upgrade and click on the [Upgrade] button.\nMake sure to backup data directories prior to upgrade.",IDC_STATIC,25,14,215,26
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_UPGRADE_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 313
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 193
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#include "res\upgrade.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/win/upgrade_wizard/upgradeDlg.cpp b/win/upgrade_wizard/upgradeDlg.cpp new file mode 100644 index 00000000000..d996c0ebe5d --- /dev/null +++ b/win/upgrade_wizard/upgradeDlg.cpp @@ -0,0 +1,627 @@ + +// upgradeDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "upgrade.h" +#include "upgradeDlg.h" +#include "windows.h" +#include "winsvc.h" +#include <msi.h> +#pragma comment(lib, "msi") +#pragma comment(lib, "version") +#include <map> +#include <string> +#include <vector> + +#include <winservice.h> + +using namespace std; + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +#define PRODUCT_NAME "MariaDB" + +// CUpgradeDlg dialog + +CUpgradeDlg::CUpgradeDlg(CWnd* pParent /*=NULL*/) + : CDialog(CUpgradeDlg::IDD, pParent) +{ + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +void CUpgradeDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_LIST1, m_Services); + DDX_Control(pDX, IDC_PROGRESS1, m_Progress); + DDX_Control(pDX, IDOK, m_Ok); + DDX_Control(pDX, IDCANCEL, m_Cancel); + DDX_Control(pDX, IDC_EDIT1, m_IniFilePath); + DDX_Control(pDX, IDC_EDIT2, m_DataDir); + DDX_Control(pDX, IDC_EDIT3, m_Version); + DDX_Control(pDX, IDC_EDIT7, m_IniFileLabel); + DDX_Control(pDX, IDC_EDIT8, m_DataDirLabel); + DDX_Control(pDX, IDC_EDIT9, m_VersionLabel); + DDX_Control(pDX, IDC_BUTTON1, m_SelectAll); + DDX_Control(pDX, IDC_BUTTON2, m_ClearAll); +} + +BEGIN_MESSAGE_MAP(CUpgradeDlg, CDialog) + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_LBN_SELCHANGE(IDC_LIST1, &CUpgradeDlg::OnLbnSelchangeList1) + ON_CONTROL(CLBN_CHKCHANGE, IDC_LIST1, OnChkChange) + ON_BN_CLICKED(IDOK, &CUpgradeDlg::OnBnClickedOk) + ON_BN_CLICKED(IDCANCEL, &CUpgradeDlg::OnBnClickedCancel) + ON_BN_CLICKED(IDC_BUTTON1,&CUpgradeDlg::OnBnSelectAll) + ON_BN_CLICKED(IDC_BUTTON2,&CUpgradeDlg::OnBnClearAll) +END_MESSAGE_MAP() + + +struct ServiceProperties +{ + string servicename; + string myini; + string datadir; + string version; +}; + +vector<ServiceProperties> services; + +/* + Get version from an executable. + Returned version is either major.minor.patch or + <unknown> , of executable does not have any version + info embedded (like MySQL 5.1 for example) +*/ +void GetExeVersion(const string& filename, int *major, int *minor, int *patch) +{ + DWORD handle; + *major= *minor= *patch= 0; + + DWORD size = GetFileVersionInfoSize(filename.c_str(), &handle); + BYTE* versionInfo = new BYTE[size]; + if (!GetFileVersionInfo(filename.c_str(), handle, size, versionInfo)) + { + delete[] versionInfo; + return; + } + // we have version information + UINT len = 0; + VS_FIXEDFILEINFO* vsfi = NULL; + VerQueryValue(versionInfo, "\\", (void**)&vsfi, &len); + + *major= (int)HIWORD(vsfi->dwFileVersionMS); + *minor= (int)LOWORD(vsfi->dwFileVersionMS); + *patch= (int)HIWORD(vsfi->dwFileVersionLS); + delete[] versionInfo; +} + + +void GetMyVersion(int *major, int *minor, int *patch) +{ + char path[MAX_PATH]; + *major= *minor= *patch =0; + if (GetModuleFileName(NULL, path, MAX_PATH)) + { + GetExeVersion(path, major, minor, patch); + } +} +// CUpgradeDlg message handlers + +/* Handle selection changes in services list */ +void CUpgradeDlg::SelectService(int index) +{ + m_IniFilePath.SetWindowText(services[index].myini.c_str()); + m_DataDir.SetWindowText(services[index].datadir.c_str()); + m_Version.SetWindowText(services[index].version.c_str()); +} + + + +/* + Iterate over services, lookup for mysqld.exe ones. + Compare mysqld.exe version with current version, and display + service if corresponding mysqld.exe has lower version. + + The version check is not strict, i.e we allow to "upgrade" + for the same major.minor combination. This can be useful for + "upgrading" from 32 to 64 bit, or for MySQL=>Maria conversion. +*/ +void CUpgradeDlg::PopulateServicesList() +{ + + SC_HANDLE scm = OpenSCManager(NULL, NULL, + SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT); + if (scm == NULL) + { + ErrorExit("OpenSCManager failed"); + } + + static BYTE buf[64*1024]; + static BYTE configBuffer[8*1024]; + + DWORD bufsize= sizeof(buf); + DWORD bufneed; + DWORD num_services; + BOOL ok= EnumServicesStatusEx(scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, + SERVICE_STATE_ALL, buf, bufsize, &bufneed, &num_services, NULL, NULL); + if(!ok) + ErrorExit("EnumServicesStatusEx failed"); + + + LPENUM_SERVICE_STATUS_PROCESS info = + (LPENUM_SERVICE_STATUS_PROCESS)buf; + int index=-1; + for (ULONG i=0; i < num_services; i++) + { + SC_HANDLE service= OpenService(scm, info[i].lpServiceName, + SERVICE_QUERY_CONFIG); + if (!service) + continue; + QUERY_SERVICE_CONFIGW *config= + (QUERY_SERVICE_CONFIGW*)(void *)configBuffer; + DWORD needed; + BOOL ok= QueryServiceConfigW(service, config,sizeof(configBuffer), &needed); + CloseServiceHandle(service); + if (ok) + { + mysqld_service_properties service_props; + + if (get_mysql_service_properties(config->lpBinaryPathName, + &service_props)) + continue; + + /* Check if service uses mysqld in installation directory */ + if (_strnicmp(service_props.mysqld_exe, m_InstallDir.c_str(), + m_InstallDir.size()) == 0) + continue; + + if(m_MajorVersion > service_props.version_major || + (m_MajorVersion == service_props.version_major && m_MinorVersion >= + service_props.version_minor)) + { + ServiceProperties props; + props.myini= service_props.inifile; + props.datadir= service_props.datadir; + props.servicename = info[i].lpServiceName; + if (service_props.version_major) + { + char ver[64]; + sprintf(ver, "%d.%d.%d", service_props.version_major, + service_props.version_minor, service_props.version_patch); + props.version= ver; + } + else + props.version= "<unknown>"; + + index = m_Services.AddString(info[i].lpServiceName); + services.resize(index+1); + services[index] = props; + } + } + if (index != -1) + { + m_Services.SetCurSel(0); + SelectService(m_Services.GetCurSel()); + } + } + if (services.size()) + { + SelectService(0); + } + else + { + char message[128]; + sprintf(message, + "There is no service that can be upgraded to " PRODUCT_NAME " %d.%d.%d", + m_MajorVersion, m_MinorVersion, m_PatchVersion); + MessageBox(message, PRODUCT_NAME " Upgrade Wizard", MB_ICONINFORMATION); + exit(0); + } + if(scm) + CloseServiceHandle(scm); +} + +BOOL CUpgradeDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + m_UpgradeRunning= FALSE; + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + m_Ok.SetWindowText("Upgrade"); + m_DataDirLabel.SetWindowText("Data directory:"); + m_IniFileLabel.SetWindowText("Configuration file:"); + m_VersionLabel.SetWindowText("Version:"); + + char myFilename[MAX_PATH]; + GetModuleFileName(NULL, myFilename, MAX_PATH); + char *p= strrchr(myFilename,'\\'); + if(p) + p[1]=0; + m_InstallDir= myFilename; + + GetMyVersion(&m_MajorVersion, &m_MinorVersion, &m_PatchVersion); + char windowTitle[64]; + + sprintf(windowTitle, PRODUCT_NAME " %d.%d.%d Upgrade Wizard", + m_MajorVersion, m_MinorVersion, m_PatchVersion); + SetWindowText(windowTitle); + + m_JobObject= CreateJobObject(NULL, NULL); + + /* + Make all processes associated with the job terminate when the + last handle to the job is closed or job is teminated. + */ + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0}; + jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + SetInformationJobObject(m_JobObject, JobObjectExtendedLimitInformation, + &jeli, sizeof(jeli)); + + + m_Progress.ShowWindow(SW_HIDE); + m_Ok.EnableWindow(FALSE); + PopulateServicesList(); + return TRUE; // return TRUE unless you set the focus to a control +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CUpgradeDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, + reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialog::OnPaint(); + } +} + +// The system calls this function to obtain the cursor to display while the user +// drags the minimized window. +HCURSOR CUpgradeDlg::OnQueryDragIcon() +{ + return static_cast<HCURSOR>(m_hIcon); +} + + +void CUpgradeDlg::OnLbnSelchangeList1() +{ + SelectService(m_Services.GetCurSel()); +} + +void CUpgradeDlg::OnChkChange() +{ + if(m_Services.GetCheck( m_Services.GetCurSel())) + { + GetDlgItem(IDOK)->EnableWindow(); + } + else + { + for(int i=0; i< m_Services.GetCount(); i++) + { + if(m_Services.GetCheck(i)) + return; + } + // all items unchecked, disable OK button + GetDlgItem(IDOK)->EnableWindow(FALSE); + } +} + + + +void CUpgradeDlg::ErrorExit(LPCSTR str) +{ + MessageBox(str, "Fatal Error", MB_ICONERROR); + exit(1); +} + + +const int MAX_MESSAGES=512; + +/* Main thread of the child process */ +static HANDLE hChildThread; + +void CUpgradeDlg::UpgradeOneService(const string& servicename) +{ + static string allMessages[MAX_MESSAGES]; + static char npname[MAX_PATH]; + static char pipeReadBuf[1]; + SECURITY_ATTRIBUTES saAttr; + STARTUPINFO si={0}; + PROCESS_INFORMATION pi; + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + HANDLE hPipeRead, hPipeWrite; + if(!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 1)) + ErrorExit("CreateNamedPipe failed"); + + /* Make sure read end of the pipe is not inherited */ + if (!SetHandleInformation(hPipeRead, HANDLE_FLAG_INHERIT, 0) ) + ErrorExit("Stdout SetHandleInformation"); + + string commandline("mysql_upgrade_service.exe --service="); + commandline += servicename; + si.cb = sizeof(si); + si.hStdInput= GetStdHandle(STD_INPUT_HANDLE); + si.hStdOutput= hPipeWrite; + si.hStdError= hPipeWrite; + si.wShowWindow= SW_HIDE; + si.dwFlags= STARTF_USESTDHANDLES |STARTF_USESHOWWINDOW; + + + /* + We will try to assign child process to a job, to be able to + terminate the process and all of its children. It might fail, + in case current process is already part of the job which does + not allows breakaways. + */ + if (CreateProcess(NULL, (LPSTR)commandline.c_str(), NULL, NULL, TRUE, + CREATE_BREAKAWAY_FROM_JOB|CREATE_SUSPENDED, NULL, NULL, &si, &pi)) + { + if(!AssignProcessToJobObject(m_JobObject, pi.hProcess)) + { + char errmsg[128]; + sprintf(errmsg, "AssignProcessToJobObject failed, error %d", + GetLastError()); + ErrorExit(errmsg); + } + ResumeThread(pi.hThread); + } + else + { + /* + Creating a process with CREATE_BREAKAWAY_FROM_JOB, reset this flag + and retry. + */ + if (!CreateProcess(NULL, (LPSTR)commandline.c_str(), NULL, NULL, TRUE, + 0, NULL, NULL, &si, &pi)) + { + string errmsg("Create Process "); + errmsg+= commandline; + errmsg+= " failed"; + ErrorExit(errmsg.c_str()); + } + } + + hChildThread = pi.hThread; + DWORD nbytes; + int lines=0; + CloseHandle(hPipeWrite); + + string output_line; + while(ReadFile(hPipeRead, pipeReadBuf, 1, &nbytes, NULL)) + { + if(pipeReadBuf[0] == '\n') + { + allMessages[lines%MAX_MESSAGES] = output_line; + m_DataDir.SetWindowText(allMessages[lines%MAX_MESSAGES].c_str()); + output_line.clear(); + lines++; + + /* + Updating progress dialog.There are currently 9 messages from + mysql_upgrade_service (actually it also writes Phase N/M but + we do not parse the output right now). + */ +#define EXPRECTED_MYSQL_UPGRADE_MESSAGES 9 + + int stepsTotal= m_ProgressTotal*EXPRECTED_MYSQL_UPGRADE_MESSAGES; + int stepsCurrent= m_ProgressCurrent*EXPRECTED_MYSQL_UPGRADE_MESSAGES + + lines; + int percentDone= stepsCurrent*100/stepsTotal; + m_Progress.SetPos(percentDone); + } + else + { + if(pipeReadBuf[0] != '\r') + output_line.push_back(pipeReadBuf[0]); + } + } + CloseHandle(hPipeWrite); + + if(WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0) + ErrorExit("WaitForSingleObject failed"); + DWORD exitcode; + if (!GetExitCodeProcess(pi.hProcess, &exitcode)) + ErrorExit("GetExitCodeProcess failed"); + + if (exitcode != 0) + { + string errmsg= "mysql_upgrade_service returned error for service "; + errmsg += servicename; + errmsg += ":\r\n"; + errmsg+= output_line; + ErrorExit(errmsg.c_str()); + } + CloseHandle(pi.hProcess); + hChildThread= 0; + CloseHandle(pi.hThread); +} + + +void CUpgradeDlg::UpgradeServices() +{ + + /* + Disable some dialog items during upgrade (OK button, + services list) + */ + m_Ok.EnableWindow(FALSE); + m_Services.EnableWindow(FALSE); + m_SelectAll.EnableWindow(FALSE); + m_ClearAll.EnableWindow(FALSE); + + /* + Temporarily repurpose IniFileLabel/IniFilePath and + DatDirLabel/DataDir controls to show progress messages. + */ + m_VersionLabel.ShowWindow(FALSE); + m_Version.ShowWindow(FALSE); + m_Progress.ShowWindow(TRUE); + m_IniFileLabel.SetWindowText("Converting service:"); + m_IniFilePath.SetWindowText(""); + m_DataDirLabel.SetWindowText("Progress message:"); + m_DataDir.SetWindowText(""); + + + m_ProgressTotal=0; + for(int i=0; i< m_Services.GetCount(); i++) + { + if(m_Services.GetCheck(i)) + m_ProgressTotal++; + } + m_ProgressCurrent=0; + for(int i=0; i< m_Services.GetCount(); i++) + { + if(m_Services.GetCheck(i)) + { + m_IniFilePath.SetWindowText(services[i].servicename.c_str()); + m_Services.SelectString(0, services[i].servicename.c_str()); + UpgradeOneService(services[i].servicename); + m_ProgressCurrent++; + } + } + + MessageBox("Service(s) successfully upgraded", "Success", + MB_ICONINFORMATION); + + /* Rebuild services list */ + vector<ServiceProperties> new_instances; + for(int i=0; i< m_Services.GetCount(); i++) + { + if(!m_Services.GetCheck(i)) + new_instances.push_back(services[i]); + } + + services= new_instances; + m_Services.ResetContent(); + for(size_t i=0; i< services.size();i++) + m_Services.AddString(services[i].servicename.c_str()); + if(services.size()) + { + m_Services.SelectString(0,services[0].servicename.c_str()); + SelectService(0); + } + else + { + /* Nothing to do, there are no upgradable services */ + exit(0); + } + + /* + Restore controls that were temporarily repurposed for + progress info to their normal state + */ + m_IniFileLabel.SetWindowText("Configuration file:"); + m_DataDirLabel.SetWindowText("Data Directory:"); + m_VersionLabel.ShowWindow(TRUE); + m_Version.ShowWindow(TRUE); + m_Progress.SetPos(0); + m_Progress.ShowWindow(FALSE); + + /* Re-enable controls */ + m_Ok.EnableWindow(TRUE); + m_Services.EnableWindow(TRUE); + m_SelectAll.EnableWindow(TRUE); + m_ClearAll.EnableWindow(TRUE); + + m_UpgradeRunning= FALSE; +} + + +/* Thread procedure for upgrade services operation */ +static UINT UpgradeServicesThread(void *param) +{ + CUpgradeDlg *dlg= (CUpgradeDlg *)param; + dlg->UpgradeServices(); + return 0; +} + + +/* + Do upgrade for all services currently selected + in the list. Since it is a potentially lengthy operation that + might block it has to be done in a background thread. +*/ +void CUpgradeDlg::OnBnClickedOk() +{ + if(m_UpgradeRunning) + return; + m_UpgradeRunning= TRUE; + AfxBeginThread(UpgradeServicesThread, this); +} + + +/* + Cancel button clicked. + If upgrade is running, suspend mysql_upgrade_service, + and ask user whether he really wants to stop.Terminate + upgrade wizard and all subprocesses if users wants it. + + If upgrade is not running, terminate the Wizard +*/ +void CUpgradeDlg::OnBnClickedCancel() +{ + if(m_UpgradeRunning) + { + bool suspended = (SuspendThread(hChildThread) != (DWORD)-1); + int ret = MessageBox( + "Upgrade is in progress. Are you sure you want to terminate?", + 0, MB_YESNO|MB_DEFBUTTON2|MB_ICONQUESTION); + if(ret != IDYES) + { + if(suspended) + ResumeThread(hChildThread); + return; + } + } + TerminateJobObject(m_JobObject, 1); + exit(1); +} + +/* + Select all services from the list +*/ +void CUpgradeDlg::OnBnSelectAll() +{ + for(int i=0; i < m_Services.GetCount(); i++) + m_Services.SetCheck(i, 1); + m_Ok.EnableWindow(TRUE); +} + +/* + Clear all services in the list +*/ +void CUpgradeDlg::OnBnClearAll() +{ + for(int i=0; i < m_Services.GetCount(); i++) + m_Services.SetCheck(i, 0); + m_Ok.EnableWindow(FALSE); +} diff --git a/win/upgrade_wizard/upgradeDlg.h b/win/upgrade_wizard/upgradeDlg.h new file mode 100644 index 00000000000..97243291748 --- /dev/null +++ b/win/upgrade_wizard/upgradeDlg.h @@ -0,0 +1,73 @@ +
+// upgradeDlg.h : header file
+//
+
+#pragma once
+#include "afxcmn.h"
+#include "afxwin.h"
+#include <string>
+
+
+// CUpgradeDlg dialog
+class CUpgradeDlg : public CDialog
+{
+ // Construction
+public:
+ CUpgradeDlg(CWnd* pParent = NULL); // standard constructor
+
+ // Dialog Data
+ enum { IDD = IDD_UPGRADE_DIALOG };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ // job object for current process and children
+ HANDLE m_JobObject;
+
+ // Services are being upgraded
+ BOOL m_UpgradeRunning;
+
+ // ProgressBar related: number of services to upgrade
+ int m_ProgressTotal;
+
+ //ProgressBar related: current service being upgraded
+ int m_ProgressCurrent;
+
+protected:
+ HICON m_hIcon;
+
+ // Generated message map functions
+ virtual BOOL OnInitDialog();
+ void PopulateServicesList();
+ afx_msg void OnPaint();
+ afx_msg HCURSOR OnQueryDragIcon();
+ DECLARE_MESSAGE_MAP()
+public:
+ void SelectService(int index);
+ void UpgradeServices();
+ void UpgradeOneService(const std::string& name);
+ void ErrorExit(const char *);
+ std::string m_InstallDir;
+ CCheckListBox m_Services;
+ CProgressCtrl m_Progress;
+ CButton m_Ok;
+ CButton m_Cancel;
+ CButton m_SelectAll;
+ CButton m_ClearAll;
+ int m_MajorVersion;
+ int m_MinorVersion;
+ int m_PatchVersion;
+
+ CEdit m_IniFilePath;
+ afx_msg void OnLbnSelchangeList1();
+ afx_msg void OnChkChange();
+ CEdit m_DataDir;
+ CEdit m_Version;
+ afx_msg void OnBnClickedOk();
+ afx_msg void OnBnClickedCancel();
+ afx_msg void OnBnSelectAll();
+ afx_msg void OnBnClearAll();
+ CEdit m_IniFileLabel;
+ CEdit m_DataDirLabel;
+ CEdit m_VersionLabel;
+};
diff --git a/win/upgrade_wizard/upgrade_wizard.exe.manifest b/win/upgrade_wizard/upgrade_wizard.exe.manifest new file mode 100644 index 00000000000..6b40eebcbd9 --- /dev/null +++ b/win/upgrade_wizard/upgrade_wizard.exe.manifest @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
+ </dependentAssembly>
+ </dependency>
+</assembly>
\ No newline at end of file diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt index a4b75bd5744..43235b631f6 100755 --- a/zlib/CMakeLists.txt +++ b/zlib/CMakeLists.txt @@ -27,6 +27,4 @@ SET(ZLIB_SOURCES adler32.c compress.c crc32.c crc32.h deflate.c deflate.h gzio. zutil.c zutil.h) IF(NOT SOURCE_SUBLIBS) ADD_LIBRARY(zlib ${ZLIB_SOURCES}) - - INSTALL(TARGETS zlib DESTINATION lib/opt COMPONENT runtime) # TODO: Component ENDIF(NOT SOURCE_SUBLIBS) |