diff options
author | Alexander Barkov <bar@mysql.com> | 2010-02-27 11:43:32 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mysql.com> | 2010-02-27 11:43:32 +0400 |
commit | 7a83782f1caa102ebc552b017885f18f005425f0 (patch) | |
tree | 79944b66b5194acfaac9f3ba322f1403d08f0080 /storage | |
parent | 69904fa6584b383368c94b1531e1a1a8a57f43b5 (diff) | |
parent | 6190282adb84a0b12829671ce9c4b98a7219c809 (diff) | |
download | mariadb-git-7a83782f1caa102ebc552b017885f18f005425f0.tar.gz |
Mergine from mysql-next-me
Diffstat (limited to 'storage')
-rw-r--r-- | storage/Makefile.am | 1 | ||||
-rw-r--r-- | storage/archive/CMakeLists.txt | 5 | ||||
-rw-r--r-- | storage/blackhole/CMakeLists.txt | 5 | ||||
-rw-r--r-- | storage/csv/CMakeLists.txt | 5 | ||||
-rw-r--r-- | storage/example/CMakeLists.txt | 4 | ||||
-rw-r--r-- | storage/federated/CMakeLists.txt | 10 | ||||
-rwxr-xr-x | storage/heap/CMakeLists.txt | 6 | ||||
-rw-r--r-- | storage/ibmdb2i/CMakeLists.txt | 26 | ||||
-rw-r--r-- | storage/innobase/CMakeLists.txt | 220 | ||||
-rwxr-xr-x | storage/myisam/CMakeLists.txt | 53 | ||||
-rw-r--r-- | storage/myisam/ha_myisam.cc | 8 | ||||
-rwxr-xr-x | storage/myisammrg/CMakeLists.txt | 4 | ||||
-rw-r--r-- | storage/myisammrg/ha_myisammrg.cc | 811 | ||||
-rw-r--r-- | storage/myisammrg/ha_myisammrg.h | 54 | ||||
-rw-r--r-- | storage/myisammrg/myrg_extra.c | 11 | ||||
-rw-r--r-- | storage/mysql_storage_engine.cmake | 44 | ||||
-rw-r--r-- | storage/perfschema/CMakeLists.txt | 8 | ||||
-rw-r--r-- | storage/perfschema/pfs.cc | 8 | ||||
-rw-r--r-- | storage/perfschema/pfs_engine_table.cc | 6 | ||||
-rw-r--r-- | storage/perfschema/unittest/CMakeLists.txt | 30 |
20 files changed, 897 insertions, 422 deletions
diff --git a/storage/Makefile.am b/storage/Makefile.am index 8aa1e4f7dc6..5b4e32374ae 100644 --- a/storage/Makefile.am +++ b/storage/Makefile.am @@ -18,7 +18,6 @@ AUTOMAKE_OPTIONS = foreign # These are built from source in the Docs directory -EXTRA_DIST = mysql_storage_engine.cmake SUBDIRS = @mysql_se_dirs@ DIST_SUBDIRS = @mysql_se_distdirs@ diff --git a/storage/archive/CMakeLists.txt b/storage/archive/CMakeLists.txt index ce4d92d3f99..d47fd254b0e 100644 --- a/storage/archive/CMakeLists.txt +++ b/storage/archive/CMakeLists.txt @@ -13,6 +13,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") + SET(ARCHIVE_SOURCES azio.c ha_archive.cc ha_archive.h) -MYSQL_STORAGE_ENGINE(ARCHIVE) +MYSQL_ADD_PLUGIN(archive ${ARCHIVE_SOURCES} STORAGE_ENGINE LINK_LIBRARIES ${ZLIB_LIBRARY}) + diff --git a/storage/blackhole/CMakeLists.txt b/storage/blackhole/CMakeLists.txt index bed282ef21d..5a4bb3fe607 100644 --- a/storage/blackhole/CMakeLists.txt +++ b/storage/blackhole/CMakeLists.txt @@ -13,7 +13,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") -SET(BLACKHOLE_SOURCES ha_blackhole.cc ha_blackhole.h) -MYSQL_STORAGE_ENGINE(BLACKHOLE) +SET(BLACKHOLE_SOURCES ha_blackhole.cc ha_blackhole.h) +MYSQL_ADD_PLUGIN(blackhole ${BLACKHOLE_SOURCES} STORAGE_ENGINE) diff --git a/storage/csv/CMakeLists.txt b/storage/csv/CMakeLists.txt index 37760588897..73d1794a369 100644 --- a/storage/csv/CMakeLists.txt +++ b/storage/csv/CMakeLists.txt @@ -13,7 +13,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +SET(CSV_PLUGIN_STATIC "csv") +SET(CSV_PLUGIN_MANDATORY TRUE) -INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") SET(CSV_SOURCES ha_tina.cc ha_tina.h transparent_file.cc transparent_file.h) -MYSQL_STORAGE_ENGINE(CSV)
\ No newline at end of file +MYSQL_ADD_PLUGIN(csv ${CSV_SOURCES} STORAGE_ENGINE MANDATORY) diff --git a/storage/example/CMakeLists.txt b/storage/example/CMakeLists.txt index f0b1343ab9c..5a6f5d78c6b 100644 --- a/storage/example/CMakeLists.txt +++ b/storage/example/CMakeLists.txt @@ -13,6 +13,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") +SET(EXAMPLE_PLUGIN_DYNAMIC "ha_example") SET(EXAMPLE_SOURCES ha_example.cc) -MYSQL_STORAGE_ENGINE(EXAMPLE) +MYSQL_ADD_PLUGIN(example ${EXAMPLE_SOURCES} STORAGE_ENGINE MODULE_ONLY) diff --git a/storage/federated/CMakeLists.txt b/storage/federated/CMakeLists.txt index fa54d36481a..ac55543f276 100644 --- a/storage/federated/CMakeLists.txt +++ b/storage/federated/CMakeLists.txt @@ -13,6 +13,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") +SET(FEDERATED_PLUGIN_STATIC "federated") +SET(FEDERATED_PLUGIN_DYNAMIC "ha_federated") SET(FEDERATED_SOURCES ha_federated.cc) -MYSQL_STORAGE_ENGINE(FEDERATED) +IF(NOT WITH_FEDERATED AND NOT WITH_FEDERATED_STORAGE_ENGINE) + # Bug#45488- federated uses symbols that are not used anywhere in + # mysqld and are optimized away by the linker. + SET(FEDERATED_SOURCES ${FEDERATED_SOURCES} ${CMAKE_SOURCE_DIR}/mysys/string.c) +ENDIF() +MYSQL_ADD_PLUGIN(federated ${FEDERATED_SOURCES} STORAGE_ENGINE) diff --git a/storage/heap/CMakeLists.txt b/storage/heap/CMakeLists.txt index 4a0fa22c8f1..32359759abc 100755 --- a/storage/heap/CMakeLists.txt +++ b/storage/heap/CMakeLists.txt @@ -13,11 +13,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +SET(HEAP_PLUGIN_STATIC "heap") +SET(HEAP_PLUGIN_MANDATORY TRUE) -INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") SET(HEAP_SOURCES _check.c _rectest.c hp_block.c hp_clear.c hp_close.c hp_create.c ha_heap.cc hp_delete.c hp_extra.c hp_hash.c hp_info.c hp_open.c hp_panic.c hp_rename.c hp_rfirst.c hp_rkey.c hp_rlast.c hp_rnext.c hp_rprev.c hp_rrnd.c hp_rsame.c hp_scan.c hp_static.c hp_update.c hp_write.c) -MYSQL_STORAGE_ENGINE(HEAP) + +MYSQL_ADD_PLUGIN(heap ${HEAP_SOURCES} STORAGE_ENGINE MANDATORY RECOMPILE_FOR_EMBEDDED) diff --git a/storage/ibmdb2i/CMakeLists.txt b/storage/ibmdb2i/CMakeLists.txt index 11cc4300569..e8db6989583 100644 --- a/storage/ibmdb2i/CMakeLists.txt +++ b/storage/ibmdb2i/CMakeLists.txt @@ -13,13 +13,27 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +CHECK_INCLUDE_FILES(qlgusr.h HAVE_PASE_ENVIRONMENT) +IF(HAVE_PASE_ENVIRONMENT) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql - ${CMAKE_SOURCE_DIR}/regex - ${CMAKE_SOURCE_DIR}/extra/yassl/include) -ADD_LIBRARY(ibmdb2i ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/include + ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_CURRENT_SOURCE_DIR} + /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0f.xpf/cur/cmvc/base.pgm/my.xpf/apis + /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0.xpf/bld/cmvc/base.pgm/lg.xpf + /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0.xpf/bld/cmvc/base.pgm/tq.xpf +) + + +SET (IBMDB2I_SOURCES ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc db2i_blobCollection.cc db2i_file.cc db2i_charsetSupport.cc db2i_collationSupport.cc db2i_errors.cc db2i_constraints.cc db2i_rir.cc db2i_sqlStatementStream.cc db2i_ioBuffers.cc db2i_myconv.cc) + + +MYSQL_ADD_PLUGIN(ibmdb2i ${IBMDB2I_SOURCES} STORAGE_ENGINE LINK_LIBRARIES iconv) + +ENDIF(HAVE_PASE_ENVIRONMENT) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index b63ed840f3c..a11007c8472 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -15,33 +15,191 @@ # This is the CMakeLists for InnoDB Plugin -# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin -# CMakeLists.txt still needs to work with previous versions of MySQL. -IF (MYSQL_VERSION_ID GREATER "50137") - INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") -ENDIF (MYSQL_VERSION_ID GREATER "50137") +INCLUDE(CheckFunctionExists) +INCLUDE(CheckCSourceCompiles) +INCLUDE(CheckCSourceRuns) + +# OS tests +IF(UNIX) + IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") + ADD_DEFINITIONS("-DUNIV_LINUX -D_GNU_SOURCE=1") + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "HP*") + ADD_DEFINITIONS("-DUNIV_HPUX -DUNIV_MUST_NOT_INLINE") + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "AIX") + ADD_DEFINITIONS("-DUNIV_AIX -DUNIX_MUST_NOT_INLINE") + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + ADD_DEFINITIONS("-DUNIV_SOLARIS") + ELSE() + ADD_DEFINITIONS("-DUNIV_MUST_NOT_INLINE") + ENDIF() +ENDIF() + + +IF(NOT MSVC) +# either define HAVE_IB_GCC_ATOMIC_BUILTINS or not +IF(NOT CMAKE_CROSSCOMPILING) + CHECK_C_SOURCE_RUNS( + " + int main() + { + long x; + long y; + long res; + char c; + + x = 10; + y = 123; + res = __sync_bool_compare_and_swap(&x, x, y); + if (!res || x != y) { + return(1); + } + + x = 10; + y = 123; + res = __sync_bool_compare_and_swap(&x, x + 1, y); + if (res || x != 10) { + return(1); + } + x = 10; + y = 123; + res = __sync_add_and_fetch(&x, y); + if (res != 123 + 10 || x != 123 + 10) { + return(1); + } + + c = 10; + res = __sync_lock_test_and_set(&c, 123); + if (res != 10 || c != 123) { + return(1); + } + return(0); + }" + HAVE_IB_GCC_ATOMIC_BUILTINS + ) +ENDIF() + +IF(HAVE_IB_GCC_ATOMIC_BUILTINS) + ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS=1) +ENDIF() + + # either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not +IF(NOT CMAKE_CROSSCOMPILING) + CHECK_C_SOURCE_RUNS( + " + #include <pthread.h> + #include <string.h> + + int main(int argc, char** argv) { + pthread_t x1; + pthread_t x2; + pthread_t x3; + + memset(&x1, 0x0, sizeof(x1)); + memset(&x2, 0x0, sizeof(x2)); + memset(&x3, 0x0, sizeof(x3)); + + __sync_bool_compare_and_swap(&x1, x2, x3); + + return(0); + }" + HAVE_IB_ATOMIC_PTHREAD_T_GCC) +ENDIF() +IF(HAVE_IB_ATOMIC_PTHREAD_T_GCC) + ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_GCC=1) +ENDIF() + +ENDIF(NOT MSVC) + +# Solaris atomics +IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + CHECK_FUNCTION_EXISTS(atomic_cas_ulong HAVE_ATOMIC_CAS_ULONG) + CHECK_FUNCTION_EXISTS(atomic_cas_32 HAVE_ATOMIC_CAS_32) + CHECK_FUNCTION_EXISTS(atomic_cas_64 HAVE_ATOMIC_CAS_64) + CHECK_FUNCTION_EXISTS(atomic_add_long HAVE_ATOMIC_ADD_LONG) + IF(HAVE_ATOMIC_CAS_ULONG AND HAVE_ATOMIC_CAS_32 AND + HAVE_ATOMIC_CAS_64 AND HAVE_ATOMIC_ADD_LONG) + SET(HAVE_IB_SOLARIS_ATOMICS 1) + ENDIF() + + IF(HAVE_IB_SOLARIS_ATOMICS) + ADD_DEFINITIONS(-DHAVE_IB_SOLARIS_ATOMICS=1) + ENDIF() + + IF(NOT CMAKE_CROSSCOMPILING) + # either define HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS or not + CHECK_C_SOURCE_COMPILES( + " #include <pthread.h> + #include <string.h> + + int main(int argc, char** argv) { + pthread_t x1; + pthread_t x2; + pthread_t x3; + + memset(&x1, 0x0, sizeof(x1)); + memset(&x2, 0x0, sizeof(x2)); + memset(&x3, 0x0, sizeof(x3)); + + if (sizeof(pthread_t) == 4) { + + atomic_cas_32(&x1, x2, x3); + + } else if (sizeof(pthread_t) == 8) { + + atomic_cas_64(&x1, x2, x3); + + } else { + + return(1); + } + + return(0); + } + " HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) + ENDIF() + IF(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) + ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_SOLARIS=1) + ENDIF() +ENDIF() + + +IF(UNIX) +# this is needed to know which one of atomic_cas_32() or atomic_cas_64() +# to use in the source +SET(CMAKE_EXTRA_INCLUDE_FILES pthread.h) +CHECK_TYPE_SIZE(pthread_t SIZEOF_PTHREAD_T) +SET(CMAKE_EXTRA_INCLUDE_FILES) +ENDIF() + +IF(SIZEOF_PTHREAD_T) + ADD_DEFINITIONS(-DSIZEOF_PTHREAD_T=${SIZEOF_PTHREAD_T}) +ENDIF() + +IF(MSVC) + ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION) +ENDIF() -IF (CMAKE_SIZEOF_VOID_P MATCHES 8) - SET(WIN64 TRUE) -ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8) # Include directories under innobase INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include ${CMAKE_SOURCE_DIR}/storage/innobase/handler) -# Include directories under mysql -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/sql - ${CMAKE_SOURCE_DIR}/regex - ${CMAKE_SOURCE_DIR}/zlib - ${CMAKE_SOURCE_DIR}/extra/yassl/include) +# Sun Studio bug with -xO2 +IF(CMAKE_C_COMPILER_ID MATCHES "SunPro" + AND CMAKE_C_FLAGS_RELEASE MATCHES "O2" + AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + # Sun Studio 12 crashes with -xO2 flag, but not with higher optimization + # -xO3 + SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/rem/rem0rec.c + PROPERTIES COMPILE_FLAGS -xO3) +ENDIF() # Removing compiler optimizations for innodb/mem/* files on 64-bit Windows # due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297 -IF (MSVC AND $(WIN64)) +IF (MSVC AND CMAKE_SIZEOF_VOIDP EQUAL 8) SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c PROPERTIES COMPILE_FLAGS -Od) -ENDIF (MSVC AND $(WIN64)) +ENDIF() SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c @@ -76,20 +234,34 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c usr/usr0sess.c ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c) -ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION) -IF (MYSQL_VERSION_ID GREATER "50137") +IF(WITH_INNODB) + # Legacy option + SET(WITH_INNOBASE_STORAGE_ENGINE TRUE) +ENDIF() + + +#The plugin's CMakeLists.txt still needs to work with previous versions of MySQL. +IF(EXISTS ${SOURCE_DIR}/storage/mysql_storage_engine.cmake) + # Old plugin support on Windows only, + # use tricks to force ha_innodb.dll name for DLL + INCLUDE(${SOURCE_DIR}/storage/mysql_storage_engine.cmake) MYSQL_STORAGE_ENGINE(INNOBASE) - # Use ha_innodb for plugin name, if plugin is built GET_TARGET_PROPERTY(LIB_LOCATION ha_innobase LOCATION) IF(LIB_LOCATION) SET_TARGET_PROPERTIES(ha_innobase PROPERTIES OUTPUT_NAME ha_innodb) - ENDIF(LIB_LOCATION) -ELSE (MYSQL_VERSION_ID GREATER "50137") + ENDIF() +ELSEIF (MYSQL_VERSION_ID LESS "50137") + # Windows only, no plugin support IF (NOT SOURCE_SUBLIBS) - ADD_DEFINITIONS(-D_WIN32 -DMYSQL_SERVER) + ADD_DEFINITIONS(-DMYSQL_SERVER) ADD_LIBRARY(innobase STATIC ${INNOBASE_SOURCES}) # Require mysqld_error.h, which is built as part of the GenError ADD_DEPENDENCIES(innobase GenError) - ENDIF (NOT SOURCE_SUBLIBS) -ENDIF (MYSQL_VERSION_ID GREATER "50137") + ENDIF() +ELSE() + # New plugin support, cross-platform , base name for shared module is "ha_innodb" + MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE + MODULE_OUTPUT_NAME ha_innodb + LINK_LIBRARIES ${ZLIB_LIBRARY}) +ENDIF() diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt index 9a0aa06e861..4b7007055d8 100755 --- a/storage/myisam/CMakeLists.txt +++ b/storage/myisam/CMakeLists.txt @@ -12,9 +12,6 @@ # 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("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") -INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") - SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c ft_stem.c ha_myisam.cc @@ -29,28 +26,42 @@ SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c rt_split.c sort.c sp_key.c ft_eval.h mi_extrafunc.h myisamdef.h rt_index.h mi_rkey.c) -MYSQL_STORAGE_ENGINE(MYISAM) +MYSQL_ADD_PLUGIN(myisam ${MYISAM_SOURCES} + STORAGE_ENGINE + MANDATORY + RECOMPILE_FOR_EMBEDDED) -IF(NOT SOURCE_SUBLIBS) - ADD_EXECUTABLE(myisam_ftdump myisam_ftdump.c) - TARGET_LINK_LIBRARIES(myisam_ftdump myisam mysys dbug strings zlib) +TARGET_LINK_LIBRARIES(myisam mysys) - ADD_EXECUTABLE(myisamchk myisamchk.c) - TARGET_LINK_LIBRARIES(myisamchk myisam mysys dbug strings zlib) +MYSQL_ADD_EXECUTABLE(myisam_ftdump myisam_ftdump.c) +TARGET_LINK_LIBRARIES(myisam_ftdump myisam) - ADD_EXECUTABLE(myisamlog myisamlog.c) - TARGET_LINK_LIBRARIES(myisamlog myisam mysys dbug strings zlib) +MYSQL_ADD_EXECUTABLE(myisamchk myisamchk.c) +TARGET_LINK_LIBRARIES(myisamchk myisam) - ADD_EXECUTABLE(myisampack myisampack.c) - TARGET_LINK_LIBRARIES(myisampack myisam mysys dbug strings zlib) +MYSQL_ADD_EXECUTABLE(myisamlog myisamlog.c) +TARGET_LINK_LIBRARIES(myisamlog myisam) - SET_TARGET_PROPERTIES(myisamchk myisampack PROPERTIES LINK_FLAGS "setargv.obj") +MYSQL_ADD_EXECUTABLE(myisampack myisampack.c) +TARGET_LINK_LIBRARIES(myisampack myisam) + +IF(WITH_UNIT_TESTS AND FALSE) + ADD_EXECUTABLE(mi_test1 mi_test1.c) + TARGET_LINK_LIBRARIES(mi_test1 myisam) - 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) + ADD_EXECUTABLE(mi_test2 mi_test2.c) + TARGET_LINK_LIBRARIES(mi_test2 myisam) -ENDIF(NOT SOURCE_SUBLIBS) + ADD_EXECUTABLE(mi_test3 mi_test3.c) + TARGET_LINK_LIBRARIES(mi_test3 myisam) + + ADD_EXECUTABLE(sp_test sp_test.c) + TARGET_LINK_LIBRARIES(sp_test myisam) + + ADD_EXECUTABLE(rt_test rt_test.c) + TARGET_LINK_LIBRARIES(rt_test myisam) +ENDIF() + +IF (MSVC) + SET_TARGET_PROPERTIES(myisamchk myisampack PROPERTIES LINK_FLAGS "setargv.obj") +ENDIF() diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 8a32e7255c0..13f042ba904 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1006,7 +1006,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) ha_release_temporary_latches(thd); // Don't lock tables if we have used LOCK TABLE - if (!thd->locked_tables && + if (! thd->locked_tables_mode && mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK)) { mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno); @@ -1116,7 +1116,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) update_state_info(¶m, file, 0); } thd_proc_info(thd, old_proc_info); - if (!thd->locked_tables) + if (! thd->locked_tables_mode) mi_lock_database(file,F_UNLCK); DBUG_RETURN(error ? HA_ADMIN_FAILED : !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK); @@ -1709,7 +1709,7 @@ int ha_myisam::info(uint flag) /* Update share */ if (share->tmp_table == NO_TMP_TABLE) - mysql_mutex_lock(&share->mutex); + mysql_mutex_lock(&share->LOCK_ha_data); share->keys_in_use.set_prefix(share->keys); share->keys_in_use.intersect_extended(misam_info.key_map); share->keys_for_keyread.intersect(share->keys_in_use); @@ -1719,7 +1719,7 @@ int ha_myisam::info(uint flag) (char*) misam_info.rec_per_key, sizeof(table->key_info[0].rec_per_key[0])*share->key_parts); if (share->tmp_table == NO_TMP_TABLE) - mysql_mutex_unlock(&share->mutex); + mysql_mutex_unlock(&share->LOCK_ha_data); /* Set data_file_name and index_file_name to point at the symlink value diff --git a/storage/myisammrg/CMakeLists.txt b/storage/myisammrg/CMakeLists.txt index c545d04a780..739bcd565bc 100755 --- a/storage/myisammrg/CMakeLists.txt +++ b/storage/myisammrg/CMakeLists.txt @@ -13,8 +13,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") - SET(MYISAMMRG_SOURCES myrg_close.c myrg_create.c myrg_delete.c myrg_extra.c myrg_info.c ha_myisammrg.cc myrg_locking.c myrg_open.c myrg_panic.c myrg_queue.c myrg_range.c @@ -22,4 +20,4 @@ SET(MYISAMMRG_SOURCES myrg_close.c myrg_create.c myrg_delete.c myrg_extra.c myr myrg_rprev.c myrg_rrnd.c myrg_rsame.c myrg_static.c myrg_update.c myrg_write.c myrg_records.c) -MYSQL_STORAGE_ENGINE(MYISAMMRG) +MYSQL_ADD_PLUGIN(myisammrg ${MYISAMMRG_SOURCES} STORAGE_ENGINE MANDATORY RECOMPILE_FOR_EMBEDDED) diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 7d9cac775a8..066290ab515 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -33,40 +33,29 @@ and hence through open_tables(). When the parent appears in the list of tables to open, the initial open of the handler does nothing but read the meta file and collect a list of TABLE_LIST objects for the - children. This list is attached to the parent TABLE object as - TABLE::child_l. The end of the children list is saved in - TABLE::child_last_l. - - Back in open_tables(), add_merge_table_list() is called. It updates - each list member with the lock type and a back pointer to the parent - TABLE_LIST object TABLE_LIST::parent_l. The list is then inserted in - the list of tables to open, right behind the parent. Consequently, - open_tables() opens the children, one after the other. The TABLE - references of the TABLE_LIST objects are implicitly set to the open - tables. The children are opened as independent MyISAM tables, right as - if they are used by the SQL statement. - - TABLE_LIST::parent_l is required to find the parent 1. when the last - child has been opened and children are to be attached, and 2. when an - error happens during child open and the child list must be removed - from the queuery list. In these cases the current child does not have - TABLE::parent set or does not have a TABLE at all respectively. - - When the last child is open, attach_merge_children() is called. It - removes the list of children from the open list. Then the children are - "attached" to the parent. All required references between parent and + children. This list is attached to the handler object as + ha_myisammrg::children_l. The end of the children list is saved in + ha_myisammrg::children_last_l. + + Back in open_tables(), handler::extra(HA_EXTRA_ADD_CHILDREN_LIST) is + called. It updates each list member with the lock type and a back + pointer to the parent TABLE_LIST object TABLE_LIST::parent_l. The list + is then inserted in the list of tables to open, right behind the + parent. Consequently, open_tables() opens the children, one after the + other. The TABLE references of the TABLE_LIST objects are implicitly + set to the open tables by open_table(). The children are opened as + independent MyISAM tables, right as if they are used by the SQL + statement. + + When all tables from the statement query list are open, + handler::extra(HA_EXTRA_ATTACH_CHILDREN) is called. It "attaches" the + children to the parent. All required references between parent and children are set up. The MERGE storage engine sets up an array with references to the low-level MyISAM table objects (MI_INFO). It remembers the state of the table in MYRG_INFO::children_attached. - Every child TABLE::parent references the parent TABLE object. That way - TABLE objects belonging to a MERGE table can be identified. - TABLE::parent is required because the parent and child TABLE objects - can live longer than the parent TABLE_LIST object. So the path - child->pos_in_table_list->parent_l->table can be broken. - If necessary, the compatibility of parent and children is checked. This check is necessary when any of the objects are reopend. This is detected by comparing the current table def version against the @@ -80,14 +69,20 @@ myisammrg_attach_children_callback() sets it ot TRUE if a table def version mismatches the remembered child def version. - Finally the parent TABLE::children_attached is set. + The children chain remains in the statement query list until the table + is closed or the children are detached. This is done so that the + children are locked by lock_tables(). + + At statement end the children are detached. At the next statement + begin the open-add-attach sequence repeats. There is no exception for + LOCK TABLES. The fresh establishment of the parent-child relationship + before every statement catches numerous cases of ALTER/FLUSH/DROP/etc + of parent or children during LOCK TABLES. --- On parent open the storage engine structures are allocated and initialized. They stay with the open table until its final close. - - */ #ifdef USE_PRAGMA_IMPLEMENTATION @@ -118,7 +113,10 @@ static handler *myisammrg_create_handler(handlerton *hton, ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), file(0), is_cloned(0) -{} +{ + init_sql_alloc(&children_mem_root, + FN_REFLEN + ALLOC_ROOT_MIN_BLOCK_SIZE, 0); +} /** @@ -126,7 +124,9 @@ ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg) */ ha_myisammrg::~ha_myisammrg(void) -{} +{ + free_root(&children_mem_root, MYF(0)); +} static const char *ha_myisammrg_exts[] = { @@ -178,49 +178,53 @@ const char *ha_myisammrg::index_type(uint key_number) /** - @brief Callback function for open of a MERGE parent table. - - @detail This function adds a TABLE_LIST object for a MERGE child table - to a list of tables of the parent TABLE object. It is called for - each child table. - - The list of child TABLE_LIST objects is kept in the TABLE object of - the parent for the whole life time of the MERGE table. It is - inserted in the statement list behind the MERGE parent TABLE_LIST - object when the MERGE table is opened. It is removed from the - statement list after the last child is opened. - - All memeory used for the child TABLE_LIST objects and the strings - referred by it are taken from the parent TABLE::mem_root. Thus they - are all freed implicitly at the final close of the table. - - TABLE::child_l -> TABLE_LIST::next_global -> TABLE_LIST::next_global - # # ^ # ^ - # # | # | - # # +--------- TABLE_LIST::prev_global - # # | - # |<--- TABLE_LIST::prev_global | - # | - TABLE::child_last_l -----------------------------------------+ + Callback function for open of a MERGE parent table. @param[in] callback_param data pointer as given to myrg_parent_open() + this is used to pass the handler handle @param[in] filename file name of MyISAM table without extension. @return status @retval 0 OK @retval != 0 Error + + @detail + + This function adds a TABLE_LIST object for a MERGE child table to a + list of tables in the parent handler object. It is called for each + child table. + + The list of child TABLE_LIST objects is kept in the handler object + of the parent for the whole life time of the MERGE table. It is + inserted in the statement query list behind the MERGE parent + TABLE_LIST object when the MERGE table is opened. It is removed from + the statement query list at end of statement or at children detach. + + All memory used for the child TABLE_LIST objects and the strings + referred by it are taken from the parent + ha_myisammrg::children_mem_root. Thus they are all freed implicitly at + the final close of the table. + + children_l -> TABLE_LIST::next_global -> TABLE_LIST::next_global + # # ^ # ^ + # # | # | + # # +--------- TABLE_LIST::prev_global + # # | + # |<--- TABLE_LIST::prev_global | + # | + children_last_l -----------------------------------------+ */ static int myisammrg_parent_open_callback(void *callback_param, const char *filename) { - ha_myisammrg *ha_myrg; - TABLE *parent; - TABLE_LIST *child_l; - const char *db; - const char *table_name; - size_t dirlen; + ha_myisammrg *ha_myrg= (ha_myisammrg*) callback_param; + Mrg_child_def *mrg_child_def; + char *db; + char *table_name; + uint dirlen; + uint table_name_length; char dir_path[FN_REFLEN]; DBUG_ENTER("myisammrg_parent_open_callback"); @@ -234,7 +238,7 @@ static int myisammrg_parent_open_callback(void *callback_param, DBUG_RETURN(1); /* purecov: end */ } - table_name= filename + dirlen; + table_name= (char*) filename + dirlen; dirlen--; /* Strip off trailing '/'. */ memcpy(dir_path, filename, dirlen); dir_path[dirlen]= '\0'; @@ -242,117 +246,325 @@ static int myisammrg_parent_open_callback(void *callback_param, dirlen-= db - dir_path; /* This is now the length of 'db'. */ DBUG_PRINT("myrg", ("open: '%s'.'%s'", db, table_name)); - ha_myrg= (ha_myisammrg*) callback_param; - parent= ha_myrg->table_ptr(); + /* Set database (schema) name. */ + db= strmake_root(&ha_myrg->children_mem_root, db, dirlen); + /* Set table name. */ + table_name_length= strlen(table_name); + table_name= strmake_root(&ha_myrg->children_mem_root, table_name, + table_name_length); - /* Get a TABLE_LIST object. */ - if (!(child_l= (TABLE_LIST*) alloc_root(&parent->mem_root, - sizeof(TABLE_LIST)))) + if (! db || ! table_name) + DBUG_RETURN(1); + + /* Convert to lowercase if required. */ + if (lower_case_table_names && table_name_length) + { + /* purecov: begin tested */ + table_name_length= my_casedn_str(files_charset_info, table_name); + /* purecov: end */ + } + + mrg_child_def= new (&ha_myrg->children_mem_root) + Mrg_child_def(db, dirlen, table_name, table_name_length); + + if (! mrg_child_def || + ha_myrg->child_def_list.push_back(mrg_child_def, + &ha_myrg->children_mem_root)) { - /* purecov: begin inspected */ - DBUG_PRINT("error", ("my_malloc error: %d", my_errno)); DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + + +/** + Open a MERGE parent table, but not its children. + + @param[in] name MERGE table path name + @param[in] mode read/write mode, unused + @param[in] test_if_locked_arg open flags + + @return status + @retval 0 OK + @retval -1 Error, my_errno gives reason + + @detail + This function initializes the MERGE storage engine structures + and adds a child list of TABLE_LIST to the parent handler. +*/ + +int ha_myisammrg::open(const char *name, int mode __attribute__((unused)), + uint test_if_locked_arg) +{ + DBUG_ENTER("ha_myisammrg::open"); + DBUG_PRINT("myrg", ("name: '%s' table: 0x%lx", name, (long) table)); + DBUG_PRINT("myrg", ("test_if_locked: %u", test_if_locked_arg)); + + /* Must not be used when table is open. */ + DBUG_ASSERT(!this->file); + + /* Save for later use. */ + test_if_locked= test_if_locked_arg; + + /* In case this handler was open and closed before, free old data. */ + free_root(&this->children_mem_root, MYF(MY_MARK_BLOCKS_FREE)); + + /* + Initialize variables that are used, modified, and/or set by + myisammrg_parent_open_callback(). + 'children_l' is the head of the children chain. + 'children_last_l' points to the end of the children chain. + 'my_errno' is set by myisammrg_parent_open_callback() in + case of an error. + */ + children_l= NULL; + children_last_l= NULL; + child_def_list.empty(); + my_errno= 0; + + /* retrieve children table list. */ + if (is_cloned) + { + /* + Open and attaches the MyISAM tables,that are under the MERGE table + parent, on the MyISAM storage engine interface directly within the + MERGE engine. The new MyISAM table instances, as well as the MERGE + clone itself, are not visible in the table cache. This is not a + problem because all locking is handled by the original MERGE table + from which this is cloned of. + */ + if (!(file= myrg_open(name, table->db_stat, HA_OPEN_IGNORE_IF_LOCKED))) + { + DBUG_PRINT("error", ("my_errno %d", my_errno)); + DBUG_RETURN(my_errno ? my_errno : -1); + } + + file->children_attached= TRUE; + + info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); + } + else if (!(file= myrg_parent_open(name, myisammrg_parent_open_callback, this))) + { + /* purecov: begin inspected */ + DBUG_PRINT("error", ("my_errno %d", my_errno)); + DBUG_RETURN(my_errno ? my_errno : -1); /* purecov: end */ } - bzero((char*) child_l, sizeof(TABLE_LIST)); + DBUG_PRINT("myrg", ("MYRG_INFO: 0x%lx child tables: %u", + (long) file, file->tables)); + DBUG_RETURN(0); +} - /* Set database (schema) name. */ - child_l->db_length= dirlen; - child_l->db= strmake_root(&parent->mem_root, db, dirlen); - /* Set table name. */ - child_l->table_name_length= strlen(table_name); - child_l->table_name= strmake_root(&parent->mem_root, table_name, - child_l->table_name_length); - /* Convert to lowercase if required. */ - if (lower_case_table_names && child_l->table_name_length) - child_l->table_name_length= my_casedn_str(files_charset_info, - child_l->table_name); - /* Set alias. */ - child_l->alias= child_l->table_name; - /* Initialize table map to 'undefined'. */ - child_l->init_child_def_version(); +/** + Add list of MERGE children to a TABLE_LIST chain. + + @return status + @retval 0 OK + @retval != 0 Error + + @detail + When a MERGE parent table has just been opened, insert the + TABLE_LIST chain from the MERGE handler into the table list used for + opening tables for this statement. This lets the children be opened + too. +*/ + +int ha_myisammrg::add_children_list(void) +{ + TABLE_LIST *parent_l= this->table->pos_in_table_list; + THD *thd= table->in_use; + List_iterator_fast<Mrg_child_def> it(child_def_list); + Mrg_child_def *mrg_child_def; + DBUG_ENTER("ha_myisammrg::add_children_list"); + DBUG_PRINT("myrg", ("table: '%s'.'%s' 0x%lx", this->table->s->db.str, + this->table->s->table_name.str, (long) this->table)); + + /* Must call this with open table. */ + DBUG_ASSERT(this->file); + + /* Ignore this for empty MERGE tables (UNION=()). */ + if (!this->file->tables) + { + DBUG_PRINT("myrg", ("empty merge table union")); + goto end; + } - /* Link TABLE_LIST object into the parent list. */ - if (!parent->child_last_l) + /* Must not call this with attached children. */ + DBUG_ASSERT(!this->file->children_attached); + + /* Must not call this with children list in place. */ + DBUG_ASSERT(this->children_l == NULL); + + /* + Prevent inclusion of another MERGE table, which could make infinite + recursion. + */ + if (parent_l->parent_l) { - /* Initialize parent->child_last_l when handling first child. */ - parent->child_last_l= &parent->child_l; + my_error(ER_ADMIN_WRONG_MRG_TABLE, MYF(0), parent_l->alias); + DBUG_RETURN(1); + } + + while ((mrg_child_def= it++)) + { + TABLE_LIST *child_l; + char *db; + char *table_name; + + child_l= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST)); + db= (char*) thd->memdup(mrg_child_def->db.str, mrg_child_def->db.length+1); + table_name= (char*) thd->memdup(mrg_child_def->name.str, + mrg_child_def->name.length+1); + + if (child_l == NULL || db == NULL || table_name == NULL) + DBUG_RETURN(1); + + child_l->init_one_table(db, mrg_child_def->db.length, + table_name, mrg_child_def->name.length, + table_name, parent_l->lock_type); + /* Set parent reference. Used to detect MERGE in children list. */ + child_l->parent_l= parent_l; + /* Copy select_lex. Used in unique_table() at least. */ + child_l->select_lex= parent_l->select_lex; + /* + Set the expected table version, to not cause spurious re-prepare. + @todo: revise after the fix for Bug#36171 + */ + child_l->set_table_ref_id(mrg_child_def->get_child_table_ref_type(), + mrg_child_def->get_child_def_version()); + /* Link TABLE_LIST object into the children list. */ + if (this->children_last_l) + child_l->prev_global= this->children_last_l; + else + { + /* Initialize children_last_l when handling first child. */ + this->children_last_l= &this->children_l; + } + *this->children_last_l= child_l; + this->children_last_l= &child_l->next_global; } - *parent->child_last_l= child_l; - child_l->prev_global= parent->child_last_l; - parent->child_last_l= &child_l->next_global; + /* Insert children into the table list. */ + if (parent_l->next_global) + parent_l->next_global->prev_global= this->children_last_l; + *this->children_last_l= parent_l->next_global; + parent_l->next_global= this->children_l; + this->children_l->prev_global= &parent_l->next_global; + /* + We have to update LEX::query_tables_last if children are added to + the tail of the table list in order to be able correctly add more + elements to it (e.g. as part of prelocking process). + */ + if (thd->lex->query_tables_last == &parent_l->next_global) + thd->lex->query_tables_last= this->children_last_l; + /* + The branch below works only when re-executing a prepared + statement or a stored routine statement: + We've just modified query_tables_last. Keep it in sync with + query_tables_last_own, if it was set by the prelocking code. + This ensures that the check that prohibits double updates (*) + can correctly identify what tables belong to the main statement. + (*) A double update is, e.g. when a user issues UPDATE t1 and + t1 has an AFTER UPDATE trigger that also modifies t1. + */ + if (thd->lex->query_tables_own_last == &parent_l->next_global) + thd->lex->query_tables_own_last= this->children_last_l; + +end: DBUG_RETURN(0); } /** - @brief Callback function for attaching a MERGE child table. + A context of myrg_attach_children() callback. +*/ - @detail This function retrieves the MyISAM table handle from the - next child table. It is called for each child table. +class Mrg_attach_children_callback_param +{ +public: + /** + 'need_compat_check' is set by myisammrg_attach_children_callback() + if a child fails the table def version check. + */ + bool need_compat_check; + /** TABLE_LIST identifying this merge parent. */ + TABLE_LIST *parent_l; + /** Iterator position, the current child to attach. */ + TABLE_LIST *next_child_attach; + List_iterator_fast<Mrg_child_def> def_it; + Mrg_child_def *mrg_child_def; +public: + Mrg_attach_children_callback_param(TABLE_LIST *parent_l_arg, + TABLE_LIST *first_child, + List<Mrg_child_def> &child_def_list) + :need_compat_check(FALSE), + parent_l(parent_l_arg), + next_child_attach(first_child), + def_it(child_def_list), + mrg_child_def(def_it++) + {} + void next() + { + next_child_attach= next_child_attach->next_global; + if (next_child_attach && next_child_attach->parent_l != parent_l) + next_child_attach= NULL; + if (mrg_child_def) + mrg_child_def= def_it++; + } +}; + + +/** + Callback function for attaching a MERGE child table. - @param[in] callback_param data pointer as given to - myrg_attach_children() + @param[in] callback_param data pointer as given to myrg_attach_children() + this is used to pass the handler handle @return pointer to open MyISAM table structure @retval !=NULL OK, returning pointer @retval NULL, my_errno == 0 Ok, no more child tables @retval NULL, my_errno != 0 error + + @detail + This function retrieves the MyISAM table handle from the + next child table. It is called for each child table. */ static MI_INFO *myisammrg_attach_children_callback(void *callback_param) { - ha_myisammrg *ha_myrg; - TABLE *parent; + Mrg_attach_children_callback_param *param= + (Mrg_attach_children_callback_param*) callback_param; + TABLE *parent= param->parent_l->table; TABLE *child; - TABLE_LIST *child_l; - MI_INFO *myisam; + TABLE_LIST *child_l= param->next_child_attach; + Mrg_child_def *mrg_child_def= param->mrg_child_def; + MI_INFO *myisam= NULL; DBUG_ENTER("myisammrg_attach_children_callback"); - my_errno= 0; - ha_myrg= (ha_myisammrg*) callback_param; - parent= ha_myrg->table_ptr(); - - /* Get child list item. */ - child_l= ha_myrg->next_child_attach; if (!child_l) { DBUG_PRINT("myrg", ("No more children to attach")); - DBUG_RETURN(NULL); + my_errno= 0; /* Ok, no more child tables. */ + goto end; } child= child_l->table; - DBUG_PRINT("myrg", ("child table: '%s'.'%s' 0x%lx", child->s->db.str, - child->s->table_name.str, (long) child)); - /* - Prepare for next child. Used as child_l in next call to this function. - We cannot rely on a NULL-terminated chain. - */ - if (&child_l->next_global == parent->child_last_l) - { - DBUG_PRINT("myrg", ("attaching last child")); - ha_myrg->next_child_attach= NULL; - } - else - ha_myrg->next_child_attach= child_l->next_global; - - /* Set parent reference. */ - child->parent= parent; + /* Prepare for next child. */ + param->next(); /* Do a quick compatibility check. The table def version is set when the table share is created. The child def version is copied - from the table def version after a sucessful compatibility check. + from the table def version after a successful compatibility check. We need to repeat the compatibility check only if a child is opened from a different share than last time it was used with this MERGE table. */ DBUG_PRINT("myrg", ("table_def_version last: %lu current: %lu", - (ulong) child_l->get_child_def_version(), + (ulong) mrg_child_def->get_child_def_version(), (ulong) child->s->get_table_def_version())); - if (child_l->get_child_def_version() != child->s->get_table_def_version()) - ha_myrg->need_compat_check= TRUE; + if (mrg_child_def->get_child_def_version() != child->s->get_table_def_version()) + param->need_compat_check= TRUE; /* If parent is temporary, children must be temporary too and vice @@ -368,7 +580,7 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param) DBUG_PRINT("error", ("temporary table mismatch parent: %d child: %d", parent->s->tmp_table, child->s->tmp_table)); my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; - goto err; + goto end; } /* Extract the MyISAM table structure pointer from the handler object. */ @@ -383,69 +595,12 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param) DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d", my_errno ? NULL : (long) myisam, my_errno)); - err: - DBUG_RETURN(my_errno ? NULL : myisam); + end: + DBUG_RETURN(myisam); } /** - @brief Open a MERGE parent table, not its children. - - @detail This function initializes the MERGE storage engine structures - and adds a child list of TABLE_LIST to the parent TABLE. - - @param[in] name MERGE table path name - @param[in] mode read/write mode, unused - @param[in] test_if_locked open flags - - @return status - @retval 0 OK - @retval -1 Error, my_errno gives reason -*/ - -int ha_myisammrg::open(const char *name, int mode __attribute__((unused)), - uint test_if_locked) -{ - DBUG_ENTER("ha_myisammrg::open"); - DBUG_PRINT("myrg", ("name: '%s' table: 0x%lx", name, (long) table)); - DBUG_PRINT("myrg", ("test_if_locked: %u", test_if_locked)); - - /* Save for later use. */ - this->test_if_locked= test_if_locked; - - /* retrieve children table list. */ - my_errno= 0; - if (is_cloned) - { - /* - Open and attaches the MyISAM tables,that are under the MERGE table - parent, on the MyISAM storage engine interface directly within the - MERGE engine. The new MyISAM table instances, as well as the MERGE - clone itself, are not visible in the table cache. This is not a - problem because all locking is handled by the original MERGE table - from which this is cloned of. - */ - if (!(file= myrg_open(table->s->normalized_path.str, table->db_stat, - HA_OPEN_IGNORE_IF_LOCKED))) - { - DBUG_PRINT("error", ("my_errno %d", my_errno)); - DBUG_RETURN(my_errno ? my_errno : -1); - } - - file->children_attached= TRUE; - - info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); - } - else if (!(file= myrg_parent_open(name, myisammrg_parent_open_callback, this))) - { - DBUG_PRINT("error", ("my_errno %d", my_errno)); - DBUG_RETURN(my_errno ? my_errno : -1); - } - DBUG_PRINT("myrg", ("MYRG_INFO: 0x%lx", (long) file)); - DBUG_RETURN(0); -} - -/** Returns a cloned instance of the current handler. @return A cloned handler instance. @@ -496,22 +651,24 @@ handler *ha_myisammrg::clone(MEM_ROOT *mem_root) /** - @brief Attach children to a MERGE table. + Attach children to a MERGE table. - @detail Let the storage engine attach its children through a callback + @return status + @retval 0 OK + @retval != 0 Error, my_errno gives reason + + @detail + Let the storage engine attach its children through a callback function. Check table definitions for consistency. - @note Special thd->open_options may be in effect. We can make use of + @note + Special thd->open_options may be in effect. We can make use of them in attach. I.e. we use HA_OPEN_FOR_REPAIR to report the names of mismatching child tables. We cannot transport these options in ha_myisammrg::test_if_locked because they may change after the parent is opened. The parent is kept open in the table cache over multiple statements and can be used by other threads. Open options can change over time. - - @return status - @retval 0 OK - @retval != 0 Error, my_errno gives reason */ int ha_myisammrg::attach_children(void) @@ -521,36 +678,47 @@ int ha_myisammrg::attach_children(void) MI_KEYDEF *keyinfo; uint recs; uint keys= table->s->keys; + TABLE_LIST *parent_l= table->pos_in_table_list; int error; + Mrg_attach_children_callback_param param(parent_l, this->children_l, child_def_list); DBUG_ENTER("ha_myisammrg::attach_children"); DBUG_PRINT("myrg", ("table: '%s'.'%s' 0x%lx", table->s->db.str, table->s->table_name.str, (long) table)); DBUG_PRINT("myrg", ("test_if_locked: %u", this->test_if_locked)); + + /* Must call this with open table. */ + DBUG_ASSERT(this->file); + + /* + A MERGE table with no children (empty union) is always seen as + attached internally. + */ + if (!this->file->tables) + { + DBUG_PRINT("myrg", ("empty merge table union")); + goto end; + } + DBUG_PRINT("myrg", ("child tables: %u", this->file->tables)); + + /* Must not call this with attached children. */ DBUG_ASSERT(!this->file->children_attached); + /* Must call this with children list in place. */ + DBUG_ASSERT(this->table->pos_in_table_list->next_global == this->children_l); + /* - Initialize variables that are used, modified, and/or set by - myisammrg_attach_children_callback(). - 'next_child_attach' traverses the chain of TABLE_LIST objects - that has been compiled during myrg_parent_open(). Every call - to myisammrg_attach_children_callback() moves the pointer to - the next object. - 'need_compat_check' is set by myisammrg_attach_children_callback() - if a child fails the table def version check. 'my_errno' is set by myisammrg_attach_children_callback() in case of an error. */ - next_child_attach= table->child_l; - need_compat_check= FALSE; my_errno= 0; if (myrg_attach_children(this->file, this->test_if_locked | current_thd->open_options, - myisammrg_attach_children_callback, this, - (my_bool *) &need_compat_check)) + myisammrg_attach_children_callback, ¶m, + (my_bool *) ¶m.need_compat_check)) { - DBUG_PRINT("error", ("my_errno %d", my_errno)); - DBUG_RETURN(my_errno ? my_errno : -1); + error= my_errno; + goto err; } DBUG_PRINT("myrg", ("calling myrg_extrafunc")); myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref); @@ -567,8 +735,8 @@ int ha_myisammrg::attach_children(void) always happen at the first attach because the reference child def version is initialized to 'undefined' at open. */ - DBUG_PRINT("myrg", ("need_compat_check: %d", need_compat_check)); - if (need_compat_check) + DBUG_PRINT("myrg", ("need_compat_check: %d", param.need_compat_check)); + if (param.need_compat_check) { TABLE_LIST *child_l; @@ -577,7 +745,11 @@ int ha_myisammrg::attach_children(void) DBUG_PRINT("error",("reclength: %lu mean_rec_length: %lu", table->s->reclength, stats.mean_rec_length)); if (test_if_locked & HA_OPEN_FOR_REPAIR) + { + /* purecov: begin inspected */ myrg_print_wrong_table(file->open_tables->table->filename); + /* purecov: end */ + } error= HA_ERR_WRONG_MRG_TABLE_DEF; goto err; } @@ -608,20 +780,25 @@ int ha_myisammrg::attach_children(void) my_free((uchar*) recinfo, MYF(0)); goto err; } + /* purecov: begin inspected */ myrg_print_wrong_table(u_table->table->filename); + /* purecov: end */ } } my_free((uchar*) recinfo, MYF(0)); if (error == HA_ERR_WRONG_MRG_TABLE_DEF) - goto err; + goto err; /* purecov: inspected */ - /* All checks passed so far. Now update child def version. */ - for (child_l= table->child_l; ; child_l= child_l->next_global) + List_iterator_fast<Mrg_child_def> def_it(child_def_list); + DBUG_ASSERT(this->children_l); + for (child_l= this->children_l; ; child_l= child_l->next_global) { - child_l->set_child_def_version( + Mrg_child_def *mrg_child_def= def_it++; + mrg_child_def->set_child_def_version( + child_l->table->s->get_table_ref_type(), child_l->table->s->get_table_def_version()); - if (&child_l->next_global == table->child_last_l) + if (&child_l->next_global == this->children_last_l) break; } } @@ -634,50 +811,141 @@ int ha_myisammrg::attach_children(void) goto err; } #endif + + end: DBUG_RETURN(0); err: - myrg_detach_children(file); + DBUG_PRINT("error", ("attaching MERGE children failed: %d", error)); + print_error(error, MYF(0)); + detach_children(); DBUG_RETURN(my_errno= error); } /** - @brief Detach all children from a MERGE table. - - @note Detach must not touch the children in any way. - They may have been closed at ths point already. - All references to the children should be removed. + Detach all children from a MERGE table and from the query list of tables. @return status @retval 0 OK @retval != 0 Error, my_errno gives reason + + @note + Detach must not touch the child TABLE objects in any way. + They may have been closed at ths point already. + All references to the children should be removed. */ int ha_myisammrg::detach_children(void) { + TABLE_LIST *child_l; DBUG_ENTER("ha_myisammrg::detach_children"); - DBUG_ASSERT(this->file && this->file->children_attached); + + /* Must call this with open table. */ + DBUG_ASSERT(this->file); + + /* A MERGE table with no children (empty union) cannot be detached. */ + if (!this->file->tables) + { + DBUG_PRINT("myrg", ("empty merge table union")); + goto end; + } + + if (this->children_l) + { + THD *thd= table->in_use; + + /* Clear TABLE references. */ + for (child_l= this->children_l; ; child_l= child_l->next_global) + { + /* + Do not DBUG_ASSERT(child_l->table); open_tables might be + incomplete. + + Clear the table reference. + */ + child_l->table= NULL; + /* Similarly, clear the ticket reference. */ + child_l->mdl_request.ticket= NULL; + + /* Break when this was the last child. */ + if (&child_l->next_global == this->children_last_l) + break; + } + /* + Remove children from the table list. This won't fail if called + twice. The list is terminated after removal. + + If the parent is LEX::query_tables_own_last and pre-locked tables + follow (tables used by stored functions or triggers), the children + are inserted behind the parent and before the pre-locked tables. But + we do not adjust LEX::query_tables_own_last. The pre-locked tables + could have chopped off the list by clearing + *LEX::query_tables_own_last. This did also chop off the children. If + we would copy the reference from *this->children_last_l in this + case, we would put the chopped off pre-locked tables back to the + list. So we refrain from copying it back, if the destination has + been set to NULL meanwhile. + */ + if (this->children_l->prev_global && *this->children_l->prev_global) + *this->children_l->prev_global= *this->children_last_l; + if (*this->children_last_l) + (*this->children_last_l)->prev_global= this->children_l->prev_global; + + /* + If table elements being removed are at the end of table list we + need to adjust LEX::query_tables_last member to point to the + new last element of the list. + */ + if (thd->lex->query_tables_last == this->children_last_l) + thd->lex->query_tables_last= this->children_l->prev_global; + + /* + If the statement requires prelocking, and prelocked + tables were added right after merge children, modify the + last own table pointer to point at prev_global of the merge + parent. + */ + if (thd->lex->query_tables_own_last == this->children_last_l) + thd->lex->query_tables_own_last= this->children_l->prev_global; + + /* Terminate child list. So it cannot be tried to remove again. */ + *this->children_last_l= NULL; + this->children_l->prev_global= NULL; + + /* Forget about the children, we don't own their memory. */ + this->children_l= NULL; + this->children_last_l= NULL; + } + + if (!this->file->children_attached) + { + DBUG_PRINT("myrg", ("merge children are already detached")); + goto end; + } if (myrg_detach_children(this->file)) { /* purecov: begin inspected */ - DBUG_PRINT("error", ("my_errno %d", my_errno)); + print_error(my_errno, MYF(0)); DBUG_RETURN(my_errno ? my_errno : -1); /* purecov: end */ } + + end: DBUG_RETURN(0); } /** - @brief Close a MERGE parent table, not its children. - - @note The children are expected to be closed separately by the caller. + Close a MERGE parent table, but not its children. @return status @retval 0 OK @retval != 0 Error, my_errno gives reason + + @note + The children are expected to be closed separately by the caller. */ int ha_myisammrg::close(void) @@ -685,11 +953,12 @@ int ha_myisammrg::close(void) int rc; DBUG_ENTER("ha_myisammrg::close"); /* - Children must not be attached here. Unless the MERGE table has no - children or the handler instance has been cloned. In these cases - children_attached is always true. + There are cases where children are not explicitly detached before + close. detach_children() protects itself against double detach. */ - DBUG_ASSERT(!this->file->children_attached || !this->file->tables || this->is_cloned); + if (!is_cloned) + detach_children(); + rc= myrg_close(file); file= 0; DBUG_RETURN(rc); @@ -967,13 +1236,23 @@ int ha_myisammrg::info(uint flag) int ha_myisammrg::extra(enum ha_extra_function operation) { - if (operation == HA_EXTRA_ATTACH_CHILDREN) + if (operation == HA_EXTRA_ADD_CHILDREN_LIST) + { + int rc= add_children_list(); + return(rc); + } + else if (operation == HA_EXTRA_ATTACH_CHILDREN) { int rc= attach_children(); if (!rc) (void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL return(rc); } + else if (operation == HA_EXTRA_IS_ATTACHED_CHILDREN) + { + /* For the upper layer pretend empty MERGE union is never attached. */ + return(file && file->tables && file->children_attached); + } else if (operation == HA_EXTRA_DETACH_CHILDREN) { /* @@ -994,6 +1273,7 @@ int ha_myisammrg::extra(enum ha_extra_function operation) int ha_myisammrg::reset(void) { + /* This is normally called with detached children. */ return myrg_reset(file); } @@ -1009,24 +1289,24 @@ int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size) int ha_myisammrg::external_lock(THD *thd, int lock_type) { - MYRG_TABLE *tmp; - DBUG_ASSERT(this->file->children_attached); - for (tmp= file->open_tables; tmp != file->end_table; tmp++) - tmp->table->in_use.data= thd; - return myrg_lock_database(file,lock_type); + /* + This can be called with no children attached. E.g. FLUSH TABLES + unlocks and re-locks tables under LOCK TABLES, but it does not open + them first. So they are detached all the time. But locking of the + children should work anyway because thd->open_tables is not changed + during FLUSH TABLES. + + If this handler instance has been cloned, we still must call + myrg_lock_database(). + */ + if (is_cloned) + return myrg_lock_database(file, lock_type); + return 0; } uint ha_myisammrg::lock_count(void) const { - /* - Return the real lock count even if the children are not attached. - This method is used for allocating memory. If we would return 0 - to another thread (e.g. doing FLUSH TABLE), and attach the children - before the other thread calls store_lock(), then we would return - more locks in store_lock() than we claimed by lock_count(). The - other tread would overrun its memory. - */ - return file->tables; + return 0; } @@ -1034,37 +1314,6 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type) { - MYRG_TABLE *open_table; - - /* - This method can be called while another thread is attaching the - children. If the processor reorders instructions or write to memory, - 'children_attached' could be set before 'open_tables' has all the - pointers to the children. Use of a mutex here and in - myrg_attach_children() forces consistent data. - */ - mysql_mutex_lock(&this->file->mutex); - - /* - When MERGE table is open, but not yet attached, other threads - could flush it, which means call 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. - */ - if (!this->file->children_attached) - goto end; /* purecov: tested */ - - for (open_table=file->open_tables ; - open_table != file->end_table ; - open_table++) - { - *(to++)= &open_table->table->lock; - if (lock_type != TL_IGNORE && open_table->table->lock.type == TL_UNLOCK) - open_table->table->lock.type=lock_type; - } - - end: - mysql_mutex_unlock(&this->file->mutex); return to; } @@ -1153,7 +1402,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form, /* Allocate a table_names array in thread mem_root. */ if (!(table_names= (const char**) thd->alloc((create_info->merge_list.elements+1) * sizeof(char*)))) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */ /* Create child path names. */ for (pos= table_names; tables; tables= tables->next_local) @@ -1263,7 +1512,7 @@ bool ha_myisammrg::check_if_incompatible_data(HA_CREATE_INFO *info, int ha_myisammrg::check(THD* thd, HA_CHECK_OPT* check_opt) { - return HA_ADMIN_OK; + return this->file->children_attached ? HA_ADMIN_OK : HA_ADMIN_CORRUPT; } diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h index 790aa15e90a..4ff24c69071 100644 --- a/storage/myisammrg/ha_myisammrg.h +++ b/storage/myisammrg/ha_myisammrg.h @@ -22,15 +22,62 @@ #include <myisammrg.h> +/** + Represents one name of a MERGE child. + + @todo: Add MYRG_SHARE and store chlidren names in the + share. +*/ + +class Mrg_child_def: public Sql_alloc +{ + /* Remembered MERGE child def version. See top comment in ha_myisammrg.cc */ + enum_table_ref_type m_child_table_ref_type; + ulong m_child_def_version; +public: + LEX_STRING db; + LEX_STRING name; + + /* Access MERGE child def version. See top comment in ha_myisammrg.cc */ + inline enum_table_ref_type get_child_table_ref_type() + { + return m_child_table_ref_type; + } + inline ulong get_child_def_version() + { + return m_child_def_version; + } + inline void set_child_def_version(enum_table_ref_type child_table_ref_type, + ulong version) + { + m_child_table_ref_type= child_table_ref_type; + m_child_def_version= version; + } + + Mrg_child_def(char *db_arg, size_t db_len_arg, + char *table_name_arg, size_t table_name_len_arg) + { + db.str= db_arg; + db.length= db_len_arg; + name.str= table_name_arg; + name.length= table_name_len_arg; + m_child_def_version= ~0UL; + m_child_table_ref_type= TABLE_REF_NULL; + } +}; + + class ha_myisammrg: public handler { MYRG_INFO *file; my_bool is_cloned; /* This instance has been cloned */ - public: - TABLE_LIST *next_child_attach; /* next child to attach */ +public: + MEM_ROOT children_mem_root; /* mem root for children list */ + List<Mrg_child_def> child_def_list; + TABLE_LIST *children_l; /* children list */ + TABLE_LIST **children_last_l; /* children list end */ uint test_if_locked; /* flags from ::open() */ - bool need_compat_check; /* if need compatibility check */ ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg); ~ha_myisammrg(); @@ -60,6 +107,7 @@ class ha_myisammrg: public handler { return ulonglong2double(stats.data_file_length) / IO_SIZE + file->tables; } int open(const char *name, int mode, uint test_if_locked); + int add_children_list(void); int attach_children(void); int detach_children(void); virtual handler *clone(MEM_ROOT *mem_root); diff --git a/storage/myisammrg/myrg_extra.c b/storage/myisammrg/myrg_extra.c index 3d14f6a56e6..0b9c138a188 100644 --- a/storage/myisammrg/myrg_extra.c +++ b/storage/myisammrg/myrg_extra.c @@ -75,12 +75,17 @@ int myrg_reset(MYRG_INFO *info) MYRG_TABLE *file; DBUG_ENTER("myrg_reset"); - if (!info->children_attached) - DBUG_RETURN(1); info->cache_in_use=0; info->current_table=0; info->last_used_table= info->open_tables; - + + /* + This is normally called with detached children. + Return OK as this is the normal case. + */ + if (!info->children_attached) + DBUG_RETURN(0); + for (file=info->open_tables ; file != info->end_table ; file++) { int error; diff --git a/storage/mysql_storage_engine.cmake b/storage/mysql_storage_engine.cmake deleted file mode 100644 index b920f16452b..00000000000 --- a/storage/mysql_storage_engine.cmake +++ /dev/null @@ -1,44 +0,0 @@ -# MYSQL_STORAGE_ENGINE Macro creates a project to build storage engine -# library. -# -# Parameters: -# engine - storage engine name. -# variable ENGINE_BUILD_TYPE should be set to "STATIC" or "DYNAMIC" -# Remarks: -# ${engine}_SOURCES variable containing source files to produce the library must set before -# calling this macro -# ${engine}_LIBS variable containing extra libraries to link with may be set - - -MACRO(MYSQL_STORAGE_ENGINE engine) -IF(NOT SOURCE_SUBLIBS) - # Add common include directories - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib - ${CMAKE_SOURCE_DIR}/sql - ${CMAKE_SOURCE_DIR}/regex - ${CMAKE_SOURCE_DIR}/extra/yassl/include) - STRING(TOUPPER ${engine} engine) - STRING(TOLOWER ${engine} libname) - IF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC") - ADD_DEFINITIONS(-DWITH_${engine}_STORAGE_ENGINE -DMYSQL_SERVER) - #Create static library. The name of the library is <storage_engine>.lib - ADD_LIBRARY(${libname} ${${engine}_SOURCES}) - ADD_DEPENDENCIES(${libname} GenError) - IF(${engine}_LIBS) - TARGET_LINK_LIBRARIES(${libname} ${${engine}_LIBS}) - ENDIF(${engine}_LIBS) - MESSAGE("build ${engine} as static library") - ELSEIF(${ENGINE_BUILD_TYPE} STREQUAL "DYNAMIC") - ADD_DEFINITIONS(-DMYSQL_DYNAMIC_PLUGIN) - #Create a DLL.The name of the dll is ha_<storage_engine>.dll - #The dll is linked to the mysqld executable - SET(dyn_libname ha_${libname}) - ADD_LIBRARY(${dyn_libname} SHARED ${${engine}_SOURCES}) - TARGET_LINK_LIBRARIES (${dyn_libname} mysqlservices mysqld) - IF(${engine}_LIBS) - TARGET_LINK_LIBRARIES(${dyn_libname} ${${engine}_LIBS}) - ENDIF(${engine}_LIBS) - MESSAGE("build ${engine} as DLL") - ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC") -ENDIF(NOT SOURCE_SUBLIBS) -ENDMACRO(MYSQL_STORAGE_ENGINE) diff --git a/storage/perfschema/CMakeLists.txt b/storage/perfschema/CMakeLists.txt index dbfab3b6749..6c7731f2d07 100644 --- a/storage/perfschema/CMakeLists.txt +++ b/storage/perfschema/CMakeLists.txt @@ -13,8 +13,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake") -INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include @@ -76,4 +74,8 @@ SET(PERFSCHEMA_SOURCES ha_perfschema.h pfs_check.cc ) -MYSQL_STORAGE_ENGINE(PERFSCHEMA) +MYSQL_ADD_PLUGIN(perfschema ${PERFSCHEMA_SOURCES} STORAGE_ENGINE DEFAULT STATIC_ONLY) +IF(WITH_PERFSCHEMA_STORAGE_ENGINE AND WITH_UNIT_TESTS) + ENABLE_TESTING() + ADD_SUBDIRECTORY(unittest) +ENDIF() diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index 01b4b3711c1..380801c8677 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -1081,6 +1081,13 @@ static void delete_current_thread_v1(void) } } +static void delete_thread_v1(PSI_thread *thread) +{ + PFS_thread *pfs= reinterpret_cast<PFS_thread*> (thread); + if (pfs != NULL) + destroy_thread(pfs); +} + static PSI_mutex_locker* get_thread_mutex_locker_v1(PSI_mutex *mutex, PSI_mutex_operation op) { @@ -2007,6 +2014,7 @@ PSI_v1 PFS_v1= get_thread_v1, set_thread_v1, delete_current_thread_v1, + delete_thread_v1, get_thread_mutex_locker_v1, get_thread_rwlock_locker_v1, get_thread_cond_locker_v1, diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index 4190094b52b..c824b93093e 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -118,6 +118,8 @@ void PFS_engine_table_share::check_one_table(THD *thd) TABLE_LIST tables; tables.init_one_table(PERFORMANCE_SCHEMA_str.str, + PERFORMANCE_SCHEMA_str.length, + m_name.str, m_name.length, m_name.str, TL_READ); /* Work around until Bug#32115 is backported. */ @@ -219,7 +221,7 @@ int PFS_engine_table::read_row(TABLE *table, if (! m_share_ptr->m_checked) { my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0), - PERFORMANCE_SCHEMA_str.str, m_share_ptr->m_name); + PERFORMANCE_SCHEMA_str.str, m_share_ptr->m_name.str); return HA_ERR_TABLE_NEEDS_UPGRADE; } @@ -256,7 +258,7 @@ int PFS_engine_table::update_row(TABLE *table, if (! m_share_ptr->m_checked) { my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0), - PERFORMANCE_SCHEMA_str.str, m_share_ptr->m_name); + PERFORMANCE_SCHEMA_str.str, m_share_ptr->m_name.str); return HA_ERR_TABLE_NEEDS_UPGRADE; } diff --git a/storage/perfschema/unittest/CMakeLists.txt b/storage/perfschema/unittest/CMakeLists.txt index 01f3fbb8c98..8a72b25b5b7 100644 --- a/storage/perfschema/unittest/CMakeLists.txt +++ b/storage/perfschema/unittest/CMakeLists.txt @@ -23,17 +23,19 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ADD_DEFINITIONS(-DMYSQL_SERVER) -LINK_LIBRARIES(perfschema mytap mysys dbug strings) - -ADD_EXECUTABLE(pfs_instr_class-t pfs_instr_class-t.cc) - -ADD_EXECUTABLE(pfs_instr_class-oom-t pfs_instr_class-oom-t.cc) - -ADD_EXECUTABLE(pfs_instr-t pfs_instr-t.cc) - -ADD_EXECUTABLE(pfs_instr-oom-t pfs_instr-oom-t.cc) - -ADD_EXECUTABLE(pfs_timer-t pfs_timer-t.cc) - -ADD_EXECUTABLE(pfs-t pfs-t.cc) - +MACRO (PFS_ADD_TEST name) + ADD_EXECUTABLE(${name}-t ${name}-t.cc) + TARGET_LINK_LIBRARIES(${name}-t mytap perfschema mysys) + ADD_TEST(${name} ${name}-t) +ENDMACRO() + +SET(tests + pfs_instr_class + pfs_instr_class-oom + pfs_instr + pfs_instr-oom + pfs +) +FOREACH(testname ${tests}) + PFS_ADD_TEST(${testname}) +ENDFOREACH() |