diff options
345 files changed, 7748 insertions, 2130 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a4b8d18651..bc6608fdc47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,6 +153,7 @@ IF (NOT CPACK_GENERATOR) ENDIF(WIN32) ENDIF(NOT CPACK_GENERATOR) +INCLUDE(FeatureSummary) INCLUDE(misc) INCLUDE(mysql_version) INCLUDE(cpack_source_ignore_files) @@ -450,12 +451,15 @@ ADD_SUBDIRECTORY(tpool) IF(NOT WITHOUT_SERVER) ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(sql) - OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF) - IF(WITH_EMBEDDED_SERVER) - ADD_SUBDIRECTORY(libmysqld) - ADD_SUBDIRECTORY(libmysqld/examples) - ADD_SUBDIRECTORY(unittest/embedded) + OPTION (WITH_EMBEDDED_SERVER "Compile MariaDB with embedded server" OFF) + IF(WITH_EMBEDDED_SERVER) + ADD_SUBDIRECTORY(libmysqld) + ADD_SUBDIRECTORY(libmysqld/examples) + ADD_SUBDIRECTORY(unittest/embedded) ENDIF(WITH_EMBEDDED_SERVER) + IF(NOT WIN32) + ADD_FEATURE_INFO(EMBEDDED_SERVER WITH_EMBEDDED_SERVER "Embedded MariaDB Server Library") + ENDIF() ADD_SUBDIRECTORY(mysql-test) ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess) @@ -549,6 +553,13 @@ IF(WIN32 AND SIGNCODE) INSTALL(SCRIPT ${PROJECT_BINARY_DIR}/sign.cmake) ENDIF() +FEATURE_SUMMARY(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES VAR MARIADB_FEATURE_SUMMARY) + +OPTION(FEATURE_SUMMARY "Print feature summary at the end of configure step" ON) +IF (FEATURE_SUMMARY) + MESSAGE_ONCE(SUMMARY "${MARIADB_FEATURE_SUMMARY}") +ENDIF() + IF(NON_DISTRIBUTABLE_WARNING) MESSAGE(WARNING " You have linked MariaDB with ${NON_DISTRIBUTABLE_WARNING} libraries! You may not distribute the resulting binary. If you do, you will put yourself into a legal problem with the Free Software Foundation.") diff --git a/cmake/aws_sdk.cmake b/cmake/aws_sdk.cmake index 7abd9974c1e..f6f88f2b880 100644 --- a/cmake/aws_sdk.cmake +++ b/cmake/aws_sdk.cmake @@ -45,6 +45,7 @@ FUNCTION (CHECK_AWS_SDK RETVAL REASON) IF(UNIX) # Check librairies required for building SDK FIND_PACKAGE(CURL) + SET_PACKAGE_PROPERTIES(CURL PROPERTIES TYPE REQUIRED) IF(NOT CURL_FOUND) SKIP_AWS_SDK("AWS C++ SDK requires libcurl development package") ENDIF() @@ -54,10 +55,12 @@ FUNCTION (CHECK_AWS_SDK RETVAL REASON) ENDIF() IF(NOT APPLE) FIND_LIBRARY(UUID_LIBRARIES uuid) + SET_PACKAGE_PROPERTIES(UUID_LIBRARIES PROPERTIES TYPE REQUIRED) IF(NOT UUID_LIBRARIES) SKIP_AWS_SDK("AWS C++ SDK requires uuid development package") ENDIF() FIND_PACKAGE(OpenSSL) + SET_PACKAGE_PROPERTIES(OpenSSL PROPERTIES TYPE REQUIRED) IF(NOT OPENSSL_FOUND) SKIP_AWS_SDK("AWS C++ SDK requires openssl development package") ENDIF() diff --git a/cmake/for_clients.cmake b/cmake/for_clients.cmake index 68066ccacc9..39c37da45e5 100644 --- a/cmake/for_clients.cmake +++ b/cmake/for_clients.cmake @@ -21,7 +21,7 @@ MACRO(EXTRACT_LINK_LIBRARIES target var) FOREACH(lib ${${target}_LIB_DEPENDS}) # Filter out "general", it is not a library, just CMake hint # Also, remove duplicates - IF(NOT lib STREQUAL "general" AND NOT ${var} MATCHES "-l${lib} ") + IF(NOT lib STREQUAL "general" AND NOT ${var} MATCHES "-l${lib} " AND NOT lib STREQUAL "zlib") IF (lib MATCHES "^\\-") SET(${var} "${${var}} ${lib} ") ELSEIF(lib MATCHES "^/") diff --git a/cmake/jemalloc.cmake b/cmake/jemalloc.cmake index b94a880cf05..55369157689 100644 --- a/cmake/jemalloc.cmake +++ b/cmake/jemalloc.cmake @@ -37,5 +37,6 @@ MACRO (CHECK_JEMALLOC) IF (NOT LIBJEMALLOC AND NOT WITH_JEMALLOC STREQUAL "auto") MESSAGE(FATAL_ERROR "jemalloc is not found") ENDIF() + ADD_FEATURE_INFO(JEMALLOC LIBJEMALLOC "Use the JeMalloc memory allocator") ENDIF() ENDMACRO() diff --git a/cmake/numa.cmake b/cmake/numa.cmake index d24318634c3..0ccb560d378 100644 --- a/cmake/numa.cmake +++ b/cmake/numa.cmake @@ -33,6 +33,7 @@ MACRO (MYSQL_CHECK_NUMA) ENDIF() ENDIF() + ADD_FEATURE_INFO(NUMA HAVE_LIBNUMA "NUMA memory allocation policy") IF(WITH_NUMA_LOWERCASE STREQUAL "auto" AND HAVE_LIBNUMA) MESSAGE_ONCE(numa "WITH_NUMA=AUTO: NUMA memory allocation policy enabled") ELSEIF(WITH_NUMA_LOWERCASE STREQUAL "auto" AND NOT HAVE_LIBNUMA) diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index 2e98afe9ec8..6bc1de3e52a 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -53,7 +53,7 @@ MACRO(MYSQL_ADD_PLUGIN) LIST(REMOVE_AT SOURCES 0) STRING(TOUPPER ${plugin} plugin) STRING(TOLOWER ${plugin} target) - + IF (ARG_MANDATORY) UNSET(PLUGIN_${plugin} CACHE) SET(PLUGIN_${plugin} "YES") @@ -114,7 +114,7 @@ MACRO(MYSQL_ADD_PLUGIN) SET(with_var "WITH_${plugin}") ENDIF() UNSET(${with_var} CACHE) - + IF(NOT ARG_DEPENDENCIES) SET(ARG_DEPENDENCIES) ENDIF() @@ -285,6 +285,16 @@ MACRO(MYSQL_ADD_PLUGIN) INSTALL_MYSQL_TEST("${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/" "plugin/${subpath}") ENDIF() + GET_TARGET_PROPERTY(plugin_type ${target} TYPE) + STRING(REGEX REPLACE "_LIBRARY$" "" plugin_type ${plugin_type}) + STRING(REGEX REPLACE "^NO$" "" plugin_type ${plugin_type}) + IF(ARG_STORAGE_ENGINE) + ADD_FEATURE_INFO(${plugin} PLUGIN_${plugin} "Storage Engine ${plugin_type}") + ELSEIF(ARG_CLIENT) + ADD_FEATURE_INFO(${plugin} PLUGIN_${plugin} "Client plugin ${plugin_type}") + ELSE() + ADD_FEATURE_INFO(${plugin} PLUGIN_${plugin} "Server plugin ${plugin_type}") + ENDIF() ENDIF(NOT WITHOUT_SERVER OR ARG_CLIENT) ENDMACRO() diff --git a/cmake/readline.cmake b/cmake/readline.cmake index 69a51d8a156..c8bbc7fc259 100644 --- a/cmake/readline.cmake +++ b/cmake/readline.cmake @@ -52,7 +52,7 @@ MACRO (MYSQL_CHECK_MULTIBYTE) ENDMACRO() MACRO (FIND_CURSES) - FIND_PACKAGE(Curses) + FIND_PACKAGE(Curses REQUIRED) MARK_AS_ADVANCED(CURSES_CURSES_H_PATH CURSES_FORM_LIBRARY CURSES_HAVE_CURSES_H) IF(NOT CURSES_FOUND) SET(ERRORMSG "Curses library not found. Please install appropriate package, diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index 5f54d77752c..7c2488be8bd 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -117,6 +117,7 @@ MACRO (MYSQL_CHECK_SSL) ENDIF() ENDIF() FIND_PACKAGE(OpenSSL) + SET_PACKAGE_PROPERTIES(OpenSSL PROPERTIES TYPE RECOMMENDED) IF(OPENSSL_FOUND) SET(OPENSSL_LIBRARY ${OPENSSL_SSL_LIBRARY}) INCLUDE(CheckSymbolExists) diff --git a/cmake/systemd.cmake b/cmake/systemd.cmake index e353004e7d2..978be0b9f98 100644 --- a/cmake/systemd.cmake +++ b/cmake/systemd.cmake @@ -65,5 +65,6 @@ MACRO(CHECK_SYSTEMD) ELSEIF(NOT WITH_SYSTEMD STREQUAL "no") MESSAGE(FATAL_ERROR "Invalid value for WITH_SYSTEMD. Must be 'yes', 'no', or 'auto'.") ENDIF() + ADD_FEATURE_INFO(SYSTEMD LIBSYSTEMD "Systemd scripts and notification support") ENDIF() ENDMACRO() diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake index a6d843e5591..368ae61d1d3 100644 --- a/cmake/wsrep.cmake +++ b/cmake/wsrep.cmake @@ -64,4 +64,7 @@ Then restart the build. ADD_SUBDIRECTORY(wsrep-lib) SET(BUILD_SHARED_LIBS ${old_BUILD_SHARED_LIBS}) ENDIF() +IF (NOT WIN32) + ADD_FEATURE_INFO(WSREP WITH_WSREP "WSREP replication API (to use, e.g. Galera Replication library)") +ENDIF() ENDIF(NOT WITHOUT_SERVER) diff --git a/configure.cmake b/configure.cmake index 8383b6921f8..a78b83bd33c 100644 --- a/configure.cmake +++ b/configure.cmake @@ -170,6 +170,7 @@ IF(UNIX) SET(LIBWRAP "wrap") ENDIF() ENDIF() + ADD_FEATURE_INFO(LIBWRAP HAVE_LIBWRAP "Support for tcp wrappers") ENDIF() # diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc index 0d931129afa..5f66278b0db 100644 --- a/extra/innochecksum.cc +++ b/extra/innochecksum.cc @@ -60,9 +60,9 @@ The parts not included are excluded by #ifndef UNIV_INNOCHECKSUM. */ /* Global variables */ static bool verbose; static bool just_count; -static unsigned long long start_page; -static unsigned long long end_page; -static unsigned long long do_page; +static uint32_t start_page; +static uint32_t end_page; +static uint32_t do_page; static bool use_end_page; static bool do_one_page; static my_bool do_leaf; @@ -73,9 +73,9 @@ static ulint physical_page_size; /* Page size in bytes on disk. */ ulong srv_page_size; ulong srv_page_size_shift; /* Current page number (0 based). */ -unsigned long long cur_page_num; +uint32_t cur_page_num; /* Current space. */ -unsigned long long cur_space; +uint32_t cur_space; /* Skip the checksum verification. */ static bool no_check; /* Enabled for strict checksum verification. */ @@ -465,11 +465,11 @@ is_page_corrupted( /* enable if page is corrupted. */ bool is_corrupted; /* use to store LSN values. */ - ulint logseq; - ulint logseqfield; - const uint16_t page_type = fil_page_get_type(buf); - uint key_version = buf_page_get_key_version(buf, flags); - ulint space_id = mach_read_from_4( + uint32_t logseq; + uint32_t logseqfield; + const uint16_t page_type = mach_read_from_2(buf+FIL_PAGE_TYPE); + uint32_t key_version = buf_page_get_key_version(buf, flags); + uint32_t space_id = mach_read_from_4( buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); ulint zip_size = fil_space_t::zip_size(flags); ulint is_compressed = fil_space_t::is_compressed(flags); @@ -487,8 +487,8 @@ is_page_corrupted( if (is_log_enabled) { fprintf(log_file, - "page id mismatch space::" ULINTPF - " page::%llu \n", + "page id mismatch space::" UINT32PF + " page::" UINT32PF " \n", space_id, cur_page_num); } @@ -517,13 +517,14 @@ is_page_corrupted( if (is_log_enabled) { fprintf(log_file, - "space::" ULINTPF " page::%llu" - "; log sequence number:first = " ULINTPF - "; second = " ULINTPF "\n", + "space::" UINT32PF " page::" UINT32PF + "; log sequence number:first = " UINT32PF + "; second = " UINT32PF "\n", space_id, cur_page_num, logseq, logseqfield); if (logseq != logseqfield) { fprintf(log_file, - "Fail; space::" ULINTPF " page::%llu" + "Fail; space::" UINT32PF + " page::" UINT32PF " invalid (fails log " "sequence number check)\n", space_id, cur_page_num); @@ -547,9 +548,9 @@ is_page_corrupted( if (is_corrupted && log_file) { fprintf(log_file, - "[page id: space=" ULINTPF - ", page_number=%llu] may be corrupted;" - " key_version=%u\n", + "[page id: space=" UINT32PF + ", page_number=" UINT32PF "] may be corrupted;" + " key_version=" UINT32PF "\n", space_id, cur_page_num, key_version); } } else { @@ -653,8 +654,8 @@ static bool update_checksum(byte* page, ulint flags) mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum); if (is_log_enabled) { - fprintf(log_file, "page::%llu; Updated checksum =" - " %u\n", cur_page_num, checksum); + fprintf(log_file, "page::" UINT32PF "; Updated checksum =" + " " UINT32PF "\n", cur_page_num, checksum); } } else if (use_full_crc32) { @@ -665,7 +666,7 @@ static bool update_checksum(byte* page, ulint flags) if (mach_read_from_4(c) == checksum) return false; mach_write_to_4(c, checksum); if (is_log_enabled) { - fprintf(log_file, "page::%llu; Updated checksum" + fprintf(log_file, "page::" UINT32PF "; Updated checksum" " = %u\n", cur_page_num, checksum); } return true; @@ -699,8 +700,8 @@ static bool update_checksum(byte* page, ulint flags) mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum); if (is_log_enabled) { - fprintf(log_file, "page::%llu; Updated checksum field1" - " = %u\n", cur_page_num, checksum); + fprintf(log_file, "page::" UINT32PF "; Updated checksum field1" + " = " UINT32PF "\n", cur_page_num, checksum); } if (write_check == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB @@ -713,8 +714,8 @@ static bool update_checksum(byte* page, ulint flags) FIL_PAGE_END_LSN_OLD_CHKSUM,checksum); if (is_log_enabled) { - fprintf(log_file, "page::%llu; Updated checksum " - "field2 = %u\n", cur_page_num, checksum); + fprintf(log_file, "page::" UINT32PF "; Updated checksum " + "field2 = " UINT32PF "\n", cur_page_num, checksum); } } @@ -786,7 +787,8 @@ write_file( if (physical_page_size != fwrite(buf, 1, physical_page_size, file == stdin ? stdout : file)) { - fprintf(stderr, "Failed to write page::%llu to %s: %s\n", + fprintf(stderr, + "Failed to write page::" UINT32PF " to %s: %s\n", cur_page_num, filename, strerror(errno)); return(false); @@ -803,6 +805,16 @@ write_file( return(true); } +// checks using current xdes page whether the page is free +static inline bool is_page_free(const byte *xdes, ulint physical_page_size, + uint32_t page_no) +{ + const byte *des= + xdes + XDES_ARR_OFFSET + + XDES_SIZE * ((page_no & (physical_page_size - 1)) / FSP_EXTENT_SIZE); + return xdes_is_free(des, page_no % FSP_EXTENT_SIZE); +} + /* Parse the page and collect/dump the information about page type @param [in] page buffer page @@ -818,12 +830,10 @@ parse_page( bool is_encrypted) { unsigned long long id; - ulint undo_page_type; + uint16_t undo_page_type; char str[20]={'\0'}; ulint n_recs; - ulint page_no; - ulint left_page_no; - ulint right_page_no; + uint32_t page_no, left_page_no, right_page_no; ulint data_bytes; bool is_leaf; ulint size_range_id; @@ -838,7 +848,7 @@ parse_page( switch (fil_page_get_type(page)) { case FIL_PAGE_INDEX: { - uint key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + uint32_t key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); page_type.n_fil_page_index++; /* If page is encrypted we can't read index header */ @@ -862,7 +872,7 @@ parse_page( is_leaf = (!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL))); if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tIndex page\t\t\t|" + fprintf(file, "#::" UINT32PF "\t\t|\t\tIndex page\t\t\t|" "\tindex id=%llu,", cur_page_num, id); fprintf(file, @@ -880,22 +890,13 @@ parse_page( size_range_id = SIZE_RANGES_FOR_PAGE + 1; } if (per_page_details) { - printf("index id=%llu page " ULINTPF " leaf %d n_recs " ULINTPF " data_bytes " ULINTPF + printf("index id=%llu page " UINT32PF " leaf %d n_recs " ULINTPF " data_bytes " ULINTPF "\n", id, page_no, is_leaf, n_recs, data_bytes); } /* update per-index statistics */ { - if (index_ids.count(id) == 0) { - index_ids[id] = per_index_stats(); - } - std::map<unsigned long long, per_index_stats>::iterator it; - it = index_ids.find(id); - per_index_stats &index = (it->second); - const byte* des = xdes + XDES_ARR_OFFSET - + XDES_SIZE * ((page_no & (physical_page_size - 1)) - / FSP_EXTENT_SIZE); - if (xdes_is_free(des, - page_no % FSP_EXTENT_SIZE)) { + per_index_stats &index = index_ids[id]; + if (is_page_free(xdes, physical_page_size, page_no)) { index.free_pages++; return; } @@ -923,8 +924,8 @@ parse_page( index.pages_in_size_range[size_range_id] ++; } } else { - fprintf(file, "#::%llu\t\t|\t\tEncrypted Index page\t\t\t|" - "\tkey_version %u,%s\n", cur_page_num, key_version, str); + fprintf(file, "#::" UINT32PF "\t\t|\t\tEncrypted Index page\t\t\t|" + "\tkey_version " UINT32PF ",%s\n", cur_page_num, key_version, str); } break; @@ -934,7 +935,7 @@ parse_page( undo_page_type = mach_read_from_2(page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE); if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tUndo log page\t\t\t|", + fprintf(file, "#::" UINT32PF "\t\t|\t\tUndo log page\t\t\t|", cur_page_num); } page_type.n_undo++; @@ -986,7 +987,7 @@ parse_page( case FIL_PAGE_INODE: page_type.n_fil_page_inode++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tInode page\t\t\t|" + fprintf(file, "#::" UINT32PF "\t\t|\t\tInode page\t\t\t|" "\t%s\n",cur_page_num, str); } break; @@ -994,7 +995,7 @@ parse_page( case FIL_PAGE_IBUF_FREE_LIST: page_type.n_fil_page_ibuf_free_list++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tInsert buffer free list" + fprintf(file, "#::" UINT32PF "\t\t|\t\tInsert buffer free list" " page\t|\t%s\n", cur_page_num, str); } break; @@ -1002,7 +1003,7 @@ parse_page( case FIL_PAGE_TYPE_ALLOCATED: page_type.n_fil_page_type_allocated++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tFreshly allocated " + fprintf(file, "#::" UINT32PF "\t\t|\t\tFreshly allocated " "page\t\t|\t%s\n", cur_page_num, str); } break; @@ -1010,7 +1011,7 @@ parse_page( case FIL_PAGE_IBUF_BITMAP: page_type.n_fil_page_ibuf_bitmap++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tInsert Buffer " + fprintf(file, "#::" UINT32PF "\t\t|\t\tInsert Buffer " "Bitmap\t\t|\t%s\n", cur_page_num, str); } break; @@ -1018,33 +1019,31 @@ parse_page( case FIL_PAGE_TYPE_SYS: page_type.n_fil_page_type_sys++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tSystem page\t\t\t|" - "\t%s\n",cur_page_num, str); + fprintf(file, "#::" UINT32PF "\t\t|\t\tSystem page\t\t\t|" + "\t%s\n", cur_page_num, str); } break; case FIL_PAGE_TYPE_TRX_SYS: page_type.n_fil_page_type_trx_sys++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tTransaction system " + fprintf(file, "#::" UINT32PF "\t\t|\t\tTransaction system " "page\t\t|\t%s\n", cur_page_num, str); } break; case FIL_PAGE_TYPE_FSP_HDR: page_type.n_fil_page_type_fsp_hdr++; - memcpy(xdes, page, physical_page_size); if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tFile Space " + fprintf(file, "#::" UINT32PF "\t\t|\t\tFile Space " "Header\t\t|\t%s\n", cur_page_num, str); } break; case FIL_PAGE_TYPE_XDES: page_type.n_fil_page_type_xdes++; - memcpy(xdes, page, physical_page_size); if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tExtent descriptor " + fprintf(file, "#::" UINT32PF "\t\t|\t\tExtent descriptor " "page\t\t|\t%s\n", cur_page_num, str); } break; @@ -1052,7 +1051,7 @@ parse_page( case FIL_PAGE_TYPE_BLOB: page_type.n_fil_page_type_blob++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tBLOB page\t\t\t|\t%s\n", + fprintf(file, "#::" UINT32PF "\t\t|\t\tBLOB page\t\t\t|\t%s\n", cur_page_num, str); } break; @@ -1060,7 +1059,7 @@ parse_page( case FIL_PAGE_TYPE_ZBLOB: page_type.n_fil_page_type_zblob++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tCompressed BLOB " + fprintf(file, "#::" UINT32PF "\t\t|\t\tCompressed BLOB " "page\t\t|\t%s\n", cur_page_num, str); } break; @@ -1068,7 +1067,7 @@ parse_page( case FIL_PAGE_TYPE_ZBLOB2: page_type.n_fil_page_type_zblob2++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tSubsequent Compressed " + fprintf(file, "#::" UINT32PF "\t\t|\t\tSubsequent Compressed " "BLOB page\t|\t%s\n", cur_page_num, str); } break; @@ -1076,7 +1075,7 @@ parse_page( case FIL_PAGE_PAGE_COMPRESSED: page_type.n_fil_page_type_page_compressed++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tPage compressed " + fprintf(file, "#::" UINT32PF "\t\t|\t\tPage compressed " "page\t|\t%s\n", cur_page_num, str); } break; @@ -1084,7 +1083,7 @@ parse_page( case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED: page_type.n_fil_page_type_page_compressed_encrypted++; if (page_type_dump) { - fprintf(file, "#::%llu\t\t|\t\tPage compressed encrypted " + fprintf(file, "#::" UINT32PF "\t\t|\t\tPage compressed encrypted " "page\t|\t%s\n", cur_page_num, str); } break; @@ -1236,14 +1235,14 @@ static struct my_option innochecksum_options[] = { {"count", 'c', "Print the count of pages in the file and exits.", &just_count, &just_count, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"start_page", 's', "Start on this page number (0 based).", - &start_page, &start_page, 0, GET_ULL, REQUIRED_ARG, - 0, 0, ULLONG_MAX, 0, 1, 0}, + &start_page, &start_page, 0, GET_UINT, REQUIRED_ARG, + 0, 0, FIL_NULL, 0, 1, 0}, {"end_page", 'e', "End at this page number (0 based).", - &end_page, &end_page, 0, GET_ULL, REQUIRED_ARG, - 0, 0, ULLONG_MAX, 0, 1, 0}, + &end_page, &end_page, 0, GET_UINT, REQUIRED_ARG, + 0, 0, FIL_NULL, 0, 1, 0}, {"page", 'p', "Check only this page (0 based).", - &do_page, &do_page, 0, GET_ULL, REQUIRED_ARG, - 0, 0, ULLONG_MAX, 0, 1, 0}, + &do_page, &do_page, 0, GET_UINT, REQUIRED_ARG, + 0, 0, FIL_NULL, 0, 1, 0}, {"strict-check", 'C', "Specify the strict checksum algorithm by the user.", &strict_check, &strict_check, &innochecksum_algorithms_typelib, GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -1439,14 +1438,14 @@ static bool check_encryption(const char* filename, const byte* page) return false; } - uint min_key_version = mach_read_from_4 + uint32_t min_key_version = mach_read_from_4 (page + offset + MAGIC_SZ + 2 + iv_length); - uint key_id = mach_read_from_4 + uint32_t key_id = mach_read_from_4 (page + offset + MAGIC_SZ + 2 + iv_length + 4); if (type == CRYPT_SCHEME_1 && is_log_enabled) { - fprintf(log_file,"Tablespace %s encrypted key_version %u key_id %u\n", + fprintf(log_file,"Tablespace %s encrypted key_version " UINT32PF " key_id " UINT32PF "\n", filename, min_key_version, key_id); } @@ -1468,7 +1467,7 @@ static int verify_checksum( { int exit_status = 0; if (is_page_corrupted(buf, is_encrypted, flags)) { - fprintf(stderr, "Fail: page::%llu invalid\n", + fprintf(stderr, "Fail: page::" UINT32PF " invalid\n", cur_page_num); (*mismatch_count)++; @@ -1542,7 +1541,7 @@ int main( /* size of file (has to be 64 bits) */ unsigned long long int size = 0; /* number of pages in file */ - ulint pages; + uint32_t pages; off_t offset = 0; /* count the no. of page corrupted. */ @@ -1742,36 +1741,38 @@ int main( } if (per_page_details) { - printf("page %llu ", cur_page_num); + printf("page " UINT32PF " ", cur_page_num); } + memcpy(xdes, buf, physical_page_size); + if (page_type_summary || page_type_dump) { parse_page(buf, xdes, fil_page_type, is_encrypted); } - pages = (ulint) (size / physical_page_size); + pages = uint32_t(size / physical_page_size); if (just_count) { - if (read_from_stdin) { - fprintf(stderr, "Number of pages:" ULINTPF "\n", pages); - } else { - printf("Number of pages:" ULINTPF "\n", pages); - } + fprintf(read_from_stdin ? stderr : stdout, + "Number of pages:" UINT32PF "\n", pages); continue; } else if (verbose && !read_from_stdin) { if (is_log_enabled) { fprintf(log_file, "file %s = %llu bytes " - "(" ULINTPF " pages)\n", filename, size, pages); + "(" UINT32PF " pages)\n", + filename, size, pages); if (do_one_page) { fprintf(log_file, "Innochecksum: " - "checking page::%llu;\n", + "checking page::" + UINT32PF ";\n", do_page); } } } else { if (is_log_enabled) { fprintf(log_file, "Innochecksum: checking " - "pages in range::%llu to %llu\n", + "pages in range::" UINT32PF + " to " UINT32PF "\n", start_page, use_end_page ? end_page : (pages - 1)); } @@ -1815,8 +1816,8 @@ int main( the desired page. */ partial_page_read = false; - offset = (off_t) start_page - * (off_t) physical_page_size; + offset = off_t(ulonglong(start_page) + * physical_page_size); if (IF_WIN(_fseeki64,fseeko)(fil_in, offset, SEEK_SET)) { perror("Error: Unable to seek to " @@ -1857,12 +1858,7 @@ int main( count++; if (!bytes || feof(fil_in)) { - fprintf(stderr, "Error: Unable " - "to seek to necessary " - "offset"); - - exit_status = 1; - goto my_exit; + goto unexpected_eof; } } } @@ -1878,6 +1874,15 @@ int main( partial_page_read = false; if (!bytes && feof(fil_in)) { + if (cur_page_num == start_page) { +unexpected_eof: + fputs("Error: Unable " + "to seek to necessary offset\n", + stderr); + + exit_status = 1; + goto my_exit; + } break; } @@ -1919,6 +1924,7 @@ first_non_zero: checksum verification.*/ if (!no_check && !skip_page + && !is_page_free(xdes, physical_page_size, cur_page_num) && (exit_status = verify_checksum( buf, is_encrypted, &mismatch_count, flags))) { @@ -1937,7 +1943,11 @@ first_non_zero: } if (per_page_details) { - printf("page %llu ", cur_page_num); + printf("page " UINT32PF " ", cur_page_num); + } + + if (page_get_page_no(buf) % physical_page_size == 0) { + memcpy(xdes, buf, physical_page_size); } if (page_type_summary || page_type_dump) { @@ -1953,10 +1963,10 @@ first_non_zero: if (!lastt) { lastt= now; } else if (now - lastt >= 1 && is_log_enabled) { - fprintf(log_file, "page::%llu " + fprintf(log_file, "page::" UINT32PF " " "okay: %.3f%% done\n", (cur_page_num - 1), - (float) cur_page_num / pages * 100); + (double) cur_page_num / pages * 100); lastt = now; } } diff --git a/extra/mariabackup/CMakeLists.txt b/extra/mariabackup/CMakeLists.txt index 561f2ab0500..ad2e9e54425 100644 --- a/extra/mariabackup/CMakeLists.txt +++ b/extra/mariabackup/CMakeLists.txt @@ -15,6 +15,7 @@ OPTION(WITH_MARIABACKUP "Include mariabackup" ON) +ADD_FEATURE_INFO(MARIABACKUP WITH_MARIABACKUP "MariaDB Backup Utility") IF(NOT WITH_MARIABACKUP) RETURN() ENDIF() diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc index 95688933324..9df674b5dc3 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -920,7 +920,7 @@ bool lock_tables(MYSQL *connection) if (have_galera_enabled) { - xb_mysql_query(connection, "SET SESSION wsrep_causal_reads=0", false); + xb_mysql_query(connection, "SET SESSION wsrep_sync_wait=0", false); } xb_mysql_query(connection, "BACKUP STAGE START", true); diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc index 99440faf864..20f87354fd0 100644 --- a/extra/mariabackup/innobackupex.cc +++ b/extra/mariabackup/innobackupex.cc @@ -309,7 +309,7 @@ static struct my_option ibx_long_options[] = {"force-non-empty-directories", OPT_FORCE_NON_EMPTY_DIRS, "This " "option, when specified, makes --copy-back or --move-back transfer " "files to non-empty directories. Note that no existing files will be " - "overwritten. If --copy-back or --nove-back has to copy a file from " + "overwritten. If --copy-back or --move-back has to copy a file from " "the backup directory which already exists in the destination " "directory, it will still fail with an error.", (uchar *) &opt_ibx_force_non_empty_dirs, diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index bf4a80832dc..801f046addd 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -51,7 +51,7 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include <my_getopt.h> #include <mysql_com.h> #include <my_default.h> -#include <mysqld.h> +#include <sql_class.h> #include <fcntl.h> #include <string.h> @@ -1241,7 +1241,7 @@ struct my_option xb_client_options[]= { "This " "option, when specified, makes --copy-back or --move-back transfer " "files to non-empty directories. Note that no existing files will be " - "overwritten. If --copy-back or --nove-back has to copy a file from " + "overwritten. If --copy-back or --move-back has to copy a file from " "the backup directory which already exists in the destination " "directory, it will still fail with an error.", (uchar *) &opt_force_non_empty_dirs, (uchar *) &opt_force_non_empty_dirs, diff --git a/extra/wolfssl/CMakeLists.txt b/extra/wolfssl/CMakeLists.txt index 908e27734b9..387f6189609 100644 --- a/extra/wolfssl/CMakeLists.txt +++ b/extra/wolfssl/CMakeLists.txt @@ -50,7 +50,9 @@ SET(WOLFSSL_SOURCES ${WOLFSSL_SRCDIR}/tls.c ${WOLFSSL_SRCDIR}/wolfio.c ${WOLFSSL_SRCDIR}/ocsp.c - ${WOLFSSL_SRCDIR}/ssl.c) + ${WOLFSSL_SRCDIR}/ssl.c + ${WOLFSSL_SRCDIR}/tls13.c) + ADD_DEFINITIONS(-DWOLFSSL_LIB -DBUILDING_WOLFSSL) INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl) @@ -105,8 +107,9 @@ ${WOLFCRYPT_SRCDIR}/wolfmath.c ) # Use fastmath large number math library. -IF(NOT (MSVC AND CMAKE_C_COMPILER_ID MATCHES Clang) - AND (CMAKE_SIZEOF_VOID_P EQUAL 8)) +IF(NOT (MSVC AND CMAKE_C_COMPILER_ID MATCHES Clang)) + # Can't use clang-cl with WOLFSSL_FASTMATH + # due to https://bugs.llvm.org/show_bug.cgi?id=25305 SET(WOLFSSL_FASTMATH 1) ENDIF() @@ -117,6 +120,21 @@ IF(WOLFSSL_FASTMATH) # WolfSSL will use more stack space with it SET(FP_MAX_BITS 16384) SET(WOLFCRYPT_SOURCES ${WOLFCRYPT_SOURCES} ${WOLFCRYPT_SRCDIR}/tfm.c) + IF((CMAKE_SIZEOF_VOID_P MATCHES 4) AND (CMAKE_SYSTEM_PROCESSOR MATCHES "86") + AND (NOT MSVC)) + # Workaround https://github.com/wolfSSL/wolfssl/issues/4245 + # On 32bit Intel, to satisfy inline assembly's wish for free registers + # 1. use -fomit-frame-pointer + # 2. With GCC 4, additionally use -fno-PIC, which works on x86 + # (modern GCC has PIC optimizations, that make it unnecessary) + # The following assumes GCC or Clang + SET(TFM_COMPILE_FLAGS "-fomit-frame-pointer") + IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "5") + SET(TFM_COMPILE_FLAGS "${TFM_COMPILE_FLAGS} -fno-PIC") + ENDIF() + SET_SOURCE_FILES_PROPERTIES(${WOLFCRYPT_SRCDIR}/tfm.c + PROPERTIES COMPILE_FLAGS ${TFM_COMPILE_FLAGS}) + ENDIF() ELSE() SET(WOLFCRYPT_SOURCES ${WOLFCRYPT_SOURCES} ${WOLFCRYPT_SRCDIR}/integer.c) ENDIF() diff --git a/extra/wolfssl/user_settings.h.in b/extra/wolfssl/user_settings.h.in index 4adb27142d9..55b43655659 100644 --- a/extra/wolfssl/user_settings.h.in +++ b/extra/wolfssl/user_settings.h.in @@ -23,12 +23,29 @@ #define OPENSSL_ALL #define WOLFSSL_ALLOW_TLSV10 #define NO_OLD_TIMEVAL_NAME + +/* TLSv1.3 definitions (all needed to build) */ +#define WOLFSSL_TLS13 +#define HAVE_HKDF +#define HAVE_TLS_EXTENSIONS +#define HAVE_SUPPORTED_CURVES +#define HAVE_FFDHE_2048 +#define WC_RSA_PSS +/* End of TLSv1.3 defines */ + +/* Features we exclude */ +#define NO_DSA +#define NO_HC128 +#define NO_MD4 +#define NO_PSK +#define NO_RABBIT +#define NO_RC4 + /* FP_MAX_BITS is set high solely to satisfy ssl_8k_key.test WolfSSL will use more stack space with it, with fastmath */ -#define FP_MAX_BITS 16384 - +#cmakedefine FP_MAX_BITS 16384 #cmakedefine WOLFSSL_AESNI #cmakedefine USE_FAST_MATH #cmakedefine TFM_TIMING_RESISTANT diff --git a/extra/wolfssl/wolfssl b/extra/wolfssl/wolfssl -Subproject 9c87f979a7f1d3a6d786b260653d566c1d31a1c +Subproject add4a68465bcdad238bcf3e5f2771d8da05e628 diff --git a/include/my_sys.h b/include/my_sys.h index f76d1f463a7..1304dee0146 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2020, MariaDB Corporation. + Copyright (c) 2010, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -266,7 +266,8 @@ extern int my_umask_dir, extern my_bool my_use_symdir; extern ulong my_default_record_cache_size; -extern my_bool my_disable_locking, my_disable_async_io, +extern MYSQL_PLUGIN_IMPORT my_bool my_disable_locking; +extern my_bool my_disable_async_io, my_disable_flush_key_blocks, my_disable_symlinks; extern my_bool my_disable_sync, my_disable_copystat_in_redel; extern char wild_many,wild_one,wild_prefix; diff --git a/include/mysql/service_json.h b/include/mysql/service_json.h index 141b76279a5..cb748c0c83f 100644 --- a/include/mysql/service_json.h +++ b/include/mysql/service_json.h @@ -20,23 +20,25 @@ @file json service - Esports JSON parsing methods for plugins to use. + Exports JSON parsing methods for plugins to use. - Fuctions of the service: - js_type - returns the type of the JSON argument, + Functions of the service: + json_type - returns the type of the JSON argument, and the parsed value if it's scalar (not object or array) - js_get_array_item - expecs JSON array as an argument, - and returns the n_item's item's type and value + json_get_array_item - expects JSON array as an argument, + and returns the type of the element at index `n_item`. Returns JSV_NOTHING type if the array is shorter - than n_item and the actual length of the array in v_len. + than n_item and the actual length of the array in value_len. + If successful, then `value` up till `value[value_len]` contains the array + element at the desired index (n_item). - js_get_object_key - expects JSON object as an argument, - searches for a key in the object, return it's type and value. + json_get_object_key - expects JSON object as an argument, + searches for a key in the object, return it's type and stores its value in `value`. JSV_NOTHING if no such key found, the number of keys in v_len. - js_get_object_nkey - expects JSON object as an argument. + json_get_object_nkey - expects JSON object as an argument. finds n_key's key in the object, returns it's name, type and value. JSV_NOTHING if object has less keys than n_key. */ diff --git a/libmariadb b/libmariadb -Subproject 802ce584a26fdc0ba67fcf35e277bf3c7440956 +Subproject 0cc16f18c1d87bbe6e360eaf578fcedeb947911 diff --git a/mysql-test/dgcov.pl b/mysql-test/dgcov.pl index fbc5540e697..2c00c64d1ff 100755 --- a/mysql-test/dgcov.pl +++ b/mysql-test/dgcov.pl @@ -155,32 +155,34 @@ END sub gcov_one_file { return unless /\.gcda$/; unless ($opt_skip_gcov) { - $cmd= "gcov -i '$_' 2>/dev/null >/dev/null"; + $cmd= "gcov -il '$_' 2>/dev/null >/dev/null"; print STDERR ++$file_no,"\r" if not $opt_verbose and -t STDERR; logv "Running: $cmd"; system($cmd)==0 or die "system($cmd): $? $!"; } # now, read the generated file - open FH, '<', "$_.gcov" or die "open(<$_.gcov): $!"; - my $fname; - while (<FH>) { - chomp; - if (/^function:/) { - next; - } - if (/^file:/) { - $fname=realpath($'); - next; - } - next if /^lcount:\d+,-\d+/; # whatever that means - unless (/^lcount:(\d+),(\d+)/ and $fname) { - warn "unknown line '$_' after running '$cmd'"; - next; + for my $gcov_file (<$_*.gcov>) { + open FH, '<', "$gcov_file" or die "open(<$gcov_file): $!"; + my $fname; + while (<FH>) { + chomp; + if (/^function:/) { + next; + } + if (/^file:/) { + $fname=realpath(-f $' ? $' : $root.$'); + next; + } + next if /^lcount:\d+,-\d+/; # whatever that means + unless (/^lcount:(\d+),(\d+)/ and $fname) { + warn "unknown line '$_' in $gcov_file"; + next; + } + $cov{$fname}->{$1}+=$2; } - $cov{$fname}->{$1}+=$2; + close(FH); } - close(FH); } sub write_coverage { diff --git a/mysql-test/include/wait_until_disconnected.inc b/mysql-test/include/wait_until_disconnected.inc index 15bc6474995..93ada7f11ce 100644 --- a/mysql-test/include/wait_until_disconnected.inc +++ b/mysql-test/include/wait_until_disconnected.inc @@ -15,7 +15,7 @@ while (!$mysql_errno) dec $counter; if (!$counter) { - --die Server failed to dissapear + --die Server failed to disappear } --real_sleep 0.1 } diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index b5a7660ed3e..69033649b46 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -389,10 +389,10 @@ sub _collect { # 1 Still running # sub wait_one { - my ($self, $timeout)= @_; - croak "usage: \$safe_proc->wait_one([timeout])" unless ref $self; + my ($self, $timeout, $keep)= @_; + croak "usage: \$safe_proc->wait_one([timeout] [, keep])" unless ref $self; - _verbose("wait_one $self, $timeout"); + _verbose("wait_one $self, $timeout, $keep"); if ( ! defined($self->{SAFE_PID}) ) { # No pid => not running @@ -466,16 +466,16 @@ sub wait_one { return 1; } - if ( not $blocking and $retpid == -1 ) { - # still running - _verbose("still running"); - return 1; - } + #if ( not $blocking and $retpid == -1 ) { + # # still running + # _verbose("still running"); + # return 1; + #} #warn "wait_one: expected pid $pid but got $retpid" # unless( $retpid == $pid ); - $self->_collect($exit_code); + $self->_collect($exit_code) unless $keep; return 0; } diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index cee9f2b6ed6..2ff78c0e10a 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -40,7 +40,7 @@ BEGIN eval 'sub USE_NETPING { $use_netping }'; } -sub sleep_until_file_created ($$$$); +sub sleep_until_file_created ($$$$$); sub mtr_ping_port ($); sub mtr_ping_port ($) { @@ -102,8 +102,9 @@ sub mtr_ping_port ($) { # FIXME check that the pidfile contains the expected pid! -sub sleep_until_file_created ($$$$) { +sub sleep_until_file_created ($$$$$) { my $pidfile= shift; + my $expectfile = shift; my $timeout= shift; my $proc= shift; my $warn_seconds = shift; @@ -120,8 +121,9 @@ sub sleep_until_file_created ($$$$) { my $seconds= ($loop * $sleeptime) / 1000; # Check if it died after the fork() was successful - if ( defined $proc and ! $proc->wait_one(0) ) + if ( defined $proc and ! $proc->wait_one(0, 1) ) { + return 1 if -r $expectfile; mtr_warning("Process $proc died after mysql-test-run waited $seconds " . "seconds for $pidfile to be created."); return 0; diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result index f1eb1dc1268..17c73f74a49 100644 --- a/mysql-test/main/cte_nonrecursive.result +++ b/mysql-test/main/cte_nonrecursive.result @@ -2019,6 +2019,73 @@ drop procedure sp1; drop procedure sp2; drop procedure sp3; drop table t1; +# +# MDEV-26095: missing RECURSIVE for the recursive definition of CTE +# embedded into another CTE definition +# +create table t1 (a int); +insert into t1 values (5), (7); +with cte_e as ( +with recursive cte_r as ( +select a from t1 union select a+1 as a from cte_r r where a < 10 +) select * from cte_r +) select * from cte_e; +a +5 +7 +6 +8 +9 +10 +with cte_e as ( +with cte_r as ( +select a from t1 union select a+1 as a from cte_r r where a < 10 +) select * from cte_r +) select * from cte_e; +ERROR 42S02: Table 'test.cte_r' doesn't exist +drop table t1; +# +# MDEV-26025: query with two usage of a CTE executing via PS /SP +# +create table t1 (a int, b int); +insert into t1 value (1,3), (3,2), (1,3), (4,1); +prepare stmt from "with +cte1 as ( select a,b from t1 where a = 1 AND b = 3 ), +cte2 as ( select a,b from cte1 ), +cte3 as ( select a,b from cte2 ) +select * from cte3, cte2"; +execute stmt; +a b a b +1 3 1 3 +1 3 1 3 +1 3 1 3 +1 3 1 3 +execute stmt; +a b a b +1 3 1 3 +1 3 1 3 +1 3 1 3 +1 3 1 3 +deallocate prepare stmt; +create procedure sp() with +cte1 as ( select a,b from t1 where a = 1 AND b = 3 ), +cte2 as ( select a,b from cte1 ), +cte3 as ( select a,b from cte2 ) +select * from cte3, cte2; +call sp(); +a b a b +1 3 1 3 +1 3 1 3 +1 3 1 3 +1 3 1 3 +call sp(); +a b a b +1 3 1 3 +1 3 1 3 +1 3 1 3 +1 3 1 3 +drop procedure sp; +drop table t1; # End of 10.2 tests # # MDEV-21673: several references to CTE that uses diff --git a/mysql-test/main/cte_nonrecursive.test b/mysql-test/main/cte_nonrecursive.test index ad03b25ceb6..8ab3bddc410 100644 --- a/mysql-test/main/cte_nonrecursive.test +++ b/mysql-test/main/cte_nonrecursive.test @@ -1504,6 +1504,56 @@ drop procedure sp3; drop table t1; +--echo # +--echo # MDEV-26095: missing RECURSIVE for the recursive definition of CTE +--echo # embedded into another CTE definition +--echo # + +create table t1 (a int); +insert into t1 values (5), (7); + +with cte_e as ( + with recursive cte_r as ( + select a from t1 union select a+1 as a from cte_r r where a < 10 + ) select * from cte_r +) select * from cte_e; + +--ERROR ER_NO_SUCH_TABLE +with cte_e as ( + with cte_r as ( + select a from t1 union select a+1 as a from cte_r r where a < 10 + ) select * from cte_r +) select * from cte_e; + +drop table t1; + +--echo # +--echo # MDEV-26025: query with two usage of a CTE executing via PS /SP +--echo # + +create table t1 (a int, b int); +insert into t1 value (1,3), (3,2), (1,3), (4,1); + +let $q= +with + cte1 as ( select a,b from t1 where a = 1 AND b = 3 ), + cte2 as ( select a,b from cte1 ), + cte3 as ( select a,b from cte2 ) +select * from cte3, cte2; + +eval prepare stmt from "$q"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +eval create procedure sp() $q; + +call sp(); +call sp(); + +drop procedure sp; +drop table t1; + --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result index 805352307ba..478bd9a92a5 100644 --- a/mysql-test/main/cte_recursive.result +++ b/mysql-test/main/cte_recursive.result @@ -3735,7 +3735,7 @@ select * from t1 as t; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t ALL NULL NULL NULL NULL 4 100.00 Warnings: -Note 1003 with recursive cte as (/* select#2 */ select `*` AS `*` from `test`.`t1` where `a` = 1 union /* select#3 */ select `a` + 1 AS `a+1` from `cte` where `a` < 3)/* select#1 */ select `test`.`t`.`a` AS `a` from `test`.`t1` `t` +Note 1003 with recursive cte as (/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1 union /* select#3 */ select `cte`.`a` + 1 AS `a+1` from `cte` where `cte`.`a` < 3)/* select#1 */ select `test`.`t`.`a` AS `a` from `test`.`t1` `t` with recursive cte as (select * from t1 where a=1 union select a+1 from cte where a<3) select * from t1 as t; @@ -3748,10 +3748,10 @@ create table t2 ( i1 int, i2 int); insert into t2 values (1,1),(2,2); explain with recursive cte as -( select * from t1 union select s1.* from t1 as s1, cte where s1.i1 = cte.i2 ) -select * from t1 as t; +( select * from t2 union select s1.* from t2 as s1, cte where s1.i1 = cte.i2 ) +select * from t2 as t; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t ALL NULL NULL NULL NULL 4 +1 PRIMARY t ALL NULL NULL NULL NULL 2 drop table t1,t2; # # MDEV-22042: ANALYZE of query using stored function and recursive CTE @@ -4499,6 +4499,93 @@ set big_tables=@save_big_tables; Warnings: Warning 1287 '@@big_tables' is deprecated and will be removed in a future release # +# MDEV-26135: execution of PS for query with hanging recursive CTE +# +create table t1 (a int); +insert into t1 values (5), (7); +create table t2 (b int); +insert into t2 values (3), (7), (1); +with recursive r as (select a from t1 union select a+1 from r where a < 10) +select * from t2; +b +3 +7 +1 +prepare stmt from "with recursive r as (select a from t1 union select a+1 from r where a < 10) +select * from t2"; +execute stmt; +b +3 +7 +1 +execute stmt; +b +3 +7 +1 +deallocate prepare stmt; +drop table t1,t2; +# +# MDEV-26189: Unknown column reference within hanging recursive CTE +# +create table t1 (a int); +insert into t1 values (3), (7), (1); +with recursive +r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b) +select * from t1 as t; +ERROR 42S22: Unknown column 'r.b' in 'where clause' +explain with recursive +r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b) +select * from t1 as t; +ERROR 42S22: Unknown column 'r.b' in 'where clause' +create procedure sp1() with recursive +r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b) +select * from t1 as t; +call sp1(); +ERROR 42S22: Unknown column 'r.b' in 'where clause' +call sp1(); +ERROR 42S22: Unknown column 'r.b' in 'where clause' +with recursive +r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a) +select * from t1 as t; +ERROR 42S22: Unknown column 's1.b' in 'where clause' +explain with recursive +r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a) +select * from t1 as t; +ERROR 42S22: Unknown column 's1.b' in 'where clause' +create procedure sp2() with recursive +r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a) +select * from t1 as t; +call sp2(); +ERROR 42S22: Unknown column 's1.b' in 'where clause' +call sp2(); +ERROR 42S22: Unknown column 's1.b' in 'where clause' +drop procedure sp1; +drop procedure sp2; +drop table t1; +# +# MDEV-26202: Recursive CTE used indirectly twice +# (fixed by the patch forMDEV-26025) +# +with recursive +rcte as ( SELECT 1 AS a +UNION ALL +SELECT cast(a + 1 as unsigned int) FROM rcte WHERE a < 3), +cte1 AS (SELECT a FROM rcte), +cte2 AS (SELECT a FROM cte1), +cte3 AS ( SELECT a FROM cte2) +SELECT * FROM cte2, cte3; +a a +1 1 +2 1 +3 1 +1 2 +2 2 +3 2 +1 3 +2 3 +3 3 +# # End of 10.2 tests # # diff --git a/mysql-test/main/cte_recursive.test b/mysql-test/main/cte_recursive.test index 9adb2de7ec5..f8c41dbc3ea 100644 --- a/mysql-test/main/cte_recursive.test +++ b/mysql-test/main/cte_recursive.test @@ -2590,8 +2590,8 @@ insert into t2 values (1,1),(2,2); explain with recursive cte as - ( select * from t1 union select s1.* from t1 as s1, cte where s1.i1 = cte.i2 ) -select * from t1 as t; + ( select * from t2 union select s1.* from t2 as s1, cte where s1.i1 = cte.i2 ) +select * from t2 as t; drop table t1,t2; @@ -2855,6 +2855,85 @@ drop table folks; set big_tables=@save_big_tables; --echo # +--echo # MDEV-26135: execution of PS for query with hanging recursive CTE +--echo # + +create table t1 (a int); +insert into t1 values (5), (7); +create table t2 (b int); +insert into t2 values (3), (7), (1); + +let $q= +with recursive r as (select a from t1 union select a+1 from r where a < 10) +select * from t2; + +eval $q; +eval prepare stmt from "$q"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +drop table t1,t2; + +--echo # +--echo # MDEV-26189: Unknown column reference within hanging recursive CTE +--echo # + +create table t1 (a int); +insert into t1 values (3), (7), (1); + +let $q1= +with recursive + r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b) +select * from t1 as t; + +--ERROR ER_BAD_FIELD_ERROR +eval $q1; +--ERROR ER_BAD_FIELD_ERROR +eval explain $q1; + +eval create procedure sp1() $q1; +--ERROR ER_BAD_FIELD_ERROR +call sp1(); +--ERROR ER_BAD_FIELD_ERROR +call sp1(); + +let $q2= +with recursive + r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a) +select * from t1 as t; + +--ERROR ER_BAD_FIELD_ERROR +eval $q2; +--ERROR ER_BAD_FIELD_ERROR +eval explain $q2; + +eval create procedure sp2() $q2; +--ERROR ER_BAD_FIELD_ERROR +call sp2(); +--ERROR ER_BAD_FIELD_ERROR +call sp2(); + +drop procedure sp1; +drop procedure sp2; + +drop table t1; + +--echo # +--echo # MDEV-26202: Recursive CTE used indirectly twice +--echo # (fixed by the patch forMDEV-26025) +--echo # + +with recursive + rcte as ( SELECT 1 AS a + UNION ALL + SELECT cast(a + 1 as unsigned int) FROM rcte WHERE a < 3), + cte1 AS (SELECT a FROM rcte), + cte2 AS (SELECT a FROM cte1), + cte3 AS ( SELECT a FROM cte2) +SELECT * FROM cte2, cte3; + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index d354bdf1220..b8a2d34786f 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5158,6 +5158,19 @@ c1 42 DROP TABLE t1, t2; # +# MDEV-25560 Creating table with certain generated column crashes server +# +CREATE TABLE t1 (i int, b int AS (RPAD(123,1)) stored); +# Original case from the reporter +CREATE TABLE crash_test_2 ( +DATA_VALUE CHAR(10) NULL, +HAS_DATA BIT NOT NULL, +TEST_COLUMN CHAR(10) AS (RPAD(CASE WHEN HAS_DATA = 1 +THEN DATA_VALUE ELSE NULL END, 10)) STORED); +ERROR HY000: Function or expression 'rpad(case when `HAS_DATA` = 1 then `DATA_VALUE` else NULL end,10)' cannot be used in the GENERATED ALWAYS AS clause of `TEST_COLUMN` +# Cleanup +DROP TABLE t1; +# # End of 10.3 tests # # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 59ef8b0a805..4df473fa0f6 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2094,6 +2094,24 @@ DROP TABLE t1, t2; --echo # +--echo # MDEV-25560 Creating table with certain generated column crashes server +--echo # + +CREATE TABLE t1 (i int, b int AS (RPAD(123,1)) stored); + +--echo # Original case from the reporter +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +CREATE TABLE crash_test_2 ( + DATA_VALUE CHAR(10) NULL, + HAS_DATA BIT NOT NULL, + TEST_COLUMN CHAR(10) AS (RPAD(CASE WHEN HAS_DATA = 1 + THEN DATA_VALUE ELSE NULL END, 10)) STORED); + +--echo # Cleanup +DROP TABLE t1; + + +--echo # --echo # End of 10.3 tests --echo # diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result index 9f6eb583e91..fa5a952a9c1 100644 --- a/mysql-test/main/grant5.result +++ b/mysql-test/main/grant5.result @@ -49,7 +49,7 @@ SHOW GRANTS FOR test_user; Grants for test_user@% GRANT `test_role` TO `test_user`@`%` GRANT USAGE ON *.* TO `test_user`@`%` -SET DEFAULT ROLE test_role FOR 'test_user'@'%' +SET DEFAULT ROLE `test_role` FOR `test_user`@`%` SET DEFAULT ROLE NONE for test_user; SHOW GRANTS FOR test_user; Grants for test_user@% @@ -63,7 +63,7 @@ Grants for test_user@% GRANT `test_role` TO `test_user`@`%` GRANT USAGE ON *.* TO `test_user`@`%` GRANT USAGE ON *.* TO `test_role` -SET DEFAULT ROLE test_role FOR 'test_user'@'%' +SET DEFAULT ROLE `test_role` FOR `test_user`@`%` SET DEFAULT ROLE NONE; SHOW GRANTS; Grants for test_user@% @@ -168,6 +168,23 @@ drop user 'user1'@'localhost'; drop user 'fetch'@'localhost'; drop user 'user-1'@'localhost'; drop user 'O\'Brien'@'localhost'; +# +# MDEV-26080 SHOW GRANTS does not quote role names properly for DEFAULT ROLE +# +CREATE USER 'test-user'; +CREATE ROLE `r``o'l"e`; +select user from mysql.user where is_role='Y'; +User +r`o'l"e +GRANT `r``o'l"e` TO 'test-user'; +SET DEFAULT ROLE `r``o'l"e` FOR 'test-user'; +SHOW GRANTS FOR 'test-user'; +Grants for test-user@% +GRANT `r``o'l"e` TO `test-user`@`%` +GRANT USAGE ON *.* TO `test-user`@`%` +SET DEFAULT ROLE `r``o'l"e` FOR `test-user`@`%` +DROP ROLE `r``o'l"e`; +DROP USER 'test-user'; # End of 10.3 tests create user u1@h identified with 'mysql_native_password' using 'pwd'; ERROR HY000: Password hash should be a 41-digit hexadecimal number diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test index 9c3f20396c4..0b4a63ab075 100644 --- a/mysql-test/main/grant5.test +++ b/mysql-test/main/grant5.test @@ -124,6 +124,20 @@ drop user 'fetch'@'localhost'; drop user 'user-1'@'localhost'; drop user 'O\'Brien'@'localhost'; +--echo # +--echo # MDEV-26080 SHOW GRANTS does not quote role names properly for DEFAULT ROLE +--echo # + +CREATE USER 'test-user'; +CREATE ROLE `r``o'l"e`; +select user from mysql.user where is_role='Y'; +GRANT `r``o'l"e` TO 'test-user'; +SET DEFAULT ROLE `r``o'l"e` FOR 'test-user'; +# it is expected that quotes won't be shown correctly +SHOW GRANTS FOR 'test-user'; +DROP ROLE `r``o'l"e`; +DROP USER 'test-user'; + --echo # End of 10.3 tests # diff --git a/mysql-test/main/lock_multi_bug38499.test b/mysql-test/main/lock_multi_bug38499.test index b812984e516..c489712e5d8 100644 --- a/mysql-test/main/lock_multi_bug38499.test +++ b/mysql-test/main/lock_multi_bug38499.test @@ -2,6 +2,9 @@ # MySQL >= 5.0 # +# The test can take hours with valgrind +--source include/not_valgrind.inc + # Save the initial number of concurrent sessions --source include/count_sessions.inc diff --git a/mysql-test/main/lock_multi_bug38691.test b/mysql-test/main/lock_multi_bug38691.test index 881a0d8e502..9760c1a873a 100644 --- a/mysql-test/main/lock_multi_bug38691.test +++ b/mysql-test/main/lock_multi_bug38691.test @@ -4,6 +4,8 @@ # MySQL >= 5.0 # +# The test can take hours with valgrind +--source include/not_valgrind.inc # Save the initial number of concurrent sessions --source include/count_sessions.inc diff --git a/mysql-test/main/mysql_client_test.result b/mysql-test/main/mysql_client_test.result index 420e2fc8e3c..dbc1feaa23b 100644 --- a/mysql-test/main/mysql_client_test.result +++ b/mysql-test/main/mysql_client_test.result @@ -127,6 +127,11 @@ Data: EOF mysql_stmt_next_result(): 0; field_count: 0 # ------------------------------------ +# cat MYSQL_TMP_DIR/test_mdev26145.out.log +# ------------------------------------ +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def MAX(a) MAX(a) 3 11 0 Y 32768 0 63 +# ------------------------------------ # cat MYSQL_TMP_DIR/test_explain_meta.out.log diff --git a/mysql-test/main/mysql_client_test.test b/mysql-test/main/mysql_client_test.test index 7885dc5c0d7..9fb7bcd81c9 100644 --- a/mysql-test/main/mysql_client_test.test +++ b/mysql-test/main/mysql_client_test.test @@ -36,6 +36,10 @@ echo ok; --echo # ------------------------------------ --cat_file $MYSQL_TMP_DIR/test_wl4435.out.log --echo # ------------------------------------ +--echo # cat MYSQL_TMP_DIR/test_mdev26145.out.log +--echo # ------------------------------------ +--cat_file $MYSQL_TMP_DIR/test_mdev26145.out.log +--echo # ------------------------------------ --echo --echo diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result index 8cb48d21d3c..6bb236b6fb8 100644 --- a/mysql-test/main/mysql_upgrade.result +++ b/mysql-test/main/mysql_upgrade.result @@ -758,7 +758,7 @@ GRANT `aRole` TO `root`@`localhost` WITH ADMIN OPTION GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION GRANT USAGE ON *.* TO `aRole` -SET DEFAULT ROLE aRole FOR 'root'@'localhost' +SET DEFAULT ROLE `aRole` FOR `root`@`localhost` SET DEFAULT ROLE NONE; SHOW GRANTS; Grants for root@localhost diff --git a/mysql-test/main/order_by_innodb.result b/mysql-test/main/order_by_innodb.result index 9cdf9800cee..14b9b861a14 100644 --- a/mysql-test/main/order_by_innodb.result +++ b/mysql-test/main/order_by_innodb.result @@ -147,4 +147,56 @@ i n 656 eight set optimizer_switch= @save_optimizer_switch; DROP TABLE t1,t2,t3; +# +# MDEV-25858: Query results are incorrect when indexes are added +# +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb; +insert into t1 values (1),(2),(3); +CREATE TABLE t2 ( +id int NOT NULL PRIMARY KEY, +id2 int NOT NULL, +d1 datetime, +d2 timestamp NOT NULL, +KEY id2 (id2) +) engine=innodb; +insert into t2 values +(1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'), +(2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'), +(3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00'); +select +t1.id,t2.id +from +t1 left join +t2 on t2.id2 = t1.id and +t2.id = (select dd.id +from t2 dd +where +dd.id2 = t1.id and +d1 > '2019-02-06 00:00:00' + order by +dd.d1 desc, dd.d2 desc, dd.id desc limit 1 +); +id id +1 NULL +2 1 +3 3 +create index for_latest_sort on t2 (d1 desc, d2 desc, id desc); +select +t1.id,t2.id +from +t1 left join +t2 on t2.id2 = t1.id and +t2.id = (select dd.id +from t2 dd +where +dd.id2 = t1.id and +d1 > '2019-02-06 00:00:00' + order by +dd.d1 desc, dd.d2 desc, dd.id desc limit 1 +); +id id +1 NULL +2 1 +3 3 +drop table t1,t2; # End of 10.2 tests diff --git a/mysql-test/main/order_by_innodb.test b/mysql-test/main/order_by_innodb.test index f4c738263ae..97c043b8dbc 100644 --- a/mysql-test/main/order_by_innodb.test +++ b/mysql-test/main/order_by_innodb.test @@ -135,4 +135,55 @@ set optimizer_switch= @save_optimizer_switch; DROP TABLE t1,t2,t3; +--echo # +--echo # MDEV-25858: Query results are incorrect when indexes are added +--echo # + +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb; +insert into t1 values (1),(2),(3); + +CREATE TABLE t2 ( + id int NOT NULL PRIMARY KEY, + id2 int NOT NULL, + d1 datetime, + d2 timestamp NOT NULL, + KEY id2 (id2) +) engine=innodb; + +insert into t2 values + (1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'), + (2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'), + (3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00'); + +select + t1.id,t2.id +from + t1 left join + t2 on t2.id2 = t1.id and + t2.id = (select dd.id + from t2 dd + where + dd.id2 = t1.id and + d1 > '2019-02-06 00:00:00' + order by + dd.d1 desc, dd.d2 desc, dd.id desc limit 1 + ); + +create index for_latest_sort on t2 (d1 desc, d2 desc, id desc); + +select + t1.id,t2.id +from + t1 left join + t2 on t2.id2 = t1.id and + t2.id = (select dd.id + from t2 dd + where + dd.id2 = t1.id and + d1 > '2019-02-06 00:00:00' + order by + dd.d1 desc, dd.d2 desc, dd.id desc limit 1 + ); +drop table t1,t2; + --echo # End of 10.2 tests diff --git a/mysql-test/main/prepare.result b/mysql-test/main/prepare.result index c1a2969212b..cfe6603dbbe 100644 --- a/mysql-test/main/prepare.result +++ b/mysql-test/main/prepare.result @@ -50,3 +50,17 @@ t1_first deallocate prepare stmt1; deallocate prepare stmt2; drop table t1; +# +# MDEV-25808 PREPARE/EXECUTE makes signed integer out of unsigned +# +prepare p1 from 'select concat(?)'; +execute p1 using 17864960750176564435; +concat(?) +17864960750176564435 +prepare p1 from 'select SQRT(?) is not null'; +execute p1 using 17864960750176564435; +SQRT(?) is not null +1 +# +# End of 10.3 tests +# diff --git a/mysql-test/main/prepare.test b/mysql-test/main/prepare.test index eaab376a5a2..4d1573eb0c8 100644 --- a/mysql-test/main/prepare.test +++ b/mysql-test/main/prepare.test @@ -40,3 +40,15 @@ execute stmt2; deallocate prepare stmt1; deallocate prepare stmt2; drop table t1; + +--echo # +--echo # MDEV-25808 PREPARE/EXECUTE makes signed integer out of unsigned +--echo # +prepare p1 from 'select concat(?)'; +execute p1 using 17864960750176564435; +prepare p1 from 'select SQRT(?) is not null'; +execute p1 using 17864960750176564435; + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index d904585d4d4..1b77d713185 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -5572,6 +5572,20 @@ DROP TABLE t1, t2, t3; # End of 10.2 tests # # +# MDEV-26147: The test main.sp-row fails in case it is run in PS mode +# +CREATE PROCEDURE p1(a ROW(a INT,b INT)) +BEGIN +SELECT a.a, a.b; +END; +$$ +PREPARE stmt FROM 'CALL p1(ROW(10, 20))'; +EXECUTE stmt; +a.a a.b +10 20 +DEALLOCATE PREPARE stmt; +DROP PROCEDURE p1; +# # MDEV-19263: Server crashes in mysql_handle_single_derived # upon 2nd execution of PS # diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test index 837fa6f2b6e..a65c54c8788 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -4994,6 +4994,22 @@ DROP TABLE t1, t2, t3; --echo # --echo # +--echo # MDEV-26147: The test main.sp-row fails in case it is run in PS mode +--echo # +DELIMITER $$; +CREATE PROCEDURE p1(a ROW(a INT,b INT)) +BEGIN + SELECT a.a, a.b; +END; +$$ +DELIMITER ;$$ +PREPARE stmt FROM 'CALL p1(ROW(10, 20))'; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +DROP PROCEDURE p1; + +--echo # --echo # MDEV-19263: Server crashes in mysql_handle_single_derived --echo # upon 2nd execution of PS --echo # diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result index dc377aa5b6c..a1d227a9baa 100644 --- a/mysql-test/main/selectivity_innodb.result +++ b/mysql-test/main/selectivity_innodb.result @@ -2098,6 +2098,57 @@ drop view v1; # # End of 10.1 tests # +# +# MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity +# +set +@tmp_jcl=@@join_cache_level, +@tmp_sel=@@optimizer_use_condition_selectivity; +set +join_cache_level=3, +optimizer_use_condition_selectivity=2; +CREATE TABLE t1 ( +c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int, c8 int, c9 int, c10 int, +c11 int, c12 int, c13 int, c14 int, c15 int, c16 int, c17 int, c18 int, c19 int, +c20 int, c21 int, c22 int, c23 int, c24 int, c25 int, c26 int, c27 int, c28 int, +c29 int, c30 int, c31 int, c32 int, c33 int, c34 int +) ENGINE=InnoDB; +SELECT * FROM t1 +WHERE +(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, +c11, c12, c13, c14, c15, c16, c17, c18, c19, +c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, +c30, c31, c32, c33, c34) IN (SELECT * FROM t1) ; +c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 +set +join_cache_level=@tmp_jcl, +optimizer_use_condition_selectivity=@tmp_sel; +drop table t1; +# +# MDEV-25013: SIGSEGV in best_extension_by_limited_search | SIGSEGV in restore_prev_nj_state +# +SET join_cache_level=3; +CREATE TABLE t1 ( +TEXT1 TEXT, TEXT2 TEXT, TEXT3 TEXT, TEXT4 TEXT, TEXT5 TEXT, +TEXT6 TEXT, TEXT7 TEXT, TEXT8 TEXT, TEXT9 TEXT, TEXT10 TEXT, +TEXT11 TEXT, TEXT12 TEXT,TEXT13 TEXT,TEXT14 TEXT,TEXT15 TEXT, +TEXT16 TEXT,TEXT17 TEXT,TEXT18 TEXT,TEXT19 TEXT,TEXT20 TEXT, +TEXT21 TEXT,TEXT22 TEXT,TEXT23 TEXT,TEXT24 TEXT,TEXT25 TEXT, +TEXT26 TEXT,TEXT27 TEXT,TEXT28 TEXT,TEXT29 TEXT,TEXT30 TEXT, +TEXT31 TEXT,TEXT32 TEXT,TEXT33 TEXT,TEXT34 TEXT,TEXT35 TEXT, +TEXT36 TEXT,TEXT37 TEXT,TEXT38 TEXT,TEXT39 TEXT,TEXT40 TEXT, +TEXT41 TEXT,TEXT42 TEXT,TEXT43 TEXT,TEXT44 TEXT,TEXT45 TEXT, +TEXT46 TEXT,TEXT47 TEXT,TEXT48 TEXT,TEXT49 TEXT,TEXT50 TEXT +) ENGINE=InnoDB; +EXPLAIN SELECT 1 FROM t1 NATURAL 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 1 Using where +1 SIMPLE t2 hash_ALL NULL #hash#$hj 150 test.t1.TEXT1,test.t1.TEXT2,test.t1.TEXT3,test.t1.TEXT4,test.t1.TEXT5,test.t1.TEXT6,test.t1.TEXT7,test.t1.TEXT8,test.t1.TEXT9,test.t1.TEXT10,test.t1.TEXT11,test.t1.TEXT12,test.t1.TEXT13,test.t1.TEXT14,test.t1.TEXT15,test.t1.TEXT16,test.t1.TEXT17,test.t1.TEXT18,test.t1.TEXT19,test.t1.TEXT20,test.t1.TEXT21,test.t1.TEXT22,test.t1.TEXT23,test.t1.TEXT24,test.t1.TEXT25,test.t1.TEXT26,test.t1.TEXT27,test.t1.TEXT28,test.t1.TEXT29,test.t1.TEXT30,test.t1.TEXT31,test.t1.TEXT32,test.t1.TEXT33,test.t1.TEXT34,test.t1.TEXT35,test.t1.TEXT36,test.t1.TEXT37,test.t1.TEXT38,test.t1.TEXT39,test.t1.TEXT40,test.t1.TEXT41,test.t1.TEXT42,test.t1.TEXT43,test.t1.TEXT44,test.t1.TEXT45,test.t1.TEXT46,test.t1.TEXT47,test.t1.TEXT48,test.t1.TEXT49,test.t1.TEXT50 1 Using where; Using join buffer (flat, BNLH join) +set join_cache_level=@tmp_jcl; +drop table t1; +# +# End of 10.1 tests +# set use_stat_tables= @tmp_ust; set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; diff --git a/mysql-test/main/selectivity_innodb.test b/mysql-test/main/selectivity_innodb.test index b98b5342183..4bcdb5d6ec9 100644 --- a/mysql-test/main/selectivity_innodb.test +++ b/mysql-test/main/selectivity_innodb.test @@ -174,6 +174,61 @@ drop view v1; --echo # End of 10.1 tests --echo # +--echo # +--echo # MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity +--echo # + +set + @tmp_jcl=@@join_cache_level, + @tmp_sel=@@optimizer_use_condition_selectivity; +set + join_cache_level=3, + optimizer_use_condition_selectivity=2; + +CREATE TABLE t1 ( + c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int, c8 int, c9 int, c10 int, + c11 int, c12 int, c13 int, c14 int, c15 int, c16 int, c17 int, c18 int, c19 int, + c20 int, c21 int, c22 int, c23 int, c24 int, c25 int, c26 int, c27 int, c28 int, + c29 int, c30 int, c31 int, c32 int, c33 int, c34 int +) ENGINE=InnoDB; + +SELECT * FROM t1 +WHERE + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, + c11, c12, c13, c14, c15, c16, c17, c18, c19, + c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, + c30, c31, c32, c33, c34) IN (SELECT * FROM t1) ; + +set + join_cache_level=@tmp_jcl, + optimizer_use_condition_selectivity=@tmp_sel; +drop table t1; + +--echo # +--echo # MDEV-25013: SIGSEGV in best_extension_by_limited_search | SIGSEGV in restore_prev_nj_state +--echo # + +SET join_cache_level=3; +CREATE TABLE t1 ( + TEXT1 TEXT, TEXT2 TEXT, TEXT3 TEXT, TEXT4 TEXT, TEXT5 TEXT, + TEXT6 TEXT, TEXT7 TEXT, TEXT8 TEXT, TEXT9 TEXT, TEXT10 TEXT, + TEXT11 TEXT, TEXT12 TEXT,TEXT13 TEXT,TEXT14 TEXT,TEXT15 TEXT, + TEXT16 TEXT,TEXT17 TEXT,TEXT18 TEXT,TEXT19 TEXT,TEXT20 TEXT, + TEXT21 TEXT,TEXT22 TEXT,TEXT23 TEXT,TEXT24 TEXT,TEXT25 TEXT, + TEXT26 TEXT,TEXT27 TEXT,TEXT28 TEXT,TEXT29 TEXT,TEXT30 TEXT, + TEXT31 TEXT,TEXT32 TEXT,TEXT33 TEXT,TEXT34 TEXT,TEXT35 TEXT, + TEXT36 TEXT,TEXT37 TEXT,TEXT38 TEXT,TEXT39 TEXT,TEXT40 TEXT, + TEXT41 TEXT,TEXT42 TEXT,TEXT43 TEXT,TEXT44 TEXT,TEXT45 TEXT, + TEXT46 TEXT,TEXT47 TEXT,TEXT48 TEXT,TEXT49 TEXT,TEXT50 TEXT +) ENGINE=InnoDB; +EXPLAIN SELECT 1 FROM t1 NATURAL JOIN t1 AS t2; + +set join_cache_level=@tmp_jcl; +drop table t1; +--echo # +--echo # End of 10.1 tests +--echo # + set use_stat_tables= @tmp_ust; set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; diff --git a/mysql-test/main/selectivity_no_engine.result b/mysql-test/main/selectivity_no_engine.result index 743dcd04695..b6830e91f61 100644 --- a/mysql-test/main/selectivity_no_engine.result +++ b/mysql-test/main/selectivity_no_engine.result @@ -294,6 +294,26 @@ SELECT * FROM t1 WHERE t1.d = 0 AND t1.p = '1' AND t1.i != '-1' AND t1.n = 'some i n d p set optimizer_use_condition_selectivity= @tmp_mdev8779; DROP TABLE t1; +# +# MDEV-23937: SIGSEGV in looped best_extension_by_limited_search from greedy_search +# (Testcase only) +# +set +@tmp_jcl= @@join_cache_level, +@tmp_ucs= @@optimizer_use_condition_selectivity; +set +join_cache_level=3, +optimizer_use_condition_selectivity=2; +CREATE TABLE t1 AS SELECT * FROM mysql.user; +CREATE TABLE t3 (b VARCHAR (1)); +CREATE TABLE t2 (c2 INT); +INSERT INTO t2 VALUES (1); +EXPLAIN +SELECT * FROM t1 AS a NATURAL JOIN t1 AS b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE a ALL NULL NULL NULL NULL 5 Using where +1 SIMPLE b hash_ALL NULL #hash#$hj 612 test.a.Host,test.a.User,test.a.Password,test.a.Select_priv,test.a.Insert_priv,test.a.Update_priv,test.a.Delete_priv,test.a.Create_priv,test.a.Drop_priv,test.a.Reload_priv,test.a.Shutdown_priv,test.a.Process_priv,test.a.File_priv,test.a.Grant_priv,test.a.References_priv,test.a.Index_priv,test.a.Alter_priv,test.a.Show_db_priv,test.a.Super_priv,test.a.Create_tmp_table_priv,test.a.Lock_tables_priv,test.a.Execute_priv,test.a.Repl_slave_priv,test.a.Repl_client_priv,test.a.Create_view_priv,test.a.Show_view_priv,test.a.Create_routine_priv,test.a.Alter_routine_priv,test.a.Create_user_priv,test.a.Event_priv,test.a.Trigger_priv,test.a.Create_tablespace_priv,test.a.Delete_history_priv,test.a.ssl_type,test.a.ssl_cipher,test.a.x509_issuer,test.a.x509_subject,test.a.max_questions,test.a.max_updates,test.a.max_connections,test.a.max_user_connections,test.a.plugin,test.a.authentication_string,test.a.password_expired,test.a.is_role,test.a.default_role,test.a.max_statement_time 5 Using where; Using join buffer (flat, BNLH join) +DROP TABLE t1,t2,t3; # # End of the test file # diff --git a/mysql-test/main/selectivity_no_engine.test b/mysql-test/main/selectivity_no_engine.test index c0f41ca7fb2..5bc78e03781 100644 --- a/mysql-test/main/selectivity_no_engine.test +++ b/mysql-test/main/selectivity_no_engine.test @@ -229,6 +229,27 @@ SELECT * FROM t1 WHERE t1.d = 0 AND t1.p = '1' AND t1.i != '-1' AND t1.n = 'some set optimizer_use_condition_selectivity= @tmp_mdev8779; DROP TABLE t1; +--echo # +--echo # MDEV-23937: SIGSEGV in looped best_extension_by_limited_search from greedy_search +--echo # (Testcase only) +--echo # +set + @tmp_jcl= @@join_cache_level, + @tmp_ucs= @@optimizer_use_condition_selectivity; +set + join_cache_level=3, + optimizer_use_condition_selectivity=2; + +CREATE TABLE t1 AS SELECT * FROM mysql.user; +CREATE TABLE t3 (b VARCHAR (1)); +CREATE TABLE t2 (c2 INT); +INSERT INTO t2 VALUES (1); + +EXPLAIN +SELECT * FROM t1 AS a NATURAL JOIN t1 AS b; + +DROP TABLE t1,t2,t3; + --echo # --echo # End of the test file --echo # diff --git a/mysql-test/main/shutdown_not_windows.combinations b/mysql-test/main/shutdown_not_windows.combinations new file mode 100644 index 00000000000..684d4cfd61d --- /dev/null +++ b/mysql-test/main/shutdown_not_windows.combinations @@ -0,0 +1,5 @@ +[1tpc] +--thread-handling=one-thread-per-connection + +[pot] +--thread-handling=pool-of-threads diff --git a/mysql-test/main/shutdown_not_windows.result b/mysql-test/main/shutdown_not_windows.result new file mode 100644 index 00000000000..524cdf20fa2 --- /dev/null +++ b/mysql-test/main/shutdown_not_windows.result @@ -0,0 +1,8 @@ +# +# MDEV-18353 Shutdown may miss to wait for connection thread +# +call mtr.add_suppression('Thread .* did not exit'); +set @old_dbug=@@global.debug_dbug; +set global debug_dbug='+d,CONNECT_wait'; +select variable_value into @cons from information_schema.global_status where variable_name='connections'; +# restart diff --git a/mysql-test/main/shutdown_not_windows.test b/mysql-test/main/shutdown_not_windows.test new file mode 100644 index 00000000000..e93867e2227 --- /dev/null +++ b/mysql-test/main/shutdown_not_windows.test @@ -0,0 +1,14 @@ +source include/not_windows.inc; +source include/not_embedded.inc; +source include/have_debug.inc; +--echo # +--echo # MDEV-18353 Shutdown may miss to wait for connection thread +--echo # +call mtr.add_suppression('Thread .* did not exit'); +set @old_dbug=@@global.debug_dbug; +set global debug_dbug='+d,CONNECT_wait'; +select variable_value into @cons from information_schema.global_status where variable_name='connections'; +exec $MYSQL -e 'select sleep(3600)' >/dev/null 2>&1 &; +let $wait_condition= select variable_value>@cons from information_schema.global_status where variable_name='connections'; +source include/wait_condition.inc; +source include/restart_mysqld.inc; diff --git a/mysql-test/main/skip_name_resolve.result b/mysql-test/main/skip_name_resolve.result index 9a903ebf472..fe71b714cbc 100644 --- a/mysql-test/main/skip_name_resolve.result +++ b/mysql-test/main/skip_name_resolve.result @@ -39,4 +39,24 @@ SET @@LOCAL.skip_name_resolve=0; ERROR HY000: Variable 'skip_name_resolve' is a read only variable SET @@GLOBAL.skip_name_resolve=0; ERROR HY000: Variable 'skip_name_resolve' is a read only variable -End of 5.1 tests +# +# End of 5.1 tests +# +# +# MDEV-26081 set role crashes when a hostname cannot be resolved +# +create user u1@`%`; +create role r1; +create role r2; +grant r2 to r1; +grant r1 to u1@`%`; +connect u1,127.0.0.1,u1,,,$MASTER_MYPORT; +set role r2; +ERROR OP000: User `u1`@`%` has not been granted role `r2` +disconnect u1; +connection default; +drop user u1@`%`; +drop role r1, r2; +# +# End of 10.2 tests +# diff --git a/mysql-test/main/skip_name_resolve.test b/mysql-test/main/skip_name_resolve.test index b0c5118f970..0ff19092b82 100644 --- a/mysql-test/main/skip_name_resolve.test +++ b/mysql-test/main/skip_name_resolve.test @@ -50,4 +50,28 @@ SET @@LOCAL.skip_name_resolve=0; --error ER_INCORRECT_GLOBAL_LOCAL_VAR SET @@GLOBAL.skip_name_resolve=0; ---echo End of 5.1 tests +--echo # +--echo # End of 5.1 tests +--echo # + +--echo # +--echo # MDEV-26081 set role crashes when a hostname cannot be resolved +--echo # + +create user u1@`%`; +create role r1; +create role r2; +grant r2 to r1; +grant r1 to u1@`%`; + +connect u1,127.0.0.1,u1,,,$MASTER_MYPORT; +error ER_INVALID_ROLE; +set role r2; +disconnect u1; +connection default; +drop user u1@`%`; +drop role r1, r2; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/main/ssl_cipher.opt b/mysql-test/main/ssl_cipher.opt new file mode 100644 index 00000000000..6545e04ba5f --- /dev/null +++ b/mysql-test/main/ssl_cipher.opt @@ -0,0 +1 @@ +--loose-tls-version=TLSv1.0,TLSv1.1,TLSv1.2 diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result index 1b41a6bab96..8b5df420269 100644 --- a/mysql-test/main/table_value_constr.result +++ b/mysql-test/main/table_value_constr.result @@ -3060,6 +3060,44 @@ a 2 3 drop table t1; +# +# MDEV-25484: Derived table using TVC with LIMIT and ORDER BY +# +create table t1 (a int); +insert into t1 values (3), (7), (1); +select * from ( (select * from t1 limit 2) order by 1 desc) as dt; +a +3 +7 +(values (3), (7), (1) limit 2) order by 1 desc; +3 +7 +3 +select * from ( (values (3), (7), (1) limit 2) order by 1 desc) as dt; +3 +3 +7 +select * from ( select * from t1 order by 1 limit 2 ) as dt; +a +1 +3 +values (3),(7),(1) order by 1 limit 2; +3 +1 +3 +select * from ( values (3),(7),(1) order by 1 limit 2 ) as dt; +3 +1 +3 +values (3),(7),(1) union values (2),(4) order by 1 limit 2; +3 +1 +2 +select * from (values (3),(7),(1) union values (2),(4) order by 1 limit 2) as dt; +3 +1 +2 +drop table t1; End of 10.3 tests # # MDEV-22610 Crash in INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT)) diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test index ddc949d8c00..b3881a77d0e 100644 --- a/mysql-test/main/table_value_constr.test +++ b/mysql-test/main/table_value_constr.test @@ -1628,6 +1628,28 @@ select * from t1; drop table t1; + +--echo # +--echo # MDEV-25484: Derived table using TVC with LIMIT and ORDER BY +--echo # + +create table t1 (a int); +insert into t1 values (3), (7), (1); + +select * from ( (select * from t1 limit 2) order by 1 desc) as dt; +(values (3), (7), (1) limit 2) order by 1 desc; +select * from ( (values (3), (7), (1) limit 2) order by 1 desc) as dt; + + +select * from ( select * from t1 order by 1 limit 2 ) as dt; +values (3),(7),(1) order by 1 limit 2; +select * from ( values (3),(7),(1) order by 1 limit 2 ) as dt; + +values (3),(7),(1) union values (2),(4) order by 1 limit 2; +select * from (values (3),(7),(1) union values (2),(4) order by 1 limit 2) as dt; + +drop table t1; + --echo End of 10.3 tests --echo # diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result index 52bc3ccb0dc..fb1a2e35eb2 100644 --- a/mysql-test/main/union.result +++ b/mysql-test/main/union.result @@ -1612,7 +1612,7 @@ NULL binary(0) YES NULL CREATE TABLE t5 SELECT NULL UNION SELECT NULL; DESC t5; Field Type Null Key Default Extra -NULL null YES NULL +NULL binary(0) YES NULL CREATE TABLE t6 SELECT * FROM (SELECT * FROM (SELECT NULL)a) b UNION SELECT a FROM t1; DESC t6; @@ -2650,5 +2650,34 @@ CAST(1 AS UNSIGNED) 1 1 # +# MDEV-24511 null field is created with CREATE..SELECT +# +set @save_default_storage_engine=@@default_storage_engine; +SET @@default_storage_engine=MEMORY; +CREATE TABLE t1 SELECT NULL UNION SELECT NULL; +ALTER TABLE t1 ADD INDEX (`PRIMARY`); +ERROR 42000: Key column 'PRIMARY' doesn't exist in table +CREATE TABLE t2 SELECT NULL; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `NULL` binary(0) DEFAULT NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +CREATE TABLE t3 SELECT NULL UNION SELECT NULL; +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `NULL` binary(0) DEFAULT NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +CREATE OR REPLACE TABLE t4 SELECT NULL UNION SELECT NULL; +SHOW CREATE TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `NULL` binary(0) DEFAULT NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +ALTER TABLE t4 ADD INDEX (`NULL`); +DROP TABLE t1, t2, t3, t4; +set @@default_storage_engine=@save_default_storage_engine; +# # End of 10.3 tests # diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test index 2e5a04a27f4..a7adc347a53 100644 --- a/mysql-test/main/union.test +++ b/mysql-test/main/union.test @@ -1884,5 +1884,30 @@ SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT CAST(1 AS SIGNED); --enable_ps_protocol --echo # +--echo # MDEV-24511 null field is created with CREATE..SELECT +--echo # + +set @save_default_storage_engine=@@default_storage_engine; +SET @@default_storage_engine=MEMORY; + +CREATE TABLE t1 SELECT NULL UNION SELECT NULL; +--error ER_KEY_COLUMN_DOES_NOT_EXITS +ALTER TABLE t1 ADD INDEX (`PRIMARY`); + +CREATE TABLE t2 SELECT NULL; +SHOW CREATE TABLE t2; + +CREATE TABLE t3 SELECT NULL UNION SELECT NULL; +SHOW CREATE TABLE t3; + +CREATE OR REPLACE TABLE t4 SELECT NULL UNION SELECT NULL; +SHOW CREATE TABLE t4; +ALTER TABLE t4 ADD INDEX (`NULL`); + +DROP TABLE t1, t2, t3, t4; + +set @@default_storage_engine=@save_default_storage_engine; + +--echo # --echo # End of 10.3 tests --echo # diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index c2b3c30011f..095936f8b82 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -3912,6 +3912,293 @@ sum(i) over () IN ( SELECT 1 FROM t1 a) 0 DROP TABLE t1; # +# MDEV-25565: 2-nd call of SP with SELECT from view / derived table / CTE +# returning the result of calculation of 2 window +# functions that use the same window specification +# +create table t1 (a int); +insert into t1 values (3), (7), (1), (7), (1), (1), (3), (1), (5); +create view v2 as select a from t1 group by a; +create view v1 as select * from v2; +create procedure sp1() select v1.a, +sum(v1.a) over (partition by v1.a order by v1.a) as k, +avg(v1.a) over (partition by v1.a order by v1.a) as m +from v1; +call sp1(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp1(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "select v1.a, +sum(v1.a) over (partition by v1.a order by v1.a) as k, +avg(v1.a) over (partition by v1.a order by v1.a) as m +from v1"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp2() select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from (select * from v2) as dt1 +) as dt; +call sp2(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp2(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from (select * from v2) as dt1 +) as dt"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp3() select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from ( select * from (select * from t1 group by a) as dt2 ) as dt1 +) as dt; +call sp3(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp3(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from ( select * from (select * from t1 group by a) as dt2 ) as dt1 +) as dt"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp4() with cte1 as (select * from (select * from t1 group by a) as dt2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp4(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp4(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with cte1 as (select * from (select * from t1 group by a) as dt2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp5() with cte1 as (select * from v2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp5(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp5(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with cte1 as (select * from v2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp6() with +cte1 as (with cte2 as (select * from t1 group by a) select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp6(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp6(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with +cte1 as (with cte2 as (select * from t1 group by a) select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp7() with +cte2 as (select * from v1), +cte1 as (select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp7(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp7(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with +cte2 as (select * from v1), +cte1 as (select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +drop procedure sp1; +drop procedure sp2; +drop procedure sp3; +drop procedure sp4; +drop procedure sp5; +drop procedure sp6; +drop procedure sp7; +drop view v1,v2; +drop table t1; +# # End of 10.2 tests # # diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index 778c685b680..43133386461 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -2556,6 +2556,153 @@ SELECT sum(i) over () IN ( SELECT 1 FROM t1 a) FROM t1; DROP TABLE t1; --echo # +--echo # MDEV-25565: 2-nd call of SP with SELECT from view / derived table / CTE +--echo # returning the result of calculation of 2 window +--echo # functions that use the same window specification +--echo # + +create table t1 (a int); +insert into t1 values (3), (7), (1), (7), (1), (1), (3), (1), (5); + +create view v2 as select a from t1 group by a; +create view v1 as select * from v2; + +let $q1= +select v1.a, + sum(v1.a) over (partition by v1.a order by v1.a) as k, + avg(v1.a) over (partition by v1.a order by v1.a) as m +from v1; + +eval create procedure sp1() $q1; +call sp1(); +call sp1(); + +eval prepare stmt from "$q1"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +let $q2= +select * from + ( select dt1.a, + sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, + avg(dt1.a) over (partition by dt1.a order by dt1.a) as m + from (select * from v2) as dt1 + ) as dt; + +eval create procedure sp2() $q2; +call sp2(); +call sp2(); + +eval prepare stmt from "$q2"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +let $q3= +select * from + ( select dt1.a, + sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, + avg(dt1.a) over (partition by dt1.a order by dt1.a) as m + from ( select * from (select * from t1 group by a) as dt2 ) as dt1 + ) as dt; + +eval create procedure sp3() $q3; +call sp3(); +call sp3(); + +eval prepare stmt from "$q3"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +let $q4= +with cte1 as (select * from (select * from t1 group by a) as dt2), + cte as + ( select cte1.a, + sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, + avg(cte1.a) over (partition by cte1.a order by cte1.a) as m + from cte1 ) +select * from cte; + +eval create procedure sp4() $q4; +call sp4(); +call sp4(); + +eval prepare stmt from "$q4"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +let $q5= +with cte1 as (select * from v2), + cte as + ( select cte1.a, + sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, + avg(cte1.a) over (partition by cte1.a order by cte1.a) as m + from cte1 ) +select * from cte; + +eval create procedure sp5() $q5; +call sp5(); +call sp5(); + +eval prepare stmt from "$q5"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +let $q6= +with +cte1 as (with cte2 as (select * from t1 group by a) select * from cte2), + cte as + ( select cte1.a, + sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, + avg(cte1.a) over (partition by cte1.a order by cte1.a) as m + from cte1 ) +select * from cte; + +eval create procedure sp6() $q6; +call sp6(); +call sp6(); + +eval prepare stmt from "$q6"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +let $q7= +with + cte2 as (select * from v1), + cte1 as (select * from cte2), + cte as + ( select cte1.a, + sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, + avg(cte1.a) over (partition by cte1.a order by cte1.a) as m + from cte1 ) +select * from cte; + +eval create procedure sp7() $q7; +call sp7(); +call sp7(); + +eval prepare stmt from "$q7"; +execute stmt; +execute stmt; +deallocate prepare stmt; + + +drop procedure sp1; +drop procedure sp2; +drop procedure sp3; +drop procedure sp4; +drop procedure sp5; +drop procedure sp6; +drop procedure sp7; +drop view v1,v2; +drop table t1; + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 65254bf653c..dbe5fc4d650 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2719,7 +2719,9 @@ sub mysql_server_start($) { if (!$opt_embedded_server) { - mysqld_start($mysqld,$extra_opts); + mysqld_start($mysqld, $extra_opts) or + mtr_error("Failed to start mysqld ".$mysqld->name()." with command " + . $ENV{MYSQLD_LAST_CMD}); # Save this test case information, so next can examine it $mysqld->{'started_tinfo'}= $tinfo; @@ -2742,10 +2744,10 @@ sub mysql_server_start($) { sub mysql_server_wait { my ($mysqld, $tinfo) = @_; + my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect"; - if (!sleep_until_file_created($mysqld->value('pid-file'), - $opt_start_timeout, - $mysqld->{'proc'}, + if (!sleep_until_file_created($mysqld->value('pid-file'), $expect_file, + $opt_start_timeout, $mysqld->{'proc'}, $warn_seconds)) { $tinfo->{comment}= "Failed to start ".$mysqld->name() . "\n"; @@ -4059,9 +4061,12 @@ sub run_testcase ($$) { # ---------------------------------------------------- # Check if it was an expected crash # ---------------------------------------------------- - my $check_crash = check_expected_crash_and_restart($wait_for_proc); + my @mysqld = grep($wait_for_proc eq $_->{proc}, mysqlds()); + goto SRVDIED unless @mysqld; + my $check_crash = check_expected_crash_and_restart($mysqld[0]); if ($check_crash == 0) # unexpected exit/crash of $wait_for_proc { + $proc= $mysqld[0]->{proc}; goto SRVDIED; } elsif ($check_crash == 1) # $wait_for_proc was started again by check_expected_crash_and_restart() @@ -4629,61 +4634,52 @@ sub check_warnings_post_shutdown { } # -# Loop through our list of processes and look for and entry -# with the provided pid, if found check for the file indicating -# expected crash and restart it. +# Check for the file indicating expected crash and restart it. # sub check_expected_crash_and_restart { - my ($proc)= @_; + my $mysqld = shift; - foreach my $mysqld ( mysqlds() ) + # Check if crash expected by looking at the .expect file + # in var/tmp + my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect"; + if ( -f $expect_file ) { - next unless ( $mysqld->{proc} and $mysqld->{proc} eq $proc ); + mtr_verbose("Crash was expected, file '$expect_file' exists"); - # Check if crash expected by looking at the .expect file - # in var/tmp - my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect"; - if ( -f $expect_file ) + for (my $waits = 0; $waits < 50; mtr_milli_sleep(100), $waits++) { - mtr_verbose("Crash was expected, file '$expect_file' exists"); - - for (my $waits = 0; $waits < 50; mtr_milli_sleep(100), $waits++) + # Race condition seen on Windows: try again until file not empty + next if -z $expect_file; + # If last line in expect file starts with "wait" + # sleep a little and try again, thus allowing the + # test script to control when the server should start + # up again. Keep trying for up to 5s at a time. + my $last_line= mtr_lastlinesfromfile($expect_file, 1); + if ($last_line =~ /^wait/ ) { - # Race condition seen on Windows: try again until file not empty - next if -z $expect_file; - # If last line in expect file starts with "wait" - # sleep a little and try again, thus allowing the - # test script to control when the server should start - # up again. Keep trying for up to 5s at a time. - my $last_line= mtr_lastlinesfromfile($expect_file, 1); - if ($last_line =~ /^wait/ ) - { - mtr_verbose("Test says wait before restart") if $waits == 0; - next; - } - - # Ignore any partial or unknown command - next unless $last_line =~ /^restart/; - # If last line begins "restart:", the rest of the line is read as - # extra command line options to add to the restarted mysqld. - # Anything other than 'wait' or 'restart:' (with a colon) will - # result in a restart with original mysqld options. - if ($last_line =~ /restart:(.+)/) { - my @rest_opt= split(' ', $1); - $mysqld->{'restart_opts'}= \@rest_opt; - } else { - delete $mysqld->{'restart_opts'}; - } - unlink($expect_file); - - # Start server with same settings as last time - mysqld_start($mysqld, $mysqld->{'started_opts'}); + mtr_verbose("Test says wait before restart") if $waits == 0; + next; + } - return 1; + # Ignore any partial or unknown command + next unless $last_line =~ /^restart/; + # If last line begins "restart:", the rest of the line is read as + # extra command line options to add to the restarted mysqld. + # Anything other than 'wait' or 'restart:' (with a colon) will + # result in a restart with original mysqld options. + if ($last_line =~ /restart:(.+)/) { + my @rest_opt= split(' ', $1); + $mysqld->{'restart_opts'}= \@rest_opt; + } else { + delete $mysqld->{'restart_opts'}; } - # Loop ran through: we should keep waiting after a re-check - return 2; + unlink($expect_file); + + # Start server with same settings as last time + return mysqld_start($mysqld, $mysqld->{'started_opts'}); } + # Loop ran through: we should keep waiting after a re-check + return 2; } # Not an expected crash @@ -5040,6 +5036,7 @@ sub mysqld_start ($$) { if ( defined $exe ) { + mtr_tofile($output, "\$ $exe @$args\n"); pre_write_errorlog($output); $mysqld->{'proc'}= My::SafeProcess->new ( @@ -5058,17 +5055,11 @@ sub mysqld_start ($$) { mtr_verbose("Started $mysqld->{proc}"); } - if (!sleep_until_file_created($mysqld->value('pid-file'), - $opt_start_timeout, $mysqld->{'proc'}, $warn_seconds)) - { - my $mname= $mysqld->name(); - mtr_error("Failed to start mysqld $mname with command $exe"); - } - - # Remember options used when starting $mysqld->{'started_opts'}= $extra_opts; - return; + my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect"; + return sleep_until_file_created($mysqld->value('pid-file'), $expect_file, + $opt_start_timeout, $mysqld->{'proc'}, $warn_seconds); } diff --git a/mysql-test/suite/binlog/include/binlog.test b/mysql-test/suite/binlog/include/binlog.test index 368dcebc5f1..9f3288b52f0 100644 --- a/mysql-test/suite/binlog/include/binlog.test +++ b/mysql-test/suite/binlog/include/binlog.test @@ -406,4 +406,22 @@ SHOW SESSION VARIABLES LIKE "unique_checks"; DROP TABLE t1; disconnect fresh; +connection default; +--echo # +--echo # MDEV-25595 DROP part of failed CREATE OR REPLACE is not written into binary log +--echo # +reset master; +--error ER_DUP_FIELDNAME +create table t as select 1 as b, 2 as b; +create table t (old_table_field int); +--error ER_DUP_FIELDNAME +create or replace table t as select 1 as b, 2 as b; +--error ER_DUP_FIELDNAME +create or replace temporary table t as select 1 as b, 2 as b; +create table t (new_table_field int); + +--source include/show_binlog_events.inc + +# cleanup +drop table t; diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index 7715d0e0325..a1622c138ee 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -1073,3 +1073,26 @@ Variable_name Value unique_checks OFF DROP TABLE t1; disconnect fresh; +connection default; +# +# MDEV-25595 DROP part of failed CREATE OR REPLACE is not written into binary log +# +reset master; +create table t as select 1 as b, 2 as b; +ERROR 42S21: Duplicate column name 'b' +create table t (old_table_field int); +create or replace table t as select 1 as b, 2 as b; +ERROR 42S21: Duplicate column name 'b' +create or replace temporary table t as select 1 as b, 2 as b; +ERROR 42S21: Duplicate column name 'b' +create table t (new_table_field int); +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t (old_table_field int) +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t`/* Generated to handle failed CREATE OR REPLACE */ +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t (new_table_field int) +drop table t; diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index ad14a31381d..7071cb3ba43 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -669,3 +669,27 @@ Variable_name Value unique_checks OFF DROP TABLE t1; disconnect fresh; +connection default; +# +# MDEV-25595 DROP part of failed CREATE OR REPLACE is not written into binary log +# +reset master; +create table t as select 1 as b, 2 as b; +ERROR 42S21: Duplicate column name 'b' +create table t (old_table_field int); +create or replace table t as select 1 as b, 2 as b; +ERROR 42S21: Duplicate column name 'b' +create or replace temporary table t as select 1 as b, 2 as b; +ERROR 42S21: Duplicate column name 'b' +create table t (new_table_field int); +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t (old_table_field int) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t`/* Generated to handle failed CREATE OR REPLACE */ +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t`/* Generated to handle failed CREATE OR REPLACE */ +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t (new_table_field int) +drop table t; diff --git a/mysql-test/suite/binlog_encryption/encrypted_master.test b/mysql-test/suite/binlog_encryption/encrypted_master.test index f67e93ce815..f6fc172c79e 100644 --- a/mysql-test/suite/binlog_encryption/encrypted_master.test +++ b/mysql-test/suite/binlog_encryption/encrypted_master.test @@ -18,6 +18,9 @@ # - with annotated events, default checksums and minimal binlog row image # +# The test can take very long time with valgrind +--source include/not_valgrind.inc + --source include/have_partition.inc --source encryption_algorithms.inc --source include/have_innodb.inc diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index 977bb0101fd..4cf31200ee2 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -3918,6 +3918,293 @@ sum(i) over () IN ( SELECT 1 FROM t1 a) 0 DROP TABLE t1; # +# MDEV-25565: 2-nd call of SP with SELECT from view / derived table / CTE +# returning the result of calculation of 2 window +# functions that use the same window specification +# +create table t1 (a int); +insert into t1 values (3), (7), (1), (7), (1), (1), (3), (1), (5); +create view v2 as select a from t1 group by a; +create view v1 as select * from v2; +create procedure sp1() select v1.a, +sum(v1.a) over (partition by v1.a order by v1.a) as k, +avg(v1.a) over (partition by v1.a order by v1.a) as m +from v1; +call sp1(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp1(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "select v1.a, +sum(v1.a) over (partition by v1.a order by v1.a) as k, +avg(v1.a) over (partition by v1.a order by v1.a) as m +from v1"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp2() select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from (select * from v2) as dt1 +) as dt; +call sp2(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp2(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from (select * from v2) as dt1 +) as dt"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp3() select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from ( select * from (select * from t1 group by a) as dt2 ) as dt1 +) as dt; +call sp3(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp3(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from ( select * from (select * from t1 group by a) as dt2 ) as dt1 +) as dt"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp4() with cte1 as (select * from (select * from t1 group by a) as dt2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp4(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp4(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with cte1 as (select * from (select * from t1 group by a) as dt2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp5() with cte1 as (select * from v2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp5(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp5(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with cte1 as (select * from v2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp6() with +cte1 as (with cte2 as (select * from t1 group by a) select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp6(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp6(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with +cte1 as (with cte2 as (select * from t1 group by a) select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp7() with +cte2 as (select * from v1), +cte1 as (select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp7(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp7(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with +cte2 as (select * from v1), +cte1 as (select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +drop procedure sp1; +drop procedure sp2; +drop procedure sp3; +drop procedure sp4; +drop procedure sp5; +drop procedure sp6; +drop procedure sp7; +drop view v1,v2; +drop table t1; +# # End of 10.2 tests # # diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption.test b/mysql-test/suite/encryption/t/innodb-page_encryption.test index df2d1d52aaa..d756f07aea0 100644 --- a/mysql-test/suite/encryption/t/innodb-page_encryption.test +++ b/mysql-test/suite/encryption/t/innodb-page_encryption.test @@ -1,6 +1,9 @@ -- source include/have_innodb.inc -- source include/have_file_key_management_plugin.inc +# The test can take very long time with valgrind +--source include/not_valgrind.inc + create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; show warnings; create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; diff --git a/mysql-test/suite/galera/r/MDEV-22051.result b/mysql-test/suite/galera/r/MDEV-22051.result index 9f5394637c2..0e9756dd20e 100644 --- a/mysql-test/suite/galera/r/MDEV-22051.result +++ b/mysql-test/suite/galera/r/MDEV-22051.result @@ -2,14 +2,14 @@ connection node_2; connection node_1; FLUSH TABLES WITH READ LOCK; CREATE TABLE t1 (a INT) ENGINE=InnoDB; -ERROR 08S01: Aborting TOI: Global Read-Lock (FTWRL) in place. +ERROR 08S01: Aborting TOI: Replication paused on node for FTWRL/BACKUP STAGE. SET wsrep_OSU_method=RSU; CREATE TABLE t1 (a INT) ENGINE=InnoDB; -ERROR 08S01: Aborting TOI: Global Read-Lock (FTWRL) in place. +ERROR 08S01: Aborting TOI: Replication paused on node for FTWRL/BACKUP STAGE. SET wsrep_OSU_method=TOI; connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; CREATE TABLE t1 (a INT) ENGINE=InnoDB; -ERROR 08S01: Aborting TOI: Global Read-Lock (FTWRL) in place. +ERROR 08S01: Aborting TOI: Replication paused on node for FTWRL/BACKUP STAGE. connection node_1; UNLOCK TABLES; CREATE TABLE t1 (a INT) ENGINE=InnoDB; diff --git a/mysql-test/suite/galera/r/MDEV-22421.result b/mysql-test/suite/galera/r/MDEV-22421.result new file mode 100644 index 00000000000..33dc3e449ae --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-22421.result @@ -0,0 +1,7 @@ +connection node_2; +connection node_1; +SET @@local.sql_mode='no_field_options'; +CREATE TABLE t1 (f1 INT, ROW_START BIGINT UNSIGNED AS ROW START INVISIBLE, ROW_END BIGINT UNSIGNED AS ROW END INVISIBLE, PERIOD FOR SYSTEM_TIME(ROW_START, ROW_END)) WITH SYSTEM VERSIONING ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +UPDATE t1 SET f1 = 1 WHERE f1 = 1; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/MDEV-25740.result b/mysql-test/suite/galera/r/MDEV-25740.result new file mode 100644 index 00000000000..5a4318a7f19 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-25740.result @@ -0,0 +1,9 @@ +connection node_2; +connection node_1; +SET AUTOCOMMIT = OFF; +SET completion_type = CHAIN; +CREATE TABLE t1(f1 INT) ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 VALUES (1); +ROLLBACK; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_backup_stage.result b/mysql-test/suite/galera/r/galera_backup_stage.result new file mode 100644 index 00000000000..6fb7d1643cd --- /dev/null +++ b/mysql-test/suite/galera/r/galera_backup_stage.result @@ -0,0 +1,78 @@ +connection node_2; +connection node_1; +connection node_1; +CREATE TABLE t1 (f1 varchar(10)) ENGINE=InnoDB; +BACKUP STAGE START; +BACKUP STAGE FLUSH; +BACKUP STAGE END; +BACKUP STAGE START; +BACKUP STAGE FLUSH; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1a; +SET SESSION wsrep_sync_wait=0; +SET SESSION wsrep_retry_autocommit=0; +INSERT INTO t1 (f1) values ("node1_1"); +ALTER TABLE t1 ADD COLUMN (f2 int(10)); +connection node_2; +INSERT INTO t1 (f1) values ("node2_1"); +ALTER TABLE t1 ADD COLUMN (f3 int(10)); +connection node_1; +BACKUP STAGE BLOCK_DDL; +connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1c; +SET SESSION wsrep_sync_wait=0; +connection node_2; +INSERT INTO t1 (f1) values("node2_2"); +ALTER TABLE t1 ADD COLUMN (f5 int(10)); +connection node_1a; +ALTER TABLE t1 ADD COLUMN (f4 int(10)); +ERROR 08S01: Aborting TOI: Replication paused on node for FTWRL/BACKUP STAGE. +INSERT INTO t1 (f1) values("node1a");; +connection node_1c; +connection node_1; +BACKUP STAGE BLOCK_COMMIT; +connection node_1c; +SELECT variable_value="Donor/Desynced" FROM information_schema.global_status WHERE variable_name="wsrep_local_state_comment"; +variable_value="Donor/Desynced" +1 +connection node_2; +INSERT INTO t1 (f1) values("node2_3"); +ALTER TABLE t1 ADD COLUMN (f6 int(10)); +connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1b; +SET SESSION wsrep_sync_wait=0; +SET SESSION wsrep_retry_autocommit=0; +ALTER TABLE t1 ADD COLUMN (f4 int(10)); +ERROR 08S01: Aborting TOI: Replication paused on node for FTWRL/BACKUP STAGE. +INSERT INTO t1 (f1) values("node1b");; +connection node_1c; +SELECT COUNT(*)=2 FROM t1; +COUNT(*)=2 +1 +SELECT COUNT(*)=3 FROM information_schema.columns WHERE table_name = 't1'; +COUNT(*)=3 +1 +connection node_1; +BACKUP STAGE END; +connection node_1a; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +connection node_1b; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +connection node_1; +SELECT COUNT(*)=4 FROM t1; +COUNT(*)=4 +1 +SELECT COUNT(*)=5 FROM information_schema.columns WHERE table_name = 't1'; +COUNT(*)=5 +1 +connection node_2; +SELECT COUNT(*)=4 FROM t1; +COUNT(*)=4 +1 +SELECT COUNT(*)=5 FROM information_schema.columns WHERE table_name = 't1'; +COUNT(*)=5 +1 +connection node_1; +DROP TABLE t1; +call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); +call mtr.add_suppression("greater than drain seqno"); diff --git a/mysql-test/suite/galera/r/galera_fk_lock_wait.result b/mysql-test/suite/galera/r/galera_fk_lock_wait.result new file mode 100644 index 00000000000..0d87aa2aa57 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_fk_lock_wait.result @@ -0,0 +1,54 @@ +connection node_2; +connection node_1; +CREATE TABLE parent(parent_id int not null AUTO_INCREMENT PRIMARY KEY, +parent_name varchar(80)) ENGINE=InnoDB; +CREATE TABLE child(child_id int not null AUTO_INCREMENT PRIMARY KEY, +child_name varchar(80), +child_parent_id int not null, +CONSTRAINT `fk_child_parent` + FOREIGN KEY (child_parent_id) REFERENCES parent (parent_id) +ON DELETE CASCADE +ON UPDATE CASCADE) ENGINE=InnoDB; +INSERT INTO parent VALUES (1, 'first'),(2,'second'),(3,'foo'),(4,'tmp'); +INSERT INTO child VALUES (NULL,'first_child',1); +INSERT INTO child VALUES (NULL,'second_child',1); +INSERT INTO child VALUES (NULL,'first_child2',2); +INSERT INTO child VALUES (NULL,'first_child3',2); +INSERT INTO child VALUES (NULL,'first_child4',3); +BEGIN; +UPDATE parent SET parent_name = 'bar' WHERE parent_id = 2; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET SESSION innodb_lock_wait_timeout=2; +UPDATE child SET child_parent_id = 5 where child_parent_id = 2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +connection node_1; +COMMIT; +SELECT * FROM parent; +parent_id parent_name +1 first +2 bar +3 foo +4 tmp +SELECT * FROM child; +child_id child_name child_parent_id +1 first_child 1 +3 second_child 1 +5 first_child2 2 +7 first_child3 2 +9 first_child4 3 +connection node_2; +SELECT * FROM parent; +parent_id parent_name +1 first +2 bar +3 foo +4 tmp +SELECT * FROM child; +child_id child_name child_parent_id +1 first_child 1 +3 second_child 1 +5 first_child2 2 +7 first_child3 2 +9 first_child4 3 +DROP TABLE child, parent; +disconnect node_1a; diff --git a/mysql-test/suite/galera/t/MDEV-22421.test b/mysql-test/suite/galera/t/MDEV-22421.test new file mode 100644 index 00000000000..369e56384a0 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-22421.test @@ -0,0 +1,12 @@ +# +# Tables with system versioning should not append keys to wsrep. +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc + +SET @@local.sql_mode='no_field_options'; +CREATE TABLE t1 (f1 INT, ROW_START BIGINT UNSIGNED AS ROW START INVISIBLE, ROW_END BIGINT UNSIGNED AS ROW END INVISIBLE, PERIOD FOR SYSTEM_TIME(ROW_START, ROW_END)) WITH SYSTEM VERSIONING ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +UPDATE t1 SET f1 = 1 WHERE f1 = 1; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MDEV-25740.test b/mysql-test/suite/galera/t/MDEV-25740.test new file mode 100644 index 00000000000..0ea8d5f55c0 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-25740.test @@ -0,0 +1,14 @@ +# +# When `completion_type = CHAIN` is used, transaction started should not have previous writeset. +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc + +SET AUTOCOMMIT = OFF; +SET completion_type = CHAIN; +CREATE TABLE t1(f1 INT) ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 VALUES (1); +ROLLBACK; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_backup_stage.test b/mysql-test/suite/galera/t/galera_backup_stage.test new file mode 100644 index 00000000000..31d76816355 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_backup_stage.test @@ -0,0 +1,120 @@ +# +# Check that BACKUP STAGE BLOCK_DDL desyncs and pauses the node until BACKUP STAGE END: +# - Local DDLs will fail immediately +# - Local DMLs will block until resync +# - Remote txns will be applied after resync (STAGE END). +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_metadata_lock_info.inc + +--connection node_1 +CREATE TABLE t1 (f1 varchar(10)) ENGINE=InnoDB; + +# First, check that BACKUP STAGE END skipping desyncing stages is fine +BACKUP STAGE START; +BACKUP STAGE FLUSH; +BACKUP STAGE END; + +BACKUP STAGE START; +BACKUP STAGE FLUSH; + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1a +SET SESSION wsrep_sync_wait=0; +SET SESSION wsrep_retry_autocommit=0; +INSERT INTO t1 (f1) values ("node1_1"); +ALTER TABLE t1 ADD COLUMN (f2 int(10)); + +--connection node_2 +INSERT INTO t1 (f1) values ("node2_1"); +ALTER TABLE t1 ADD COLUMN (f3 int(10)); + +# BLOCK_DDL desyncs and pauses the node +--connection node_1 +BACKUP STAGE BLOCK_DDL; + +--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1c +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT variable_value="Donor/Desynced" FROM information_schema.global_status WHERE variable_name="wsrep_local_state_comment" +--source include/wait_condition.inc + +--connection node_2 +INSERT INTO t1 (f1) values("node2_2"); +ALTER TABLE t1 ADD COLUMN (f5 int(10)); + +--connection node_1a +--error ER_UNKNOWN_COM_ERROR +ALTER TABLE t1 ADD COLUMN (f4 int(10)); +--let $insert_id = `SELECT CONNECTION_ID()` +--send INSERT INTO t1 (f1) values("node1a"); + +# the insert will block during commit inside the provider, in certify. We can't +# check for sure it is blocked there, so we wait for the thread to at least +# reach commit stage. In the unlikely case the interleaving is different, the +# result of the test should not change. +--connection node_1c +--let $wait_condition = SELECT COUNT(*)=1 FROM information_schema.processlist WHERE State='Commit' AND ID=$insert_id +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*)=1 FROM information_schema.metadata_lock_info WHERE TABLE_NAME='t1' AND THREAD_ID=$insert_id +--source include/wait_condition.inc + +--connection node_1 +BACKUP STAGE BLOCK_COMMIT; + +# node only resumes/resyncs upon STAGE END +--connection node_1c +SELECT variable_value="Donor/Desynced" FROM information_schema.global_status WHERE variable_name="wsrep_local_state_comment"; + +--connection node_2 +INSERT INTO t1 (f1) values("node2_3"); +ALTER TABLE t1 ADD COLUMN (f6 int(10)); + +--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1b +SET SESSION wsrep_sync_wait=0; +SET SESSION wsrep_retry_autocommit=0; +--error ER_UNKNOWN_COM_ERROR +ALTER TABLE t1 ADD COLUMN (f4 int(10)); +--let $insert_id = `SELECT CONNECTION_ID()` +--send INSERT INTO t1 (f1) values("node1b"); + +# wait for insert to get blocked +--connection node_1c +--let $wait_condition = SELECT COUNT(*)=1 FROM information_schema.processlist WHERE State='Commit' AND ID=$insert_id +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*)=1 FROM information_schema.metadata_lock_info WHERE TABLE_NAME='t1' AND THREAD_ID=$insert_id +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*)=2 FROM information_schema.processlist WHERE Info like 'INSERT INTO t1 (f1) values("node1%")' AND State = 'Commit' +--source include/wait_condition.inc + +# nothing after BLOCK_DDL is applied +SELECT COUNT(*)=2 FROM t1; +SELECT COUNT(*)=3 FROM information_schema.columns WHERE table_name = 't1'; + +# STAGE END resumes and resyncs the node +--connection node_1 +BACKUP STAGE END; + +# Upon resume, blocked inserts will continue but conflict with the applying alters +--connection node_1a +--error ER_LOCK_DEADLOCK +--reap +--connection node_1b +--error ER_LOCK_DEADLOCK +--reap + +--connection node_1 +SELECT COUNT(*)=4 FROM t1; +SELECT COUNT(*)=5 FROM information_schema.columns WHERE table_name = 't1'; + +--connection node_2 +SELECT COUNT(*)=4 FROM t1; +SELECT COUNT(*)=5 FROM information_schema.columns WHERE table_name = 't1'; + +--connection node_1 +DROP TABLE t1; +call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); +call mtr.add_suppression("greater than drain seqno"); diff --git a/mysql-test/suite/galera/t/galera_fk_lock_wait.test b/mysql-test/suite/galera/t/galera_fk_lock_wait.test new file mode 100644 index 00000000000..150c7397f7e --- /dev/null +++ b/mysql-test/suite/galera/t/galera_fk_lock_wait.test @@ -0,0 +1,40 @@ +--source include/galera_cluster.inc + +CREATE TABLE parent(parent_id int not null AUTO_INCREMENT PRIMARY KEY, +parent_name varchar(80)) ENGINE=InnoDB; + +CREATE TABLE child(child_id int not null AUTO_INCREMENT PRIMARY KEY, +child_name varchar(80), +child_parent_id int not null, +CONSTRAINT `fk_child_parent` + FOREIGN KEY (child_parent_id) REFERENCES parent (parent_id) + ON DELETE CASCADE + ON UPDATE CASCADE) ENGINE=InnoDB; + +INSERT INTO parent VALUES (1, 'first'),(2,'second'),(3,'foo'),(4,'tmp'); +INSERT INTO child VALUES (NULL,'first_child',1); +INSERT INTO child VALUES (NULL,'second_child',1); +INSERT INTO child VALUES (NULL,'first_child2',2); +INSERT INTO child VALUES (NULL,'first_child3',2); +INSERT INTO child VALUES (NULL,'first_child4',3); + +BEGIN; +UPDATE parent SET parent_name = 'bar' WHERE parent_id = 2; + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +SET SESSION innodb_lock_wait_timeout=2; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE child SET child_parent_id = 5 where child_parent_id = 2; + +--connection node_1 +COMMIT; +SELECT * FROM parent; +SELECT * FROM child; + +--connection node_2 + +SELECT * FROM parent; +SELECT * FROM child; +DROP TABLE child, parent; + +--disconnect node_1a diff --git a/mysql-test/suite/gcol/inc/gcol_ins_upd.inc b/mysql-test/suite/gcol/inc/gcol_ins_upd.inc index 8c00bde7fca..68c0a0e30c9 100644 --- a/mysql-test/suite/gcol/inc/gcol_ins_upd.inc +++ b/mysql-test/suite/gcol/inc/gcol_ins_upd.inc @@ -613,4 +613,78 @@ DELETE FROM t1; DROP TEMPORARY TABLE t1; +--echo # +--echo # Original test case from MDEV-17890 +--echo # + +CREATE TABLE t1 ( + pk BIGINT AUTO_INCREMENT, + b BIT(15), + v BIT(10) AS (b) VIRTUAL, + PRIMARY KEY(pk), + UNIQUE(v) +); + +INSERT IGNORE INTO t1 (b) VALUES (b'101110001110100'),(b'011101'); +SELECT pk, b INTO OUTFILE 'load.data' FROM t1; +--error ER_DATA_TOO_LONG +LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b); + +# Cleanup +DROP TABLE t1; +--let $datadir= `SELECT @@datadir` +--remove_file $datadir/test/load.data + + +--echo # +--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +--echo # + +CREATE TABLE t1 ( + id INT NOT NULL AUTO_INCREMENT, + f ENUM('a','b','c'), + v ENUM('a','b','c') AS (f), + KEY(v,id) +) ENGINE=MyISAM; +INSERT INTO t1 (f) VALUES ('a'),('b'); +INSERT IGNORE INTO t1 SELECT * FROM t1; + +# Cleanup +DROP TABLE t1; + + +CREATE TABLE t1 ( + id INT NOT NULL AUTO_INCREMENT, + f ENUM('a','b','c'), + v ENUM('a','b','c') AS (f), + KEY(v,id) +) ENGINE=MyISAM; +INSERT INTO t1 (f) VALUES ('a'),('b'); +INSERT IGNORE INTO t1 SELECT * FROM t1; + +# Cleanup +DROP TABLE t1; + } + +--echo # +--echo # MDEV-23597 Assertion `marked_for_read()' failed while evaluating DEFAULT +--echo # + +CREATE TABLE t1 (a INT UNIQUE, b INT DEFAULT (c+1), c int); +INSERT INTO t1 VALUES (1,1,1); +UPDATE t1 SET b=DEFAULT; +SELECT * from t1; + +REPLACE t1 VALUES(1,1,1); +INSERT INTO t1 VALUES (1,1,1) ON DUPLICATE KEY UPDATE b= DEFAULT; +SELECT * from t1; + +REPLACE t1 VALUES(1,1,1); +CREATE TABLE t2 (a INT, b INT DEFAULT (c+1), c int); +INSERT INTO t2 VALUES (5,5,5); +UPDATE t1 join t2 set t1.b= DEFAULT, t2.b= DEFAULT; +SELECT * from t1, t2; + +DROP TABLE t1, t2; + diff --git a/mysql-test/suite/gcol/inc/gcol_keys.inc b/mysql-test/suite/gcol/inc/gcol_keys.inc index e5f7f976120..cf0612b0d0c 100644 --- a/mysql-test/suite/gcol/inc/gcol_keys.inc +++ b/mysql-test/suite/gcol/inc/gcol_keys.inc @@ -812,7 +812,7 @@ DROP TABLE t1; --echo # MDEV-19011 Assertion `file->s->base.reclength < file->s->vreclength' --echo # failed in ha_myisam::setup_vcols_for_repair -CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL) ENGINE=MyISAM; +CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL); ALTER TABLE t1 ADD KEY (a); DROP TABLE t1; diff --git a/mysql-test/suite/gcol/inc/gcol_partition.inc b/mysql-test/suite/gcol/inc/gcol_partition.inc index df199e86c68..4e4af4f0023 100644 --- a/mysql-test/suite/gcol/inc/gcol_partition.inc +++ b/mysql-test/suite/gcol/inc/gcol_partition.inc @@ -153,3 +153,19 @@ CHECK TABLE t EXTENDED; FLUSH TABLES; CHECK TABLE t EXTENDED; DROP TABLE t; + +--echo # +--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +--echo # +CREATE TABLE t1 ( + a INT, + b INT, + c BIT(4) NOT NULL DEFAULT b'0', + pk INTEGER AUTO_INCREMENT, + d BIT(4) AS (c) VIRTUAL, + PRIMARY KEY(pk), + KEY (b,d) +) PARTITION BY HASH(pk); +INSERT INTO t1 () VALUES (),(); +UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk; +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/inc/gcol_view.inc b/mysql-test/suite/gcol/inc/gcol_view.inc index 51cb9b5d725..6f9ce673199 100644 --- a/mysql-test/suite/gcol/inc/gcol_view.inc +++ b/mysql-test/suite/gcol/inc/gcol_view.inc @@ -221,3 +221,58 @@ select * from t1; drop view v1; drop table t1; + +--echo # +--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +--echo # + +CREATE TABLE t1 (d DATETIME(3), v DATETIME(2) AS (d)); +CREATE VIEW v1 AS SELECT * FROM t1; + +INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'), + ('1985-12-24 10:15:08.456'); +DELETE FROM v1 ORDER BY v LIMIT 4; + +# Cleanup +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # [duplicate] MDEV-19306 Assertion `marked_for_read()' failed in +--echo # Field_blob::val_str with virtual columns and views +--echo # + +CREATE TABLE t1 (a BLOB, b TEXT AS (a) VIRTUAL); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (a) VALUES ('foo'),('bar'); +DELETE FROM v1 ORDER BY b LIMIT 2; + +# Cleanup +DROP VIEW v1; +DROP TABLE t1; +CREATE TABLE t1 (d INT, v TINYINT AS (d)); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (d) VALUES ('2004'),('1985') ; +DELETE FROM v1 ORDER BY v LIMIT 4; + +DROP VIEW v1; +DROP TABLE t1; + + +CREATE TABLE t1 (d VARCHAR(64), v VARCHAR(63) AS (d)); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),('1985-12-24 10:15:08.456') ; +DELETE FROM v1 ORDER BY v LIMIT 4; + +DROP TABLE t1; +DROP VIEW v1; + + +--echo # +--echo # MDEV-18249 ASSERT_COLUMN_MARKED_FOR_READ failed in ANALYZE TABLE +--echo # + +create table t1 (c varchar(3) not null, v varchar(4) as (c) virtual); +insert into t1 (c) values ('a'),('b'); +analyze table t1 persistent for columns (v) indexes (); + diff --git a/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result b/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result index 3024b58da54..193ef064da8 100644 --- a/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result @@ -435,6 +435,26 @@ UPDATE t1 SET col1 = 2; UPDATE t1 SET col7 = DEFAULT; UPDATE t1 SET col8 = DEFAULT; DROP TABLE t1; +Bug#20797344: WL#8149: ALLOCATED SPACE FOR INDEXED BLOB VGC CAN BE +OVERWRITTEN FOR UPDATE +# +CREATE TABLE t (a varchar(100), b blob, +c blob GENERATED ALWAYS AS (concat(a,b)) VIRTUAL, +d blob GENERATED ALWAYS AS (b) VIRTUAL, +e int(11) GENERATED ALWAYS AS (10) VIRTUAL, +h int(11) NOT NULL, PRIMARY KEY (h), key(c(20))); +INSERT INTO t(a,b,h) VALUES('aaaaaaa','1111111', 11); +INSERT INTO t(a,b,h) VALUES('bbbbbbb','2222222', 22); +SELECT c FROM t; +c +aaaaaaa1111111 +bbbbbbb2222222 +UPDATE t SET a='ccccccc'; +SELECT c FROM t; +c +ccccccc1111111 +ccccccc2222222 +DROP TABLE t; # Bug#21081742: ASSERTION !TABLE || (!TABLE->WRITE_SET || # BITMAP_IS_SET(TABLE->WRITE_SET # @@ -491,6 +511,21 @@ SELECT * FROM t; x y gc 2 1 3 DROP TABLE t; +CREATE TABLE t ( +x INT, y INT, gc INT GENERATED ALWAYS AS (x+1), KEY (x,gc) +); +INSERT INTO t VALUES (); +UPDATE t t1, t t2 SET t1.x = 1, t2.y = 2; +SELECT * FROM t; +x y gc +1 2 2 +SELECT gc FROM t; +gc +2 +CHECK TABLE t; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; # stored CREATE TABLE C ( col_varchar_nokey VARCHAR(1), @@ -552,6 +587,100 @@ SELECT * from C; col_varchar_nokey col_varchar_key a aa DROP TABLE C; +# virtual, indexed +CREATE TABLE C ( +col_varchar_nokey VARCHAR(1), +col_varchar_key VARCHAR(2) GENERATED ALWAYS AS +(CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, +KEY (col_varchar_key, col_varchar_nokey) +); +INSERT INTO C (col_varchar_nokey) VALUES ('c'); +EXPLAIN UPDATE C AS OUTR1, C AS OUTR2 +SET OUTR1.`col_varchar_nokey` = 'f', +OUTR2.`col_varchar_nokey` = "a"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE OUTR1 ALL NULL NULL NULL NULL 1 +1 SIMPLE OUTR2 ALL NULL NULL NULL NULL 1 +UPDATE C AS OUTR1, C AS OUTR2 +SET OUTR1.`col_varchar_nokey` = 'f', +OUTR2.`col_varchar_nokey` = "a"; +SELECT * from C; +col_varchar_nokey col_varchar_key +a aa +DROP TABLE C; +# +# Bug #21530366 CRASH/ASSERTION, CORRUPTION WITH INDEXES + +# VIRTUAL COLUMNS, BLOB +# +CREATE TABLE t ( +a INTEGER, +b BLOB GENERATED ALWAYS AS (a) VIRTUAL, +INDEX (b(57)) +); +INSERT INTO t (a) VALUES (9); +UPDATE t SET a = 10; +DELETE FROM t WHERE a = 10; +DROP TABLE t; +# Bug#21807818: Generated columns not updated with empty insert list +CREATE TABLE t ( +a BLOB GENERATED ALWAYS AS ('') VIRTUAL, +b TIMESTAMP(4) GENERATED ALWAYS AS ('') VIRTUAL, +KEY (a(183),b) +); +ERROR HY000: Function or expression '''' cannot be used in the GENERATED ALWAYS AS clause of `b` +CREATE TABLE t ( +a BLOB GENERATED ALWAYS AS ('') VIRTUAL, +b TIMESTAMP(4) GENERATED ALWAYS AS ('') VIRTUAL +); +INSERT IGNORE INTO t VALUES(), (), (); +DELETE IGNORE FROM t; +DROP TABLE t; +# +# Bug#22195458:GCOLS: ASSERTION 0 AND CORRUPTION... +# +CREATE TABLE t ( +a INT, +b YEAR GENERATED ALWAYS AS ('a') VIRTUAL, +c YEAR GENERATED ALWAYS AS ('aaaa') VIRTUAL, +b1 YEAR GENERATED ALWAYS AS ('a') STORED, +c1 YEAR GENERATED ALWAYS AS ('aaaa') STORED, +UNIQUE(b), +UNIQUE(b1) +); +INSERT IGNORE INTO t VALUES(); +SELECT b from t; +b +0000 +SELECT b1 from t; +b1 +0000 +SELECT * from t; +a b c b1 c1 +NULL 0000 0000 0000 0000 +DELETE FROM t; +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; +# Bug#22195364:GCOLS: FAILING ASSERTION: +# DFIELD_IS_NULL(DFIELD2) || DFIELD2->DATA +CREATE TABLE t ( +a INT, +c BLOB GENERATED ALWAYS AS ('') VIRTUAL, +UNIQUE KEY(c(1),a) +); +INSERT INTO t(a) VALUES(1) ON DUPLICATE KEY UPDATE a=2; +SELECT * FROM t; +a c +1 +INSERT INTO t(a) VALUES(1) ON DUPLICATE KEY UPDATE a=2; +SELECT * FROM t; +a c +2 +SELECT GROUP_CONCAT(c ORDER BY c) FROM t; +GROUP_CONCAT(c ORDER BY c) + +DROP TABLE t; #Bug#21929967:GCOLS:GCOL VALUE CHANGES WHEN SESSION CHANGES SQL_MODE CREATE TABLE t(c1 INT GENERATED ALWAYS AS (1) VIRTUAL, c2 INT GENERATED ALWAYS AS(2) STORED); @@ -593,6 +722,98 @@ i1 i2 5 10 5 10 DROP TABLE t1,t2; +# +# Bug#22070021 GCOL:ASSERTION `!TABLE || (!TABLE->WRITE_SET || +# BITMAP_IS_SET(TABLE->WRITE_SET, +# +CREATE TABLE t1( +c1 INT, +c2 INT GENERATED ALWAYS AS (c1 + c1) VIRTUAL, +KEY(c2) +); +INSERT INTO t1(c1) VALUES(0); +DELETE O1.* FROM t1 AS O1, t1 AS O2; +SELECT * FROM t1; +c1 c2 +DROP TABLE t1; +# +# Bug#21944199 SIMPLE DELETE QUERY CAUSES INNODB: FAILING ASSERTION: 0 +# & DATA CORRUPTION +# +CREATE TEMPORARY TABLE t1 ( +a INTEGER NOT NULL, +b INTEGER GENERATED ALWAYS AS (a+1) VIRTUAL +); +INSERT INTO t1 (a) VALUES (0), (0), (0); +ALTER TABLE t1 ADD INDEX idx (b); +DELETE FROM t1; +DROP TEMPORARY TABLE t1; +# +# Original test case from MDEV-17890 +# +CREATE TABLE t1 ( +pk BIGINT AUTO_INCREMENT, +b BIT(15), +v BIT(10) AS (b) VIRTUAL, +PRIMARY KEY(pk), +UNIQUE(v) +); +INSERT IGNORE INTO t1 (b) VALUES (b'101110001110100'),(b'011101'); +Warnings: +Warning 1264 Out of range value for column 'v' at row 1 +SELECT pk, b INTO OUTFILE 'load.data' FROM t1; +LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b); +ERROR 22001: Data too long for column 'v' at row 1 +DROP TABLE t1; +# +# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +# +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +f ENUM('a','b','c'), +v ENUM('a','b','c') AS (f), +KEY(v,id) +) ENGINE=MyISAM; +INSERT INTO t1 (f) VALUES ('a'),('b'); +INSERT IGNORE INTO t1 SELECT * FROM t1; +Warnings: +Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored +Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored +DROP TABLE t1; +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +f ENUM('a','b','c'), +v ENUM('a','b','c') AS (f), +KEY(v,id) +) ENGINE=MyISAM; +INSERT INTO t1 (f) VALUES ('a'),('b'); +INSERT IGNORE INTO t1 SELECT * FROM t1; +Warnings: +Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored +Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored +DROP TABLE t1; +# +# MDEV-23597 Assertion `marked_for_read()' failed while evaluating DEFAULT +# +CREATE TABLE t1 (a INT UNIQUE, b INT DEFAULT (c+1), c int); +INSERT INTO t1 VALUES (1,1,1); +UPDATE t1 SET b=DEFAULT; +SELECT * from t1; +a b c +1 2 1 +REPLACE t1 VALUES(1,1,1); +INSERT INTO t1 VALUES (1,1,1) ON DUPLICATE KEY UPDATE b= DEFAULT; +SELECT * from t1; +a b c +1 2 1 +REPLACE t1 VALUES(1,1,1); +CREATE TABLE t2 (a INT, b INT DEFAULT (c+1), c int); +INSERT INTO t2 VALUES (5,5,5); +UPDATE t1 join t2 set t1.b= DEFAULT, t2.b= DEFAULT; +SELECT * from t1, t2; +a b c a b c +1 2 1 5 6 5 +DROP TABLE t1, t2; DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result b/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result index e5f512d5029..98db88abf4b 100644 --- a/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result @@ -572,13 +572,13 @@ UNIQUE(b1) INSERT IGNORE INTO t VALUES(); SELECT b from t; b -2000 +0000 SELECT b1 from t; b1 0000 SELECT * from t; a b c b1 c1 -NULL 2000 0000 0000 0000 +NULL 0000 0000 0000 0000 DELETE FROM t; CHECK TABLE t EXTENDED; Table Op Msg_type Msg_text @@ -670,6 +670,72 @@ INSERT INTO t1 (a) VALUES (0), (0), (0); ALTER TABLE t1 ADD INDEX idx (b); DELETE FROM t1; DROP TEMPORARY TABLE t1; +# +# Original test case from MDEV-17890 +# +CREATE TABLE t1 ( +pk BIGINT AUTO_INCREMENT, +b BIT(15), +v BIT(10) AS (b) VIRTUAL, +PRIMARY KEY(pk), +UNIQUE(v) +); +INSERT IGNORE INTO t1 (b) VALUES (b'101110001110100'),(b'011101'); +Warnings: +Warning 1264 Out of range value for column 'v' at row 1 +SELECT pk, b INTO OUTFILE 'load.data' FROM t1; +LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b); +ERROR 22001: Data too long for column 'v' at row 1 +DROP TABLE t1; +# +# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +# +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +f ENUM('a','b','c'), +v ENUM('a','b','c') AS (f), +KEY(v,id) +) ENGINE=MyISAM; +INSERT INTO t1 (f) VALUES ('a'),('b'); +INSERT IGNORE INTO t1 SELECT * FROM t1; +Warnings: +Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored +Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored +DROP TABLE t1; +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +f ENUM('a','b','c'), +v ENUM('a','b','c') AS (f), +KEY(v,id) +) ENGINE=MyISAM; +INSERT INTO t1 (f) VALUES ('a'),('b'); +INSERT IGNORE INTO t1 SELECT * FROM t1; +Warnings: +Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored +Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored +DROP TABLE t1; +# +# MDEV-23597 Assertion `marked_for_read()' failed while evaluating DEFAULT +# +CREATE TABLE t1 (a INT UNIQUE, b INT DEFAULT (c+1), c int); +INSERT INTO t1 VALUES (1,1,1); +UPDATE t1 SET b=DEFAULT; +SELECT * from t1; +a b c +1 2 1 +REPLACE t1 VALUES(1,1,1); +INSERT INTO t1 VALUES (1,1,1) ON DUPLICATE KEY UPDATE b= DEFAULT; +SELECT * from t1; +a b c +1 2 1 +REPLACE t1 VALUES(1,1,1); +CREATE TABLE t2 (a INT, b INT DEFAULT (c+1), c int); +INSERT INTO t2 VALUES (5,5,5); +UPDATE t1 join t2 set t1.b= DEFAULT, t2.b= DEFAULT; +SELECT * from t1, t2; +a b c a b c +1 2 1 5 6 5 +DROP TABLE t1, t2; DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/mysql-test/suite/gcol/r/gcol_keys_innodb.result b/mysql-test/suite/gcol/r/gcol_keys_innodb.result index 0ee6654f3a7..196ceb5459e 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_keys_innodb.result @@ -885,7 +885,7 @@ ERROR 22003: Out of range value for column 'vi' at row 1 DROP TABLE t1; # MDEV-19011 Assertion `file->s->base.reclength < file->s->vreclength' # failed in ha_myisam::setup_vcols_for_repair -CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL) ENGINE=MyISAM; +CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL); ALTER TABLE t1 ADD KEY (a); DROP TABLE t1; # diff --git a/mysql-test/suite/gcol/r/gcol_keys_myisam.result b/mysql-test/suite/gcol/r/gcol_keys_myisam.result index 48e11cbe222..c3cb35416ef 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_keys_myisam.result @@ -885,7 +885,7 @@ ERROR 22003: Out of range value for column 'vi' at row 1 DROP TABLE t1; # MDEV-19011 Assertion `file->s->base.reclength < file->s->vreclength' # failed in ha_myisam::setup_vcols_for_repair -CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL) ENGINE=MyISAM; +CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL); ALTER TABLE t1 ADD KEY (a); DROP TABLE t1; DROP VIEW IF EXISTS v1,v2; diff --git a/mysql-test/suite/gcol/r/gcol_partition_innodb.result b/mysql-test/suite/gcol/r/gcol_partition_innodb.result index e5a68cdb177..d3f211c9b9a 100644 --- a/mysql-test/suite/gcol/r/gcol_partition_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_partition_innodb.result @@ -89,6 +89,21 @@ Table Op Msg_type Msg_text test.t check status OK DROP TABLE t; # +# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +# +CREATE TABLE t1 ( +a INT, +b INT, +c BIT(4) NOT NULL DEFAULT b'0', +pk INTEGER AUTO_INCREMENT, +d BIT(4) AS (c) VIRTUAL, +PRIMARY KEY(pk), +KEY (b,d) +) PARTITION BY HASH(pk); +INSERT INTO t1 () VALUES (),(); +UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk; +DROP TABLE t1; +# # MDEV-16980 Wrongly set tablename len while opening the # table for purge thread # diff --git a/mysql-test/suite/gcol/r/gcol_partition_myisam.result b/mysql-test/suite/gcol/r/gcol_partition_myisam.result index 81324da6fcd..75e216f903b 100644 --- a/mysql-test/suite/gcol/r/gcol_partition_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_partition_myisam.result @@ -86,6 +86,21 @@ CHECK TABLE t EXTENDED; Table Op Msg_type Msg_text test.t check status OK DROP TABLE t; +# +# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +# +CREATE TABLE t1 ( +a INT, +b INT, +c BIT(4) NOT NULL DEFAULT b'0', +pk INTEGER AUTO_INCREMENT, +d BIT(4) AS (c) VIRTUAL, +PRIMARY KEY(pk), +KEY (b,d) +) PARTITION BY HASH(pk); +INSERT INTO t1 () VALUES (),(); +UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk; +DROP TABLE t1; DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/mysql-test/suite/gcol/r/gcol_view_innodb.result b/mysql-test/suite/gcol/r/gcol_view_innodb.result index b23dbfc4bff..ac23d64bcee 100644 --- a/mysql-test/suite/gcol/r/gcol_view_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_view_innodb.result @@ -272,6 +272,47 @@ a b c 1 -1 -1 drop view v1; drop table t1; +# +# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +# +CREATE TABLE t1 (d DATETIME(3), v DATETIME(2) AS (d)); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'), +('1985-12-24 10:15:08.456'); +DELETE FROM v1 ORDER BY v LIMIT 4; +DROP VIEW v1; +DROP TABLE t1; +# +# [duplicate] MDEV-19306 Assertion `marked_for_read()' failed in +# Field_blob::val_str with virtual columns and views +# +CREATE TABLE t1 (a BLOB, b TEXT AS (a) VIRTUAL); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (a) VALUES ('foo'),('bar'); +DELETE FROM v1 ORDER BY b LIMIT 2; +DROP VIEW v1; +DROP TABLE t1; +CREATE TABLE t1 (d INT, v TINYINT AS (d)); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (d) VALUES ('2004'),('1985') ; +DELETE FROM v1 ORDER BY v LIMIT 4; +DROP VIEW v1; +DROP TABLE t1; +CREATE TABLE t1 (d VARCHAR(64), v VARCHAR(63) AS (d)); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),('1985-12-24 10:15:08.456') ; +DELETE FROM v1 ORDER BY v LIMIT 4; +DROP TABLE t1; +DROP VIEW v1; +# +# MDEV-18249 ASSERT_COLUMN_MARKED_FOR_READ failed in ANALYZE TABLE +# +create table t1 (c varchar(3) not null, v varchar(4) as (c) virtual); +insert into t1 (c) values ('a'),('b'); +analyze table t1 persistent for columns (v) indexes (); +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/mysql-test/suite/gcol/r/gcol_view_myisam.result b/mysql-test/suite/gcol/r/gcol_view_myisam.result index 264bd904c30..ddbbf44222c 100644 --- a/mysql-test/suite/gcol/r/gcol_view_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_view_myisam.result @@ -272,6 +272,47 @@ a b c 1 -1 -1 drop view v1; drop table t1; +# +# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +# +CREATE TABLE t1 (d DATETIME(3), v DATETIME(2) AS (d)); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'), +('1985-12-24 10:15:08.456'); +DELETE FROM v1 ORDER BY v LIMIT 4; +DROP VIEW v1; +DROP TABLE t1; +# +# [duplicate] MDEV-19306 Assertion `marked_for_read()' failed in +# Field_blob::val_str with virtual columns and views +# +CREATE TABLE t1 (a BLOB, b TEXT AS (a) VIRTUAL); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (a) VALUES ('foo'),('bar'); +DELETE FROM v1 ORDER BY b LIMIT 2; +DROP VIEW v1; +DROP TABLE t1; +CREATE TABLE t1 (d INT, v TINYINT AS (d)); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (d) VALUES ('2004'),('1985') ; +DELETE FROM v1 ORDER BY v LIMIT 4; +DROP VIEW v1; +DROP TABLE t1; +CREATE TABLE t1 (d VARCHAR(64), v VARCHAR(63) AS (d)); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 (d) VALUES ('2004-04-19 15:37:39.123'),('1985-12-24 10:15:08.456') ; +DELETE FROM v1 ORDER BY v LIMIT 4; +DROP TABLE t1; +DROP VIEW v1; +# +# MDEV-18249 ASSERT_COLUMN_MARKED_FOR_READ failed in ANALYZE TABLE +# +create table t1 (c varchar(3) not null, v varchar(4) as (c) virtual); +insert into t1 (c) values ('a'),('b'); +analyze table t1 persistent for columns (v) indexes (); +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_fk.result b/mysql-test/suite/gcol/r/innodb_virtual_fk.result index 252274f3e0a..367ed1223f7 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_fk.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_fk.result @@ -809,15 +809,18 @@ generated_email_id int as (email_id), PRIMARY KEY (id), KEY mautic_generated_sent_date_email_id (generated_email_id), FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL +ON UPDATE CASCADE ) ENGINE=InnoDB; CREATE TABLE emails_metadata ( email_id int, PRIMARY KEY (email_id), CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE +ON UPDATE CASCADE ) ENGINE=InnoDB; INSERT INTO emails VALUES (1); INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan'); INSERT INTO emails_metadata VALUES (1); +UPDATE emails SET id=2; DELETE FROM emails; DROP TABLE email_stats; DROP TABLE emails_metadata; diff --git a/mysql-test/suite/gcol/t/gcol_ins_upd_innodb.test b/mysql-test/suite/gcol/t/gcol_ins_upd_innodb.test index 23d97a797e0..15a0db29615 100644 --- a/mysql-test/suite/gcol/t/gcol_ins_upd_innodb.test +++ b/mysql-test/suite/gcol/t/gcol_ins_upd_innodb.test @@ -36,7 +36,7 @@ eval SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------------# # Execute the tests to be applied to all storage engines -let $support_virtual_index= 0; +let $support_virtual_index= 1; --source suite/gcol/inc/gcol_ins_upd.inc #------------------------------------------------------------------------------# diff --git a/mysql-test/suite/gcol/t/innodb_virtual_fk.test b/mysql-test/suite/gcol/t/innodb_virtual_fk.test index 24b6a4631e6..c99259531b3 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_fk.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_fk.test @@ -670,6 +670,7 @@ CREATE TABLE email_stats ( PRIMARY KEY (id), KEY mautic_generated_sent_date_email_id (generated_email_id), FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL + ON UPDATE CASCADE ) ENGINE=InnoDB; @@ -677,6 +678,7 @@ CREATE TABLE emails_metadata ( email_id int, PRIMARY KEY (email_id), CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE + ON UPDATE CASCADE ) ENGINE=InnoDB; @@ -684,6 +686,7 @@ INSERT INTO emails VALUES (1); INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan'); INSERT INTO emails_metadata VALUES (1); +UPDATE emails SET id=2; DELETE FROM emails; DROP TABLE email_stats; diff --git a/mysql-test/suite/innodb/r/alter_table.result b/mysql-test/suite/innodb/r/alter_table.result index aec2964121b..3b0d3b0659d 100644 --- a/mysql-test/suite/innodb/r/alter_table.result +++ b/mysql-test/suite/innodb/r/alter_table.result @@ -107,6 +107,16 @@ alter table t1 engine=innodb; alter table t1 add column b int; drop table t1,t2; # +# MDEV-19272 Assertion unireg_check...Field::NEXT_NUMBER failed +# +CREATE TABLE t1 (c INT AUTO_INCREMENT NULL UNIQUE) ENGINE=InnoDB; +ALTER TABLE t1 MODIFY c INT NOT NULL, ALGORITHM=INPLACE; +DROP TABLE t1; +CREATE TABLE t1 (c TIMESTAMP AUTO_INCREMENT UNIQUE) ENGINE=InnoDB; +ERROR 42000: Incorrect column specifier for column 'c' +CREATE TABLE t1 (c DATETIME AUTO_INCREMENT UNIQUE) ENGINE=InnoDB; +ERROR 42000: Incorrect column specifier for column 'c' +# # End of 10.4 tests # # diff --git a/mysql-test/suite/innodb/r/default_row_format_alter.result b/mysql-test/suite/innodb/r/default_row_format_alter.result index fa5adb32fb0..42cbab8a5f2 100644 --- a/mysql-test/suite/innodb/r/default_row_format_alter.result +++ b/mysql-test/suite/innodb/r/default_row_format_alter.result @@ -23,6 +23,7 @@ INSERT INTO t1 VALUES (1, 'abc'); 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 Max_index_length Temporary t1 InnoDB # Compact # # # # # # NULL # # NULL latin1_swedish_ci NULL 0 N +CREATE TABLE t2 (b VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL) ENGINE=InnoDB; SET GLOBAL innodb_default_row_format = DYNAMIC; ALTER TABLE t1 DROP PRIMARY KEY, ADD COLUMN c INT PRIMARY KEY; # Here we expect DYNAMIC because there is no explicit ROW_FORMAT and the @@ -31,6 +32,10 @@ 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 Max_index_length Temporary t1 InnoDB # Dynamic # # # # # # NULL # # NULL latin1_swedish_ci NULL 0 N DROP TABLE t1; +ALTER TABLE t2 ADD INDEX(b); +ERROR HY000: Index column size too large. The maximum column size is 767 bytes +ALTER TABLE t2 FORCE, ADD INDEX(b); +DROP TABLE t2; #################################### # Check the row_format effect on ALTER, ALGORITHM=COPY SET GLOBAL innodb_default_row_format = REDUNDANT; @@ -39,6 +44,7 @@ INSERT INTO t1 VALUES (1, REPEAT('abc',1000)); 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 Max_index_length Temporary t1 InnoDB # Redundant # # # # # # NULL # # NULL latin1_swedish_ci NULL 0 N +CREATE TABLE t2 (b VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL) ENGINE=InnoDB; SET GLOBAL innoDB_default_row_format = COMPACT; ALTER TABLE t1 ADD COLUMN c2 BLOB, ALGORITHM=COPY; # Because of ALGORITHM=COPY, there is TABLE REBUILD and the table isn't @@ -47,9 +53,18 @@ 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 Max_index_length Temporary t1 InnoDB # Compact # # # # # # NULL # # NULL latin1_swedish_ci NULL 0 N DROP TABLE t1; +ALTER TABLE t2 ADD INDEX(b); +ERROR HY000: Index column size too large. The maximum column size is 767 bytes +ALTER TABLE t2 FORCE, ADD INDEX(b); +ERROR HY000: Index column size too large. The maximum column size is 767 bytes +SET GLOBAL innodb_default_row_format = DYNAMIC; +ALTER TABLE t2 ADD INDEX(b); +ERROR HY000: Index column size too large. The maximum column size is 767 bytes +ALTER TABLE t2 FORCE, ADD INDEX(b); +DROP TABLE t2; ################################### -# Check the row_format effect on ALTER, ALGORITH=COPY on +# Check the row_format effect on ALTER, ALGORITHM=COPY on # create table with explicit row_format CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=INNODB; INSERT INTO t1 VALUES (1, REPEAT('abc',1000)); diff --git a/mysql-test/suite/innodb/r/import_bugs.result b/mysql-test/suite/innodb/r/import_bugs.result new file mode 100644 index 00000000000..a52fe6abbd6 --- /dev/null +++ b/mysql-test/suite/innodb/r/import_bugs.result @@ -0,0 +1,12 @@ +call mtr.add_suppression("Index for table 'imp_t1' is corrupt; try to repair it"); +SET @save_innodb_checksum_algorithm=@@GLOBAL.innodb_checksum_algorithm; +SET GLOBAL innodb_checksum_algorithm=full_crc32; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +CREATE TABLE imp_t1 (a INT PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ALTER TABLE imp_t1 DISCARD TABLESPACE ; +FLUSH TABLES t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE imp_t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (ROW_FORMAT mismatch) +DROP TABLE imp_t1, t1; +SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm; diff --git a/mysql-test/suite/innodb/t/alter_table.test b/mysql-test/suite/innodb/t/alter_table.test index 53a9dbfea03..67ada081d46 100644 --- a/mysql-test/suite/innodb/t/alter_table.test +++ b/mysql-test/suite/innodb/t/alter_table.test @@ -110,6 +110,17 @@ alter table t1 add column b int; drop table t1,t2; --echo # +--echo # MDEV-19272 Assertion unireg_check...Field::NEXT_NUMBER failed +--echo # +CREATE TABLE t1 (c INT AUTO_INCREMENT NULL UNIQUE) ENGINE=InnoDB; +ALTER TABLE t1 MODIFY c INT NOT NULL, ALGORITHM=INPLACE; +DROP TABLE t1; +--error ER_WRONG_FIELD_SPEC +CREATE TABLE t1 (c TIMESTAMP AUTO_INCREMENT UNIQUE) ENGINE=InnoDB; +--error ER_WRONG_FIELD_SPEC +CREATE TABLE t1 (c DATETIME AUTO_INCREMENT UNIQUE) ENGINE=InnoDB; + +--echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/suite/innodb/t/default_row_format_alter.test b/mysql-test/suite/innodb/t/default_row_format_alter.test index 7cd4d672858..f5dd246efb5 100644 --- a/mysql-test/suite/innodb/t/default_row_format_alter.test +++ b/mysql-test/suite/innodb/t/default_row_format_alter.test @@ -6,7 +6,7 @@ SET @row_format = @@GLOBAL.innodb_default_row_format; --echo #################################### --echo # Check if table rebuilding alter isn't affect if table is created --echo # with explicit row_format -eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=INNODB; +CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=INNODB; INSERT INTO t1 VALUES (1, 'abc'); --replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; @@ -23,12 +23,14 @@ DROP TABLE t1; --echo # Check if table rebuilding alter is affected when there is no --echo # row_format specified at CREATE TABLE. SET GLOBAL innodb_default_row_format = COMPACT; -eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=INNODB; +CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=INNODB; INSERT INTO t1 VALUES (1, 'abc'); --replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; +CREATE TABLE t2 (b VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL) ENGINE=InnoDB; + SET GLOBAL innodb_default_row_format = DYNAMIC; ALTER TABLE t1 DROP PRIMARY KEY, ADD COLUMN c INT PRIMARY KEY; @@ -38,15 +40,22 @@ ALTER TABLE t1 DROP PRIMARY KEY, ADD COLUMN c INT PRIMARY KEY; SHOW TABLE STATUS LIKE 't1'; DROP TABLE t1; +--error ER_INDEX_COLUMN_TOO_LONG +ALTER TABLE t2 ADD INDEX(b); +ALTER TABLE t2 FORCE, ADD INDEX(b); +DROP TABLE t2; + --echo #################################### --echo # Check the row_format effect on ALTER, ALGORITHM=COPY SET GLOBAL innodb_default_row_format = REDUNDANT; -eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=INNODB; +CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ENGINE=INNODB; INSERT INTO t1 VALUES (1, REPEAT('abc',1000)); --replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; +CREATE TABLE t2 (b VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL) ENGINE=InnoDB; + SET GLOBAL innoDB_default_row_format = COMPACT; ALTER TABLE t1 ADD COLUMN c2 BLOB, ALGORITHM=COPY; @@ -56,11 +65,23 @@ ALTER TABLE t1 ADD COLUMN c2 BLOB, ALGORITHM=COPY; SHOW TABLE STATUS LIKE 't1'; DROP TABLE t1; +--error ER_INDEX_COLUMN_TOO_LONG +ALTER TABLE t2 ADD INDEX(b); +--error ER_INDEX_COLUMN_TOO_LONG +ALTER TABLE t2 FORCE, ADD INDEX(b); + +SET GLOBAL innodb_default_row_format = DYNAMIC; +--error ER_INDEX_COLUMN_TOO_LONG +ALTER TABLE t2 ADD INDEX(b); +ALTER TABLE t2 FORCE, ADD INDEX(b); + +DROP TABLE t2; + --echo --echo ################################### ---echo # Check the row_format effect on ALTER, ALGORITH=COPY on +--echo # Check the row_format effect on ALTER, ALGORITHM=COPY on --echo # create table with explicit row_format -eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=INNODB; +CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=INNODB; INSERT INTO t1 VALUES (1, REPEAT('abc',1000)); --replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # @@ -81,7 +102,7 @@ DROP TABLE t1; --echo # Check row_format on ALTER ALGORITHM=INPLACE SET GLOBAL innodb_default_row_format=COMPACT; -eval CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT, KEY k1(b(10))) ENGINE=INNODB; +CREATE TABLE t1 (a INT PRIMARY KEY, b TEXT, KEY k1(b(10))) ENGINE=INNODB; INSERT INTO t1 VALUES (1, REPEAT('abc',1000)); --replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # diff --git a/mysql-test/suite/innodb/t/import_bugs.test b/mysql-test/suite/innodb/t/import_bugs.test new file mode 100644 index 00000000000..42bb5d90ef9 --- /dev/null +++ b/mysql-test/suite/innodb/t/import_bugs.test @@ -0,0 +1,19 @@ +--source include/have_innodb.inc + +call mtr.add_suppression("Index for table 'imp_t1' is corrupt; try to repair it"); + +SET @save_innodb_checksum_algorithm=@@GLOBAL.innodb_checksum_algorithm; +SET GLOBAL innodb_checksum_algorithm=full_crc32; + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +CREATE TABLE imp_t1 (a INT PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ALTER TABLE imp_t1 DISCARD TABLESPACE ; +FLUSH TABLES t1 FOR EXPORT; +let $datadir=`select @@datadir`; +--copy_file $datadir/test/t1.ibd $datadir/test/imp_t1.ibd +UNLOCK TABLES; +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE imp_t1 IMPORT TABLESPACE; +DROP TABLE imp_t1, t1; + +SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm; diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test b/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test index 49255d3a1ac..ec9bc456e74 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test @@ -1,6 +1,8 @@ -- source include/have_innodb.inc -- source include/have_innodb_lz4.inc -- source include/not_embedded.inc +# The test can take very long time with valgrind +--source include/not_valgrind.inc # lz4 set global innodb_compression_algorithm = 2; diff --git a/mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test b/mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test index ccd9e3d70f4..a0b9fc626f3 100644 --- a/mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test +++ b/mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test @@ -88,7 +88,7 @@ while (!$mysql_errno) if (!$counter) { # This will fail this test. - --die Server failed to dissapear + --die Server failed to disappear } --sleep 1 } diff --git a/mysql-test/suite/innodb_zip/r/innochecksum_3.result b/mysql-test/suite/innodb_zip/r/innochecksum_3.result index edc71c801c0..3ec8c93f208 100644 --- a/mysql-test/suite/innodb_zip/r/innochecksum_3.result +++ b/mysql-test/suite/innodb_zip/r/innochecksum_3.result @@ -213,10 +213,10 @@ Filename::tab#.ibd # allow-mismatches,page,start-page,end-page [9]: check the both short and long options "page" and "start-page" when # seek value is larger than file size. -FOUND 1 /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err -FOUND 1 /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err -FOUND 1 /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err -FOUND 1 /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err +FOUND 1 /Error: Unable to seek to necessary offset/ in my_restart.err +FOUND 1 /Error: Unable to seek to necessary offset/ in my_restart.err +FOUND 1 /Error: Unable to seek to necessary offset/ in my_restart.err +FOUND 1 /Error: Unable to seek to necessary offset/ in my_restart.err [34]: check the invalid upper bound values for options, allow-mismatches, end-page, start-page and page. # innochecksum will fail with error code: 1 NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err diff --git a/mysql-test/suite/innodb_zip/t/innochecksum_3.test b/mysql-test/suite/innodb_zip/t/innochecksum_3.test index dab10dcc997..6d14d4c334e 100644 --- a/mysql-test/suite/innodb_zip/t/innochecksum_3.test +++ b/mysql-test/suite/innodb_zip/t/innochecksum_3.test @@ -339,22 +339,19 @@ cat_file $MYSQLTEST_VARDIR/tmp/dump.txt; --echo # seek value is larger than file size. --error 1 --exec $INNOCHECKSUM --page=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE -let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument; +let SEARCH_PATTERN= Error: Unable to seek to necessary offset; --source include/search_pattern_in_file.inc --error 1 --exec $INNOCHECKSUM -p 18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE -let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument; --source include/search_pattern_in_file.inc --error 1 --exec $INNOCHECKSUM --start-page=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE -let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument; --source include/search_pattern_in_file.inc --error 1 --exec $INNOCHECKSUM -s 18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE -let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument; --source include/search_pattern_in_file.inc --echo [34]: check the invalid upper bound values for options, allow-mismatches, end-page, start-page and page. diff --git a/mysql-test/suite/roles/set_default_role_clear.result b/mysql-test/suite/roles/set_default_role_clear.result index 281ed7e45ea..d8508f5d0d6 100644 --- a/mysql-test/suite/roles/set_default_role_clear.result +++ b/mysql-test/suite/roles/set_default_role_clear.result @@ -17,7 +17,7 @@ Grants for test_user@localhost GRANT `test_role` TO `test_user`@`localhost` GRANT USAGE ON *.* TO `test_user`@`localhost` GRANT SELECT ON *.* TO `test_role` -SET DEFAULT ROLE test_role FOR 'test_user'@'localhost' +SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost` select user, host, default_role from mysql.user where user='test_user'; User Host default_role test_user localhost test_role diff --git a/mysql-test/suite/roles/set_default_role_for.result b/mysql-test/suite/roles/set_default_role_for.result index fec43b8e763..3ddf48eb416 100644 --- a/mysql-test/suite/roles/set_default_role_for.result +++ b/mysql-test/suite/roles/set_default_role_for.result @@ -14,14 +14,14 @@ set default role role_a for user_a@localhost; set default role invalid_role for user_a@localhost; ERROR OP000: Invalid role specification `invalid_role` set default role role_b for user_a@localhost; -ERROR OP000: User `user_a@localhost` has not been granted role `role_b` +ERROR OP000: User `root`@`localhost` has not been granted role `role_b` set default role role_b for user_b@localhost; show grants; Grants for user_a@localhost GRANT `role_a` TO `user_a`@`localhost` GRANT USAGE ON *.* TO `user_a`@`localhost` GRANT SELECT ON *.* TO `role_a` -SET DEFAULT ROLE role_a FOR 'user_a'@'localhost' +SET DEFAULT ROLE `role_a` FOR `user_a`@`localhost` select user, host, default_role from mysql.user where user like 'user_%'; User Host default_role user_a localhost role_a @@ -37,13 +37,13 @@ User Host default_role user_a localhost role_a user_b localhost role_b set default role role_b for current_user; -ERROR OP000: User `user_a@localhost` has not been granted role `role_b` +ERROR OP000: User `user_a`@`localhost` has not been granted role `role_b` show grants; Grants for user_b@localhost GRANT `role_b` TO `user_b`@`localhost` GRANT USAGE ON *.* TO `user_b`@`localhost` GRANT INSERT, UPDATE ON *.* TO `role_b` -SET DEFAULT ROLE role_b FOR 'user_b'@'localhost' +SET DEFAULT ROLE `role_b` FOR `user_b`@`localhost` select user, host, default_role from mysql.user where user like 'user_%'; ERROR 42000: SELECT command denied to user 'user_b'@'localhost' for table 'user' set default role NONE for user_a@localhost; diff --git a/mysql-test/suite/roles/set_default_role_invalid.result b/mysql-test/suite/roles/set_default_role_invalid.result index 08087acc51f..eb3924dc617 100644 --- a/mysql-test/suite/roles/set_default_role_invalid.result +++ b/mysql-test/suite/roles/set_default_role_invalid.result @@ -24,7 +24,7 @@ Grants for test_user@localhost GRANT `test_role` TO `test_user`@`localhost` GRANT USAGE ON *.* TO `test_user`@`localhost` GRANT SELECT ON *.* TO `test_role` -SET DEFAULT ROLE test_role FOR 'test_user'@'localhost' +SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost` select user, host, default_role from mysql.user where user='test_user'; User Host default_role test_user localhost test_role @@ -48,7 +48,7 @@ CREATE USER b; CREATE ROLE r1; CREATE ROLE r2; SET DEFAULT ROLE r1 FOR a; -ERROR OP000: User `a@%` has not been granted role `r1` +ERROR OP000: User `root`@`localhost` has not been granted role `r1` GRANT r1 TO b; GRANT r2 TO b; SET DEFAULT ROLE r1 FOR b; @@ -72,7 +72,7 @@ GRANT `r1` TO `b`@`%` GRANT `r2` TO `b`@`%` GRANT USAGE ON *.* TO `b`@`%` GRANT SELECT ON `mysql`.* TO `b`@`%` -SET DEFAULT ROLE r2 FOR 'b'@'%' +SET DEFAULT ROLE `r2` FOR `b`@`%` SET DEFAULT ROLE r1 FOR a; ERROR 42000: Access denied for user 'b'@'%' to database 'mysql' SELECT CURRENT_ROLE; @@ -98,9 +98,9 @@ GRANT `r1` TO `b`@`%` GRANT `r2` TO `b`@`%` GRANT USAGE ON *.* TO `b`@`%` GRANT SELECT, UPDATE ON `mysql`.* TO `b`@`%` -SET DEFAULT ROLE r2 FOR 'b'@'%' +SET DEFAULT ROLE `r2` FOR `b`@`%` SET DEFAULT ROLE r1 FOR a; -ERROR OP000: User `a@%` has not been granted role `r1` +ERROR OP000: User `b`@`%` has not been granted role `r1` SET DEFAULT ROLE invalid_role; ERROR OP000: Invalid role specification `invalid_role` SET DEFAULT ROLE invalid_role FOR a; @@ -117,7 +117,7 @@ SET DEFAULT ROLE None; # Change user b (session 3: role granted to user a) SET DEFAULT ROLE r1 FOR a; SET DEFAULT ROLE r2 FOR a; -ERROR OP000: User `a@%` has not been granted role `r2` +ERROR OP000: User `b`@`%` has not been granted role `r2` SET DEFAULT ROLE invalid_role; ERROR OP000: Invalid role specification `invalid_role` SET DEFAULT ROLE invalid_role FOR a; diff --git a/mysql-test/suite/roles/set_default_role_new_connection.result b/mysql-test/suite/roles/set_default_role_new_connection.result index 71035737f99..5c51b782ab7 100644 --- a/mysql-test/suite/roles/set_default_role_new_connection.result +++ b/mysql-test/suite/roles/set_default_role_new_connection.result @@ -23,7 +23,7 @@ Grants for test_user@localhost GRANT `test_role` TO `test_user`@`localhost` GRANT USAGE ON *.* TO `test_user`@`localhost` GRANT SELECT ON *.* TO `test_role` -SET DEFAULT ROLE test_role FOR 'test_user'@'localhost' +SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost` select user, host, default_role from mysql.user where user = 'test_user'; User Host default_role test_user localhost test_role @@ -52,7 +52,7 @@ Grants for test_user@localhost GRANT `test_role` TO `test_user`@`localhost` GRANT USAGE ON *.* TO `test_user`@`localhost` GRANT SELECT ON *.* TO `test_role` -SET DEFAULT ROLE test_role FOR 'test_user'@'localhost' +SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost` select user, host, default_role from mysql.user where user = 'test_user'; User Host default_role test_user localhost test_role diff --git a/mysql-test/suite/roles/set_role-recursive.result b/mysql-test/suite/roles/set_role-recursive.result index be11728ad4e..102ee392581 100644 --- a/mysql-test/suite/roles/set_role-recursive.result +++ b/mysql-test/suite/roles/set_role-recursive.result @@ -67,7 +67,7 @@ Grants for test_user@localhost GRANT USAGE ON *.* TO `test_user`@`localhost` GRANT `test_role1` TO `test_user`@`localhost` set role test_role2; -ERROR OP000: User `test_user@localhost` has not been granted role `test_role2` +ERROR OP000: User `test_user`@`localhost` has not been granted role `test_role2` select current_user(), current_role(); current_user() current_role() test_user@localhost NULL diff --git a/mysql-test/suite/rpl/r/create_or_replace_mix.result b/mysql-test/suite/rpl/r/create_or_replace_mix.result index 6c83d27eef9..9036ab425ae 100644 --- a/mysql-test/suite/rpl/r/create_or_replace_mix.result +++ b/mysql-test/suite/rpl/r/create_or_replace_mix.result @@ -103,6 +103,8 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */ drop table if exists t1,t2; Warnings: Note 1051 Unknown table 'test.t1' diff --git a/mysql-test/suite/rpl/r/create_or_replace_row.result b/mysql-test/suite/rpl/r/create_or_replace_row.result index c45daefd671..16f92b5e4b6 100644 --- a/mysql-test/suite/rpl/r/create_or_replace_row.result +++ b/mysql-test/suite/rpl/r/create_or_replace_row.result @@ -128,6 +128,9 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */ +master-bin.000001 # Query # # ROLLBACK drop table if exists t1,t2; Warnings: Note 1051 Unknown table 'test.t1' diff --git a/mysql-test/suite/rpl/r/create_or_replace_statement.result b/mysql-test/suite/rpl/r/create_or_replace_statement.result index 6c83d27eef9..9036ab425ae 100644 --- a/mysql-test/suite/rpl/r/create_or_replace_statement.result +++ b/mysql-test/suite/rpl/r/create_or_replace_statement.result @@ -103,6 +103,8 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */ drop table if exists t1,t2; Warnings: Note 1051 Unknown table 'test.t1' diff --git a/mysql-test/suite/rpl/t/rpl_trunc_temp.test b/mysql-test/suite/rpl/t/rpl_trunc_temp.test index 0e7d5483f62..1ef0fcedd1d 100644 --- a/mysql-test/suite/rpl/t/rpl_trunc_temp.test +++ b/mysql-test/suite/rpl/t/rpl_trunc_temp.test @@ -42,7 +42,7 @@ truncate t1; sync_slave_with_master; show status like 'Slave_open_temp_tables'; -# Disconnect the master, temp table on slave should dissapear +# Disconnect the master, temp table on slave should disappear disconnect master; connection slave; diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index 7d2ca937de2..5511d758d50 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -3469,7 +3469,7 @@ VARIABLE_COMMENT Default value for the FOR SYSTEM_TIME AS OF clause NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST DEFAULT +ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME TABLE_DEFINITION_CACHE diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 3498d5de743..5eeb5698eba 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -4159,7 +4159,7 @@ VARIABLE_COMMENT Default value for the FOR SYSTEM_TIME AS OF clause NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST DEFAULT +ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME TABLE_DEFINITION_CACHE diff --git a/mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test b/mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test index e9dd0c71936..4563e9b4469 100644 --- a/mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test +++ b/mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test @@ -89,7 +89,7 @@ while (!$mysql_errno) if (!$counter) { # This will fail this test. - --die Server failed to dissapear + --die Server failed to disappear } --sleep 1 } diff --git a/mysql-test/suite/vcol/r/binlog.result b/mysql-test/suite/vcol/r/binlog.result index d4893b7ed3c..519877e9bc0 100644 --- a/mysql-test/suite/vcol/r/binlog.result +++ b/mysql-test/suite/vcol/r/binlog.result @@ -80,4 +80,18 @@ Warnings: Warning 1265 Data truncated for column 'b' at row 1 Warning 1265 Data truncated for column 'b' at row 2 DROP TABLE t1; +# +# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +# +SET SESSION binlog_row_image= noblob; +CREATE TEMPORARY TABLE t1 SELECT UUID(); +show create table t1; +Table Create Table +t1 CREATE TEMPORARY TABLE `t1` ( + `UUID()` varchar(36) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +CREATE TABLE t2 (a INT PRIMARY KEY, b TEXT, c INT GENERATED ALWAYS AS(b)); +INSERT INTO t2 (a,b) VALUES (1,1); +SET SESSION binlog_row_image= default; +DROP TABLE t2; include/rpl_end.inc diff --git a/mysql-test/suite/vcol/t/binlog.test b/mysql-test/suite/vcol/t/binlog.test index aa939086f12..edf0a8957b9 100644 --- a/mysql-test/suite/vcol/t/binlog.test +++ b/mysql-test/suite/vcol/t/binlog.test @@ -66,4 +66,18 @@ UPDATE IGNORE t1 SET a = NULL; DROP TABLE t1; +--echo # +--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols +--echo # + +SET SESSION binlog_row_image= noblob; +CREATE TEMPORARY TABLE t1 SELECT UUID(); +show create table t1; +CREATE TABLE t2 (a INT PRIMARY KEY, b TEXT, c INT GENERATED ALWAYS AS(b)); +INSERT INTO t2 (a,b) VALUES (1,1); + +SET SESSION binlog_row_image= default; +DROP TABLE t2; + + --source include/rpl_end.inc diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result index 5badb4b4a22..05e248e40f4 100644 --- a/mysql-test/suite/versioning/r/create.result +++ b/mysql-test/suite/versioning/r/create.result @@ -592,3 +592,22 @@ t2 CREATE TEMPORARY TABLE `t2` ( ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 drop temporary table t2; drop table t1; +# +# MDEV-16857 system-invisible row_end is displayed in SHOW INDEX +# +create or replace table t1 (id int primary key, x int) with system versioning; +select table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name +from information_schema.statistics where table_name = 't1'; +table_schema table_name non_unique index_schema index_name seq_in_index column_name +test t1 0 test PRIMARY 1 id +show index from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 0 PRIMARY 1 id # # # # # # +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `x` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +drop table t1; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 2a277b1c2ea..d6e6d827ddc 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -1119,6 +1119,27 @@ create or replace table t1 (a int) with system versioning; alter table t1 partition by system_time (partition pn current); ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT drop table t1; +# +# MDEV-22247 History partition overflow leads to wrong SELECT result +# +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour +(partition p0 history, partition p1 history, partition pn current); +insert into t1 values (0); +update t1 set x= x + 1; +set timestamp= unix_timestamp('2000-01-01 02:00:01'); +update t1 set x= x + 1; +select *, row_start, row_end from t1 for system_time as of '2000-01-01 02:00:00'; +x row_start row_end +1 2000-01-01 00:00:00.000000 2000-01-01 02:00:01.000000 +explain partitions select * from t1 for system_time as of '2000-01-01 02:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p1,pn ALL NULL NULL NULL NULL # Using where +explain partitions select * from t1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 pn # NULL NULL NULL NULL # # +drop table t1; # End of 10.3 tests # # MDEV-22283 Server crashes in key_copy or unexpected error 156: The table already existed in the storage engine diff --git a/mysql-test/suite/versioning/r/sysvars-notembedded.result b/mysql-test/suite/versioning/r/sysvars-notembedded.result new file mode 100644 index 00000000000..8b1ad6cfc58 --- /dev/null +++ b/mysql-test/suite/versioning/r/sysvars-notembedded.result @@ -0,0 +1,30 @@ +create table t (a int) with system versioning; +set @before= UNIX_TIMESTAMP(now(6)); +insert into t values (1); +set @after= UNIX_TIMESTAMP(now(6)); +update t set a= 2; +set global system_versioning_asof= FROM_UNIXTIME(@after); +set system_versioning_asof= FROM_UNIXTIME(@after); +select * from t as nonempty; +a +1 +connect subcon,127.0.0.1,root,,,$SERVER_MYPORT_1; +connection subcon; +select * from t as nonempty; +a +1 +disconnect subcon; +connection default; +set global system_versioning_asof= FROM_UNIXTIME(@before); +select * from t as nonempty; +a +1 +connect subcon,127.0.0.1,root,,,$SERVER_MYPORT_1; +connection subcon; +select * from t as empty; +a +disconnect subcon; +connection default; +drop table t; +set global system_versioning_asof= DEFAULT; +set system_versioning_asof= DEFAULT; diff --git a/mysql-test/suite/versioning/r/sysvars.result b/mysql-test/suite/versioning/r/sysvars.result index 66513741631..a5a3f79990c 100644 --- a/mysql-test/suite/versioning/r/sysvars.result +++ b/mysql-test/suite/versioning/r/sysvars.result @@ -1,5 +1,7 @@ create table t (a int) with system versioning; +set @before= UNIX_TIMESTAMP(now(6)); insert into t values (1); +set @after= UNIX_TIMESTAMP(now(6)); update t set a= 2; show global variables like 'system_versioning_asof'; Variable_name Value @@ -56,65 +58,71 @@ ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '201 set system_versioning_asof= '0000-00-00 00:00'; ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '0000-00-00 00:00' # GLOBAL @@system_versioning_asof -set global system_versioning_asof= '1911-11-11 11:11:11.1111119'; +set global system_versioning_asof= '1991-11-11 11:11:11.1111119'; Warnings: -Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' -Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' +Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119' show global variables like 'system_versioning_asof'; Variable_name Value -system_versioning_asof 1911-11-11 11:11:11.111111 -set global system_versioning_asof= '1900-01-01 00:00:00'; +system_versioning_asof 1991-11-11 11:11:11.111111 +set global system_versioning_asof= '1990-01-01 00:00:00'; show global variables like 'system_versioning_asof'; Variable_name Value -system_versioning_asof 1900-01-01 00:00:00.000000 -set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119'; +system_versioning_asof 1990-01-01 00:00:00.000000 +set global system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119'; Warnings: -Note 1292 Truncated incorrect DATETIME value: '1911-11-11 11:11:11.1111119' +Note 1292 Truncated incorrect DATETIME value: '1991-11-11 11:11:11.1111119' show global variables like 'system_versioning_asof'; Variable_name Value -system_versioning_asof 1911-11-11 11:11:11.111111 -set @ts= timestamp'1900-01-01 00:00:00'; +system_versioning_asof 1991-11-11 11:11:11.111111 +set @ts= timestamp'1990-01-01 00:00:00'; set global system_versioning_asof= @ts; show global variables like 'system_versioning_asof'; Variable_name Value -system_versioning_asof 1900-01-01 00:00:00.000000 +system_versioning_asof 1990-01-01 00:00:00.000000 set global system_versioning_asof= default; select @@global.system_versioning_asof; @@global.system_versioning_asof DEFAULT # SESSION @@system_versioning_asof -set system_versioning_asof= '1911-11-11 11:11:11.1111119'; +set system_versioning_asof= '1991-11-11 11:11:11.1111119'; Warnings: -Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' -Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' +Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119' show variables like 'system_versioning_asof'; Variable_name Value -system_versioning_asof 1911-11-11 11:11:11.111111 -set system_versioning_asof= '1900-01-01 00:00:00'; +system_versioning_asof 1991-11-11 11:11:11.111111 +set system_versioning_asof= '1990-01-01 00:00:00'; show variables like 'system_versioning_asof'; Variable_name Value -system_versioning_asof 1900-01-01 00:00:00.000000 -set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119'; +system_versioning_asof 1990-01-01 00:00:00.000000 +set system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119'; Warnings: -Note 1292 Truncated incorrect DATETIME value: '1911-11-11 11:11:11.1111119' +Note 1292 Truncated incorrect DATETIME value: '1991-11-11 11:11:11.1111119' show variables like 'system_versioning_asof'; Variable_name Value -system_versioning_asof 1911-11-11 11:11:11.111111 -set @ts= timestamp'1900-01-01 00:00:00'; +system_versioning_asof 1991-11-11 11:11:11.111111 +set @ts= timestamp'1990-01-01 00:00:00'; set system_versioning_asof= @ts; show variables like 'system_versioning_asof'; Variable_name Value -system_versioning_asof 1900-01-01 00:00:00.000000 +system_versioning_asof 1990-01-01 00:00:00.000000 # DEFAULT: value is copied from GLOBAL to SESSION -set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111'; -set system_versioning_asof= '1900-01-01 00:00:00'; +set global time_zone= "+03:00"; +set time_zone= "+10:00"; +set global system_versioning_asof= timestamp'1991-11-11 11:11:11.111111'; +set system_versioning_asof= '1990-01-01 00:00:00'; select @@global.system_versioning_asof != @@system_versioning_asof as different; different 1 set system_versioning_asof= default; +select @@global.system_versioning_asof != @@system_versioning_asof as different; +different +1 +set global system_versioning_asof= default; select @@global.system_versioning_asof = @@system_versioning_asof as equal; equal 1 +set global time_zone= DEFAULT; +set time_zone= DEFAULT; set global system_versioning_asof= DEFAULT; set system_versioning_asof= DEFAULT; select @@global.system_versioning_asof, @@system_versioning_asof; @@ -142,6 +150,56 @@ select * from t for system_time between '1970-01-01 00:00' and current_timestamp a 2 1 +# MDEV-16026: Global system_versioning_asof must not be used if client sessions can have non-default time zone +# changing time zone should not abuse `system_versioning_asof` +set session time_zone = '+10:00'; +set global system_versioning_asof = '1999-09-08 00:00:00.000000'; +show global variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1999-09-08 00:00:00.000000 +set session time_zone = '+03:00'; +show global variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1999-09-07 17:00:00.000000 +set session time_zone = '+03:00'; +set session system_versioning_asof = '2000-09-08 00:00:00.000000'; +show session variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 2000-09-08 00:00:00.000000 +set session time_zone = '+10:00'; +show session variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 2000-09-08 07:00:00.000000 +# global and local time zones should not interfere +show global variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1999-09-08 00:00:00.000000 +set time_zone= "+10:00"; +set system_versioning_asof= FROM_UNIXTIME(@before); +select * from t as empty; +a +set system_versioning_asof= FROM_UNIXTIME(@after); +select * from t as nonempty; +a +1 +set time_zone= "+03:00"; +set system_versioning_asof= FROM_UNIXTIME(@before); +select * from t as empty; +a +set system_versioning_asof= FROM_UNIXTIME(@after); +select * from t as nonempty; +a +1 +# MDEV-16481: set global system_versioning_asof=sf() crashes in specific case +# Using global variable inside a stored function should not crash +create or replace function now_global() returns timestamp +return CONVERT_TZ(now(), @@session.time_zone, @@global.time_zone); +set global system_versioning_asof= now_global(); +drop function now_global; +set global time_zone= "SYSTEM"; +set time_zone= "SYSTEM"; +set global system_versioning_asof= default; +set system_versioning_asof= default; show status like "Feature_system_versioning"; Variable_name Value Feature_system_versioning 2 @@ -153,7 +211,7 @@ create or replace table t1 (x int) with system versioning; create or replace table t2 (y int); insert into t1 values (1); insert into t2 values (1); -set system_versioning_asof= '1970-01-01 00:00:00'; +set system_versioning_asof= '1970-01-02 00:00:00'; delete t1, t2 from t1 join t2 where t1.x = t2.y; select * from t1 for system_time as of timestamp now(6); x diff --git a/mysql-test/suite/versioning/t/create.test b/mysql-test/suite/versioning/t/create.test index 1f016fed871..6f8cff3ca2e 100644 --- a/mysql-test/suite/versioning/t/create.test +++ b/mysql-test/suite/versioning/t/create.test @@ -439,3 +439,15 @@ show create table t1; show create table t2; drop temporary table t2; drop table t1; + +--echo # +--echo # MDEV-16857 system-invisible row_end is displayed in SHOW INDEX +--echo # +create or replace table t1 (id int primary key, x int) with system versioning; +select table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name +from information_schema.statistics where table_name = 't1'; +--replace_column 6 # 7 # 8 # 9 # 10 # 11 # +show index from t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 445f5844630..ac7a3ebfd55 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -993,6 +993,27 @@ alter table t1 partition by system_time (partition pn current); # Cleanup drop table t1; +--echo # +--echo # MDEV-22247 History partition overflow leads to wrong SELECT result +--echo # +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour +(partition p0 history, partition p1 history, partition pn current); + +insert into t1 values (0); +update t1 set x= x + 1; + +set timestamp= unix_timestamp('2000-01-01 02:00:01'); +update t1 set x= x + 1; + +select *, row_start, row_end from t1 for system_time as of '2000-01-01 02:00:00'; +--replace_column 10 # +explain partitions select * from t1 for system_time as of '2000-01-01 02:00:00'; +--replace_column 5 # 10 # 11 # +explain partitions select * from t1; +drop table t1; + --echo # End of 10.3 tests --echo # diff --git a/mysql-test/suite/versioning/t/sysvars-notembedded.test b/mysql-test/suite/versioning/t/sysvars-notembedded.test new file mode 100644 index 00000000000..314972bc375 --- /dev/null +++ b/mysql-test/suite/versioning/t/sysvars-notembedded.test @@ -0,0 +1,31 @@ +source include/not_embedded.inc; + +create table t (a int) with system versioning; +set @before= UNIX_TIMESTAMP(now(6)); +insert into t values (1); +set @after= UNIX_TIMESTAMP(now(6)); +update t set a= 2; + +set global system_versioning_asof= FROM_UNIXTIME(@after); +set system_versioning_asof= FROM_UNIXTIME(@after); +select * from t as nonempty; + +--connect (subcon,127.0.0.1,root,,,$SERVER_MYPORT_1) +--connection subcon +select * from t as nonempty; +--disconnect subcon +--connection default + +set global system_versioning_asof= FROM_UNIXTIME(@before); +select * from t as nonempty; + +--connect (subcon,127.0.0.1,root,,,$SERVER_MYPORT_1) +--connection subcon +select * from t as empty; +--disconnect subcon +--connection default + +drop table t; + +set global system_versioning_asof= DEFAULT; +set system_versioning_asof= DEFAULT; diff --git a/mysql-test/suite/versioning/t/sysvars.test b/mysql-test/suite/versioning/t/sysvars.test index a1026418e98..ab1f612edf3 100644 --- a/mysql-test/suite/versioning/t/sysvars.test +++ b/mysql-test/suite/versioning/t/sysvars.test @@ -1,5 +1,7 @@ create table t (a int) with system versioning; +set @before= UNIX_TIMESTAMP(now(6)); insert into t values (1); +set @after= UNIX_TIMESTAMP(now(6)); update t set a= 2; show global variables like 'system_versioning_asof'; @@ -51,16 +53,16 @@ set system_versioning_asof= '2011-00-28 00:00'; set system_versioning_asof= '0000-00-00 00:00'; --echo # GLOBAL @@system_versioning_asof -set global system_versioning_asof= '1911-11-11 11:11:11.1111119'; +set global system_versioning_asof= '1991-11-11 11:11:11.1111119'; show global variables like 'system_versioning_asof'; -set global system_versioning_asof= '1900-01-01 00:00:00'; +set global system_versioning_asof= '1990-01-01 00:00:00'; show global variables like 'system_versioning_asof'; -set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119'; +set global system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119'; show global variables like 'system_versioning_asof'; -set @ts= timestamp'1900-01-01 00:00:00'; +set @ts= timestamp'1990-01-01 00:00:00'; set global system_versioning_asof= @ts; show global variables like 'system_versioning_asof'; @@ -68,26 +70,32 @@ set global system_versioning_asof= default; select @@global.system_versioning_asof; --echo # SESSION @@system_versioning_asof -set system_versioning_asof= '1911-11-11 11:11:11.1111119'; +set system_versioning_asof= '1991-11-11 11:11:11.1111119'; show variables like 'system_versioning_asof'; -set system_versioning_asof= '1900-01-01 00:00:00'; +set system_versioning_asof= '1990-01-01 00:00:00'; show variables like 'system_versioning_asof'; -set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119'; +set system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119'; show variables like 'system_versioning_asof'; -set @ts= timestamp'1900-01-01 00:00:00'; +set @ts= timestamp'1990-01-01 00:00:00'; set system_versioning_asof= @ts; show variables like 'system_versioning_asof'; --echo # DEFAULT: value is copied from GLOBAL to SESSION -set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111'; -set system_versioning_asof= '1900-01-01 00:00:00'; +set global time_zone= "+03:00"; +set time_zone= "+10:00"; +set global system_versioning_asof= timestamp'1991-11-11 11:11:11.111111'; +set system_versioning_asof= '1990-01-01 00:00:00'; select @@global.system_versioning_asof != @@system_versioning_asof as different; set system_versioning_asof= default; +select @@global.system_versioning_asof != @@system_versioning_asof as different; +set global system_versioning_asof= default; select @@global.system_versioning_asof = @@system_versioning_asof as equal; +set global time_zone= DEFAULT; +set time_zone= DEFAULT; set global system_versioning_asof= DEFAULT; set system_versioning_asof= DEFAULT; select @@global.system_versioning_asof, @@system_versioning_asof; @@ -100,6 +108,47 @@ select * from t for system_time all; select * from t for system_time from '1970-01-01 00:00' to current_timestamp(6); select * from t for system_time between '1970-01-01 00:00' and current_timestamp(6); +-- echo # MDEV-16026: Global system_versioning_asof must not be used if client sessions can have non-default time zone +-- echo # changing time zone should not abuse `system_versioning_asof` + +set session time_zone = '+10:00'; +set global system_versioning_asof = '1999-09-08 00:00:00.000000'; +show global variables like 'system_versioning_asof'; +set session time_zone = '+03:00'; +show global variables like 'system_versioning_asof'; + +set session time_zone = '+03:00'; +set session system_versioning_asof = '2000-09-08 00:00:00.000000'; +show session variables like 'system_versioning_asof'; +set session time_zone = '+10:00'; +show session variables like 'system_versioning_asof'; +-- echo # global and local time zones should not interfere +show global variables like 'system_versioning_asof'; + +set time_zone= "+10:00"; +set system_versioning_asof= FROM_UNIXTIME(@before); +select * from t as empty; +set system_versioning_asof= FROM_UNIXTIME(@after); +select * from t as nonempty; + +set time_zone= "+03:00"; +set system_versioning_asof= FROM_UNIXTIME(@before); +select * from t as empty; +set system_versioning_asof= FROM_UNIXTIME(@after); +select * from t as nonempty; + +--echo # MDEV-16481: set global system_versioning_asof=sf() crashes in specific case +--echo # Using global variable inside a stored function should not crash +create or replace function now_global() returns timestamp + return CONVERT_TZ(now(), @@session.time_zone, @@global.time_zone); +set global system_versioning_asof= now_global(); +drop function now_global; + +set global time_zone= "SYSTEM"; +set time_zone= "SYSTEM"; +set global system_versioning_asof= default; +set system_versioning_asof= default; + show status like "Feature_system_versioning"; drop table t; @@ -111,7 +160,7 @@ create or replace table t1 (x int) with system versioning; create or replace table t2 (y int); insert into t1 values (1); insert into t2 values (1); -set system_versioning_asof= '1970-01-01 00:00:00'; +set system_versioning_asof= '1970-01-02 00:00:00'; delete t1, t2 from t1 join t2 where t1.x = t2.y; select * from t1 for system_time as of timestamp now(6); diff --git a/mysql-test/suite/wsrep/r/variables.result b/mysql-test/suite/wsrep/r/variables.result index 5fe8dcb1c6d..c21e4dc0323 100644 --- a/mysql-test/suite/wsrep/r/variables.result +++ b/mysql-test/suite/wsrep/r/variables.result @@ -34,6 +34,7 @@ wsrep_cert_deps_distance # wsrep_apply_oooe # wsrep_apply_oool # wsrep_apply_window # +wsrep_apply_waits # wsrep_commit_oooe # wsrep_commit_oool # wsrep_commit_window # diff --git a/mysql-test/suite/wsrep/r/variables_debug.result b/mysql-test/suite/wsrep/r/variables_debug.result index 0bb41ebb1f8..65f5b0ee274 100644 --- a/mysql-test/suite/wsrep/r/variables_debug.result +++ b/mysql-test/suite/wsrep/r/variables_debug.result @@ -34,6 +34,7 @@ wsrep_cert_deps_distance # wsrep_apply_oooe # wsrep_apply_oool # wsrep_apply_window # +wsrep_apply_waits # wsrep_commit_oooe # wsrep_commit_oool # wsrep_commit_window # diff --git a/mysql-test/suite/wsrep/t/variables.test b/mysql-test/suite/wsrep/t/variables.test index 249fba48d44..e40ac7b8772 100644 --- a/mysql-test/suite/wsrep/t/variables.test +++ b/mysql-test/suite/wsrep/t/variables.test @@ -3,7 +3,7 @@ --source include/have_innodb.inc --source include/galera_no_debug_sync.inc ---let $galera_version=26.4.8 +--let $galera_version=26.4.9 source include/check_galera_version.inc; source include/galera_variables_ok.inc; diff --git a/mysql-test/suite/wsrep/t/variables_debug.test b/mysql-test/suite/wsrep/t/variables_debug.test index c48c2d895b9..29747e48f18 100644 --- a/mysql-test/suite/wsrep/t/variables_debug.test +++ b/mysql-test/suite/wsrep/t/variables_debug.test @@ -5,7 +5,7 @@ --source include/have_debug_sync.inc --source include/galera_have_debug_sync.inc ---let $galera_version=26.4.8 +--let $galera_version=26.4.9 source include/check_galera_version.inc; source include/galera_variables_ok.inc; diff --git a/mysys/mf_qsort.c b/mysys/mf_qsort.c index 3f91bb35354..b516639a341 100644 --- a/mysys/mf_qsort.c +++ b/mysys/mf_qsort.c @@ -114,7 +114,7 @@ qsort_t my_qsort(void *base_ptr, size_t count, size_t size, qsort_cmp cmp) stack[0].low=stack[0].high=0; #endif pivot = (char *) my_alloca((int) size); - ptr_cmp= size == sizeof(char*) && !((low - (char*) 0)& (sizeof(char*)-1)); + ptr_cmp= size == sizeof(char*) && (intptr_t)low % sizeof(char*) == 0; /* The following loop sorts elements between high and low */ do diff --git a/plugin/auth_gssapi/CMakeLists.txt b/plugin/auth_gssapi/CMakeLists.txt index d96d62d7e18..7fc0819a3b3 100644 --- a/plugin/auth_gssapi/CMakeLists.txt +++ b/plugin/auth_gssapi/CMakeLists.txt @@ -11,6 +11,7 @@ IF(USE_SSPI) ELSE() SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) FIND_PACKAGE(GSSAPI) + SET_PACKAGE_PROPERTIES(GSSAPI PROPERTIES TYPE OPTIONAL) IF(GSSAPI_FOUND) INCLUDE_DIRECTORIES(${GSSAPI_INCS}) ADD_DEFINITIONS(-DPLUGIN_GSSAPI) diff --git a/plugin/aws_key_management/CMakeLists.txt b/plugin/aws_key_management/CMakeLists.txt index 248d56e8d76..3c6ca018273 100644 --- a/plugin/aws_key_management/CMakeLists.txt +++ b/plugin/aws_key_management/CMakeLists.txt @@ -2,6 +2,7 @@ INCLUDE(aws_sdk) CHECK_AWS_SDK(HAVE_AWS_SDK REASON) IF(NOT HAVE_AWS_SDK) MESSAGE_ONCE(AWS_KEY_MANAGEMENT_NO_AWS_SDK "Can't build aws_key_management - AWS SDK not available (${REASON})") + ADD_FEATURE_INFO(AWS_KEY_MANAGEMENT "OFF" "AWS Encryption Key Management Plugin") RETURN() ENDIF() @@ -12,3 +13,5 @@ MYSQL_ADD_PLUGIN(aws_key_management IF(TARGET aws_key_management) USE_AWS_SDK_LIBS(aws_key_management kms) ENDIF() + +ADD_FEATURE_INFO(AWS_KEY_MANAGEMENT "ON" "AWS Encryption Key Management Plugin") diff --git a/plugin/win_auth_client/CMakeLists.txt b/plugin/win_auth_client/CMakeLists.txt index 8c7696347aa..46f837e58d6 100644 --- a/plugin/win_auth_client/CMakeLists.txt +++ b/plugin/win_auth_client/CMakeLists.txt @@ -29,6 +29,6 @@ IF(WIN32) MYSQL_ADD_PLUGIN(authentication_windows_client ${PLUGIN_SOURCES} ${HEADERS} LINK_LIBRARIES Secur32 - MODULE_ONLY COMPONENT ClientPlugins) + MODULE_ONLY COMPONENT ClientPlugins CLIENT) ENDIF(WIN32) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 5f183afe8fc..14ef6840d6d 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -611,12 +611,8 @@ then echo echo echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !" - echo "To do so, start the server, then issue the following commands:" + echo "To do so, start the server, then issue the following command:" echo - echo "'$bindir/mysqladmin' -u root password 'new-password'" - echo "'$bindir/mysqladmin' -u root -h $hostname password 'new-password'" - echo - echo "Alternatively you can run:" echo "'$bindir/mysql_secure_installation'" echo echo "which will also give you the option of removing the test" diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 126eb924814..75a613b27cc 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -73,12 +73,14 @@ usage () { cat <<EOF Usage: $0 [OPTIONS] --no-defaults Don't read the system defaults file - --core-file-size=LIMIT Limit core files to the specified size --defaults-file=FILE Use the specified defaults file --defaults-extra-file=FILE Also use defaults from the specified file + --defaults-group-suffix=X Additionally read default groups with X appended + as a suffix --ledir=DIRECTORY Look for mysqld in the specified directory --open-files-limit=LIMIT Limit the number of open files --crash-script=FILE Script to call when mysqld crashes + --core-file-size=LIMIT Limit core files to the specified size --timezone=TZ Set the system timezone --malloc-lib=LIB Preload shared library LIB if available --mysqld=FILE Use the specified file as mysqld diff --git a/sql/backup.cc b/sql/backup.cc index e89f9a108a7..539dc9c31f4 100644 --- a/sql/backup.cc +++ b/sql/backup.cc @@ -34,6 +34,7 @@ #include "sql_insert.h" // kill_delayed_threads #include "sql_handler.h" // mysql_ha_cleanup_no_free #include <my_sys.h> +#include "wsrep_mysqld.h" static const char *stage_names[]= {"START", "FLUSH", "BLOCK_DDL", "BLOCK_COMMIT", "END", 0}; @@ -255,6 +256,21 @@ static bool backup_block_ddl(THD *thd) (void) flush_tables(thd, FLUSH_NON_TRANS_TABLES); thd->clear_error(); +#ifdef WITH_WSREP + /* + We desync the node for BACKUP STAGE because applier threads + bypass backup MDL locks (see MDL_lock::can_grant_lock) + */ + if (WSREP_NNULL(thd)) + { + Wsrep_server_state &server_state= Wsrep_server_state::instance(); + if (server_state.desync_and_pause().is_undefined()) { + DBUG_RETURN(1); + } + thd->wsrep_desynced_backup_stage= true; + } +#endif /* WITH_WSREP */ + /* block new DDL's, in addition to all previous blocks We didn't do this lock above, as we wanted DDL's to be executed while @@ -319,6 +335,14 @@ bool backup_end(THD *thd) ha_end_backup(); thd->current_backup_stage= BACKUP_FINISHED; thd->mdl_context.release_lock(backup_flush_ticket); +#ifdef WITH_WSREP + if (WSREP_NNULL(thd) && thd->wsrep_desynced_backup_stage) + { + Wsrep_server_state &server_state= Wsrep_server_state::instance(); + server_state.resume_and_resync(); + thd->wsrep_desynced_backup_stage= false; + } +#endif /* WITH_WSREP */ } DBUG_RETURN(0); } diff --git a/sql/field.cc b/sql/field.cc index ab4f6a96921..71ca27c5ad0 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6399,6 +6399,7 @@ bool Field_timef::val_native(Native *to) int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs) { DBUG_ASSERT(marked_for_write_or_computed()); + THD *thd= get_thd(); char *end; int error; longlong nr= cs->strntoull10rnd(from, len, 0, &end, &error); @@ -6410,7 +6411,14 @@ int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs) set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); return 1; } - if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION && + + if (thd->count_cuted_fields <= CHECK_FIELD_EXPRESSION && error == MY_ERRNO_EDOM) + { + *ptr= 0; + return 1; + } + + if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION && (error= check_int(cs, from, len, end, error))) { if (unlikely(error == 1) /* empty or incorrect string */) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 6b7f6a880d9..2c60a98de33 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5572,8 +5572,7 @@ int ha_partition::index_init(uint inx, bool sorted) do { for (i= 0; i < (*key_info)->user_defined_key_parts; i++) - bitmap_set_bit(table->read_set, - (*key_info)->key_part[i].field->field_index); + (*key_info)->key_part[i].field->register_field_in_read_map(); } while (*(++key_info)); } for (i= bitmap_get_first_set(&m_part_info->read_partitions); diff --git a/sql/handler.cc b/sql/handler.cc index 112ed23939e..7e5975d7477 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1686,13 +1686,27 @@ int ha_commit_trans(THD *thd, bool all) goto err; } DBUG_ASSERT(trx_start_id); +#ifdef WITH_WSREP + bool saved_wsrep_on= thd->variables.wsrep_on; + thd->variables.wsrep_on= false; +#endif TR_table trt(thd, true); if (trt.update(trx_start_id, trx_end_id)) +#ifdef WITH_WSREP + { + thd->variables.wsrep_on= saved_wsrep_on; +#endif goto err; +#ifdef WITH_WSREP + } +#endif // Here, the call will not commit inside InnoDB. It is only working // around closing thd->transaction.stmt open by TR_table::open(). if (all) commit_one_phase_2(thd, false, &thd->transaction->stmt, false); +#ifdef WITH_WSREP + thd->variables.wsrep_on= saved_wsrep_on; +#endif } } #endif diff --git a/sql/item.cc b/sql/item.cc index 6e45c6a8086..8f6bfdc6b09 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4422,13 +4422,15 @@ bool Item_param::get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate) } -double Item_param::PValue::val_real() const +double Item_param::PValue::val_real(const Type_std_attributes *attr) const { switch (type_handler()->cmp_type()) { case REAL_RESULT: return real; case INT_RESULT: - return (double) integer; + return attr->unsigned_flag + ? (double) (ulonglong) integer + : (double) integer; case DECIMAL_RESULT: return m_decimal.to_double(); case STRING_RESULT: @@ -4502,7 +4504,7 @@ String *Item_param::PValue::val_str(String *str, str->set_real(real, NOT_FIXED_DEC, &my_charset_bin); return str; case INT_RESULT: - str->set(integer, &my_charset_bin); + str->set_int(integer, attr->unsigned_flag, &my_charset_bin); return str; case DECIMAL_RESULT: if (m_decimal.to_string_native(str, 0, 0, 0) <= 1) diff --git a/sql/item.h b/sql/item.h index 74ffce6153f..2720dddefd9 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3930,7 +3930,7 @@ class Item_param :public Item_basic_value, m_string.swap(other.m_string); m_string_ptr.swap(other.m_string_ptr); } - double val_real() const; + double val_real(const Type_std_attributes *attr) const; longlong val_int(const Type_std_attributes *attr) const; my_decimal *val_decimal(my_decimal *dec, const Type_std_attributes *attr); String *val_str(String *str, const Type_std_attributes *attr); @@ -4026,7 +4026,7 @@ public: double val_real() override { - return can_return_value() ? value.val_real() : 0e0; + return can_return_value() ? value.val_real(this) : 0e0; } longlong val_int() override { @@ -6448,12 +6448,15 @@ public: class Item_default_value : public Item_field { + bool vcol_assignment_ok; void calculate(); public: Item *arg= nullptr; Field *cached_field= nullptr; - Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a) : - Item_field(thd, context_arg), arg(a) {} + Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a, + bool vcol_assignment_arg) + : Item_field(thd, context_arg), + vcol_assignment_ok(vcol_assignment_arg), arg(a) {} Type type() const override { return DEFAULT_VALUE_ITEM; } bool eq(const Item *item, bool binary_cmp) const override; bool fix_fields(THD *, Item **) override; @@ -6492,6 +6495,8 @@ public: if (field && field->default_value) field->default_value->expr->update_used_tables(); } + bool vcol_assignment_allowed_value() const override + { return vcol_assignment_ok; } Field *get_tmp_table_field() override { return nullptr; } Item *get_tmp_table_item(THD *) override { return this; } Item_field *field_for_view_update() override { return nullptr; } diff --git a/sql/item_func.cc b/sql/item_func.cc index b3f60e052ae..60efc55d878 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5863,7 +5863,7 @@ void Item_func_get_system_var::update_null_value() bool Item_func_get_system_var::fix_length_and_dec() { - char *cptr; + const char *cptr; maybe_null= TRUE; max_length= 0; @@ -5897,9 +5897,12 @@ bool Item_func_get_system_var::fix_length_and_dec() case SHOW_CHAR: case SHOW_CHAR_PTR: mysql_mutex_lock(&LOCK_global_system_variables); - cptr= var->show_type() == SHOW_CHAR ? - (char*) var->value_ptr(current_thd, var_type, &component) : - *(char**) var->value_ptr(current_thd, var_type, &component); + cptr= var->show_type() == SHOW_CHAR ? + reinterpret_cast<const char*>(var->value_ptr(current_thd, var_type, + &component)) : + *reinterpret_cast<const char* const*>(var->value_ptr(current_thd, + var_type, + &component)); if (cptr) max_length= (uint32) system_charset_info->numchars(cptr, cptr + strlen(cptr)); @@ -5911,7 +5914,10 @@ bool Item_func_get_system_var::fix_length_and_dec() case SHOW_LEX_STRING: { mysql_mutex_lock(&LOCK_global_system_variables); - LEX_STRING *ls= ((LEX_STRING*)var->value_ptr(current_thd, var_type, &component)); + const LEX_STRING *ls= + reinterpret_cast<const LEX_STRING*>(var->value_ptr(current_thd, + var_type, + &component)); max_length= (uint32) system_charset_info->numchars(ls->str, ls->str + ls->length); mysql_mutex_unlock(&LOCK_global_system_variables); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 27f00c308d4..fb359884f13 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -495,7 +495,7 @@ err: const char *histogram_types[] = {"SINGLE_PREC_HB", "DOUBLE_PREC_HB", 0}; -static TYPELIB hystorgam_types_typelib= +static TYPELIB histogram_types_typelib= { array_elements(histogram_types), "histogram_types", histogram_types, NULL}; @@ -511,7 +511,7 @@ String *Item_func_decode_histogram::val_str(String *str) tmp.length(0); if (!(res= args[0]->val_str(&tmp)) || (type= find_type(res->c_ptr_safe(), - &hystorgam_types_typelib, MYF(0))) <= 0) + &histogram_types_typelib, MYF(0))) <= 0) { null_value= 1; return 0; @@ -596,7 +596,7 @@ bool Item_func_concat::realloc_result(String *str, uint length) const as str was initially set by args[0]->val_str(str). So multiplication by 2 can overflow, if args[0] for some reasons did not limit the result to max_alloced_packet. But it's not harmful, - "str" will be realloced exactly to "length" bytes in case of overflow. + "str" will be reallocated exactly to "length" bytes in case of overflow. */ uint new_length= MY_MAX(str->alloced_length() * 2, length); return str->realloc(new_length); @@ -1510,7 +1510,7 @@ String *Item_func_insert::val_str(String *str) start--; /* - There is one exception not handled (intentionaly) by the character set + There is one exception not handled (intentionally) by the character set aggregation code. If one string is strong side and is binary, and another one is weak side and is a multi-byte character string, then we need to operate on the second string in terms on bytes when @@ -3200,6 +3200,14 @@ err: } +static String *default_pad_str(String *pad_str, CHARSET_INFO *collation) +{ + pad_str->set_charset(collation); + pad_str->length(0); + pad_str->append(" ", 1); + return pad_str; +} + bool Item_func_pad::fix_length_and_dec() { if (arg_count == 3) @@ -3215,9 +3223,7 @@ bool Item_func_pad::fix_length_and_dec() { if (agg_arg_charsets_for_string_result(collation, &args[0], 1, 1)) return TRUE; - pad_str.set_charset(collation.collation); - pad_str.length(0); - pad_str.append(" ", 1); + default_pad_str(&pad_str, collation.collation); } DBUG_ASSERT(collation.collation->mbmaxlen > 0); @@ -3240,9 +3246,9 @@ bool Item_func_pad::fix_length_and_dec() Sql_mode_dependency Item_func_rpad::value_depends_on_sql_mode() const { DBUG_ASSERT(fixed); - DBUG_ASSERT(arg_count == 3); + DBUG_ASSERT(arg_count >= 2); if (!args[1]->value_depends_on_sql_mode_const_item() || - !args[2]->value_depends_on_sql_mode_const_item()) + (arg_count == 3 && !args[2]->value_depends_on_sql_mode_const_item())) return Item_func::value_depends_on_sql_mode(); Longlong_hybrid len= args[1]->to_longlong_hybrid(); if (args[1]->null_value || len.neg()) @@ -3250,7 +3256,8 @@ Sql_mode_dependency Item_func_rpad::value_depends_on_sql_mode() const if (len.abs() > 0 && len.abs() < args[0]->max_char_length()) return Item_func::value_depends_on_sql_mode(); StringBuffer<64> padstrbuf; - String *padstr= args[2]->val_str(&padstrbuf); + String *padstr= arg_count == 3 ? args[2]->val_str(&padstrbuf) : + default_pad_str(&padstrbuf, collation.collation); if (!padstr || !padstr->length()) return Sql_mode_dependency(); // will return NULL if (padstr->lengthsp() != 0) @@ -3290,7 +3297,7 @@ String *Item_func_rpad::val_str(String *str) if ((ulonglong) count > INT_MAX32) count= INT_MAX32; /* - There is one exception not handled (intentionaly) by the character set + There is one exception not handled (intentionally) by the character set aggregation code. If one string is strong side and is binary, and another one is weak side and is a multi-byte character string, then we need to operate on the second string in terms on bytes when @@ -3383,7 +3390,7 @@ String *Item_func_lpad::val_str(String *str) count= INT_MAX32; /* - There is one exception not handled (intentionaly) by the character set + There is one exception not handled (intentionally) by the character set aggregation code. If one string is strong side and is binary, and another one is weak side and is a multi-byte character string, then we need to operate on the second string in terms on bytes when @@ -4190,7 +4197,7 @@ longlong Item_func_uncompressed_length::val_int() 5 bytes long. res->c_ptr() is not used because: - we do not need \0 terminated string to get first 4 bytes - - c_ptr() tests simbol after string end (uninitialiozed memory) which + - c_ptr() tests simbol after string end (uninitialized memory) which confuse valgrind */ return uint4korr(res->ptr()) & 0x3FFFFFFF; diff --git a/sql/key.cc b/sql/key.cc index 53f897de15f..79f1c55b61c 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -466,7 +466,7 @@ void key_unpack(String *to, TABLE *table, KEY *key) bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields) { - table->mark_columns_used_by_index(idx, &table->tmp_set); + table->mark_index_columns(idx, &table->tmp_set); return bitmap_is_overlapping(&table->tmp_set, fields); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index cb87cb737c3..072cd42cc23 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -442,7 +442,7 @@ ulong delay_key_write_options; uint protocol_version; uint lower_case_table_names; ulong tc_heuristic_recover= 0; -Atomic_counter<uint32_t> thread_count; +Atomic_counter<uint32_t> THD_count::count, CONNECT::count; bool shutdown_wait_for_slaves; Atomic_counter<uint32_t> slave_open_temp_tables; ulong thread_created; @@ -1715,6 +1715,9 @@ static void close_connections(void) #endif end_thr_alarm(0); // Abort old alarms. + while (CONNECT::count) + my_sleep(100); + /* First signal all threads that it's time to die This will give the threads some time to gracefully abort their @@ -1741,9 +1744,9 @@ static void close_connections(void) much smaller than even 2 seconds, this is only a safety fallback against stuck threads so server shutdown is not held up forever. */ - DBUG_PRINT("info", ("thread_count: %u", uint32_t(thread_count))); + DBUG_PRINT("info", ("THD_count: %u", THD_count::value())); - for (int i= 0; (thread_count - binlog_dump_thread_count) && i < 1000; i++) + for (int i= 0; (THD_count::value() - binlog_dump_thread_count) && i < 1000; i++) my_sleep(20000); if (global_system_variables.log_warnings) @@ -1756,15 +1759,14 @@ static void close_connections(void) } #endif /* All threads has now been aborted */ - DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", - uint32_t(thread_count))); + DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", THD_count::value())); - while (thread_count - binlog_dump_thread_count) + while (THD_count::value() - binlog_dump_thread_count) my_sleep(1000); /* Kill phase 2 */ server_threads.iterate(kill_thread_phase_2); - for (uint64 i= 0; thread_count; i++) + for (uint64 i= 0; THD_count::value(); i++) { /* This time the warnings are emitted within the loop to provide a @@ -7694,7 +7696,7 @@ static int mysql_init_variables(void) mqh_used= 0; cleanup_done= 0; test_flags= select_errors= dropping_tables= ha_open_options=0; - thread_count= 0; + THD_count::count= CONNECT::count= 0; slave_open_temp_tables= 0; opt_endinfo= using_udf_functions= 0; opt_using_transactions= 0; diff --git a/sql/mysqld.h b/sql/mysqld.h index 8ca3a109333..142d2dbafb0 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -192,7 +192,8 @@ enum vers_system_time_t struct vers_asof_timestamp_t { ulong type; - MYSQL_TIME ltime; + my_time_t unix_time; + ulong second_part; }; enum vers_alter_history_enum @@ -756,7 +757,6 @@ extern mysql_rwlock_t LOCK_ssl_refresh; extern mysql_prlock_t LOCK_system_variables_hash; extern mysql_cond_t COND_start_thread; extern mysql_cond_t COND_manager; -extern Atomic_counter<uint32_t> thread_count; extern my_bool opt_use_ssl; extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, diff --git a/sql/set_var.cc b/sql/set_var.cc index fe98d98fbd4..9744f0f6f39 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -231,12 +231,12 @@ bool sys_var::update(THD *thd, set_var *var) } } -uchar *sys_var::session_value_ptr(THD *thd, const LEX_CSTRING *base) +const uchar *sys_var::session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return session_var_ptr(thd); } -uchar *sys_var::global_value_ptr(THD *thd, const LEX_CSTRING *base) +const uchar *sys_var::global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return global_var_ptr(); } @@ -269,8 +269,8 @@ bool sys_var::check(THD *thd, set_var *var) return false; } -uchar *sys_var::value_ptr(THD *thd, enum_var_type type, - const LEX_CSTRING *base) +const uchar *sys_var::value_ptr(THD *thd, enum_var_type type, + const LEX_CSTRING *base) const { DBUG_ASSERT(base); if (type == OPT_GLOBAL || scope() == GLOBAL) @@ -1063,7 +1063,7 @@ int set_var_collation_client::update(THD *thd) INFORMATION_SCHEMA.SYSTEM_VARIABLES *****************************************************************************/ static void store_value_ptr(Field *field, sys_var *var, String *str, - uchar *value_ptr) + const uchar *value_ptr) { field->set_notnull(); str= var->val_str_nolock(str, field->table->in_use, value_ptr); @@ -1133,8 +1133,8 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond) fields[3]->store(origin->str, origin->length, scs); // DEFAULT_VALUE - uchar *def= var->is_readonly() && var->option.id < 0 - ? 0 : var->default_value_ptr(thd); + const uchar *def= var->is_readonly() && var->option.id < 0 + ? 0 : var->default_value_ptr(thd); if (def) store_value_ptr(fields[4], var, &strbuf, def); diff --git a/sql/set_var.h b/sql/set_var.h index 18c4dbc664e..2d538624825 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -112,7 +112,7 @@ public: virtual sys_var_pluginvar *cast_pluginvar() { return 0; } bool check(THD *thd, set_var *var); - uchar *value_ptr(THD *thd, enum_var_type type, const LEX_CSTRING *base); + const uchar *value_ptr(THD *thd, enum_var_type type, const LEX_CSTRING *base) const; /** Update the system variable with the default value from either @@ -127,7 +127,7 @@ public: String *val_str(String *str, THD *thd, enum_var_type type, const LEX_CSTRING *base); double val_real(bool *is_null, THD *thd, enum_var_type type, const LEX_CSTRING *base); - SHOW_TYPE show_type() { return show_val_type; } + SHOW_TYPE show_type() const { return show_val_type; } int scope() const { return flags & SCOPE_MASK; } virtual CHARSET_INFO *charset(THD *thd) const { @@ -211,7 +211,7 @@ public: */ virtual bool session_is_default(THD *thd) { return false; } - virtual uchar *default_value_ptr(THD *thd) + virtual const uchar *default_value_ptr(THD *thd) const { return (uchar*)&option.def_value; } virtual bool on_check_access_global(THD *thd) const; @@ -239,18 +239,18 @@ protected: It must be of show_val_type type (my_bool for SHOW_MY_BOOL, int for SHOW_INT, longlong for SHOW_LONGLONG, etc). */ - virtual uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base); - virtual uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base); + virtual const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const; + virtual const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const; /** A pointer to a storage area of the variable, to the raw data. Typically it's the same as session_value_ptr(), but it's different, for example, for ENUM, that is printed as a string, but stored as a number. */ - uchar *session_var_ptr(THD *thd) + uchar *session_var_ptr(THD *thd) const { return ((uchar*)&(thd->variables)) + offset; } - uchar *global_var_ptr() + uchar *global_var_ptr() const { return ((uchar*)&global_system_variables) + offset; } void *max_var_ptr() @@ -292,6 +292,16 @@ public: /** + Structure for holding unix timestamp and high precision second part. + */ +typedef struct my_time_t_hires +{ + my_time_t unix_time; + ulong second_part; +} my_time_t_hires; + + +/** set_var_base descendant for assignments to the system variables. */ class set_var :public set_var_base @@ -309,6 +319,7 @@ public: plugin_ref *plugins; ///< for Sys_var_pluginlist Time_zone *time_zone; ///< for Sys_var_tz LEX_STRING string_value; ///< for Sys_var_charptr and others + my_time_t_hires timestamp; ///< for Sys_var_vers_asof const void *ptr; ///< for Sys_var_struct } save_result; LEX_CSTRING base; /**< for structured variables, like keycache_name.variable_name */ diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 6aac9ac5962..0cfe55fe254 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -187,7 +187,7 @@ extern "C" sig_handler handle_fatal_signal(int sig) (uint) thread_scheduler->max_threads + (uint) extra_max_connections); - my_safe_printf_stderr("thread_count=%u\n", (uint) thread_count); + my_safe_printf_stderr("thread_count=%u\n", THD_count::value()); if (dflt_key_cache && thread_scheduler) { diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 71b5defeef8..65f053aa09b 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3252,7 +3252,6 @@ end: my_error(ER_INVALID_ROLE, MYF(0), rolename); break; case 1: - StringBuffer<1024> c_usr; LEX_CSTRING role_lex; /* First, check if current user can see mysql database. */ bool read_access= !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1); @@ -3273,11 +3272,9 @@ end: NULL) == -1)) { /* Role is not granted but current user can see the role */ - c_usr.append(user, strlen(user)); - c_usr.append('@'); - c_usr.append(host, strlen(host)); - my_printf_error(ER_INVALID_ROLE, "User %`s has not been granted role %`s", - MYF(0), c_usr.c_ptr(), rolename); + my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s", + MYF(0), thd->security_ctx->priv_user, + thd->security_ctx->priv_host, rolename); } else { @@ -9416,14 +9413,13 @@ static bool show_default_role(THD *thd, ACL_USER *acl_entry, String def_str(buff, buffsize, system_charset_info); def_str.length(0); def_str.append(STRING_WITH_LEN("SET DEFAULT ROLE ")); - def_str.append(&def_rolename); - def_str.append(" FOR '"); - def_str.append(&acl_entry->user); + append_identifier(thd, &def_str, def_rolename.str, def_rolename.length); + def_str.append(" FOR "); + append_identifier(thd, &def_str, acl_entry->user.str, acl_entry->user.length); DBUG_ASSERT(!(acl_entry->flags & IS_ROLE)); - def_str.append(STRING_WITH_LEN("'@'")); - def_str.append(acl_entry->host.hostname, acl_entry->hostname_length, - system_charset_info); - def_str.append('\''); + def_str.append('@'); + append_identifier(thd, &def_str, acl_entry->host.hostname, + acl_entry->hostname_length); protocol->prepare_for_resend(); protocol->store(def_str.ptr(),def_str.length(),def_str.charset()); if (protocol->write()) diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index ec0bc7b0111..c62e4c1669c 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -906,7 +906,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, enum enum_field_types type= (*field_ptr)->type(); if (type < MYSQL_TYPE_MEDIUM_BLOB || type > MYSQL_TYPE_BLOB) - bitmap_set_bit(tab->read_set, fields); + tab->field[fields]->register_field_in_read_map(); else push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NO_EIS_FOR_FIELD, @@ -934,7 +934,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, enum enum_field_types type= tab->field[pos]->type(); if (type < MYSQL_TYPE_MEDIUM_BLOB || type > MYSQL_TYPE_BLOB) - bitmap_set_bit(tab->read_set, pos); + tab->field[pos]->register_field_in_read_map(); else push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NO_EIS_FOR_FIELD, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index bb076ba9f3f..a9d7de9a9b0 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6211,7 +6211,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, TABLE *table= field_to_set->table; DBUG_ASSERT(table); if (thd->column_usage == MARK_COLUMNS_READ) - bitmap_set_bit(table->read_set, field_to_set->field_index); + field_to_set->register_field_in_read_map(); else bitmap_set_bit(table->write_set, field_to_set->field_index); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 8b61750ffca..31d9979b22c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1306,6 +1306,7 @@ void THD::init() wsrep_affected_rows = 0; m_wsrep_next_trx_id = WSREP_UNDEFINED_TRX_ID; wsrep_aborter = 0; + wsrep_desynced_backup_stage= false; #endif /* WITH_WSREP */ if (variables.sql_log_bin) @@ -4886,7 +4887,7 @@ MYSQL_THD create_background_thd() in THD constructor. We do not want these THDs to be counted, or waited for on shutdown. */ - thread_count--; + THD_count::count--; thd->mysys_var= (st_my_thread_var *) thd_mysysvar; thd->set_command(COM_DAEMON); @@ -4942,7 +4943,7 @@ void destroy_background_thd(MYSQL_THD thd) As we decremented it in create_background_thd(), in order for it not to go negative, we have to increment it before destructor. */ - thread_count++; + THD_count::count++; delete thd; thd_detach_thd(save_mysys_var); @@ -7071,8 +7072,8 @@ void THD::binlog_prepare_row_images(TABLE *table) { case BINLOG_ROW_IMAGE_MINIMAL: /* MINIMAL: Mark only PK */ - table->mark_columns_used_by_index(table->s->primary_key, - &table->tmp_set); + table->mark_index_columns(table->s->primary_key, + &table->tmp_set); break; case BINLOG_ROW_IMAGE_NOBLOB: /** diff --git a/sql/sql_class.h b/sql/sql_class.h index 62ce5c8a2d2..ec031bf06e6 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1080,6 +1080,23 @@ public: static THD_list_iterator *iterator(); }; +/** + A counter of THDs + + It must be specified as a first base class of THD, so that increment is + done before any other THD constructors and decrement - after any other THD + destructors. + + Destructor unblocks close_conneciton() if there are no more THD's left. +*/ +struct THD_count +{ + static Atomic_counter<uint32_t> count; + static uint value() { return static_cast<uint>(count); } + THD_count() { count++; } + ~THD_count() { count--; } +}; + #ifdef MYSQL_SERVER void free_tmp_table(THD *thd, TABLE *entry); @@ -2269,22 +2286,6 @@ public: }; /** - A wrapper around thread_count. - - It must be specified as a first base class of THD, so that increment is - done before any other THD constructors and decrement - after any other THD - destructors. - - Destructor unblocks close_conneciton() if there are no more THD's left. -*/ -struct THD_count -{ - THD_count() { thread_count++; } - ~THD_count() { thread_count--; } -}; - - -/** @class THD For each client connection we create a separate thread with THD serving as a thread/connection descriptor @@ -3152,6 +3153,9 @@ public: uint server_status,open_options; enum enum_thread_type system_thread; enum backup_stages current_backup_stage; +#ifdef WITH_WSREP + bool wsrep_desynced_backup_stage; +#endif /* WITH_WSREP */ /* Current or next transaction isolation level. When a connection is established, the value is taken from diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index e0119e50eaa..999830ff67e 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1359,6 +1359,14 @@ void do_handle_one_connection(CONNECT *connect, bool put_in_cache) return; } + DBUG_EXECUTE_IF("CONNECT_wait", + { + extern MYSQL_SOCKET unix_sock; + DBUG_ASSERT(unix_sock.fd >= 0); + while (unix_sock.fd >= 0) + my_sleep(1000); + }); + /* If a thread was created to handle this connection: increment slow_launch_threads counter if it took more than @@ -1372,10 +1380,10 @@ void do_handle_one_connection(CONNECT *connect, bool put_in_cache) if (launch_time >= slow_launch_time*1000000L) statistic_increment(slow_launch_threads, &LOCK_status); } - delete connect; - /* Make THD visible in show processlist */ - server_threads.insert(thd); + server_threads.insert(thd); // Make THD visible in show processlist + + delete connect; // must be after server_threads.insert, see close_connections() thd->thr_create_utime= thr_create_utime; /* We need to set this because of time_out_user_resource_limits */ diff --git a/sql/sql_connect.h b/sql/sql_connect.h index 152bd71afd7..1a84cb56e5c 100644 --- a/sql/sql_connect.h +++ b/sql/sql_connect.h @@ -44,11 +44,20 @@ public: /* Own variables */ ulonglong prior_thr_create_utime; + static Atomic_counter<uint32_t> count; + CONNECT(MYSQL_SOCKET sock_arg, enum enum_vio_type vio_type_arg, scheduler_functions *scheduler_arg): sock(sock_arg), vio_type(vio_type_arg), scheduler(scheduler_arg), thread_id(0), - prior_thr_create_utime(0) {} - ~CONNECT() { DBUG_ASSERT(vio_type == VIO_CLOSED); } + prior_thr_create_utime(0) + { + count++; + } + ~CONNECT() + { + count--; + DBUG_ASSERT(vio_type == VIO_CLOSED); + } void close_and_delete(); void close_with_error(uint sql_errno, const char *message, uint close_error); diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 2403a6d9f17..c53ae300d0d 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -938,7 +938,8 @@ bool With_clause::prepare_unreferenced_elements(THD *thd) with_elem; with_elem= with_elem->next) { - if (!with_elem->is_referenced() && with_elem->prepare_unreferenced(thd)) + if ((with_elem->is_hanging_recursive() || !with_elem->is_referenced()) && + with_elem->prepare_unreferenced(thd)) return true; } @@ -1126,14 +1127,6 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex, lex->unit.include_down(with_table->select_lex); lex->unit.set_slave(with_select); lex->unit.cloned_from= spec; - last_clone_select= lex->all_selects_list; - while (last_clone_select->next_select_in_list()) - last_clone_select= last_clone_select->next_select_in_list(); - old_lex->all_selects_list= - (st_select_lex*) (lex->all_selects_list-> - insert_chain_before( - (st_select_lex_node **) &(old_lex->all_selects_list), - last_clone_select)); /* Now all references to the CTE defined outside of the cloned specification @@ -1149,6 +1142,15 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex, goto err; } + last_clone_select= lex->all_selects_list; + while (last_clone_select->next_select_in_list()) + last_clone_select= last_clone_select->next_select_in_list(); + old_lex->all_selects_list= + (st_select_lex*) (lex->all_selects_list-> + insert_chain_before( + (st_select_lex_node **) &(old_lex->all_selects_list), + last_clone_select)); + lex->sphead= NULL; // in order not to delete lex->sphead lex_end(lex); err: @@ -1323,6 +1325,7 @@ bool With_element::is_anchor(st_select_lex *sel) With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table) { With_element *found= NULL; + With_clause *containing_with_clause= NULL; st_select_lex_unit *master_unit; st_select_lex *outer_sl; for (st_select_lex *sl= this; sl; sl= outer_sl) @@ -1335,6 +1338,7 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table) */ With_clause *attached_with_clause= sl->get_with_clause(); if (attached_with_clause && + attached_with_clause != containing_with_clause && (found= attached_with_clause->find_table_def(table, NULL))) break; master_unit= sl->master_unit(); @@ -1342,7 +1346,7 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table) With_element *with_elem= sl->get_with_element(); if (with_elem) { - With_clause *containing_with_clause= with_elem->get_owner(); + containing_with_clause= with_elem->get_owner(); With_element *barrier= containing_with_clause->with_recursive ? NULL : with_elem; if ((found= containing_with_clause->find_table_def(table, barrier))) diff --git a/sql/sql_cte.h b/sql/sql_cte.h index 44628df3ff8..4cec1240d1f 100644 --- a/sql/sql_cte.h +++ b/sql/sql_cte.h @@ -262,6 +262,8 @@ public: bool is_referenced() { return referenced; } + bool is_hanging_recursive() { return is_recursive && !rec_outer_references; } + void inc_references() { references++; } bool process_columns_of_derived_unit(THD *thd, st_select_lex_unit *unit); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9d3444a5ac6..c1cb45d5d69 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4680,8 +4680,17 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u) } if (!(table= create_table_from_items(thd, &values, &extra_lock, hook_ptr))) + { + if (create_info->or_replace()) + { + /* Original table was deleted. We have to log it */ + log_drop_table(thd, &create_table->db, &create_table->table_name, + thd->lex->tmp_table()); + } + /* abort() deletes table */ DBUG_RETURN(-1); + } if (create_info->tmp_table()) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5784c10a29c..5a39b380855 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -11613,3 +11613,23 @@ bool LEX::map_data_type(const Lex_ident_sys_st &schema_name, type->set_handler(mapped); return false; } + + +bool SELECT_LEX_UNIT::explainable() const +{ + /* + EXPLAIN/ANALYZE unit, when: + (1) if it's a subquery - it's not part of eliminated WHERE/ON clause. + (2) if it's a CTE - it's not hanging (needed for execution) + (3) if it's a derived - it's not merged + if it's not 1/2/3 - it's some weird internal thing, ignore it + */ + return item ? + !item->eliminated : // (1) + with_element ? + derived && derived->derived_result && + !with_element->is_hanging_recursive(): // (2) + derived ? + derived->is_materialized_derived() : // (3) + false; +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index d0ccf19ddab..d9e29b06a91 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1022,20 +1022,7 @@ public: int save_union_explain_part2(Explain_query *output); unit_common_op common_op(); - bool explainable() const - { - /* - EXPLAIN/ANALYZE unit, when: - (1) if it's a subquery - it's not part of eliminated WHERE/ON clause. - (2) if it's a CTE - it's not hanging (needed for execution) - (3) if it's a derived - it's not merged - if it's not 1/2/3 - it's some weird internal thing, ignore it - */ - return item ? !item->eliminated : // (1) - with_element ? derived && derived->derived_result : // (2) - derived ? derived->is_materialized_derived() : // (3) - false; - } + bool explainable() const; void reset_distinct(); void fix_distinct(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 19f80606e34..64aca9fb87d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2264,11 +2264,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, size_t length= #endif my_snprintf(buff, buff_len - 1, - "Uptime: %lu Threads: %d Questions: %lu " + "Uptime: %lu Threads: %u Questions: %lu " "Slow queries: %lu Opens: %lu " "Open tables: %u Queries per second avg: %u.%03u", - uptime, - (int) thread_count, (ulong) thd->query_id, + uptime, THD_count::value(), (ulong) thd->query_id, current_global_status_var->long_query_count, current_global_status_var->opened_tables, tc_records(), @@ -5726,6 +5725,11 @@ mysql_execute_command(THD *thd) /* Begin transaction with the same isolation level. */ if (tx_chain) { +#ifdef WITH_WSREP + /* If there are pending changes after rollback we should clear them */ + if (wsrep_on(thd) && wsrep_has_changes(thd)) + wsrep_after_statement(thd); +#endif if (trans_begin(thd)) goto error; } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 74f2e1b33f1..114b1a19af7 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -3639,6 +3639,17 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info, if (part_func_value >= part_end_val && (loc_part_id < max_partition || !part_info->defined_max_value)) loc_part_id++; + if (part_info->part_type == VERSIONING_PARTITION && + part_func_value < INT_MAX32 && + loc_part_id > part_info->vers_info->hist_part->id) + { + /* + Historical query with AS OF point after the last history partition must + include last history partition because it can be overflown (contain + history rows out of right endpoint). + */ + loc_part_id= part_info->vers_info->hist_part->id; + } } else { diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 02ae08c910c..330d8b668ed 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -313,14 +313,14 @@ public: sys_var_pluginvar(sys_var_chain *chain, const char *name_arg, st_plugin_int *p, st_mysql_sys_var *plugin_var_arg); sys_var_pluginvar *cast_pluginvar() { return this; } - uchar* real_value_ptr(THD *thd, enum_var_type type); - TYPELIB* plugin_var_typelib(void); - uchar* do_value_ptr(THD *thd, enum_var_type type, const LEX_CSTRING *base); - uchar* session_value_ptr(THD *thd, const LEX_CSTRING *base) + uchar* real_value_ptr(THD *thd, enum_var_type type) const; + TYPELIB* plugin_var_typelib(void) const; + const uchar* do_value_ptr(THD *thd, enum_var_type type, const LEX_CSTRING *base) const; + const uchar* session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return do_value_ptr(thd, OPT_SESSION, base); } - uchar* global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar* global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return do_value_ptr(thd, OPT_GLOBAL, base); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return do_value_ptr(thd, OPT_DEFAULT, 0); } bool do_check(THD *thd, set_var *var); virtual void session_save_default(THD *thd, set_var *var) {} @@ -3423,7 +3423,7 @@ sys_var_pluginvar::sys_var_pluginvar(sys_var_chain *chain, const char *name_arg, plugin_opt_set_limits(&option, pv); } -uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type) +uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type) const { if (type == OPT_DEFAULT) { @@ -3497,7 +3497,7 @@ bool sys_var_pluginvar::session_is_default(THD *thd) } -TYPELIB* sys_var_pluginvar::plugin_var_typelib(void) +TYPELIB* sys_var_pluginvar::plugin_var_typelib(void) const { switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) { case PLUGIN_VAR_ENUM: @@ -3515,12 +3515,10 @@ TYPELIB* sys_var_pluginvar::plugin_var_typelib(void) } -uchar* sys_var_pluginvar::do_value_ptr(THD *thd, enum_var_type type, - const LEX_CSTRING *base) +const uchar* sys_var_pluginvar::do_value_ptr(THD *thd, enum_var_type type, + const LEX_CSTRING *base) const { - uchar* result; - - result= real_value_ptr(thd, type); + const uchar* result= real_value_ptr(thd, type); if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_ENUM) result= (uchar*) get_type(plugin_var_typelib(), *(ulong*)result); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 70d9dd783c8..b1a5a3e7199 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1570,7 +1570,12 @@ static int mysql_test_select(Prepared_statement *stmt, if (!lex->describe && !thd->lex->analyze_stmt && !stmt->is_sql_prepare()) { /* Make copy of item list, as change_columns may change it */ - List<Item> fields(lex->first_select_lex()->item_list); + SELECT_LEX_UNIT* master_unit= unit->first_select()->master_unit(); + bool is_union_op= + master_unit->is_unit_op() || master_unit->fake_select_lex; + + List<Item> fields(is_union_op ? unit->item_list : + lex->first_select_lex()->item_list); /* Change columns if a procedure like analyse() */ if (unit->last_procedure && unit->last_procedure->change_columns(thd, fields)) @@ -1692,7 +1697,7 @@ static bool mysql_test_call_fields(Prepared_statement *stmt, while ((item= it++)) { - if (item->fix_fields_if_needed_for_scalar(thd, it.ref())) + if (item->fix_fields_if_needed(thd, it.ref())) goto err; } DBUG_RETURN(FALSE); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 80bc24cd3cd..9c76ecc5dbf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -768,7 +768,8 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd) if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL) { DBUG_ASSERT(type == SYSTEM_TIME_AS_OF); - Datetime dt(&in.ltime); + Datetime dt(in.unix_time, in.second_part, thd->variables.time_zone); + start.item= new (thd->mem_root) Item_datetime_literal(thd, &dt, TIME_SECOND_PART_DIGITS); if (!start.item) @@ -2072,7 +2073,7 @@ JOIN::optimize_inner() sel->attach_to_conds.empty(); } } - + if (optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_SUBQUERY)) { TABLE_LIST *tbl; @@ -2341,7 +2342,7 @@ int JOIN::optimize_stage2() /* Generate an execution plan from the found optimal join order. */ if (get_best_combination()) DBUG_RETURN(1); - + if (make_range_rowid_filters()) DBUG_RETURN(1); @@ -3254,8 +3255,17 @@ bool JOIN::make_aggr_tables_info() if (ht && ht->create_group_by) { - /* Check if the storage engine can intercept the query */ - Query query= {&all_fields, select_distinct, tables_list, conds, + /* + Check if the storage engine can intercept the query + + JOIN::optimize_stage2() might convert DISTINCT into GROUP BY and then + optimize away GROUP BY (group_list). In such a case, we need to notify + a storage engine supporting a group by handler of the existence of the + original DISTINCT. Thus, we set select_distinct || group_optimized_away + to Query::distinct. + */ + Query query= {&all_fields, select_distinct || group_optimized_away, + tables_list, conds, group_list, order ? order : group_list, having, &select_lex->master_unit()->lim}; group_by_handler *gbh= ht->create_group_by(thd, &query); @@ -7450,7 +7460,7 @@ best_access_path(JOIN *join, Json_writer_object trace_wrapper(thd, "best_access_path"); Json_writer_array trace_paths(thd, "considered_access_paths"); - + bitmap_clear_all(eq_join_set); loose_scan_opt.init(join, s, remaining_tables); @@ -9244,7 +9254,9 @@ static double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, table_map rem_tables) { - uint16 ref_keyuse_steps[MAX_REF_PARTS - 1]; + uint16 ref_keyuse_steps_buf[MAX_REF_PARTS]; + uint ref_keyuse_size= MAX_REF_PARTS; + uint16 *ref_keyuse_steps= ref_keyuse_steps_buf; Field *field; TABLE *table= s->table; MY_BITMAP *read_set= table->read_set; @@ -9392,6 +9404,30 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, } if (keyparts > 1) { + /* + Prepare to set ref_keyuse_steps[keyparts-2]: resize the array + if it is not large enough + */ + if (keyparts - 2 >= ref_keyuse_size) + { + uint new_size= MY_MAX(ref_keyuse_size*2, keyparts); + void *new_buf; + if (!(new_buf= my_malloc(PSI_INSTRUMENT_ME, + sizeof(*ref_keyuse_steps)*new_size, + MYF(0)))) + { + sel= 1.0; // As if no selectivity was computed + goto exit; + } + memcpy(new_buf, ref_keyuse_steps, + sizeof(*ref_keyuse_steps)*ref_keyuse_size); + if (ref_keyuse_steps != ref_keyuse_steps_buf) + my_free(ref_keyuse_steps); + + ref_keyuse_steps= (uint16*)new_buf; + ref_keyuse_size= new_size; + } + ref_keyuse_steps[keyparts-2]= (uint16)(keyuse - prev_ref_keyuse); prev_ref_keyuse= keyuse; } @@ -9446,7 +9482,9 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables, keyparts, ref_keyuse_steps); - +exit: + if (ref_keyuse_steps != ref_keyuse_steps_buf) + my_free(ref_keyuse_steps); return sel; } @@ -23932,6 +23970,12 @@ check_reverse_order: if (select->quick == save_quick) save_quick= 0; // make_reverse() consumed it select->set_quick(tmp); + /* Cancel "Range checked for each record" */ + if (tab->use_quick == 2) + { + tab->use_quick= 1; + tab->read_first_record= join_init_read_record; + } } else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL && tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts) @@ -23944,6 +23988,12 @@ check_reverse_order: */ tab->read_first_record= join_read_last_key; tab->read_record.read_record_func= join_read_prev_same; + /* Cancel "Range checked for each record" */ + if (tab->use_quick == 2) + { + tab->use_quick= 1; + tab->read_first_record= join_init_read_record; + } /* Cancel Pushed Index Condition, as it doesn't work for reverse scans. */ @@ -28318,7 +28368,7 @@ void JOIN::cache_const_exprs() static bool get_range_limit_read_cost(const JOIN_TAB *tab, const TABLE *table, ha_rows table_records, - uint keynr, + uint keynr, ha_rows rows_limit, double *read_time) { @@ -28401,7 +28451,7 @@ static bool get_range_limit_read_cost(const JOIN_TAB *tab, to discount it from the rows_limit: */ double rows_limit_for_quick= rows_limit * (best_rows / table_records); - + if (best_rows > rows_limit_for_quick) { /* @@ -28684,7 +28734,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, refkey_rows_estimate is E(#rows) produced by the table access strategy that was picked without regard to ORDER BY ... LIMIT. - It will be used as the source of selectivity data. + It will be used as the source of selectivity data. Use table->cond_selectivity as a better estimate which includes condition selectivity too. */ @@ -28693,7 +28743,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, // cond_selectivity=1 while refkey_rows_estimate has a better // estimate. refkey_rows_estimate= MY_MIN(refkey_rows_estimate, - ha_rows(table_records * + ha_rows(table_records * table->cond_selectivity)); } @@ -28801,7 +28851,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, { possible_key.add("usable", false); possible_key.add("cause", "cost"); - } + } } else { @@ -29646,7 +29696,7 @@ void JOIN::init_join_cache_and_keyread() tuple. */ if (!(table->file->index_flags(table->file->keyread, 0, 1) & HA_CLUSTERED_INDEX)) - table->mark_columns_used_by_index(table->file->keyread, table->read_set); + table->mark_index_columns(table->file->keyread, table->read_set); } if (tab->cache && tab->cache->init(select_options & SELECT_DESCRIBE)) revise_cache_usage(tab); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f9546b79e6f..6ff9ef8a810 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3531,6 +3531,30 @@ ulonglong get_status_vars_version(void) } /** + A union holding a pointer to a type that can be referred by a status variable. + */ +union Any_pointer { + const void *as_void; + const uchar *as_uchar; + const char *as_char; + const char ** as_charptr; + const double *as_double; + const int * as_int; + const uint * as_uint; + const long *as_long; + const longlong *as_longlong; + const bool *as_bool; + const my_bool *as_my_bool; + const sys_var *as_sys_var; + const system_status_var *as_system_status_var; + const ha_rows *as_ha_rows; + const LEX_STRING *as_lex_cstring; + const SHOW_COMP_OPTION *as_show_comp_options; + intptr as_intptr; + Atomic_counter<uint32_t>* as_atomic_counter; +}; + +/** @brief Returns the value of a system or a status variable. @param thd [in] The handle of the current THD. @@ -3553,16 +3577,18 @@ const char* get_one_variable(THD *thd, const CHARSET_INFO **charset, char *buff, size_t *length) { - void *value= variable->value; + Any_pointer value, status_var_value; + value.as_void= variable->value; + status_var_value.as_system_status_var= status_var; const char *pos= buff; const char *end= buff; if (show_type == SHOW_SYS) { - sys_var *var= (sys_var *) value; + const sys_var *var= value.as_sys_var; show_type= var->show_type(); - value= var->value_ptr(thd, value_type, &null_clex_str); + value.as_uchar= var->value_ptr(thd, value_type, &null_clex_str); *charset= var->charset(thd); } @@ -3572,72 +3598,71 @@ const char* get_one_variable(THD *thd, */ switch (show_type) { case SHOW_DOUBLE_STATUS: - value= ((char *) status_var + (intptr) value); + value.as_char= status_var_value.as_char + value.as_intptr; /* fall through */ case SHOW_DOUBLE: /* 6 is the default precision for '%f' in sprintf() */ - end= buff + my_fcvt(*(double *) value, 6, buff, NULL); + end= buff + my_fcvt(*value.as_double, 6, buff, NULL); break; case SHOW_LONG_STATUS: - value= ((char *) status_var + (intptr) value); + value.as_char= status_var_value.as_char + value.as_intptr; /* fall through */ case SHOW_ULONG: case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status() #ifndef _WIN64 case SHOW_SIZE_T: #endif - end= int10_to_str(*(long*) value, buff, 10); + end= int10_to_str(*value.as_long, buff, 10); break; case SHOW_LONGLONG_STATUS: - value= ((char *) status_var + (intptr) value); + value.as_char= status_var_value.as_char + value.as_intptr; /* fall through */ case SHOW_ULONGLONG: #ifdef _WIN64 case SHOW_SIZE_T: #endif - end= longlong10_to_str(*(longlong*) value, buff, 10); + end= longlong10_to_str(*value.as_longlong, buff, 10); break; case SHOW_HA_ROWS: - end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10); + end= longlong10_to_str((longlong) *value.as_ha_rows, buff, 10); break; case SHOW_BOOL: - end= strmov(buff, *(bool*) value ? "ON" : "OFF"); + end= strmov(buff, *value.as_bool ? "ON" : "OFF"); break; case SHOW_MY_BOOL: - end= strmov(buff, *(my_bool*) value ? "ON" : "OFF"); + end= strmov(buff, *value.as_my_bool ? "ON" : "OFF"); break; case SHOW_UINT32_STATUS: - value= ((char *) status_var + (intptr) value); + value.as_char= status_var_value.as_char + value.as_intptr; /* fall through */ case SHOW_UINT: - end= int10_to_str((long) *(uint*) value, buff, 10); + end= int10_to_str((long) *value.as_uint, buff, 10); break; case SHOW_SINT: - end= int10_to_str((long) *(int*) value, buff, -10); + end= int10_to_str((long) *value.as_int, buff, -10); break; case SHOW_SLONG: - end= int10_to_str(*(long*) value, buff, -10); + end= int10_to_str(*value.as_long, buff, -10); break; case SHOW_SLONGLONG: - end= longlong10_to_str(*(longlong*) value, buff, -10); + end= longlong10_to_str(*value.as_longlong, buff, -10); break; case SHOW_HAVE: { - SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value; - pos= show_comp_option_name[(int) tmp]; + pos= show_comp_option_name[(int) *value.as_show_comp_options]; end= strend(pos); break; } case SHOW_CHAR: { - if (!(pos= (char*)value)) + if (!(pos= value.as_char)) pos= ""; end= strend(pos); break; } case SHOW_CHAR_PTR: { - if (!(pos= *(char**) value)) + if (!(pos= *value.as_charptr)) pos= ""; end= strend(pos); @@ -3645,17 +3670,14 @@ const char* get_one_variable(THD *thd, } case SHOW_LEX_STRING: { - LEX_STRING *ls=(LEX_STRING*)value; - if (!(pos= ls->str)) + if (!(pos= value.as_lex_cstring->str)) end= pos= ""; else - end= pos + ls->length; + end= pos + value.as_lex_cstring->length; break; } case SHOW_ATOMIC_COUNTER_UINT32_T: - end= int10_to_str( - static_cast<long>(*static_cast<Atomic_counter<uint32_t>*>(value)), - buff, 10); + end= int10_to_str(static_cast<long>(*value.as_atomic_counter), buff, 10); break; case SHOW_UNDEF: break; // Return empty string @@ -6665,6 +6687,16 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, LEX_CSTRING unknown= {STRING_WITH_LEN("?unknown field?") }; for (uint j=0 ; j < key_info->user_defined_key_parts ; j++,key_part++) { + if (key_part->field->invisible >= INVISIBLE_SYSTEM && + DBUG_EVALUATE_IF("test_completely_invisible", 0, 1)) + { + /* + NOTE: we will get SEQ_IN_INDEX gap inside the result if this key_part + is not last (currently not possible). Though nothing is wrong with + that probably. + */ + continue; + } restore_record(table, s->default_values); table->field[0]->store(STRING_WITH_LEN("def"), cs); table->field[1]->store(db_name->str, db_name->length, cs); diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 6ee51b763e0..118dcaf9d59 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -1089,6 +1089,13 @@ Datetime::Datetime(THD *thd, int *warn, const MYSQL_TIME *from, DBUG_ASSERT(is_valid_value_slow()); } +Datetime::Datetime(my_time_t unix_time, ulong second_part_arg, + const Time_zone* time_zone) +{ + time_zone->gmt_sec_to_TIME(this, unix_time); + second_part= second_part_arg; +} + bool Temporal::datetime_add_nanoseconds_or_invalidate(THD *thd, int *warn, ulong nsec) { @@ -8738,7 +8745,7 @@ bool Type_handler_string_result::Item_eq_value(THD *thd, /***************************************************************************/ -bool Type_handler_string_result::union_element_finalize(const Item * item) const +bool Type_handler_string_result::union_element_finalize(Item_type_holder* item) const { if (item->collation.derivation == DERIVATION_NONE) { @@ -9034,6 +9041,12 @@ Type_handler_timestamp_common::Item_val_native_with_conversion(THD *thd, TIME_to_native(thd, <ime, to, item->datetime_precision(thd)); } +bool Type_handler_null::union_element_finalize(Item_type_holder *item) const +{ + item->set_handler(&type_handler_string); + return false; +} + bool Type_handler_timestamp_common::Item_val_native_with_conversion_result(THD *thd, diff --git a/sql/sql_type.h b/sql/sql_type.h index f801c243171..aa1fe1a9f7e 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -74,6 +74,7 @@ class Item_func_minus; class Item_func_mul; class Item_func_div; class Item_func_mod; +class Item_type_holder; class cmp_item; class in_vector; class Type_handler_data; @@ -2454,6 +2455,8 @@ public: *(static_cast<MYSQL_TIME*>(this))= *from; DBUG_ASSERT(is_valid_datetime_slow()); } + Datetime(my_time_t unix_time, ulong second_part, + const Time_zone* time_zone); bool is_valid_datetime() const { @@ -3883,7 +3886,7 @@ public: Performs the final data type validation for a UNION element, after the regular "aggregation for result" was done. */ - virtual bool union_element_finalize(const Item * item) const + virtual bool union_element_finalize(Item_type_holder* item) const { return false; } @@ -5383,7 +5386,7 @@ public: const Type_std_attributes *item, SORT_FIELD_ATTR *attr) const override; bool is_packable() const override { return true; } - bool union_element_finalize(const Item * item) const override; + bool union_element_finalize(Item_type_holder* item) const override; uint calc_key_length(const Column_definition &def) const override; bool Column_definition_prepare_stage1(THD *thd, MEM_ROOT *mem_root, @@ -6824,6 +6827,7 @@ public: Field *make_conversion_table_field(MEM_ROOT *root, TABLE *table, uint metadata, const Field *target) const override; + bool union_element_finalize(Item_type_holder* item) const override; bool Column_definition_fix_attributes(Column_definition *c) const override; bool Column_definition_prepare_stage1(THD *thd, MEM_ROOT *mem_root, diff --git a/sql/sql_union.cc b/sql/sql_union.cc index b88d78c0db3..b746b510140 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -30,6 +30,7 @@ #include "filesort.h" // filesort_free_buffers #include "sql_view.h" #include "sql_cte.h" +#include "item_windowfunc.h" bool mysql_union(THD *thd, LEX *lex, select_result *result, SELECT_LEX_UNIT *unit, ulong setup_tables_done_option) @@ -1687,7 +1688,8 @@ cont: Test if the aggregated data type is OK for a UNION element. E.g. in case of string data, DERIVATION_NONE is not allowed. */ - if (type->type_handler()->union_element_finalize(type)) + if (type->type() == Item::TYPE_HOLDER && type->type_handler()-> + union_element_finalize(static_cast<Item_type_holder*>(type))) goto err; } @@ -2561,7 +2563,8 @@ bool st_select_lex_unit::cleanup() { DBUG_RETURN(FALSE); } - if (with_element && with_element->is_recursive && union_result) + if (with_element && with_element->is_recursive && union_result && + with_element->rec_outer_references) { select_union_recursive *result= with_element->rec_result; if (++result->cleanup_count == with_element->rec_outer_references) @@ -2730,6 +2733,29 @@ static void cleanup_order(ORDER *order) } +static void cleanup_window_funcs(List<Item_window_func> &win_funcs) +{ + List_iterator_fast<Item_window_func> it(win_funcs); + Item_window_func *win_func; + while ((win_func= it++)) + { + Window_spec *win_spec= win_func->window_spec; + if (!win_spec) + continue; + if (win_spec->save_partition_list) + { + win_spec->partition_list= win_spec->save_partition_list; + win_spec->save_partition_list= NULL; + } + if (win_spec->save_order_list) + { + win_spec->order_list= win_spec->save_order_list; + win_spec->save_order_list= NULL; + } + } +} + + bool st_select_lex::cleanup() { bool error= FALSE; @@ -2741,6 +2767,8 @@ bool st_select_lex::cleanup() cleanup_order(group_list.first); cleanup_ftfuncs(this); + cleanup_window_funcs(window_funcs); + if (join) { List_iterator<TABLE_LIST> ti(leaf_tables); @@ -2767,7 +2795,8 @@ bool st_select_lex::cleanup() for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ; lex_unit= lex_unit->next_unit()) { - if (lex_unit->with_element && lex_unit->with_element->is_recursive) + if (lex_unit->with_element && lex_unit->with_element->is_recursive && + lex_unit->with_element->rec_outer_references) continue; error= (bool) ((uint) error | (uint) lex_unit->cleanup()); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c14585f44c5..977e459f9df 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -272,7 +272,7 @@ static void prepare_record_for_error_message(int error, TABLE *table) /* Create unique_map with all fields used by that index. */ my_bitmap_init(&unique_map, unique_map_buf, table->s->fields, FALSE); - table->mark_columns_used_by_index(keynr, &unique_map); + table->mark_index_columns(keynr, &unique_map); /* Subtract read_set and write_set. */ bitmap_subtract(&unique_map, table->read_set); diff --git a/sql/sql_window.cc b/sql/sql_window.cc index af6a73006a8..2624a5e4510 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -592,9 +592,15 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1, Let's use only one of the lists. */ if (!win_spec1->name() && win_spec2->name()) + { + win_spec1->save_partition_list= win_spec1->partition_list; win_spec1->partition_list= win_spec2->partition_list; + } else + { + win_spec2->save_partition_list= win_spec2->partition_list; win_spec2->partition_list= win_spec1->partition_list; + } cmp= compare_order_lists(win_spec1->order_list, win_spec2->order_list); @@ -607,9 +613,15 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1, Let's use only one of the lists. */ if (!win_spec1->name() && win_spec2->name()) + { + win_spec1->save_order_list= win_spec2->order_list; win_spec1->order_list= win_spec2->order_list; + } else + { + win_spec1->save_order_list= win_spec2->order_list; win_spec2->order_list= win_spec1->order_list; + } cmp= compare_window_frames(win_spec1->window_frame, win_spec2->window_frame); diff --git a/sql/sql_window.h b/sql/sql_window.h index 373b367b211..5e76a33dcd0 100644 --- a/sql/sql_window.h +++ b/sql/sql_window.h @@ -111,8 +111,10 @@ class Window_spec : public Sql_alloc LEX_CSTRING *window_ref; SQL_I_List<ORDER> *partition_list; + SQL_I_List<ORDER> *save_partition_list; SQL_I_List<ORDER> *order_list; + SQL_I_List<ORDER> *save_order_list; Window_frame *window_frame; @@ -123,7 +125,8 @@ class Window_spec : public Sql_alloc SQL_I_List<ORDER> *ord_list, Window_frame *win_frame) : window_names_are_checked(false), window_ref(win_ref), - partition_list(part_list), order_list(ord_list), + partition_list(part_list), save_partition_list(NULL), + order_list(ord_list), save_order_list(NULL), window_frame(win_frame), referenced_win_spec(NULL) {} virtual const char *name() { return NULL; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c9bc2bdc6a6..1f756450f3c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1448,7 +1448,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); table_wild simple_expr column_default_non_parenthesized_expr udf_expr primary_expr string_factor_expr mysql_concatenation_expr select_sublist_qualified_asterisk - expr_or_default set_expr_or_default + expr_or_ignore expr_or_ignore_or_default set_expr_or_default signed_literal expr_or_literal sp_opt_default simple_ident_nospvar @@ -2004,12 +2004,12 @@ execute_using: ; execute_params: - expr_or_default + expr_or_ignore_or_default { if (unlikely(!($$= List<Item>::make(thd->mem_root, $1)))) MYSQL_YYABORT; } - | execute_params ',' expr_or_default + | execute_params ',' expr_or_ignore_or_default { if (($$= $1)->push_back($3, thd->mem_root)) MYSQL_YYABORT; @@ -9882,7 +9882,7 @@ column_default_non_parenthesized_expr: if (unlikely(il)) my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str)); $$= new (thd->mem_root) Item_default_value(thd, Lex->current_context(), - $3); + $3, 0); if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->default_used= TRUE; @@ -12978,7 +12978,7 @@ ident_eq_list: ; ident_eq_value: - simple_ident_nospvar equal expr_or_default + simple_ident_nospvar equal expr_or_ignore_or_default { LEX *lex=Lex; if (unlikely(lex->field_list.push_back($1, thd->mem_root)) || @@ -13048,12 +13048,12 @@ opt_values_with_names: ; values: - values ',' expr_or_default + values ',' expr_or_ignore_or_default { if (unlikely(Lex->insert_list->push_back($3, thd->mem_root))) MYSQL_YYABORT; } - | expr_or_default + | expr_or_ignore_or_default { if (unlikely(Lex->insert_list->push_back($1, thd->mem_root))) MYSQL_YYABORT; @@ -13061,7 +13061,7 @@ values: ; values_with_names: - values_with_names ',' remember_name expr_or_default remember_end + values_with_names ',' remember_name expr_or_ignore_or_default remember_end { if (unlikely(Lex->insert_list->push_back($4, thd->mem_root))) MYSQL_YYABORT; @@ -13069,7 +13069,7 @@ values_with_names: if (!$4->name.str || $4->name.str == item_empty_name) $4->set_name(thd, $3, (uint) ($5 - $3), thd->charset()); } - | remember_name expr_or_default remember_end + | remember_name expr_or_ignore_or_default remember_end { if (unlikely(Lex->insert_list->push_back($2, thd->mem_root))) MYSQL_YYABORT; @@ -13079,17 +13079,21 @@ values_with_names: } ; -expr_or_default: +expr_or_ignore: expr { $$= $1;} - | DEFAULT + | IGNORE_SYM { - $$= new (thd->mem_root) Item_default_specification(thd); + $$= new (thd->mem_root) Item_ignore_specification(thd); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | IGNORE_SYM + ; + +expr_or_ignore_or_default: + expr_or_ignore { $$= $1;} + | DEFAULT { - $$= new (thd->mem_root) Item_ignore_specification(thd); + $$= new (thd->mem_root) Item_default_specification(thd); if (unlikely($$ == NULL)) MYSQL_YYABORT; } @@ -13171,10 +13175,16 @@ update_list: ; update_elem: - simple_ident_nospvar equal expr_or_default + simple_ident_nospvar equal DEFAULT + { + Item *def= new (thd->mem_root) Item_default_value(thd, + Lex->current_context(), $1, 1); + if (!def || add_item_to_list(thd, $1) || add_value_to_list(thd, def)) + MYSQL_YYABORT; + } + | simple_ident_nospvar equal expr_or_ignore { - if (unlikely(add_item_to_list(thd, $1)) || - unlikely(add_value_to_list(thd, $3))) + if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3)) MYSQL_YYABORT; } ; @@ -13185,7 +13195,7 @@ insert_update_list: ; insert_update_elem: - simple_ident_nospvar equal expr_or_default + simple_ident_nospvar equal expr_or_ignore_or_default { LEX *lex= Lex; if (unlikely(lex->update_list.push_back($1, thd->mem_root)) || @@ -14579,7 +14589,7 @@ load_data_set_list: ; load_data_set_elem: - simple_ident_nospvar equal remember_name expr_or_default remember_end + simple_ident_nospvar equal remember_name expr_or_ignore_or_default remember_end { LEX *lex= Lex; if (unlikely(lex->update_list.push_back($1, thd->mem_root)) || diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index a8e4ff2dded..d826d01edbf 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -512,11 +512,10 @@ static Sys_var_charptr_fscs Sys_my_bind_addr( READ_ONLY GLOBAL_VAR(my_bind_addr_str), CMD_LINE(REQUIRED_ARG), DEFAULT(0)); -const char *Sys_var_vers_asof::asof_keywords[]= {"DEFAULT", NULL}; static Sys_var_vers_asof Sys_vers_asof_timestamp( "system_versioning_asof", "Default value for the FOR SYSTEM_TIME AS OF clause", SESSION_VAR(vers_asof_timestamp.type), NO_CMD_LINE, - Sys_var_vers_asof::asof_keywords, DEFAULT(SYSTEM_TIME_UNSPECIFIED)); + DEFAULT(SYSTEM_TIME_UNSPECIFIED)); static const char *vers_alter_history_keywords[]= {"ERROR", "KEEP", NullS}; static Sys_var_enum Sys_vers_alter_history( @@ -1843,8 +1842,9 @@ static Sys_var_gtid_binlog_pos Sys_gtid_binlog_pos( READ_ONLY GLOBAL_VAR(opt_gtid_binlog_pos_dummy), NO_CMD_LINE); -uchar * -Sys_var_gtid_binlog_pos::global_value_ptr(THD *thd, const LEX_CSTRING *base) +const uchar * +Sys_var_gtid_binlog_pos::global_value_ptr(THD *thd, + const LEX_CSTRING *base) const { char buf[128]; String str(buf, sizeof(buf), system_charset_info); @@ -1871,8 +1871,9 @@ static Sys_var_gtid_current_pos Sys_gtid_current_pos( READ_ONLY GLOBAL_VAR(opt_gtid_current_pos_dummy), NO_CMD_LINE); -uchar * -Sys_var_gtid_current_pos::global_value_ptr(THD *thd, const LEX_CSTRING *base) +const uchar * +Sys_var_gtid_current_pos::global_value_ptr(THD *thd, + const LEX_CSTRING *base) const { String str; char *p; @@ -1952,8 +1953,9 @@ Sys_var_gtid_slave_pos::global_update(THD *thd, set_var *var) } -uchar * -Sys_var_gtid_slave_pos::global_value_ptr(THD *thd, const LEX_CSTRING *base) +const uchar * +Sys_var_gtid_slave_pos::global_value_ptr(THD *thd, + const LEX_CSTRING *base) const { String str; char *p; @@ -2076,8 +2078,9 @@ Sys_var_gtid_binlog_state::global_update(THD *thd, set_var *var) } -uchar * -Sys_var_gtid_binlog_state::global_value_ptr(THD *thd, const LEX_CSTRING *base) +const uchar * +Sys_var_gtid_binlog_state::global_value_ptr(THD *thd, + const LEX_CSTRING *base) const { char buf[512]; String str(buf, sizeof(buf), system_charset_info); @@ -2111,8 +2114,8 @@ static Sys_var_last_gtid Sys_last_gtid( export sys_var *Sys_last_gtid_ptr= &Sys_last_gtid; // for check changing -uchar * -Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_CSTRING *base) +const uchar * +Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_CSTRING *base) const { char buf[10+1+10+1+20+1]; String str(buf, sizeof(buf), system_charset_info); @@ -2286,9 +2289,10 @@ Sys_var_slave_parallel_mode::global_update(THD *thd, set_var *var) } -uchar * +const uchar * Sys_var_slave_parallel_mode::global_value_ptr(THD *thd, - const LEX_CSTRING *base_name) + const + LEX_CSTRING *base_name) const { Master_info *mi; enum_slave_parallel_mode val= @@ -5283,8 +5287,9 @@ bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi) return status; } -uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd, - const LEX_CSTRING *base_name) +const uchar * +Sys_var_rpl_filter::global_value_ptr(THD *thd, + const LEX_CSTRING *base_name) const { char buf[256]; String tmp(buf, sizeof(buf), &my_charset_bin); @@ -5404,7 +5409,7 @@ Sys_slave_net_timeout( */ ulonglong Sys_var_multi_source_ulonglong:: -get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) +get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const { Master_info *mi; ulonglong res= 0; // Default value diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic index 2bd6ee6467d..97e3a28b67e 100644 --- a/sql/sys_vars.ic +++ b/sql/sys_vars.ic @@ -261,7 +261,7 @@ public: { var->save_result.ulonglong_value= option.def_value; } private: T get_max_var() { return *((T*) max_var_ptr()); } - uchar *default_value_ptr(THD *thd) { return (uchar*) &option.def_value; } + const uchar *default_value_ptr(THD *thd) const { return (uchar*) &option.def_value; } }; typedef Sys_var_integer<int, GET_INT, SHOW_SINT> Sys_var_int; @@ -272,25 +272,25 @@ typedef Sys_var_integer<ulonglong, GET_ULL, SHOW_ULONGLONG> Sys_var_ulonglong; typedef Sys_var_integer<long, GET_LONG, SHOW_SLONG> Sys_var_long; -template<> uchar *Sys_var_int::default_value_ptr(THD *thd) +template<> const uchar *Sys_var_int::default_value_ptr(THD *thd) const { thd->sys_var_tmp.int_value= (int)option.def_value; return (uchar*) &thd->sys_var_tmp.int_value; } -template<> uchar *Sys_var_uint::default_value_ptr(THD *thd) +template<> const uchar *Sys_var_uint::default_value_ptr(THD *thd) const { thd->sys_var_tmp.uint_value= (uint)option.def_value; return (uchar*) &thd->sys_var_tmp.uint_value; } -template<> uchar *Sys_var_long::default_value_ptr(THD *thd) +template<> const uchar *Sys_var_long::default_value_ptr(THD *thd) const { thd->sys_var_tmp.long_value= (long)option.def_value; return (uchar*) &thd->sys_var_tmp.long_value; } -template<> uchar *Sys_var_ulong::default_value_ptr(THD *thd) +template<> const uchar *Sys_var_ulong::default_value_ptr(THD *thd) const { thd->sys_var_tmp.ulong_value= (ulong)option.def_value; return (uchar*) &thd->sys_var_tmp.ulong_value; @@ -420,13 +420,13 @@ public: { var->save_result.ulonglong_value= global_var(ulong); } void global_save_default(THD *thd, set_var *var) { var->save_result.ulonglong_value= option.def_value; } - uchar *valptr(THD *thd, ulong val) - { return (uchar*)typelib.type_names[val]; } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *valptr(THD *thd, ulong val) const + { return reinterpret_cast<const uchar*>(typelib.type_names[val]); } + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, session_var(thd, ulong)); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, global_var(ulong)); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return valptr(thd, (ulong)option.def_value); } ulong get_max_var() { return *((ulong *) max_var_ptr()); } @@ -474,7 +474,7 @@ public: { var->save_result.ulonglong_value= (ulonglong)*(my_bool *)global_value_ptr(thd, 0); } void global_save_default(THD *thd, set_var *var) { var->save_result.ulonglong_value= option.def_value; } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { thd->sys_var_tmp.my_bool_value=(my_bool) option.def_value; return (uchar*) &thd->sys_var_tmp.my_bool_value; @@ -723,7 +723,7 @@ public: void global_save_default(THD *thd, set_var *var) { DBUG_ASSERT(FALSE); } protected: - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return thd->security_ctx->proxy_user[0] ? (uchar *) &(thd->security_ctx->proxy_user[0]) : NULL; @@ -738,7 +738,7 @@ public: {} protected: - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return (uchar*)thd->security_ctx->external_user; } @@ -790,7 +790,8 @@ public: } protected: - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) override; + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const override; bool set_filter_value(const char *value, Master_info *mi); }; @@ -903,7 +904,7 @@ public: { DBUG_ASSERT(FALSE); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(FALSE); return NULL; @@ -981,19 +982,19 @@ public: var->save_result.string_value.str= ptr; var->save_result.string_value.length= safe_strlen(ptr); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { char buf[256]; DBUG_EXPLAIN(buf, sizeof(buf)); return (uchar*) thd->strdup(buf); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { char buf[256]; DBUG_EXPLAIN_INITIAL(buf, sizeof(buf)); return (uchar*) thd->strdup(buf); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return (uchar*)""; } }; #endif @@ -1069,7 +1070,7 @@ public: return keycache_update(thd, key_cache, offset, new_value); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { KEY_CACHE *key_cache= get_key_cache(base); if (!key_cache) @@ -1254,7 +1255,7 @@ public: lock, binlog_status_arg, on_check_func, on_update_func, substitute) { } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { if (thd->user_connect && thd->user_connect->user_resources.user_conn) return (uchar*) &(thd->user_connect->user_resources.user_conn); @@ -1366,13 +1367,13 @@ public: { var->save_result.ulonglong_value= global_var(ulonglong); } void global_save_default(THD *thd, set_var *var) { var->save_result.ulonglong_value= option.def_value; } - uchar *valptr(THD *thd, ulonglong val) + const uchar *valptr(THD *thd, ulonglong val) const { return (uchar*)flagset_to_string(thd, 0, val, typelib.type_names); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, session_var(thd, ulonglong)); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, global_var(ulonglong)); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return valptr(thd, option.def_value); } }; @@ -1480,13 +1481,13 @@ public: { var->save_result.ulonglong_value= global_var(ulonglong); } void global_save_default(THD *thd, set_var *var) { var->save_result.ulonglong_value= option.def_value; } - uchar *valptr(THD *thd, ulonglong val) - { return (uchar*)set_to_string(thd, 0, val, typelib.type_names); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *valptr(THD *thd, ulonglong val) const + { return reinterpret_cast<const uchar*>(set_to_string(thd, 0, val, typelib.type_names)); } + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, session_var(thd, ulonglong)); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, global_var(ulonglong)); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return valptr(thd, option.def_value); } ulonglong get_max_var() { return *((ulonglong*) max_var_ptr()); } @@ -1583,7 +1584,7 @@ public: plugin_ref plugin= global_var(plugin_ref); var->save_result.plugin= plugin ? my_plugin_lock(thd, plugin) : 0; } - plugin_ref get_default(THD *thd) + plugin_ref get_default(THD *thd) const { char *default_value= *reinterpret_cast<char**>(option.def_value); if (!default_value) @@ -1605,16 +1606,16 @@ public: var->save_result.plugin= get_default(thd); } - uchar *valptr(THD *thd, plugin_ref plugin) + uchar *valptr(THD *thd, plugin_ref plugin) const { return (uchar*)(plugin ? thd->strmake(plugin_name(plugin)->str, plugin_name(plugin)->length) : 0); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, session_var(thd, plugin_ref)); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, global_var(plugin_ref)); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return valptr(thd, get_default(thd)); } }; @@ -1701,7 +1702,7 @@ public: plugin_ref* plugins= global_var(plugin_ref *); var->save_result.plugins= plugins ? temp_copy_engine_list(thd, plugins) : 0; } - plugin_ref *get_default(THD *thd) + plugin_ref *get_default(THD *thd) const { char *default_value= *reinterpret_cast<char**>(option.def_value); if (!default_value) @@ -1715,15 +1716,15 @@ public: var->save_result.plugins= get_default(thd); } - uchar *valptr(THD *thd, plugin_ref *plugins) + uchar *valptr(THD *thd, plugin_ref *plugins) const { - return (uchar*)pretty_print_engine_list(thd, plugins); + return reinterpret_cast<uchar*>(pretty_print_engine_list(thd, plugins)); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, session_var(thd, plugin_ref*)); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, global_var(plugin_ref*)); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return valptr(thd, get_default(thd)); } }; @@ -1787,16 +1788,16 @@ public: { DBUG_ASSERT(FALSE); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return debug_sync_value_ptr(thd); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(FALSE); return 0; } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return (uchar*)""; } }; #endif /* defined(ENABLED_DEBUG_SYNC) */ @@ -1872,16 +1873,16 @@ public: void global_save_default(THD *thd, set_var *var) { var->save_result.ulonglong_value= option.def_value; } - uchar *valptr(THD *thd, ulonglong val) + uchar *valptr(THD *thd, ulonglong val) const { thd->sys_var_tmp.my_bool_value= (reverse_semantics == !(val & bitmask)); return (uchar*) &thd->sys_var_tmp.my_bool_value; } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, session_var(thd, ulonglong)); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, global_var(ulonglong)); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { thd->sys_var_tmp.my_bool_value= option.def_value != 0; return (uchar*) &thd->sys_var_tmp.my_bool_value; @@ -1940,17 +1941,17 @@ public: { var->value= 0; } void global_save_default(THD *thd, set_var *var) { DBUG_ASSERT(FALSE); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { thd->sys_var_tmp.ulonglong_value= read_func(thd); return (uchar*) &thd->sys_var_tmp.ulonglong_value; } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(FALSE); return 0; } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { thd->sys_var_tmp.ulonglong_value= 0; return (uchar*) &thd->sys_var_tmp.ulonglong_value; @@ -2006,18 +2007,18 @@ public: { var->value= 0; } void global_save_default(THD *thd, set_var *var) { DBUG_ASSERT(FALSE); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { thd->sys_var_tmp.double_value= thd->start_time + thd->start_time_sec_part/(double)TIME_SECOND_PART_FACTOR; return (uchar*) &thd->sys_var_tmp.double_value; } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(FALSE); return 0; } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { thd->sys_var_tmp.double_value= 0; return (uchar*) &thd->sys_var_tmp.double_value; @@ -2077,12 +2078,12 @@ public: } void session_save_default(THD *thd, set_var *var) { } void global_save_default(THD *thd, set_var *var) { } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(FALSE); return 0; } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return (uchar*)show_comp_option_name[global_var(enum SHOW_COMP_OPTION)]; } @@ -2152,13 +2153,13 @@ public: void **default_value= reinterpret_cast<void**>(option.def_value); var->save_result.ptr= *default_value; } - uchar *valptr(THD *thd, uchar *val) + uchar *valptr(THD *thd, uchar *val) const { return val ? *(uchar**)(val+name_offset) : 0; } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, session_var(thd, uchar*)); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, global_var(uchar*)); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return valptr(thd, *(uchar**)option.def_value); } }; @@ -2228,9 +2229,9 @@ public: var->save_result.time_zone= *(Time_zone**)(intptr)option.def_value; } - uchar *valptr(THD *thd, Time_zone *val) - { return (uchar *)(val->get_name()->ptr()); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *valptr(THD *thd, Time_zone *val) const + { return reinterpret_cast<const uchar*>(val->get_name()->ptr()); } + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { /* This is an ugly fix for replication: we don't replicate properly queries @@ -2243,9 +2244,9 @@ public: thd->time_zone_used= 1; return valptr(thd, session_var(thd, Time_zone *)); } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return valptr(thd, global_var(Time_zone*)); } - uchar *default_value_ptr(THD *thd) + const uchar *default_value_ptr(THD *thd) const { return valptr(thd, *(Time_zone**)option.def_value); } }; @@ -2404,7 +2405,7 @@ public: /* Use value given in variable declaration */ global_save_default(thd, var); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { ulonglong *tmp, res; tmp= (ulonglong*) (((uchar*)&(thd->variables)) + offset); @@ -2412,11 +2413,11 @@ public: *tmp= res; return (uchar*) tmp; } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return session_value_ptr(thd, base); } - ulonglong get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset); + ulonglong get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const; bool update_variable(THD *thd, Master_info *mi) { return update_multi_source_variable_func(this, thd, mi); @@ -2464,12 +2465,12 @@ public: { DBUG_ASSERT(false); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(false); return NULL; } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base); + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const; }; @@ -2513,12 +2514,12 @@ public: { DBUG_ASSERT(false); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(false); return NULL; } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base); + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const; }; @@ -2553,13 +2554,13 @@ public: /* Record the attempt to use default so we can error. */ var->value= 0; } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(false); return NULL; } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base); - uchar *default_value_ptr(THD *thd) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const; + const uchar *default_value_ptr(THD *thd) const { return 0; } bool on_check_access_global(THD *thd) const { @@ -2599,13 +2600,13 @@ public: /* Record the attempt to use default so we can error. */ var->value= 0; } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(false); return NULL; } - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base); - uchar *default_value_ptr(THD *thd) + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const; + const uchar *default_value_ptr(THD *thd) const { return 0; } bool on_check_access_global(THD *thd) const { @@ -2654,8 +2655,8 @@ public: { DBUG_ASSERT(false); } - uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base); - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const; + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { DBUG_ASSERT(false); return NULL; @@ -2681,30 +2682,32 @@ public: SYSVAR_ASSERT(scope() == GLOBAL); } bool global_update(THD *thd, set_var *var); - uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base); + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const; }; -class Sys_var_vers_asof: public Sys_var_enum +class Sys_var_vers_asof: public sys_var { public: - static const char *asof_keywords[]; - -public: Sys_var_vers_asof(const char *name_arg, const char *comment, int flag_args, ptrdiff_t off, size_t size, - CMD_LINE getopt, const char *values[], - uint def_val) - : Sys_var_enum(name_arg, comment, flag_args, off, size, - getopt, values, def_val) + CMD_LINE getopt, uint def_val, + PolyLock *lock= NO_MUTEX_GUARD, + binlog_status_enum binlog_status_arg= VARIABLE_NOT_IN_BINLOG, + on_check_function on_check_func= NULL, + on_update_function on_update_func= NULL, + const char *substitute= NULL) + : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, + getopt.id, getopt.arg_type, SHOW_CHAR, def_val, lock, + binlog_status_arg, on_check_func, on_update_func, substitute) { - // setval() accepts string rather enum option.var_type= GET_STR; } virtual bool do_check(THD *thd, set_var *var) { - if (!Sys_var_enum::do_check(thd, var)) + if (!var->value) return false; + MYSQL_TIME ltime; Datetime::Options opt(TIME_CONV_NONE | TIME_NO_ZERO_IN_DATE | @@ -2712,78 +2715,92 @@ public: bool res= var->value->get_date(thd, <ime, opt); if (!res) { - var->save_result.ulonglong_value= SYSTEM_TIME_AS_OF; + uint error; + var->save_result.timestamp.unix_time= + thd->variables.time_zone->TIME_to_gmt_sec(<ime, &error); + var->save_result.timestamp.second_part= ltime.second_part; + res= error != 0; } return res; } private: - bool update(set_var *var, vers_asof_timestamp_t &out) + static bool update(THD *thd, set_var *var, vers_asof_timestamp_t *out) { - bool res= false; - out.type= static_cast<enum_var_type>(var->save_result.ulonglong_value); - if (out.type == SYSTEM_TIME_AS_OF) + if (var->value) { - if (var->value) - { - THD *thd= current_thd; - Datetime::Options opt(TIME_CONV_NONE | - TIME_NO_ZERO_IN_DATE | - TIME_NO_ZERO_DATE, thd); - /* - var->value is allowed to return DATETIME and DATE - Make sure to convert DATE to DATETIME. - */ - res= Datetime(thd, var->value, opt).copy_to_mysql_time(&out.ltime); - } - else // set DEFAULT from global var - { - out= global_var(vers_asof_timestamp_t); - res= false; - } + out->type = SYSTEM_TIME_AS_OF; + out->unix_time = var->save_result.timestamp.unix_time; + out->second_part= var->save_result.timestamp.second_part; } - return res; + return 0; + } + + static void save_default(set_var *var, vers_asof_timestamp_t *out) + { + out->type= SYSTEM_TIME_UNSPECIFIED; } public: virtual bool global_update(THD *thd, set_var *var) { - return update(var, global_var(vers_asof_timestamp_t)); + return update(thd, var, &global_var(vers_asof_timestamp_t)); } virtual bool session_update(THD *thd, set_var *var) { - return update(var, session_var(thd, vers_asof_timestamp_t)); + return update(thd, var, &session_var(thd, vers_asof_timestamp_t)); + } + + virtual bool session_is_default(THD *thd) + { + const vers_asof_timestamp_t &var= session_var(thd, vers_asof_timestamp_t); + return var.type == SYSTEM_TIME_UNSPECIFIED; + } + + virtual void session_save_default(THD *thd, set_var *var) + { + save_default(var, &session_var(thd, vers_asof_timestamp_t)); + } + virtual void global_save_default(THD *thd, set_var *var) + { + save_default(var, &global_var(vers_asof_timestamp_t)); } private: - uchar *value_ptr(THD *thd, vers_asof_timestamp_t &val) + const uchar *value_ptr(THD *thd, vers_asof_timestamp_t &val) const { + const char *value; switch (val.type) { case SYSTEM_TIME_UNSPECIFIED: - case SYSTEM_TIME_ALL: - return (uchar*) thd->strdup(asof_keywords[val.type]); + return (uchar*)"DEFAULT"; + break; case SYSTEM_TIME_AS_OF: { - uchar *buf= (uchar*) thd->alloc(MAX_DATE_STRING_REP_LENGTH); - if (buf &&!my_datetime_to_str(&val.ltime, (char*) buf, 6)) + char *buf= (char*) thd->alloc(MAX_DATE_STRING_REP_LENGTH); + MYSQL_TIME ltime; + + thd->variables.time_zone->gmt_sec_to_TIME(<ime, val.unix_time); + ltime.second_part= val.second_part; + + value= buf; + if (buf && !my_datetime_to_str(<ime, buf, 6)) { - // TODO: figure out variable name - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "system_versioning_asof_timestamp", "NULL (wrong datetime)"); - return (uchar*) thd->strdup("Error: wrong datetime"); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, "NULL (wrong datetime)"); + value= thd->strdup("Error: wrong datetime"); } - return buf; + break; } default: - break; + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, "NULL (wrong range type)"); + value= thd->strdup("Error: wrong range type"); } - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "system_versioning_asof_timestamp", "NULL (wrong range type)"); - return (uchar*) thd->strdup("Error: wrong range type"); + return reinterpret_cast<const uchar *>(value); } public: - virtual uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) + virtual const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const { return value_ptr(thd, session_var(thd, vers_asof_timestamp_t)); } - virtual uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) + virtual const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const { return value_ptr(thd, global_var(vers_asof_timestamp_t)); } }; diff --git a/sql/table.cc b/sql/table.cc index a64df48e20d..025612ca87b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -7105,7 +7105,7 @@ void TABLE::prepare_for_position() if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && s->primary_key < MAX_KEY) { - mark_columns_used_by_index_no_reset(s->primary_key, read_set); + mark_index_columns_for_read(s->primary_key); /* signal change */ file->column_bitmaps_signal(); } @@ -7121,7 +7121,7 @@ MY_BITMAP *TABLE::prepare_for_keyread(uint index, MY_BITMAP *map) file->ha_start_keyread(index); if (map != read_set || !(file->index_flags(index, 0, 1) & HA_CLUSTERED_INDEX)) { - mark_columns_used_by_index(index, map); + mark_index_columns(index, map); column_bitmaps_set(map); } DBUG_RETURN(backup); @@ -7132,12 +7132,12 @@ MY_BITMAP *TABLE::prepare_for_keyread(uint index, MY_BITMAP *map) Mark that only fields from one key is used. Useful before keyread. */ -void TABLE::mark_columns_used_by_index(uint index, MY_BITMAP *bitmap) +void TABLE::mark_index_columns(uint index, MY_BITMAP *bitmap) { - DBUG_ENTER("TABLE::mark_columns_used_by_index"); + DBUG_ENTER("TABLE::mark_index_columns"); bitmap_clear_all(bitmap); - mark_columns_used_by_index_no_reset(index, bitmap); + mark_index_columns_no_reset(index, bitmap); DBUG_VOID_RETURN; } @@ -7145,11 +7145,11 @@ void TABLE::mark_columns_used_by_index(uint index, MY_BITMAP *bitmap) Restore to use normal column maps after key read NOTES - This reverse the change done by mark_columns_used_by_index + This reverse the change done by mark_index_columns WARNING For this to work, one must have the normal table maps in place - when calling mark_columns_used_by_index + when calling mark_index_columns */ void TABLE::restore_column_maps_after_keyread(MY_BITMAP *backup) @@ -7161,23 +7161,36 @@ void TABLE::restore_column_maps_after_keyread(MY_BITMAP *backup) DBUG_VOID_RETURN; } +static void do_mark_index_columns(TABLE *table, uint index, + MY_BITMAP *bitmap, bool read) +{ + KEY_PART_INFO *key_part= table->key_info[index].key_part; + uint key_parts= table->key_info[index].user_defined_key_parts; + for (uint k= 0; k < key_parts; k++) + if (read) + key_part[k].field->register_field_in_read_map(); + else + bitmap_set_bit(bitmap, key_part[k].fieldnr-1); + if (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX && + table->s->primary_key != MAX_KEY && table->s->primary_key != index) + do_mark_index_columns(table, table->s->primary_key, bitmap, read); +} /* mark columns used by key, but don't reset other fields */ -void TABLE::mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *bitmap) +inline void TABLE::mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap) { - KEY_PART_INFO *key_part= key_info[index].key_part; - KEY_PART_INFO *key_part_end= (key_part + key_info[index].user_defined_key_parts); - for (;key_part != key_part_end; key_part++) - bitmap_set_bit(bitmap, key_part->fieldnr-1); - if (file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX && - s->primary_key != MAX_KEY && s->primary_key != index) - mark_columns_used_by_index_no_reset(s->primary_key, bitmap); + do_mark_index_columns(this, index, bitmap, false); } +inline void TABLE::mark_index_columns_for_read(uint index) +{ + do_mark_index_columns(this, index, read_set, true); +} + /* Mark auto-increment fields as used fields in both read and write maps @@ -7196,7 +7209,7 @@ void TABLE::mark_auto_increment_column() bitmap_set_bit(read_set, found_next_number_field->field_index); bitmap_set_bit(write_set, found_next_number_field->field_index); if (s->next_number_keypart) - mark_columns_used_by_index_no_reset(s->next_number_index, read_set); + mark_index_columns_for_read(s->next_number_index); file->column_bitmaps_signal(); } @@ -7247,7 +7260,7 @@ void TABLE::mark_columns_needed_for_delete() file->use_hidden_primary_key(); else { - mark_columns_used_by_index_no_reset(s->primary_key, read_set); + mark_index_columns_for_read(s->primary_key); need_signal= true; } } @@ -7333,7 +7346,7 @@ void TABLE::mark_columns_needed_for_update() file->use_hidden_primary_key(); else { - mark_columns_used_by_index_no_reset(s->primary_key, read_set); + mark_index_columns_for_read(s->primary_key); need_signal= true; } } @@ -7493,7 +7506,7 @@ void TABLE::mark_columns_per_binlog_row_image() if ((my_field->flags & PRI_KEY_FLAG) || (my_field->type() != MYSQL_TYPE_BLOB)) { - bitmap_set_bit(read_set, my_field->field_index); + my_field->register_field_in_read_map(); bitmap_set_bit(rpl_write_set, my_field->field_index); } } @@ -7505,7 +7518,7 @@ void TABLE::mark_columns_per_binlog_row_image() We don't need to mark the primary key in the rpl_write_set as the binary log will include all columns read anyway. */ - mark_columns_used_by_index_no_reset(s->primary_key, read_set); + mark_index_columns_for_read(s->primary_key); if (versioned()) { // TODO: After MDEV-18432 we don't pass history rows, so remove this: diff --git a/sql/table.h b/sql/table.h index 8efab4ca70d..d063a3f27be 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1542,8 +1542,9 @@ public: MY_BITMAP *prepare_for_keyread(uint index, MY_BITMAP *map); MY_BITMAP *prepare_for_keyread(uint index) { return prepare_for_keyread(index, &tmp_set); } - void mark_columns_used_by_index(uint index, MY_BITMAP *map); - void mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *map); + void mark_index_columns(uint index, MY_BITMAP *bitmap); + void mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap); + void mark_index_columns_for_read(uint index); void restore_column_maps_after_keyread(MY_BITMAP *backup); void mark_auto_increment_column(void); void mark_columns_needed_for_update(void); diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc index e8eb0dcc29d..088c97ddb99 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -224,6 +224,14 @@ static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data) { THD *thd= NULL; + DBUG_EXECUTE_IF("CONNECT_wait", + { + extern MYSQL_SOCKET unix_sock; + DBUG_ASSERT(unix_sock.fd >= 0); + while (unix_sock.fd >= 0) + my_sleep(1000); + }); + /* Create a new connection context: mysys_thread_var and PSI thread Store them in THD. @@ -241,10 +249,9 @@ static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data) my_thread_end(); return NULL; } - delete connect; - thd->event_scheduler.data = scheduler_data; - server_threads.insert(thd); + server_threads.insert(thd); // Make THD visible in show processlist + delete connect; // must be after server_threads.insert, see close_connections() thd->set_mysys_var(mysys_var); diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index a5592fc5ae6..972876c24c2 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2390,8 +2390,8 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_, if (Wsrep_server_state::instance().desynced_on_pause()) { my_message(ER_UNKNOWN_COM_ERROR, - "Aborting TOI: Global Read-Lock (FTWRL) in place.", MYF(0)); - WSREP_DEBUG("Aborting TOI: Global Read-Lock (FTWRL) in place: %s %llu", + "Aborting TOI: Replication paused on node for FTWRL/BACKUP STAGE.", MYF(0)); + WSREP_DEBUG("Aborting TOI: Replication paused on node for FTWRL/BACKUP STAGE.: %s %llu", wsrep_thd_query(thd), thd->thread_id); return -1; } @@ -2735,15 +2735,13 @@ void wsrep_close_client_connections(my_bool wait_to_end, THD* except_caller_thd) */ server_threads.iterate(kill_remaining_threads, except_caller_thd); - DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", - uint32_t(thread_count))); - WSREP_DEBUG("waiting for client connections to close: %u", - uint32_t(thread_count)); + DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", THD_count::value())); + WSREP_DEBUG("waiting for client connections to close: %u", THD_count::value()); while (wait_to_end && server_threads.iterate(have_client_connections)) { sleep(1); - DBUG_PRINT("quit",("One thread died (count=%u)", uint32_t(thread_count))); + DBUG_PRINT("quit",("One thread died (count=%u)", THD_count::value())); } /* All client connection threads have now been aborted */ diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 15fd87eda5d..a5d292700a7 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -349,6 +349,15 @@ bool wsrep_bf_abort(const THD* bf_thd, THD* victim_thd) if (WSREP(victim_thd) && !victim_thd->wsrep_trx().active()) { WSREP_DEBUG("wsrep_bf_abort, BF abort for non active transaction"); + switch (victim_thd->wsrep_trx().state()) + { + case wsrep::transaction::s_aborting: /* fall through */ + case wsrep::transaction::s_aborted: + WSREP_DEBUG("victim thd is already aborted or in aborting state."); + return false; + default: + break; + } wsrep_start_transaction(victim_thd, victim_thd->wsrep_next_trx_id()); } diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index a41ed86371d..456a7b62815 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -108,6 +108,7 @@ IF(CONNECT_WITH_VCT) SET(CONNECT_SOURCES ${CONNECT_SOURCES} filamvct.cpp tabvct.cpp filamvct.h tabvct.h) add_definitions(-DVCT_SUPPORT) ENDIF(CONNECT_WITH_VCT) +ADD_FEATURE_INFO(CONNECT_VCT CONNECT_WITH_VCT "Support for VCT in the CONNECT storage engine") # @@ -133,6 +134,7 @@ IF(CONNECT_WITH_LIBXML2) D:/libxml/lib) ENDIF(WIN32) FIND_PACKAGE(LibXml2) + SET_PACKAGE_PROPERTIES(LibXml2 PROPERTIES TYPE OPTIONAL) IF (LIBXML2_FOUND) INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) SET(XML_LIBRARY ${LIBXML2_LIBRARIES}) @@ -140,6 +142,8 @@ IF(CONNECT_WITH_LIBXML2) add_definitions(-DLIBXML2_SUPPORT) ENDIF(LIBXML2_FOUND) ENDIF(CONNECT_WITH_LIBXML2) +ADD_FEATURE_INFO(CONNECT_LIBXML2 CONNECT_WITH_LIBXML2 + "Support for LIBXML2 in the CONNECT storage engine") IF(WIN32) @@ -149,6 +153,8 @@ IF(WIN32) SET(MSXML_FOUND 1) SET(CONNECT_SOURCES ${CONNECT_SOURCES} domdoc.cpp domdoc.h) ENDIF(CONNECT_WITH_MSXML) + ADD_FEATURE_INFO(CONNECT_MSXML CONNECT_WITH_MSXML + "Support for MSXML in the CONNECT storage engine") ENDIF(WIN32) IF(LIBXML2_FOUND OR MSXML_FOUND) @@ -249,6 +255,7 @@ int main() { tabodbc.cpp tabodbc.h odbccat.h odbconn.cpp odbconn.h) ENDIF(UNIX) ENDIF(CONNECT_WITH_ODBC) +ADD_FEATURE_INFO(CONNECT_ODBC ODBC_LIBRARY "Support for ODBC in the CONNECT storage engine") # # JDBC with MongoDB Java Driver included but disabled if without MONGO @@ -258,7 +265,9 @@ OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON) IF(CONNECT_WITH_JDBC) FIND_PACKAGE(Java 1.6) + SET_PACKAGE_PROPERTIES(Java PROPERTIES TYPE OPTIONAL) FIND_PACKAGE(JNI) + SET_PACKAGE_PROPERTIES(JNI PROPERTIES TYPE OPTIONAL) IF (JAVA_FOUND AND JNI_FOUND) INCLUDE(UseJava) INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH}) @@ -274,6 +283,7 @@ IF(CONNECT_WITH_JDBC) Mongo2Interface.java Mongo3Interface.java mysql-test/connect/std_data/JavaWrappers.jar) add_definitions(-DJAVA_SUPPORT) + ADD_FEATURE_INFO(CONNECT_JDBC "ON" "Support for JDBC in the CONNECT storage engine") IF(CONNECT_WITH_MONGO) SET(CONNECT_SOURCES ${CONNECT_SOURCES} mysql-test/connect/std_data/Mongo2.jar @@ -282,7 +292,10 @@ IF(CONNECT_WITH_JDBC) ENDIF() ELSE() SET(JDBC_LIBRARY "") + ADD_FEATURE_INFO(CONNECT_JDBC "OFF" "Support for JDBC in the CONNECT storage engine") ENDIF() +ELSE(CONNECT_WITH_JDBC) + ADD_FEATURE_INFO(CONNECT_JDBC "OFF" "Support for JDBC in the CONNECT storage engine") ENDIF(CONNECT_WITH_JDBC) # @@ -296,6 +309,7 @@ IF(CONNECT_WITH_ZIP) filamzip.h tabzip.h ioapi.h unzip.h zip.h) add_definitions(-DZIP_SUPPORT -DNOCRYPT) ENDIF(CONNECT_WITH_ZIP) +ADD_FEATURE_INFO(CONNECT_ZIP CONNECT_WITH_ZIP "Support for ZIP in the CONNECT storage engine") # # MONGO C Driver @@ -312,6 +326,7 @@ IF(CONNECT_WITH_MONGO) D:/mongo-c-driver/lib) ENDIF(WIN32) FIND_PACKAGE(libmongoc-1.0 1.7 QUIET) + SET_PACKAGE_PROPERTIES(libmongoc PROPERTIES TYPE OPTIONAL) IF (libmongoc-1.0_FOUND) INCLUDE_DIRECTORIES(${MONGOC_INCLUDE_DIRS}) SET(MONGOC_LIBRARY ${MONGOC_LIBRARIES}) @@ -319,14 +334,18 @@ IF(CONNECT_WITH_MONGO) cmgoconn.cpp cmgfam.cpp tabcmg.cpp cmgoconn.h cmgfam.h tabcmg.h) add_definitions(-DCMGO_SUPPORT) + ADD_FEATURE_INFO(CONNECT_MONGODB "ON" "Support for MongoDB in the CONNECT storage engine") IF (NOT JAVA_FOUND AND JNI_FOUND) SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongo.cpp mongo.h) add_definitions(-DMONGO_SUPPORT) ENDIF (NOT JAVA_FOUND AND JNI_FOUND) + ELSE(libmongoc-1.0_FOUND) + ADD_FEATURE_INFO(CONNECT_MONGODB "OFF" "Support for MongoDB in the CONNECT storage engine") ENDIF(libmongoc-1.0_FOUND) +ELSE(CONNECT_WITH_MONGO) + ADD_FEATURE_INFO(CONNECT_MONGODB "OFF" "Support for MongoDB in the CONNECT storage engine") ENDIF(CONNECT_WITH_MONGO) - # # REST # @@ -358,6 +377,7 @@ IF(CONNECT_WITH_REST) ## MESSAGE(STATUS "=====> cpprestsdk package not found") # ENDIF (cpprestsdk_FOUND) ENDIF(CONNECT_WITH_REST) +ADD_FEATURE_INFO(CONNECT_REST CONNECT_WITH_REST "Support for REST API in the CONNECT storage engine") # # XMAP @@ -368,6 +388,7 @@ OPTION(CONNECT_WITH_XMAP "Compile CONNECT storage engine with index file mapping IF(CONNECT_WITH_XMAP) add_definitions(-DXMAP) ENDIF(CONNECT_WITH_XMAP) +ADD_FEATURE_INFO(CONNECT_XMAP CONNECT_WITH_XMAP "Support for index file mapping in the CONNECT storage engine") # # Plugin definition diff --git a/storage/connect/Client2.java b/storage/connect/Client2.java new file mode 100644 index 00000000000..6dbf4188032 --- /dev/null +++ b/storage/connect/Client2.java @@ -0,0 +1,130 @@ +package wrappers; + +import java.io.BufferedReader; +import java.io.Console; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Set; + +public class Client2 { + static boolean DEBUG = true; + static final Console c = System.console(); + static Mongo2Interface jdi = null; + + public static void main(String[] args) { + int rc, m, i = 0; + boolean brc; + Set<String> columns; + String[] parms = new String[4]; + + jdi = new Mongo2Interface(DEBUG); + + parms[0] = getLine("URI: ", false); + parms[1] = getLine("DB: ", false); + parms[2] = null; + parms[3] = null; + + if (parms[0] == null) + parms[0] = "mongodb://localhost:27017"; + + if (parms[1] == null) + parms[1] = "test"; + + rc = jdi.MongoConnect(parms); + + if (rc == 0) { + String name, pipeline, query, fields; + System.out.println("Successfully connected to " + parms[1]); + + while ((name = getLine("Collection: ", false)) != null) { + if (jdi.GetCollection(name)) + System.out.println("GetCollection failed"); + else + System.out.println("Collection size: " + jdi.GetCollSize()); + + pipeline = getLine("Pipeline: ", false); + + if (pipeline == null) { + query = getLine("Filter: ", false); + fields = getLine("Proj: ", false); + brc = jdi.FindColl(query, fields); + } else + brc = jdi.AggregateColl(pipeline); + + System.out.println("Returned brc = " + brc); + + if (!brc) { + for (i = 0; i < 10; i++) { + m = jdi.ReadNext(); + + if (m > 0) { + columns = jdi.GetColumns(); + + for (String col : columns) + System.out.println(col + "=" + jdi.GetField(col)); + + if (pipeline == null) { + if (name.equalsIgnoreCase("gtst")) + System.out.println("gtst=" + jdi.GetField("*")); + + if (name.equalsIgnoreCase("inventory")) { + System.out.println("warehouse=" + jdi.GetField("instock.0.warehouse")); + System.out.println("quantity=" + jdi.GetField("instock.1.qty")); + } // endif inventory + + if (name.equalsIgnoreCase("restaurants")) { + System.out.println("score=" + jdi.GetField("grades.0.score")); + System.out.println("date=" + jdi.GetField("grades.0.date")); + } // endif restaurants + + } // endif pipeline + + } else if (m < 0) { + System.out.println("ReadNext: " + jdi.GetErrmsg()); + break; + } else + break; + + } // endfor i + + } // endif brc + + } // endwhile name + + rc = jdi.MongoDisconnect(); + System.out.println("Disconnect returned " + rc); + } else + System.out.println(jdi.GetErrmsg() + " rc=" + rc); + + } // end of main + + // ================================================================== + private static String getLine(String p, boolean b) { + String response; + + if (c != null) { + // Standard console mode + if (b) { + response = new String(c.readPassword(p)); + } else + response = c.readLine(p); + + } else { + // For instance when testing from Eclipse + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + + System.out.print(p); + + try { + // Cannot suppress echo for password entry + response = in.readLine(); + } catch (IOException e) { + response = ""; + } // end of try/catch + + } // endif c + + return (response.isEmpty()) ? null : response; + } // end of getLine + +} // end of class Client diff --git a/storage/connect/Client3.java b/storage/connect/Client3.java new file mode 100644 index 00000000000..0d3914cdd0d --- /dev/null +++ b/storage/connect/Client3.java @@ -0,0 +1,154 @@ +package wrappers; + +import java.io.BufferedReader; +import java.io.Console; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Set; + +public class Client3 { + static boolean DEBUG = true; + static final Console c = System.console(); + static Mongo3Interface jdi = null; + + public static void main(String[] args) { + int rc, level = 0; + boolean brc, desc = false; + Set<String> columns; + String[] parms = new String[4]; + + jdi = new Mongo3Interface(DEBUG); + + parms[0] = getLine("URI: ", false); + parms[1] = getLine("Database: ", false); + parms[2] = null; + parms[3] = null; + + if (parms[0] == null) + parms[0] = "mongodb://localhost:27017"; + + if (parms[1] == null) + parms[1] = "test"; + + rc = jdi.MongoConnect(parms); + + if (rc == 0) { + String name, pipeline, query, fields; + System.out.println("Successfully connected to " + parms[0]); + + while ((name = getLine("Collection: ", false)) != null) { + if (jdi.GetCollection(name)) + System.out.println("GetCollection failed"); + else + System.out.println("Collection size: " + jdi.GetCollSize()); + + pipeline = getLine("Pipeline: ", false); + + if (pipeline == null || (desc = pipeline.equals("*"))) { + query = getLine("Filter: ", false); + fields = getLine("Proj: ", false); + + if (desc) + level = Integer.parseInt(getLine("Level: ", false)); + + brc = jdi.FindColl(query, fields); + } else + brc = jdi.AggregateColl(pipeline); + + System.out.println("Returned brc = " + brc); + + if (!brc && !desc) { + for (int i = 0; jdi.ReadNext() > 0 && i < 10; i++) { + columns = jdi.GetColumns(); + + for (String col : columns) + System.out.println(col + "=" + jdi.GetField(col)); + + if (name.equalsIgnoreCase("gtst")) + System.out.println("gtst=" + jdi.GetField("*")); + + if (name.equalsIgnoreCase("inventory")) { + System.out.println("warehouse=" + jdi.GetField("instock.0.warehouse")); + System.out.println("quantity=" + jdi.GetField("instock.1.qty")); + } // endif inventory + + if (name.equalsIgnoreCase("restaurants")) { + System.out.println("score=" + jdi.GetField("grades.0.score")); + System.out.println("date=" + jdi.GetField("grades.0.date")); + } // endif inventory + + } // endfor i + + } else if (desc) { + int ncol; + + for (int i = 0; (ncol = jdi.ReadNext()) > 0 && i < 2; i++) { + if (discovery(null, "", ncol, level)) + break; + + System.out.println("--------------"); + } // endfor i + + } // endif desc + + } // endwhile query + + rc = jdi.MongoDisconnect(); + System.out.println("Disconnect returned " + rc); + } else + System.out.println(jdi.GetErrmsg() + " rc=" + rc); + + } // end of main + + private static boolean discovery(Object obj, String name, int ncol, int level) { + int[] val = new int[5]; + Object ret = null; + String bvn = null; + + for (int k = 0; k < ncol; k++) { + ret = jdi.ColumnDesc(obj, k, val, level); + bvn = jdi.ColDescName(); + + if (ret != null) + discovery(ret, name.concat(bvn).concat("."), val[4], level - 1); + else if (val[0] > 0) + System.out.println( + name + bvn + ": type=" + val[0] + " length=" + val[1] + " prec=" + val[2] + " nullable=" + val[3]); + else if (val[0] < 0) + System.out.println(jdi.GetErrmsg()); + + } // endfor k + + return false; + } // end of discovery + + // ================================================================== + private static String getLine(String p, boolean b) { + String response; + + if (c != null) { + // Standard console mode + if (b) { + response = new String(c.readPassword(p)); + } else + response = c.readLine(p); + + } else { + // For instance when testing from Eclipse + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + + System.out.print(p); + + try { + // Cannot suppress echo for password entry + response = in.readLine(); + } catch (IOException e) { + response = ""; + } // end of try/catch + + } // endif c + + return (response.isEmpty()) ? null : response; + } // end of getLine + +} // end of class Client diff --git a/storage/connect/Mongo2Interface.java b/storage/connect/Mongo2Interface.java index 106dd4a4d63..5d27fe467d6 100644 --- a/storage/connect/Mongo2Interface.java +++ b/storage/connect/Mongo2Interface.java @@ -21,6 +21,7 @@ import com.mongodb.util.JSON; public class Mongo2Interface { boolean DEBUG = false; String Errmsg = "No error"; + String ovalName = null; Set<String> Colnames = null; Cursor cursor = null; MongoClient client = null; @@ -220,7 +221,7 @@ public class Mongo2Interface { System.out.println("Class doc = " + doc.getClass()); Colnames = doc.keySet(); - return 1; + return Colnames.size(); } else return 0; @@ -253,30 +254,106 @@ public class Mongo2Interface { } // end of GetColumns - public String ColumnDesc(int n, int[] val) { - // if (rsmd == null) { - // System.out.println("No result metadata"); - // return null; - // } else try { - // val[0] = rsmd.getColumnType(n); - // val[1] = rsmd.getPrecision(n); - // val[2] = rsmd.getScale(n); - // val[3] = rsmd.isNullable(n); - // return rsmd.getColumnLabel(n); - // } catch (SQLException se) { - // SetErrmsg(se); - // } //end try/catch + public Object ColumnDesc(Object obj, int n, int[] val, int lvl) { + Object ret = null; + Object oval = ((obj != null) ? obj : doc); + BasicDBObject dob = (oval instanceof BasicDBObject) ? (BasicDBObject) oval : null; + BasicDBList ary = (oval instanceof BasicDBList) ? (BasicDBList) oval : null; + try { + if (ary != null) { + oval = ary.get(n); + ovalName = Integer.toString(n); + } else if (dob != null) { + // String[] k = dob.keySet().toArray(new String[0]); + Object[] k = dob.keySet().toArray(); + oval = dob.get(k[n]); + ovalName = (String) k[n]; + } else + ovalName = "x" + Integer.toString(n); + + if (DEBUG) + System.out.println("Class of " + ovalName + " = " + oval.getClass()); + + val[0] = 0; // ColumnType + val[1] = 0; // Precision + val[2] = 0; // Scale + val[3] = 0; // Nullable + val[4] = 0; // ncol + + if (oval == null) { + val[3] = 1; + } else if (oval instanceof String) { + val[0] = 1; + val[1] = ((String) oval).length(); + } else if (oval instanceof org.bson.types.ObjectId) { + val[0] = 1; + val[1] = ((org.bson.types.ObjectId) oval).toString().length(); + } else if (oval instanceof Integer) { + val[0] = 7; + val[1] = Integer.toString(((Integer) oval).intValue()).length(); + } else if (oval instanceof Long) { + val[0] = 5; + val[1] = Long.toString(((Long) oval).longValue()).length(); + } else if (oval instanceof Date) { + Long TS = (((Date) oval).getTime() / 1000); + val[0] = 8; + val[1] = TS.toString().length(); + } else if (oval instanceof Double) { + String d = Double.toString(((Double) oval).doubleValue()); + int i = d.indexOf('.') + 1; + + val[0] = 2; + val[1] = d.length(); + val[2] = (i > 0) ? val[1] - i : 0; + } else if (oval instanceof Boolean) { + val[0] = 4; + val[1] = 1; + } else if (oval instanceof BasicDBObject) { + if (lvl > 0) { + ret = oval; + val[0] = 1; + val[4] = ((BasicDBObject) oval).size(); + } else if (lvl == 0) { + val[0] = 1; + val[1] = oval.toString().length(); + } // endif lvl + + } else if (oval instanceof BasicDBList) { + if (lvl > 0) { + ret = oval; + val[0] = 2; + val[4] = ((BasicDBList) oval).size(); + } else if (lvl == 0) { + val[0] = 1; + val[1] = oval.toString().length(); + } // endif lvl + + } else { + SetErrmsg("Type " + " of " + ovalName + " not supported"); + val[0] = -1; + } // endif's + + return ret; + } catch (Exception ex) { + SetErrmsg(ex); + } // end try/catch + + val[0] = -1; return null; } // end of ColumnDesc + public String ColDescName() { + return ovalName; + } // end of ColDescName + protected Object GetFieldObject(String path) { Object o = null; BasicDBObject dob = null; BasicDBList lst = null; String[] names = null; - if (path == null || path.equals("*")) + if (path == null || path.equals("") || path.equals("*")) return doc; else if (doc instanceof BasicDBObject) dob = doc; @@ -325,9 +402,10 @@ public class Mongo2Interface { if (o != null) { if (o instanceof Date) { - Integer TS = (int) (((Date) o).getTime() / 1000); + Long TS = (((Date) o).getTime() / 1000); return TS.toString(); - } // endif Date + } else if (o instanceof Boolean) + return (Boolean) o ? "1" : "0"; return o.toString(); } else @@ -335,13 +413,25 @@ public class Mongo2Interface { } // end of GetField + public Object MakeBson(String s, int json) { + if (json == 1 || json == 2) { + return com.mongodb.util.JSON.parse(s); + } else + return null; + + } // end of MakeBson + public Object MakeDocument() { return new BasicDBObject(); } // end of MakeDocument - public boolean DocAdd(Object bdc, String key, Object val) { + public boolean DocAdd(Object bdc, String key, Object val, int json) { try { - ((BasicDBObject) bdc).append(key, val); + if (json != 0 && val instanceof String) + ((BasicDBObject) bdc).append(key, JSON.parse((String) val)); + else + ((BasicDBObject) bdc).append(key, val); + } catch (MongoException me) { SetErrmsg(me); return true; @@ -354,9 +444,13 @@ public class Mongo2Interface { return new BasicDBList(); } // end of MakeArray - public boolean ArrayAdd(Object bar, int n, Object val) { + public boolean ArrayAdd(Object bar, int n, Object val, int json) { try { - ((BasicDBList) bar).put(n, val); + if (json != 0 && val instanceof String) + ((BasicDBList) bar).put(n, JSON.parse((String) val)); + else + ((BasicDBList) bar).put(n, val); + } catch (MongoException me) { SetErrmsg(me); return true; diff --git a/storage/connect/Mongo3Interface.java b/storage/connect/Mongo3Interface.java index f587c01b391..73175e13aa3 100644 --- a/storage/connect/Mongo3Interface.java +++ b/storage/connect/Mongo3Interface.java @@ -1,5 +1,6 @@ package wrappers; +//import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.Date; @@ -9,6 +10,7 @@ import java.util.Set; import org.bson.BsonArray; import org.bson.BsonBoolean; import org.bson.BsonDateTime; +//import org.bson.BsonDecimal128; import org.bson.BsonDocument; import org.bson.BsonDouble; import org.bson.BsonInt32; @@ -18,6 +20,7 @@ import org.bson.BsonString; import org.bson.BsonValue; import org.bson.Document; import org.bson.conversions.Bson; +//import org.bson.types.Decimal128; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; @@ -34,6 +37,7 @@ import com.mongodb.client.result.UpdateResult; public class Mongo3Interface { boolean DEBUG = false; String Errmsg = "No error"; + String bvalName = null; Set<String> Colnames = null; MongoClient client = null; MongoDatabase db = null; @@ -167,7 +171,7 @@ public class Mongo3Interface { try { if (query != null) { - Bson dbq = Document.parse((query != null) ? query : "{}"); + Bson dbq = Document.parse(query); finditer = coll.find(dbq); } else finditer = coll.find(); @@ -218,17 +222,23 @@ public class Mongo3Interface { } // end of Rewind public int ReadNext() { - if (cursor.hasNext()) { - doc = cursor.next(); + try { + if (cursor.hasNext()) { + doc = cursor.next(); - if (DEBUG) - System.out.println("Class doc = " + doc.getClass()); + if (DEBUG) + System.out.println("Class doc = " + doc.getClass()); - Colnames = doc.keySet(); - return 1; - } else - return 0; + Colnames = doc.keySet(); + return Colnames.size(); + } else + return 0; + } catch (MongoException mx) { + SetErrmsg(mx); + } // end try/catch + + return -1; } // end of ReadNext public boolean Fetch(int row) { @@ -254,13 +264,11 @@ public class Mongo3Interface { } // end of GetColumns public String ColumnName(int n) { - int i = 1; - - for (String name : Colnames) - if (i++ == n) - return name; + if (n < Colnames.size()) + return (String) Colnames.toArray()[n]; + else + return null; - return null; } // end of ColumnName public int ColumnType(int n, String name) { @@ -278,30 +286,111 @@ public class Mongo3Interface { return 666; // Not a type } // end of ColumnType - public String ColumnDesc(int n, int[] val) { - // if (rsmd == null) { - // System.out.println("No result metadata"); - // return null; - // } else try { - // val[0] = rsmd.getColumnType(n); - // val[1] = rsmd.getPrecision(n); - // val[2] = rsmd.getScale(n); - // val[3] = rsmd.isNullable(n); - // return rsmd.getColumnLabel(n); - // } catch (SQLException se) { - // SetErrmsg(se); - // } //end try/catch + public Object ColumnDesc(Object obj, int n, int[] val, int lvl) { + Object ret = null; + BsonValue bval = (BsonValue) ((obj != null) ? obj : doc); + BsonDocument dob = (bval instanceof BsonDocument) ? (BsonDocument) bval : null; + BsonArray ary = (bval instanceof BsonArray) ? (BsonArray) bval : null; + + try { + if (ary != null) { + bval = ary.get(n); + bvalName = Integer.toString(n); + } else if (dob != null) { + // String[] k = dob.keySet().toArray(new String[0]); + Object[] k = dob.keySet().toArray(); + bval = dob.get(k[n]); + bvalName = (String) k[n]; + } else + bvalName = "x" + Integer.toString(n); + + val[0] = 0; // ColumnType + val[1] = 0; // Precision + val[2] = 0; // Scale + val[3] = 0; // Nullable + val[4] = 0; // ncol + + if (bval.isString()) { + val[0] = 1; + val[1] = bval.asString().getValue().length(); + } else if (bval.isInt32()) { + val[0] = 7; + val[1] = Integer.toString(bval.asInt32().getValue()).length(); + } else if (bval.isInt64()) { + val[0] = 5; + val[1] = Long.toString(bval.asInt64().getValue()).length(); + } else if (bval.isObjectId()) { + val[0] = 1; + val[1] = bval.asObjectId().getValue().toString().length(); + } else if (bval.isDateTime()) { + Long TS = (bval.asDateTime().getValue() / 1000); + val[0] = 8; + val[1] = TS.toString().length(); + } else if (bval.isDouble()) { + String d = Double.toString(bval.asDouble().getValue()); + int i = d.indexOf('.') + 1; + + val[0] = 2; + val[1] = d.length(); + val[2] = (i > 0) ? val[1] - i : 0; + } else if (bval.isBoolean()) { + val[0] = 4; + val[1] = 1; + } else if (bval.isDocument()) { + if (lvl > 0) { + ret = bval; + val[0] = 1; + val[4] = bval.asDocument().keySet().size(); + } else if (lvl == 0) { + val[0] = 1; + val[1] = bval.asDocument().toJson().length(); + } // endif lvl + + } else if (bval.isArray()) { + if (lvl > 0) { + ret = bval; + val[0] = 2; + val[4] = bval.asArray().size(); + } else if (lvl == 0) { + val[0] = 1; + util = new BsonDocument("arr", bval.asArray()); + String s = util.toJson(); + int i1 = s.indexOf('['); + int i2 = s.lastIndexOf(']'); + val[1] = i2 - i1 + 1; + } // endif lvl + + } else if (bval.isDecimal128()) { + val[0] = 9; + val[1] = bval.asDecimal128().toString().length(); + } else if (bval.isNull()) { + val[0] = 0; + val[3] = 1; + } else { + SetErrmsg("Type " + bval.getBsonType() + " of " + bvalName + " not supported"); + val[0] = -1; + } // endif's + + return ret; + } catch (Exception ex) { + SetErrmsg(ex); + } // end try/catch + val[0] = -1; return null; } // end of ColumnDesc + public String ColDescName() { + return bvalName; + } // end of ColDescName + protected BsonValue GetFieldObject(String path) { BsonValue o = doc; BsonDocument dob = null; BsonArray ary = null; String[] names = null; - if (path == null || path.equals("*")) + if (path == null || path.equals("") || path.equals("*")) return doc; else if (o instanceof BsonDocument) dob = doc; @@ -362,6 +451,8 @@ public class Mongo3Interface { return TS.toString(); } else if (o.isDouble()) { return Double.toString(o.asDouble().getValue()); + } else if (o.isBoolean()) { + return o.asBoolean().getValue() ? "1" : "0"; } else if (o.isDocument()) { return o.asDocument().toJson(); } else if (o.isArray()) { @@ -370,6 +461,8 @@ public class Mongo3Interface { int i1 = s.indexOf('['); int i2 = s.lastIndexOf(']'); return s.substring(i1, i2 + 1); + } else if (o.isDecimal128()) { + return o.asDecimal128().toString(); } else if (o.isNull()) { return null; } else @@ -380,14 +473,33 @@ public class Mongo3Interface { } // end of GetField - protected BsonValue ObjToBson(Object val) { + public Object MakeBson(String s, int json) { + BsonValue bval; + + if (json == 1) + bval = BsonDocument.parse(s); + else if (json == 2) + bval = BsonArray.parse(s); + else + bval = null; + + return bval; + } // end of MakeBson + + protected BsonValue ObjToBson(Object val, int json) { BsonValue bval = null; if (val == null) bval = bsonull; - else if (val.getClass() == String.class) - bval = new BsonString((String) val); - else if (val.getClass() == Integer.class) + else if (val.getClass() == String.class) { + if (json == 1) + bval = BsonDocument.parse((String) val); + else if (json == 2) + bval = BsonArray.parse((String) val); + else + bval = new BsonString((String) val); + + } else if (val.getClass() == Integer.class) bval = new BsonInt32((int) val); else if (val.getClass() == Double.class) bval = new BsonDouble((double) val); @@ -401,6 +513,8 @@ public class Mongo3Interface { bval = (BsonDocument) val; else if (val.getClass() == BsonArray.class) bval = (BsonArray) val; + // else if (val.getClass() == BigDecimal.class) + // bval = new BsonDecimal128((BigDecimal) val); return bval; } // end of ObjToBson @@ -409,9 +523,9 @@ public class Mongo3Interface { return new BsonDocument(); } // end of MakeDocument - public boolean DocAdd(Object bdc, String key, Object val) { + public boolean DocAdd(Object bdc, String key, Object val, int json) { try { - ((BsonDocument) bdc).append(key, ObjToBson(val)); + ((BsonDocument) bdc).append(key, ObjToBson(val, json)); } catch (MongoException me) { SetErrmsg(me); return true; @@ -424,12 +538,12 @@ public class Mongo3Interface { return new BsonArray(); } // end of MakeArray - public boolean ArrayAdd(Object bar, int n, Object val) { + public boolean ArrayAdd(Object bar, int n, Object val, int json) { try { for (int i = ((BsonArray) bar).size(); i < n; i++) ((BsonArray) bar).add(bsonull); - ((BsonArray) bar).add(ObjToBson(val)); + ((BsonArray) bar).add(ObjToBson(val, json)); } catch (MongoException me) { SetErrmsg(me); return true; @@ -501,4 +615,4 @@ public class Mongo3Interface { return n; } // end of CollDelete -} // end of class MongoInterface +} // end of class Mongo3Interface diff --git a/storage/connect/TestInsert2.java b/storage/connect/TestInsert2.java new file mode 100644 index 00000000000..e1a7cb4f98b --- /dev/null +++ b/storage/connect/TestInsert2.java @@ -0,0 +1,131 @@ +package wrappers; + +import java.io.BufferedReader; +import java.io.Console; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Date; + +public class TestInsert2 { + static boolean DEBUG = true; + static final Console c = System.console(); + static Mongo2Interface jdi = null; + + public static void main(String[] args) { + int rc; + String[] parms = new String[4]; + + jdi = new Mongo2Interface(DEBUG); + + parms[0] = getLine("URI: ", false); + parms[1] = getLine("Database: ", false); + parms[2] = null; + parms[3] = null; + + if (parms[0] == null) + parms[0] = "mongodb://localhost:27017"; + + if (parms[1] == null) + parms[1] = "test"; + + rc = jdi.MongoConnect(parms); + + if (rc == 0) { + Object bdoc = jdi.MakeDocument(); + + if (jdi.DocAdd(bdoc, "_id", (Object) 1, 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Name", (Object) "Smith", 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Age", (Object) 39, 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Pi", (Object) 3.14, 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Phone", (Object) "{\"ext\":[4,5,7]}", 1)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Scores", (Object) "[24,2,13]", 2)) + System.out.println(jdi.GetErrmsg()); + + Object bar = jdi.MakeArray(); + + for (int i = 1; i < 3; i++) + if (jdi.ArrayAdd(bar, i, (Object) (Math.random() * 10.0), 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Prices", bar, 0)) + System.out.println(jdi.GetErrmsg()); + + Object dat = new Date(); + + if (jdi.DocAdd(bdoc, "Date", dat, 0)) + System.out.println(jdi.GetErrmsg()); + + System.out.println(bdoc); + + // Try to update + if (!jdi.GetCollection("updtest") && !jdi.FindColl(null, null)) { + if (jdi.CollDelete(true) < 0) + System.out.println(jdi.GetErrmsg()); + + if (jdi.CollInsert(bdoc)) + System.out.println(jdi.GetErrmsg()); + + Object updlist = jdi.MakeDocument(); + + if (jdi.DocAdd(updlist, "Age", (Object) 45, 0)) + System.out.println(jdi.GetErrmsg()); + + Object upd = jdi.MakeDocument(); + + if (jdi.DocAdd(upd, "$set", updlist, 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.ReadNext() > 0 && jdi.CollUpdate(upd) < 0) + System.out.println(jdi.GetErrmsg()); + + if (!jdi.Rewind() && jdi.ReadNext() > 0) + System.out.println(jdi.GetDoc()); + else + System.out.println("Failed Rewind"); + + } // endif n + + } // endif rc + + } // end of main + + // ================================================================== + private static String getLine(String p, boolean b) { + String response; + + if (c != null) { + // Standard console mode + if (b) { + response = new String(c.readPassword(p)); + } else + response = c.readLine(p); + + } else { + // For instance when testing from Eclipse + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + + System.out.print(p); + + try { + // Cannot suppress echo for password entry + response = in.readLine(); + } catch (IOException e) { + response = ""; + } // end of try/catch + + } // endif c + + return (response.isEmpty()) ? null : response; + } // end of getLine + +} diff --git a/storage/connect/TestInsert3.java b/storage/connect/TestInsert3.java new file mode 100644 index 00000000000..a56a361e7aa --- /dev/null +++ b/storage/connect/TestInsert3.java @@ -0,0 +1,131 @@ +package wrappers; + +import java.io.BufferedReader; +import java.io.Console; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Date; + +public class TestInsert3 { + static boolean DEBUG = true; + static final Console c = System.console(); + static Mongo3Interface jdi = null; + + public static void main(String[] args) { + int rc; + String[] parms = new String[4]; + + jdi = new Mongo3Interface(DEBUG); + + parms[0] = getLine("URI: ", false); + parms[1] = getLine("Database: ", false); + parms[2] = null; + parms[3] = null; + + if (parms[0] == null) + parms[0] = "mongodb://localhost:27017"; + + if (parms[1] == null) + parms[1] = "test"; + + rc = jdi.MongoConnect(parms); + + if (rc == 0) { + Object bdoc = jdi.MakeDocument(); + + if (jdi.DocAdd(bdoc, "_id", (Object) 1, 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Name", (Object) "Smith", 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Age", (Object) 39, 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Pi", (Object) 3.14, 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Phone", (Object) "{\"ext\":[4,5,7]}", 1)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Scores", (Object) "[24,2,13]", 2)) + System.out.println(jdi.GetErrmsg()); + + Object bar = jdi.MakeArray(); + + for (int i = 0; i < 2; i++) + if (jdi.ArrayAdd(bar, i, (Object) (Math.random() * 10.0), 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.DocAdd(bdoc, "Prices", bar, 0)) + System.out.println(jdi.GetErrmsg()); + + Object dat = new Date(); + + if (jdi.DocAdd(bdoc, "Date", dat, 0)) + System.out.println(jdi.GetErrmsg()); + + System.out.println(bdoc); + + // Try to update + if (!jdi.GetCollection("updtest") && !jdi.FindColl(null, null)) { + if (jdi.CollDelete(true) < 0) + System.out.println(jdi.GetErrmsg()); + + if (jdi.CollInsert(bdoc)) + System.out.println(jdi.GetErrmsg()); + + Object updlist = jdi.MakeDocument(); + + if (jdi.DocAdd(updlist, "Age", (Object) 40, 0)) + System.out.println(jdi.GetErrmsg()); + + Object upd = jdi.MakeDocument(); + + if (jdi.DocAdd(upd, "$set", updlist, 0)) + System.out.println(jdi.GetErrmsg()); + + if (jdi.ReadNext() > 0 && jdi.CollUpdate(upd) < 0) + System.out.println(jdi.GetErrmsg()); + + if (!jdi.Rewind() && jdi.ReadNext() > 0) + System.out.println(jdi.GetDoc()); + else + System.out.println("Failed Rewind"); + + } // endif n + + } // endif rc + + } // end of main + + // ================================================================== + private static String getLine(String p, boolean b) { + String response; + + if (c != null) { + // Standard console mode + if (b) { + response = new String(c.readPassword(p)); + } else + response = c.readLine(p); + + } else { + // For instance when testing from Eclipse + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + + System.out.print(p); + + try { + // Cannot suppress echo for password entry + response = in.readLine(); + } catch (IOException e) { + response = ""; + } // end of try/catch + + } // endif c + + return (response.isEmpty()) ? null : response; + } // end of getLine + +} diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp index 3c736941b6f..6d105c12a59 100644 --- a/storage/connect/array.cpp +++ b/storage/connect/array.cpp @@ -19,14 +19,14 @@ #include "sql_class.h" //#include "sql_time.h" -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <stdint.h> // for uintprt_h -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include required application header files */ diff --git a/storage/connect/blkfil.cpp b/storage/connect/blkfil.cpp index 76c9d09ac93..93ae5a5ef0c 100644 --- a/storage/connect/blkfil.cpp +++ b/storage/connect/blkfil.cpp @@ -20,13 +20,13 @@ #include "sql_class.h" //#include "sql_time.h" -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #include <string.h> #include <sys/types.h> #include <sys/stat.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ diff --git a/storage/connect/block.h b/storage/connect/block.h index c10fc4761ac..e8871277d48 100644 --- a/storage/connect/block.h +++ b/storage/connect/block.h @@ -24,11 +24,11 @@ #if !defined(BLOCK_DEFINED) #define BLOCK_DEFINED -#if defined(__WIN__) && !defined(NOEX) +#if defined(_WIN32) && !defined(NOEX) #define DllExport __declspec( dllexport ) -#else // !__WIN__ +#else // !_WIN32 #define DllExport -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Definition of class BLOCK with its method function new. */ diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 132c7fdd51f..fa9cd5f1e52 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -30,7 +30,7 @@ #define CheckType(X,Y) #endif -#if defined(__WIN__) +#if defined(_WIN32) #define EL "\r\n" #else #define EL "\n" @@ -1205,15 +1205,14 @@ void BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n) int i = 0; PBVAL bvp = NULL; - if (bap->To_Val) - for (bvp = GetArray(bap); bvp; i++, bvp = GetNext(bvp)) - if (i == n) { - SetValueVal(bvp, nvp); - return; - } + for (bvp = GetArray(bap); i < n; i++, bvp = bvp ? GetNext(bvp) : NULL) + if (!bvp) + AddArrayValue(bap, NewVal()); if (!bvp) AddArrayValue(bap, MOF(nvp)); + else + SetValueVal(bvp, nvp); } // end of SetValue diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp index a7d8f811975..7022600e140 100644 --- a/storage/connect/bsonudf.cpp +++ b/storage/connect/bsonudf.cpp @@ -1890,24 +1890,31 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n) /*********************************************************************************/ int IsArgJson(UDF_ARGS *args, uint i) { - int n = 0; + const char *pat = args->attributes[i]; + int n = 0; + + if (*pat == '@') { + pat++; + + if (*pat == '\'' || *pat == '"') + pat++; + + } // endif pat if (i >= args->arg_count || args->arg_type[i] != STRING_RESULT) { - } else if (!strnicmp(args->attributes[i], "Bson_", 5) || - !strnicmp(args->attributes[i], "Json_", 5)) { + } else if (!strnicmp(pat, "Bson_", 5) || !strnicmp(pat, "Json_", 5)) { if (!args->args[i] || strchr("[{ \t\r\n", *args->args[i])) n = 1; // arg should be is a json item // else // n = 2; // A file name may have been returned - } else if (!strnicmp(args->attributes[i], "Bbin_", 5)) { + } else if (!strnicmp(pat, "Bbin_", 5)) { if (args->lengths[i] == sizeof(BSON)) n = 3; // arg is a binary json item // else // n = 2; // A file name may have been returned - } else if (!strnicmp(args->attributes[i], "Bfile_", 6) || - !strnicmp(args->attributes[i], "Jfile_", 6)) { + } else if (!strnicmp(pat, "Bfile_", 6) || !strnicmp(pat, "Jfile_", 6)) { n = 2; // arg is a json file name #if 0 } else if (args->lengths[i]) { diff --git a/storage/connect/cmgfam.cpp b/storage/connect/cmgfam.cpp index 690c087c2bb..a3afc154224 100644 --- a/storage/connect/cmgfam.cpp +++ b/storage/connect/cmgfam.cpp @@ -56,6 +56,7 @@ CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL) Pcg.Coll_name = tdp->Collname; Pcg.Options = tdp->Options; Pcg.Filter = tdp->Filter; + Pcg.Line = NULL; Pcg.Pipe = tdp->Pipe && tdp->Options != NULL; Lrecl = tdp->Lrecl + tdp->Ending; } else { @@ -64,6 +65,7 @@ CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL) Pcg.Coll_name = NULL; Pcg.Options = NULL; Pcg.Filter = NULL; + Pcg.Line = NULL; Pcg.Pipe = false; Lrecl = 0; } // endif tdp @@ -88,6 +90,7 @@ CMGFAM::CMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL) Pcg.Coll_name = tdp->Collname; Pcg.Options = tdp->Options; Pcg.Filter = tdp->Filter; + Pcg.Line = NULL; Pcg.Pipe = tdp->Pipe && tdp->Options != NULL; Lrecl = tdp->Lrecl + tdp->Ending; } else { @@ -96,6 +99,7 @@ CMGFAM::CMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL) Pcg.Coll_name = NULL; Pcg.Options = NULL; Pcg.Filter = NULL; + Pcg.Line = NULL; Pcg.Pipe = false; Lrecl = 0; } // endif tdp @@ -280,6 +284,7 @@ int CMGFAM::ReadBuffer(PGLOBAL g) /***********************************************************************/ int CMGFAM::WriteBuffer(PGLOBAL g) { + Pcg.Line = Tdbp->GetLine(); return Cmgp->Write(g); } // end of WriteBuffer diff --git a/storage/connect/cmgoconn.cpp b/storage/connect/cmgoconn.cpp index 474f940a8cf..f3fc30fa9e2 100644 --- a/storage/connect/cmgoconn.cpp +++ b/storage/connect/cmgoconn.cpp @@ -1,7 +1,7 @@ /************ CMgoConn C++ Functions Source Code File (.CPP) ***********/ -/* Name: CMgoConn.CPP Version 1.0 */ +/* Name: CMgoConn.CPP Version 1.1 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */ /* */ /* This file contains the MongoDB C connection classes functions. */ /***********************************************************************/ @@ -24,8 +24,9 @@ bool CMgoConn::IsInit = false; -bool IsNum(PSZ s); +bool IsArray(PSZ s); bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s); +int GetDefaultPrec(void); /* --------------------------- Class INCOL --------------------------- */ @@ -47,12 +48,13 @@ void INCOL::AddCol(PGLOBAL g, PCOL colp, char *jp) break; if (!kp) { - icp = new(g) INCOL(IsNum(p)); + icp = new(g) INCOL(); kcp = (PKC)PlugSubAlloc(g, NULL, sizeof(KEYCOL)); kcp->Next = NULL; kcp->Incolp = icp; kcp->Colp = NULL; kcp->Key = PlugDup(g, jp); + kcp->Array = IsArray(p); if (Klist) { for (kp = Klist; kp->Next; kp = kp->Next); @@ -73,6 +75,7 @@ void INCOL::AddCol(PGLOBAL g, PCOL colp, char *jp) kcp->Incolp = NULL; kcp->Colp = colp; kcp->Key = jp; + kcp->Array = IsArray(jp); if (Klist) { for (kp = Klist; kp->Next; kp = kp->Next); @@ -120,11 +123,12 @@ CMgoConn::CMgoConn(PGLOBAL g, PCPARM pcg) { Pcg = pcg; Uri = NULL; - Pool = NULL; +//Pool = NULL; Client = NULL; Database = NULL; Collection = NULL; Cursor = NULL; + Document = NULL; Query = NULL; Opts = NULL; Fpc = NULL; @@ -157,24 +161,26 @@ bool CMgoConn::Connect(PGLOBAL g) } // endif name if (!IsInit) -#if defined(__WIN__) +#if defined(_WIN32) __try { mongo_init(true); } __except (EXCEPTION_EXECUTE_HANDLER) { strcpy(g->Message, "Cannot load MongoDB C driver"); return true; } // end try/except -#else // !__WIN__ +#else // !_WIN32 mongo_init(true); -#endif // !__WIN__ +#endif // !_WIN32 - Uri = mongoc_uri_new(Pcg->Uristr); + Uri = mongoc_uri_new_with_error(Pcg->Uristr, &Error); if (!Uri) { - sprintf(g->Message, "Failed to parse URI: \"%s\"", Pcg->Uristr); + sprintf(g->Message, "Failed to parse URI: \"%s\" Msg: %s", + Pcg->Uristr, Error.message); return true; } // endif Uri +#if 0 // Create a new client pool instance Pool = mongoc_client_pool_new(Uri); mongoc_client_pool_set_error_api(Pool, 2); @@ -185,13 +191,24 @@ bool CMgoConn::Connect(PGLOBAL g) // Create a new client instance Client = mongoc_client_pool_pop(Pool); +#else + // Create a new client instance + Client = mongoc_client_new_from_uri (Uri); if (!Client) { sprintf(g->Message, "Failed to get Client"); return true; } // endif Client - // Get a handle on the collection Coll_name + // Register the application name so we can track it in the profile logs + // on the server. This can also be done from the URI (see other examples). + mongoc_client_set_appname (Client, "Connect"); + + // Get a handle on the database + // Database = mongoc_client_get_database (Client, Pcg->Db_name); +#endif // 0 + + // Get a handle on the collection Collection = mongoc_client_get_collection(Client, Pcg->Db_name, Pcg->Coll_name); if (!Collection) { @@ -228,8 +245,8 @@ bool CMgoConn::Connect(PGLOBAL g) int CMgoConn::CollSize(PGLOBAL g) { int cnt; - bson_t *query; - const char *jf = NULL; + bson_t* query; + const char* jf = NULL; if (Pcg->Pipe) return 10; @@ -237,7 +254,7 @@ int CMgoConn::CollSize(PGLOBAL g) jf = Pcg->Filter; if (jf) { - query = bson_new_from_json((const uint8_t *)jf, -1, &Error); + query = bson_new_from_json((const uint8_t*)jf, -1, &Error); if (!query) { htrc("Wrong filter: %s", Error.message); @@ -247,8 +264,17 @@ int CMgoConn::CollSize(PGLOBAL g) } else query = bson_new(); +#if defined(DEVELOPMENT) + if (jf) + cnt = (int)mongoc_collection_count_documents(Collection, + query, NULL, NULL, NULL, &Error); + else + cnt = (int)mongoc_collection_estimated_document_count( + Collection, NULL, NULL, NULL, &Error); +#else cnt = (int)mongoc_collection_count(Collection, - MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error); + MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error); +#endif if (cnt < 0) { htrc("Collection count: %s", Error.message); @@ -260,30 +286,91 @@ int CMgoConn::CollSize(PGLOBAL g) } // end of CollSize /***********************************************************************/ -/* OpenDB: Data Base open routine for MONGO access method. */ +/* Project: make the projection avoid path collision. */ +/***********************************************************************/ +void CMgoConn::Project(PGLOBAL g, PSTRG s) +{ + bool m, b = false; + size_t n; + PSZ path; + PCOL cp; + PTDB tp = Pcg->Tdbp; + PTHP hp, php = NULL, * nphp = &php; + + for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) { + path = cp->GetJpath(g, true); + + // Resolve path collision + for (hp = php; hp; hp = hp->Next) { + if (strlen(path) < strlen(hp->Path)) { + n = strlen(path); + m = true; + } else { + n = strlen(hp->Path); + m = false; + } // endif path + + if (!strncmp(path, hp->Path, n)) + break; + + } // endfor hp + + if (!hp) { + // New path + hp = (PTHP)PlugSubAlloc(g, NULL, sizeof(PTH)); + hp->Path = path; + hp->Name = cp->GetName(); + hp->Next = NULL; + *nphp = hp; + nphp = &hp->Next; + } else if (m) // Smaller path must replace longer one + hp->Path = path; + + } // endfor cp + + for (hp = php; hp; hp = hp->Next) { + if (b) + s->Append(",\""); + else + b = true; + + if (*hp->Path == '{') { + // This is a Mongo defined column + s->Append(hp->Name); + s->Append("\":"); + s->Append(hp->Path); + } else { + s->Append(hp->Path); + s->Append("\":1"); + } // endif Path + + } // endfor hp + +} // end of Project + +/***********************************************************************/ +/* MakeCursor: make the cursor used to retrieve documents. */ /***********************************************************************/ bool CMgoConn::MakeCursor(PGLOBAL g) { const char *p; - bool id, b = false, all = false; + bool id, all = false; PCSZ options = Pcg->Options; PTDB tp = Pcg->Tdbp; PCOL cp; PSTRG s = NULL; PFIL filp = tp->GetFilter(); - id = (tp->GetMode() != MODE_READ); + id = (tp->GetMode() == MODE_UPDATE || tp->GetMode() == MODE_DELETE); if (options && !stricmp(options, "all")) { options = NULL; all = true; - } // endif Options - - for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) - if (!strcmp(cp->GetName(), "_id")) - id = true; - else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && !options) + } else for (cp = tp->GetColumns(); cp && !all; cp = cp->GetNext()) + if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && !options) all = true; + else if (!id) + id = !strcmp(cp->GetFmt() ? cp->GetFmt() : cp->GetName(), "_id"); if (Pcg->Pipe) { if (trace(1)) @@ -311,23 +398,14 @@ bool CMgoConn::MakeCursor(PGLOBAL g) tp->SetFilter(NULL); // Not needed anymore } // endif To_Filter - if (!all && tp->GetColumns()) { + if (tp->GetColumns() && !strstr(s->GetStr(), "$project")) { // Project list s->Append(",{\"$project\":{\""); if (!id) s->Append("_id\":0,\""); - for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) { - if (b) - s->Append(",\""); - else - b = true; - - s->Append(cp->GetJpath(g, true)); - s->Append("\":1"); - } // endfor cp - + Project(g, s); s->Append("}}"); } // endif all @@ -377,7 +455,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g) if (MakeSelector(g, filp, s)) { strcpy(g->Message, "Failed making selector"); - return NULL; + return true; } // endif Selector tp->SetFilter(NULL); // Not needed anymore @@ -391,7 +469,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g) if (!Query) { sprintf(g->Message, "Wrong filter: %s", Error.message); - return NULL; + return true; } // endif Query } else @@ -413,16 +491,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g) if (!id) s->Append("_id\":0,\""); - for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) { - if (b) - s->Append(",\""); - else - b = true; - - s->Append(cp->GetJpath(g, true)); - s->Append("\":1"); - } // endfor cp - + Project(g, s); s->Append("}}"); s->Resize(s->GetLength() + 1); p = s->GetStr(); @@ -435,7 +504,7 @@ bool CMgoConn::MakeCursor(PGLOBAL g) if (!Opts) { sprintf(g->Message, "Wrong options: %s", Error.message); - return NULL; + return true; } // endif Opts } // endif all @@ -495,44 +564,54 @@ void CMgoConn::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k) key = bson_iter_key(iter); htrc("Found element key: \"%s\"\n", key); - if (BSON_ITER_HOLDS_UTF8(iter)) - htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL)); - else if (BSON_ITER_HOLDS_INT32(iter)) - htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter)); - else if (BSON_ITER_HOLDS_INT64(iter)) - htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter)); - else if (BSON_ITER_HOLDS_DOUBLE(iter)) - htrc("%s.%s=%g\n", k, key, bson_iter_double(iter)); - else if (BSON_ITER_HOLDS_DATE_TIME(iter)) - htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter)); - else if (BSON_ITER_HOLDS_OID(iter)) { - char str[25]; - - bson_oid_to_string(bson_iter_oid(iter), str); - htrc("%s.%s=%s\n", k, key, str); - } else if (BSON_ITER_HOLDS_DECIMAL128(iter)) { - char *str = NULL; - bson_decimal128_t dec; - - bson_iter_decimal128(iter, &dec); - bson_decimal128_to_string(&dec, str); - htrc("%s.%s=%s\n", k, key, str); - } else if (BSON_ITER_HOLDS_DOCUMENT(iter)) { - bson_iter_t child; - - if (bson_iter_recurse(iter, &child)) - ShowDocument(&child, NULL, key); - - } else if (BSON_ITER_HOLDS_ARRAY(iter)) { - bson_t *arr; - bson_iter_t itar; - const uint8_t *data = NULL; - uint32_t len = 0; - - bson_iter_array(iter, &len, &data); - arr = bson_new_from_data(data, len); - ShowDocument(&itar, arr, key); - } // endif's + switch (bson_iter_type(iter)) { + case BSON_TYPE_UTF8: + htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL)); + break; + case BSON_TYPE_INT32: + htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter)); + break; + case BSON_TYPE_INT64: + htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter)); + break; + case BSON_TYPE_DOUBLE: + htrc("%s.%s=%g\n", k, key, bson_iter_double(iter)); + break; + case BSON_TYPE_DATE_TIME: + htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter)); + break; + case BSON_TYPE_OID: { + char str[25]; + + bson_oid_to_string(bson_iter_oid(iter), str); + htrc("%s.%s=%s\n", k, key, str); + } break; + case BSON_TYPE_DECIMAL128: { + char str[BSON_DECIMAL128_STRING]; + bson_decimal128_t dec; + + bson_iter_decimal128(iter, &dec); + bson_decimal128_to_string(&dec, str); + htrc("%s.%s=%s\n", k, key, str); + } break; + case BSON_TYPE_DOCUMENT: { + bson_iter_t child; + + if (bson_iter_recurse(iter, &child)) + ShowDocument(&child, NULL, key); + + } break; + case BSON_TYPE_ARRAY: { + bson_t* arr; + bson_iter_t itar; + const uint8_t* data = NULL; + uint32_t len = 0; + + bson_iter_array(iter, &len, &data); + arr = bson_new_from_data(data, len); + ShowDocument(&itar, arr, key); + } break; + } // endswitch iter } // endwhile bson_iter_next @@ -545,7 +624,7 @@ void CMgoConn::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k) /***********************************************************************/ void CMgoConn::MakeColumnGroups(PGLOBAL g) { - Fpc = new(g) INCOL(false); + Fpc = new(g) INCOL(); for (PCOL colp = Pcg->Tdbp->GetColumns(); colp; colp = colp->GetNext()) if (!colp->IsSpecial()) @@ -560,7 +639,7 @@ bool CMgoConn::DocWrite(PGLOBAL g, PINCOL icp) { for (PKC kp = icp->Klist; kp; kp = kp->Next) if (kp->Incolp) { - bool isdoc = !kp->Incolp->Array; + bool isdoc = !kp->Array; if (isdoc) BSON_APPEND_DOCUMENT_BEGIN(icp->Child, kp->Key, kp->Incolp->Child); @@ -582,7 +661,7 @@ bool CMgoConn::DocWrite(PGLOBAL g, PINCOL icp) } // end of DocWrite /***********************************************************************/ -/* WriteDB: Data Base write routine for DOS access method. */ +/* WriteDB: Data Base write routine for CMGO access method. */ /***********************************************************************/ int CMgoConn::Write(PGLOBAL g) { @@ -590,22 +669,45 @@ int CMgoConn::Write(PGLOBAL g) PTDB tp = Pcg->Tdbp; if (tp->GetMode() == MODE_INSERT) { - Fpc->Init(); + if (!Pcg->Line) { + Fpc->Init(); - if (DocWrite(g, Fpc)) - return RC_FX; + if (DocWrite(g, Fpc)) + return RC_FX; - if (trace(2)) { - char *str = bson_as_json(Fpc->Child, NULL); - htrc("Inserting: %s\n", str); - bson_free(str); - } // endif trace + if (trace(2)) { + char* str = bson_as_json(Fpc->Child, NULL); + htrc("Inserting: %s\n", str); + bson_free(str); + } // endif trace - if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE, - Fpc->Child, NULL, &Error)) { - sprintf(g->Message, "Mongo insert: %s", Error.message); - rc = RC_FX; - } // endif insert + if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE, + Fpc->Child, NULL, &Error)) { + sprintf(g->Message, "Mongo insert: %s", Error.message); + rc = RC_FX; + } // endif insert + + } else { + const uint8_t* val = (const uint8_t*)Pcg->Line; + bson_t* doc = bson_new_from_json(val, -1, &Error); + + if (doc && trace(2)) { + char* str = bson_as_json(doc, NULL); + htrc("Inserting: %s\n", str); + bson_free(str); + } // endif trace + + if (!doc) { + sprintf(g->Message, "bson_new_from_json: %s", Error.message); + rc = RC_FX; + } else if (!mongoc_collection_insert(Collection, + MONGOC_INSERT_NONE, doc, NULL, &Error)) { + sprintf(g->Message, "Mongo insert: %s", Error.message); + bson_destroy(doc); + rc = RC_FX; + } // endif insert + + } // endif Line } else { bool b = false; @@ -614,19 +716,26 @@ int CMgoConn::Write(PGLOBAL g) bson_iter_init(&iter, Document); - if (bson_iter_find(&iter, "_id")) { - if (BSON_ITER_HOLDS_OID(&iter)) - b = BSON_APPEND_OID(query, "_id", bson_iter_oid(&iter)); - else if (BSON_ITER_HOLDS_INT32(&iter)) - b = BSON_APPEND_INT32(query, "_id", bson_iter_int32(&iter)); - else if (BSON_ITER_HOLDS_INT64(&iter)) - b = BSON_APPEND_INT64(query, "_id", bson_iter_int64(&iter)); - else if (BSON_ITER_HOLDS_DOUBLE(&iter)) - b = BSON_APPEND_DOUBLE(query, "_id", bson_iter_double(&iter)); - else if (BSON_ITER_HOLDS_UTF8(&iter)) - b = BSON_APPEND_UTF8(query, "_id", bson_iter_utf8(&iter, NULL)); - - } // endif iter + if (bson_iter_find(&iter, "_id")) + switch (bson_iter_type(&iter)) { + case BSON_TYPE_OID: + b = BSON_APPEND_OID(query, "_id", bson_iter_oid(&iter)); + break; + case BSON_TYPE_UTF8: + b = BSON_APPEND_UTF8(query, "_id", bson_iter_utf8(&iter, NULL)); + break; + case BSON_TYPE_INT32: + b = BSON_APPEND_INT32(query, "_id", bson_iter_int32(&iter)); + break; + case BSON_TYPE_INT64: + b = BSON_APPEND_INT64(query, "_id", bson_iter_int64(&iter)); + break; + case BSON_TYPE_DOUBLE: + b = BSON_APPEND_DOUBLE(query, "_id", bson_iter_double(&iter)); + break; + default: + break; + } // endswitch iter if (b) { if (trace(2)) { @@ -708,8 +817,9 @@ void CMgoConn::Close(void) if (Opts) bson_destroy(Opts); if (Cursor) mongoc_cursor_destroy(Cursor); if (Collection) mongoc_collection_destroy(Collection); - if (Client) mongoc_client_pool_push(Pool, Client); - if (Pool) mongoc_client_pool_destroy(Pool); +//if (Client) mongoc_client_pool_push(Pool, Client); +//if (Pool) mongoc_client_pool_destroy(Pool); + if (Client) mongoc_client_destroy(Client); if (Uri) mongoc_uri_destroy(Uri); if (Fpc) Fpc->Destroy(); if (fp) fp->Count = 0; @@ -720,23 +830,51 @@ void CMgoConn::Close(void) /***********************************************************************/ char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b) { - char *s, *str = NULL; - char *Mbuf = (char*)PlugSubAlloc(g, NULL, colp->GetLength() + 1); - int i, k = 0; - bool ok = true; + char *s, *str = NULL; + char *Mbuf = (char*)PlugSubAlloc(g, NULL, (size_t)colp->GetLength() + 1); + int i, j = 0, k = 0, n = 0, m = GetDefaultPrec(); + bool ok = true, dbl = false; + double d; + size_t len; if (b) - s = str = bson_array_as_json(bson, NULL); + s = str = bson_array_as_json(bson, &len); else - s = str = bson_as_json(bson, NULL); + s = str = bson_as_json(bson, &len); + + if (len > (size_t)colp->GetLength()) { + sprintf(g->Message, "Value too long for column %s", colp->GetName()); + bson_free(str); + throw (int)TYPE_AM_MGO; + } // endif len for (i = 0; i < colp->GetLength() && s[i]; i++) { switch (s[i]) { case ' ': if (ok) continue; + break; case '"': ok = !ok; + break; + case '.': + if (j) dbl = true; + break; default: + if (ok) { + if (isdigit(s[i])) { + if (!j) j = k; + if (dbl) n++; + } else if (dbl && n > m) { + Mbuf[k] = 0; + d = atof(Mbuf + j); + n = sprintf(Mbuf + j, "%.*f", m, d); + k = j + n; + j = n = 0; + } else if (j) + j = n = 0; + + } // endif ok + break; } // endswitch s[i] @@ -745,11 +883,6 @@ char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b) bson_free(str); - if (i >= colp->GetLength()) { - sprintf(g->Message, "Value too long for column %s", colp->GetName()); - throw (int)TYPE_AM_MGO; - } // endif i - Mbuf[k] = 0; return Mbuf; } // end of Mini @@ -759,97 +892,103 @@ char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b) /***********************************************************************/ void CMgoConn::GetColumnValue(PGLOBAL g, PCOL colp) { - char *jpath = colp->GetJpath(g, false); - PVAL value = colp->GetValue(); - - if (!strcmp(jpath, "*")) { + char *jpath = colp->GetJpath(g, false); + bool b = false; + PVAL value = colp->GetValue(); + bson_iter_t Iter; // Used to retrieve column value + bson_iter_t Desc; // Descendant iter + + if (*jpath == '{') + jpath = colp->GetName(); // This is a Mongo defined column + + if (!*jpath || !strcmp(jpath, "*")) { value->SetValue_psz(Mini(g, colp, Document, false)); } else if (bson_iter_init(&Iter, Document) && bson_iter_find_descendant(&Iter, jpath, &Desc)) { - if (BSON_ITER_HOLDS_UTF8(&Desc)) - value->SetValue_psz((PSZ)bson_iter_utf8(&Desc, NULL)); - else if (BSON_ITER_HOLDS_INT32(&Desc)) - value->SetValue(bson_iter_int32(&Desc)); - else if (BSON_ITER_HOLDS_INT64(&Desc)) - value->SetValue(bson_iter_int64(&Desc)); - else if (BSON_ITER_HOLDS_DOUBLE(&Desc)) - value->SetValue(bson_iter_double(&Desc)); - else if (BSON_ITER_HOLDS_DATE_TIME(&Desc)) - value->SetValue(bson_iter_date_time(&Desc) / 1000); - else if (BSON_ITER_HOLDS_BOOL(&Desc)) { - bool b = bson_iter_bool(&Desc); - - if (value->IsTypeNum()) - value->SetValue(b ? 1 : 0); - else - value->SetValue_psz(b ? "true" : "false"); - - } else if (BSON_ITER_HOLDS_OID(&Desc)) { - char str[25]; - - bson_oid_to_string(bson_iter_oid(&Desc), str); - value->SetValue_psz(str); - } else if (BSON_ITER_HOLDS_NULL(&Iter)) { - // Apparently this does not work... - value->Reset(); - value->SetNull(true); - } else if (BSON_ITER_HOLDS_DECIMAL128(&Desc)) { - char *str = NULL; - bson_decimal128_t dec; - - bson_iter_decimal128(&Desc, &dec); - bson_decimal128_to_string(&dec, str); - value->SetValue_psz(str); - bson_free(str); - } else if (BSON_ITER_HOLDS_DOCUMENT(&Iter)) { - bson_t *doc; - const uint8_t *data = NULL; - uint32_t len = 0; - - bson_iter_document(&Desc, &len, &data); - - if (data) { - doc = bson_new_from_data(data, len); - value->SetValue_psz(Mini(g, colp, doc, false)); - bson_destroy(doc); - } else { - // ... but we can come here in case of NULL! - value->Reset(); - value->SetNull(true); - } // endif data + switch (bson_iter_type(&Desc)) { + case BSON_TYPE_UTF8: + value->SetValue_psz((PSZ)bson_iter_utf8(&Desc, NULL)); + break; + case BSON_TYPE_INT32: + value->SetValue(bson_iter_int32(&Desc)); + break; + case BSON_TYPE_INT64: + value->SetValue(bson_iter_int64(&Desc)); + break; + case BSON_TYPE_DOUBLE: + value->SetValue(bson_iter_double(&Desc)); + break; + case BSON_TYPE_DATE_TIME: + value->SetValue(bson_iter_date_time(&Desc) / 1000); + break; + case BSON_TYPE_BOOL: + b = bson_iter_bool(&Desc); - } else if (BSON_ITER_HOLDS_ARRAY(&Iter)) { - bson_t *arr; - const uint8_t *data = NULL; - uint32_t len = 0; + if (value->IsTypeNum()) + value->SetValue(b ? 1 : 0); + else + value->SetValue_psz(b ? "true" : "false"); - bson_iter_array(&Desc, &len, &data); + break; + case BSON_TYPE_OID: { + char str[25]; - if (data) { - arr = bson_new_from_data(data, len); - value->SetValue_psz(Mini(g, colp, arr, true)); - bson_destroy(arr); - } else { - // This is a bug in returning the wrong type - // This fix is only for document items - bson_t *doc; + bson_oid_to_string(bson_iter_oid(&Desc), str); + value->SetValue_psz(str); + } break; + case BSON_TYPE_ARRAY: + b = true; + // passthru + case BSON_TYPE_DOCUMENT: + { // All this because MongoDB can return the wrong type + int i = 0; + const uint8_t *data = NULL; + uint32_t len = 0; - bson_iter_document(&Desc, &len, &data); + for (; i < 2; i++) { + if (b) // Try array first + bson_iter_array(&Desc, &len, &data); + else + bson_iter_document(&Desc, &len, &data); + + if (!data) { + len = 0; + b = !b; + } else + break; + + } // endfor i if (data) { - doc = bson_new_from_data(data, len); - value->SetValue_psz(Mini(g, colp, doc, false)); + bson_t *doc = bson_new_from_data(data, len); + + value->SetValue_psz(Mini(g, colp, doc, b)); bson_destroy(doc); } else { // ... or we can also come here in case of NULL! value->Reset(); value->SetNull(true); - } // endif data + } // endif data - } // endif data + } break; + case BSON_TYPE_NULL: + // Apparently this does not work... + value->Reset(); + value->SetNull(true); + break; + case BSON_TYPE_DECIMAL128: { + char str[BSON_DECIMAL128_STRING]; + bson_decimal128_t dec; - } else - value->Reset(); + bson_iter_decimal128(&Desc, &dec); + bson_decimal128_to_string(&dec, str); + value->SetValue_psz(str); +// bson_free(str); + } break; + default: + value->Reset(); + break; + } // endswitch Desc } else { // Field does not exist @@ -868,14 +1007,35 @@ bool CMgoConn::AddValue(PGLOBAL g, PCOL colp, bson_t *doc, char *key, bool upd) PVAL value = colp->GetValue(); if (value->IsNull()) { - if (upd) +// if (upd) rc = BSON_APPEND_NULL(doc, key); - else - return false; +// else +// return false; } else switch (colp->GetResultType()) { case TYPE_STRING: - rc = BSON_APPEND_UTF8(doc, key, value->GetCharValue()); + if (colp->Stringify()) { + const uint8_t *val = (const uint8_t*)value->GetCharValue(); + bson_t *bsn = bson_new_from_json(val, -1, &Error); + + if (!bsn) { + sprintf (g->Message, "AddValue: %s", Error.message); + return true; + } else if (*key) { + if (*val == '[') + rc = BSON_APPEND_ARRAY(doc, key, bsn); + else + rc = BSON_APPEND_DOCUMENT(doc, key, bsn); + + } else { + bson_copy_to (bsn, doc); + rc = true; + } // endif's + + bson_free(bsn); + } else + rc = BSON_APPEND_UTF8(doc, key, value->GetCharValue()); + break; case TYPE_INT: case TYPE_SHORT: diff --git a/storage/connect/cmgoconn.h b/storage/connect/cmgoconn.h index b1216ac576c..f37a96cb7b9 100644 --- a/storage/connect/cmgoconn.h +++ b/storage/connect/cmgoconn.h @@ -28,11 +28,8 @@ typedef struct mongo_parms { PCSZ Coll_name; PCSZ Options; PCSZ Filter; + PCSZ Line; bool Pipe; -//PCSZ User; // User connect info -//PCSZ Pwd; // Password connect info -//int Fsize; // Fetch size -//bool Scrollable; // Scrollable cursor } CMGOPARM, *PCPARM; typedef struct KEYCOL { @@ -40,15 +37,24 @@ typedef struct KEYCOL { PINCOL Incolp; PCOL Colp; char *Key; + bool Array; } *PKC; +typedef struct _path_list *PTHP; + +typedef struct _path_list { + PSZ Path; + PSZ Name; + PTHP Next; +} PTH; + /***********************************************************************/ /* Used when inserting values in a MongoDB collection. */ /***********************************************************************/ class INCOL : public BLOCK { public: // Constructor - INCOL(bool ar) { Child = bson_new(); Klist = NULL; Array = ar; } + INCOL(void) { Child = bson_new(); Klist = NULL; } // Methods void AddCol(PGLOBAL g, PCOL colp, char *jp); @@ -58,7 +64,6 @@ public: //Members bson_t *Child; PKC Klist; - bool Array; }; // end of INCOL; /***********************************************************************/ @@ -80,6 +85,7 @@ public: bool IsConnected(void) { return m_Connected; } bool Connect(PGLOBAL g); int CollSize(PGLOBAL g); + void CMgoConn::Project(PGLOBAL g, PSTRG s); bool MakeCursor(PGLOBAL g); int ReadNext(PGLOBAL g); PSZ GetDocument(PGLOBAL g); @@ -99,7 +105,7 @@ protected: // Members PCPARM Pcg; mongoc_uri_t *Uri; - mongoc_client_pool_t *Pool; // Thread safe client pool +//mongoc_client_pool_t *Pool; // Thread safe client pool mongoc_client_t *Client; // The MongoDB client mongoc_database_t *Database; // The MongoDB database mongoc_collection_t *Collection; // The MongoDB collection @@ -108,8 +114,6 @@ protected: bson_t *Query; // MongoDB cursor filter bson_t *Opts; // MongoDB cursor options bson_error_t Error; - bson_iter_t Iter; // Used to retrieve column value - bson_iter_t Desc; // Descendant iter PINCOL Fpc; // To insert INCOL classes PFBLOCK fp; bool m_Connected; diff --git a/storage/connect/colblk.cpp b/storage/connect/colblk.cpp index 44383d584a8..d531685950d 100644 --- a/storage/connect/colblk.cpp +++ b/storage/connect/colblk.cpp @@ -297,9 +297,9 @@ FIDBLK::FIDBLK(PCOLUMN cp, OPVAL op) : SPCBLK(cp), Op(op) Buf_Type = TYPE_STRING; *Format.Type = 'C'; Format.Length = Long; -#if defined(__WIN__) +#if defined(_WIN32) Format.Prec = 1; // Case insensitive -#endif // __WIN__ +#endif // _WIN32 Constant = (!To_Tdb->GetDef()->GetMultiple() && To_Tdb->GetAmType() != TYPE_AM_PLG && To_Tdb->GetAmType() != TYPE_AM_PLM); diff --git a/storage/connect/colblk.h b/storage/connect/colblk.h index 51ab32cfae2..7f1af8b8368 100644 --- a/storage/connect/colblk.h +++ b/storage/connect/colblk.h @@ -38,7 +38,8 @@ class DllExport COLBLK : public XOBJECT { virtual PTDB GetTo_Tdb(void) {return To_Tdb;} virtual int GetClustered(void) {return 0;} virtual int IsClustered(void) {return FALSE;} - virtual PSZ GetJpath(PGLOBAL g, bool proj) {return NULL;} + virtual bool Stringify(void) {return FALSE;} + virtual PSZ GetJpath(PGLOBAL g, bool proj) {return NULL;} PCOL GetNext(void) {return Next;} PSZ GetName(void) {return Name;} int GetIndex(void) {return Index;} diff --git a/storage/connect/domdoc.cpp b/storage/connect/domdoc.cpp index 4502530cf82..482f0b347d2 100644 --- a/storage/connect/domdoc.cpp +++ b/storage/connect/domdoc.cpp @@ -4,7 +4,7 @@ /******************************************************************/ #include "my_global.h" #include <stdio.h> -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> #if defined(MSX2) #import "msxml2.dll" //Does not exist on Vista diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp index f50290119ae..4930e3944af 100644 --- a/storage/connect/filamap.cpp +++ b/storage/connect/filamap.cpp @@ -17,12 +17,12 @@ /* Include relevant sections of the System header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #if defined(__BORLANDC__) #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <errno.h> #include <unistd.h> @@ -30,7 +30,7 @@ #include <io.h> #endif // !UNIX #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ @@ -197,11 +197,11 @@ bool MAPFAM::OpenTableFile(PGLOBAL g) return true; } // endif Memory -#if defined(__WIN__) +#if defined(_WIN32) if (mode != MODE_DELETE) { -#else // !__WIN__ +#else // !_WIN32 if (mode == MODE_READ) { -#endif // !__WIN__ +#endif // !_WIN32 CloseFileHandle(hFile); // Not used anymore hFile = INVALID_HANDLE_VALUE; // For Fblock } // endif Mode @@ -469,7 +469,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) /*****************************************************************/ n = (int)(Tpos - Memory); -#if defined(__WIN__) +#if defined(_WIN32) DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN); if (drc == 0xFFFFFFFF) { @@ -499,7 +499,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) #endif // UNIX } // endif Abort -#if defined(__WIN__) +#if defined(_WIN32) CloseHandle(fp->Handle); #else // UNIX close(fp->Handle); diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp index c8571cea559..3d1718b9983 100644 --- a/storage/connect/filamdbf.cpp +++ b/storage/connect/filamdbf.cpp @@ -22,12 +22,12 @@ /* Include relevant sections of the System header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> //#include <errno.h> //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <errno.h> #include <unistd.h> @@ -35,7 +35,7 @@ //#include <io.h> #endif // !UNIX //#include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 #include <ctype.h> #include <stdio.h> #include <string.h> @@ -649,7 +649,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen); if (mode == MODE_INSERT) { -#if defined(__WIN__) +#if defined(_WIN32) /************************************************************************/ /* Now we can revert to binary mode in particular because the eventual */ /* writing of a new header must be done in binary mode to avoid */ @@ -659,7 +659,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) sprintf(g->Message, MSG(BIN_MODE_FAIL), strerror(errno)); return true; } // endif setmode -#endif // __WIN__ +#endif // _WIN32 /************************************************************************/ /* If this is a new file, the header must be generated. */ diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp index d27551bb97d..46f3ea01129 100644 --- a/storage/connect/filamfix.cpp +++ b/storage/connect/filamfix.cpp @@ -17,7 +17,7 @@ /* Include relevant sections of the System header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #include <errno.h> @@ -25,7 +25,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <errno.h> #include <unistd.h> @@ -34,7 +34,7 @@ #endif // !UNIX #include <sys/stat.h> #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ @@ -336,7 +336,7 @@ int FIXFAM::ReadBuffer(PGLOBAL g) } else if (feof(Stream)) { rc = RC_EF; } else { -#if defined(__WIN__) +#if defined(_WIN32) sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL)); #else sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno)); @@ -676,7 +676,7 @@ BGXFAM::BGXFAM(PBGXFAM txfp) : FIXFAM(txfp) /***********************************************************************/ bool BGXFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, int org) { -#if defined(__WIN__) +#if defined(_WIN32) char buf[256]; DWORD drc; LARGE_INTEGER of; @@ -692,14 +692,14 @@ bool BGXFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, int org) sprintf(g->Message, MSG(SFP_ERROR), buf); return true; } // endif -#else // !__WIN__ +#else // !_WIN32 if (lseek64(h, pos, org) < 0) { // sprintf(g->Message, MSG(ERROR_IN_LSK), errno); sprintf(g->Message, "lseek64: %s", strerror(errno)); printf("%s\n", g->Message); return true; } // endif -#endif // !__WIN__ +#endif // !_WIN32 return false; } // end of BigSeek @@ -712,7 +712,7 @@ int BGXFAM::BigRead(PGLOBAL g __attribute__((unused)), { int rc; -#if defined(__WIN__) +#if defined(_WIN32) DWORD nbr, drc, len = (DWORD)req; bool brc = ReadFile(h, inbuf, len, &nbr, NULL); @@ -734,12 +734,12 @@ int BGXFAM::BigRead(PGLOBAL g __attribute__((unused)), rc = -1; } else rc = (int)nbr; -#else // !__WIN__ +#else // !_WIN32 size_t len = (size_t)req; ssize_t nbr = read(h, inbuf, len); rc = (int)nbr; -#endif // !__WIN__ +#endif // !_WIN32 return rc; } // end of BigRead @@ -751,7 +751,7 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req) { bool rc = false; -#if defined(__WIN__) +#if defined(_WIN32) DWORD nbw, drc, len = (DWORD)req; bool brc = WriteFile(h, inbuf, len, &nbw, NULL); @@ -779,7 +779,7 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req) rc = true; } // endif brc || nbw -#else // !__WIN__ +#else // !_WIN32 size_t len = (size_t)req; ssize_t nbw = write(h, inbuf, len); @@ -794,7 +794,7 @@ bool BGXFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req) rc = true; } // endif nbr -#endif // !__WIN__ +#endif // !_WIN32 return rc; } // end of BigWrite @@ -829,7 +829,7 @@ bool BGXFAM::OpenTableFile(PGLOBAL g) if (trace(1)) htrc("OpenTableFile: filename=%s mode=%d\n", filename, mode); -#if defined(__WIN__) +#if defined(_WIN32) DWORD rc, access, creation, share = 0; /*********************************************************************/ @@ -987,7 +987,7 @@ int BGXFAM::Cardinality(PGLOBAL g) PlugSetPath(filename, To_File, Tdbp->GetPath()); -#if defined(__WIN__) // OB +#if defined(_WIN32) // OB LARGE_INTEGER len; DWORD rc = 0; @@ -1346,7 +1346,7 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc) /*****************************************************************/ /* Remove extra records. */ /*****************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) if (BigSeek(g, Hfile, (BIGINT)Tpos * (BIGINT)Lrecl)) return RC_FX; @@ -1356,12 +1356,12 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc) sprintf(g->Message, MSG(SETEOF_ERROR), drc); return RC_FX; } // endif error -#else // !__WIN__ +#else // !_WIN32 if (ftruncate64(Hfile, (BIGINT)(Tpos * Lrecl))) { sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno)); return RC_FX; } // endif -#endif // !__WIN__ +#endif // !_WIN32 } // endif UseTemp @@ -1386,7 +1386,7 @@ bool BGXFAM::OpenTempFile(PGLOBAL g) strcat(PlugRemoveType(tempname, tempname), ".t"); remove(tempname); // Be sure it does not exist yet -#if defined(__WIN__) +#if defined(_WIN32) Tfile = CreateFile(tempname, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); @@ -1526,7 +1526,7 @@ void BGXFAM::CloseTableFile(PGLOBAL g, bool abort) void BGXFAM::Rewind(void) { #if 0 // This is probably unuseful because file is accessed directly -#if defined(__WIN__) //OB +#if defined(_WIN32) //OB SetFilePointer(Hfile, 0, NULL, FILE_BEGIN); #else // UNIX lseek64(Hfile, 0, SEEK_SET); diff --git a/storage/connect/filamgz.cpp b/storage/connect/filamgz.cpp index d694eab3845..634599eced3 100644 --- a/storage/connect/filamgz.cpp +++ b/storage/connect/filamgz.cpp @@ -17,21 +17,21 @@ /* Include relevant MariaDB header file. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #if defined(__BORLANDC__) #define __MFC_COMPAT__ // To define min/max as macro #endif //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <errno.h> #else // !UNIX #include <io.h> #endif #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ @@ -89,11 +89,11 @@ int GZFAM::Zerror(PGLOBAL g) strcpy(g->Message, gzerror(Zfile, &errnum)); if (errnum == Z_ERRNO) -#if defined(__WIN__) +#if defined(_WIN32) sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(NULL)); -#else // !__WIN__ +#else // !_WIN32 sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno)); -#endif // !__WIN__ +#endif // !_WIN32 return (errnum == Z_STREAM_END) ? RC_EF : RC_FX; } // end of Zerror @@ -764,9 +764,9 @@ bool GZXFAM::AllocateBuffer(PGLOBAL g) if (Tdbp->GetFtype() < 2) // if not binary, the file is physically a text file for (int len = Lrecl; len <= Buflen; len += Lrecl) { -#if defined(__WIN__) +#if defined(_WIN32) To_Buf[len - 2] = '\r'; -#endif // __WIN__ +#endif // _WIN32 To_Buf[len - 1] = '\n'; } // endfor len diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp index 84eab272cc5..393ca360df9 100644 --- a/storage/connect/filamtxt.cpp +++ b/storage/connect/filamtxt.cpp @@ -17,7 +17,7 @@ /* Include relevant sections of the System header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #include <errno.h> @@ -25,7 +25,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) || defined(UNIV_LINUX) #include <errno.h> #include <unistd.h> @@ -36,7 +36,7 @@ #include <io.h> #endif // !UNIX #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ @@ -82,7 +82,7 @@ TXTFAM::TXTFAM(PDOSDEF tdp) To_File = NULL; Lrecl = 0; Eof = false; -#if defined(__WIN__) +#if defined(_WIN32) Ending = 2; #else Ending = 1; @@ -731,7 +731,7 @@ int DOSFAM::SkipRecord(PGLOBAL g, bool header) if (feof(Stream)) return RC_EF; -#if defined(__WIN__) +#if defined(_WIN32) sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL)); #else sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(0)); @@ -814,7 +814,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g) if (trace(2)) htrc(" Read: To_Buf=%p p=%c\n", To_Buf, p); -#if defined(__WIN__) +#if defined(_WIN32) if (Bin) { // Data file is read in binary so CRLF remains #else @@ -848,7 +848,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g) } else if (feof(Stream)) { rc = RC_EF; } else { -#if defined(__WIN__) +#if defined(_WIN32) sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL)); #else sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(0)); @@ -1043,7 +1043,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc) /*****************************************************************/ /* Remove extra records. */ /*****************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) if (chsize(h, Tpos)) { sprintf(g->Message, MSG(CHSIZE_ERROR), strerror(errno)); close(h); @@ -1482,7 +1482,7 @@ int BLKFAM::ReadBuffer(PGLOBAL g) } else if (feof(Stream)) { rc = RC_EF; } else { -#if defined(__WIN__) +#if defined(_WIN32) sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL)); #else sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno)); @@ -1568,11 +1568,11 @@ int BLKFAM::WriteBuffer(PGLOBAL g) Spos = GetNextPos(); // New start position // Prepare the output buffer -#if defined(__WIN__) +#if defined(_WIN32) crlf = "\r\n"; #else crlf = "\n"; -#endif // __WIN__ +#endif // _WIN32 strcat(strcpy(OutBuf, Tdbp->GetLine()), crlf); len = strlen(OutBuf); } else { @@ -1872,7 +1872,7 @@ int BINFAM::ReadBuffer(PGLOBAL g) } else if (feof(Stream)) { rc = RC_EF; } else { -#if defined(__WIN__) +#if defined(_WIN32) sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL)); #else sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(0)); @@ -2066,7 +2066,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc) /*****************************************************************/ /* Remove extra records. */ /*****************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) if (chsize(h, Tpos)) { sprintf(g->Message, MSG(CHSIZE_ERROR), strerror(errno)); close(h); diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp index d2add16b31d..2cd80f5d43f 100644 --- a/storage/connect/filamvct.cpp +++ b/storage/connect/filamvct.cpp @@ -21,7 +21,7 @@ /* Include relevant MariaDB header file. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #if defined(__BORLANDC__) @@ -29,7 +29,7 @@ #endif // __BORLAND__ //#include <windows.h> #include <sys/stat.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <sys/types.h> #include <sys/stat.h> @@ -40,7 +40,7 @@ #include <io.h> #endif // !UNIX #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ @@ -372,11 +372,11 @@ bool VCTFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn) int h, n; PlugSetPath(filename, fn, Tdbp->GetPath()); -#if defined(__WIN__) +#if defined(_WIN32) h= global_open(g, MSGID_OPEN_EMPTY_FILE, filename, _O_CREAT | _O_WRONLY, S_IREAD | S_IWRITE); -#else // !__WIN__ +#else // !_WIN32 h= global_open(g, MSGID_OPEN_EMPTY_FILE, filename, O_CREAT | O_WRONLY, S_IREAD | S_IWRITE); -#endif // !__WIN__ +#endif // !_WIN32 if (h == -1) return true; @@ -1672,7 +1672,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc) // Remove extra blocks n = Block * Blksize; -#if defined(__WIN__) +#if defined(_WIN32) DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN); if (drc == 0xFFFFFFFF) { @@ -2579,11 +2579,11 @@ bool VECFAM::ReadBlock(PGLOBAL g, PVCTCOL colp) char fn[_MAX_PATH]; sprintf(fn, Colfn, colp->Index); -#if defined(__WIN__) +#if defined(_WIN32) if (feof(Streams[i])) -#else // !__WIN__ +#else // !_WIN32 if (errno == NO_ERROR) -#endif // !__WIN__ +#endif // !_WIN32 sprintf(g->Message, MSG(BAD_READ_NUMBER), (int) n, fn); else sprintf(g->Message, MSG(READ_ERROR), @@ -2979,7 +2979,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc) /*****************************************************************/ n = Tpos * Clens[i]; -#if defined(__WIN__) +#if defined(_WIN32) DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN); if (drc == 0xFFFFFFFF) { @@ -3059,7 +3059,7 @@ BGVFAM::BGVFAM(PBGVFAM txfp) : VCTFAM(txfp) /***********************************************************************/ bool BGVFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, bool b) { -#if defined(__WIN__) +#if defined(_WIN32) char buf[256]; DWORD drc, m = (b) ? FILE_END : FILE_BEGIN; LARGE_INTEGER of; @@ -3075,12 +3075,12 @@ bool BGVFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, bool b) sprintf(g->Message, MSG(SFP_ERROR), buf); return true; } // endif -#else // !__WIN__ +#else // !_WIN32 if (lseek64(h, pos, (b) ? SEEK_END : SEEK_SET) < 0) { sprintf(g->Message, MSG(ERROR_IN_LSK), errno); return true; } // endif -#endif // !__WIN__ +#endif // !_WIN32 return false; } // end of BigSeek @@ -3092,7 +3092,7 @@ bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req) { bool rc = false; -#if defined(__WIN__) +#if defined(_WIN32) DWORD nbr, drc, len = (DWORD)req; bool brc = ReadFile(h, inbuf, len, &nbr, NULL); @@ -3118,7 +3118,7 @@ bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req) rc = true; } // endif brc || nbr -#else // !__WIN__ +#else // !_WIN32 size_t len = (size_t)req; ssize_t nbr = read(h, inbuf, len); @@ -3133,7 +3133,7 @@ bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req) rc = true; } // endif nbr -#endif // !__WIN__ +#endif // !_WIN32 return rc; } // end of BigRead @@ -3145,7 +3145,7 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req) { bool rc = false; -#if defined(__WIN__) +#if defined(_WIN32) DWORD nbw, drc, len = (DWORD)req; bool brc = WriteFile(h, inbuf, len, &nbw, NULL); @@ -3173,7 +3173,7 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req) rc = true; } // endif brc || nbw -#else // !__WIN__ +#else // !_WIN32 size_t len = (size_t)req; ssize_t nbw = write(h, inbuf, len); @@ -3188,7 +3188,7 @@ bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req) rc = true; } // endif nbr -#endif // !__WIN__ +#endif // !_WIN32 return rc; } // end of BigWrite @@ -3214,7 +3214,7 @@ int BGVFAM::GetBlockInfo(PGLOBAL g) if (Header == 2) strcat(PlugRemoveType(filename, filename), ".blk"); -#if defined(__WIN__) +#if defined(_WIN32) LARGE_INTEGER len; h = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, @@ -3226,11 +3226,11 @@ int BGVFAM::GetBlockInfo(PGLOBAL g) } // endif h if (h == INVALID_HANDLE_VALUE || !len.QuadPart) { -#else // !__WIN__ +#else // !_WIN32 h = open64(filename, O_RDONLY, 0); if (h == INVALID_HANDLE_VALUE || !_filelength(h)) { -#endif // !__WIN__ +#endif // !_WIN32 // Consider this is a void table if (trace(1)) htrc("Void table h=%d\n", h); @@ -3291,17 +3291,17 @@ bool BGVFAM::SetBlockInfo(PGLOBAL g) strcat(PlugRemoveType(filename, filename), ".blk"); if (h == INVALID_HANDLE_VALUE) { -#if defined(__WIN__) +#if defined(_WIN32) DWORD creation = (b) ? OPEN_EXISTING : TRUNCATE_EXISTING; h = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL); -#else // !__WIN__ +#else // !_WIN32 int oflag = (b) ? O_RDWR : O_RDWR | O_TRUNC; h = open64(filename, oflag, 0); -#endif // !__WIN__ +#endif // !_WIN32 if (h == INVALID_HANDLE_VALUE) { sprintf(g->Message, "Error opening header file %s", filename); @@ -3339,7 +3339,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn) PlugSetPath(filename, fn, Tdbp->GetPath()); -#if defined(__WIN__) +#if defined(_WIN32) PCSZ p; DWORD rc; bool brc; @@ -3391,7 +3391,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn) CloseHandle(h); return true; -#else // !__WIN__ +#else // !_WIN32 int h; BIGINT pos; @@ -3420,7 +3420,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn) sprintf(g->Message, MSG(MAKE_EMPTY_FILE), To_File, strerror(errno)); close(h); return true; -#endif // !__WIN__ +#endif // !_WIN32 } // end of MakeEmptyFile /***********************************************************************/ @@ -3451,7 +3451,7 @@ bool BGVFAM::OpenTableFile(PGLOBAL g) htrc("OpenTableFile: filename=%s mode=%d Last=%d\n", filename, mode, Last); -#if defined(__WIN__) +#if defined(_WIN32) DWORD access, creation, share = 0, rc = 0; /*********************************************************************/ @@ -3779,7 +3779,7 @@ int BGVFAM::WriteBuffer(PGLOBAL g) if (!Closing && !MaxBlk) { // Close the VCT file and reopen it in mode Insert -//#if defined(__WIN__) //OB +//#if defined(_WIN32) //OB // CloseHandle(Hfile); //#else // UNIX // close(Hfile); @@ -3906,7 +3906,7 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc) /***************************************************************/ /* Remove extra records. */ /***************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) BIGINT pos = (BIGINT)Block * (BIGINT)Blksize; if (BigSeek(g, Hfile, pos)) @@ -3918,12 +3918,12 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc) sprintf(g->Message, MSG(SETEOF_ERROR), drc); return RC_FX; } // endif error -#else // !__WIN__ +#else // !_WIN32 if (ftruncate64(Hfile, (BIGINT)(Tpos * Lrecl))) { sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno)); return RC_FX; } // endif -#endif // !__WIN__ +#endif // !_WIN32 } else // MaxBlk // Clean the unused space in the file, this is required when // inserting again with a partial column list. @@ -3960,7 +3960,7 @@ bool BGVFAM::OpenTempFile(PGLOBAL g) else if (MakeEmptyFile(g, tempname)) return true; -#if defined(__WIN__) +#if defined(_WIN32) DWORD access = (MaxBlk) ? OPEN_EXISTING : CREATE_NEW; Tfile = CreateFile(tempname, GENERIC_WRITE, 0, NULL, @@ -4232,7 +4232,7 @@ void BGVFAM::Rewind(void) CurNum = Nrec - 1; #if 0 // This is probably unuseful as the file is directly accessed -#if defined(__WIN__) //OB +#if defined(_WIN32) //OB SetFilePointer(Hfile, 0, NULL, FILE_BEGIN); #else // UNIX lseek64(Hfile, 0, SEEK_SET); diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp index 8de536273b4..77a97b95107 100644 --- a/storage/connect/filamzip.cpp +++ b/storage/connect/filamzip.cpp @@ -17,7 +17,7 @@ /* Include relevant sections of the System header files. */ /***********************************************************************/ #include "my_global.h" -#if !defined(__WIN__) +#if !defined(_WIN32) #if defined(UNIX) #include <fnmatch.h> #include <errno.h> @@ -27,7 +27,7 @@ #include <io.h> #endif // !UNIX #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 #include <time.h> /***********************************************************************/ @@ -153,7 +153,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf) /*********************************************************************/ strcpy(filename, pat); -#if defined(__WIN__) +#if defined(_WIN32) int rc; char drive[_MAX_DRIVE], direc[_MAX_DIR]; WIN32_FIND_DATA FileData; @@ -210,7 +210,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf) return true; } // endif FindClose -#else // !__WIN__ +#else // !_WIN32 struct stat fileinfo; char fn[FN_REFLEN], direc[FN_REFLEN], pattern[FN_HEADLEN], ftype[FN_EXTLEN]; DIR *dir; @@ -251,7 +251,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf) // Close the dir handle. closedir(dir); -#endif // !__WIN__ +#endif // !_WIN32 return false; } // end of ZipFiles @@ -275,9 +275,9 @@ bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul if (!entry) { // entry defaults to the file name char* p = strrchr((char*)fn, '/'); -#if defined(__WIN__) +#if defined(_WIN32) if (!p) p = strrchr((char*)fn, '\\'); -#endif // __WIN__ +#endif // _WIN32 entp = (p) ? p + 1 : entry; } else entp = entry; @@ -467,7 +467,7 @@ UNZIPUTL::UNZIPUTL(PCSZ tgt, PCSZ pw, bool mul) memset(fn, 0, sizeof(fn)); // Init the case mapping table. -#if defined(__WIN__) +#if defined(_WIN32) for (int i = 0; i < 256; ++i) mapCaseTable[i] = toupper(i); #else for (int i = 0; i < 256; ++i) mapCaseTable[i] = i; @@ -487,7 +487,7 @@ UNZIPUTL::UNZIPUTL(PDOSDEF tdp) memset(fn, 0, sizeof(fn)); // Init the case mapping table. -#if defined(__WIN__) +#if defined(_WIN32) for (int i = 0; i < 256; ++i) mapCaseTable[i] = toupper(i); #else for (int i = 0; i < 256; ++i) mapCaseTable[i] = i; diff --git a/storage/connect/filter.cpp b/storage/connect/filter.cpp index 5dea66fff0d..9d8518ec3a5 100644 --- a/storage/connect/filter.cpp +++ b/storage/connect/filter.cpp @@ -13,13 +13,13 @@ //#include "sql_class.h" //#include "sql_time.h" -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #include <string.h> #include <sys/types.h> #include <sys/stat.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ diff --git a/storage/connect/filter.h b/storage/connect/filter.h index c6ab8fddd35..12ac3a169c1 100644 --- a/storage/connect/filter.h +++ b/storage/connect/filter.h @@ -106,7 +106,7 @@ class FILTERX : public FILTER { // Fake operator new used to change a filter into a derived filter void * operator new(size_t, PFIL filp) {return filp;} -#if defined(__WIN__) +#if defined(_WIN32) // Avoid warning C4291 by defining a matching dummy delete operator void operator delete(void *, PFIL) {} #else diff --git a/storage/connect/fmdlex.c b/storage/connect/fmdlex.c index 28b71b95e4d..1bca2d4ec18 100644 --- a/storage/connect/fmdlex.c +++ b/storage/connect/fmdlex.c @@ -22,12 +22,12 @@ */ #define FLEX_SCANNER -#ifdef __WIN__ +#ifdef _WIN32 #define __STDC__ 1 #define isatty _isatty #endif #include <stdio.h> -#ifndef __WIN__ +#ifndef _WIN32 #include <unistd.h> #endif diff --git a/storage/connect/global.h b/storage/connect/global.h index 8774285e54b..eb3d4106477 100644 --- a/storage/connect/global.h +++ b/storage/connect/global.h @@ -14,11 +14,11 @@ #include <time.h> /* time_t type declaration */ #include <setjmp.h> /* Long jump declarations */ -#if defined(__WIN__) && !defined(NOEX) +#if defined(_WIN32) && !defined(NOEX) #define DllExport __declspec( dllexport ) -#else // !__WIN__ +#else // !_WIN32 #define DllExport -#endif // !__WIN__ +#endif // !_WIN32 #if defined(DOMDOC_SUPPORT) || defined(LIBXML2_SUPPORT) #define XML_SUPPORT 1 @@ -43,11 +43,11 @@ #define STEP(I) MSG_##I #endif // !XMSG and !NEWMSG -#if defined(__WIN__) +#if defined(_WIN32) #define CRLF 2 -#else // !__WIN__ +#else // !_WIN32 #define CRLF 1 -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Define access to the thread based trace value. */ @@ -204,9 +204,9 @@ DllExport char *PlugReadMessage(PGLOBAL, int, char *); #elif defined(NEWMSG) DllExport char *PlugGetMessage(PGLOBAL, int); #endif // XMSG || NEWMSG -#if defined(__WIN__) +#if defined(_WIN32) DllExport short GetLineLength(PGLOBAL); // Console line length -#endif // __WIN__ +#endif // _WIN32 DllExport PGLOBAL PlugInit(LPCSTR, size_t); // Plug global initialization DllExport PGLOBAL PlugExit(PGLOBAL); // Plug global termination DllExport LPSTR PlugRemoveType(LPSTR, LPCSTR); diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 85781925e31..e95e91e1ca6 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -139,10 +139,10 @@ //#include "reldef.h" #include "tabcol.h" #include "xindex.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include "tabwmi.h" -#endif // __WIN__ +#endif // _WIN32 #include "connect.h" #include "user_connect.h" #include "ha_connect.h" @@ -167,16 +167,16 @@ #define SZCONV 1024 // Default converted text size #define SZWORK 67108864 // Default work area size 64M #define SZWMIN 4194304 // Minimum work area size 4M -#define JSONMAX 10 // JSON Default max grp size +#define JSONMAX 50 // JSON Default max grp size extern "C" { char version[]= "Version 1.07.0002 March 22, 2021"; -#if defined(__WIN__) +#if defined(_WIN32) char compver[]= "Version 1.07.0002 " __DATE__ " " __TIME__; static char slash= '\\'; -#else // !__WIN__ +#else // !_WIN32 static char slash= '/'; -#endif // !__WIN__ +#endif // !_WIN32 } // extern "C" #if MYSQL_VERSION_ID > 100200 @@ -288,15 +288,14 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, /****************************************************************************/ static char *strz(PGLOBAL g, LEX_CSTRING &ls) { - char *str= (char*)PlugSubAlloc(g, NULL, ls.length + 1); - - /* - ls.str can be NULL, for example when called with - create_info->connect_string - */ - if (ls.str) + char* str= NULL; + + if (ls.str) { + str= (char*)PlugSubAlloc(g, NULL, ls.length + 1); memcpy(str, ls.str, ls.length); - str[ls.length]= 0; + str[ls.length] = 0; + } // endif str + return str; } // end of strz @@ -511,7 +510,7 @@ char *GetJsonNull(void) int GetDefaultDepth(void) {return THDVAR(current_thd, default_depth);} int GetDefaultPrec(void) {return THDVAR(current_thd, default_prec);} uint GetJsonGrpSize(void) - {return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;} + {return connect_hton ? THDVAR(current_thd, json_grp_size) : 50;} size_t GetWorkSize(void) {return (size_t)THDVAR(current_thd, work_size);} void SetWorkSize(size_t) { @@ -805,11 +804,11 @@ static int connect_init_func(void *p) } #endif // 0 (LINUX) -#if defined(__WIN__) +#if defined(_WIN32) sql_print_information("CONNECT: %s", compver); -#else // !__WIN__ +#else // !_WIN32 sql_print_information("CONNECT: %s", version); -#endif // !__WIN__ +#endif // !_WIN32 pthread_mutex_init(&parmut, NULL); pthread_mutex_init(&usrmut, NULL); pthread_mutex_init(&tblmut, NULL); @@ -867,9 +866,9 @@ int connect_done_func(void *) JAVAConn::ResetJVM(); #endif // JAVA_SUPPORT -#if !defined(__WIN__) +#if !defined(_WIN32) PROFILE_End(); -#endif // !__WIN__ +#endif // !_WIN32 pthread_mutex_lock(&usrmut); for (pc= user_connect::to_users; pc; pc= pn) { @@ -943,11 +942,11 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg) xp= (table) ? GetUser(ha_thd(), NULL) : NULL; if (xp) xp->SetHandler(this); -#if defined(__WIN__) +#if defined(_WIN32) datapath= ".\\"; -#else // !__WIN__ +#else // !_WIN32 datapath= "./"; -#endif // !__WIN__ +#endif // !_WIN32 tdbp= NULL; sdvalin1= sdvalin2= sdvalin3= sdvalin4= NULL; sdvalout= NULL; @@ -4550,11 +4549,11 @@ static bool checkPrivileges(THD *thd, TABTYPE type, PTOS options, strcpy(dbpath, mysql_real_data_home); if (db) -#if defined(__WIN__) +#if defined(_WIN32) strcat(strcat(dbpath, db), "\\"); -#else // !__WIN__ +#else // !_WIN32 strcat(strcat(dbpath, db), "/"); -#endif // !__WIN__ +#endif // !_WIN32 (void)fn_format(path, options->filename, dbpath, "", MY_RELATIVE_PATH | MY_UNPACK_FILENAME); @@ -5487,14 +5486,13 @@ static bool add_field(String* sql, TABTYPE ttp, const char* field_name, int typ, } // endif rem if (fmt && *fmt) { - switch (ttp) { - case TAB_JSON: error |= sql->append(" JPATH='"); break; -#if defined(BSON_SUPPORT) - case TAB_BSON: error |= sql->append(" JPATH='"); break; -#endif // BSON_SUPPORT - case TAB_XML: error |= sql->append(" XPATH='"); break; - default: error |= sql->append(" FIELD_FORMAT='"); - } // endswitch ttp + switch (ttp) { + case TAB_MONGO: + case TAB_BSON: + case TAB_JSON: error |= sql->append(" JPATH='"); break; + case TAB_XML: error |= sql->append(" XPATH='"); break; + default: error |= sql->append(" FIELD_FORMAT='"); + } // endswitch ttp error |= sql->append_for_single_quote(fmt, strlen(fmt)); error |= sql->append("'"); @@ -5625,9 +5623,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd, PCSZ user, fn, db, host, pwd, sep, tbl, src; PCSZ col, ocl, rnk, pic, fcl, skc, zfn; char *tab, *dsn, *shm, *dpath, *url; -#if defined(__WIN__) +#if defined(_WIN32) PCSZ nsp= NULL, cls= NULL; -#endif // __WIN__ +#endif // _WIN32 //int hdr, mxe; int port= 0, mxr __attribute__((unused)) = 0, rc= 0, mul= 0; //PCSZ tabtyp= NULL; @@ -5643,7 +5641,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, #endif // JAVA_SUPPORT uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL); bool bif, ok= false, dbf= false; - TABTYPE ttp= TAB_UNDEF; + TABTYPE ttp= TAB_UNDEF, ttr=TAB_UNDEF; PQRYRES qrp= NULL; PCOLRES crp; PCONNECT xp= NULL; @@ -5686,10 +5684,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd, skc= GetListOption(g, "skipcol", topt->oplist, NULL); rnk= GetListOption(g, "rankcol", topt->oplist, NULL); pwd= GetListOption(g, "password", topt->oplist); -#if defined(__WIN__) +#if defined(_WIN32) nsp= GetListOption(g, "namespace", topt->oplist); cls= GetListOption(g, "class", topt->oplist); -#endif // __WIN__ +#endif // _WIN32 port= atoi(GetListOption(g, "port", topt->oplist, "0")); #if defined(ODBC_SUPPORT) // tabtyp= GetListOption(g, "Tabtype", topt->oplist, NULL); @@ -5723,7 +5721,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS"; ttp= GetTypeID(topt->type); sprintf(g->Message, "No table_type. Was set to %s", topt->type); - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); + push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message); } else if (ttp == TAB_NIY) { sprintf(g->Message, "Unsupported table type %s", topt->type); rc= HA_ERR_INTERNAL_ERROR; @@ -5731,13 +5729,13 @@ static int connect_assisted_discovery(handlerton *, THD* thd, #if defined(REST_SUPPORT) } else if (topt->http) { if (ttp == TAB_UNDEF) { - topt->type = "JSON"; - ttp= GetTypeID(topt->type); - sprintf(g->Message, "No table_type. Was set to %s", topt->type); - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); - } // endif ttp + ttr= TAB_JSON; + strcpy(g->Message, "No table_type. Was set to JSON"); + push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message); + } else + ttr= ttp; - switch (ttp) { + switch (ttr) { case TAB_JSON: #if defined(BSON_SUPPORT) case TAB_BSON: @@ -5920,11 +5918,11 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ok= false; break; -#if defined(__WIN__) +#if defined(_WIN32) case TAB_WMI: ok= true; break; -#endif // __WIN__ +#endif // _WIN32 case TAB_PIVOT: supfnc= FNC_NO; // fall through @@ -5957,9 +5955,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd, if (!fn && !zfn && !mul && !dsn) sprintf(g->Message, "Missing %s file name", topt->type); - else - ok= true; + else if (dsn && !topt->tabname) + topt->tabname= tab; + ok= true; break; #if defined(JAVA_SUPPORT) case TAB_MONGO: @@ -5972,7 +5971,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, #if defined(REST_SUPPORT) case TAB_REST: if (!topt->http) - sprintf(g->Message, "Missing %s HTTP address", topt->type); + strcpy(g->Message, "Missing REST HTTP option"); else ok = true; @@ -6088,11 +6087,11 @@ static int connect_assisted_discovery(handlerton *, THD* thd, case TAB_CSV: qrp= CSVColumns(g, dpath, topt, fnc == FNC_COL); break; -#if defined(__WIN__) +#if defined(_WIN32) case TAB_WMI: qrp= WMIColumns(g, nsp, cls, fnc == FNC_COL); break; -#endif // __WIN__ +#endif // _WIN32 case TAB_PRX: case TAB_TBL: case TAB_XCL: @@ -6192,7 +6191,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, // Restore language type if (ttp == TAB_REST) - ttp = GetTypeID(topt->type); + ttp = ttr; for (i= 0; !rc && i < qrp->Nblin; i++) { typ= len= prec= dec= flg= 0; @@ -6622,11 +6621,11 @@ int ha_connect::create(const char *name, TABLE *table_arg, // on Windows and libxml2 otherwise switch (toupper(*xsup)) { case '*': -#if defined(__WIN__) +#if defined(_WIN32) dom= true; -#else // !__WIN__ +#else // !_WIN32 dom= false; -#endif // !__WIN__ +#endif // !_WIN32 break; case 'M': case 'D': @@ -7009,11 +7008,11 @@ bool ha_connect::FileExists(const char *fn, bool bf) int n; struct stat info; -#if defined(__WIN__) +#if defined(_WIN32) s= "\\"; -#else // !__WIN__ +#else // !_WIN32 s= "/"; -#endif // !__WIN__ +#endif // !_WIN32 if (IsPartitioned()) { sprintf(tfn, fn, GetPartName()); @@ -7530,7 +7529,7 @@ maria_declare_plugin(connect) 0x0107, /* version number (1.07) */ NULL, /* status variables */ connect_system_variables, /* system variables */ - "1.07.0002", /* string version */ + "1.07.0003", /* string version */ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ } maria_declare_plugin_end; diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp index 03c9ecb9221..de37d5b6970 100644 --- a/storage/connect/javaconn.cpp +++ b/storage/connect/javaconn.cpp @@ -6,24 +6,24 @@ /* This file contains the JAVA connection classes functions. */ /***********************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) // This is needed for RegGetValue #define _WINVER 0x0601 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0601 -#endif // __WIN__ +#endif // _WIN32 /***********************************************************************/ /* Include relevant MariaDB header file. */ /***********************************************************************/ #include <my_global.h> //#include <m_string.h> -#if defined(__WIN__) +#if defined(_WIN32) #include <direct.h> // for getcwd #if defined(__BORLANDC__) #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <errno.h> #else // !UNIX @@ -31,7 +31,7 @@ #include <stdio.h> #include <stdlib.h> // for getenv #define NODW -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Required objects includes. */ @@ -47,9 +47,9 @@ #include "valblk.h" #include "osutil.h" -#if defined(__WIN__) +#if defined(_WIN32) extern "C" HINSTANCE s_hModule; // Saved module handle -#endif // __WIN__ +#endif // _WIN32 #define nullptr 0 //TYPCONV GetTypeConv(); @@ -57,6 +57,8 @@ extern "C" HINSTANCE s_hModule; // Saved module handle extern char *JvmPath; // The connect_jvm_path global variable value extern char *ClassPath; // The connect_class_path global variable value +char *GetPluginDir(void); +char *GetMessageDir(void); char *GetJavaWrapper(void); // The connect_java_wrapper variable value extern MYSQL_PLUGIN_IMPORT char lc_messages_dir[FN_REFLEN]; @@ -199,11 +201,11 @@ int JAVAConn::GetMaxValue(int n) void JAVAConn::ResetJVM(void) { if (LibJvm) { -#if defined(__WIN__) +#if defined(_WIN32) FreeLibrary((HMODULE)LibJvm); -#else // !__WIN__ +#else // !_WIN32 dlclose(LibJvm); -#endif // !__WIN__ +#endif // !_WIN32 LibJvm = NULL; CreateJavaVM = NULL; GetCreatedJavaVMs = NULL; @@ -226,7 +228,7 @@ bool JAVAConn::GetJVM(PGLOBAL g) if (!LibJvm) { char soname[512]; -#if defined(__WIN__) +#if defined(_WIN32) for (ntry = 0; !LibJvm && ntry < 3; ntry++) { if (!ntry && JvmPath) { strcat(strcpy(soname, JvmPath), "\\jvm.dll"); @@ -294,7 +296,7 @@ bool JAVAConn::GetJVM(PGLOBAL g) LibJvm = NULL; #endif // _DEBUG } // endif LibJvm -#else // !__WIN__ +#else // !_WIN32 const char *error = NULL; for (ntry = 0; !LibJvm && ntry < 2; ntry++) { @@ -335,7 +337,7 @@ bool JAVAConn::GetJVM(PGLOBAL g) LibJvm = NULL; #endif // _DEBUG } // endif LibJvm -#endif // !__WIN__ +#endif // !_WIN32 } // endif LibJvm @@ -377,7 +379,7 @@ bool JAVAConn::Open(PGLOBAL g) char *cp = NULL; char sep; -#if defined(__WIN__) +#if defined(_WIN32) sep = ';'; #define N 1 //#define N 2 @@ -400,24 +402,17 @@ bool JAVAConn::Open(PGLOBAL g) jpop->Append(ClassPath); } // endif ClassPath -#if 0 - // Java source will be compiled as a jar file installed in the mysql share dir - jpop->Append(sep); - jpop->Append(lc_messages_dir); - jpop->Append("JdbcInterface.jar"); -#endif // 0 - - // All wrappers are pre-compiled in JavaWrappers.jar in the mysql share dir + // All wrappers are pre-compiled in JavaWrappers.jar in the share dir jpop->Append(sep); - jpop->Append(lc_messages_dir); + jpop->Append(GetMessageDir()); jpop->Append("JavaWrappers.jar"); #if defined(MONGO_SUPPORT) jpop->Append(sep); - jpop->Append(lc_messages_dir); + jpop->Append(GetMessageDir()); jpop->Append("Mongo3.jar"); jpop->Append(sep); - jpop->Append(lc_messages_dir); + jpop->Append(GetMessageDir()); jpop->Append("Mongo2.jar"); #endif // MONGO_SUPPORT diff --git a/storage/connect/javaconn.h b/storage/connect/javaconn.h index 73812f6ab3b..963b8c1a6ac 100644 --- a/storage/connect/javaconn.h +++ b/storage/connect/javaconn.h @@ -27,9 +27,9 @@ //efine MAX_CURSOR_NAME 18 // Max size of a cursor name //efine DEFAULT_FIELD_TYPE 0 // TYPE_NULL -#if !defined(__WIN__) +#if !defined(_WIN32) typedef unsigned char *PUCHAR; -#endif // !__WIN__ +#endif // !_WIN32 enum JCATINFO { JCAT_TAB = 1, // JDBC Tables @@ -104,11 +104,11 @@ public: protected: // Members -#if defined(__WIN__) +#if defined(_WIN32) static HANDLE LibJvm; // Handle to the jvm DLL -#else // !__WIN__ +#else // !_WIN32 static void *LibJvm; // Handle for the jvm shared library -#endif // !__WIN__ +#endif // !_WIN32 static CRTJVM CreateJavaVM; static GETJVM GetCreatedJavaVMs; #if defined(_DEBUG) diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index cea4d0a5b30..1035c2b8305 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -6,19 +6,19 @@ /* This file contains the JDBC connection classes functions. */ /***********************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) // This is needed for RegGetValue #define _WINVER 0x0601 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0601 -#endif // __WIN__ +#endif // _WIN32 /***********************************************************************/ /* Include relevant MariaDB header file. */ /***********************************************************************/ #include <my_global.h> #include <m_string.h> -#if defined(__WIN__) +#if defined(_WIN32) //nclude <io.h> //nclude <fcntl.h> #include <direct.h> // for getcwd @@ -26,7 +26,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <errno.h> #else // !UNIX @@ -36,7 +36,7 @@ #include <stdlib.h> // for getenv //nclude <fcntl.h> #define NODW -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Required objects includes. */ @@ -53,9 +53,9 @@ #include "osutil.h" -//#if defined(__WIN__) +//#if defined(_WIN32) //extern "C" HINSTANCE s_hModule; // Saved module handle -//#endif // __WIN__ +//#endif // _WIN32 #define nullptr 0 TYPCONV GetTypeConv(); diff --git a/storage/connect/jmgfam.cpp b/storage/connect/jmgfam.cpp index 2d45753ec63..670781da6f5 100644 --- a/storage/connect/jmgfam.cpp +++ b/storage/connect/jmgfam.cpp @@ -1,11 +1,11 @@ /************ JMONGO FAM C++ Program Source Code File (.CPP) ***********/ /* PROGRAM NAME: jmgfam.cpp */ /* ------------- */ -/* Version 1.1 */ +/* Version 1.2 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 20017 - 2020 */ +/* (C) Copyright to the author Olivier BERTRAND 20017 - 2021 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -17,7 +17,7 @@ /* Include relevant sections of the System header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) //#include <io.h> //#include <fcntl.h> //#include <errno.h> @@ -25,7 +25,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) || defined(UNIV_LINUX) //#include <errno.h> #include <unistd.h> @@ -36,7 +36,7 @@ //#include <io.h> #endif // !UNIX //#include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ @@ -241,8 +241,8 @@ bool JMGFAM::OpenTableFile(PGLOBAL g) return true; } // endif Mode - if (Mode == MODE_INSERT) - Jcp->MakeColumnGroups(g, Tdbp); +//if (Mode == MODE_INSERT) +// Jcp->MakeColumnGroups(g, Tdbp); if (Mode != MODE_UPDATE) return Jcp->MakeCursor(g, Tdbp, Options, Filter, Pipe); @@ -346,14 +346,14 @@ int JMGFAM::ReadBuffer(PGLOBAL g) } // end of ReadBuffer /***********************************************************************/ -/* WriteBuffer: File write routine for MGO access method. */ +/* WriteBuffer: File write routine for JMG access method. */ /***********************************************************************/ int JMGFAM::WriteBuffer(PGLOBAL g) { int rc = RC_OK; if (Mode == MODE_INSERT) { - rc = Jcp->DocWrite(g); + rc = Jcp->DocWrite(g, Tdbp->GetLine()); } else if (Mode == MODE_DELETE) { rc = Jcp->DocDelete(g, false); } else if (Mode == MODE_UPDATE) { diff --git a/storage/connect/jmgoconn.cpp b/storage/connect/jmgoconn.cpp index 0af91bc78cd..a4091e88bbf 100644 --- a/storage/connect/jmgoconn.cpp +++ b/storage/connect/jmgoconn.cpp @@ -1,7 +1,7 @@ /************ JMgoConn C++ Functions Source Code File (.CPP) ***********/ -/* Name: JMgoConn.CPP Version 1.1 */ +/* Name: JMgoConn.CPP Version 1.2 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */ /* */ /* This file contains the MongoDB Java connection classes functions. */ /***********************************************************************/ @@ -24,7 +24,7 @@ #define nullptr 0 -bool IsNum(PSZ s); +bool IsArray(PSZ s); bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s); /* --------------------------- Class JNCOL --------------------------- */ @@ -43,19 +43,21 @@ void JNCOL::AddCol(PGLOBAL g, PCOL colp, PSZ jp) *p++ = 0; for (kp = Klist; kp; kp = kp->Next) - if (kp->Jncolp && !strcmp(jp, kp->Key)) + if (kp->Jncolp && ((kp->Key && !strcmp(jp, kp->Key)) + || (!kp->Key && IsArray(jp) && kp->N == atoi(jp)))) break; if (!kp) { - icp = new(g) JNCOL(IsNum(p)); + icp = new(g) JNCOL(); kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL)); kcp->Next = NULL; kcp->Jncolp = icp; kcp->Colp = NULL; + kcp->Array = IsArray(jp); - if (Array) { + if (kcp->Array) { kcp->Key = NULL; - kcp->N = atoi(p); + kcp->N = atoi(jp); } else { kcp->Key = PlugDup(g, jp); kcp->N = 0; @@ -75,12 +77,12 @@ void JNCOL::AddCol(PGLOBAL g, PCOL colp, PSZ jp) icp->AddCol(g, colp, p); } else { kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL)); - kcp->Next = NULL; kcp->Jncolp = NULL; kcp->Colp = colp; + kcp->Array = IsArray(jp); - if (Array) { + if (kcp->Array) { kcp->Key = NULL; kcp->N = atoi(jp); } else { @@ -108,7 +110,7 @@ JMgoConn::JMgoConn(PGLOBAL g, PCSZ collname, PCSZ wrapper) CollName = collname; readid = fetchid = getdocid = objfldid = fcollid = acollid = mkdocid = docaddid = mkarid = araddid = insertid = updateid = - deleteid = gcollid = countid = rewindid = nullptr; + deleteid = gcollid = countid = rewindid = mkbsonid = nullptr; DiscFunc = "MongoDisconnect"; Fpc = NULL; m_Fetch = 0; @@ -235,7 +237,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options, PCSZ filter, bool pipe) { const char *p; - bool b = false, id = (tdbp->GetMode() != MODE_READ), all = false; + bool id, b = false, all = false; uint len; PCOL cp; PSZ jp; @@ -246,13 +248,14 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options, if (Options && !stricmp(Options, "all")) { Options = NULL; all = true; - } // endif Options + } else + id = (tdbp->GetMode() == MODE_UPDATE || tdbp->GetMode() == MODE_DELETE); - for (cp = tdbp->GetColumns(); cp; cp = cp->GetNext()) - if (!strcmp(cp->GetName(), "_id")) - id = true; - else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && (!Options || pipe)) + for (cp = tdbp->GetColumns(); cp && !all; cp = cp->GetNext()) + if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && (!Options || pipe)) all = true; + else if (!id) + id = !strcmp(cp->GetJpath(g, false), "_id"); if (pipe && Options) { if (trace(1)) @@ -535,7 +538,7 @@ PSZ JMgoConn::GetDocument(void) /***********************************************************************/ void JMgoConn::MakeColumnGroups(PGLOBAL g, PTDB tdbp) { - Fpc = new(g) JNCOL(false); + Fpc = new(g) JNCOL(); for (PCOL colp = tdbp->GetColumns(); colp; colp = colp->GetNext()) if (!colp->IsSpecial()) @@ -553,7 +556,7 @@ bool JMgoConn::GetMethodId(PGLOBAL g, MODE mode) return true; if (gmID(g, docaddid, "DocAdd", - "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z")) + "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;I)Z")) return true; if (gmID(g, updateid, "CollUpdate", "(Ljava/lang/Object;)J")) @@ -563,14 +566,19 @@ bool JMgoConn::GetMethodId(PGLOBAL g, MODE mode) if (gmID(g, mkdocid, "MakeDocument", "()Ljava/lang/Object;")) return true; + if (gmID(g, mkbsonid, "MakeBson", + "(Ljava/lang/String;I)Ljava/lang/Object;")) + return true; + if (gmID(g, docaddid, "DocAdd", - "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z")) + "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;I)Z")) return true; if (gmID(g, mkarid, "MakeArray", "()Ljava/lang/Object;")) return true; - if (gmID(g, araddid, "ArrayAdd", "(Ljava/lang/Object;ILjava/lang/Object;)Z")) + if (gmID(g, araddid, "ArrayAdd", + "(Ljava/lang/Object;ILjava/lang/Object;I)Z")) return true; if (gmID(g, insertid, "CollInsert", "(Ljava/lang/Object;)Z")) @@ -639,48 +647,81 @@ jobject JMgoConn::MakeObject(PGLOBAL g, PCOL colp, bool&error ) } // end of MakeObject /***********************************************************************/ +/* Stringify. */ +/***********************************************************************/ +bool JMgoConn::Stringify(PCOL colp) +{ + bool b = false; + + if (colp) + b = (colp->Stringify() && colp->GetResultType() == TYPE_STRING); + + return b; +} // end of Stringify + +/***********************************************************************/ /* MakeDoc. */ /***********************************************************************/ jobject JMgoConn::MakeDoc(PGLOBAL g, PJNCOL jcp) { - bool error = false; + int j; + bool b, error = false; jobject parent, child, val; jstring jkey; - - if (jcp->Array) + PJKC kp = jcp->Klist; + + if (kp->Array) parent = env->CallObjectMethod(job, mkarid); else parent = env->CallObjectMethod(job, mkdocid); - for (PJKC kp = jcp->Klist; kp; kp = kp->Next) + for (j = 0; kp; j = 0, kp = kp->Next) { + if (Stringify(kp->Colp)) { + switch (*kp->Colp->GetCharValue()) { + case '{': j = 1; break; + case '[': j = 2; break; + default: break; + } // endswitch + + b = (!kp->Key || !*kp->Key || *kp->Key == '*'); + } else + b = false; + if (kp->Jncolp) { if (!(child = MakeDoc(g, kp->Jncolp))) return NULL; - if (!jcp->Array) { + if (!kp->Array) { jkey = env->NewStringUTF(kp->Key); - if (env->CallBooleanMethod(job, docaddid, parent, jkey, child)) + if (env->CallBooleanMethod(job, docaddid, parent, jkey, child, j)) return NULL; env->DeleteLocalRef(jkey); } else - if (env->CallBooleanMethod(job, araddid, parent, kp->N, child)) + if (env->CallBooleanMethod(job, araddid, parent, kp->N, child, j)) return NULL; + env->DeleteLocalRef(child); } else { if (!(val = MakeObject(g, kp->Colp, error))) { if (error) return NULL; - } else if (!jcp->Array) { - jkey = env->NewStringUTF(kp->Key); + } else if (!kp->Array) { + if (!b) { + jkey = env->NewStringUTF(kp->Key); - if (env->CallBooleanMethod(job, docaddid, parent, jkey, val)) - return NULL; + if (env->CallBooleanMethod(job, docaddid, parent, jkey, val, j)) + return NULL; - env->DeleteLocalRef(jkey); - } else if (env->CallBooleanMethod(job, araddid, parent, kp->N, val)) { + env->DeleteLocalRef(jkey); + } else { + env->DeleteLocalRef(parent); + parent = env->CallObjectMethod(job, mkbsonid, val, j); + } // endif b + + } else if (env->CallBooleanMethod(job, araddid, parent, kp->N, val, j)) { if (Check(-1)) sprintf(g->Message, "ArrayAdd: %s", Msg); else @@ -689,19 +730,38 @@ jobject JMgoConn::MakeDoc(PGLOBAL g, PJNCOL jcp) return NULL; } // endif ArrayAdd + env->DeleteLocalRef(val); } // endif Jncolp + } // endfor kp + return parent; } // end of MakeDoc /***********************************************************************/ /* Insert a new document in the collation. */ /***********************************************************************/ -int JMgoConn::DocWrite(PGLOBAL g) +int JMgoConn::DocWrite(PGLOBAL g, PCSZ line) { - jobject doc; + int rc = RC_OK; + jobject doc = nullptr; + + if (line) { + int j; + jobject val = env->NewStringUTF(line); - if (!Fpc || !(doc = MakeDoc(g, Fpc))) + switch (*line) { + case '{': j = 1; break; + case '[': j = 2; break; + default: j = 0; break; + } // endswitch line + + doc = env->CallObjectMethod(job, mkbsonid, val, j); + env->DeleteLocalRef(val); + } else if (Fpc) + doc = MakeDoc(g, Fpc); + + if (!doc) return RC_FX; if (env->CallBooleanMethod(job, insertid, doc)) { @@ -710,10 +770,11 @@ int JMgoConn::DocWrite(PGLOBAL g) else sprintf(g->Message, "CollInsert: unknown error"); - return RC_FX; + rc = RC_FX; } // endif Insert - return RC_OK; + env->DeleteLocalRef(doc); + return rc; } // end of DocWrite /***********************************************************************/ @@ -721,7 +782,7 @@ int JMgoConn::DocWrite(PGLOBAL g) /***********************************************************************/ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp) { - int rc = RC_OK; + int j = 0, rc = RC_OK; bool error; PCOL colp; jstring jkey; @@ -734,8 +795,14 @@ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp) if (error) return RC_FX; - - if (env->CallBooleanMethod(job, docaddid, updlist, jkey, val)) + else if (Stringify(colp)) + switch (*colp->GetCharValue()) { + case '{': j = 1; break; + case '[': j = 2; break; + default: break; + } // endswitch + + if (env->CallBooleanMethod(job, docaddid, updlist, jkey, val, j)) return RC_OK; env->DeleteLocalRef(jkey); @@ -745,7 +812,7 @@ int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp) upd = env->CallObjectMethod(job, mkdocid); jkey = env->NewStringUTF("$set"); - if (env->CallBooleanMethod(job, docaddid, upd, jkey, updlist)) + if (env->CallBooleanMethod(job, docaddid, upd, jkey, updlist, 0)) return RC_OK; env->DeleteLocalRef(jkey); diff --git a/storage/connect/jmgoconn.h b/storage/connect/jmgoconn.h index 8ee7985d760..9fed1907abc 100644 --- a/storage/connect/jmgoconn.h +++ b/storage/connect/jmgoconn.h @@ -25,6 +25,7 @@ typedef struct JKCOL { PCOL Colp; char *Key; int N; + bool Array; } *PJKC; /***********************************************************************/ @@ -33,18 +34,18 @@ typedef struct JKCOL { class JNCOL : public BLOCK { public: // Constructor - JNCOL(bool ar) { Klist = NULL; Array = ar; } +//JNCOL(bool ar) { Klist = NULL; Array = ar; } + JNCOL(void) { Klist = NULL; } // Methods void AddCol(PGLOBAL g, PCOL colp, PSZ jp); //Members PJKC Klist; - bool Array; }; // end of JNCOL; /***********************************************************************/ -/* JMgoConn class. */ +/* JMgoConn class. */ /***********************************************************************/ class JMgoConn : public JAVAConn { friend class TDBJMG; @@ -81,11 +82,12 @@ public: bool GetMethodId(PGLOBAL g, MODE mode); jobject MakeObject(PGLOBAL g, PCOL colp, bool& error); jobject MakeDoc(PGLOBAL g, PJNCOL jcp); - int DocWrite(PGLOBAL g); + int DocWrite(PGLOBAL g, PCSZ line); int DocUpdate(PGLOBAL g, PTDB tdbp); int DocDelete(PGLOBAL g, bool all); bool Rewind(void); PSZ GetDocument(void); + bool Stringify(PCOL colp); protected: // Members @@ -100,6 +102,7 @@ protected: jmethodID getdocid; // The GetDoc method ID jmethodID objfldid; // The ObjectField method ID jmethodID mkdocid; // The MakeDocument method ID + jmethodID mkbsonid; // The MakeBson method ID jmethodID docaddid; // The DocAdd method ID jmethodID mkarid; // The MakeArray method ID jmethodID araddid; // The ArrayAdd method ID diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp index e9925ee959a..b9f9492320b 100644 --- a/storage/connect/json.cpp +++ b/storage/connect/json.cpp @@ -1,7 +1,7 @@ /*************** json CPP Declares Source Code File (.H) ***************/ -/* Name: json.cpp Version 1.5 */ +/* Name: json.cpp Version 1.6 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2014 - 2020 */ +/* (C) Copyright to the author Olivier BERTRAND 2014 - 2021 */ /* */ /* This file contains the JSON classes functions. */ /***********************************************************************/ @@ -23,7 +23,7 @@ #define ARGS MY_MIN(24,(int)len-i),s+MY_MAX(i-3,0) -#if defined(__WIN__) +#if defined(_WIN32) #define EL "\r\n" #else #define EL "\n" @@ -55,6 +55,7 @@ char *GetExceptionDesc(PGLOBAL g, unsigned int e); char *GetJsonNull(void); int GetDefaultPrec(void); +int PrepareColist(char*); /***********************************************************************/ /* IsNum: check whether this string is all digits. */ @@ -78,6 +79,24 @@ bool IsNum(PSZ s) } // end of IsNum /***********************************************************************/ +/* IsArray: check whether this is a Mongo array path. */ +/***********************************************************************/ +bool IsArray(PSZ s) +{ + char* p = s; + + if (!p || !*p) + return false; + else for (; *p; p++) + if (*p == '.') + break; + else if (!isdigit(*p)) + return false; + + return true; +} // end of IsArray + +/***********************************************************************/ /* NextChr: return the first found '[' or Sep pointer. */ /***********************************************************************/ char* NextChr(PSZ s, char sep) @@ -93,6 +112,27 @@ char* NextChr(PSZ s, char sep) return p2; } // end of NextChr +/***********************************************************************/ +/* Stringified: check that this column is in the stringified list. */ +/***********************************************************************/ +bool Stringified(PCSZ strfy, char *colname) +{ + if (strfy) { + char *p, colist[512]; + int n; + + strncpy(colist, strfy, sizeof(colist) - 1); + n = PrepareColist(colist); + + for (p = colist; n && p; p += (strlen(p) + 1), n--) + if (!stricmp(p, colname)) + return true; + + } // endif strfy + + return false; +} // end of Stringified + #if 0 /***********************************************************************/ /* Allocate a VAL structure, make sure common field and Nd are zeroed. */ @@ -227,6 +267,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char* fn, int pretty) { try { jdp = new(g) JDOC; // MUST BE ALLOCATED BEFORE jp !!!!! + jdp->dfp = GetDefaultPrec(); if (!jsp) { strcpy(g->Message, "Null json tree"); @@ -987,8 +1028,8 @@ bool JDOC::SerializeValue(PJVAL jvp) case TYPE_BINT: sprintf(buf, "%lld", jvp->LLn); return js->WriteStr(buf); - case TYPE_DBL: - sprintf(buf, "%.*lf", jvp->Nd, jvp->F); + case TYPE_DBL: // dfp to limit to the default number of decimals + sprintf(buf, "%.*f", MY_MIN(jvp->Nd, dfp), jvp->F); return js->WriteStr(buf); case TYPE_NULL: return js->WriteStr("null"); @@ -1326,9 +1367,9 @@ bool JARRAY::Merge(PGLOBAL g, PJSON jsp) } // end of Merge /***********************************************************************/ -/* Set the nth Value of the Array Value list. */ +/* Set the nth Value of the Array Value list or add it. */ /***********************************************************************/ -bool JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n) +void JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n) { int i = 0; PJVAL jp, *jpp = &First; @@ -1339,7 +1380,6 @@ bool JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n) *jpp = jvp; jvp->Next = (jp ? jp->Next : NULL); - return false; } // end of SetValue /***********************************************************************/ @@ -1417,7 +1457,7 @@ bool JARRAY::IsNull(void) /***********************************************************************/ JVALUE::JVALUE(PJSON jsp) : JSON() { - if (jsp->GetType() == TYPE_JVAL) { + if (jsp && jsp->GetType() == TYPE_JVAL) { PJVAL jvp = (PJVAL)jsp; // Val = ((PJVAL)jsp)->GetVal(); @@ -1434,7 +1474,7 @@ JVALUE::JVALUE(PJSON jsp) : JSON() } else { Jsp = jsp; // Val = NULL; - DataType = TYPE_JSON; + DataType = Jsp ? TYPE_JSON : TYPE_NULL; Nd = 0; } // endif Type diff --git a/storage/connect/json.h b/storage/connect/json.h index 3a026f5df22..53fc5f65e7b 100644 --- a/storage/connect/json.h +++ b/storage/connect/json.h @@ -66,6 +66,8 @@ const char* GetFmt(int type, bool un); PJSON ParseJson(PGLOBAL g, char* s, size_t n, int* prty = NULL, bool* b = NULL); PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty); DllExport bool IsNum(PSZ s); +bool IsArray(PSZ s); +bool Stringified(PCSZ strfy, char *colname); /***********************************************************************/ /* Class JDOC. The class for parsing and serializing json documents. */ @@ -74,7 +76,7 @@ class JDOC: public BLOCK { friend PJSON ParseJson(PGLOBAL, char*, size_t, int*, bool*); friend PSZ Serialize(PGLOBAL, PJSON, char*, int); public: - JDOC(void) : js(NULL), s(NULL), len(0), pty(NULL) {} + JDOC(void) : js(NULL), s(NULL), len(0), dfp(0), pty(NULL) {} void SetJp(JOUT* jp) { js = jp; } @@ -93,7 +95,7 @@ public: private: JOUT* js; char *s; - int len; + int len, dfp; bool *pty; }; // end of class JDOC @@ -184,7 +186,7 @@ class JARRAY : public JSON { // Specific PJVAL AddArrayValue(PGLOBAL g, PJVAL jvp = NULL, int* x = NULL); - bool SetArrayValue(PGLOBAL g, PJVAL jvp, int i); + void SetArrayValue(PGLOBAL g, PJVAL jvp, int i); void InitArray(PGLOBAL g); protected: diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index c633993863c..8185be66687 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -1524,22 +1524,31 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n) /*********************************************************************************/ int IsJson(UDF_ARGS *args, uint i, bool b) { - int n = 0; + const char *pat = args->attributes[i]; + int n = 0; + + if (*pat == '@') { + pat++; + + if (*pat == '\'' || *pat == '"') + pat++; + + } // endif pat if (i >= args->arg_count || args->arg_type[i] != STRING_RESULT) { - } else if (!strnicmp(args->attributes[i], "Json_", 5)) { + } else if (!strnicmp(pat, "Json_", 5)) { if (!args->args[i] || strchr("[{ \t\r\n", *args->args[i])) n = 1; // arg should be is a json item else n = 2; // A file name may have been returned - } else if (!strnicmp(args->attributes[i], "Jbin_", 5)) { + } else if (!strnicmp(pat, "Jbin_", 5)) { if (args->lengths[i] == sizeof(BSON)) n = 3; // arg is a binary json item else n = 2; // A file name may have been returned - } else if (!strnicmp(args->attributes[i], "Jfile_", 6)) { + } else if (!strnicmp(pat, "Jfile_", 6)) { n = 2; // arg is a json file name } else if (b) { char *sap; diff --git a/storage/connect/macutil.cpp b/storage/connect/macutil.cpp index f95f3adcc6e..93cd0bcb5e1 100644 --- a/storage/connect/macutil.cpp +++ b/storage/connect/macutil.cpp @@ -2,11 +2,11 @@ /* MACUTIL: Author Olivier Bertrand -- 2008-2012 */ /* From the article and sample code by Khalid Shaikh. */ /***********************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) #include "my_global.h" -#else // !__WIN__ +#else // !_WIN32 #error This is WINDOWS only DLL -#endif // !__WIN__ +#endif // !_WIN32 #include "global.h" #include "plgdbsem.h" #include "macutil.h" diff --git a/storage/connect/macutil.h b/storage/connect/macutil.h index c80bd58e20a..69a785dc9da 100644 --- a/storage/connect/macutil.h +++ b/storage/connect/macutil.h @@ -1,10 +1,10 @@ // MACUTIL.H Olivier Bertrand 2008-2012 // Get Mac Addresses via GetAdaptersInfo -#if defined(__WIN__) +#if defined(_WIN32) #include <iphlpapi.h> -#else // !__WIN__ +#else // !_WIN32 #error This is WINDOWS only -#endif // !__WIN__ +#endif // !_WIN32 #include "block.h" typedef class MACINFO *MACIP; diff --git a/storage/connect/maputil.cpp b/storage/connect/maputil.cpp index 71290511f8e..b722a438011 100644 --- a/storage/connect/maputil.cpp +++ b/storage/connect/maputil.cpp @@ -14,7 +14,7 @@ #include "plgdbsem.h" #include "maputil.h" -#ifdef __WIN__ +#ifdef _WIN32 /***********************************************************************/ /* In Insert mode, just open the file for append. Otherwise */ /* create the mapping file object. The map handle can be released */ diff --git a/storage/connect/mongo.cpp b/storage/connect/mongo.cpp index 5f10a89ee67..a9c4813684b 100644 --- a/storage/connect/mongo.cpp +++ b/storage/connect/mongo.cpp @@ -1,6 +1,6 @@ /************** mongo C++ Program Source Code File (.CPP) **************/ -/* PROGRAM NAME: mongo Version 1.0 */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* PROGRAM NAME: mongo Version 1.1 */ +/* (C) Copyright to the author Olivier BERTRAND 2021 */ /* These programs are the MGODEF class execution routines. */ /***********************************************************************/ @@ -36,6 +36,7 @@ bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s); bool IsNum(PSZ s); int GetDefaultDepth(void); +bool JsonAllPath(void); /***********************************************************************/ /* Make selector json representation for Mongo tables. */ @@ -350,7 +351,7 @@ void MGODISC::AddColumn(PGLOBAL g, PCSZ colname, PCSZ fmt, int k) bcp->Name = PlugDup(g, colname); length[0] = MY_MAX(length[0], (signed)strlen(colname)); - if (k) { + if (k || JsonAllPath()) { bcp->Fmt = PlugDup(g, fmt); length[7] = MY_MAX(length[7], (signed)strlen(fmt)); } else @@ -395,6 +396,7 @@ bool MGODEF::DefineAM(PGLOBAL g, LPCSTR, int poff) Uri = GetStringCatInfo(g, "Connect", "mongodb://localhost:27017"); Colist = GetStringCatInfo(g, "Colist", NULL); Filter = GetStringCatInfo(g, "Filter", NULL); + Strfy = GetStringCatInfo(g, "Stringify", NULL); Base = GetIntCatInfo("Base", 0) ? 1 : 0; Version = GetIntCatInfo("Version", 3); diff --git a/storage/connect/mongo.h b/storage/connect/mongo.h index dcefac372c0..7e92a7dc8e9 100644 --- a/storage/connect/mongo.h +++ b/storage/connect/mongo.h @@ -1,7 +1,7 @@ /**************** mongo H Declares Source Code File (.H) ***************/ -/* Name: mongo.h Version 1.0 */ +/* Name: mongo.h Version 1.1 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2021 */ /* */ /* This file contains the common MongoDB classes declares. */ /***********************************************************************/ @@ -82,6 +82,7 @@ protected: PSZ Wrapname; /* Java wrapper name */ PCSZ Colist; /* Options list */ PCSZ Filter; /* Filtering query */ + PCSZ Strfy; /* The stringify columns */ int Base; /* The array index base */ int Version; /* The Java driver version */ bool Pipe; /* True is Colist is a pipeline */ diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc index e3fa00e119f..d4b182b4c64 100644 --- a/storage/connect/mycat.cc +++ b/storage/connect/mycat.cc @@ -62,10 +62,10 @@ #include "tabvct.h" #endif // VCT_SUPPORT #include "tabsys.h" -#if defined(__WIN__) +#if defined(_WIN32) #include "tabmac.h" #include "tabwmi.h" -#endif // __WIN__ +#endif // _WIN32 //#include "tabtbl.h" #include "tabxcl.h" #include "tabtbl.h" @@ -105,9 +105,9 @@ /***********************************************************************/ /* Extern static variables. */ /***********************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) extern "C" HINSTANCE s_hModule; // Saved module handle -#endif // !__WIN__ +#endif // !_WIN32 #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT) bool MongoEnabled(void); #endif // JAVA_SUPPORT || CMGO_SUPPORT @@ -124,6 +124,15 @@ char *GetPluginDir(void) } // end of GetPluginDir /***********************************************************************/ +/* Get the lc_messages_dir, it is where error messages for various */ +/* languages are installed, and by default the INSTALL_MYSQLSHAREDIR. */ +/***********************************************************************/ +char *GetMessageDir(void) +{ + return lc_messages_dir; +} // end of GetMessageDir + +/***********************************************************************/ /* Get a unique enum table type ID. */ /***********************************************************************/ TABTYPE GetTypeID(const char *type) @@ -152,10 +161,10 @@ TABTYPE GetTypeID(const char *type) : (!stricmp(type, "MYSQL")) ? TAB_MYSQL : (!stricmp(type, "MYPRX")) ? TAB_MYSQL : (!stricmp(type, "DIR")) ? TAB_DIR -#if defined(__WIN__) +#if defined(_WIN32) : (!stricmp(type, "MAC")) ? TAB_MAC : (!stricmp(type, "WMI")) ? TAB_WMI -#endif // __WIN__ +#endif // _WIN32 : (!stricmp(type, "TBL")) ? TAB_TBL : (!stricmp(type, "XCOL")) ? TAB_XCL : (!stricmp(type, "OCCUR")) ? TAB_OCCUR @@ -374,11 +383,11 @@ uint GetFuncID(const char *func) /***********************************************************************/ CATALOG::CATALOG(void) { -#if defined(__WIN__) +#if defined(_WIN32) //DataPath= ".\\"; -#else // !__WIN__ +#else // !_WIN32 //DataPath= "./"; -#endif // !__WIN__ +#endif // !_WIN32 memset(&Ctb, 0, sizeof(CURTAB)); Cbuf= NULL; Cblen= 0; @@ -472,10 +481,10 @@ PTABDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am) #if defined(JAVA_SUPPORT) case TAB_JDBC: tdp= new(g) JDBCDEF; break; #endif // JAVA_SUPPORT -#if defined(__WIN__) +#if defined(_WIN32) case TAB_MAC: tdp= new(g) MACDEF; break; case TAB_WMI: tdp= new(g) WMIDEF; break; -#endif // __WIN__ +#endif // _WIN32 case TAB_OEM: tdp= new(g) OEMDEF; break; case TAB_TBL: tdp= new(g) TBLDEF; break; case TAB_XCL: tdp= new(g) XCLDEF; break; diff --git a/storage/connect/mycat.h b/storage/connect/mycat.h index 6473f7a5c11..147148f4a57 100644 --- a/storage/connect/mycat.h +++ b/storage/connect/mycat.h @@ -78,7 +78,8 @@ struct ha_table_option_struct { typedef class ha_connect *PHC; -char *GetPluginDir(void); +char *GetPluginDir(void); +char *GetMessageDir(void); TABTYPE GetTypeID(const char *type); bool IsFileType(TABTYPE type); bool IsExactType(TABTYPE type); diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index 2e270368916..ca3728471b1 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -35,11 +35,11 @@ #include "my_sys.h" #include "mysqld_error.h" #endif // !MYSQL_PREPARED_STATEMENTS -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #include "osutil.h" -#endif // !__WIN__ +#endif // !_WIN32 #include "global.h" #include "plgdbsem.h" @@ -492,15 +492,15 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db, //mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt); //mysql_options(m_DB, MYSQL_OPT_WRITE_TIMEOUT, ...); -#if defined(__WIN__) +#if defined(_WIN32) if (!strcmp(host, ".")) { mysql_options(m_DB, MYSQL_OPT_NAMED_PIPE, NULL); pipe = mysqld_unix_port; } // endif host -#else // !__WIN__ +#else // !_WIN32 if (!strcmp(host, "localhost")) pipe = mysqld_unix_port; -#endif // !__WIN__ +#endif // !_WIN32 #if 0 if (pwd && !strcmp(pwd, "*")) { diff --git a/storage/connect/myconn.h b/storage/connect/myconn.h index 9ebd37527a6..5f64f933878 100644 --- a/storage/connect/myconn.h +++ b/storage/connect/myconn.h @@ -7,24 +7,24 @@ /* DO NOT define DLL_EXPORT in your application so these items are */ /* declared are imported from the Myconn DLL. */ /***********************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) #include <winsock.h> -#else // !__WIN__ +#else // !_WIN32 #include <sys/socket.h> -#endif // !__WIN__ +#endif // !_WIN32 #include <mysql.h> #include <errmsg.h> #include "myutil.h" -#if defined(__WIN__) && defined(MYCONN_EXPORTS) +#if defined(_WIN32) && defined(MYCONN_EXPORTS) #if defined(DLL_EXPORT) #define DllItem _declspec(dllexport) #else // !DLL_EXPORT #define DllItem _declspec(dllimport) #endif // !DLL_EXPORT -#else // !__WIN__ || !MYCONN_EXPORTS +#else // !_WIN32 || !MYCONN_EXPORTS #define DllItem -#endif // !__WIN__ +#endif // !_WIN32 #define MYSQL_ENABLED 0x00000001 #define MYSQL_LOGON 0x00000002 diff --git a/storage/connect/mysql-test/connect/r/bson_mongo_c.result b/storage/connect/mysql-test/connect/r/bson_mongo_c.result index 83bf7cd1974..e2273be4bec 100644 --- a/storage/connect/mysql-test/connect/r/bson_mongo_c.result +++ b/storage/connect/mysql-test/connect/r/bson_mongo_c.result @@ -363,7 +363,7 @@ _id item prices_0 prices_1 prices_2 prices_3 prices_4 1 journal 87 45 63 12 78 2 notebook 123 456 789 NULL NULL 3 paper 5 7 3 8 NULL -4 planner 25 71 44 27 NULL +4 planner 25 71 NULL 44 27 5 postcard 5 7 3 8 NULL DROP TABLE t1; # diff --git a/storage/connect/mysql-test/connect/r/jdbc.result b/storage/connect/mysql-test/connect/r/jdbc.result index 0dbdf851860..b42311b8136 100644 --- a/storage/connect/mysql-test/connect/r/jdbc.result +++ b/storage/connect/mysql-test/connect/r/jdbc.result @@ -1,4 +1,5 @@ -SET GLOBAL time_zone='+1:00'; +SET GLOBAL time_zone='+0:00'; +SET time_zone='+0:00'; CREATE DATABASE connect; USE connect; CREATE TABLE t2 ( @@ -16,7 +17,7 @@ id msg tm dt dtm ts # Testing JDBC connection to MySQL driver # USE test; -CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root'; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root&useSSL=false'; SELECT * FROM t1; id msg tm dt dtm ts 455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 @@ -26,7 +27,7 @@ Note 1105 t2: 1 affected rows SELECT * FROM t1; id msg tm dt dtm ts 455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 -786325481247 Hello! 19:45:03 1933-08-09 1985-11-12 09:02:44 2014-06-17 10:32:01 +786325481247 Hello! 19:45:03 1933-08-10 1985-11-12 09:02:44 2014-06-17 10:32:01 DELETE FROM t1 WHERE msg = 'Hello!'; Warnings: Note 1105 t2: 1 affected rows @@ -37,7 +38,7 @@ DROP TABLE t1; # # Testing JDBC view # -CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root'; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root&useSSL=false'; SELECT * FROM t1; id msg tm dt 455000000000 A very big number 18:10:25 2016-03-16 @@ -74,7 +75,7 @@ SELECT * FROM t3; name city birth hired Donald Atlanta 1999-04-01 2016-03-31 Mick New York 1980-01-20 2002-09-11 -CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root' OPTION_LIST='scrollable=1'; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root&useSSL=false' OPTION_LIST='scrollable=1'; SELECT * FROM t1; name city birth hired John Boston 1986-01-25 2010-06-02 @@ -100,9 +101,9 @@ George San Jose 1981-08-10 2010-06-02 Sam Chicago 1979-11-22 2007-10-10 James Dallas 1992-05-13 2009-12-14 Bill Boston 1986-09-11 2008-02-10 -Donald Atlanta 1999-03-31 2016-03-30 -Mick New York 1980-01-20 2002-09-10 -Tom Seatle 2002-03-15 1970-01-01 +Donald Atlanta 1999-04-01 2016-03-31 +Mick New York 1980-01-20 2002-09-11 +Tom Seatle 2002-03-15 NULL DROP TABLE t3; # # Testing JDBC join operations @@ -280,3 +281,4 @@ DROP TABLE t1; DROP TABLE connect.tx1; DROP DATABASE connect; SET GLOBAL time_zone=SYSTEM; +SET time_zone=SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_new.result b/storage/connect/mysql-test/connect/r/jdbc_new.result index 33d8bd3b7d8..a47fb9ccaf9 100644 --- a/storage/connect/mysql-test/connect/r/jdbc_new.result +++ b/storage/connect/mysql-test/connect/r/jdbc_new.result @@ -2,7 +2,8 @@ connect master,127.0.0.1,root,,test,$MASTER_MYPORT,; connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,; connection master; connection slave; -SET GLOBAL time_zone='+1:00'; +SET GLOBAL time_zone='+0:00'; +SET time_zone='+0:00'; CREATE TABLE t1 (a int, b char(10)); INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03'); SELECT * FROM t1; @@ -16,31 +17,32 @@ NULL NULL # Testing errors # connection master; -SET GLOBAL time_zone='+1:00'; +SET GLOBAL time_zone='+0:00'; +SET time_zone='+0:00'; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=unknown'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=unknown&useSSL=false'; ERROR HY000: Connecting: java.sql.SQLException: Access denied for user 'unknown'@'localhost' (using password: NO) rc=-2 CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/unknown?user=root'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/unknown?user=root&useSSL=false'; ERROR HY000: Connecting: java.sql.SQLSyntaxErrorException: Unknown database 'unknown' rc=-2 CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='unknown' - CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; ERROR HY000: Cannot get columns from unknown SHOW CREATE TABLE t1; ERROR 42S02: Table 'test.t1' doesn't exist CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `x` int(11) DEFAULT NULL, `y` char(10) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`=JDBC SELECT * FROM t1; ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: Unknown column 'x' in 'field list'' from CONNECT DROP TABLE t1; CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; connection slave; ALTER TABLE t1 RENAME t1backup; connection master; @@ -54,13 +56,13 @@ DROP TABLE t1; # Testing SELECT, etc. # CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(10) DEFAULT NULL, `b` char(10) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`='JDBC' SELECT * FROM t1; a b NULL NULL @@ -70,13 +72,13 @@ NULL NULL 3 test03 DROP TABLE t1; CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='t1' - CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` char(10) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC `TABNAME`='t1' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`=JDBC `TABNAME`='t1' SELECT * FROM t1; a b NULL NULL @@ -86,13 +88,13 @@ NULL NULL 3 test03 DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, `b` char(10) NOT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`=JDBC SELECT * FROM t1; a b 0 @@ -102,13 +104,13 @@ a b 3 test03 DROP TABLE t1; CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` char(10) DEFAULT NULL, `b` int(11) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`=JDBC SELECT * FROM t1; a b NULL NULL @@ -138,7 +140,7 @@ t1 CREATE TABLE `t1` ( INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265); connection master; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -150,7 +152,7 @@ t1 CREATE TABLE `t1` ( `f` double(14,0) DEFAULT NULL, `g` double(24,0) DEFAULT NULL, `h` decimal(27,5) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`='JDBC' SELECT * FROM t1; a b c d e f g h 100 3333 41235 1234567890 235000000000 3 3 3141.59265 @@ -173,13 +175,13 @@ a b Welcome Hello, World connection master; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` char(12) DEFAULT NULL, `b` varchar(12) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`='JDBC' SELECT * FROM t1; a b Welcome Hello, World @@ -209,7 +211,7 @@ a b c d e 2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003 connection master; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC -CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -218,13 +220,15 @@ t1 CREATE TABLE `t1` ( `c` time DEFAULT NULL, `d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), `e` year(4) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root&useSSL=false' `TABLE_TYPE`='JDBC' SELECT * FROM t1; a b c d e -2003-05-27 2003-05-27 11:45:23 10:45:23 2003-05-27 10:45:23 2003 +2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003 DROP TABLE t1; connection slave; DROP TABLE t1; SET GLOBAL time_zone=SYSTEM; +SET time_zone=SYSTEM; connection master; SET GLOBAL time_zone=SYSTEM; +SET time_zone=SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_oracle.result b/storage/connect/mysql-test/connect/r/jdbc_oracle.result index d895a9aed87..21a2d10fef7 100644 --- a/storage/connect/mysql-test/connect/r/jdbc_oracle.result +++ b/storage/connect/mysql-test/connect/r/jdbc_oracle.result @@ -3,7 +3,7 @@ command varchar(128) not null, number int(5) not null flag=1, message varchar(255) flag=2) ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' -OPTION_LIST='User=system,Password=Choupy01,Execsrc=1'; +OPTION_LIST='User=system,Password=Biscote01,Execsrc=1'; SELECT * FROM t2 WHERE command = 'drop table employee'; command number message drop table employee 0 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist @@ -23,14 +23,14 @@ Warnings: Warning 1105 Affected rows CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' -OPTION_LIST='User=system,Password=Choupy01'; +OPTION_LIST='User=system,Password=Biscote01'; SELECT * FROM t1 WHERE table_name='employee'; Table_Cat Table_Schema Table_Name Table_Type Remark NULL SYSTEM EMPLOYEE TABLE NULL DROP TABLE t1; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='EMPLOYEE' CATFUNC=columns CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' -OPTION_LIST='User=system,Password=Choupy01'; +OPTION_LIST='User=system,Password=Biscote01'; SELECT * FROM t1; Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks NULL SYSTEM EMPLOYEE ID 3 NUMBER 38 0 0 10 0 NULL @@ -42,7 +42,7 @@ CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OP HOST 'jdbc:oracle:thin:@localhost:1521:xe', DATABASE 'SYSTEM', USER 'system', -PASSWORD 'Choupy01', +PASSWORD 'Biscote01', PORT 0, SOCKET '', OWNER 'SYSTEM'); diff --git a/storage/connect/mysql-test/connect/r/json_java_2.result b/storage/connect/mysql-test/connect/r/json_java_2.result index e0b08889f40..c05501013a5 100644 --- a/storage/connect/mysql-test/connect/r/json_java_2.result +++ b/storage/connect/mysql-test/connect/r/json_java_2.result @@ -10,7 +10,7 @@ SELECT * from t1 limit 3; Document {"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":"2014-03-03T00:00:00.000Z"},"grade":"A","score":2},{"date":{"$date":"2013-09-11T00:00:00.000Z"},"grade":"A","score":6},{"date":{"$date":"2013-01-24T00:00:00.000Z"},"grade":"A","score":10},{"date":{"$date":"2011-11-23T00:00:00.000Z"},"grade":"A","score":9},{"date":{"$date":"2011-03-10T00:00:00.000Z"},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"} {"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":"2014-12-30T00:00:00.000Z"},"grade":"A","score":8},{"date":{"$date":"2014-07-01T00:00:00.000Z"},"grade":"B","score":23},{"date":{"$date":"2013-04-30T00:00:00.000Z"},"grade":"A","score":12},{"date":{"$date":"2012-05-08T00:00:00.000Z"},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"} -{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.98513559999999,40.7676919],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":"2014-09-06T00:00:00.000Z"},"grade":"A","score":2},{"date":{"$date":"2013-07-22T00:00:00.000Z"},"grade":"A","score":11},{"date":{"$date":"2012-07-31T00:00:00.000Z"},"grade":"A","score":12},{"date":{"$date":"2011-12-29T00:00:00.000Z"},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"} +{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":"2014-09-06T00:00:00.000Z"},"grade":"A","score":2},{"date":{"$date":"2013-07-22T00:00:00.000Z"},"grade":"A","score":11},{"date":{"$date":"2012-07-31T00:00:00.000Z"},"grade":"A","score":12},{"date":{"$date":"2011-12-29T00:00:00.000Z"},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"} DROP TABLE t1; # # Test catfunc diff --git a/storage/connect/mysql-test/connect/r/json_java_3.result b/storage/connect/mysql-test/connect/r/json_java_3.result index b9ba919507d..b74f92bfee2 100644 --- a/storage/connect/mysql-test/connect/r/json_java_3.result +++ b/storage/connect/mysql-test/connect/r/json_java_3.result @@ -10,7 +10,7 @@ SELECT * from t1 limit 3; Document {"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"} {"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"} -{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.98513559999999,40.7676919],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"} +{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"} DROP TABLE t1; # # Test catfunc diff --git a/storage/connect/mysql-test/connect/r/json_mongo_c.result b/storage/connect/mysql-test/connect/r/json_mongo_c.result index 482ccc85b57..008e41f63d1 100644 --- a/storage/connect/mysql-test/connect/r/json_mongo_c.result +++ b/storage/connect/mysql-test/connect/r/json_mongo_c.result @@ -8,9 +8,9 @@ ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants CONNECTION='mongodb://localho OPTION_LIST='Driver=C,Version=0' DATA_CHARSET=utf8; SELECT * from t1 limit 3; Document -{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856076999999999089,40.848447000000000173],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"} -{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.96170399999999745,40.66294200000000103],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"} -{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985135599999992451,40.767691900000002647],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"} +{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"} +{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"} +{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"} DROP TABLE t1; # # Test catfunc @@ -363,7 +363,7 @@ _id item prices_0 prices_1 prices_2 prices_3 prices_4 1 journal 87 45 63 12 78 2 notebook 123 456 789 NULL NULL 3 paper 5 7 3 8 NULL -4 planner 25 71 44 27 NULL +4 planner 25 71 NULL 44 27 5 postcard 5 7 3 8 NULL DROP TABLE t1; # diff --git a/storage/connect/mysql-test/connect/r/mongo_c.result b/storage/connect/mysql-test/connect/r/mongo_c.result index 8b86ce32943..5b29bb54d3a 100644 --- a/storage/connect/mysql-test/connect/r/mongo_c.result +++ b/storage/connect/mysql-test/connect/r/mongo_c.result @@ -8,9 +8,9 @@ ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants OPTION_LIST='Driver=C,Version=0' DATA_CHARSET=utf8; SELECT * from t1 limit 3; Document -{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856076999999999089,40.848447000000000173],"street":"Morris ParkAve", "zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris ParkBakeShop", "restaurant_id":"30075445"} -{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.96170399999999745,40.66294200000000103],"street":"Flatbush Avenue", "zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"} -{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985135599999992451,40.767691900000002647],"street":"West 57Street", "zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj ReynoldsPubAndRestaurant", "restaurant_id":"30191841"} +{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000.000000},"grade":"A","score":2},{"date":{"$date":1378857600000.000000},"grade":"A","score":6},{"date":{"$date":1358985600000.000000},"grade":"A","score":10},{"date":{"$date":1322006400000.000000},"grade":"A","score":9},{"date":{"$date":1299715200000.000000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"} +{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000.000000},"grade":"A","score":8},{"date":{"$date":1404172800000.000000},"grade":"B","score":23},{"date":{"$date":1367280000000.000000},"grade":"A","score":12},{"date":{"$date":1336435200000.000000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"} +{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000.000000},"grade":"A","score":2},{"date":{"$date":1374451200000.000000},"grade":"A","score":11},{"date":{"$date":1343692800000.000000},"grade":"A","score":12},{"date":{"$date":1325116800000.000000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"} DROP TABLE t1; # # Test catfunc @@ -64,23 +64,23 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `_id` char(24) NOT NULL, - `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', - `address_coord` varchar(512) NOT NULL `FIELD_FORMAT`='address.coord', - `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', - `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', + `address_building` char(10) NOT NULL `JPATH`='address.building', + `address_coord` varchar(512) NOT NULL `JPATH`='address.coord', + `address_street` char(38) NOT NULL `JPATH`='address.street', + `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode', `borough` char(13) NOT NULL, `cuisine` char(64) NOT NULL, - `grades_0` varchar(512) DEFAULT NULL `FIELD_FORMAT`='grades.0', + `grades_0` varchar(512) DEFAULT NULL `JPATH`='grades.0', `name` char(98) NOT NULL, `restaurant_id` char(8) NOT NULL ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=C,Version=0' `DATA_CHARSET`='utf8' SELECT * FROM t1 LIMIT 5; _id address_building address_coord address_street address_zipcode borough cuisine grades_0 name restaurant_id -58ada47de5a51ddfcd5ed51c 1007 Morris Park Ave 10462 Bronx Bakery {"date":{"$date":1393804800000},"grade":"A","score":2} Morris Park Bake Shop 30075445 -58ada47de5a51ddfcd5ed51d 469 Flatbush Avenue 11225 Brooklyn Hamburgers {"date":{"$date":1419897600000},"grade":"A","score":8} Wendy'S 30112340 -58ada47de5a51ddfcd5ed51e 351 West 57 Street 10019 Manhattan Irish {"date":{"$date":1409961600000},"grade":"A","score":2} Dj Reynolds Pub And Restaurant 30191841 -58ada47de5a51ddfcd5ed51f 2780 Stillwell Avenue 11224 Brooklyn American {"date":{"$date":1402358400000},"grade":"A","score":5} Riviera Caterer 40356018 -58ada47de5a51ddfcd5ed520 97-22 63 Road 11374 Queens Jewish/Kosher {"date":{"$date":1416787200000},"grade":"Z","score":20} Tov Kosher Kitchen 40356068 +58ada47de5a51ddfcd5ed51c 1007 [-73.856077,40.848447] Morris Park Ave 10462 Bronx Bakery {"date":{"$date":1393804800000},"grade":"A","score":2} Morris Park Bake Shop 30075445 +58ada47de5a51ddfcd5ed51d 469 [-73.961704,40.662942] Flatbush Avenue 11225 Brooklyn Hamburgers {"date":{"$date":1419897600000},"grade":"A","score":8} Wendy'S 30112340 +58ada47de5a51ddfcd5ed51e 351 [-73.985136,40.767692] West 57 Street 10019 Manhattan Irish {"date":{"$date":1409961600000},"grade":"A","score":2} Dj Reynolds Pub And Restaurant 30191841 +58ada47de5a51ddfcd5ed51f 2780 [-73.982420,40.579505] Stillwell Avenue 11224 Brooklyn American {"date":{"$date":1402358400000},"grade":"A","score":5} Riviera Caterer 40356018 +58ada47de5a51ddfcd5ed520 97-22 [-73.860115,40.731174] 63 Road 11374 Queens Jewish/Kosher {"date":{"$date":1416787200000},"grade":"Z","score":20} Tov Kosher Kitchen 40356068 DROP TABLE t1; # # Dropping a column @@ -89,16 +89,16 @@ CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants DATA_CHARSET COLIST='{"projection":{"grades":0}}' OPTION_LIST='Driver=C,Version=0,level=0' ; SELECT * FROM t1 LIMIT 10; _id address borough cuisine name restaurant_id -58ada47de5a51ddfcd5ed51c {"building":"1007","coord":[-73.856076999999999089,40.848447000000000173],"street":"Morris ParkAve", "zipcode":"10462"} Bronx Bakery Morris Park Bake Shop 30075445 -58ada47de5a51ddfcd5ed51d {"building":"469","coord":[-73.96170399999999745,40.66294200000000103],"street":"Flatbush Avenue", "zipcode":"11225"} Brooklyn Hamburgers Wendy'S 30112340 -58ada47de5a51ddfcd5ed51e {"building":"351","coord":[-73.985135599999992451,40.767691900000002647],"street":"West 57Street", "zipcode":"10019"} Manhattan Irish Dj Reynolds Pub And Restaurant 30191841 -58ada47de5a51ddfcd5ed51f {"building":"2780","coord":[-73.982419999999990523,40.579504999999997494],"street":"Stillwell Avenue", "zipcode":"11224"} Brooklyn American Riviera Caterer 40356018 -58ada47de5a51ddfcd5ed520 {"building":"97-22","coord":[-73.860115199999995639,40.731173900000001709],"street":"63 Road", "zipcode":"11374"} Queens Jewish/Kosher Tov Kosher Kitchen 40356068 -58ada47de5a51ddfcd5ed521 {"building":"8825","coord":[-73.880382699999998408,40.764312400000001446],"street":"Astoria Boulevard", "zipcode":"11369"} Queens American Brunos On The Boulevard 40356151 -58ada47de5a51ddfcd5ed522 {"building":"2206","coord":[-74.137728600000002643,40.611957199999999091],"street":"Victory Boulevard", "zipcode":"10314"} Staten Island Jewish/Kosher Kosher Island 40356442 -58ada47de5a51ddfcd5ed523 {"building":"7114","coord":[-73.906850599999998508,40.619903399999998328],"street":"Avenue U", "zipcode":"11234"} Brooklyn Delicatessen Wilken'S Fine Food 40356483 -58ada47de5a51ddfcd5ed524 {"building":"6409","coord":[-74.005288999999990551,40.628886000000001388],"street":"11 Avenue", "zipcode":"11219"} Brooklyn American Regina Caterers 40356649 -58ada47de5a51ddfcd5ed525 {"building":"1839","coord":[-73.948260899999993967,40.640827100000002758],"street":"Nostrand Avenue", "zipcode":"11226"} Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731 +58ada47de5a51ddfcd5ed51c {"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"} Bronx Bakery Morris Park Bake Shop 30075445 +58ada47de5a51ddfcd5ed51d {"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"} Brooklyn Hamburgers Wendy'S 30112340 +58ada47de5a51ddfcd5ed51e {"building":"351","coord":[-73.985136,40.767692],"street":"West 57 Street","zipcode":"10019"} Manhattan Irish Dj Reynolds Pub And Restaurant 30191841 +58ada47de5a51ddfcd5ed51f {"building":"2780","coord":[-73.982420,40.579505],"street":"Stillwell Avenue","zipcode":"11224"} Brooklyn American Riviera Caterer 40356018 +58ada47de5a51ddfcd5ed520 {"building":"97-22","coord":[-73.860115,40.731174],"street":"63 Road","zipcode":"11374"} Queens Jewish/Kosher Tov Kosher Kitchen 40356068 +58ada47de5a51ddfcd5ed521 {"building":"8825","coord":[-73.880383,40.764312],"street":"Astoria Boulevard","zipcode":"11369"} Queens American Brunos On The Boulevard 40356151 +58ada47de5a51ddfcd5ed522 {"building":"2206","coord":[-74.137729,40.611957],"street":"Victory Boulevard","zipcode":"10314"} Staten Island Jewish/Kosher Kosher Island 40356442 +58ada47de5a51ddfcd5ed523 {"building":"7114","coord":[-73.906851,40.619903],"street":"Avenue U","zipcode":"11234"} Brooklyn Delicatessen Wilken'S Fine Food 40356483 +58ada47de5a51ddfcd5ed524 {"building":"6409","coord":[-74.005289,40.628886],"street":"11 Avenue","zipcode":"11219"} Brooklyn American Regina Caterers 40356649 +58ada47de5a51ddfcd5ed525 {"building":"1839","coord":[-73.948261,40.640827],"street":"Nostrand Avenue","zipcode":"11226"} Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731 DROP TABLE t1; # # Specifying Jpath @@ -249,14 +249,14 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `_id` char(24) NOT NULL, - `address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building', - `address_coord_0` double(12,6) NOT NULL `FIELD_FORMAT`='address.coord.0', - `address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street', - `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', + `address_building` char(6) NOT NULL `JPATH`='address.building', + `address_coord_0` double(12,6) NOT NULL `JPATH`='address.coord.0', + `address_street` char(25) NOT NULL `JPATH`='address.street', + `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode', `borough` char(13) NOT NULL, - `grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date', - `grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade', - `grades_0_score` int(11) NOT NULL `FIELD_FORMAT`='grades.0.score', + `grades_0_date` datetime NOT NULL `JPATH`='grades.0.date', + `grades_0_grade` char(14) NOT NULL `JPATH`='grades.0.grade', + `grades_0_score` int(11) NOT NULL `JPATH`='grades.0.score', `name` char(32) NOT NULL, `restaurant_id` char(8) NOT NULL ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"projection":{"cuisine":0}}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=C,level=2,version=0' diff --git a/storage/connect/mysql-test/connect/r/mongo_java_2.result b/storage/connect/mysql-test/connect/r/mongo_java_2.result index cccda2760d6..bcedd717cc4 100644 --- a/storage/connect/mysql-test/connect/r/mongo_java_2.result +++ b/storage/connect/mysql-test/connect/r/mongo_java_2.result @@ -64,13 +64,13 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `_id` char(24) NOT NULL, - `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', - `address_coord` char(41) NOT NULL `FIELD_FORMAT`='address.coord', - `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', - `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', + `address_building` char(10) NOT NULL `JPATH`='address.building', + `address_coord` char(41) NOT NULL `JPATH`='address.coord', + `address_street` char(38) NOT NULL `JPATH`='address.street', + `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode', `borough` char(13) NOT NULL, `cuisine` char(64) NOT NULL, - `grades_0` char(99) DEFAULT NULL `FIELD_FORMAT`='grades.0', + `grades_0` char(99) DEFAULT NULL `JPATH`='grades.0', `name` char(98) NOT NULL, `restaurant_id` char(8) NOT NULL ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8' @@ -249,14 +249,14 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `_id` char(24) NOT NULL, - `address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building', - `address_coord_0` double(18,14) NOT NULL `FIELD_FORMAT`='address.coord.0', - `address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street', - `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', + `address_building` char(6) NOT NULL `JPATH`='address.building', + `address_coord_0` double(18,14) NOT NULL `JPATH`='address.coord.0', + `address_street` char(25) NOT NULL `JPATH`='address.street', + `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode', `borough` char(13) NOT NULL, - `grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date', - `grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade', - `grades_0_score` int(2) NOT NULL `FIELD_FORMAT`='grades.0.score', + `grades_0_date` datetime NOT NULL `JPATH`='grades.0.date', + `grades_0_grade` char(14) NOT NULL `JPATH`='grades.0.grade', + `grades_0_score` int(2) NOT NULL `JPATH`='grades.0.score', `name` char(32) NOT NULL, `restaurant_id` char(8) NOT NULL ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=2' diff --git a/storage/connect/mysql-test/connect/r/mongo_java_3.result b/storage/connect/mysql-test/connect/r/mongo_java_3.result index ae39148a156..3183d4984d6 100644 --- a/storage/connect/mysql-test/connect/r/mongo_java_3.result +++ b/storage/connect/mysql-test/connect/r/mongo_java_3.result @@ -64,13 +64,13 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `_id` char(24) NOT NULL, - `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building', - `address_coord` char(39) NOT NULL `FIELD_FORMAT`='address.coord', - `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street', - `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', + `address_building` char(10) NOT NULL `JPATH`='address.building', + `address_coord` char(39) NOT NULL `JPATH`='address.coord', + `address_street` char(38) NOT NULL `JPATH`='address.street', + `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode', `borough` char(13) NOT NULL, `cuisine` char(64) NOT NULL, - `grades_0` char(84) DEFAULT NULL `FIELD_FORMAT`='grades.0', + `grades_0` char(84) DEFAULT NULL `JPATH`='grades.0', `name` char(98) NOT NULL, `restaurant_id` char(8) NOT NULL ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Depth=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8' @@ -249,14 +249,14 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `_id` char(24) NOT NULL, - `address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building', - `address_coord_0` double(18,14) NOT NULL `FIELD_FORMAT`='address.coord.0', - `address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street', - `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode', + `address_building` char(6) NOT NULL `JPATH`='address.building', + `address_coord_0` double(18,14) NOT NULL `JPATH`='address.coord.0', + `address_street` char(25) NOT NULL `JPATH`='address.street', + `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode', `borough` char(13) NOT NULL, - `grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date', - `grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade', - `grades_0_score` int(2) NOT NULL `FIELD_FORMAT`='grades.0.score', + `grades_0_date` datetime NOT NULL `JPATH`='grades.0.date', + `grades_0_grade` char(14) NOT NULL `JPATH`='grades.0.grade', + `grades_0_score` int(2) NOT NULL `JPATH`='grades.0.score', `name` char(32) NOT NULL, `restaurant_id` char(8) NOT NULL ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=3' diff --git a/storage/connect/mysql-test/connect/r/odbc_oracle.result b/storage/connect/mysql-test/connect/r/odbc_oracle.result index acb7d9a74c9..317aacef7a9 100644 --- a/storage/connect/mysql-test/connect/r/odbc_oracle.result +++ b/storage/connect/mysql-test/connect/r/odbc_oracle.result @@ -10,7 +10,7 @@ SET NAMES utf8; # All tables in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Table_Type Remark @@ -20,7 +20,7 @@ NULL MTR V1 VIEW NULL DROP TABLE t1; # All tables in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='%.%'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Table_Type Remark @@ -30,7 +30,7 @@ NULL MTR V1 VIEW NULL DROP TABLE t1; # All tables "T1" in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='%.T1'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Table_Type Remark @@ -38,7 +38,7 @@ NULL MTR T1 TABLE NULL DROP TABLE t1; # All tables "T1" in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='T1'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Table_Type Remark @@ -46,7 +46,7 @@ NULL MTR T1 TABLE NULL DROP TABLE t1; # Table "T1" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='MTR.T1'; SELECT * FROM t1 ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Table_Type Remark @@ -54,7 +54,7 @@ NULL MTR T1 TABLE NULL DROP TABLE t1; # All tables in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='MTR.%'; SELECT * FROM t1 ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Table_Type Remark @@ -68,7 +68,7 @@ DROP TABLE t1; # All columns in all schemas (limited with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks @@ -80,7 +80,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu DROP TABLE t1; # All columns in all schemas (limited with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='%.%'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks @@ -91,7 +91,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu MTR V1 B 6 NUMBER 38 40 NULL NULL 1 DROP TABLE t1; # All tables "T1" in all schemas (limited with WHERE) -CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' CATFUNC=Columns TABNAME='%.T1'; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='%.T1'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks MTR T1 A 3 DECIMAL 38 40 0 10 1 @@ -99,7 +99,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu DROP TABLE t1; # Table "T1" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='MTR.T1'; SELECT * FROM t1 ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks @@ -108,7 +108,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu DROP TABLE t1; # All tables "T1" in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='%.T1'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks @@ -121,14 +121,14 @@ DROP TABLE t1; # Table "T1" in the default schema ("MTR") CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' TABNAME='T1'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `A` decimal(40,0) DEFAULT NULL, `B` double DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' `TABLE_TYPE`='ODBC' `TABNAME`='T1' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' `TABLE_TYPE`='ODBC' `TABNAME`='T1' SELECT * FROM t1 ORDER BY A; A B 10 1000000000 @@ -157,14 +157,14 @@ DROP VIEW v1; DROP TABLE t1; # Table "T1" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' TABNAME='MTR.T1'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `A` decimal(40,0) DEFAULT NULL, `B` double DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T1' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T1' SELECT * FROM t1; A B 10 1000000000 @@ -173,14 +173,14 @@ A B DROP TABLE t1; # View "V1" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' TABNAME='MTR.V1'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `A` decimal(40,0) DEFAULT NULL, `B` double DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.V1' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.V1' SELECT * FROM t1; A B 10 1000000000 @@ -209,13 +209,13 @@ DROP VIEW v1; DROP TABLE t1; # Table "T2" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' TABNAME='MTR.T2'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `A` varchar(64) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T2' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T2' SELECT * FROM t1; A test diff --git a/storage/connect/mysql-test/connect/std_data/Mongo2.jar b/storage/connect/mysql-test/connect/std_data/Mongo2.jar Binary files differindex 9be654bd4c8..d51cc5d2345 100644 --- a/storage/connect/mysql-test/connect/std_data/Mongo2.jar +++ b/storage/connect/mysql-test/connect/std_data/Mongo2.jar diff --git a/storage/connect/mysql-test/connect/std_data/Mongo3.jar b/storage/connect/mysql-test/connect/std_data/Mongo3.jar Binary files differindex 2850177a668..f84e089ef50 100644 --- a/storage/connect/mysql-test/connect/std_data/Mongo3.jar +++ b/storage/connect/mysql-test/connect/std_data/Mongo3.jar diff --git a/storage/connect/mysql-test/connect/t/jdbc.test b/storage/connect/mysql-test/connect/t/jdbc.test index 58a527a3e6b..79809f4eaf3 100644 --- a/storage/connect/mysql-test/connect/t/jdbc.test +++ b/storage/connect/mysql-test/connect/t/jdbc.test @@ -1,6 +1,7 @@ -- source windows.inc -- source jdbconn.inc -SET GLOBAL time_zone='+1:00'; +SET GLOBAL time_zone='+0:00'; +SET time_zone='+0:00'; let $MYSQLD_DATADIR= `select @@datadir`; --copy_file $MTR_SUITE_DIR/std_data/girls.txt $MYSQLD_DATADIR/test/girls.txt @@ -27,7 +28,7 @@ SELECT * FROM t2; --echo # USE test; --replace_result $PORT PORT ---eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root&useSSL=false' SELECT * FROM t1; INSERT INTO t1 VALUES(786325481247, 'Hello!', '19:45:03', '1933-08-10', '1985-11-12 09:02:44', '2014-06-17 10:32:01'); SELECT * FROM t1; @@ -39,7 +40,7 @@ DROP TABLE t1; --echo # Testing JDBC view --echo # --replace_result $PORT PORT ---eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root&useSSL=false' SELECT * FROM t1; SELECT msg, dt FROM t1; DROP TABLE t1, connect.t2; @@ -67,7 +68,7 @@ INSERT INTO t3 VALUES('Donald','Atlanta','1999-04-01','2016-03-31'),('Mick','New SELECT * FROM t3; --replace_result $PORT PORT ---eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' OPTION_LIST='scrollable=1' +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root&useSSL=false' OPTION_LIST='scrollable=1' SELECT * FROM t1; UPDATE t1 SET city = 'Phoenix' WHERE name = 'Henry'; INSERT INTO t1 SELECT * FROM t3; @@ -145,4 +146,5 @@ DROP TABLE connect.tx1; DROP DATABASE connect; --remove_file $MYSQLD_DATADIR/test/girls.txt SET GLOBAL time_zone=SYSTEM; +SET time_zone=SYSTEM; -- source jdbconn_cleanup.inc diff --git a/storage/connect/mysql-test/connect/t/jdbc_new.test b/storage/connect/mysql-test/connect/t/jdbc_new.test index 36e8f36ced0..1eaafdfbf43 100644 --- a/storage/connect/mysql-test/connect/t/jdbc_new.test +++ b/storage/connect/mysql-test/connect/t/jdbc_new.test @@ -9,7 +9,8 @@ connection master; -- source jdbconn.inc connection slave; -SET GLOBAL time_zone='+1:00'; +SET GLOBAL time_zone='+0:00'; +SET time_zone='+0:00'; CREATE TABLE t1 (a int, b char(10)); INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03'); @@ -19,33 +20,34 @@ SELECT * FROM t1; --echo # Testing errors --echo # connection master; -SET GLOBAL time_zone='+1:00'; +SET GLOBAL time_zone='+0:00'; +SET time_zone='+0:00'; # Bad user name # Suppress "mysql_real_connect failed:" (printed in _DEBUG build) --replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " "" --error ER_UNKNOWN_ERROR eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=unknown'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=unknown&useSSL=false'; # Bad database name --replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " "" --error ER_UNKNOWN_ERROR eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/unknown?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/unknown?user=root&useSSL=false'; # Bad table name --replace_result $SLAVE_MYPORT SLAVE_PORT --error ER_UNKNOWN_ERROR eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='unknown' - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; --error ER_NO_SUCH_TABLE SHOW CREATE TABLE t1; # Bad column name --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW CREATE TABLE t1; --error ER_GET_ERRMSG @@ -55,7 +57,7 @@ DROP TABLE t1; # The remote table disappeared --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; connection slave; ALTER TABLE t1 RENAME t1backup; @@ -77,7 +79,7 @@ DROP TABLE t1; # Automatic table structure --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -86,7 +88,7 @@ DROP TABLE t1; # Explicit table structure --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='t1' - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -95,7 +97,7 @@ DROP TABLE t1; # Explicit table structure: remote NULL, local NOT NULL --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -104,7 +106,7 @@ DROP TABLE t1; # Explicit table structure with wrong column types --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -125,7 +127,7 @@ INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.141592 connection master; --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -146,7 +148,7 @@ SELECT * FROM t1; connection master; --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -167,7 +169,7 @@ SELECT * FROM t1; connection master; --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC - CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root&useSSL=false'; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -176,8 +178,10 @@ DROP TABLE t1; connection slave; DROP TABLE t1; SET GLOBAL time_zone=SYSTEM; +SET time_zone=SYSTEM; connection master; SET GLOBAL time_zone=SYSTEM; +SET time_zone=SYSTEM; -- source jdbconn_cleanup.inc diff --git a/storage/connect/mysql-test/connect/t/jdbc_oracle.test b/storage/connect/mysql-test/connect/t/jdbc_oracle.test index 1316352d4f5..0a475102ff7 100644 --- a/storage/connect/mysql-test/connect/t/jdbc_oracle.test +++ b/storage/connect/mysql-test/connect/t/jdbc_oracle.test @@ -8,20 +8,20 @@ CREATE TABLE t2 ( number int(5) not null flag=1, message varchar(255) flag=2) ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' -OPTION_LIST='User=system,Password=Choupy01,Execsrc=1'; +OPTION_LIST='User=system,Password=Biscote01,Execsrc=1'; SELECT * FROM t2 WHERE command = 'drop table employee'; SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))'; SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' -OPTION_LIST='User=system,Password=Choupy01'; +OPTION_LIST='User=system,Password=Biscote01'; SELECT * FROM t1 WHERE table_name='employee'; DROP TABLE t1; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='EMPLOYEE' CATFUNC=columns CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' -OPTION_LIST='User=system,Password=Choupy01'; +OPTION_LIST='User=system,Password=Biscote01'; SELECT * FROM t1; DROP TABLE t1; @@ -32,7 +32,7 @@ CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OP HOST 'jdbc:oracle:thin:@localhost:1521:xe', DATABASE 'SYSTEM', USER 'system', -PASSWORD 'Choupy01', +PASSWORD 'Biscote01', PORT 0, SOCKET '', OWNER 'SYSTEM'); diff --git a/storage/connect/mysql-test/connect/t/odbc_oracle.test b/storage/connect/mysql-test/connect/t/odbc_oracle.test index 18d29f69f1a..2a6eb5b7fce 100644 --- a/storage/connect/mysql-test/connect/t/odbc_oracle.test +++ b/storage/connect/mysql-test/connect/t/odbc_oracle.test @@ -78,42 +78,42 @@ SET NAMES utf8; --echo # All tables in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; DROP TABLE t1; --echo # All tables in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='%.%'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; DROP TABLE t1; --echo # All tables "T1" in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='%.T1'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; DROP TABLE t1; --echo # All tables "T1" in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='T1'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; DROP TABLE t1; --echo # Table "T1" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='MTR.T1'; SELECT * FROM t1 ORDER BY Table_Schema, Table_Name; DROP TABLE t1; --echo # All tables in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Tables TABNAME='MTR.%'; SELECT * FROM t1 ORDER BY Table_Schema, Table_Name; DROP TABLE t1; @@ -127,7 +127,7 @@ DROP TABLE t1; --echo # All columns in all schemas (limited with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns; # Disable warnings to avoid "Result limited to 20000 lines" --disable_warnings @@ -137,7 +137,7 @@ DROP TABLE t1; --echo # All columns in all schemas (limited with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='%.%'; # Disable warnings to avoid "Result limited to 20000 lines" --disable_warnings @@ -146,20 +146,20 @@ SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; DROP TABLE t1; --echo # All tables "T1" in all schemas (limited with WHERE) -CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' CATFUNC=Columns TABNAME='%.T1'; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='%.T1'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; DROP TABLE t1; --echo # Table "T1" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='MTR.T1'; SELECT * FROM t1 ORDER BY Table_Schema, Table_Name; DROP TABLE t1; --echo # All tables "T1" in all schemas (filtered with WHERE) CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' CATFUNC=Columns TABNAME='%.T1'; SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name; DROP TABLE t1; @@ -172,7 +172,7 @@ DROP TABLE t1; --echo # Table "T1" in the default schema ("MTR") CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' TABNAME='T1'; SHOW CREATE TABLE t1; SELECT * FROM t1 ORDER BY A; @@ -189,7 +189,7 @@ DROP TABLE t1; --echo # Table "T1" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' TABNAME='MTR.T1'; SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -197,7 +197,7 @@ DROP TABLE t1; --echo # View "V1" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' TABNAME='MTR.V1'; SHOW CREATE TABLE t1; SELECT * FROM t1; @@ -214,7 +214,7 @@ DROP TABLE t1; --echo # Table "T2" in the schema "MTR" CREATE TABLE t1 ENGINE=CONNECT -TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=newmtr' +TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtrnew' TABNAME='MTR.T2'; SHOW CREATE TABLE t1; SELECT * FROM t1; diff --git a/storage/connect/myutil.cpp b/storage/connect/myutil.cpp index e53ee1310e4..c49db48bfb3 100644 --- a/storage/connect/myutil.cpp +++ b/storage/connect/myutil.cpp @@ -13,11 +13,11 @@ /************************************************************************/ #include "my_global.h" #include <mysql.h> -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #include "osutil.h" -#endif // !__WIN__ +#endif // !_WIN32 #include "global.h" #include "plgdbsem.h" diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index 514951d8d2a..d7a7bf19729 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -11,7 +11,7 @@ /***********************************************************************/ #include <my_global.h> #include <m_string.h> -#if defined(__WIN__) +#if defined(_WIN32) //nclude <io.h> //nclude <fcntl.h> #include <direct.h> // for getcwd @@ -45,13 +45,13 @@ #include "osutil.h" -#if defined(__WIN__) +#if defined(_WIN32) /***********************************************************************/ /* For dynamic load of ODBC32.DLL */ /***********************************************************************/ #pragma comment(lib, "odbc32.lib") extern "C" HINSTANCE s_hModule; // Saved module handle -#endif // __WIN__ +#endif // _WIN32 TYPCONV GetTypeConv(); int GetConvSize(); @@ -1280,15 +1280,15 @@ bool ODBConn::DriverConnect(DWORD Options) SWORD nResult; PUCHAR ConnOut = (PUCHAR)PlugSubAlloc(m_G, NULL, MAX_CONNECT_LEN); UWORD wConnectOption = SQL_DRIVER_COMPLETE; -#if defined(__WIN__) +#if defined(_WIN32) HWND hWndTop = GetForegroundWindow(); HWND hWnd = GetParent(hWndTop); if (hWnd == NULL) hWnd = GetDesktopWindow(); -#else // !__WIN__ +#else // !_WIN32 HWND hWnd = (HWND)1; -#endif // !__WIN__ +#endif // !_WIN32 wConnectOption = SQL_DRIVER_NOPROMPT; //else if (Options & forceOdbcDialog) @@ -1298,10 +1298,10 @@ bool ODBConn::DriverConnect(DWORD Options) SQL_NTS, ConnOut, MAX_CONNECT_LEN, &nResult, wConnectOption); -#if defined(__WIN__) +#if defined(_WIN32) if (hWndTop) EnableWindow(hWndTop, true); -#endif // __WIN__ +#endif // _WIN32 // If user hit 'Cancel' if (rc == SQL_NO_DATA_FOUND) { diff --git a/storage/connect/odbconn.h b/storage/connect/odbconn.h index f98c67bd12f..7038f06e5f3 100644 --- a/storage/connect/odbconn.h +++ b/storage/connect/odbconn.h @@ -29,9 +29,9 @@ //efine MAX_CURSOR_NAME 18 // Max size of a cursor name //efine DEFAULT_FIELD_TYPE SQL_TYPE_NULL // pick "C" data type to match SQL data type -#if !defined(__WIN__) +#if !defined(_WIN32) typedef unsigned char *PUCHAR; -#endif // !__WIN__ +#endif // !_WIN32 // Field Flags, used to indicate status of fields //efine SQL_FIELD_FLAG_DIRTY 0x1 diff --git a/storage/connect/os.h b/storage/connect/os.h index 797692d47b2..7d0d5cabbb6 100644 --- a/storage/connect/os.h +++ b/storage/connect/os.h @@ -16,19 +16,19 @@ typedef off_t off64_t; #endif #endif -#if defined(__WIN__) +#if defined(_WIN32) typedef __int64 BIGINT; typedef _Null_terminated_ const char *PCSZ; -#else // !__WIN__ +#else // !_WIN32 typedef longlong BIGINT; #define FILE_BEGIN SEEK_SET #define FILE_CURRENT SEEK_CUR #define FILE_END SEEK_END typedef const char *PCSZ; -#endif // !__WIN__ +#endif // !_WIN32 -#if !defined(__WIN__) +#if !defined(_WIN32) typedef const void *LPCVOID; typedef const char *LPCTSTR; typedef const char *LPCSTR; @@ -65,6 +65,6 @@ typedef int HANDLE; #define _MAX_EXT FN_EXTLEN #define INVALID_HANDLE_VALUE (-1) #define __stdcall -#endif /* !__WIN__ */ +#endif /* !_WIN32 */ #endif /* _OS_H_INCLUDED */ diff --git a/storage/connect/osutil.c b/storage/connect/osutil.c index da896fec50e..278023f55a2 100644 --- a/storage/connect/osutil.c +++ b/storage/connect/osutil.c @@ -5,7 +5,7 @@ #include <stdio.h> #include "osutil.h" -#ifdef __WIN__ +#ifdef _WIN32 my_bool CloseFileHandle(HANDLE h) { return !CloseHandle(h); diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h index dd204d065ed..370bf69ffa0 100644 --- a/storage/connect/plgdbsem.h +++ b/storage/connect/plgdbsem.h @@ -581,11 +581,11 @@ typedef struct _colres { char Var; /* Type added information */ } COLRES; -#if defined(__WIN__) && !defined(NOEX) +#if defined(_WIN32) && !defined(NOEX) #define DllExport __declspec( dllexport ) -#else // !__WIN__ +#else // !_WIN32 #define DllExport -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Utility routines. */ diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index bdfa3462c28..55c7b8110fd 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -39,12 +39,12 @@ /***********************************************************************/ #include "my_global.h" #include "my_pthread.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #include <errno.h> #define BIGMEM 1048576 // 1 Megabyte -#else // !__WIN__ +#else // !_WIN32 #include <unistd.h> #include <fcntl.h> //#if defined(THREAD) @@ -52,7 +52,7 @@ //#endif // THREAD #include <stdarg.h> #define BIGMEM 2147483647 // Max int value -#endif // !__WIN__ +#endif // !_WIN32 #include <locale.h> /***********************************************************************/ @@ -89,11 +89,11 @@ extern "C" { extern char version[]; } // extern "C" -//#if defined(__WIN__) +//#if defined(_WIN32) //extern CRITICAL_SECTION parsec; // Used calling the Flex parser -//#else // !__WIN__ +//#else // !_WIN32 extern pthread_mutex_t parmut; -//#endif // !__WIN__ +//#endif // !_WIN32 // The debug trace used by the main thread FILE *pfile = NULL; @@ -386,11 +386,11 @@ char *SetPath(PGLOBAL g, const char *path) } // endif path if (*path != '.') { -#if defined(__WIN__) +#if defined(_WIN32) const char *s = "\\"; -#else // !__WIN__ +#else // !_WIN32 const char *s = "/"; -#endif // !__WIN__ +#endif // !_WIN32 strcat(strcat(strcat(strcpy(buf, "."), s), path), s); } else strcpy(buf, path); @@ -409,7 +409,7 @@ char *ExtractFromPath(PGLOBAL g, char *pBuff, char *FileName, OPVAL op) char *drive = NULL, *direc = NULL, *fname = NULL, *ftype = NULL; switch (op) { // Determine which part to extract -#if defined(__WIN__) +#if defined(_WIN32) case OP_FDISK: drive = pBuff; break; #endif // !UNIX case OP_FPATH: direc = pBuff; break; @@ -1252,7 +1252,7 @@ void *PlgDBalloc(PGLOBAL g, void *area, MBLOCK& mp) // For allocations greater than one fourth of remaining storage // in the area, do allocate from virtual storage. const char*v = "malloc"; -#if defined(__WIN__) +#if defined(_WIN32) if (mp.Size >= BIGMEM) { v = "VirtualAlloc"; mp.Memp = VirtualAlloc(NULL, mp.Size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); @@ -1355,7 +1355,7 @@ void PlgDBfree(MBLOCK& mp) { if (!mp.Sub && mp.Memp) { const char*v = "free"; -#if defined(__WIN__) +#if defined(_WIN32) if (mp.Size >= BIGMEM) { v = "VirtualFree"; VirtualFree(mp.Memp, 0, MEM_RELEASE); @@ -1557,11 +1557,11 @@ int FileComp(PGLOBAL g, char *file1, char *file2) bp[0] = buff1; bp[1] = buff2; for (i = 0; i < 2; i++) { -#if defined(__WIN__) +#if defined(_WIN32) h[i]= global_open(g, MSGID_NONE, fn[i], _O_RDONLY | _O_BINARY); -#else // !__WIN__ +#else // !_WIN32 h[i]= global_open(g, MSGOD_NONE, fn[i], O_RDONLY); -#endif // !__WIN__ +#endif // !_WIN32 if (h[i] == -1) { // if (errno != ENOENT) { diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp index f2887987c3f..a63eee75c1b 100644 --- a/storage/connect/plugutil.cpp +++ b/storage/connect/plugutil.cpp @@ -44,7 +44,7 @@ /* */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> #else #if defined(UNIX) || defined(UNIV_LINUX) @@ -81,9 +81,9 @@ #include "rcmsg.h" #endif // NEWMSG -#if defined(__WIN__) +#if defined(_WIN32) extern HINSTANCE s_hModule; /* Saved module handle */ -#endif // __WIN__ +#endif // _WIN32 #if defined(XMSG) extern char *msg_path; @@ -205,7 +205,7 @@ PGLOBAL PlugExit(PGLOBAL g) /***********************************************************************/ LPSTR PlugRemoveType(LPSTR pBuff, LPCSTR FileName) { -#if defined(__WIN__) +#if defined(_WIN32) char drive[_MAX_DRIVE]; #else char *drive = NULL; @@ -232,7 +232,7 @@ LPSTR PlugRemoveType(LPSTR pBuff, LPCSTR FileName) BOOL PlugIsAbsolutePath(LPCSTR path) { -#if defined(__WIN__) +#if defined(_WIN32) return ((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z')) && path[1] == ':'; #else @@ -250,7 +250,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath) char direc[_MAX_DIR], defdir[_MAX_DIR], tmpdir[_MAX_DIR]; char fname[_MAX_FNAME]; char ftype[_MAX_EXT]; -#if defined(__WIN__) +#if defined(_WIN32) char drive[_MAX_DRIVE], defdrv[_MAX_DRIVE]; #else char *drive = NULL, *defdrv = NULL; @@ -270,7 +270,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath) return pBuff; } // endif -#if !defined(__WIN__) +#if !defined(_WIN32) if (*FileName == '~') { if (_fullpath(pBuff, FileName, _MAX_PATH)) { if (trace(2)) @@ -281,7 +281,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath) return FileName; // Error, return unchanged name } // endif FileName -#endif // !__WIN__ +#endif // !_WIN32 if (prefix && strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath)) { @@ -310,7 +310,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath) if (trace(2)) { htrc("after _splitpath: FileName=%-.256s\n", FileName); -#if defined(__WIN__) +#if defined(_WIN32) htrc("drive=%-.256s dir=%-.256s fname=%-.256s ext=%-.256s\n", drive, direc, fname, ftype); htrc("defdrv=%-.256s defdir=%-.256s\n", defdrv, defdir); #else @@ -442,7 +442,7 @@ char *PlugGetMessage(PGLOBAL g, int mid) } // end of PlugGetMessage #endif // NEWMSG -#if defined(__WIN__) +#if defined(_WIN32) /***********************************************************************/ /* Return the line length of the console screen buffer. */ /***********************************************************************/ @@ -454,7 +454,7 @@ short GetLineLength(PGLOBAL g) return (b) ? coninfo.dwSize.X : 0; } // end of GetLineLength -#endif // __WIN__ +#endif // _WIN32 /***********************************************************************/ /* Program for memory allocation of work and language areas. */ @@ -464,7 +464,7 @@ bool AllocSarea(PGLOBAL g, size_t size) /*********************************************************************/ /* This is the allocation routine for the WIN32/UNIX/AIX version. */ /*********************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) if (size >= 1048576) // 1M g->Sarea = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); else @@ -500,7 +500,7 @@ bool AllocSarea(PGLOBAL g, size_t size) void FreeSarea(PGLOBAL g) { if (g->Sarea) { -#if defined(__WIN__) +#if defined(_WIN32) if (g->Sarea_Size >= 1048576) // 1M VirtualFree(g->Sarea, 0, MEM_RELEASE); else diff --git a/storage/connect/rcmsg.c b/storage/connect/rcmsg.c index 895f8f5862b..4cd443d88bb 100644 --- a/storage/connect/rcmsg.c +++ b/storage/connect/rcmsg.c @@ -21,9 +21,9 @@ #include "msgid.h" #endif // NEWMSG -#if !defined(__WIN__) +#if !defined(_WIN32) #define stricmp strcasecmp -#endif // !__WIN__ +#endif // !_WIN32 char *msglang(void); diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index 5b97377db97..39761fc2f18 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -17,7 +17,7 @@ /* Include relevant MariaDB header file. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <sqlext.h> #else //#include <dlfcn.h> // dlopen(), dlclose(), dlsym() ... @@ -52,9 +52,9 @@ #include "ha_connect.h" #include "mycat.h" -#if !defined(__WIN__) +#if !defined(_WIN32) extern handlerton *connect_hton; -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* External function. */ @@ -71,11 +71,11 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info) typedef PQRYRES(__stdcall* XCOLDEF) (PGLOBAL, void*, char*, char*, bool); const char* module, * subtype; char c, soname[_MAX_PATH], getname[40] = "Col"; -#if defined(__WIN__) +#if defined(_WIN32) HANDLE hdll; /* Handle to the external DLL */ -#else // !__WIN__ +#else // !_WIN32 void* hdll; /* Handle for the loaded shared library */ -#endif // !__WIN__ +#endif // !_WIN32 XCOLDEF coldef = NULL; PQRYRES qrp = NULL; @@ -93,8 +93,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info) if (check_valid_path(module, strlen(module))) { strcpy(g->Message, "Module cannot contain a path"); return NULL; - } - else + } else PlugSetPath(soname, module, GetPluginDir()); // The exported name is always in uppercase @@ -104,7 +103,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info) if (!c) break; } // endfor i -#if defined(__WIN__) +#if defined(_WIN32) // Load the Dll implementing the table if (!(hdll = LoadLibrary(soname))) { char buf[256]; @@ -124,7 +123,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info) FreeLibrary((HMODULE)hdll); return NULL; } // endif coldef -#else // !__WIN__ +#else // !_WIN32 const char* error = NULL; // Load the desired shared library @@ -141,7 +140,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info) dlclose(hdll); return NULL; } // endif coldef -#endif // !__WIN__ +#endif // !_WIN32 // Just in case the external Get function does not set error messages sprintf(g->Message, "Error getting column info from %s", subtype); @@ -149,11 +148,11 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info) // Get the table column definition qrp = coldef(g, topt, tab, db, info); -#if defined(__WIN__) +#if defined(_WIN32) FreeLibrary((HMODULE)hdll); -#else // !__WIN__ +#else // !_WIN32 dlclose(hdll); -#endif // !__WIN__ +#endif // !_WIN32 return qrp; } // end of OEMColumns @@ -406,13 +405,13 @@ int TABDEF::GetColCatInfo(PGLOBAL g) // Take care of the column definitions i= poff= nof= nlg= 0; -#if defined(__WIN__) +#if defined(_WIN32) // Offsets of HTML and DIR tables start from 0, DBF at 1 loff= (trf == RECFM_DBF) ? 1 : (trf == RECFM_XML || trf == RECFM_DIR) ? -1 : 0; -#else // !__WIN__ +#else // !_WIN32 // Offsets of HTML tables start from 0, DIR and DBF at 1 loff = (trf == RECFM_DBF || trf == RECFM_DIR) ? 1 : (trf == RECFM_XML) ? -1 : 0; -#endif // !__WIN__ +#endif // !_WIN32 while (true) { // Default Offset depends on table format @@ -625,7 +624,7 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g) strncat(strcpy(soname, GetPluginDir()), Module, sizeof(soname) - strlen(soname) - 1); -#if defined(__WIN__) +#if defined(_WIN32) // Is the DLL already loaded? if (!Hdll && !(Hdll = GetModuleHandle(soname))) // No, load the Dll implementing the function @@ -661,7 +660,7 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g) FreeLibrary((HMODULE)Hdll); return NULL; } // endif getdef -#else // !__WIN__ +#else // !_WIN32 const char *error = NULL; #if 0 // Don't know what all this stuff does @@ -703,7 +702,7 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g) dlclose(Hdll); return NULL; } // endif getdef -#endif // !__WIN__ +#endif // !_WIN32 // Just in case the external Get function does not set error messages sprintf(g->Message, MSG(DEF_ALLOC_ERROR), Subtype); diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h index 73e178ed51c..1b81ae9e3b3 100644 --- a/storage/connect/reldef.h +++ b/storage/connect/reldef.h @@ -146,11 +146,11 @@ class DllExport OEMDEF : public TABDEF { /* OEM table */ PTABDEF GetXdef(PGLOBAL g); // Members -#if defined(__WIN__) +#if defined(_WIN32) HANDLE Hdll; /* Handle to the external DLL */ -#else // !__WIN__ +#else // !_WIN32 void *Hdll; /* Handle for the loaded shared library */ -#endif // !__WIN__ +#endif // !_WIN32 PTABDEF Pxdef; /* Pointer to the external TABDEF class */ char *Module; /* Path/Name of the DLL implenting it */ char *Subtype; /* The name of the OEM table sub type */ diff --git a/storage/connect/tabbson.cpp b/storage/connect/tabbson.cpp index ce6d1d3b670..de272798e7c 100644 --- a/storage/connect/tabbson.cpp +++ b/storage/connect/tabbson.cpp @@ -1,5 +1,5 @@ /************* tabbson C++ Program Source Code File (.CPP) *************/ -/* PROGRAM NAME: tabbson Version 1.1 */ +/* PROGRAM NAME: tabbson Version 1.2 */ /* (C) Copyright to the author Olivier BERTRAND 2020 - 2021 */ /* This program are the BSON class DB execution routines. */ /***********************************************************************/ @@ -53,6 +53,7 @@ USETEMP UseTemp(void); bool JsonAllPath(void); int GetDefaultDepth(void); char *GetJsonNull(void); +bool Stringified(PCSZ, char*); /***********************************************************************/ /* BSONColumns: construct the result blocks containing the description */ @@ -173,7 +174,7 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) lvl = GetIntegerTableOption(g, topt, "Depth", lvl); sep = GetStringTableOption(g, topt, "Separator", "."); sz = GetIntegerTableOption(g, topt, "Jsize", 1024); - limit = GetIntegerTableOption(g, topt, "Limit", 10); + limit = GetIntegerTableOption(g, topt, "Limit", 50); strfy = GetStringTableOption(g, topt, "Stringify", NULL); /*********************************************************************/ @@ -193,7 +194,11 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) if (!(tdp->Database = SetPath(g, db))) return 0; - tdp->Objname = GetStringTableOption(g, topt, "Object", NULL); + if ((tdp->Objname = GetStringTableOption(g, topt, "Object", NULL))) { + if (*tdp->Objname == '$') tdp->Objname++; + if (*tdp->Objname == '.') tdp->Objname++; + } // endif Objname + tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0; tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2); tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL); @@ -218,8 +223,7 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) if (tdp->Uri) { #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT) - tdp->Collname = GetStringTableOption(g, topt, "Name", NULL); - tdp->Collname = GetStringTableOption(g, topt, "Tabname", tdp->Collname); + tdp->Collname = GetStringTableOption(g, topt, "Tabname", NULL); tdp->Schema = GetStringTableOption(g, topt, "Dbname", "test"); tdp->Options = (PSZ)GetStringTableOption(g, topt, "Colist", "all"); tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false); @@ -433,7 +437,7 @@ bool BSONDISC::Find(PGLOBAL g, PBVAL jvp, PCSZ key, int j) jcol.Type = TYPE_UNKNOWN; jcol.Len = jcol.Scale = 0; jcol.Cbn = true; - } else if (j < lvl && !(strfy && !stricmp(strfy, colname))) { + } else if (j < lvl && !Stringified(strfy, colname)) { if (!fmt[bf]) strcat(fmt, colname); @@ -504,7 +508,7 @@ bool BSONDISC::Find(PGLOBAL g, PBVAL jvp, PCSZ key, int j) } // endswitch Type } else if (lvl >= 0) { - if (strfy && !stricmp(strfy, colname)) { + if (Stringified(strfy, colname)) { if (!fmt[bf]) strcat(fmt, colname); @@ -604,33 +608,51 @@ void BSONDISC::AddColumn(PGLOBAL g) /***********************************************************************/ PBVAL BTUTIL::FindRow(PGLOBAL g) { - char *p, *objpath; + char *p, *objpath = PlugDup(g, Tp->Objname); + char *sep = (char*)(Tp->Sep == ':' ? ":[" : ".["); + bool bp = false, b = false; PBVAL jsp = Tp->Row; PBVAL val = NULL; - for (objpath = PlugDup(g, Tp->Objname); jsp && objpath; objpath = p) { - if ((p = strchr(objpath, Tp->Sep))) + for (; jsp && objpath; objpath = p, bp = b) { + if ((p = strpbrk(objpath + 1, sep))) { + b = (*p == '['); *p++ = 0; + } // endif p - if (*objpath != '[' && !IsNum(objpath)) { // objpass is a key + if (!bp && *objpath != '[' && !IsNum(objpath)) { // objpass is a key val = (jsp->Type == TYPE_JOB) ? GetKeyValue(jsp, objpath) : NULL; } else { - if (*objpath == '[') { - if (objpath[strlen(objpath) - 1] == ']') - objpath++; - else + if (bp || *objpath == '[') { // Old style + if (objpath[strlen(objpath) - 1] != ']') { + sprintf(g->Message, "Invalid Table path %s", Tp->Objname); return NULL; - } // endif [ + } else if (!bp) + objpath++; + + } // endif bp val = (jsp->Type == TYPE_JAR) ? - GetArrayValue(GetArray(jsp), atoi(objpath) - Tp->B) : NULL; + GetArrayValue(jsp, atoi(objpath) - Tp->B) : NULL; } // endif objpath // jsp = (val) ? val->GetJson() : NULL; jsp = val; } // endfor objpath + if (jsp && jsp->Type != TYPE_JOB) { + if (jsp->Type == TYPE_JAR) { + jsp = GetArrayValue(jsp, Tp->B); + + if (jsp->Type != TYPE_JOB) + jsp = NULL; + + } else + jsp = NULL; + + } // endif Type + return jsp; } // end of FindRow @@ -654,17 +676,22 @@ PBVAL BTUTIL::MakeTopTree(PGLOBAL g, int type) if (Tp->Objname) { if (!Tp->Row) { // Parse and allocate Objpath item(s) - char* p; - char *objpath = PlugDup(g, Tp->Objname); + char *p, *objpath = PlugDup(g, Tp->Objname); + char *sep = (char*)(Tp->Sep == ':' ? ":[" : ".["); int i; + bool bp = false, b = false; PBVAL objp = NULL; PBVAL arp = NULL; - for (; objpath; objpath = p) { - if ((p = strchr(objpath, Tp->Sep))) + for (; objpath; objpath = p, bp = b) { + if ((p = strpbrk(objpath + 1, sep))) { + b = (*p == '['); *p++ = 0; + } // endif p + - if (*objpath != '[' && !IsNum(objpath)) { + if (!bp && *objpath != '[' && !IsNum(objpath)) { + // objpass is a key objp = NewVal(TYPE_JOB); if (!top) @@ -676,15 +703,15 @@ PBVAL BTUTIL::MakeTopTree(PGLOBAL g, int type) val = NewVal(); SetKeyValue(objp, MOF(val), objpath); } else { - if (*objpath == '[') { + if (bp || *objpath == '[') { // Old style if (objpath[strlen(objpath) - 1] != ']') { sprintf(g->Message, "Invalid Table path %s", Tp->Objname); return NULL; - } else + } else if (!bp) objpath++; - } // endif objpath + } // endif bp if (!top) top = NewVal(TYPE_JAR); @@ -756,10 +783,16 @@ void BCUTIL::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL jvp) break; case TYPE_DATE: if (jvp->Type == TYPE_STRG) { - if (!((DTVAL*)vp)->IsFormatted()) - ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0); + PSZ dat = GetString(jvp); + + if (!IsNum(dat)) { + if (!((DTVAL*)vp)->IsFormatted()) + ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0); + + vp->SetValue_psz(dat); + } else + vp->SetValue(atoi(dat)); - vp->SetValue_psz(GetString(jvp)); } else vp->SetValue(GetInteger(jvp)); @@ -1157,10 +1190,15 @@ bool BSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) G = g; Schema = GetStringCatInfo(g, "DBname", Schema); Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT); - Objname = GetStringCatInfo(g, "Object", NULL); + + if ((Objname = GetStringCatInfo(g, "Object", NULL))) { + if (*Objname == '$') Objname++; + if (*Objname == '.') Objname++; + } // endif Objname + Xcol = GetStringCatInfo(g, "Expand", NULL); Pretty = GetIntCatInfo("Pretty", 2); - Limit = GetIntCatInfo("Limit", 10); + Limit = GetIntCatInfo("Limit", 50); Base = GetIntCatInfo("Base", 0) ? 1 : 0; Sep = *GetStringCatInfo(g, "Separator", "."); Accept = GetBoolCatInfo("Accept", false); @@ -1171,7 +1209,7 @@ bool BSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Collname = GetStringCatInfo(g, "Name", (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); Collname = GetStringCatInfo(g, "Tabname", Collname); - Options = GetStringCatInfo(g, "Colist", NULL); + Options = GetStringCatInfo(g, "Colist", Xcol ? "all" : NULL); Filter = GetStringCatInfo(g, "Filter", NULL); Pipe = GetBoolCatInfo("Pipeline", false); Driver = GetStringCatInfo(g, "Driver", NULL); @@ -1215,7 +1253,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m) if (Lrecl) { // Allocate the parse work memory - G = PlugInit(NULL, (size_t)Lrecl * (Pretty < 0 ? 2 : 4)); + G = PlugInit(NULL, (size_t)Lrecl * (Pretty < 0 ? 3 : 5)); } else { strcpy(g->Message, "LRECL is not defined"); return NULL; @@ -1249,6 +1287,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m) #endif // !MONGO_SUPPORT } // endif Driver + Pretty = 4; // Not a file } else if (Zipped) { #if defined(ZIP_SUPPORT) if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) { @@ -1454,7 +1493,7 @@ int TDBBSN::EstimatedLength(void) } // end of Estimated Length /***********************************************************************/ -/* OpenDB: Data Base open routine for JSN access method. */ +/* OpenDB: Data Base open routine for BSN access method. */ /***********************************************************************/ bool TDBBSN::OpenDB(PGLOBAL g) { @@ -1676,6 +1715,7 @@ BSONCOL::BSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) Xpd = false; Parsed = false; Warned = false; + Sgfy = false; } // end of BSONCOL constructor /***********************************************************************/ @@ -1695,6 +1735,7 @@ BSONCOL::BSONCOL(BSONCOL* col1, PTDB tdbp) : DOSCOL(col1, tdbp) Xpd = col1->Xpd; Parsed = col1->Parsed; Warned = col1->Warned; + Sgfy = col1->Sgfy; } // end of BSONCOL copy constructor /***********************************************************************/ @@ -1933,6 +1974,10 @@ bool BSONCOL::ParseJpath(PGLOBAL g) // Analyse intermediate array processing if (SetArrayOptions(g, p, i, Nodes[i - 1].Key)) return true; + else if (Xpd && Tbp->Mode == MODE_DELETE) { + strcpy(g->Message, "Cannot delete expanded columns"); + return true; + } // endif Xpd } else if (*p == '*') { // Return JSON @@ -1966,8 +2011,10 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj) if (*p1 == '$') p1++; if (*p1 == '.') p1++; mgopath = PlugDup(g, p1); - } else + } else { + Sgfy = true; return NULL; + } // endif for (p1 = p2 = mgopath; *p1; p1++) { @@ -2006,6 +2053,7 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj) case '*': if (*(p2 - 1) == '.' && !*(p1 + 1)) { p2--; // Suppress last :* + Sgfy = true; break; } // endif p2 /* fall through */ @@ -2014,6 +2062,10 @@ PSZ BSONCOL::GetJpath(PGLOBAL g, bool proj) break; } // endswitch p1; } + + if (*(p2 - 1) == '.') + p2--; + *p2 = 0; return mgopath; } else @@ -2230,8 +2282,6 @@ int TDBBSON::MakeDocument(PGLOBAL g) return RC_FX; if ((objpath = PlugDup(g, Objname))) { - if (*objpath == '$') objpath++; - if (*objpath == '.') objpath++; p1 = (*objpath == '[') ? objpath++ : NULL; /*********************************************************************/ diff --git a/storage/connect/tabbson.h b/storage/connect/tabbson.h index e9c5cc6477f..7f41bba6bd9 100644 --- a/storage/connect/tabbson.h +++ b/storage/connect/tabbson.h @@ -1,7 +1,7 @@ /*************** tabbson H Declares Source Code File (.H) **************/ -/* Name: tabbson.h Version 1.0 */ +/* Name: tabbson.h Version 1.1 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2020 */ +/* (C) Copyright to the author Olivier BERTRAND 2020 - 2021 */ /* */ /* This file contains the BSON classes declares. */ /***********************************************************************/ @@ -242,7 +242,8 @@ public: BSONCOL(BSONCOL* colp, PTDB tdbp); // Constructor used in copy process // Implementation - virtual int GetAmType(void) { return Tbp->GetAmType(); } + virtual int GetAmType(void) { return Tbp->GetAmType(); } + virtual bool Stringify(void) { return Sgfy; } // Methods virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); @@ -270,6 +271,7 @@ protected: bool Xpd; // True for expandable column bool Parsed; // True when parsed bool Warned; // True when warning issued + bool Sgfy; // True if stringified }; // end of class BSONCOL /* -------------------------- TDBBSON class -------------------------- */ diff --git a/storage/connect/tabcmg.cpp b/storage/connect/tabcmg.cpp index f2ff721627c..56d705f42ca 100644 --- a/storage/connect/tabcmg.cpp +++ b/storage/connect/tabcmg.cpp @@ -1,6 +1,6 @@ /************** tabcmg C++ Program Source Code File (.CPP) *************/ -/* PROGRAM NAME: tabcmg Version 1.1 */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* PROGRAM NAME: tabcmg Version 1.3 */ +/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */ /* This program are the C MongoDB class DB execution routines. */ /***********************************************************************/ @@ -27,6 +27,7 @@ #include "filter.h" PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info); +bool Stringified(PCSZ, char*); /* -------------------------- Class CMGDISC -------------------------- */ @@ -84,69 +85,80 @@ bool CMGDISC::FindInDoc(PGLOBAL g, bson_iter_t *iter, const bson_t *doc, bcol.Cbn = false; - if (BSON_ITER_HOLDS_UTF8(iter)) { - bcol.Type = TYPE_STRING; - bcol.Len = strlen(bson_iter_utf8(iter, NULL)); - } else if (BSON_ITER_HOLDS_INT32(iter)) { - bcol.Type = TYPE_INT; - bcol.Len = 11; // bson_iter_int32(iter) - } else if (BSON_ITER_HOLDS_INT64(iter)) { - bcol.Type = TYPE_BIGINT; - bcol.Len = 22; // bson_iter_int64(iter) - } else if (BSON_ITER_HOLDS_DOUBLE(iter)) { - bcol.Type = TYPE_DOUBLE; - bcol.Len = 12; - bcol.Scale = 6; // bson_iter_double(iter) - } else if (BSON_ITER_HOLDS_DATE_TIME(iter)) { - bcol.Type = TYPE_DATE; - bcol.Len = 19; // bson_iter_date_time(iter) - } else if (BSON_ITER_HOLDS_BOOL(iter)) { - bcol.Type = TYPE_TINY; - bcol.Len = 1; - } else if (BSON_ITER_HOLDS_OID(iter)) { - bcol.Type = TYPE_STRING; - bcol.Len = 24; // bson_iter_oid(iter) - } else if (BSON_ITER_HOLDS_DECIMAL128(iter)) { - bcol.Type = TYPE_DECIM; - bcol.Len = 32; // bson_iter_decimal128(iter, &dec) - } else if (BSON_ITER_HOLDS_DOCUMENT(iter)) { - if (lvl < 0) - continue; - else if (lvl <= k) { + switch (bson_iter_type(iter)) { + case BSON_TYPE_UTF8: bcol.Type = TYPE_STRING; - bcol.Len = 512; - } else { - bson_iter_t child; - - if (bson_iter_recurse(iter, &child)) - if (FindInDoc(g, &child, NULL, colname, fmt, k + 1, false)) - return true; - - newcol = false; - } // endif lvl - - } else if (BSON_ITER_HOLDS_ARRAY(iter)) { - if (lvl < 0) - continue; - else if (lvl <= k) { + bcol.Len = strlen(bson_iter_utf8(iter, NULL)); + break; + case BSON_TYPE_INT32: + bcol.Type = TYPE_INT; + bcol.Len = 11; // bson_iter_int32(iter) + break; + case BSON_TYPE_INT64: + bcol.Type = TYPE_BIGINT; + bcol.Len = 22; // bson_iter_int64(iter) + break; + case BSON_TYPE_DOUBLE: + bcol.Type = TYPE_DOUBLE; + bcol.Len = 12; + bcol.Scale = 6; // bson_iter_double(iter) + break; + case BSON_TYPE_DATE_TIME: + bcol.Type = TYPE_DATE; + bcol.Len = 19; // bson_iter_date_time(iter) + break; + case BSON_TYPE_BOOL: + bcol.Type = TYPE_TINY; + bcol.Len = 1; + break; + case BSON_TYPE_OID: bcol.Type = TYPE_STRING; - bcol.Len = 512; - } else { - bson_t *arr; - bson_iter_t itar; - const uint8_t *data = NULL; - uint32_t len = 0; - - bson_iter_array(iter, &len, &data); - arr = bson_new_from_data(data, len); - - if (FindInDoc(g, &itar, arr, colname, fmt, k + 1, !all)) - return true; + bcol.Len = 24; // bson_iter_oid(iter) + break; + case BSON_TYPE_DECIMAL128: + bcol.Type = TYPE_DECIM; + bcol.Len = 32; // bson_iter_decimal128(iter, &dec) + break; + case BSON_TYPE_DOCUMENT: + if (lvl < 0) + continue; + else if (lvl <= k) { + bcol.Type = TYPE_STRING; + bcol.Len = 512; + } else { + bson_iter_t child; + + if (bson_iter_recurse(iter, &child)) + if (FindInDoc(g, &child, NULL, colname, fmt, k + 1, false)) + return true; + + newcol = false; + } // endif lvl + + break; + case BSON_TYPE_ARRAY: + if (lvl < 0) + continue; + else if (lvl <= k) { + bcol.Type = TYPE_STRING; + bcol.Len = 512; + } else { + bson_t* arr; + bson_iter_t itar; + const uint8_t* data = NULL; + uint32_t len = 0; + + bson_iter_array(iter, &len, &data); + arr = bson_new_from_data(data, len); + + if (FindInDoc(g, &itar, arr, colname, fmt, k + 1, !all)) + return true; - newcol = false; - } // endif lvl + newcol = false; + } // endif lvl - } // endif's + break; + } // endswitch iter if (newcol) AddColumn(g, colname, fmt, k); @@ -178,15 +190,19 @@ TDBCMG::TDBCMG(MGODEF *tdp) : TDBEXT(tdp) Pcg.Coll_name = tdp->Tabname; Pcg.Options = tdp->Colist; Pcg.Filter = tdp->Filter; + Pcg.Line = NULL; Pcg.Pipe = tdp->Pipe && tdp->Colist != NULL; B = tdp->Base ? 1 : 0; + Strfy = tdp->Strfy; } else { Pcg.Uristr = NULL; Pcg.Db_name = NULL; Pcg.Coll_name = NULL; Pcg.Options = NULL; Pcg.Filter = NULL; + Pcg.Line = NULL; Pcg.Pipe = false; + Strfy = NULL; B = 0; } // endif tdp @@ -200,6 +216,7 @@ TDBCMG::TDBCMG(TDBCMG *tdbp) : TDBEXT(tdbp) Cmgp = tdbp->Cmgp; Cnd = tdbp->Cnd; Pcg = tdbp->Pcg; + Strfy = tdbp->Strfy; B = tdbp->B; Fpos = tdbp->Fpos; N = tdbp->N; @@ -381,7 +398,21 @@ MGOCOL::MGOCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) : EXTCOL(cdp, tdbp, cprec, i, "MGO") { Tmgp = (PTDBCMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp); - Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName(); + Sgfy = Stringified(Tmgp->Strfy, Name); + + if ((Jpath = cdp->GetFmt())) { + int n = strlen(Jpath) - 1; + + if (Jpath[n] == '*') { + Jpath = PlugDup(g, cdp->GetFmt()); + if (Jpath[n - 1] == '.') n--; + Jpath[n] = 0; + Sgfy = true; + } // endif Jpath + + } else + Jpath = cdp->GetName(); + } // end of MGOCOL constructor /***********************************************************************/ @@ -392,6 +423,7 @@ MGOCOL::MGOCOL(MGOCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) { Tmgp = col1->Tmgp; Jpath = col1->Jpath; + Sgfy = col1->Sgfy; } // end of MGOCOL copy constructor /***********************************************************************/ @@ -419,6 +451,9 @@ PSZ MGOCOL::GetJpath(PGLOBAL g, bool proj) } else *p2++ = *p1; + if (*(p2 - 1) == '.') + p2--; + *p2 = 0; return projpath; } else diff --git a/storage/connect/tabcmg.h b/storage/connect/tabcmg.h index 260f2def8a2..9effe714fdd 100644 --- a/storage/connect/tabcmg.h +++ b/storage/connect/tabcmg.h @@ -1,7 +1,7 @@ /**************** tabcmg H Declares Source Code File (.H) **************/ -/* Name: tabcmg.h Version 1.2 */ +/* Name: tabcmg.h Version 1.3 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */ /* */ /* This file contains the MongoDB classes declares. */ /***********************************************************************/ @@ -75,6 +75,7 @@ protected: CMgoConn *Cmgp; // Points to a C Mongo connection class CMGOPARM Pcg; // Parms passed to Cmgp const Item *Cnd; // The first condition + PCSZ Strfy; // The stringified columns int Fpos; // The current row index int N; // The current Rownum int B; // Array index base @@ -96,6 +97,7 @@ public: // Implementation virtual int GetAmType(void) { return Tmgp->GetAmType(); } + virtual bool Stringify(void) { return Sgfy; } // Methods virtual PSZ GetJpath(PGLOBAL g, bool proj); @@ -109,6 +111,7 @@ protected: // Members TDBCMG *Tmgp; // To the MGO table block char *Jpath; // The json path + bool Sgfy; // True if stringified }; // end of class MGOCOL /***********************************************************************/ diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index 822d7871b78..2e70fdfc558 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -17,7 +17,7 @@ /* Include relevant sections of the System header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <sys\timeb.h> // For testing only #include <fcntl.h> @@ -26,7 +26,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <errno.h> #include <unistd.h> @@ -34,7 +34,7 @@ #include <io.h> #endif // !UNIX #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ @@ -233,11 +233,11 @@ void DOSDEF::RemoveOptValues(PGLOBAL g) // Delete any eventually ill formed non matching optimization file if (!GetOptFileName(g, filename)) -#if defined(__WIN__) +#if defined(_WIN32) DeleteFile(filename); #else // UNIX remove(filename); -#endif // __WIN__ +#endif // _WIN32 Optimized = 0; } // end of RemoveOptValues @@ -279,7 +279,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf) /*********************************************************************/ if (sep) { // Indexes are save in separate files -#if defined(__WIN__) +#if defined(_WIN32) char drive[_MAX_DRIVE]; #else char *drive = NULL; @@ -296,7 +296,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf) strcat(strcat(fname, "_"), pxdf->GetName()); _makepath(filename, drive, direc, fname, ftype); PlugSetPath(filename, filename, GetPath()); -#if defined(__WIN__) +#if defined(_WIN32) if (!DeleteFile(filename)) rc |= (GetLastError() != ERROR_FILE_NOT_FOUND); #else // UNIX @@ -313,7 +313,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf) // Drop all indexes, delete the common file PlugSetPath(filename, Ofn, GetPath()); strcat(PlugRemoveType(filename, filename), ftype); -#if defined(__WIN__) +#if defined(_WIN32) if (!DeleteFile(filename)) rc = (GetLastError() != ERROR_FILE_NOT_FOUND); #else // UNIX @@ -1027,7 +1027,7 @@ bool TDBDOS::GetBlockValues(PGLOBAL g) #if 0 if (Mode == MODE_INSERT && Txfp->GetAmType() == TYPE_AM_DOS) return false; -#endif // __WIN__ +#endif // _WIN32 if (defp->Optimized || !(dup->Check & CHK_OPT)) return false; // Already done or to be redone @@ -2535,6 +2535,7 @@ void DOSCOL::ReadColumn(PGLOBAL g) char *p = NULL; int i, rc; int field; + bool err = false; double dval; PTDBDOS tdbp = (PTDBDOS)To_Tdb; @@ -2578,33 +2579,39 @@ void DOSCOL::ReadColumn(PGLOBAL g) case TYPE_SHORT: case TYPE_TINY: case TYPE_BIGINT: - if (Value->SetValue_char(p, field - Dcm)) { - sprintf(g->Message, "Out of range value for column %s at row %d", - Name, tdbp->RowNumber(g)); - PushWarning(g, tdbp); - } // endif SetValue_char - + err = Value->SetValue_char(p, field - Dcm); break; case TYPE_DOUBLE: - Value->SetValue_char(p, field); - dval = Value->GetFloatValue(); + if (!(err = Value->SetValue_char(p, field))) { + dval = Value->GetFloatValue(); + + for (i = 0; i < Dcm; i++) + dval /= 10.0; - for (i = 0; i < Dcm; i++) - dval /= 10.0; + Value->SetValue(dval); + } // endif err - Value->SetValue(dval); break; default: - Value->SetValue_char(p, field); + err = Value->SetValue_char(p, field); + + if (!err && Buf_Type == TYPE_DECIM) { + char* s = Value->GetCharValue(); + + if (!(err = ((i = strlen(s)) >= Value->GetClen()))) { + for (int d = Dcm + 1; d; i--, d--) + s[i + 1] = s[i]; + + s[i + 1] = '.'; + } // endif err + + } // endif DECIM + break; - } // endswitch Buf_Type + } // endswitch Buf_Type else - if (Value->SetValue_char(p, field)) { - sprintf(g->Message, "Out of range value for column %s at row %d", - Name, tdbp->RowNumber(g)); - PushWarning(g, tdbp); - } // endif SetValue_char + err = Value->SetValue_char(p, field); break; default: @@ -2612,6 +2619,12 @@ void DOSCOL::ReadColumn(PGLOBAL g) throw 34; } // endswitch Ftype + if (err) { + sprintf(g->Message, "Out of range value for column %s at row %d", + Name, tdbp->RowNumber(g)); + PushWarning(g, tdbp); + } // endif err + // Set null when applicable if (Nullable) Value->SetNull(Value->IsZero()); @@ -2702,7 +2715,7 @@ void DOSCOL::WriteColumn(PGLOBAL g) case TYPE_DECIM: strcpy(fmt, (Ldz) ? "%0*.*lf" : "%*.*lf"); len = field + ((Nod && Dcm) ? 1 : 0); - snprintf(Buf, len, fmt, len, Dcm, Value->GetFloatValue()); + snprintf(Buf, len + 1, fmt, len, Dcm, Value->GetFloatValue()); len = strlen(Buf); if (Nod && Dcm) diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp index 5f803aa1269..212d27f06d1 100644 --- a/storage/connect/tabext.cpp +++ b/storage/connect/tabext.cpp @@ -14,7 +14,7 @@ #include "sql_class.h" #include "sql_servers.h" #include "sql_string.h" -#if !defined(__WIN__) +#if !defined(_WIN32) #include "osutil.h" #endif diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp index 1a266f0e263..60c37075f66 100644 --- a/storage/connect/tabfix.cpp +++ b/storage/connect/tabfix.cpp @@ -17,7 +17,7 @@ /* Include relevant section of system dependant header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #include <errno.h> @@ -25,7 +25,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <sys/types.h> #include <sys/stat.h> @@ -35,7 +35,7 @@ #include <io.h> #endif // !UNIX #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index 8741ddae94e..49233f4f799 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -20,7 +20,7 @@ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #include <errno.h> @@ -156,14 +156,14 @@ PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info) p = (char*)GetStringTableOption(g, topt, "Separator", ","); tdp->Sep = (strlen(p) == 2 && p[0] == '\\' && p[1] == 't') ? '\t' : *p; -#if defined(__WIN__) +#if defined(_WIN32) if (tdp->Sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6)) dechar = '.'; else dechar = ','; -#else // !__WIN__ +#else // !_WIN32 dechar = '.'; -#endif // !__WIN__ +#endif // !_WIN32 sep = tdp->Sep; tdp->Quoted = GetIntegerTableOption(g, topt, "Quoted", -1); diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index 4d834bcf9e0..1268bcfd1de 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -38,7 +38,7 @@ #include "my_global.h" #include "sql_class.h" #include "sql_servers.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #if defined(__BORLANDC__) @@ -188,6 +188,9 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b) } else // host is a URL Url = PlugDup(g, server->host); + if (!Tabschema && server->db) + Tabschema = PlugDup(g, server->db); + if (!Username && server->username) Username = PlugDup(g, server->username); diff --git a/storage/connect/tabjmg.cpp b/storage/connect/tabjmg.cpp index 850d9e5fa9b..983ee39d65f 100644 --- a/storage/connect/tabjmg.cpp +++ b/storage/connect/tabjmg.cpp @@ -1,6 +1,6 @@ /************** tabjmg C++ Program Source Code File (.CPP) *************/ -/* PROGRAM NAME: tabjmg Version 1.2 */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* PROGRAM NAME: tabjmg Version 1.3 */ +/* (C) Copyright to the author Olivier BERTRAND 2021 */ /* This file contains the MongoDB classes using the Java Driver. */ /***********************************************************************/ @@ -30,6 +30,7 @@ #define nullptr 0 PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info); +bool Stringified(PCSZ, char*); /* -------------------------- Class JMGDISC -------------------------- */ @@ -166,6 +167,7 @@ TDBJMG::TDBJMG(PMGODEF tdp) : TDBEXT(tdp) Coll_name = tdp->Tabname; Options = tdp->Colist; Filter = tdp->Filter; + Strfy = tdp->Strfy; B = tdp->Base ? 1 : 0; Pipe = tdp->Pipe && Options != NULL; } else { @@ -177,6 +179,7 @@ TDBJMG::TDBJMG(PMGODEF tdp) : TDBEXT(tdp) Coll_name = NULL; Options = NULL; Filter = NULL; + Strfy = NULL; B = 0; Pipe = false; } // endif tdp @@ -197,6 +200,7 @@ TDBJMG::TDBJMG(TDBJMG *tdbp) : TDBEXT(tdbp) Coll_name = tdbp->Coll_name; Options = tdbp->Options; Filter = tdbp->Filter; + Strfy = tdbp->Strfy; B = tdbp->B; Fpos = tdbp->Fpos; N = tdbp->N; @@ -384,7 +388,7 @@ int TDBJMG::WriteDB(PGLOBAL g) int rc = RC_OK; if (Mode == MODE_INSERT) { - rc = Jcp->DocWrite(g); + rc = Jcp->DocWrite(g, NULL); } else if (Mode == MODE_DELETE) { rc = Jcp->DocDelete(g, false); } else if (Mode == MODE_UPDATE) { @@ -420,8 +424,25 @@ JMGCOL::JMGCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) : EXTCOL(cdp, tdbp, cprec, i, "MGO") { Tmgp = (PTDBJMG)(tdbp->GetOrig() ? tdbp->GetOrig() : tdbp); - Jpath = cdp->GetFmt() ? cdp->GetFmt() : cdp->GetName(); -//Mbuf = NULL; + Sgfy = Stringified(Tmgp->Strfy, Name); + + if ((Jpath = cdp->GetFmt())) { + int n = strlen(Jpath); + + if (n && Jpath[n - 1] == '*') { + Jpath = PlugDup(g, cdp->GetFmt()); + + if (--n) { + if (Jpath[n - 1] == '.') n--; + Jpath[n] = 0; + } // endif n + + Sgfy = true; + } // endif Jpath + + } else + Jpath = cdp->GetName(); + } // end of JMGCOL constructor /***********************************************************************/ @@ -432,7 +453,7 @@ JMGCOL::JMGCOL(JMGCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) { Tmgp = col1->Tmgp; Jpath = col1->Jpath; -//Mbuf = col1->Mbuf; + Sgfy = col1->Sgfy; } // end of JMGCOL copy constructor /***********************************************************************/ @@ -442,7 +463,7 @@ PSZ JMGCOL::GetJpath(PGLOBAL g, bool proj) { if (Jpath) { if (proj) { - char *p1, *p2, *projpath = PlugDup(g, Jpath); + char* p1, * p2, * projpath = PlugDup(g, Jpath); int i = 0; for (p1 = p2 = projpath; *p1; p1++) @@ -460,6 +481,9 @@ PSZ JMGCOL::GetJpath(PGLOBAL g, bool proj) } else *p2++ = *p1; + if (*(p2 - 1) == '.') + p2--; + *p2 = 0; return projpath; } else @@ -489,6 +513,7 @@ char *JMGCOL::Mini(PGLOBAL g, const bson_t *bson, bool b) switch (s[i]) { case ' ': if (ok) continue; + break; case '"': ok = !ok; default: diff --git a/storage/connect/tabjmg.h b/storage/connect/tabjmg.h index 5a637145cff..cf7cff83b68 100644 --- a/storage/connect/tabjmg.h +++ b/storage/connect/tabjmg.h @@ -1,7 +1,7 @@ /**************** tabjmg H Declares Source Code File (.H) **************/ -/* Name: tabjmg.h Version 1.1 */ +/* Name: tabjmg.h Version 1.3 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2017 - 2021 */ /* */ /* This file contains the MongoDB classes using the Java Driver. */ /***********************************************************************/ @@ -83,6 +83,7 @@ protected: PCSZ Coll_name; PCSZ Options; // The MongoDB options PCSZ Filter; // The filtering query + PCSZ Strfy; // The stringified columns PSZ Wrapname; // Java wrapper name int Fpos; // The current row index int N; // The current Rownum @@ -106,6 +107,7 @@ public: // Implementation virtual int GetAmType(void) {return Tmgp->GetAmType();} + virtual bool Stringify(void) { return Sgfy; } // Methods //virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); @@ -123,7 +125,7 @@ protected: // Members TDBJMG *Tmgp; // To the MGO table block char *Jpath; // The json path -//char *Mbuf; // The Mini buffer + bool Sgfy; // True if stringified }; // end of class JMGCOL /***********************************************************************/ diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index 737326dfcfe..76a1f742b7f 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -1,5 +1,5 @@ /************* tabjson C++ Program Source Code File (.CPP) *************/ -/* PROGRAM NAME: tabjson Version 1.8 */ +/* PROGRAM NAME: tabjson Version 1.9 */ /* (C) Copyright to the author Olivier BERTRAND 2014 - 2021 */ /* This program are the JSON class DB execution routines. */ /***********************************************************************/ @@ -58,6 +58,7 @@ USETEMP UseTemp(void); bool JsonAllPath(void); int GetDefaultDepth(void); char *GetJsonNull(void); +bool Stringified(PCSZ, char*); /***********************************************************************/ /* JSONColumns: construct the result blocks containing the description */ @@ -178,8 +179,8 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) lvl = GetIntegerTableOption(g, topt, "Depth", lvl); sep = GetStringTableOption(g, topt, "Separator", "."); strfy = GetStringTableOption(g, topt, "Stringify", NULL); - sz = GetIntegerTableOption(g, topt, "Jsize", 250); - limit = GetIntegerTableOption(g, topt, "Limit", 10); + sz = GetIntegerTableOption(g, topt, "Jsize", 1024); + limit = GetIntegerTableOption(g, topt, "Limit", 50); /*********************************************************************/ /* Open the input file. */ @@ -191,13 +192,19 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) #endif // ZIP_SUPPORT tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL); - if (!tdp->Fn && topt->http) + if (!tdp->Fn && topt->http) { tdp->Fn = GetStringTableOption(g, topt, "Subtype", NULL); + topt->subtype = NULL; + } // endif fn if (!(tdp->Database = SetPath(g, db))) return 0; - tdp->Objname = GetStringTableOption(g, topt, "Object", NULL); + if ((tdp->Objname = GetStringTableOption(g, topt, "Object", NULL))) { + if (*tdp->Objname == '$') tdp->Objname++; + if (*tdp->Objname == '.') tdp->Objname++; + } // endif Objname + tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0; tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2); tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL); @@ -222,8 +229,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) if (tdp->Uri) { #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT) - tdp->Collname = GetStringTableOption(g, topt, "Name", NULL); - tdp->Collname = GetStringTableOption(g, topt, "Tabname", tdp->Collname); + tdp->Collname = GetStringTableOption(g, topt, "Tabname", NULL); tdp->Schema = GetStringTableOption(g, topt, "Dbname", "test"); tdp->Options = (PSZ)GetStringTableOption(g, topt, "Colist", "all"); tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false); @@ -442,7 +448,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j) jcol.Type = TYPE_UNKNOWN; jcol.Len = jcol.Scale = 0; jcol.Cbn = true; - } else if (j < lvl && !(strfy && !stricmp(strfy, colname))) { + } else if (j < lvl && !Stringified(strfy, colname)) { if (!fmt[bf]) strcat(fmt, colname); @@ -512,7 +518,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j) } // endswitch Type } else if (lvl >= 0) { - if (strfy && !stricmp(strfy, colname)) { + if (Stringified(strfy, colname)) { if (!fmt[bf]) strcat(fmt, colname); @@ -633,10 +639,15 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { Schema = GetStringCatInfo(g, "DBname", Schema); Jmode = (JMODE)GetIntCatInfo("Jmode", MODE_OBJECT); - Objname = GetStringCatInfo(g, "Object", NULL); + + if ((Objname = GetStringCatInfo(g, "Object", NULL))) { + if (*Objname == '$') Objname++; + if (*Objname == '.') Objname++; + } // endif Objname + Xcol = GetStringCatInfo(g, "Expand", NULL); Pretty = GetIntCatInfo("Pretty", 2); - Limit = GetIntCatInfo("Limit", 10); + Limit = GetIntCatInfo("Limit", 50); Base = GetIntCatInfo("Base", 0) ? 1 : 0; Sep = *GetStringCatInfo(g, "Separator", "."); Accept = GetBoolCatInfo("Accept", false); @@ -647,7 +658,7 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Collname = GetStringCatInfo(g, "Name", (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); Collname = GetStringCatInfo(g, "Tabname", Collname); - Options = GetStringCatInfo(g, "Colist", NULL); + Options = GetStringCatInfo(g, "Colist", Xcol ? "all" : NULL); Filter = GetStringCatInfo(g, "Filter", NULL); Pipe = GetBoolCatInfo("Pipeline", false); Driver = GetStringCatInfo(g, "Driver", NULL); @@ -716,6 +727,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) #endif // !MONGO_SUPPORT } // endif Driver + Pretty = 4; // Not a file } else if (Zipped) { #if defined(ZIP_SUPPORT) if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) { @@ -761,7 +773,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) G->jump_level = 0; ((TDBJSN*)tdbp)->G = G; #endif // 0 - ((TDBJSN*)tdbp)->G = PlugInit(NULL, (size_t)Lrecl * (Pretty >= 0 ? 10 : 2)); + ((TDBJSN*)tdbp)->G = PlugInit(NULL, (size_t)Lrecl * (Pretty >= 0 ? 12 : 4)); } else { strcpy(g->Message, "LRECL is not defined"); return NULL; @@ -950,23 +962,29 @@ int TDBJSN::EstimatedLength(void) /***********************************************************************/ PJSON TDBJSN::FindRow(PGLOBAL g) { - char *p, *objpath; + char *p, *objpath = PlugDup(g, Objname); + char *sep = (char*)(Sep == ':' ? ":[" : ".["); + bool bp = false, b = false; PJSON jsp = Row; PJVAL val = NULL; - for (objpath = PlugDup(g, Objname); jsp && objpath; objpath = p) { - if ((p = strchr(objpath, Sep))) + for (; jsp && objpath; objpath = p, bp = b) { + if ((p = strpbrk(objpath + 1, sep))) { + b = (*p == '['); *p++ = 0; + } // endif p - if (*objpath != '[' && !IsNum(objpath)) { // objpass is a key + if (!bp && *objpath != '[' && !IsNum(objpath)) { // objpass is a key val = (jsp->GetType() == TYPE_JOB) ? jsp->GetObject()->GetKeyValue(objpath) : NULL; } else { - if (*objpath == '[') { - if (objpath[strlen(objpath) - 1] == ']') - objpath++; - else + if (bp || *objpath == '[') { + if (objpath[strlen(objpath) - 1] != ']') { + sprintf(g->Message, "Invalid Table path %s", Objname); return NULL; + } else if (!bp) + objpath++; + } // endif [ val = (jsp->GetType() == TYPE_JAR) ? @@ -976,6 +994,18 @@ PJSON TDBJSN::FindRow(PGLOBAL g) jsp = (val) ? val->GetJson() : NULL; } // endfor objpath + if (jsp && jsp->GetType() != TYPE_JOB) { + if (jsp->GetType() == TYPE_JAR) { + jsp = jsp->GetArray()->GetArrayValue(B); + + if (jsp->GetType() != TYPE_JOB) + jsp = NULL; + + } else + jsp = NULL; + + } // endif Type + return jsp; } // end of FindRow @@ -1144,25 +1174,28 @@ int TDBJSN::ReadDB(PGLOBAL g) { /***********************************************************************/ /* Make the top tree from the object path. */ /***********************************************************************/ -int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) +bool TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) { if (Objname) { if (!Val) { // Parse and allocate Objname item(s) - char *p; - char *objpath = PlugDup(g, Objname); + char *p, *objpath = PlugDup(g, Objname); + char *sep = (char*)(Sep == ':' ? ":[" : ".["); int i; + bool bp = false, b = false; PJOB objp; PJAR arp; PJVAL val = NULL; Top = NULL; - for (; objpath; objpath = p) { - if ((p = strchr(objpath, Sep))) + for (; objpath; objpath = p, bp = b) { + if ((p = strpbrk(objpath + 1, sep))) { + b = (*p == '['); *p++ = 0; + } // endif p - if (*objpath != '[' && !IsNum(objpath)) { + if (!bp && *objpath != '[' && !IsNum(objpath)) { objp = new(g) JOBJECT; if (!Top) @@ -1174,15 +1207,15 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) val = new(g) JVALUE; objp->SetKeyValue(g, val, objpath); } else { - if (*objpath == '[') { + if (bp || *objpath == '[') { // Old style if (objpath[strlen(objpath) - 1] != ']') { sprintf(g->Message, "Invalid Table path %s", Objname); - return RC_FX; - } else + return true; + } else if (!bp) objpath++; - } // endif objpath + } // endif bp arp = new(g) JARRAY; @@ -1207,7 +1240,7 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) } else Top = jsp; - return RC_OK; + return false; } // end of MakeTopTree /***********************************************************************/ @@ -1277,6 +1310,7 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) Xpd = false; Parsed = false; Warned = false; + Sgfy = false; } // end of JSONCOL constructor /***********************************************************************/ @@ -1296,6 +1330,7 @@ JSONCOL::JSONCOL(JSONCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp) Xpd = col1->Xpd; Parsed = col1->Parsed; Warned = col1->Warned; + Sgfy = col1->Sgfy; } // end of JSONCOL copy constructor /***********************************************************************/ @@ -1535,6 +1570,10 @@ bool JSONCOL::ParseJpath(PGLOBAL g) // Analyse intermediate array processing if (SetArrayOptions(g, p, i, Nodes[i - 1].Key)) return true; + else if (Xpd && Tjp->Mode == MODE_DELETE) { + strcpy(g->Message, "Cannot delete expanded columns"); + return true; + } // endif Xpd } else if (*p == '*') { // Return JSON @@ -1568,8 +1607,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) if (*p1 == '$') p1++; if (*p1 == '.') p1++; mgopath = PlugDup(g, p1); - } else + } else { + Sgfy = true; return NULL; + } // endif for (p1 = p2 = mgopath; *p1; p1++) { @@ -1608,6 +1649,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) case '*': if (*(p2 - 1) == '.' && !*(p1 + 1)) { p2--; // Suppress last :* + Sgfy = true; break; } // endif p2 /* falls through */ @@ -1616,6 +1658,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) break; } // endswitch p1; } + + if (*(p2 - 1) == '.') + p2--; + *p2 = 0; return mgopath; } else @@ -1744,10 +1790,16 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL jvp) break; case TYPE_DATE: if (jvp->GetValType() == TYPE_STRG) { - if (!((DTVAL*)vp)->IsFormatted()) - ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0); + PSZ dat = jvp->GetString(g); + + if (!IsNum(dat)) { + if (!((DTVAL*)vp)->IsFormatted()) + ((DTVAL*)vp)->SetFormat(g, "YYYY-MM-DDThh:mm:ssZ", 20, 0); + + vp->SetValue_psz(dat); + } else + vp->SetValue(atoi(dat)); - vp->SetValue_psz(jvp->GetString(g)); } else vp->SetValue(jvp->GetInteger()); @@ -2126,10 +2178,14 @@ void JSONCOL::WriteColumn(PGLOBAL g) if (Nodes[Nod-1].Op == OP_XX) { s = Value->GetCharValue(); - if (!(jsp = ParseJson(G, s, strlen(s)))) { - strcpy(g->Message, s); - throw 666; - } // endif jsp + if (s && *s) { + if (!(jsp = ParseJson(G, s, strlen(s)))) { + strcpy(g->Message, s); + throw 666; + } // endif jsp + + } else + jsp = NULL; if (arp) { if (Nod > 1 && Nodes[Nod-2].Op == OP_EQ) @@ -2558,8 +2614,8 @@ int TDBJSON::WriteDB(PGLOBAL g) if (Mode == MODE_INSERT) { Doc->AddArrayValue(g, vp); Row = new(g) JOBJECT; - } else if (Doc->SetArrayValue(g, vp, Fpos)) - return RC_FX; + } else + Doc->SetArrayValue(g, vp, Fpos); } else if (Jmode == MODE_ARRAY) { PJVAL vp = new(g) JVALUE(Row); @@ -2567,15 +2623,15 @@ int TDBJSON::WriteDB(PGLOBAL g) if (Mode == MODE_INSERT) { Doc->AddArrayValue(g, vp); Row = new(g) JARRAY; - } else if (Doc->SetArrayValue(g, vp, Fpos)) - return RC_FX; + } else + Doc->SetArrayValue(g, vp, Fpos); } else { // if (Jmode == MODE_VALUE) if (Mode == MODE_INSERT) { Doc->AddArrayValue(g, (PJVAL)Row); Row = new(g) JVALUE; - } else if (Doc->SetArrayValue(g, (PJVAL)Row, Fpos)) - return RC_FX; + } else + Doc->SetArrayValue(g, (PJVAL)Row, Fpos); } // endif Jmode diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h index 1062928d410..623e5b6d509 100644 --- a/storage/connect/tabjson.h +++ b/storage/connect/tabjson.h @@ -170,7 +170,7 @@ public: protected: PJSON FindRow(PGLOBAL g); - int MakeTopTree(PGLOBAL g, PJSON jsp); + bool MakeTopTree(PGLOBAL g, PJSON jsp); // Members PGLOBAL G; // Support of parse memory @@ -216,7 +216,8 @@ public: JSONCOL(JSONCOL *colp, PTDB tdbp); // Constructor used in copy process // Implementation - virtual int GetAmType(void) {return Tjp->GetAmType();} + virtual int GetAmType(void) {return Tjp->GetAmType();} + virtual bool Stringify(void) { return Sgfy; } // Methods virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); @@ -251,6 +252,7 @@ public: bool Xpd; // True for expandable column bool Parsed; // True when parsed bool Warned; // True when warning issued + bool Sgfy; // True if stringified }; // end of class JSONCOL /* -------------------------- TDBJSON class -------------------------- */ diff --git a/storage/connect/tabmac.cpp b/storage/connect/tabmac.cpp index 8260ab65391..ed161ac4be1 100644 --- a/storage/connect/tabmac.cpp +++ b/storage/connect/tabmac.cpp @@ -3,12 +3,12 @@ /* From the article and sample code by Khalid Shaikh. */ /* TABMAC: virtual table to get the list of MAC addresses. */ /***********************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) #include "my_global.h" //#include <iphlpapi.h> -#else // !__WIN__ +#else // !_WIN32 #error This is a WINDOWS only table type -#endif // !__WIN__ +#endif // !_WIN32 #include "global.h" #include "plgdbsem.h" //#include "catalog.h" diff --git a/storage/connect/tabmac.h b/storage/connect/tabmac.h index 47565bb2541..68135edb95f 100644 --- a/storage/connect/tabmac.h +++ b/storage/connect/tabmac.h @@ -1,11 +1,11 @@ // TABMAC.H Olivier Bertrand 2011-2012 // MAC: virtual table to Get Mac Addresses via GetAdaptersInfo -#if defined(__WIN__) +#if defined(_WIN32) #include <windows.h> #include <iphlpapi.h> -#else // !__WIN__ +#else // !_WIN32 #error This is a WINDOWS only table TYPE -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Definitions. */ diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp index 3da72dcc29c..d260149514d 100644 --- a/storage/connect/tabmul.cpp +++ b/storage/connect/tabmul.cpp @@ -37,7 +37,7 @@ /* Include relevant section of system dependant header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <stdlib.h> #include <stdio.h> #if defined(__BORLANDC__) @@ -166,11 +166,11 @@ bool TDBMUL::InitFileNames(PGLOBAL g) while (true) if ((rc = dirp->ReadDB(g)) == RC_OK) { -#if defined(__WIN__) +#if defined(_WIN32) strcat(strcpy(filename, dirp->Drive), dirp->Direc); -#else // !__WIN__ +#else // !_WIN32 strcpy(filename, dirp->Direc); -#endif // !__WIN__ +#endif // !_WIN32 strcat(strcat(filename, dirp->Fname), dirp->Ftype); pfn[n++] = PlugDup(g, filename); } else @@ -199,7 +199,7 @@ bool TDBMUL::InitFileNames(PGLOBAL g) p = filename + strlen(filename) - 1; -#if !defined(__WIN__) +#if !defined(_WIN32) // Data files can be imported from Windows (having CRLF) if (*p == '\n' || *p == '\r') { // is this enough for Unix ??? @@ -566,11 +566,11 @@ bool TDBMSD::InitFileNames(PGLOBAL g) while (true) if ((rc = dirp->ReadDB(g)) == RC_OK) { -#if defined(__WIN__) +#if defined(_WIN32) strcat(strcpy(filename, dirp->Drive), dirp->Direc); -#else // !__WIN__ +#else // !_WIN32 strcpy(filename, dirp->Direc); -#endif // !__WIN__ +#endif // !_WIN32 strcat(strcat(filename, dirp->Fname), dirp->Ftype); pfn[n++] = PlugDup(g, filename); } else @@ -634,18 +634,18 @@ PTDB DIRDEF::GetTable(PGLOBAL g, MODE) void TDBDIR::Init(void) { iFile = 0; -#if defined(__WIN__) +#if defined(_WIN32) Dvalp = NULL; memset(&FileData, 0, sizeof(_finddata_t)); hSearch = INVALID_HANDLE_VALUE; *Drive = '\0'; -#else // !__WIN__ +#else // !_WIN32 memset(&Fileinfo, 0, sizeof(struct stat)); Entry = NULL; Dir = NULL; Done = false; *Pattern = '\0'; -#endif // !__WIN__ +#endif // !_WIN32 *Fpath = '\0'; *Direc = '\0'; *Fname = '\0'; @@ -674,7 +674,7 @@ char* TDBDIR::Path(PGLOBAL g) (void) PlgGetCatalog(g); // XXX Should be removed? PTABDEF defp = (PTABDEF)To_Def; -#if defined(__WIN__) +#if defined(_WIN32) if (!*Drive) { PlugSetPath(Fpath, To_File, defp ? defp->GetPath() : NULL); _splitpath(Fpath, Drive, Direc, Fname, Ftype); @@ -682,7 +682,7 @@ char* TDBDIR::Path(PGLOBAL g) _makepath(Fpath, Drive, Direc, Fname, Ftype); // Usefull for TDBSDR return Fpath; -#else // !__WIN__ +#else // !_WIN32 if (!Done) { PlugSetPath(Fpath, To_File, defp ? defp->GetPath() : NULL); _splitpath(Fpath, NULL, Direc, Fname, Ftype); @@ -691,7 +691,7 @@ char* TDBDIR::Path(PGLOBAL g) } // endif Done return Pattern; -#endif // !__WIN__ +#endif // !_WIN32 } // end of Path /***********************************************************************/ @@ -709,7 +709,7 @@ int TDBDIR::GetMaxSize(PGLOBAL g) { if (MaxSize < 0) { int n = -1; -#if defined(__WIN__) +#if defined(_WIN32) int rc; // Start searching files in the target directory. hSearch = FindFirstFile(Path(g), &FileData); @@ -750,7 +750,7 @@ int TDBDIR::GetMaxSize(PGLOBAL g) // Close the search handle. FindClose(hSearch); -#else // !__WIN__ +#else // !_WIN32 Path(g); // Start searching files in the target directory. @@ -774,7 +774,7 @@ int TDBDIR::GetMaxSize(PGLOBAL g) // Close the DIR handle. closedir(Dir); -#endif // !__WIN__ +#endif // !_WIN32 MaxSize = n; } // endif MaxSize @@ -800,10 +800,10 @@ bool TDBDIR::OpenDB(PGLOBAL g) } // endif use Use = USE_OPEN; -#if !defined(__WIN__) +#if !defined(_WIN32) Path(g); // Be sure it is done Dir = NULL; // For ReadDB -#endif // !__WIN__ +#endif // !_WIN32 return false; } // end of OpenDB @@ -814,7 +814,7 @@ int TDBDIR::ReadDB(PGLOBAL g) { int rc = RC_OK; -#if defined(__WIN__) +#if defined(_WIN32) do { if (hSearch == INVALID_HANDLE_VALUE) { /*****************************************************************/ @@ -877,7 +877,7 @@ int TDBDIR::ReadDB(PGLOBAL g) rc = RC_EF; } // endif Entry -#endif // !__WIN__ +#endif // !_WIN32 return rc; } // end of ReadDB @@ -905,17 +905,17 @@ int TDBDIR::DeleteDB(PGLOBAL g, int) /***********************************************************************/ void TDBDIR::CloseDB(PGLOBAL) { -#if defined(__WIN__) +#if defined(_WIN32) // Close the search handle. FindClose(hSearch); hSearch = INVALID_HANDLE_VALUE; -#else // !__WIN__ +#else // !_WIN32 // Close the DIR handle if (Dir) { closedir(Dir); Dir = NULL; } // endif dir -#endif // !__WIN__ +#endif // !_WIN32 iFile = 0; } // end of CloseDB @@ -950,7 +950,7 @@ DIRCOL::DIRCOL(DIRCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp) N = col1->N; } // end of DIRCOL copy constructor -#if defined(__WIN__) +#if defined(_WIN32) /***********************************************************************/ /* Retrieve time information from FileData. */ /***********************************************************************/ @@ -977,7 +977,7 @@ void DIRCOL::SetTimeValue(PGLOBAL g, FILETIME& ftime) Value->Reset(); } // end of SetTimeValue -#endif // __WIN__ +#endif // _WIN32 /***********************************************************************/ /* ReadColumn: what this routine does is to access the information */ @@ -993,19 +993,19 @@ void DIRCOL::ReadColumn(PGLOBAL g) /* Retrieve the information corresponding to the column number. */ /*********************************************************************/ switch (N) { -#if defined(__WIN__) +#if defined(_WIN32) case 0: Value->SetValue_psz(Tdbp->Drive); break; -#endif // __WIN__ +#endif // _WIN32 case 1: Value->SetValue_psz(Tdbp->Direc); break; case 2: Value->SetValue_psz(Tdbp->Fname); break; case 3: Value->SetValue_psz(Tdbp->Ftype); break; -#if defined(__WIN__) +#if defined(_WIN32) case 4: Value->SetValue((int)Tdbp->FileData.dwFileAttributes); break; case 5: Value->SetValue((int)Tdbp->FileData.nFileSizeLow); break; case 6: SetTimeValue(g, Tdbp->FileData.ftLastWriteTime); break; case 7: SetTimeValue(g, Tdbp->FileData.ftCreationTime); break; case 8: SetTimeValue(g, Tdbp->FileData.ftLastAccessTime); break; -#else // !__WIN__ +#else // !_WIN32 case 4: Value->SetValue((int)Tdbp->Fileinfo.st_mode); break; case 5: Value->SetValue((int)Tdbp->Fileinfo.st_size); break; case 6: Value->SetValue((int)Tdbp->Fileinfo.st_mtime); break; @@ -1013,7 +1013,7 @@ void DIRCOL::ReadColumn(PGLOBAL g) case 8: Value->SetValue((int)Tdbp->Fileinfo.st_atime); break; case 9: Value->SetValue((int)Tdbp->Fileinfo.st_uid); break; case 10: Value->SetValue((int)Tdbp->Fileinfo.st_gid); break; -#endif // !__WIN__ +#endif // !_WIN32 default: sprintf(g->Message, MSG(INV_DIRCOL_OFST), N); throw GetAmType(); @@ -1045,7 +1045,7 @@ int TDBSDR::FindInDir(PGLOBAL g) size_t m = strlen(Direc); // Start searching files in the target directory. -#if defined(__WIN__) +#if defined(_WIN32) int rc; HANDLE h; @@ -1156,7 +1156,7 @@ int TDBSDR::FindInDir(PGLOBAL g) // Close the search handle. FindClose(h); -#else // !__WIN__ +#else // !_WIN32 int k; DIR *dir = opendir(Direc); @@ -1190,7 +1190,7 @@ int TDBSDR::FindInDir(PGLOBAL g) // Close the DIR handle. closedir(dir); -#endif // !__WIN__ +#endif // !_WIN32 return n; } // end of FindInDir @@ -1206,13 +1206,13 @@ bool TDBSDR::OpenDB(PGLOBAL g) Sub = (PSUBDIR)PlugSubAlloc(g, NULL, sizeof(SUBDIR)); Sub->Next = NULL; Sub->Prev = NULL; -#if defined(__WIN__) +#if defined(_WIN32) Sub->H = INVALID_HANDLE_VALUE; Sub->Len = strlen(Direc); -#else // !__WIN__ +#else // !_WIN32 Sub->D = NULL; Sub->Len = 0; -#endif // !__WIN__ +#endif // !_WIN32 } // endif To_Sub return TDBDIR::OpenDB(g); @@ -1225,7 +1225,7 @@ int TDBSDR::ReadDB(PGLOBAL g) { int rc; -#if defined(__WIN__) +#if defined(_WIN32) again: rc = TDBDIR::ReadDB(g); @@ -1281,7 +1281,7 @@ int TDBSDR::ReadDB(PGLOBAL g) } // endif H } // endif rc -#else // !__WIN__ +#else // !_WIN32 rc = RC_NF; again: @@ -1339,7 +1339,7 @@ int TDBSDR::ReadDB(PGLOBAL g) } // endif Entry -#endif // !__WIN__ +#endif // !_WIN32 return rc; } // end of ReadDB diff --git a/storage/connect/tabmul.h b/storage/connect/tabmul.h index 8a95a772c41..a9d3f88cc44 100644 --- a/storage/connect/tabmul.h +++ b/storage/connect/tabmul.h @@ -6,14 +6,14 @@ /* */ /* This file contains the TDBMUL and TDBDIR classes declares. */ /***********************************************************************/ -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> -#else // !__WIN__ +#else // !_WIN32 #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <dirent.h> -#endif // !__WIN__ +#endif // !_WIN32 //#include "osutil.h" #include "block.h" @@ -160,18 +160,18 @@ public: // Members PSZ To_File; // Points to file search pathname int iFile; // Index of currently retrieved file -#if defined(__WIN__) +#if defined(_WIN32) PVAL Dvalp; // Used to retrieve file date values WIN32_FIND_DATA FileData; // Find data structure HANDLE hSearch; // Search handle char Drive[_MAX_DRIVE]; // Drive name -#else // !__WIN__ +#else // !_WIN32 struct stat Fileinfo; // File info structure struct dirent *Entry; // Point to directory entry structure DIR *Dir; // To searched directory structure bool Done; // true when _splipath is done char Pattern[_MAX_FNAME+_MAX_EXT]; -#endif // !__WIN__ +#endif // !_WIN32 char Fpath[_MAX_PATH]; // Absolute file search pattern char Direc[_MAX_DIR]; // Search path char Fname[_MAX_FNAME]; // File name @@ -207,11 +207,11 @@ class TDBSDR : public TDBDIR { typedef struct _Sub_Dir { struct _Sub_Dir *Next; struct _Sub_Dir *Prev; -#if defined(__WIN__) +#if defined(_WIN32) HANDLE H; // Search handle -#else // !__WIN__ +#else // !_WIN32 DIR *D; -#endif // !__WIN__ +#endif // !_WIN32 size_t Len; // Initial directory name length } SUBDIR, *PSUBDIR; @@ -238,9 +238,9 @@ class DIRCOL : public COLBLK { protected: // Default constructor not to be used DIRCOL(void) {} -#if defined(__WIN__) +#if defined(_WIN32) void SetTimeValue(PGLOBAL g, FILETIME& ftime); -#endif // __WIN__ +#endif // _WIN32 // Members PTDBDIR Tdbp; // To DIR table diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index c3197d8b373..b14b0b14231 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -35,9 +35,9 @@ #include "my_global.h" #include "sql_class.h" #include "sql_servers.h" -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 //#include <fnmatch.h> //#include <errno.h> #include <stdlib.h> @@ -46,7 +46,7 @@ #include "osutil.h" //#include <io.h> //#include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ diff --git a/storage/connect/taboccur.cpp b/storage/connect/taboccur.cpp index 8f5c4e0e732..718b8a066d1 100644 --- a/storage/connect/taboccur.cpp +++ b/storage/connect/taboccur.cpp @@ -1,7 +1,7 @@ /************ TabOccur CPP Declares Source Code File (.CPP) ************/ /* Name: TABOCCUR.CPP Version 1.2 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2013 - 2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2013 - 2021 */ /* */ /* OCCUR: Table that provides a view of a source table where the */ /* contain of several columns of the source table is placed in only */ @@ -13,7 +13,7 @@ /***********************************************************************/ #include "my_global.h" #include "table.h" // MySQL table definitions -#if defined(__WIN__) +#if defined(_WIN32) #include <stdlib.h> #include <stdio.h> #if defined(__BORLANDC__) @@ -49,11 +49,13 @@ #include "tabmysql.h" #include "ha_connect.h" +int PrepareColist(char *colist); + /***********************************************************************/ /* Prepare and count columns in the column list. */ /***********************************************************************/ -static int PrepareColist(char *colist) - { +int PrepareColist(char *colist) +{ char *p, *pn; int n = 0; @@ -71,7 +73,7 @@ static int PrepareColist(char *colist) } // endif p return n; - } // end of PrepareColist +} // end of PrepareColist /************************************************************************/ /* OcrColumns: constructs the result blocks containing all the columns */ @@ -79,7 +81,7 @@ static int PrepareColist(char *colist) /************************************************************************/ bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col, const char *ocr, const char *rank) - { +{ char *pn, *colist; int i, k, m, n = 0, c = 0, j = qrp->Nblin; bool rk, b = false; @@ -168,7 +170,7 @@ bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col, /**********************************************************************/ qrp->Nblin = j; return false; - } // end of OcrColumns +} // end of OcrColumns /************************************************************************/ /* OcrSrcCols: constructs the result blocks containing all the columns */ @@ -176,7 +178,7 @@ bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col, /************************************************************************/ bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col, const char *ocr, const char *rank) - { +{ char *pn, *colist; int i, k, m, n = 0, c = 0; bool rk, b = false; @@ -249,7 +251,7 @@ bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col, /**********************************************************************/ qrp->Nblin = i; return false; - } // end of OcrSrcCols +} // end of OcrSrcCols /* -------------- Implementation of the OCCUR classes ---------------- */ @@ -257,24 +259,24 @@ bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col, /* DefineAM: define specific AM block values from OCCUR table. */ /***********************************************************************/ bool OCCURDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) - { +{ Rcol = GetStringCatInfo(g, "RankCol", ""); Colist = GetStringCatInfo(g, "Colist", ""); Xcol = GetStringCatInfo(g, "OccurCol", Colist); return PRXDEF::DefineAM(g, am, poff); - } // end of DefineAM +} // end of DefineAM /***********************************************************************/ /* GetTable: makes a new TDB of the proper type. */ /***********************************************************************/ PTDB OCCURDEF::GetTable(PGLOBAL g, MODE) - { +{ if (Catfunc != FNC_COL) return new(g) TDBOCCUR(this); else return new(g) TDBTBC(this); - } // end of GetTable +} // end of GetTable /* ------------------------------------------------------------------- */ @@ -282,7 +284,7 @@ PTDB OCCURDEF::GetTable(PGLOBAL g, MODE) /* Implementation of the TDBOCCUR class. */ /***********************************************************************/ TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp) - { +{ //Tdbp = NULL; // Source table (in TDBPRX) Tabname = tdp->Tablep->GetName(); // Name of source table Colist = tdp->Colist; // List of source columns @@ -294,13 +296,13 @@ TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp) N = 0; // The current table index M = 0; // The occurrence rank RowFlag = 0; // 0: Ok, 1: Same, 2: Skip - } // end of TDBOCCUR constructor +} // end of TDBOCCUR constructor /***********************************************************************/ /* Allocate OCCUR/SRC column description block. */ /***********************************************************************/ PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) - { +{ PCOL colp = NULL; if (!stricmp(cdp->GetName(), Rcolumn)) { @@ -321,13 +323,13 @@ PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) } // endif cprec return colp; - } // end of MakeCol +} // end of MakeCol /***********************************************************************/ /* Initializes the table. */ /***********************************************************************/ bool TDBOCCUR::InitTable(PGLOBAL g) - { +{ if (!Tdbp) // Get the table description block of this table if (!(Tdbp = GetSubTable(g, ((POCCURDEF)To_Def)->Tablep, TRUE))) @@ -338,13 +340,13 @@ bool TDBOCCUR::InitTable(PGLOBAL g) return TRUE; return FALSE; - } // end of InitTable +} // end of InitTable /***********************************************************************/ /* Allocate OCCUR column description block. */ /***********************************************************************/ bool TDBOCCUR::MakeColumnList(PGLOBAL g) - { +{ char *pn; int i; PCOL colp; @@ -371,13 +373,13 @@ bool TDBOCCUR::MakeColumnList(PGLOBAL g) } // endfor i return false; - } // end of MakeColumnList +} // end of MakeColumnList /***********************************************************************/ /* Allocate OCCUR column description block for a view. */ /***********************************************************************/ bool TDBOCCUR::ViewColumnList(PGLOBAL g) - { +{ char *pn; int i; PCOL colp, cp; @@ -412,13 +414,13 @@ bool TDBOCCUR::ViewColumnList(PGLOBAL g) } // endif Col return false; - } // end of ViewColumnList +} // end of ViewColumnList /***********************************************************************/ /* OCCUR GetMaxSize: returns the maximum number of rows in the table. */ /***********************************************************************/ int TDBOCCUR::GetMaxSize(PGLOBAL g) - { +{ if (MaxSize < 0) { if (!(Tdbp = GetSubTable(g, ((POCCURDEF)To_Def)->Tablep, TRUE))) return 0; @@ -427,22 +429,22 @@ int TDBOCCUR::GetMaxSize(PGLOBAL g) } // endif MaxSize return MaxSize; - } // end of GetMaxSize +} // end of GetMaxSize /***********************************************************************/ /* In this sample, ROWID will be the (virtual) row number, */ /* while ROWNUM will be the occurrence rank in the multiple column. */ /***********************************************************************/ int TDBOCCUR::RowNumber(PGLOBAL, bool b) - { +{ return (b) ? M : N; - } // end of RowNumber +} // end of RowNumber /***********************************************************************/ /* OCCUR Access Method opening routine. */ /***********************************************************************/ bool TDBOCCUR::OpenDB(PGLOBAL g) - { +{ if (Use == USE_OPEN) { /*******************************************************************/ /* Table already open, just replace it at its beginning. */ @@ -491,13 +493,13 @@ bool TDBOCCUR::OpenDB(PGLOBAL g) Use = USE_OPEN; return ViewColumnList(g); - } // end of OpenDB +} // end of OpenDB /***********************************************************************/ /* Data Base read routine for OCCUR access method. */ /***********************************************************************/ int TDBOCCUR::ReadDB(PGLOBAL g) - { +{ int rc = RC_OK; /*********************************************************************/ @@ -518,7 +520,7 @@ int TDBOCCUR::ReadDB(PGLOBAL g) N++; return rc; - } // end of ReadDB +} // end of ReadDB // ------------------------ OCCURCOL functions ---------------------------- @@ -527,17 +529,17 @@ int TDBOCCUR::ReadDB(PGLOBAL g) /***********************************************************************/ OCCURCOL::OCCURCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n) : COLBLK(cdp, tdbp, n) - { +{ // Set additional OCCUR access method information for column. I = 0; - } // end of OCCURCOL constructor +} // end of OCCURCOL constructor /***********************************************************************/ /* ReadColumn: what this routine does is to access the columns of */ /* list, extract their value and convert it to buffer type. */ /***********************************************************************/ void OCCURCOL::ReadColumn(PGLOBAL g) - { +{ PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb; PCOL *col = tdbp->Col; @@ -559,7 +561,7 @@ void OCCURCOL::ReadColumn(PGLOBAL g) // Set the OCCUR column value from the Ith source column value Value->SetValue_pval(col[I++]->GetValue()); tdbp->RowFlag = 1; - } // end of ReadColumn +} // end of ReadColumn // ------------------------ RANKCOL functions --------------------------- @@ -569,7 +571,7 @@ void OCCURCOL::ReadColumn(PGLOBAL g) /* list, extract its name and set to it the rank column value. */ /***********************************************************************/ void RANKCOL::ReadColumn(PGLOBAL) - { +{ PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb; PCOL *col = tdbp->Col; @@ -584,4 +586,4 @@ void RANKCOL::ReadColumn(PGLOBAL) } // endelse - } // end of ReadColumn +} // end of ReadColumn diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index 77d82556d8c..4e8b4417a33 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -36,7 +36,7 @@ /***********************************************************************/ #include "my_global.h" #include "sql_class.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #if defined(__BORLANDC__) diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp index 25fe798f2ac..5ba4b511528 100644 --- a/storage/connect/tabpivot.cpp +++ b/storage/connect/tabpivot.cpp @@ -17,7 +17,7 @@ /***********************************************************************/ #include "my_global.h" #include "table.h" // MySQL table definitions -#if defined(__WIN__) +#if defined(_WIN32) #if defined(__BORLANDC__) #define __MFC_COMPAT__ // To define min/max as macro #endif diff --git a/storage/connect/tabrest.cpp b/storage/connect/tabrest.cpp index 6679ccd55b0..c66d8d76f3d 100644 --- a/storage/connect/tabrest.cpp +++ b/storage/connect/tabrest.cpp @@ -1,5 +1,5 @@ /************** tabrest C++ Program Source Code File (.CPP) ************/ -/* PROGRAM NAME: tabrest Version 2.0 */ +/* PROGRAM NAME: tabrest Version 2.1 */ /* (C) Copyright to the author Olivier BERTRAND 2018 - 2021 */ /* This program is the REST Web API support for MariaDB. */ /* The way Connect handles NOSQL data returned by REST queries is */ @@ -13,10 +13,10 @@ #include <my_global.h> // All MariaDB stuff #include <mysqld.h> #include <sql_error.h> -#if !defined(__WIN__) && !defined(_WINDOWS) +#if !defined(_WIN32) && !defined(_WINDOWS) #include <sys/types.h> #include <sys/wait.h> -#endif // !__WIN__ && !_WINDOWS +#endif // !_WIN32 && !_WINDOWS /***********************************************************************/ /* Include application header files: */ @@ -37,7 +37,7 @@ #include "tabrest.h" #if defined(connect_EXPORTS) -#define PUSH_WARNING(M) push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0, M) +#define PUSH_WARNING(M) push_warning(current_thd, Sql_condition::WARN_LEVEL_NOTE, 0, M) #else #define PUSH_WARNING(M) htrc(M) #endif @@ -65,9 +65,9 @@ int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename) my_snprintf(buf, sizeof(buf)-1, "%s/%s", Http, Uri); } else - my_snprintf(buf, sizeof(buf)-1, "%s", Http); + my_snprintf(buf, sizeof(buf)-1, "%s", Http); -#if defined(__WIN__) +#if defined(_WIN32) char cmd[1024]; STARTUPINFO si; PROCESS_INFORMATION pi; @@ -90,7 +90,7 @@ int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename) sprintf(g->Message, "CreateProcess curl failed (%d)", GetLastError()); rc = 1; } // endif CreateProcess -#else // !__WIN__ +#else // !_WIN32 char fn[600]; pid_t pID; @@ -130,7 +130,7 @@ int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename) // Parent process wait(NULL); // Wait for the child to terminate } // endif pID -#endif // !__WIN__ +#endif // !_WIN32 return rc; } // end of Xcurl @@ -147,7 +147,7 @@ XGETREST GetRestFunction(PGLOBAL g) if (trace(515)) htrc("Looking for GetRest library\n"); -#if defined(__WIN__) || defined(_WINDOWS) +#if defined(_WIN32) || defined(_WINDOWS) HANDLE Hdll; const char* soname = "GetRest.dll"; // Module name @@ -176,7 +176,7 @@ XGETREST GetRestFunction(PGLOBAL g) FreeLibrary((HMODULE)Hdll); return NULL; } // endif getRestFnc -#else // !__WIN__ +#else // !_WIN32 void* Hso; const char* error = NULL; const char* soname = "GetRest.so"; // Module name @@ -195,7 +195,7 @@ XGETREST GetRestFunction(PGLOBAL g) dlclose(Hso); return NULL; } // endif getdef -#endif // !__WIN__ +#endif // !_WIN32 #else // REST_SOURCE getRestFnc = restGetFile; #endif // REST_SOURCE diff --git a/storage/connect/tabrest.h b/storage/connect/tabrest.h index 9cf2d10a6b8..9066a89b306 100644 --- a/storage/connect/tabrest.h +++ b/storage/connect/tabrest.h @@ -5,12 +5,12 @@ /***********************************************************************/ #pragma once -#if defined(__WIN__) +#if defined(_WIN32) static PCSZ slash = "\\"; -#else // !__WIN__ +#else // !_WIN32 static PCSZ slash = "/"; #define stricmp strcasecmp -#endif // !__WIN__ +#endif // !_WIN32 typedef int(__stdcall* XGETREST) (char*, bool, PCSZ, PCSZ, PCSZ); diff --git a/storage/connect/tabsys.cpp b/storage/connect/tabsys.cpp index f73a2b6578d..9a8e4a9c562 100644 --- a/storage/connect/tabsys.cpp +++ b/storage/connect/tabsys.cpp @@ -12,12 +12,12 @@ /* Include relevant sections of the System header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #if defined(__BORLANDC__) #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <errno.h> #include <unistd.h> @@ -25,7 +25,7 @@ #include <io.h> #endif // !UNIX #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include application header files: */ @@ -36,9 +36,9 @@ #include "global.h" #include "plgdbsem.h" #include "reldef.h" -#if !defined(__WIN__) +#if !defined(_WIN32) #include "osutil.h" -#endif // !__WIN__ +#endif // !_WIN32 #include "filamtxt.h" #include "tabdos.h" #include "tabsys.h" @@ -48,10 +48,10 @@ #define CSZ 36 // Column section name length #define CDZ 256 // Column definition length -#if !defined(__WIN__) +#if !defined(_WIN32) #define GetPrivateProfileSectionNames(S,L,I) \ GetPrivateProfileString(NULL,NULL,"",S,L,I) -#endif // !__WIN__ +#endif // !_WIN32 /* -------------- Implementation of the INI classes ------------------ */ @@ -123,7 +123,7 @@ bool INIDEF::DeleteTableFile(PGLOBAL g) // Delete the INI table file if not protected if (!IsReadOnly()) { PlugSetPath(filename, Fn, GetPath()); -#if defined(__WIN__) +#if defined(_WIN32) rc = !DeleteFile(filename); #else // UNIX rc = remove(filename); @@ -345,9 +345,9 @@ int TDBINI::DeleteDB(PGLOBAL g, int irc) /***********************************************************************/ void TDBINI::CloseDB(PGLOBAL) { -#if !defined(__WIN__) +#if !defined(_WIN32) PROFILE_Close(Ifile); -#endif // !__WIN__ +#endif // !_WIN32 } // end of CloseDB // ------------------------ INICOL functions ---------------------------- diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp index 1150824464f..b6277088bac 100644 --- a/storage/connect/tabtbl.cpp +++ b/storage/connect/tabtbl.cpp @@ -36,7 +36,7 @@ //#include "sql_base.h" #include "my_global.h" #include "table.h" // MySQL table definitions -#if defined(__WIN__) +#if defined(_WIN32) #include <stdlib.h> #include <stdio.h> #if defined(__BORLANDC__) @@ -71,15 +71,15 @@ #include "tabmysql.h" #include "ha_connect.h" -#if defined(__WIN__) +#if defined(_WIN32) #if defined(__BORLANDC__) #define SYSEXIT void _USERENTRY #else #define SYSEXIT void #endif -#else // !__WIN__ +#else // !_WIN32 #define SYSEXIT void * -#endif // !__WIN__ +#endif // !_WIN32 extern pthread_mutex_t tblmut; diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp index 705f567f464..941073b35e6 100644 --- a/storage/connect/tabutil.cpp +++ b/storage/connect/tabutil.cpp @@ -14,7 +14,7 @@ #include "sql_class.h" #include "table.h" #include "field.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <stdlib.h> #include <stdio.h> #if defined(__BORLANDC__) diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp index 0ed466f6ffb..9cf5f41d1fe 100644 --- a/storage/connect/tabvct.cpp +++ b/storage/connect/tabvct.cpp @@ -35,7 +35,7 @@ /* Include relevant MariaDB header file. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #if defined(__BORLANDC__) @@ -149,7 +149,7 @@ bool VCTDEF::Erase(char *filename) for (i = 1, cdp = To_Cols; cdp; i++, cdp = cdp->GetNext()) { sprintf(filename, fpat, i); -//#if defined(__WIN__) +//#if defined(_WIN32) // rc |= !DeleteFile(filename); //#else // UNIX rc |= remove(filename); @@ -178,7 +178,7 @@ bool VCTDEF::Erase(char *filename) int VCTDEF::MakeFnPattern(char *fpat) { char pat[16]; -#if defined(__WIN__) +#if defined(_WIN32) char drive[_MAX_DRIVE]; #else char *drive = NULL; diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp index 8a8e1bcbcb6..a6aab7d2563 100644 --- a/storage/connect/tabwmi.cpp +++ b/storage/connect/tabwmi.cpp @@ -2,9 +2,9 @@ /* TABWMI: Author Olivier Bertrand -- PlugDB -- 2012 - 2017 */ /* TABWMI: Virtual table to get WMI information. */ /***********************************************************************/ -#if !defined(__WIN__) +#if !defined(_WIN32) #error This is a WINDOWS only table type -#endif // !__WIN__ +#endif // !_WIN32 #include "my_global.h" #include <stdio.h> diff --git a/storage/connect/tabxcl.cpp b/storage/connect/tabxcl.cpp index 46620985852..d354f556ca1 100644 --- a/storage/connect/tabxcl.cpp +++ b/storage/connect/tabxcl.cpp @@ -17,7 +17,7 @@ /***********************************************************************/ #include "my_global.h" #include "table.h" // MySQL table definitions -#if defined(__WIN__) +#if defined(_WIN32) #include <stdlib.h> #include <stdio.h> #if defined(__BORLANDC__) diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp index dcebe18dd36..2d8df9a4053 100644 --- a/storage/connect/tabxml.cpp +++ b/storage/connect/tabxml.cpp @@ -15,12 +15,12 @@ #include <stdio.h> #include <fcntl.h> #include <errno.h> -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <winsock2.h> //#include <windows.h> #include <comdef.h> -#else // !__WIN__ +#else // !_WIN32 #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> @@ -28,7 +28,7 @@ //#include <ctype.h> #include "osutil.h" #define _O_RDONLY O_RDONLY -#endif // !__WIN__ +#endif // !_WIN32 #include "resource.h" // for IDS_COLUMNS #define INCLUDE_TDBXML @@ -53,11 +53,11 @@ extern "C" char version[]; -#if defined(__WIN__) && defined(DOMDOC_SUPPORT) +#if defined(_WIN32) && defined(DOMDOC_SUPPORT) #define XMLSUP "MS-DOM" -#else // !__WIN__ +#else // !_WIN32 #define XMLSUP "libxml2" -#endif // !__WIN__ +#endif // !_WIN32 #define TYPE_UNKNOWN 12 /* Must be greater than other types */ #define XLEN(M) sizeof(M) - strlen(M) - 1 /* To avoid overflow*/ @@ -180,11 +180,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) tdp->Skip = GetBooleanTableOption(g, topt, "Skipnull", false); if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL))) -#if defined(__WIN__) +#if defined(_WIN32) tdp->Usedom = true; -#else // !__WIN__ +#else // !_WIN32 tdp->Usedom = false; -#endif // !__WIN__ +#endif // !_WIN32 else tdp->Usedom = (toupper(*op) == 'M' || toupper(*op) == 'D'); @@ -529,7 +529,7 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) XmlDB = GetStringCatInfo(g, "XmlDB", NULL); Nslist = GetStringCatInfo(g, "Nslist", NULL); DefNs = GetStringCatInfo(g, "DefNs", NULL); - Limit = GetIntCatInfo("Limit", 10); + Limit = GetIntCatInfo("Limit", 50); Xpand = GetBoolCatInfo("Expand", false); Header = GetIntCatInfo("Header", 0); GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf)); @@ -537,11 +537,11 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) // Note that if no support is specified, the default is MS-DOM // on Windows and libxml2 otherwise if (*buf == '*') -#if defined(__WIN__) +#if defined(_WIN32) Usedom = true; -#else // !__WIN__ +#else // !_WIN32 Usedom = false; -#endif // !__WIN__ +#endif // !_WIN32 else Usedom = (toupper(*buf) == 'M' || toupper(*buf) == 'D'); @@ -974,7 +974,7 @@ bool TDBXML::Initialize(PGLOBAL g) Docp->SetNofree(true); // For libxml2 -#if defined(__WIN__) +#if defined(_WIN32) } catch (_com_error e) { // We come here if a DOM command threw an error char buf[128]; @@ -988,7 +988,7 @@ bool TDBXML::Initialize(PGLOBAL g) sprintf(g->Message, "%s hr=%x", MSG(COM_ERROR), e.Error()); goto error; -#endif // __WIN__ +#endif // _WIN32 #if !defined(UNIX) } catch(...) { // Other errors diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp index 2ae9382609d..40d9751721e 100644 --- a/storage/connect/valblk.cpp +++ b/storage/connect/valblk.cpp @@ -23,7 +23,7 @@ /* Include relevant MariaDB header file. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> #else #include "osutil.h" diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp index 412cb808936..a34133a9b72 100644 --- a/storage/connect/value.cpp +++ b/storage/connect/value.cpp @@ -30,11 +30,11 @@ #include "sql_class.h" #include "sql_time.h" -#if defined(__WIN__) +#if defined(_WIN32) //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #include <string.h> -#endif // !__WIN__ +#endif // !_WIN32 #include <math.h> @@ -77,12 +77,12 @@ int DTVAL::Shift = 0; /***********************************************************************/ bool PlugEvalLike(PGLOBAL, LPCSTR, LPCSTR, bool); -#if !defined(__WIN__) +#if !defined(_WIN32) extern "C" { PSZ strupr(PSZ s); PSZ strlwr(PSZ s); } -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Get a long long number from its character representation. */ @@ -1648,10 +1648,10 @@ int TYPVAL<PSZ>::CompareValue(PVAL vp) else n = strcmp(Strp, vp->GetCharValue()); -#if defined(__WIN__) +#if defined(_WIN32) if (n == _NLSCMPERROR) return n; // Here we should raise an error -#endif // __WIN__ +#endif // _WIN32 return (n > 0) ? 1 : (n < 0) ? -1 : 0; } // end of CompareValue @@ -2644,9 +2644,9 @@ bool DTVAL::SetValue_pval(PVAL valp, bool chktype) } else if (valp->GetType() == TYPE_BIGINT && !(valp->GetBigintValue() % 1000)) { // Assuming that this timestamp is in milliseconds - Tval = (int)(valp->GetBigintValue() / 1000); + SetValue((int)(valp->GetBigintValue() / 1000)); } else - Tval = valp->GetIntValue(); + SetValue(valp->GetIntValue()); } else Reset(); @@ -2738,20 +2738,38 @@ void DTVAL::SetValue_pvblk(PVBLK blk, int n) } // end of SetValue /***********************************************************************/ +/* DTVAL SetValue: get date as an integer. */ +/***********************************************************************/ +void DTVAL::SetValue(int n) +{ + Tval = n; + + if (Pdtp) { + size_t slen = (size_t)Len + 1; + struct tm tm, *ptm= GetGmTime(&tm); + + if (ptm) + strftime(Sdate, slen, Pdtp->OutFmt, ptm); + + } // endif Pdtp + +} // end of SetValue + +/***********************************************************************/ /* DTVAL GetCharString: get string representation of a date value. */ /***********************************************************************/ char *DTVAL::GetCharString(char *p) { if (Pdtp) { - size_t n = 0; + size_t n = 0, slen = (size_t)Len + 1; struct tm tm, *ptm= GetGmTime(&tm); if (ptm) - n = strftime(Sdate, Len + 1, Pdtp->OutFmt, ptm); + n = strftime(Sdate, slen, Pdtp->OutFmt, ptm); if (!n) { *Sdate = '\0'; - strncat(Sdate, "Error", Len + 1); + strncat(Sdate, "Error", slen); } // endif n return Sdate; diff --git a/storage/connect/value.h b/storage/connect/value.h index df6a55501b6..a0d947347c3 100644 --- a/storage/connect/value.h +++ b/storage/connect/value.h @@ -412,13 +412,15 @@ class DllExport DTVAL : public TYPVAL<int> { // Constructors DTVAL(PGLOBAL g, int n, int p, PCSZ fmt); DTVAL(int n); + using TYPVAL<int>::SetValue; // Implementation virtual bool SetValue_pval(PVAL valp, bool chktype); virtual bool SetValue_char(const char *p, int n); virtual void SetValue_psz(PCSZ s); virtual void SetValue_pvblk(PVBLK blk, int n); - virtual PSZ GetCharValue(void) { return Sdate; } + virtual void SetValue(int n); + virtual PSZ GetCharValue(void) { return Sdate; } virtual char *GetCharString(char *p); virtual int ShowValue(char *buf, int len); virtual bool FormatValue(PVAL vp, PCSZ fmt); diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index 1b3534b4f1b..6ed70f21a85 100644 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -10,12 +10,12 @@ /* Include relevant sections of the System header files. */ /***********************************************************************/ #include "my_global.h" -#if defined(__WIN__) +#if defined(_WIN32) #include <io.h> #include <fcntl.h> #include <errno.h> //#include <windows.h> -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include <sys/types.h> #include <sys/stat.h> @@ -25,7 +25,7 @@ #include <io.h> #endif // !UNIX #include <fcntl.h> -#endif // !__WIN__ +#endif // !_WIN32 /***********************************************************************/ /* Include required application header files */ @@ -848,7 +848,7 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) if ((sep = defp->GetBoolCatInfo("SepIndex", false))) { // Index is saved in a separate file -#if defined(__WIN__) +#if defined(_WIN32) char drive[_MAX_DRIVE]; #else char *drive = NULL; @@ -1002,7 +1002,7 @@ bool XINDEX::Init(PGLOBAL g) if (defp->SepIndex()) { // Index was saved in a separate file -#if defined(__WIN__) +#if defined(_WIN32) char drive[_MAX_DRIVE]; #else char *drive = NULL; @@ -1255,7 +1255,7 @@ bool XINDEX::MapInit(PGLOBAL g) if (defp->SepIndex()) { // Index was save in a separate file -#if defined(__WIN__) +#if defined(_WIN32) char drive[_MAX_DRIVE]; #else char *drive = NULL; @@ -1470,7 +1470,7 @@ bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk) if (defp->SepIndex()) { // Index was saved in a separate file -#if defined(__WIN__) +#if defined(_WIN32) char drive[_MAX_DRIVE]; #else char *drive = NULL; @@ -2519,7 +2519,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode) if (trace(1)) htrc(" Xopen: filename=%s id=%d mode=%d\n", filename, id, mode); -#if defined(__WIN__) +#if defined(_WIN32) LONG high = 0; DWORD rc, drc, access, share, creation; @@ -2695,7 +2695,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode) /***********************************************************************/ bool XHUGE::Seek(PGLOBAL g, int low, int high, int origin) { -#if defined(__WIN__) +#if defined(_WIN32) LONG hi = high; DWORD rc = SetFilePointer(Hfile, low, &hi, origin); @@ -2731,7 +2731,7 @@ bool XHUGE::Read(PGLOBAL g, void *buf, int n, int size) { bool rc = false; -#if defined(__WIN__) +#if defined(_WIN32) bool brc; DWORD nbr, count = (DWORD)(n * size); @@ -2777,7 +2777,7 @@ bool XHUGE::Read(PGLOBAL g, void *buf, int n, int size) /***********************************************************************/ int XHUGE::Write(PGLOBAL g, void *buf, int n, int size, bool& rc) { -#if defined(__WIN__) +#if defined(_WIN32) bool brc; DWORD nbw, count = (DWORD)n * (DWORD) size; @@ -2819,7 +2819,7 @@ void XHUGE::Close(char *fn, int id) if (trace(1)) htrc("XHUGE::Close: fn=%s id=%d NewOff=%lld\n", fn, id, NewOff.Val); -#if defined(__WIN__) +#if defined(_WIN32) if (id >= 0 && fn) { CloseFileHandle(Hfile); Hfile = CreateFile(fn, GENERIC_READ | GENERIC_WRITE, 0, NULL, @@ -2834,7 +2834,7 @@ void XHUGE::Close(char *fn, int id) } // endif SetFilePointer } // endif id -#else // !__WIN__ +#else // !_WIN32 if (id >= 0 && fn) { if (Hfile != INVALID_HANDLE_VALUE) { if (lseek64(Hfile, id * sizeof(IOFF), SEEK_SET) >= 0) { @@ -2850,7 +2850,7 @@ void XHUGE::Close(char *fn, int id) htrc("(XHUGE)error reopening %s: %s\n", fn, strerror(errno)); } // endif id -#endif // !__WIN__ +#endif // !_WIN32 XLOAD::Close(); } // end of Close diff --git a/storage/connect/xindex.h b/storage/connect/xindex.h index 339d7e68b75..ce62f0591c1 100644 --- a/storage/connect/xindex.h +++ b/storage/connect/xindex.h @@ -350,7 +350,7 @@ class DllExport XLOAD : public BLOCK { protected: // Members -#if defined(__WIN__) +#if defined(_WIN32) HANDLE Hfile; // Handle to file or map #else // UNIX int Hfile; // Descriptor to file or map diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 8de876ebe6b..b658bdfc540 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -519,8 +519,8 @@ buf_page_is_checksum_valid_crc32( #ifdef UNIV_INNOCHECKSUM if (log_file && srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) { - fprintf(log_file, "page::%llu;" - " crc32 calculated = %u;" + fprintf(log_file, "page::" UINT32PF ";" + " crc32 calculated = " UINT32PF ";" " recorded checksum field1 = " ULINTPF " recorded" " checksum field2 =" ULINTPF "\n", cur_page_num, crc32, checksum_field1, checksum_field2); @@ -561,26 +561,26 @@ buf_page_is_checksum_valid_innodb( #ifdef UNIV_INNOCHECKSUM if (log_file && srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_INNODB) { - fprintf(log_file, "page::%llu;" + fprintf(log_file, "page::" UINT32PF ";" " old style: calculated =" " " ULINTPF "; recorded = " ULINTPF "\n", cur_page_num, old_checksum, checksum_field2); - fprintf(log_file, "page::%llu;" + fprintf(log_file, "page::" UINT32PF ";" " new style: calculated =" - " " ULINTPF "; crc32 = %u; recorded = " ULINTPF "\n", + " " ULINTPF "; crc32 = " UINT32PF "; recorded = " ULINTPF "\n", cur_page_num, new_checksum, buf_calc_page_crc32(read_buf), checksum_field1); } if (log_file && srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) { - fprintf(log_file, "page::%llu;" + fprintf(log_file, "page::" UINT32PF ";" " old style: calculated =" " " ULINTPF "; recorded checksum = " ULINTPF "\n", cur_page_num, old_checksum, checksum_field2); - fprintf(log_file, "page::%llu;" + fprintf(log_file, "page::" UINT32PF ";" " new style: calculated =" " " ULINTPF "; recorded checksum = " ULINTPF "\n", cur_page_num, new_checksum, @@ -648,7 +648,7 @@ buf_page_is_checksum_valid_none( if (log_file && srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_NONE) { fprintf(log_file, - "page::%llu; none checksum: calculated" + "page::" UINT32PF "; none checksum: calculated" " = %lu; recorded checksum_field1 = " ULINTPF " recorded checksum_field2 = " ULINTPF "\n", cur_page_num, BUF_NO_CHECKSUM_MAGIC, @@ -877,15 +877,15 @@ buf_page_is_corrupted( checksum_field1, checksum_field2)) { #ifdef UNIV_INNOCHECKSUM if (log_file) { - fprintf(log_file, "page::%llu;" + fprintf(log_file, "page::" UINT32PF ";" " old style: calculated = %u;" " recorded = " ULINTPF ";\n", cur_page_num, buf_calc_page_old_checksum(read_buf), checksum_field2); - fprintf(log_file, "page::%llu;" - " new style: calculated = %u;" - " crc32 = %u; recorded = " ULINTPF ";\n", + fprintf(log_file, "page::" UINT32PF ";" + " new style: calculated = " UINT32PF ";" + " crc32 = " UINT32PF "; recorded = " ULINTPF ";\n", cur_page_num, buf_calc_page_new_checksum(read_buf), buf_calc_page_crc32(read_buf), diff --git a/storage/innobase/bzip2.cmake b/storage/innobase/bzip2.cmake index 26fd703120e..91dd2bf0fcd 100644 --- a/storage/innobase/bzip2.cmake +++ b/storage/innobase/bzip2.cmake @@ -22,12 +22,15 @@ MACRO (MYSQL_CHECK_BZIP2) CHECK_LIBRARY_EXISTS(bz2 BZ2_bzBuffToBuffDecompress "" HAVE_BZLIB2_DECOMPRESS) IF (HAVE_BZLIB2_COMPRESS AND HAVE_BZLIB2_DECOMPRESS AND HAVE_BZLIB2_H) + SET(HAVE_INNODB_BZLIB2 TRUE) ADD_DEFINITIONS(-DHAVE_BZIP2=1) LINK_LIBRARIES(bz2) ELSE() IF (WITH_INNODB_BZIP2 STREQUAL "ON") - MESSAGE(FATAL_ERROR "Required bzip2 library is not found") + MESSAGE(FATAL_ERROR "Required bzip2 library is not found") ENDIF() ENDIF() ENDIF() + ADD_FEATURE_INFO(INNODB_BZIP2 HAVE_INNODB_BZLIB2 + "BZIP2 compression in the InnoDB storage engine") ENDMACRO() diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 960cd7f7eeb..240a2682efc 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1168,6 +1168,33 @@ struct rotate_thread_t { } }; +/** Avoid the removal of the tablespace from +default_encrypt_list only when +1) Another active encryption thread working on tablespace +2) Eligible for tablespace key rotation +3) Tablespace is in flushing phase +@return true if tablespace should be removed from +default encrypt */ +static bool fil_crypt_must_remove(const fil_space_t &space) +{ + ut_ad(space.purpose == FIL_TYPE_TABLESPACE); + fil_space_crypt_t *crypt_data = space.crypt_data; + ut_ad(mutex_own(&fil_system.mutex)); + const ulong encrypt_tables= srv_encrypt_tables; + if (!crypt_data) + return !encrypt_tables; + if (!crypt_data->is_key_found()) + return true; + + mutex_enter(&crypt_data->mutex); + const bool remove= (space.is_stopping() || crypt_data->not_encrypted()) && + (!crypt_data->rotate_state.flushing && + !encrypt_tables == !!crypt_data->min_key_version && + !crypt_data->rotate_state.active_threads); + mutex_exit(&crypt_data->mutex); + return remove; +} + /*********************************************************************** Check if space needs rotation given a key_state @param[in,out] state Key rotation state @@ -1213,6 +1240,7 @@ fil_crypt_space_needs_rotation( return false; } + bool need_key_rotation = false; mutex_enter(&crypt_data->mutex); do { @@ -1242,25 +1270,15 @@ fil_crypt_space_needs_rotation( fil_crypt_get_key_state(key_state, crypt_data); } - bool need_key_rotation = fil_crypt_needs_rotation( + need_key_rotation = fil_crypt_needs_rotation( crypt_data, crypt_data->min_key_version, key_state->key_version, key_state->rotate_key_age); - - if (need_key_rotation == false) { - break; - } - - mutex_exit(&crypt_data->mutex); - - return true; } while (0); mutex_exit(&crypt_data->mutex); - - - return false; + return need_key_rotation; } /*********************************************************************** @@ -1506,8 +1524,7 @@ inline fil_space_t *fil_system_t::default_encrypt_next(fil_space_t *space, If there is a change in innodb_encrypt_tables variables value then don't remove the last processed tablespace from the default encrypt list. */ - if (released && (!recheck || space->crypt_data) && - !encrypt == !srv_encrypt_tables) + if (released && !recheck && fil_crypt_must_remove(*space)) { ut_a(!default_encrypt_tables.empty()); default_encrypt_tables.remove(*space); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index bdc6660c0a6..c8ecf4d7d1f 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2021, Oracle and/or its affiliates. Copyright (c) 2016, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -1285,6 +1285,9 @@ fts_cache_node_add_positions( ptr = ilist + node->ilist_size; node->ilist_size_alloc = new_size; + if (cache) { + cache->total_size += new_size; + } } ptr_start = ptr; @@ -1311,6 +1314,9 @@ fts_cache_node_add_positions( if (node->ilist_size > 0) { memcpy(ilist, node->ilist, node->ilist_size); ut_free(node->ilist); + if (cache) { + cache->total_size -= node->ilist_size; + } } node->ilist = ilist; @@ -1318,10 +1324,6 @@ fts_cache_node_add_positions( node->ilist_size += enc_len; - if (cache) { - cache->total_size += enc_len; - } - if (node->first_doc_id == FTS_NULL_DOC_ID) { node->first_doc_id = doc_id; } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index caae4035f7c..45acc5d0716 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2369,6 +2369,13 @@ innodb_instant_alter_column_allowed_reason: & ALTER_ADD_COLUMN)); if (const Field* f = cf.field) { + /* An AUTO_INCREMENT attribute can only + be added to an existing column by ALGORITHM=COPY, + but we can remove the attribute. */ + ut_ad((MTYP_TYPENR((*af)->unireg_check) + != Field::NEXT_NUMBER) + || (MTYP_TYPENR(f->unireg_check) + == Field::NEXT_NUMBER)); if (!f->real_maybe_null() || (*af)->real_maybe_null()) goto next_column; /* We are changing an existing column @@ -2377,7 +2384,6 @@ innodb_instant_alter_column_allowed_reason: & ALTER_COLUMN_NOT_NULLABLE); /* Virtual columns are never NOT NULL. */ DBUG_ASSERT(f->stored_in_db()); - switch ((*af)->type()) { case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_TIMESTAMP2: @@ -2397,14 +2403,7 @@ innodb_instant_alter_column_allowed_reason: break; default: /* For any other data type, NULL - values are not converted. - (An AUTO_INCREMENT attribute cannot - be introduced to a column with - ALGORITHM=INPLACE.) */ - ut_ad((MTYP_TYPENR((*af)->unireg_check) - == Field::NEXT_NUMBER) - == (MTYP_TYPENR(f->unireg_check) - == Field::NEXT_NUMBER)); + values are not converted. */ goto next_column; } @@ -7536,7 +7535,6 @@ ha_innobase::prepare_inplace_alter_table( mem_heap_t* heap; const char** col_names; int error; - ulint max_col_len; ulint add_autoinc_col_no = ULINT_UNDEFINED; ulonglong autoinc_col_max_value = 0; ulint fts_doc_col_no = ULINT_UNDEFINED; @@ -7574,12 +7572,6 @@ ha_innobase::prepare_inplace_alter_table( if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) { /* Nothing to do */ DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); - if (ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) { - - online_retry_drop_indexes( - m_prebuilt->table, m_user_thd); - - } DBUG_RETURN(false); } @@ -7745,7 +7737,13 @@ check_if_ok_to_rename: & 1U << DICT_TF_POS_DATA_DIR); } - max_col_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(info.flags()); + + /* ALGORITHM=INPLACE without rebuild (10.3+ ALGORITHM=NOCOPY) + must use the current ROW_FORMAT of the table. */ + const ulint max_col_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG( + innobase_need_rebuild(ha_alter_info, this->table) + ? info.flags() + : m_prebuilt->table->flags); /* Check each index's column length to make sure they do not exceed limit */ diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 6f633a45499..6c68bf170b6 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -421,7 +421,7 @@ in both 32-bit and 64-bit environments. */ #ifdef UNIV_INNOCHECKSUM extern bool strict_verify; extern FILE* log_file; -extern unsigned long long cur_page_num; +extern uint32_t cur_page_num; #endif /* UNIV_INNOCHECKSUM */ typedef int64_t ib_int64_t; diff --git a/storage/innobase/innodb.cmake b/storage/innobase/innodb.cmake index 385e87f828e..05a70aae114 100644 --- a/storage/innobase/innodb.cmake +++ b/storage/innobase/innodb.cmake @@ -81,6 +81,7 @@ MARK_AS_ADVANCED(INNODB_COMPILER_HINTS) IF(INNODB_COMPILER_HINTS) ADD_DEFINITIONS("-DCOMPILER_HINTS") ENDIF() +ADD_FEATURE_INFO(INNODB_COMPILER_HINTS INNODB_COMPILER_HINTS "InnoDB compiled with compiler hints") # Enable InnoDB's UNIV_DEBUG in debug builds SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG") @@ -91,15 +92,21 @@ IF(WITH_INNODB_AHI) ADD_DEFINITIONS(-DBTR_CUR_HASH_ADAPT -DBTR_CUR_ADAPT) IF(NOT WITH_INNODB_ROOT_GUESS) MESSAGE(WARNING "WITH_INNODB_AHI implies WITH_INNODB_ROOT_GUESS") + SET(WITH_INNODB_ROOT_GUESS ON) ENDIF() ELSEIF(WITH_INNODB_ROOT_GUESS) ADD_DEFINITIONS(-DBTR_CUR_ADAPT) ENDIF() +ADD_FEATURE_INFO(INNODB_AHI WITH_INNODB_AHI "InnoDB Adaptive Hash Index") +ADD_FEATURE_INFO(INNODB_ROOT_GUESS WITH_INNODB_ROOT_GUESS + "Cache index root block descriptors in InnoDB") OPTION(WITH_INNODB_EXTRA_DEBUG "Enable extra InnoDB debug checks" OFF) IF(WITH_INNODB_EXTRA_DEBUG) ADD_DEFINITIONS(-DUNIV_ZIP_DEBUG) ENDIF() +ADD_FEATURE_INFO(INNODB_EXTRA_DEBUG WITH_INNODB_EXTRA_DEBUG "Extra InnoDB debug checks") + CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU) IF(HAVE_SCHED_GETCPU) @@ -151,6 +158,7 @@ OPTION(WITH_INNODB_DISALLOW_WRITES "InnoDB freeze writes patch from Google" ${WI IF (WITH_INNODB_DISALLOW_WRITES) ADD_DEFINITIONS(-DWITH_INNODB_DISALLOW_WRITES) ENDIF() +ADD_FEATURE_INFO(INNODB_DISALLOW_WRITES WITH_INNODB_DISALLOW_WRITES "Expose innodb_disallow_writes switch to stop innodb from writing to disk") # Include directories under innobase @@ -176,8 +184,8 @@ IF(MSVC) SET_SOURCE_FILES_PROPERTIES(${_SRC_DIR}/pars/lexyy.c PROPERTIES COMPILE_FLAGS "/wd4003") ENDIF() - + # Include directories under innobase INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include - ${CMAKE_SOURCE_DIR}/storage/innobase/handler + ${CMAKE_SOURCE_DIR}/storage/innobase/handler ${CMAKE_SOURCE_DIR}/libbinlogevents/include ) diff --git a/storage/innobase/lz4.cmake b/storage/innobase/lz4.cmake index e901378eafc..a908dd3b73e 100644 --- a/storage/innobase/lz4.cmake +++ b/storage/innobase/lz4.cmake @@ -22,35 +22,17 @@ MACRO (MYSQL_CHECK_LZ4) CHECK_LIBRARY_EXISTS(lz4 LZ4_compress_default "" HAVE_LZ4_COMPRESS_DEFAULT) IF (HAVE_LZ4_SHARED_LIB AND HAVE_LZ4_H) + SET(HAVE_INNODB_LZ4 TRUE) ADD_DEFINITIONS(-DHAVE_LZ4=1) IF (HAVE_LZ4_COMPRESS_DEFAULT) - ADD_DEFINITIONS(-DHAVE_LZ4_COMPRESS_DEFAULT=1) + ADD_DEFINITIONS(-DHAVE_LZ4_COMPRESS_DEFAULT=1) ENDIF() LINK_LIBRARIES(lz4) ELSE() IF (WITH_INNODB_LZ4 STREQUAL "ON") - MESSAGE(FATAL_ERROR "Required lz4 library is not found") + MESSAGE(FATAL_ERROR "Required lz4 library is not found") ENDIF() ENDIF() ENDIF() -ENDMACRO() - -MACRO (MYSQL_CHECK_LZ4_STATIC) - IF (WITH_INNODB_LZ4 STREQUAL "ON" OR WITH_INNODB_LZ4 STREQUAL "AUTO") - CHECK_INCLUDE_FILES(lz4.h HAVE_LZ4_H) - CHECK_LIBRARY_EXISTS(liblz4.a LZ4_compress_limitedOutput "" HAVE_LZ4_LIB) - CHECK_LIBRARY_EXISTS(liblz3.a LZ4_compress_default "" HAVE_LZ4_COMPRESS_DEFAULT) - - IF(HAVE_LZ4_LIB AND HAVE_LZ4_H) - ADD_DEFINITIONS(-DHAVE_LZ4=1) - IF (HAVE_LZ4_COMPRESS_DEFAULT) - ADD_DEFINITIONS(-DHAVE_LZ4_COMPRESS_DEFAULT=1) - ENDIF() - LINK_LIBRARIES(liblz4.a) - ELSE() - IF (WITH_INNODB_LZ4 STREQUAL "ON") - MESSAGE(FATAL_ERROR "Required lz4 library is not found") - ENDIF() - ENDIF() - ENDIF() + ADD_FEATURE_INFO(INNODB_LZ4 HAVE_INNODB_LZ4 "LZ4 compression in the InnoDB storage engine") ENDMACRO() diff --git a/storage/innobase/lzma.cmake b/storage/innobase/lzma.cmake index 93de0a2934d..3060139c27c 100644 --- a/storage/innobase/lzma.cmake +++ b/storage/innobase/lzma.cmake @@ -22,12 +22,14 @@ MACRO (MYSQL_CHECK_LZMA) CHECK_LIBRARY_EXISTS(lzma lzma_easy_buffer_encode "" HAVE_LZMA_ENCODE) IF (HAVE_LZMA_DECODE AND HAVE_LZMA_ENCODE AND HAVE_LZMA_H) + SET(HAVE_INNODB_LZMA TRUE) ADD_DEFINITIONS(-DHAVE_LZMA=1) LINK_LIBRARIES(lzma) ELSE() IF (WITH_INNODB_LZMA STREQUAL "ON") - MESSAGE(FATAL_ERROR "Required lzma library is not found") + MESSAGE(FATAL_ERROR "Required lzma library is not found") ENDIF() ENDIF() ENDIF() + ADD_FEATURE_INFO(INNODB_LZMA HAVE_INNODB_LZMA "LZMA compression in the InnoDB storage engine") ENDMACRO() diff --git a/storage/innobase/lzo.cmake b/storage/innobase/lzo.cmake index 236eac2d1e5..ca2de6ab1c5 100644 --- a/storage/innobase/lzo.cmake +++ b/storage/innobase/lzo.cmake @@ -15,34 +15,20 @@ SET(WITH_INNODB_LZO AUTO CACHE STRING "Build with lzo. Possible values are 'ON', 'OFF', 'AUTO' and default is 'AUTO'") -MACRO (MYSQL_CHECK_LZO_STATIC) - IF (WITH_INNODB_LZO STREQUAL "ON" OR WITH_INNODB_LZO STREQUAL "AUTO") - CHECK_INCLUDE_FILES(lzo/lzo1x.h HAVE_LZO_H) - CHECK_LIBRARY_EXISTS(liblzo2.a lzo1x_1_compress "" HAVE_LZO_LIB) - - IF(HAVE_LZO_LIB AND HAVE_LZO_H) - ADD_DEFINITIONS(-DHAVE_LZO=1) - LINK_LIBRARIES(liblzo2.a) - ELSE() - IF (WITH_INNODB_LZO STREQUAL "ON") - MESSAGE(FATAL_ERROR "Required lzo library is not found") - ENDIF() - ENDIF() - ENDIF() -ENDMACRO() - MACRO (MYSQL_CHECK_LZO) IF (WITH_INNODB_LZO STREQUAL "ON" OR WITH_INNODB_LZO STREQUAL "AUTO") CHECK_INCLUDE_FILES(lzo/lzo1x.h HAVE_LZO_H) CHECK_LIBRARY_EXISTS(lzo2 lzo1x_1_compress "" HAVE_LZO_SHARED_LIB) IF(HAVE_LZO_SHARED_LIB AND HAVE_LZO_H) + SET(HAVE_INNODB_LZO TRUE) ADD_DEFINITIONS(-DHAVE_LZO=1) LINK_LIBRARIES(lzo2) ELSE() IF (WITH_INNODB_LZO STREQUAL "ON") - MESSAGE(FATAL_ERROR "Required lzo library is not found") + MESSAGE(FATAL_ERROR "Required lzo library is not found") ENDIF() ENDIF() ENDIF() + ADD_FEATURE_INFO(INNODB_LZO HAVE_INNODB_LZO "LZO compression in the InnoDB storage engine") ENDMACRO() diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 3eb8d03dbd3..7a6829e7865 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -342,6 +342,10 @@ os_file_lock( int fd, const char* name) { + if (my_disable_locking) { + return 0; + } + struct flock lk; lk.l_type = F_WRLCK; diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 74989fb018d..331ecbfb0c4 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -4656,9 +4656,9 @@ bool page_zip_verify_checksum(const byte *data, size_t size) #ifdef UNIV_INNOCHECKSUM if (log_file) { - fprintf(log_file, "page::%llu;" - " %s checksum: calculated = %u;" - " recorded = %u\n", cur_page_num, + fprintf(log_file, "page::" UINT32PF ";" + " %s checksum: calculated = " UINT32PF ";" + " recorded = " UINT32PF "\n", cur_page_num, buf_checksum_algorithm_name( static_cast<srv_checksum_algorithm_t>( srv_checksum_algorithm)), @@ -4670,11 +4670,11 @@ bool page_zip_verify_checksum(const byte *data, size_t size) data, size, SRV_CHECKSUM_ALGORITHM_CRC32); if (log_file) { - fprintf(log_file, "page::%llu: crc32 checksum:" - " calculated = %u; recorded = %u\n", + fprintf(log_file, "page::" UINT32PF ": crc32 checksum:" + " calculated = " UINT32PF "; recorded = " UINT32PF "\n", cur_page_num, crc32, stored); - fprintf(log_file, "page::%llu: none checksum:" - " calculated = %lu; recorded = %u\n", + fprintf(log_file, "page::" UINT32PF ": none checksum:" + " calculated = %lu; recorded = " UINT32PF "\n", cur_page_num, BUF_NO_CHECKSUM_MAGIC, stored); } } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 52852f21f2c..219e0e9381c 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -710,6 +710,14 @@ dberr_t FetchIndexRootPages::operator()(buf_block_t* block) UNIV_NOTHROW return(DB_CORRUPTION); } } + + if (!page_is_comp(block->frame) != + !dict_table_is_comp(m_table)) { + ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR, + ER_TABLE_SCHEMA_MISMATCH, + "ROW_FORMAT mismatch"); + return DB_CORRUPTION; + } } return DB_SUCCESS; diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index fe79c747d19..6c2edd1933f 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -930,8 +930,8 @@ row_ins_foreign_fill_virtual( upd_field = update->fields + n_diff; upd_field->old_v_val = static_cast<dfield_t*>( - mem_heap_alloc(cascade->heap, - sizeof *upd_field->old_v_val)); + mem_heap_alloc(update->heap, + sizeof *upd_field->old_v_val)); dfield_copy(upd_field->old_v_val, vfield); diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 09f49edfc71..3792aab44ea 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -52,6 +52,11 @@ Created 12/27/1996 Heikki Tuuri #include <algorithm> #include <mysql/plugin.h> #include <mysql/service_wsrep.h> +#ifdef WITH_WSREP +#include "log.h" +#include "wsrep.h" +#endif /* WITH_WSREP */ + /* What kind of latch and lock can we assume when the control comes to ------------------------------------------------------------------- @@ -2148,34 +2153,30 @@ row_upd_sec_index_entry( err = DB_SUCCESS; break; case DB_LOCK_WAIT: - if (UNIV_UNLIKELY(wsrep_debug)) { - ib::warn() << "WSREP: sec index FK lock wait" - << " index " << index->name - << " table " << index->table->name - << " query " << wsrep_thd_query(trx->mysql_thd); - } - break; case DB_DEADLOCK: - if (UNIV_UNLIKELY(wsrep_debug)) { - ib::warn() << "WSREP: sec index FK check fail for deadlock" - << " index " << index->name - << " table " << index->table->name - << " query " << wsrep_thd_query(trx->mysql_thd); - } + case DB_LOCK_WAIT_TIMEOUT: + WSREP_DEBUG("Foreign key check fail: " + "%s on table %s index %s query %s", + ut_strerr(err), index->name(), index->table->name.m_name, + wsrep_thd_query(trx->mysql_thd)); break; default: - ib::error() << "WSREP: referenced FK check fail: " << err - << " index " << index->name - << " table " << index->table->name - << " query " << wsrep_thd_query(trx->mysql_thd); - + WSREP_ERROR("Foreign key check fail: " + "%s on table %s index %s query %s", + ut_strerr(err), index->name(), index->table->name.m_name, + wsrep_thd_query(trx->mysql_thd)); break; } } #endif /* WITH_WSREP */ } +#ifdef WITH_WSREP + ut_ad(err == DB_SUCCESS || err == DB_LOCK_WAIT + || err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT); +#else ut_ad(err == DB_SUCCESS); +#endif if (referenced) { rec_offs* offsets = rec_get_offsets( @@ -2496,17 +2497,21 @@ check_fk: case DB_NO_REFERENCED_ROW: err = DB_SUCCESS; break; + case DB_LOCK_WAIT: case DB_DEADLOCK: - if (UNIV_UNLIKELY(wsrep_debug)) { - ib::warn() << "WSREP: sec index FK check fail for deadlock" - << " index " << index->name - << " table " << index->table->name; - } + case DB_LOCK_WAIT_TIMEOUT: + WSREP_DEBUG("Foreign key check fail: " + "%s on table %s index %s query %s", + ut_strerr(err), index->name(), index->table->name.m_name, + wsrep_thd_query(trx->mysql_thd)); + goto err_exit; default: - ib::error() << "WSREP: referenced FK check fail: " << err - << " index " << index->name - << " table " << index->table->name; + WSREP_ERROR("Foreign key check fail: " + "%s on table %s index %s query %s", + ut_strerr(err), index->name(), index->table->name.m_name, + wsrep_thd_query(trx->mysql_thd)); + goto err_exit; } #endif /* WITH_WSREP */ @@ -2723,18 +2728,19 @@ row_upd_del_mark_clust_rec( case DB_NO_REFERENCED_ROW: err = DB_SUCCESS; break; + case DB_LOCK_WAIT: case DB_DEADLOCK: - if (UNIV_UNLIKELY(wsrep_debug)) { - ib::warn() << "WSREP: sec index FK check fail for deadlock" - << " index " << index->name - << " table " << index->table->name; - } + case DB_LOCK_WAIT_TIMEOUT: + WSREP_DEBUG("Foreign key check fail: " + "%d on table %s index %s query %s", + err, index->name(), index->table->name.m_name, + wsrep_thd_query(trx->mysql_thd)); break; default: - ib::error() << "WSREP: referenced FK check fail: " << err - << " index " << index->name - << " table " << index->table->name; - + WSREP_ERROR("Foreign key check fail: " + "%d on table %s index %s query %s", + err, index->name(), index->table->name.m_name, + wsrep_thd_query(trx->mysql_thd)); break; } #endif /* WITH_WSREP */ diff --git a/storage/innobase/snappy.cmake b/storage/innobase/snappy.cmake index 2810472cef6..3a2d828ee5c 100644 --- a/storage/innobase/snappy.cmake +++ b/storage/innobase/snappy.cmake @@ -21,12 +21,14 @@ MACRO (MYSQL_CHECK_SNAPPY) CHECK_LIBRARY_EXISTS(snappy snappy_uncompress "" HAVE_SNAPPY_SHARED_LIB) IF(HAVE_SNAPPY_SHARED_LIB AND HAVE_SNAPPY_H) + SET(HAVE_INNODB_SNAPPY TRUE) ADD_DEFINITIONS(-DHAVE_SNAPPY=1) LINK_LIBRARIES(snappy) ELSE() IF (WITH_INNODB_SNAPPY STREQUAL "ON") - MESSAGE(FATAL_ERROR "Required snappy library is not found") + MESSAGE(FATAL_ERROR "Required snappy library is not found") ENDIF() ENDIF() ENDIF() + ADD_FEATURE_INFO(INNODB_SNAPPY HAVE_INNODB_SNAPPY "Snappy compression in the InnoDB storage engine") ENDMACRO() diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index bd3b9641e1e..cf8fa17cf1a 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1169,12 +1169,12 @@ trx_flush_log_if_needed_low( bool flush = srv_file_flush_method != SRV_NOSYNC; switch (srv_flush_log_at_trx_commit) { - case 3: case 2: /* Write the log but do not flush it to disk */ flush = false; /* fall through */ case 1: + case 3: /* Write the log and optionally flush it to disk */ log_write_up_to(lsn, flush); srv_inc_activity_count(); @@ -1717,6 +1717,7 @@ trx_print_low( /*!< in: mem_heap_get_size(trx->lock.lock_heap) */ { ibool newline; + fprintf(f, "TRANSACTION " TRX_ID_FMT, trx_get_id_for_print(trx)); switch (trx->state) { @@ -1739,8 +1740,9 @@ trx_print_low( fprintf(f, ", state %lu", (ulong) trx->state); ut_ad(0); state_ok: + const char* op_info = trx->op_info; - if (const char *op_info = trx->op_info) { + if (*op_info) { putc(' ', f); fputs(op_info, f); } diff --git a/storage/mroonga/CMakeLists.txt b/storage/mroonga/CMakeLists.txt index 555ab248751..2a449a8627c 100644 --- a/storage/mroonga/CMakeLists.txt +++ b/storage/mroonga/CMakeLists.txt @@ -80,7 +80,7 @@ else() set(MRN_SOURCE_DIR ${CMAKE_SOURCE_DIR}) endif() -file(READ ${MRN_SOURCE_DIR}/version MRN_VERSION) +file(READ ${MRN_SOURCE_DIR}/version_full MRN_VERSION) file(READ ${MRN_SOURCE_DIR}/version_major MRN_VERSION_MAJOR) file(READ ${MRN_SOURCE_DIR}/version_minor MRN_VERSION_MINOR) file(READ ${MRN_SOURCE_DIR}/version_micro MRN_VERSION_MICRO) diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt index d1ca2a8a0d8..ae083028038 100644 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/CMakeLists.txt @@ -28,7 +28,7 @@ endif() set(GROONGA_NORMALIZER_MYSQL_EMBED ${GROONGA_NORMALIZER_MYSQL_EMBED_DEFAULT} CACHE BOOL "Build as a static library to embed into an application") -file(READ "${CMAKE_CURRENT_SOURCE_DIR}/version" VERSION) +file(READ "${CMAKE_CURRENT_SOURCE_DIR}/version_full" VERSION) if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") set(GROONGA_NORMALIZER_MYSQL_BUNDLED FALSE) diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version_full index 8cfbc905b39..8cfbc905b39 100644 --- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version +++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version_full diff --git a/storage/mroonga/version b/storage/mroonga/version_full index 5b1f56847ae..5b1f56847ae 100644 --- a/storage/mroonga/version +++ b/storage/mroonga/version_full diff --git a/storage/oqgraph/CMakeLists.txt b/storage/oqgraph/CMakeLists.txt index 901acc6a8ca..a41b864d15b 100644 --- a/storage/oqgraph/CMakeLists.txt +++ b/storage/oqgraph/CMakeLists.txt @@ -3,6 +3,10 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") MACRO(CHECK_OQGRAPH) MESSAGE(STATUS "Configuring OQGraph") FIND_PACKAGE(Boost 1.40.0) +SET_PACKAGE_PROPERTIES(Boost PROPERTIES + PURPOSE "Required for the OQGraph storage engine" + TYPE OPTIONAL +) IF(NOT Boost_FOUND) MESSAGE(STATUS "Boost not found. OQGraph will not be compiled") SET(OQGRAPH_OK 0 CACHE INTERNAL "") @@ -11,6 +15,10 @@ ENDIF() INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS}) FIND_PACKAGE(Judy) +SET_PACKAGE_PROPERTIES(Judy PROPERTIES + PURPOSE "Required for the OQGraph storage engine" + TYPE OPTIONAL +) IF(NOT Judy_FOUND) MESSAGE(STATUS "Judy not found. OQGraph will not be compiled") SET(OQGRAPH_OK 0 CACHE INTERNAL "") diff --git a/storage/oqgraph/mysql-test/oqgraph/social.test b/storage/oqgraph/mysql-test/oqgraph/social.test index 69eb7698bb9..a71b160cc1d 100644 --- a/storage/oqgraph/mysql-test/oqgraph/social.test +++ b/storage/oqgraph/mysql-test/oqgraph/social.test @@ -1,3 +1,6 @@ +# The test can take very long time with valgrind +--source include/not_valgrind.inc + --disable_warnings DROP TABLE IF EXISTS rsb, rsb_graph; --enable_warnings diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt index c2fc8de8149..d5bbefbd27e 100644 --- a/storage/rocksdb/CMakeLists.txt +++ b/storage/rocksdb/CMakeLists.txt @@ -2,6 +2,7 @@ MACRO(SKIP_ROCKSDB_PLUGIN msg) MESSAGE_ONCE(SKIP_ROCKSDB_PLUGIN "Can't build rocksdb engine - ${msg}") + ADD_FEATURE_INFO(ROCKSDB "OFF" "Storage Engine") RETURN() ENDMACRO() diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake index 3a2297fd0f2..762368b4a80 100644 --- a/storage/rocksdb/build_rocksdb.cmake +++ b/storage/rocksdb/build_rocksdb.cmake @@ -42,6 +42,7 @@ macro(check_lib package var) IF (NOT ${WITH_ROCKSDB_${package}} STREQUAL "OFF") FIND_PACKAGE(${package} QUIET) + SET(HAVE_ROCKSDB_${PACKAGE_NAME} TRUE) IF (${${PACKAGE_NAME}_FOUND}) IF(${ARGC} GREATER 2) SET(CMAKE_REQUIRED_LIBRARIES ${${var}_LIBRARIES}) @@ -52,6 +53,7 @@ macro(check_lib package var) ENDIF() ENDIF() ENDIF() + ADD_FEATURE_INFO(ROCKSDB_${PACKAGE_NAME} HAVE_ROCKSDB_${PACKAGE_NAME} "${package} Compression in the RocksDB storage engine") IF(${${var}_VALID}) MESSAGE_ONCE(rocksdb_${var} "Found ${package}: ${${var}_LIBRARIES}") @@ -78,6 +80,7 @@ check_lib(ZSTD ZSTD ZDICT_trainFromBuffer) add_definitions(-DZLIB) list(APPEND THIRDPARTY_LIBS ${ZLIB_LIBRARY}) +ADD_FEATURE_INFO(ROCKSDB_ZLIB "ON" "zlib Compression in the RocksDB storage engine") if(CMAKE_SYSTEM_NAME MATCHES "Cygwin") add_definitions(-fno-builtin-memcmp -DCYGWIN) diff --git a/storage/spider/mysql-test/spider/bugfix/disabled.def b/storage/spider/mysql-test/spider/bugfix/disabled.def new file mode 100644 index 00000000000..e19ea07b76b --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/disabled.def @@ -0,0 +1 @@ +wait_timeout : MDEV-26045 diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_deinit.inc new file mode 100644 index 00000000000..1880a1c7bba --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_deinit.inc @@ -0,0 +1,11 @@ +--let $MASTER_1_COMMENT_P_2_1= $MASTER_1_COMMENT_P_2_1_BACKUP +--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP +--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP +--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP +--disable_warnings +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_result_log +--enable_query_log +--enable_warnings diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_init.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_init.inc new file mode 100644 index 00000000000..63fd70a4b49 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_24020_init.inc @@ -0,0 +1,43 @@ +--disable_warnings +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_result_log +--enable_query_log +--enable_warnings +--let $MASTER_1_COMMENT_P_2_1_BACKUP= $MASTER_1_COMMENT_P_2_1 +let $MASTER_1_COMMENT_P_2_1= + PARTITION BY LIST(a % 3) ( + PARTITION pt1 VALUES IN (0) COMMENT='srv "s_2_1", table "ta_r2"', + PARTITION pt2 VALUES IN (1) COMMENT='srv "s_2_1", table "ta_r3"', + PARTITION pt3 VALUES IN (2) COMMENT='srv "s_2_1", table "ta_r4"' + ); +--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES +let $CHILD2_1_DROP_TABLES= + DROP TABLE IF EXISTS ta_r2 $STR_SEMICOLON + DROP TABLE IF EXISTS ta_r3 $STR_SEMICOLON + DROP TABLE IF EXISTS ta_r4; +--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES +let $CHILD2_1_CREATE_TABLES= + CREATE TABLE ta_r2 ( + a INT, + b VARCHAR(30), + PRIMARY KEY(a) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON + CREATE TABLE ta_r3 ( + a INT, + b VARCHAR(30), + PRIMARY KEY(a) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON + CREATE TABLE ta_r4 ( + a INT, + b VARCHAR(30), + PRIMARY KEY(a) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; +--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES +let $CHILD2_1_SELECT_TABLES= + SELECT a, b FROM ta_r2 ORDER BY a $STR_SEMICOLON + SELECT a, b FROM ta_r3 ORDER BY a $STR_SEMICOLON + SELECT a, b FROM ta_r4 ORDER BY a; +let $CHILD2_1_SELECT_ARGUMENT1= + SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_deinit.inc new file mode 100644 index 00000000000..1880a1c7bba --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_deinit.inc @@ -0,0 +1,11 @@ +--let $MASTER_1_COMMENT_P_2_1= $MASTER_1_COMMENT_P_2_1_BACKUP +--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP +--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP +--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP +--disable_warnings +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_result_log +--enable_query_log +--enable_warnings diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_init.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_init.inc new file mode 100644 index 00000000000..b5b77a53798 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_24517_init.inc @@ -0,0 +1,43 @@ +--disable_warnings +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_result_log +--enable_query_log +--enable_warnings +--let $MASTER_1_COMMENT_P_2_1_BACKUP= $MASTER_1_COMMENT_P_2_1 +let $MASTER_1_COMMENT_P_2_1= + PARTITION BY RANGE(i) ( + PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1", table "ta_r2"', + PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_1", table "ta_r3"', + PARTITION pt3 VALUES LESS THAN MAXVALUE COMMENT='srv "s_2_1", table "ta_r4"' + ); +--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES +let $CHILD2_1_DROP_TABLES= + DROP TABLE IF EXISTS ta_r2 $STR_SEMICOLON + DROP TABLE IF EXISTS ta_r3 $STR_SEMICOLON + DROP TABLE IF EXISTS ta_r4; +--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES +let $CHILD2_1_CREATE_TABLES= + CREATE TABLE ta_r2 ( + i INT, + j JSON, + PRIMARY KEY(i) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON + CREATE TABLE ta_r3 ( + i INT, + j JSON, + PRIMARY KEY(i) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON + CREATE TABLE ta_r4 ( + i INT, + j JSON, + PRIMARY KEY(i) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; +--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES +let $CHILD2_1_SELECT_TABLES= + SELECT i, j FROM ta_r2 ORDER BY i $STR_SEMICOLON + SELECT i, j FROM ta_r3 ORDER BY i $STR_SEMICOLON + SELECT i, j FROM ta_r4 ORDER BY i; +let $CHILD2_1_SELECT_ARGUMENT1= + SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_24020.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_24020.result new file mode 100644 index 00000000000..164c68fbc0c --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_24020.result @@ -0,0 +1,97 @@ +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +this test is for MDEV-24020 + +drop and create databases +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +create table and insert +connection child2_1; +CHILD2_1_CREATE_TABLES +connection master_1; +CREATE TABLE tbl_a ( +a INT, +b VARCHAR(30), +PRIMARY KEY(a) +) ENGINE=Spider PARTITION BY LIST(a % 3) ( +PARTITION pt1 VALUES IN (0) COMMENT='srv "s_2_1", table "ta_r2"', +PARTITION pt2 VALUES IN (1) COMMENT='srv "s_2_1", table "ta_r3"', +PARTITION pt3 VALUES IN (2) COMMENT='srv "s_2_1", table "ta_r4"' + ) +INSERT INTO tbl_a VALUES(10000, " abcd "); +INSERT INTO tbl_a VALUES(10001, " abcd "); +INSERT INTO tbl_a VALUES(10002, " abcd "); +INSERT INTO tbl_a VALUES(10003, "[[[abcd][["); +INSERT INTO tbl_a VALUES(10004, "[[[abcd][["); +INSERT INTO tbl_a VALUES(10005, "[[[abcd][["); +INSERT INTO tbl_a VALUES(10006, "[[[abcd]]"); +INSERT INTO tbl_a VALUES(10007, "[[[abcd]]"); +INSERT INTO tbl_a VALUES(10008, "[[[abcd]]"); +INSERT INTO tbl_a VALUES(10009, "[[[**abcd****]]"); + +test 1 +connection master_1; +UPDATE tbl_a SET b = trim(b) WHERE a = 10000; +SELECT * FROM tbl_a WHERE a = 10000; +a b +10000 abcd +UPDATE tbl_a SET b = ltrim(b) WHERE a = 10001; +SELECT * FROM tbl_a WHERE a = 10001; +a b +10001 abcd +UPDATE tbl_a SET b = rtrim(b) WHERE a = 10002; +SELECT * FROM tbl_a WHERE a = 10002; +a b +10002 abcd +UPDATE tbl_a SET b = trim(BOTH '[' FROM b) WHERE a = 10003; +SELECT * FROM tbl_a WHERE a = 10003; +a b +10003 abcd] +UPDATE tbl_a SET b = trim(LEADING '[' FROM b) WHERE a = 10004; +SELECT * FROM tbl_a WHERE a = 10004; +a b +10004 abcd][[ +UPDATE tbl_a SET b = trim(TRAILING '[' FROM b) WHERE a = 10005; +SELECT * FROM tbl_a WHERE a = 10005; +a b +10005 [[[abcd] +UPDATE tbl_a SET b = trim(LEADING '[' FROM trim(TRAILING ']' FROM b)) WHERE a = 10006; +SELECT * FROM tbl_a WHERE a = 10006; +a b +10006 abcd +UPDATE tbl_a SET b = trim(TRAILING '[' FROM trim(LEADING ']' FROM b)) WHERE a = 10007; +SELECT * FROM tbl_a WHERE a = 10007; +a b +10007 [[[abcd]] +UPDATE tbl_a SET b = trim(TRAILING ']' FROM trim(LEADING '[' FROM b)) WHERE a = 10008; +SELECT * FROM tbl_a WHERE a = 10008; +a b +10008 abcd +UPDATE tbl_a SET b = trim(BOTH '*' FROM trim(TRAILING ']' FROM trim(LEADING '[' FROM b))) WHERE a = 10009; +SELECT * FROM tbl_a WHERE a = 10009; +a b +10009 abcd + +deinit +connection master_1; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +end of test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_24517.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_24517.result new file mode 100644 index 00000000000..f084c967435 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_24517.result @@ -0,0 +1,78 @@ +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +this test is for MDEV-24517 + +drop and create databases +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +connection child2_1; +SET @old_log_output = @@global.log_output; +SET GLOBAL log_output = 'TABLE,FILE'; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +create table and insert +connection child2_1; +CHILD2_1_CREATE_TABLES +TRUNCATE TABLE mysql.general_log; +connection master_1; +CREATE TABLE tbl_a ( +i INT, +j JSON, +PRIMARY KEY(i) +) ENGINE=Spider PARTITION BY RANGE(i) ( +PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1", table "ta_r2"', +PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_1", table "ta_r3"', +PARTITION pt3 VALUES LESS THAN MAXVALUE COMMENT='srv "s_2_1", table "ta_r4"' + ) +INSERT INTO tbl_a (i, j) VALUES +(1, '{"ID": "3", "Name": "Barney", "Age": 18}'), +(2, '{"ID": "4", "Name": "Betty", "Age": 19}'), +(3, '{"ID": "2", "Name": "Wilma", "Age": 20}'), +(4, '[10, 20, [30, 40]]'); + +test 1 +connection child2_1; +TRUNCATE TABLE mysql.general_log; +connection master_1; +SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$.Age')=19; +i j +2 {"ID": "4", "Name": "Betty", "Age": 19} +SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$.Name')="Betty"; +i j +2 {"ID": "4", "Name": "Betty", "Age": 19} +SELECT i, JSON_EXTRACT(j, "$.ID") +FROM tbl_a +WHERE JSON_EXTRACT(j, "$.ID") > 1 AND i < 4 +ORDER BY JSON_EXTRACT(j, "$.Name"); +i JSON_EXTRACT(j, "$.ID") +1 "3" +2 "4" +3 "2" +SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$[1]') = 20; +i j +4 [10, 20, [30, 40]] +SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$[2][0]') = 30; +i j +4 [10, 20, [30, 40]] + +deinit +connection master_1; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; +SET GLOBAL log_output = @old_log_output; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +end of test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_24760.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_24760.result new file mode 100644 index 00000000000..08481cd15f9 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_24760.result @@ -0,0 +1,49 @@ +# +# MDEV-24760 SELECT..CASE statement syntax error at Spider Engine table +# +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +DROP TABLE IF EXISTS tbl_a; +Warnings: +Note 1051 Unknown table 'auto_test_remote.tbl_a' +CREATE TABLE tbl_a ( +id int NOT NULL AUTO_INCREMENT, +name varchar(255) DEFAULT NULL, +PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO tbl_a (name) VALUES ('Alice'), ('Bob'); +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +id int NOT NULL AUTO_INCREMENT, +name varchar(255) DEFAULT NULL, +PRIMARY KEY (id) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a"' +PARTITION BY HASH(id) ( +PARTITION pt1 COMMENT='srv "s_2_1"' +); +SELECT id, CASE WHEN name='Alice' THEN "A" WHEN name='Bob' THEN "B" END FROM tbl_a; +id CASE WHEN name='Alice' THEN "A" WHEN name='Bob' THEN "B" END +1 A +2 B +SELECT id, CASE name WHEN 'Alice' THEN "A" WHEN 'Bob' THEN "B" END FROM tbl_a; +id CASE name WHEN 'Alice' THEN "A" WHEN 'Bob' THEN "B" END +1 A +2 B +DROP DATABASE auto_test_local; +connection child2_1; +DROP DATABASE auto_test_remote; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26013.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26013.result new file mode 100644 index 00000000000..3af1f7df0a7 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26013.result @@ -0,0 +1,42 @@ +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +MDEV-26013 distinct not work properly in some cases for spider tables + +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +`a`int, +`b`int, +PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +insert into `tbl_a` VALUES (1,999), (2,999); +connection master_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +`a`int, +`b`int, +PRIMARY KEY (`a`) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a"' PARTITION BY LIST COLUMNS(`a`) ( +PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' +); +connection master_1; +SELECT distinct b FROM tbl_a WHERE b=999; +b +999 +connection master_1; +DROP DATABASE IF EXISTS auto_test_remote; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.test new file mode 100644 index 00000000000..ac06d86052b --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24020.test @@ -0,0 +1,90 @@ +--source ../include/mdev_24020_init.inc +--echo +--echo this test is for MDEV-24020 +--echo +--echo drop and create databases + +--connection master_1 +--disable_warnings +CREATE DATABASE auto_test_local; +USE auto_test_local; + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +--enable_warnings + +--echo +--echo create table and insert + +--connection child2_1 +--disable_query_log +--disable_ps_protocol +echo CHILD2_1_CREATE_TABLES; +eval $CHILD2_1_CREATE_TABLES; +--enable_ps_protocol +--enable_query_log + +--connection master_1 +--disable_query_log +echo CREATE TABLE tbl_a ( + a INT, + b VARCHAR(30), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1; +eval CREATE TABLE tbl_a ( + a INT, + b VARCHAR(30), + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1; +--enable_query_log +INSERT INTO tbl_a VALUES(10000, " abcd "); +INSERT INTO tbl_a VALUES(10001, " abcd "); +INSERT INTO tbl_a VALUES(10002, " abcd "); +INSERT INTO tbl_a VALUES(10003, "[[[abcd][["); +INSERT INTO tbl_a VALUES(10004, "[[[abcd][["); +INSERT INTO tbl_a VALUES(10005, "[[[abcd][["); +INSERT INTO tbl_a VALUES(10006, "[[[abcd]]"); +INSERT INTO tbl_a VALUES(10007, "[[[abcd]]"); +INSERT INTO tbl_a VALUES(10008, "[[[abcd]]"); +INSERT INTO tbl_a VALUES(10009, "[[[**abcd****]]"); + +--echo +--echo test 1 + +--connection master_1 +UPDATE tbl_a SET b = trim(b) WHERE a = 10000; +SELECT * FROM tbl_a WHERE a = 10000; +UPDATE tbl_a SET b = ltrim(b) WHERE a = 10001; +SELECT * FROM tbl_a WHERE a = 10001; +UPDATE tbl_a SET b = rtrim(b) WHERE a = 10002; +SELECT * FROM tbl_a WHERE a = 10002; +UPDATE tbl_a SET b = trim(BOTH '[' FROM b) WHERE a = 10003; +SELECT * FROM tbl_a WHERE a = 10003; +UPDATE tbl_a SET b = trim(LEADING '[' FROM b) WHERE a = 10004; +SELECT * FROM tbl_a WHERE a = 10004; +UPDATE tbl_a SET b = trim(TRAILING '[' FROM b) WHERE a = 10005; +SELECT * FROM tbl_a WHERE a = 10005; +UPDATE tbl_a SET b = trim(LEADING '[' FROM trim(TRAILING ']' FROM b)) WHERE a = 10006; +SELECT * FROM tbl_a WHERE a = 10006; +UPDATE tbl_a SET b = trim(TRAILING '[' FROM trim(LEADING ']' FROM b)) WHERE a = 10007; +SELECT * FROM tbl_a WHERE a = 10007; +UPDATE tbl_a SET b = trim(TRAILING ']' FROM trim(LEADING '[' FROM b)) WHERE a = 10008; +SELECT * FROM tbl_a WHERE a = 10008; +UPDATE tbl_a SET b = trim(BOTH '*' FROM trim(TRAILING ']' FROM trim(LEADING '[' FROM b))) WHERE a = 10009; +SELECT * FROM tbl_a WHERE a = 10009; + +--echo +--echo deinit +--disable_warnings + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; + +--enable_warnings +--source ../include/mdev_24020_deinit.inc +--echo +--echo end of test diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.test new file mode 100644 index 00000000000..21b9dda4f12 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24517.test @@ -0,0 +1,80 @@ +--source ../include/mdev_24517_init.inc +--echo +--echo this test is for MDEV-24517 +--echo +--echo drop and create databases + +--connection master_1 +--disable_warnings +CREATE DATABASE auto_test_local; +USE auto_test_local; + +--connection child2_1 +SET @old_log_output = @@global.log_output; +SET GLOBAL log_output = 'TABLE,FILE'; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +--enable_warnings + +--echo +--echo create table and insert + +--connection child2_1 +--disable_query_log +--disable_ps_protocol +echo CHILD2_1_CREATE_TABLES; +eval $CHILD2_1_CREATE_TABLES; +--enable_ps_protocol +--enable_query_log +TRUNCATE TABLE mysql.general_log; + +--connection master_1 +--disable_query_log +echo CREATE TABLE tbl_a ( + i INT, + j JSON, + PRIMARY KEY(i) +) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1; +eval CREATE TABLE tbl_a ( + i INT, + j JSON, + PRIMARY KEY(i) +) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1; +--enable_query_log +INSERT INTO tbl_a (i, j) VALUES + (1, '{"ID": "3", "Name": "Barney", "Age": 18}'), + (2, '{"ID": "4", "Name": "Betty", "Age": 19}'), + (3, '{"ID": "2", "Name": "Wilma", "Age": 20}'), + (4, '[10, 20, [30, 40]]'); + +--echo +--echo test 1 + +--connection child2_1 +TRUNCATE TABLE mysql.general_log; + +--connection master_1 +SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$.Age')=19; +SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$.Name')="Betty"; +SELECT i, JSON_EXTRACT(j, "$.ID") + FROM tbl_a + WHERE JSON_EXTRACT(j, "$.ID") > 1 AND i < 4 + ORDER BY JSON_EXTRACT(j, "$.Name"); +SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$[1]') = 20; +SELECT * FROM tbl_a WHERE JSON_EXTRACT(j, '$[2][0]') = 30; + +--echo +--echo deinit +--disable_warnings + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; +SET GLOBAL log_output = @old_log_output; + +--enable_warnings +--source ../include/mdev_24517_deinit.inc +--echo +--echo end of test diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.test new file mode 100644 index 00000000000..149b057d003 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24760.test @@ -0,0 +1,49 @@ +--echo # +--echo # MDEV-24760 SELECT..CASE statement syntax error at Spider Engine table +--echo # + +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_query_log +--enable_result_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +DROP TABLE IF EXISTS tbl_a; +eval CREATE TABLE tbl_a ( + id int NOT NULL AUTO_INCREMENT, + name varchar(255) DEFAULT NULL, + PRIMARY KEY (id) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +INSERT INTO tbl_a (name) VALUES ('Alice'), ('Bob'); + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; + +eval CREATE TABLE tbl_a ( + id int NOT NULL AUTO_INCREMENT, + name varchar(255) DEFAULT NULL, + PRIMARY KEY (id) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a"' +PARTITION BY HASH(id) ( + PARTITION pt1 COMMENT='srv "s_2_1"' +); + +SELECT id, CASE WHEN name='Alice' THEN "A" WHEN name='Bob' THEN "B" END FROM tbl_a; +SELECT id, CASE name WHEN 'Alice' THEN "A" WHEN 'Bob' THEN "B" END FROM tbl_a; + +DROP DATABASE auto_test_local; + +--connection child2_1 +DROP DATABASE auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_query_log +--enable_result_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26013.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_26013.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26013.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26013.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26013.test new file mode 100644 index 00000000000..e31041c3bf1 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26013.test @@ -0,0 +1,51 @@ +--disable_warnings +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +--enable_warnings + +--echo +--echo MDEV-26013 distinct not work properly in some cases for spider tables +--echo + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +eval CREATE TABLE tbl_a ( + `a`int, + `b`int, + PRIMARY KEY (`a`) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +insert into `tbl_a` VALUES (1,999), (2,999); + +--connection master_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +eval CREATE TABLE tbl_a ( + `a`int, + `b`int, + PRIMARY KEY (`a`) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a"' PARTITION BY LIST COLUMNS(`a`) ( + PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' +); + +--connection master_1 +SELECT distinct b FROM tbl_a WHERE b=999; + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_remote; +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; + +--disable_warnings +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--enable_warnings diff --git a/storage/spider/mysql-test/spider/include/init_master_1.inc b/storage/spider/mysql-test/spider/include/init_master_1.inc index 2c45d0bd65d..460142b9c7d 100644 --- a/storage/spider/mysql-test/spider/include/init_master_1.inc +++ b/storage/spider/mysql-test/spider/include/init_master_1.inc @@ -152,6 +152,11 @@ let $MASTER_1_COMMENT_TEXT_PK1_1= COMMENT 'tbl "t1", srv "s_2_1"'; let $MASTER_1_COMMENT_TEXT_KEY1_1= COMMENT 'tbl "t1", srv "s_2_1"'; +let $MASTER_1_COMMENT_MDEV_25985= + COMMENT='table "t1"' + PARTITION BY LIST COLUMNS(`a`) ( + PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' + ); let $MASTER_1_CHECK_DIRECT_UPDATE_STATUS= SHOW STATUS LIKE 'Spider_direct_update'; let $MASTER_1_CHECK_DIRECT_DELETE_STATUS= diff --git a/storage/spider/mysql-test/spider/r/spider_fixes_part.result b/storage/spider/mysql-test/spider/r/spider_fixes_part.result index 234d52fed0d..571af94c1f2 100644 --- a/storage/spider/mysql-test/spider/r/spider_fixes_part.result +++ b/storage/spider/mysql-test/spider/r/spider_fixes_part.result @@ -262,6 +262,40 @@ a b c d e f 56B68DA68D6D4A04A08B453D09AD7B70 821E71E6ABB4404EBAA349BB681089F8 51041110620310 2018-08-02 13:48:28 510411 0 51ECF2C0CD3C48D99C91792E99D3C1A0 017B8A460DBC444682B791305EF75356 51041110620308 2018-08-02 13:48:29 510411 0 093B37A93A534DF883787AF5F6799674 996C7F14989D480589A553717D735E3E 51041110620302 2018-08-02 13:48:30 510411 0 +# +# MDEV-25985 Spider handle ">=" as ">" in some cases +# +connection child2_1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( +a int, +b int, +c int, +PRIMARY KEY (a), +KEY (b,c) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES (1, 1, 1), (2, 2, 1); +connection master_1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( +a int, +b int, +c int, +PRIMARY KEY (a), +KEY (b,c) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "t1"' + PARTITION BY LIST COLUMNS(`a`) ( +PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' + ); +connection master_1; +SELECT * FROM t1 WHERE c > 0 AND b >= 1 AND b <= 2; +a b c +1 1 1 +2 2 1 +SELECT * FROM t1 WHERE c < 3 AND b <= 2; +a b c +1 1 1 +2 2 1 Crash from b4a2baffa82e5c07b96a1c752228560dcac1359b (MDEV-11084) Fixed with 4968049799193394d442f26b4e3a8d95b185be72 diff --git a/storage/spider/mysql-test/spider/t/spider_fixes_part.test b/storage/spider/mysql-test/spider/t/spider_fixes_part.test index b0b9ce86588..d2be62a6d31 100644 --- a/storage/spider/mysql-test/spider/t/spider_fixes_part.test +++ b/storage/spider/mysql-test/spider/t/spider_fixes_part.test @@ -726,6 +726,41 @@ if ($HAVE_PARTITION) } } + +--echo # +--echo # MDEV-25985 Spider handle ">=" as ">" in some cases +--echo # + +--connection child2_1 +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +eval CREATE TABLE t1 ( + a int, + b int, + c int, + PRIMARY KEY (a), + KEY (b,c) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +INSERT INTO t1 VALUES (1, 1, 1), (2, 2, 1); + +--connection master_1 +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +eval CREATE TABLE t1 ( + a int, + b int, + c int, + PRIMARY KEY (a), + KEY (b,c) +) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_MDEV_25985; + +--connection master_1 +SELECT * FROM t1 WHERE c > 0 AND b >= 1 AND b <= 2; +SELECT * FROM t1 WHERE c < 3 AND b <= 2; + --echo --echo Crash from b4a2baffa82e5c07b96a1c752228560dcac1359b (MDEV-11084) --echo Fixed with 4968049799193394d442f26b4e3a8d95b185be72 diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 2305173ab00..22567d82bc1 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -2033,12 +2033,20 @@ int spider_db_append_key_where_internal( case HA_READ_AFTER_KEY: if (sql_kind == SPIDER_SQL_KIND_SQL) { + const char* op_str; + uint32 op_len; + if (start_key_part_map == 1) { + op_str = SPIDER_SQL_GT_STR; + op_len = SPIDER_SQL_GT_LEN; + } else { + op_str = SPIDER_SQL_GTEQUAL_STR; + op_len = SPIDER_SQL_GTEQUAL_LEN; + } if (str->reserve(store_length + key_name_length + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + - SPIDER_SQL_GT_LEN)) + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + op_len)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_GT_STR, SPIDER_SQL_GT_LEN); + str->q_append(op_str, op_len); if (spider_dbton[dbton_id].db_util-> append_column_value(spider, str, field, ptr, share->access_charset)) @@ -2106,12 +2114,20 @@ int spider_db_append_key_where_internal( result_list->desc_flg = TRUE; if (sql_kind == SPIDER_SQL_KIND_SQL) { + const char* op_str; + uint32 op_len; + if (start_key_part_map == 1) { + op_str = SPIDER_SQL_LT_STR; + op_len = SPIDER_SQL_LT_LEN; + } else { + op_str = SPIDER_SQL_LTEQUAL_STR; + op_len = SPIDER_SQL_LTEQUAL_LEN; + } if (str->reserve(store_length + key_name_length + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + - SPIDER_SQL_LT_LEN)) + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + op_len)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); + str->q_append(op_str, op_len); if (spider_dbton[dbton_id].db_util-> append_column_value(spider, str, field, ptr, share->access_charset)) @@ -2524,12 +2540,20 @@ int spider_db_append_key_where_internal( case HA_READ_BEFORE_KEY: if (sql_kind == SPIDER_SQL_KIND_SQL) { + const char* op_str; + uint32 op_len; + if (end_key_part_map == 1) { + op_str = SPIDER_SQL_LT_STR; + op_len = SPIDER_SQL_LT_LEN; + } else { + op_str = SPIDER_SQL_LTEQUAL_STR; + op_len = SPIDER_SQL_LTEQUAL_LEN; + } if (str->reserve(store_length + key_name_length + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + - SPIDER_SQL_LT_LEN)) + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + op_len)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); + str->q_append(op_str, op_len); if (spider_dbton[dbton_id].db_util-> append_column_value(spider, str, field, ptr, share->access_charset)) diff --git a/storage/spider/spd_db_conn.h b/storage/spider/spd_db_conn.h index 0b69253c43b..8af820c7dfa 100644 --- a/storage/spider/spd_db_conn.h +++ b/storage/spider/spd_db_conn.h @@ -257,6 +257,15 @@ #define SPIDER_SQL_B_STR "b" #define SPIDER_SQL_B_LEN (sizeof(SPIDER_SQL_B_STR) - 1) +#define SPIDER_SQL_TRIM_STR "trim" +#define SPIDER_SQL_TRIM_LEN sizeof(SPIDER_SQL_TRIM_STR) - 1 +#define SPIDER_SQL_TRIM_BOTH_STR "both " +#define SPIDER_SQL_TRIM_BOTH_LEN sizeof(SPIDER_SQL_TRIM_BOTH_STR) - 1 +#define SPIDER_SQL_TRIM_LEADING_STR "leading " +#define SPIDER_SQL_TRIM_LEADING_LEN sizeof(SPIDER_SQL_TRIM_LEADING_STR) - 1 +#define SPIDER_SQL_TRIM_TRAILING_STR "trailing " +#define SPIDER_SQL_TRIM_TRAILING_LEN sizeof(SPIDER_SQL_TRIM_TRAILING_STR) - 1 + #define SPIDER_SQL_INDEX_IGNORE_STR " IGNORE INDEX " #define SPIDER_SQL_INDEX_IGNORE_LEN (sizeof(SPIDER_SQL_INDEX_IGNORE_STR) - 1) #define SPIDER_SQL_INDEX_USE_STR " USE INDEX " diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 95185bbf1ce..57e3893d09b 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -5869,72 +5869,106 @@ int spider_db_mbase_util::open_item_func( DBUG_RETURN(spider_db_open_item_int(item_func, NULL, spider, str, alias, alias_length, dbton_id, use_fields, fields)); } else if ( - !strncasecmp("case", func_name, func_name_length) + !strncasecmp("trim", func_name, func_name_length) && + item_count == 2 ) { -#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC - Item_func_case *item_func_case = (Item_func_case *) item_func; - if (str) - { - if (str->reserve(SPIDER_SQL_CASE_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_CASE_STR, SPIDER_SQL_CASE_LEN); - } - if (item_func_case->first_expr_num != -1) - { - if ((error_num = spider_db_print_item_type( - item_list[item_func_case->first_expr_num], NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - } - for (roop_count = 0; roop_count < item_func_case->ncases; - roop_count += 2) + /* item_count == 1 means this TRIM() is without a remove_str */ + item = item_list[0]; + Item *item_tmp = item_list[1]; + if (str) { - if (str) + if (item_tmp->is_of_type(Item::CONST_ITEM, STRING_RESULT)) { - if (str->reserve(SPIDER_SQL_WHEN_LEN)) + /* 1. append 'TRIM(BOTH ' */ + if (str->reserve(SPIDER_SQL_TRIM_LEN + SPIDER_SQL_OPEN_PAREN_LEN + + SPIDER_SQL_TRIM_BOTH_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_WHEN_STR, SPIDER_SQL_WHEN_LEN); - } - if ((error_num = spider_db_print_item_type( - item_list[roop_count], NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - if (str) - { - if (str->reserve(SPIDER_SQL_THEN_LEN)) + str->q_append(SPIDER_SQL_TRIM_STR, SPIDER_SQL_TRIM_LEN); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR, + SPIDER_SQL_OPEN_PAREN_LEN); + str->q_append(SPIDER_SQL_TRIM_BOTH_STR, SPIDER_SQL_TRIM_BOTH_LEN); + /* 2. append "remove_str"*/ + if ((error_num = spider_db_print_item_type( + item_tmp, NULL, spider, str, alias, alias_length, dbton_id, + use_fields, fields))) + DBUG_RETURN(error_num); + /* 3. append ' FROM ' */ + if (str->reserve(SPIDER_SQL_FROM_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN); + /* 4. append `field` */ + if ((error_num = spider_db_print_item_type( + item, NULL, spider, str, alias, alias_length, dbton_id, + use_fields, fields))) + DBUG_RETURN(error_num); + /* 5. append ')' */ + if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_THEN_STR, SPIDER_SQL_THEN_LEN); + str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, + SPIDER_SQL_CLOSE_PAREN_LEN); } - if ((error_num = spider_db_print_item_type( - item_list[roop_count + 1], NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); } - if (item_func_case->else_expr_num != -1) + item_count -= 2; + break; + } + } else if (func_name_length == 5) + { + if ( + (!strncasecmp("ltrim", func_name, func_name_length) || + !strncasecmp("rtrim", func_name, func_name_length)) && + (item_count == 2) + ) { + /* the func_name for TRIM(LEADING ...) is LTRIM, for TRIM(TRAILING) is RTRIM */ + /* item_count == 2 means this TRIM(LEADING/TRAILING ...) is with a remove_str */ + item = item_list[0]; + Item *item_tmp = item_list[1]; + if (str) { - if (str) + if (item_tmp->is_of_type(Item::CONST_ITEM, STRING_RESULT)) { - if (str->reserve(SPIDER_SQL_ELSE_LEN)) + /* 1. append 'TRIM(LEADING ' or 'TRIM(TRAILING ' */ + if (func_name[0] == 'l' || func_name[0] == 'L') + { /* ltrim */ + if (str->reserve(SPIDER_SQL_TRIM_LEN + SPIDER_SQL_OPEN_PAREN_LEN + + SPIDER_SQL_TRIM_LEADING_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_TRIM_STR, SPIDER_SQL_TRIM_LEN); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR, + SPIDER_SQL_OPEN_PAREN_LEN); + str->q_append(SPIDER_SQL_TRIM_LEADING_STR, SPIDER_SQL_TRIM_LEADING_LEN); + } else + { /* rtrim */ + if (str->reserve(SPIDER_SQL_TRIM_LEN + SPIDER_SQL_OPEN_PAREN_LEN + + SPIDER_SQL_TRIM_TRAILING_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_TRIM_STR, SPIDER_SQL_TRIM_LEN); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR, + SPIDER_SQL_OPEN_PAREN_LEN); + str->q_append(SPIDER_SQL_TRIM_TRAILING_STR, SPIDER_SQL_TRIM_TRAILING_LEN); + } + /* 2. append "remove_str"*/ + if ((error_num = spider_db_print_item_type( + item_tmp, NULL, spider, str, alias, alias_length, dbton_id, + use_fields, fields))) + DBUG_RETURN(error_num); + /* 3. append ' FROM ' */ + if (str->reserve(SPIDER_SQL_FROM_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_ELSE_STR, SPIDER_SQL_ELSE_LEN); + str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN); + /* 4. append `field` */ + if ((error_num = spider_db_print_item_type( + item, NULL, spider, str, alias, alias_length, dbton_id, + use_fields, fields))) + DBUG_RETURN(error_num); + /* 5. append ')' */ + if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, + SPIDER_SQL_CLOSE_PAREN_LEN); } - if ((error_num = spider_db_print_item_type( - item_list[item_func_case->else_expr_num], NULL, spider, str, - alias, alias_length, dbton_id, use_fields, fields))) - DBUG_RETURN(error_num); - } - if (str) - { - if (str->reserve(SPIDER_SQL_END_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_END_STR, SPIDER_SQL_END_LEN); - str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, - SPIDER_SQL_CLOSE_PAREN_LEN); } - DBUG_RETURN(0); -#else - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); -#endif + item_count -= 2; + break; } } else if (func_name_length == 6 && !strncasecmp("istrue", func_name, func_name_length) @@ -6766,6 +6800,89 @@ int spider_db_mbase_util::open_item_func( #else DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); #endif + case Item_func::CASE_SEARCHED_FUNC: + case Item_func::CASE_SIMPLE_FUNC: +#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC + Item_func_case *item_func_case = (Item_func_case *) item_func; + if (str) + { + if (str->reserve(SPIDER_SQL_CASE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CASE_STR, SPIDER_SQL_CASE_LEN); + } + if (item_func_case->first_expr_num != -1) + { + if ((error_num = spider_db_print_item_type( + item_list[item_func_case->first_expr_num], NULL, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + } + for (roop_count = 0; roop_count < item_func_case->ncases; + roop_count += 2) + { + if (str) + { + if (str->reserve(SPIDER_SQL_WHEN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_WHEN_STR, SPIDER_SQL_WHEN_LEN); + } + if ((error_num = spider_db_print_item_type( + item_list[roop_count], NULL, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + if (str) + { + if (str->reserve(SPIDER_SQL_THEN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_THEN_STR, SPIDER_SQL_THEN_LEN); + } + if ((error_num = spider_db_print_item_type( + item_list[roop_count + 1], NULL, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + } + if (item_func_case->else_expr_num != -1) + { + if (str) + { + if (str->reserve(SPIDER_SQL_ELSE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_ELSE_STR, SPIDER_SQL_ELSE_LEN); + } + if ((error_num = spider_db_print_item_type( + item_list[item_func_case->else_expr_num], NULL, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + } + if (str) + { + if (str->reserve(SPIDER_SQL_END_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_END_STR, SPIDER_SQL_END_LEN); + str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, + SPIDER_SQL_CLOSE_PAREN_LEN); + } + DBUG_RETURN(0); +#else + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); +#endif + case Item_func::JSON_EXTRACT_FUNC: + func_name = (char*) item_func->func_name(); + func_name_length = strlen(func_name); + if (str) + { + if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(func_name, func_name_length); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); + } + func_name = SPIDER_SQL_COMMA_STR; + func_name_length = SPIDER_SQL_COMMA_LEN; + separator_str = SPIDER_SQL_COMMA_STR; + separator_str_length = SPIDER_SQL_COMMA_LEN; + last_str = SPIDER_SQL_CLOSE_PAREN_STR; + last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; + break; default: THD *thd = spider->wide_handler->trx->thd; SPIDER_SHARE *share = spider->share; diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index 35673d0fc8d..cc7911da557 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -7266,7 +7266,7 @@ int ha_tokudb::create( // in the database directory, so automatic filename-based // discover_table_names() doesn't work either. So, it must force .frm // file to disk. - form->s->write_frm_image(); + error= form->s->write_frm_image(); #endif #if defined(TOKU_INCLUDE_OPTION_STRUCTS) && TOKU_INCLUDE_OPTION_STRUCTS @@ -7298,8 +7298,8 @@ int ha_tokudb::create( #endif // defined(TOKU_INCLUDE_OPTION_STRUCTS) && TOKU_INCLUDE_OPTION_STRUCTS const toku_compression_method compression_method = row_format_to_toku_compression_method(row_format); - bool create_from_engine = (create_info->table_options & HA_OPTION_CREATE_FROM_ENGINE); + if (error) { goto cleanup; } if (create_from_engine) { // table already exists, nothing to do error = 0; diff --git a/storage/tokudb/mysql-test/tokudb/r/bug-23786.result b/storage/tokudb/mysql-test/tokudb/r/bug-23786.result new file mode 100644 index 00000000000..1b21758b85a --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb/r/bug-23786.result @@ -0,0 +1,10 @@ +# +# 10.2 Test +# +# MDEV-23786: Assertion `!is_set() || (m_status == DA_OK_BULK && +# is_bulk_op())'failed for TokuDB engine CREATE TABLE +# +set default_storage_engine='tokudb'; +CREATE TABLE _uppercase.t (a INT) ENGINE=TokuDB; +ERROR 42000: Unknown database '_uppercase' +# End of 10.2 Test diff --git a/storage/tokudb/mysql-test/tokudb/t/bug-23786.test b/storage/tokudb/mysql-test/tokudb/t/bug-23786.test new file mode 100644 index 00000000000..a8a0c4a1577 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb/t/bug-23786.test @@ -0,0 +1,14 @@ +source include/have_tokudb.inc; + +--echo # +--echo # 10.2 Test +--echo # +--echo # MDEV-23786: Assertion `!is_set() || (m_status == DA_OK_BULK && +--echo # is_bulk_op())'failed for TokuDB engine CREATE TABLE +--echo # + +set default_storage_engine='tokudb'; +--error ER_BAD_DB_ERROR +CREATE TABLE _uppercase.t (a INT) ENGINE=TokuDB; + +--echo # End of 10.2 Test diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 0e5a62a9514..8ca2ccdb64a 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -79,7 +79,7 @@ IF(UNIX) INSTALL(FILES ${out} DESTINATION ${inst_location}/policy/selinux COMPONENT SupportFiles) ENDFOREACH() IF(RPM) - EXECUTE_PROCESS(COMMAND rpm -q --qf "%{VERSION}-%{RELEASE}" libsepol + EXECUTE_PROCESS(COMMAND rpm -q --qf "%{VERSION}" libsepol OUTPUT_VARIABLE LIBSEPOL_VERSION RESULT_VARIABLE err) IF (NOT err) SET(CPACK_RPM_server_PACKAGE_REQUIRES diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 7587e08e727..9614d6a8880 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -20773,6 +20773,71 @@ static void test_ps_params_in_ctes() myquery(rc); } +void display_result_metadata(MYSQL_FIELD *field, + uint num_fields) +{ + MYSQL_FIELD* field_end; + + mct_log("Catalog\tDatabase\tTable\tTable_alias\tColumn\t" + "Column_alias\tType\tLength\tMax length\tIs_null\t" + "Flags\tDecimals\tCharsetnr\n"); + for (field_end= field+num_fields; field < field_end; field++) + { + mct_log("%s\t", field->catalog); + mct_log("%s\t", field->db); + mct_log("%s\t", field->org_table); + mct_log("%s\t", field->table); + mct_log("%s\t", field->org_name); + mct_log("%s\t", field->name); + mct_log("%u\t", field->type); + mct_log("%lu\t", field->length); + mct_log("%lu\t", field->max_length); + mct_log("%s\t", (IS_NOT_NULL(field->flags) ? "N" : "Y")); + mct_log("%u\t", field->flags); + mct_log("%u\t", field->decimals); + mct_log("%u\n", field->charsetnr); + } +} + +static void test_mdev_26145() +{ + MYSQL_STMT *stmt; + MYSQL_RES *result; + MYSQL_FIELD *fields; + int rc, num_fields; + + myheader("test_mdev_26145"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + + rc= mysql_query(mysql, "CREATE TABLE t1(a INT)"); + myquery(rc); + + stmt= mysql_simple_prepare( + mysql, "(SELECT MAX(a) FROM t1) UNION (SELECT MAX(a) FROM t1)"); + check_stmt(stmt); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + result= mysql_stmt_result_metadata(stmt); + DIE_UNLESS(result); + + num_fields= mysql_stmt_field_count(stmt); + fields= mysql_fetch_fields(result); + + mct_start_logging("test_mdev26145"); + display_result_metadata(fields, num_fields); + mct_close_log(); + + mysql_free_result(result); + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "DROP TABLE t1"); + + myquery(rc); +} static void print_metadata(MYSQL_RES *rs_metadata, int num_fields) { @@ -21310,6 +21375,7 @@ static void test_mdev20261() static struct my_tests_st my_tests[]= { + { "test_mdev_26145", test_mdev_26145 }, { "disable_query_logs", disable_query_logs }, { "test_view_sp_list_fields", test_view_sp_list_fields }, { "client_query", client_query }, diff --git a/wsrep-lib b/wsrep-lib -Subproject 85b815032145ef5c18b7a8931d84becf6df8cd1 +Subproject c45b1eff940077e2b2f364f30ba04930f134da8 |