diff --git a/CMakeLists.txt b/CMakeLists.txt index d6cf989711d..b8b3f5c7d12 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) @@ -449,12 +450,15 @@ ADD_SUBDIRECTORY(sql/share) 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) @@ -548,6 +552,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/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index 19a4b484538..454e008363f 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -157,6 +157,9 @@ SETA(CPACK_RPM_client_PACKAGE_PROVIDES SETA(CPACK_RPM_client_PACKAGE_CONFLICTS "MariaDB-server < 10.6.0") +SETA(CPACK_RPM_common_PACKAGE_CONFLICTS + "MariaDB-server < 10.6.1") + SETA(CPACK_RPM_devel_PACKAGE_OBSOLETES "MySQL-devel") SETA(CPACK_RPM_devel_PACKAGE_PROVIDES @@ -181,7 +184,7 @@ SETA(CPACK_RPM_test_PACKAGE_PROVIDES "MySQL-test") SETA(CPACK_RPM_server_PACKAGE_REQUIRES - "${CPACK_RPM_PACKAGE_REQUIRES}" + "MariaDB-common >= 10.6.1" "MariaDB-client") IF(WITH_WSREP) 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/pcre.cmake b/cmake/pcre.cmake index 009dbbe5ae1..3d4f163fab9 100644 --- a/cmake/pcre.cmake +++ b/cmake/pcre.cmake @@ -43,8 +43,8 @@ MACRO(BUNDLE_PCRE2) ExternalProject_Add( pcre2 PREFIX "${dir}" - URL "http://ftp.pcre.org/pub/pcre/pcre2-10.36.zip" - URL_MD5 ba9e743af42aac5642f7504b12af4116 + URL "http://ftp.pcre.org/pub/pcre/pcre2-10.37.zip" + URL_MD5 8c1699a725d4b28410adf4b964ebbcb7 INSTALL_COMMAND "" CMAKE_ARGS "-DPCRE2_BUILD_TESTS=OFF" 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 c223716faeb..303b3a25aa9 100644 --- a/cmake/systemd.cmake +++ b/cmake/systemd.cmake @@ -70,5 +70,6 @@ LimitMEMLOCK=524288") 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 5d2ba365d65..740bf812304 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 e033c3f942f..e1f368a2c0f 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; @@ -72,9 +72,9 @@ static ulint physical_page_size; /* Page size in bytes on disk. */ ulong srv_page_size; uint32_t 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 rewrite checksum. */ @@ -434,11 +434,11 @@ static bool is_page_corrupted(byte *buf, bool is_encrypted, uint32_t flags) /* 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); @@ -456,8 +456,8 @@ static bool is_page_corrupted(byte *buf, bool is_encrypted, uint32_t flags) 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); } @@ -486,13 +486,14 @@ static bool is_page_corrupted(byte *buf, bool is_encrypted, uint32_t flags) 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); @@ -516,9 +517,9 @@ static bool is_page_corrupted(byte *buf, bool is_encrypted, uint32_t flags) 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 { @@ -621,8 +622,8 @@ static bool update_checksum(byte* page, uint32_t 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) { @@ -633,7 +634,7 @@ static bool update_checksum(byte* page, uint32_t 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; @@ -645,8 +646,9 @@ static bool update_checksum(byte* page, uint32_t 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); } mach_write_to_4(page + physical_page_size - @@ -720,7 +722,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); @@ -737,6 +740,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 @@ -752,12 +765,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; @@ -772,7 +783,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 */ @@ -796,7 +807,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, @@ -814,22 +825,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::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; } @@ -857,8 +859,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; @@ -868,7 +870,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++; @@ -920,7 +922,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; @@ -928,7 +930,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; @@ -936,7 +938,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; @@ -944,7 +946,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; @@ -952,33 +954,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; @@ -986,7 +986,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; @@ -994,7 +994,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; @@ -1002,7 +1002,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; @@ -1010,7 +1010,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; @@ -1018,7 +1018,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; @@ -1170,14 +1170,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}, {"no-check", 'n', "Ignore the checksum verification.", &no_check, &no_check, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"allow-mismatches", 'a', "Maximum checksum mismatch allowed.", @@ -1335,14 +1335,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); } @@ -1364,7 +1364,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)++; @@ -1631,33 +1631,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 = (uint32_t) (size / physical_page_size); + pages = uint32_t(size / physical_page_size); if (just_count) { fprintf(read_from_stdin ? stderr : stdout, - "Number of pages:%u\n", pages); + "Number of pages:" UINT32PF "\n", pages); continue; } else if (verbose && !read_from_stdin) { if (is_log_enabled) { fprintf(log_file, "file %s = %llu bytes " - "(%u 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)); } @@ -1701,8 +1706,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 " @@ -1743,12 +1748,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; } } } @@ -1764,6 +1764,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; } @@ -1805,6 +1814,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))) { @@ -1823,7 +1833,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) { @@ -1839,7 +1853,7 @@ 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), (double) cur_page_num / pages * 100); diff --git a/extra/mariabackup/CMakeLists.txt b/extra/mariabackup/CMakeLists.txt index 41de993317e..5776a7ddab3 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 6250f18ba39..a2251bcf5d7 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -918,7 +918,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/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index f579ae51f68..6c4cd3537f5 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -51,7 +51,7 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include #include #include -#include +#include #include #include diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c index f73ac7825b6..b7f52382721 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -141,28 +141,50 @@ static int get_options(int *argc,char ***argv) return 0; } +static char *make_args(const char *s1, const char *s2) +{ + char *s= malloc(strlen(s1) + strlen(s2) + 1); + strmov(strmov(s, s1), s2); + return s; +} int main(int argc, char **argv) { - int count, error, args_used; + int count= 0, error, no_defaults= 0; char **load_default_groups= 0, *tmp_arguments[6]; char **argument, **arguments, **org_argv; int nargs, i= 0; MY_INIT(argv[0]); org_argv= argv; - args_used= get_defaults_options(argv); - - /* Copy defaults-xxx arguments & program name */ - count=args_used; + if (*argv && !strcmp(*argv, "--no-defaults")) + { + argv++; + ++count; + no_defaults= 1; + } + /* Copy program name and --no-defaults if present*/ arguments= tmp_arguments; - memcpy((char*) arguments, (char*) org_argv, count * sizeof(*org_argv)); + memcpy((char*) arguments, (char*) org_argv, (++count)*sizeof(*org_argv)); arguments[count]= 0; /* Check out the args */ if (get_options(&argc,&argv)) cleanup_and_exit(1); + if (!no_defaults) + { + if (opt_defaults_file_used) + arguments[count++]= make_args("--defaults-file=", config_file); + if (my_defaults_extra_file) + arguments[count++]= make_args("--defaults-extra-file=", + my_defaults_extra_file); + if (my_defaults_group_suffix) + arguments[count++]= make_args("--defaults-group-suffix=", + my_defaults_group_suffix); + arguments[count]= 0; + } + nargs= argc + 1; if (opt_mysqld) nargs+= array_elements(mysqld_groups); diff --git a/extra/wolfssl/CMakeLists.txt b/extra/wolfssl/CMakeLists.txt index 0137d3539dc..b38d57d3710 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 index 9c87f979a7f..add4a68465b 160000 --- a/extra/wolfssl/wolfssl +++ b/extra/wolfssl/wolfssl @@ -1 +1 @@ -Subproject commit 9c87f979a7f1d3a6d786b260653d566c1d31a1c4 +Subproject commit add4a68465bcdad238bcf3e5f2771d8da05e6285 diff --git a/include/my_sys.h b/include/my_sys.h index b1f7c322360..dae4777db11 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -279,7 +279,8 @@ LPSECURITY_ATTRIBUTES my_win_file_secattr(); 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 index c288f7d0b6f..7cf38704c91 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit c288f7d0b6fcb82cb8231293f5c03d5e5de46813 +Subproject commit 7cf38704c916996e7b44f62c9e644cc6d001ee91 diff --git a/mysql-test/dgcov.pl b/mysql-test/dgcov.pl index 525db191efa..639f3a5b72a 100755 --- a/mysql-test/dgcov.pl +++ b/mysql-test/dgcov.pl @@ -155,7 +155,7 @@ 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): $? $!"; @@ -167,25 +167,27 @@ sub gcov_one_file { { return; } - open FH, '<', "$gcov_file_path" or die "open(<$gcov_file_path): $!"; - my $fname; - while () { - chomp; - if (/^function:/) { - next; + for my $gcov_file (<$_*.gcov>) { + open FH, '<', "$gcov_file_path" or die "open(<$gcov_file_path): $!"; + my $fname; + while () { + 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; } - 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; - } - $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 4c64a546f65..a384aa584c4 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; @@ -121,8 +122,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 eb9150ec86f..f8c41dbc3ea 100644 --- a/mysql-test/main/cte_recursive.test +++ b/mysql-test/main/cte_recursive.test @@ -1,7 +1,3 @@ -if (`SELECT $PS_PROTOCOL != 0`) -{ - --skip Test temporarily disabled for ps-protocol -} --source include/default_optimizer_switch.inc create table t1 (a int, b varchar(32)); @@ -2594,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; @@ -2858,6 +2854,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_group.test b/mysql-test/main/func_group.test index 949d40dda1a..71129352aae 100644 --- a/mysql-test/main/func_group.test +++ b/mysql-test/main/func_group.test @@ -2,11 +2,6 @@ # simple test of all group functions # -if (`SELECT $PS_PROTOCOL != 0`) -{ - --skip Test temporarily disabled for ps-protocol -} - --disable_warnings drop table if exists t1,t2,t3,t4,t5,t6; --enable_warnings diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index dc787219b73..f6f8db95f98 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 @@ -2093,6 +2093,24 @@ SELECT c1 FROM t2; 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/insert_returning.result b/mysql-test/main/insert_returning.result index e664e02bedc..a3cde7b1270 100644 --- a/mysql-test/main/insert_returning.result +++ b/mysql-test/main/insert_returning.result @@ -89,6 +89,9 @@ total val1 id1 && id1 id1 UPPER(val1) f(id1) ANALYZE INSERT INTO t1(id1,val1) VALUES(13,'l') RETURNING *; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL +INSERT INTO t1(id1,val1) VALUES(14,'m') RETURNING t1.*; +id1 val1 +14 m TRUNCATE TABLE t1; # # Multiple values in one insert statement...RETURNING @@ -182,6 +185,9 @@ id val1 id1 && id1 id1|id1 UPPER(val1) f(id1) ANALYZE INSERT INTO t1 VALUES(25,'a'),(26,'b') RETURNING *; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL +ANALYZE INSERT INTO t1 VALUES(27,'c'),(28,'d') RETURNING t1.*; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL # # INSERT...ON DUPLICATE KEY UPDATE...RETURNING # @@ -250,10 +256,14 @@ ANALYZE INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE val='k' RETURNING *; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 INSERT ins_duplicate ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL +INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE +val='l' RETURNING ins_duplicate.*; +id val +2 l SELECT * FROM ins_duplicate; id val 1 a -2 k +2 l 3 c 4 d # @@ -327,6 +337,9 @@ total val1 id1 && id1 id1|id1 UPPER(val1) f(id1) ANALYZE INSERT INTO t1 SET id1=12, val1='l' RETURNING *; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 INSERT t1 ALL NULL NULL NULL NULL NULL NULL 100.00 100.00 NULL +INSERT INTO t1 SET id1= 13, val1= 'm' RETURNING t1.*; +id1 val1 +13 m SELECT * FROM t1; id1 val1 1 a @@ -339,6 +352,7 @@ id1 val1 8 n 26 Z 12 l +13 m # # INSERT...SELECT...RETURNING # @@ -372,6 +386,7 @@ id1 val1 8 n 26 Z 12 l +13 m EXECUTE stmt; (SELECT id1 FROM t1 WHERE val1='b') 2 @@ -407,6 +422,7 @@ id2 val2 5 e 26 Z 12 l +13 m Warnings: Warning 1062 Duplicate entry '1' for key 'PRIMARY' Warning 1062 Duplicate entry '2' for key 'PRIMARY' @@ -430,6 +446,18 @@ id2 val2 5 e 26 Z 12 l +13 m +TRUNCATE TABLE t2; +INSERT INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING t2.*; +id2 val2 +1 a +INSERT INTO t2 SELECT t1.* FROM t1 WHERE id1=2 RETURNING t2.*; +id2 val2 +2 b +SELECT * FROM t2; +id2 val2 +1 a +2 b DROP TABLE t1; DROP TABLE t2; DROP TABLE ins_duplicate; @@ -460,6 +488,8 @@ t1 WHERE id1=1) 5 6 INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2); ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data +INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*; +ERROR 42S02: Unknown table 'test.t1' # # Multiple rows in single insert statement # @@ -481,6 +511,8 @@ t1 WHERE id1=1) 12 13 INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING (SELECT id2 FROM t2); ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data +INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING t1.*; +ERROR 42S02: Unknown table 'test.t1' # # INSERT ... SET # @@ -501,6 +533,8 @@ WHERE id1=1) 5 6 INSERT INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2); ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data +INSERT INTO t2 SET id2=5, val2='f' RETURNING t1.*; +ERROR 42S02: Unknown table 'test.t1' # # INSERT...ON DUPLICATE KEY UPDATE # @@ -525,6 +559,9 @@ ERROR 42S22: Unknown column 'id2' in 'field list' INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b' RETURNING (SELECT id FROM ins_duplicate); ERROR HY000: Table 'ins_duplicate' is specified twice, both as a target for 'INSERT' and as a separate source for data +INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b' +RETURNING t1.*; +ERROR 42S02: Unknown table 'test.t1' # # INSERT...SELECT # @@ -544,6 +581,8 @@ ERROR 21000: Operand should contain 1 column(s) INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT id2 FROM t2); ERROR 21000: Subquery returns more than 1 row +INSERT INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*; +ERROR 42S02: Unknown table 'test.t1' # # TRIGGER # diff --git a/mysql-test/main/insert_returning.test b/mysql-test/main/insert_returning.test index b4fc75c28bb..6c8e71a4617 100644 --- a/mysql-test/main/insert_returning.test +++ b/mysql-test/main/insert_returning.test @@ -41,6 +41,7 @@ SELECT * FROM t1; INSERT INTO v1(id1, val1) VALUES (12, 'a') RETURNING id1+id1 as total,val1, id1 && id1, id1 id1, UPPER(val1),f(id1); ANALYZE INSERT INTO t1(id1,val1) VALUES(13,'l') RETURNING *; +INSERT INTO t1(id1,val1) VALUES(14,'m') RETURNING t1.*; TRUNCATE TABLE t1; --echo # @@ -68,6 +69,7 @@ SELECT * FROM t1; INSERT INTO v1 VALUES(23,'y'),(24,'z') RETURNING id1 as id,val1, id1 && id1, id1|id1, UPPER(val1),f(id1); ANALYZE INSERT INTO t1 VALUES(25,'a'),(26,'b') RETURNING *; +ANALYZE INSERT INTO t1 VALUES(27,'c'),(28,'d') RETURNING t1.*; --echo # --echo # INSERT...ON DUPLICATE KEY UPDATE...RETURNING @@ -101,6 +103,8 @@ val1='d' RETURNING id1+id1 AS total, val1, id1 && id1, id1|id1, UPPER(val1), f(id1); ANALYZE INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE val='k' RETURNING *; +INSERT INTO ins_duplicate(id,val) VALUES(2,'b') ON DUPLICATE KEY UPDATE +val='l' RETURNING ins_duplicate.*; SELECT * FROM ins_duplicate; --echo # @@ -130,6 +134,7 @@ EXPLAIN FORMAT="json" INSERT INTO t1 SET id1=11, val1='k' RETURNING val1; INSERT INTO v1 SET id1=26, val1='Z' RETURNING id1+id1 AS total,val1, id1 && id1, id1|id1, UPPER(val1),f(id1); ANALYZE INSERT INTO t1 SET id1=12, val1='l' RETURNING *; +INSERT INTO t1 SET id1= 13, val1= 'm' RETURNING t1.*; SELECT * FROM t1; --echo # @@ -158,6 +163,10 @@ INSERT IGNORE INTO t2 SELECT * FROM t1 WHERE id1=8 RETURNING *; INSERT IGNORE INTO v2 SELECT * FROM v1 RETURNING *; ANALYZE INSERT INTO t2 SELECT * FROM t1 WHERE id1=11 RETURNING *; SELECT * FROM t2; +TRUNCATE TABLE t2; +INSERT INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING t2.*; +INSERT INTO t2 SELECT t1.* FROM t1 WHERE id1=2 RETURNING t2.*; +SELECT * FROM t2; DROP TABLE t1; DROP TABLE t2; @@ -190,6 +199,8 @@ INSERT INTO t2(id2,val2) VALUES(5,'e') RETURNING id2, (SELECT id1+id2 FROM t1 WHERE id1=1); --error ER_UPDATE_TABLE_USED INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2); +--error ER_BAD_TABLE_ERROR +INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*; --echo # --echo # Multiple rows in single insert statement @@ -208,6 +219,8 @@ INSERT INTO t2 VALUES(11,'e'),(12,'f') RETURNING id2, (SELECT id1+id2 FROM t1 WHERE id1=1); --error ER_UPDATE_TABLE_USED INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING (SELECT id2 FROM t2); +--error ER_BAD_TABLE_ERROR +INSERT INTO t2 VALUES(13,'f'),(14,'g') RETURNING t1.*; --echo # --echo # INSERT ... SET @@ -226,6 +239,8 @@ INSERT INTO t2 SET id2=5, val2='e' RETURNING id2, (SELECT id1+id2 FROM t1 WHERE id1=1); --error ER_UPDATE_TABLE_USED INSERT INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2); +--error ER_BAD_TABLE_ERROR +INSERT INTO t2 SET id2=5, val2='f' RETURNING t1.*; --echo # --echo # INSERT...ON DUPLICATE KEY UPDATE @@ -251,6 +266,9 @@ RETURNING id2, (SELECT id1+id FROM t1 WHERE id1=1); --error ER_UPDATE_TABLE_USED INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b' RETURNING (SELECT id FROM ins_duplicate); +--error ER_BAD_TABLE_ERROR +INSERT INTO ins_duplicate VALUES(2,'b') ON DUPLICATE KEY UPDATE val='b' +RETURNING t1.*; --echo # --echo # INSERT...SELECT @@ -271,6 +289,8 @@ INSERT INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING(SELECT --error ER_SUBQUERY_NO_1_ROW INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT id2 FROM t2); +--error ER_BAD_TABLE_ERROR +INSERT INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*; --echo # --echo # TRIGGER 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/my_print_defaults.result b/mysql-test/main/my_print_defaults.result new file mode 100644 index 00000000000..64aa7b45ca8 --- /dev/null +++ b/mysql-test/main/my_print_defaults.result @@ -0,0 +1,51 @@ +# MDEV-24248: my_print_defaults is not taking all the values when using +# -e option which is called from mysql.server (extra_args). +# +# checking for mysql.server +--key_buffer_size=20M +--max_allowed_packet=250M +--table_open_cache=1000 +--table_definition_cache=2000 +--read_buffer_size=1M +--thread_cache_size=8 +--max_connections=1024 +--long_query_time=60 +--slow_query_log=1 +# +# MDEV-25908: -e does not work for my_print_defaults +# +# Testing -e +--key_buffer_size=20M +--max_allowed_packet=250M +--table_open_cache=1000 +#Testing --defaults-extra-file +--key_buffer_size=20M +--max_allowed_packet=250M +--table_open_cache=1000 +# +# Testing other options +# +# Testing -c option +--key_buffer_size=20M +--max_allowed_packet=250M +--table_open_cache=1000 +# Testing --defaults-file +--key_buffer_size=20M +--max_allowed_packet=250M +--table_open_cache=1000 +# Testing -g option +--key_buffer_size=20M +--max_allowed_packet=250M +--table_open_cache=1000 +--table_definition_cache=2000 +--read_buffer_size=1M +--thread_cache_size=8 +# Testing --defaults-group-suffix +--key_buffer_size=20M +--max_allowed_packet=250M +--table_open_cache=1000 +--table_definition_cache=2000 +--read_buffer_size=1M +--thread_cache_size=8 +# Testing --no-defaults +# End of 10.5 Test diff --git a/mysql-test/main/my_print_defaults.test b/mysql-test/main/my_print_defaults.test new file mode 100644 index 00000000000..bfd4e563826 --- /dev/null +++ b/mysql-test/main/my_print_defaults.test @@ -0,0 +1,106 @@ +--echo # MDEV-24248: my_print_defaults is not taking all the values when using +--echo # -e option which is called from mysql.server (extra_args). +--echo # + +--echo # checking for mysql.server + +--write_file $MYSQLTEST_VARDIR/tmp/tmp1.cnf +[mariadb] +key_buffer_size=20M +max_allowed_packet=250M +table_open_cache=1000 +table_definition_cache=2000 +read_buffer_size=1M +thread_cache_size=8 +max_connections=1024 +long_query_time=60 +slow_query_log=1 +EOF + +--write_file $MYSQLTEST_VARDIR/tmp/tmp2.cnf +[mariadb] +key_buffer_size=20M +max_allowed_packet=250M +table_open_cache=1000 +table_definition_cache=2000 +read_buffer_size=1M +thread_cache_size=8 +max_connections=1024 +long_query_time=60 +slow_query_log=1 +EOF + +--exec $MYSQL_MY_PRINT_DEFAULTS --defaults-extra-file=$MYSQLTEST_VARDIR/tmp/tmp1.cnf -c $MYSQLTEST_VARDIR/tmp/tmp2.cnf --mysqld mysql.server +--remove_file $MYSQLTEST_VARDIR/tmp/tmp1.cnf +--remove_file $MYSQLTEST_VARDIR/tmp/tmp2.cnf + + +--echo # +--echo # MDEV-25908: -e does not work for my_print_defaults +--echo # + +--write_file $MYSQLTEST_VARDIR/tmp/tmp1.cnf + +[mariadb] +key_buffer_size=20M +max_allowed_packet=250M +table_open_cache=1000 +EOF + +--write_file $MYSQLTEST_VARDIR/tmp/tmp2.cnf + +[mariadb] +key_buffer_size=20M +max_allowed_packet=250M +table_open_cache=1000 +EOF + +--echo # Testing -e +--exec $MYSQL_MY_PRINT_DEFAULTS -e $MYSQLTEST_VARDIR/tmp/tmp1.cnf -c $MYSQLTEST_VARDIR/tmp/tmp2.cnf --mysqld mysql.server +--echo #Testing --defaults-extra-file +--exec $MYSQL_MY_PRINT_DEFAULTS --defaults-extra-file=$MYSQLTEST_VARDIR/tmp/tmp1.cnf -c $MYSQLTEST_VARDIR/tmp/tmp2.cnf --mysqld mysql.server + +--remove_file $MYSQLTEST_VARDIR/tmp/tmp1.cnf +--remove_file $MYSQLTEST_VARDIR/tmp/tmp2.cnf + +--echo # +--echo # Testing other options +--echo # + + +--write_file $MYSQLTEST_VARDIR/tmp/tmp2.cnf +[mariadb] +key_buffer_size=20M +max_allowed_packet=250M +table_open_cache=1000 +EOF + +--write_file $MYSQLTEST_VARDIR/tmp/tmp3.cnf +[mariadb] +key_buffer_size=20M +max_allowed_packet=250M +table_open_cache=1000 + +[mariadb.1] +table_definition_cache=2000 +read_buffer_size=1M +thread_cache_size=8 +EOF + +--echo # Testing -c option +--exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQLTEST_VARDIR/tmp/tmp2.cnf --mysqld mysql.server +--echo # Testing --defaults-file +--exec $MYSQL_MY_PRINT_DEFAULTS --defaults-file=$MYSQLTEST_VARDIR/tmp/tmp2.cnf --mysqld mysql.server + +--echo # Testing -g option +--exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQLTEST_VARDIR/tmp/tmp3.cnf --mysqld mysql.server -g .1 +--echo # Testing --defaults-group-suffix +--exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQLTEST_VARDIR/tmp/tmp3.cnf --mysqld mysql.server --defaults-group-suffix=.1 + +--echo # Testing --no-defaults +--exec $MYSQL_MY_PRINT_DEFAULTS --no-defaults + +--remove_file $MYSQLTEST_VARDIR/tmp/tmp2.cnf +--remove_file $MYSQLTEST_VARDIR/tmp/tmp3.cnf + +--echo # End of 10.5 Test 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_install_db_win.test b/mysql-test/main/mysql_install_db_win.test index 7251ff11481..ceb7293f611 100644 --- a/mysql-test/main/mysql_install_db_win.test +++ b/mysql-test/main/mysql_install_db_win.test @@ -48,9 +48,9 @@ connection default; # Test --template option let _BASEDIR = $MYSQLTEST_VARDIR/tmp/basedir; perl; - - open(IN, '<', "std_data/mysql_install_db_win.ini.in") or die; - open(OUT, '>', "$ENV{MYSQLTEST_VARDIR}/tmp/mysql_install_db_win.ini") or die; + use autodie; + open(IN, '<', "std_data/mysql_install_db_win.ini"); + open(OUT, '>', "$ENV{MYSQLTEST_VARDIR}/tmp/mysql_install_db_win.ini"); while () { s/BASEDIR/$ENV{_BASEDIR}/g; print OUT $_; @@ -68,7 +68,8 @@ exec $MYSQL_INSTALL_DB_EXE -o --port=3307 --config=$MYSQLTEST_VARDIR/tmp/mysql_i # dump the modified config in data directory perl; - open(IN, '<', "$ENV{_BASEDIR}/data/my.ini") or die; + use autodie; + open(IN, '<', "$ENV{_BASEDIR}/data/my.ini"); while () { s/$ENV{_BASEDIR}/BASEDIR/g; # when testing on installation layout, client's plugin diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result index 2f7d968a8bd..347d942be5e 100644 --- a/mysql-test/main/mysql_upgrade.result +++ b/mysql-test/main/mysql_upgrade.result @@ -1880,7 +1880,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/mysqld--help.result b/mysql-test/main/mysqld--help.result index 5d014240faa..2a158151528 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -1844,5 +1844,5 @@ userstat FALSE verbose TRUE wait-timeout 28800 -To see what variables a running MySQL server is using, type -'mysqladmin variables' instead of 'mysqld --verbose --help'. +To see what variables a running server is using, type +'SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES' instead of 'mysqld --verbose --help' or 'mariadbd --verbose --help'. diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index b4bea9d3686..0de2c5a111b 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -2688,6 +2688,7 @@ DROP TABLE t1, t2; # (Problems with --defaults-extra-file option) # --port=1234 +--port=1234 # # Test of fix to Bug#12597 mysqldump dumps triggers wrongly # 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/processlist_notembedded.result b/mysql-test/main/processlist_notembedded.result index d5c25c0a1d9..26f6e4f9247 100644 --- a/mysql-test/main/processlist_notembedded.result +++ b/mysql-test/main/processlist_notembedded.result @@ -28,6 +28,7 @@ id select_type table type possible_keys key key_len ref rows Extra Warnings: Note 1003 select sleep(100000) KILL QUERY $con_id; +disconnect con1; # # End of 10.2 tests # diff --git a/mysql-test/main/processlist_notembedded.test b/mysql-test/main/processlist_notembedded.test index cc577200368..35cac36bb95 100644 --- a/mysql-test/main/processlist_notembedded.test +++ b/mysql-test/main/processlist_notembedded.test @@ -1,4 +1,3 @@ -source include/have_debug.inc; source include/have_debug_sync.inc; source include/not_embedded.inc; source include/count_sessions.inc; @@ -37,8 +36,6 @@ connection default; SET DEBUG_SYNC = 'RESET'; -source include/wait_until_count_sessions.inc; - --echo # --echo # End of 5.5 tests --echo # @@ -52,8 +49,12 @@ source include/wait_until_count_sessions.inc; --send select sleep(100000) --connection default +let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist where state='User sleep'; +source include/wait_condition.inc; evalp SHOW EXPLAIN FOR $con_id; evalp KILL QUERY $con_id; +disconnect con1; +source include/wait_until_count_sessions.inc; --echo # --echo # End of 10.2 tests diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index eb17def9a4b..e595b6f8c21 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -5566,6 +5566,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 e5285022efd..fa184ab8250 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -4994,6 +4994,22 @@ DROP TABLE t1, t2, t3; --echo # End of 10.2 tests --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 diff --git a/mysql-test/main/replace_returning.result b/mysql-test/main/replace_returning.result index 628b70abad1..1bc9bbd4cc5 100644 --- a/mysql-test/main/replace_returning.result +++ b/mysql-test/main/replace_returning.result @@ -33,9 +33,12 @@ EXECUTE stmt; id1 (SELECT id2 FROM t2 WHERE val2='b') 1 2 DEALLOCATE PREPARE stmt; +REPLACE INTO t1 (id1, val1) VALUES (1, 'g') RETURNING t1.*; +id1 val1 +1 g SELECT * FROM t1; id1 val1 -1 f +1 g TRUNCATE TABLE t1; # # Multiple values in one replace statement...RETURNING @@ -69,10 +72,14 @@ id1 (SELECT id2 FROM t2 WHERE val2='b') 1 2 2 2 DEALLOCATE PREPARE stmt; +REPLACE INTO t1 VALUES (1,'u'),(2,'v') RETURNING t1.*; +id1 val1 +1 u +2 v SELECT * FROM t1; id1 val1 -1 s -2 t +1 u +2 v TRUNCATE TABLE t1; # # REPLACE...SET...RETURNING @@ -101,9 +108,12 @@ EXECUTE stmt; id1 (SELECT id2 FROM t2 WHERE val2='b') 3 2 DEALLOCATE PREPARE stmt; +REPLACE INTO t1 SET id1=1, val1 = 'o' RETURNING t1.*; +id1 val1 +1 o SELECT * FROM t1; id1 val1 -1 i +1 o 2 j 3 k # @@ -113,7 +123,7 @@ TRUNCATE TABLE t2; REPLACE INTO t2(id2,val2) SELECT * FROM t1; REPLACE INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING *; id2 val2 -1 i +1 o REPLACE INTO t2 SELECT * FROM t1 WHERE id1=2 RETURNING id2+id2 AS total, id2&&id2, id2|id2,UPPER(val2),f(id2); total id2&&id2 id2|id2 UPPER(val2) f(id2) @@ -122,7 +132,7 @@ REPLACE INTO t2 SELECT * FROM t1 WHERE id1=3 RETURNING (SELECT GROUP_CONCAT(val1) FROM t1 WHERE id1=1); (SELECT GROUP_CONCAT(val1) FROM t1 WHERE id1=1) -i +o REPLACE INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING (SELECT GROUP_CONCAT(val1) FROM t1 GROUP BY id1 HAVING id1=id1+1); (SELECT @@ -144,11 +154,109 @@ FROM t2 WHERE id2=0); (SELECT id1+id2 FROM t2 WHERE id2=0) NULL +REPLACE INTO t2 SELECT * FROM t1 WHERE id1=2 RETURNING t2.*; +id2 val2 +2 j SELECT * FROM t2; id2 val2 -1 i +1 o 2 j 3 k DROP TABLE t1; DROP TABLE t2; DROP FUNCTION f; +# +# checking errors +# +CREATE TABLE t1(id1 INT,val1 VARCHAR(1)); +CREATE TABLE t2(id2 INT,val2 VARCHAR(1)); +REPLACE INTO t1 VALUES(1,'a'),(2,'b'),(3,'c'); +# +# SIMLPE REPLACE STATEMENT +# +REPLACE INTO t2(id2,val2) VALUES(1,'a') RETURNING id1; +ERROR 42S22: Unknown column 'id1' in 'field list' +REPLACE INTO t2(id2,val2) values(2,'b') RETURNING SUM(id2); +ERROR HY000: Invalid use of group function +REPLACE INTO t2(id2,val2) VALUES(3,'c') RETURNING (SELECT id1 FROM t1); +ERROR 21000: Subquery returns more than 1 row +REPLACE INTO t2(id2,val2) VALUES(4,'d') RETURNING (SELECT * FROM t1); +ERROR 21000: Operand should contain 1 column(s) +REPLACE INTO t2(id2,val2) VALUES(4,'d') RETURNING (SELECT * FROM t2); +ERROR 21000: Operand should contain 1 column(s) +REPLACE INTO t2(id2,val2) VALUES(5,'e') RETURNING id2, (SELECT id1+id2 FROM +t1 WHERE id1=1); +id2 (SELECT id1+id2 FROM +t1 WHERE id1=1) +5 6 +REPLACE INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2); +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data +REPLACE INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*; +ERROR 42S02: Unknown table 'test.t1' +# +# Multiple rows in single insert statement +# +REPLACE INTO t2 VALUES(1,'a'),(2,'b') RETURNING id1; +ERROR 42S22: Unknown column 'id1' in 'field list' +REPLACE INTO t2 VALUES(3,'c'),(4,'d') RETURNING MAX(id2); +ERROR HY000: Invalid use of group function +REPLACE INTO t2 VALUES(5,'c'),(6,'f') RETURNING (SELECT id1 FROM t1); +ERROR 21000: Subquery returns more than 1 row +REPLACE INTO t2 VALUES(7,'g'),(8,'h') RETURNING (SELECT * FROM t1); +ERROR 21000: Operand should contain 1 column(s) +REPLACE INTO t2 VALUES(9,'g'),(10,'h') RETURNING (SELECT * FROM t2); +ERROR 21000: Operand should contain 1 column(s) +REPLACE INTO t2 VALUES(11,'e'),(12,'f') RETURNING id2, (SELECT id1+id2 FROM +t1 WHERE id1=1); +id2 (SELECT id1+id2 FROM +t1 WHERE id1=1) +11 12 +12 13 +REPLACE INTO t2 VALUES(13,'f'),(14,'g') RETURNING (SELECT id2 FROM t2); +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data +REPLACE INTO t2 VALUES(13,'f'),(14,'g') RETURNING t1.*; +ERROR 42S02: Unknown table 'test.t1' +# +# REPLACE ... SET +# +REPLACE INTO t2 SET id2=1, val2='a' RETURNING id1; +ERROR 42S22: Unknown column 'id1' in 'field list' +REPLACE INTO t2 SET id2=2, val2='b' RETURNING COUNT(id2); +ERROR HY000: Invalid use of group function +REPLACE INTO t2 SET id2=3, val2='c' RETURNING (SELECT id1 FROM t1); +ERROR 21000: Subquery returns more than 1 row +REPLACE INTO t2 SET id2=4, val2='d' RETURNING (SELECT * FROM t1); +ERROR 21000: Operand should contain 1 column(s) +REPLACE INTO t2 SET id2=4, val2='d' RETURNING (SELECT * FROM t2); +ERROR 21000: Operand should contain 1 column(s) +REPLACE INTO t2 SET id2=5, val2='e' RETURNING id2, (SELECT id1+id2 FROM t1 +WHERE id1=1); +id2 (SELECT id1+id2 FROM t1 +WHERE id1=1) +5 6 +REPLACE INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2); +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data +REPLACE INTO t2 SET id2=5, val2='f' RETURNING t1.*; +ERROR 42S02: Unknown table 'test.t1' +# +# REPLACE...SELECT +# +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=1 RETURNING id1; +ERROR 42S22: Unknown column 'id1' in 'field list' +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING MAX(id2); +ERROR HY000: Invalid use of group function +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT +id1 FROM t1); +ERROR 21000: Subquery returns more than 1 row +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT +* FROM t1); +ERROR 21000: Operand should contain 1 column(s) +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING(SELECT +* FROM t2); +ERROR 21000: Operand should contain 1 column(s) +REPLACE INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT +id2 FROM t2); +ERROR 21000: Subquery returns more than 1 row +REPLACE INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*; +ERROR 42S02: Unknown table 'test.t1' +DROP TABLE t1,t2; diff --git a/mysql-test/main/replace_returning.test b/mysql-test/main/replace_returning.test index b2681585d31..8b8a1c24e3e 100644 --- a/mysql-test/main/replace_returning.test +++ b/mysql-test/main/replace_returning.test @@ -28,6 +28,7 @@ PREPARE stmt FROM "REPLACE INTO t1 (id1,val1) VALUES (1,'f') RETURNING id1,(SELECT id2 FROM t2 WHERE val2='b')"; EXECUTE stmt; DEALLOCATE PREPARE stmt; +REPLACE INTO t1 (id1, val1) VALUES (1, 'g') RETURNING t1.*; SELECT * FROM t1; TRUNCATE TABLE t1; @@ -46,6 +47,7 @@ PREPARE stmt FROM "REPLACE INTO t1 VALUES (1,'s'),(2,'t') RETURNING id1, (SELECT id2 FROM t2 WHERE val2='b')"; EXECUTE stmt; DEALLOCATE PREPARE stmt; +REPLACE INTO t1 VALUES (1,'u'),(2,'v') RETURNING t1.*; SELECT * FROM t1; TRUNCATE TABLE t1; @@ -64,6 +66,8 @@ PREPARE stmt FROM "REPLACE INTO t1 SET id1=3, val1='k' RETURNING id1, (SELECT id2 FROM t2 WHERE val2='b')"; EXECUTE stmt; DEALLOCATE PREPARE stmt; +REPLACE INTO t1 SET id1=1, val1 = 'o' RETURNING t1.*; + SELECT * FROM t1; --echo # @@ -86,8 +90,103 @@ REPLACE INTO t2 SELECT * FROM t1 WHERE id1=3 RETURNING (SELECT id1+id2 FROM t1 WHERE id1=1); REPLACE INTO t2 SELECT * FROM t1 WHERE id1=1 RETURNING (SELECT id1+id2 FROM t2 WHERE id2=0); +REPLACE INTO t2 SELECT * FROM t1 WHERE id1=2 RETURNING t2.*; SELECT * FROM t2; DROP TABLE t1; DROP TABLE t2; DROP FUNCTION f; + +--echo # +--echo # checking errors +--echo # + +CREATE TABLE t1(id1 INT,val1 VARCHAR(1)); +CREATE TABLE t2(id2 INT,val2 VARCHAR(1)); + +REPLACE INTO t1 VALUES(1,'a'),(2,'b'),(3,'c'); + +--echo # +--echo # SIMLPE REPLACE STATEMENT +--echo # +--error ER_BAD_FIELD_ERROR +REPLACE INTO t2(id2,val2) VALUES(1,'a') RETURNING id1; +--error ER_INVALID_GROUP_FUNC_USE +REPLACE INTO t2(id2,val2) values(2,'b') RETURNING SUM(id2); +--error ER_SUBQUERY_NO_1_ROW +REPLACE INTO t2(id2,val2) VALUES(3,'c') RETURNING (SELECT id1 FROM t1); +--error ER_OPERAND_COLUMNS +REPLACE INTO t2(id2,val2) VALUES(4,'d') RETURNING (SELECT * FROM t1); +--error ER_OPERAND_COLUMNS +REPLACE INTO t2(id2,val2) VALUES(4,'d') RETURNING (SELECT * FROM t2); +REPLACE INTO t2(id2,val2) VALUES(5,'e') RETURNING id2, (SELECT id1+id2 FROM +t1 WHERE id1=1); +--error ER_UPDATE_TABLE_USED +REPLACE INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2); +--error ER_BAD_TABLE_ERROR +REPLACE INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*; + +--echo # +--echo # Multiple rows in single insert statement +--echo # +--error ER_BAD_FIELD_ERROR +REPLACE INTO t2 VALUES(1,'a'),(2,'b') RETURNING id1; +--error ER_INVALID_GROUP_FUNC_USE +REPLACE INTO t2 VALUES(3,'c'),(4,'d') RETURNING MAX(id2); +--error ER_SUBQUERY_NO_1_ROW +REPLACE INTO t2 VALUES(5,'c'),(6,'f') RETURNING (SELECT id1 FROM t1); +--error ER_OPERAND_COLUMNS +REPLACE INTO t2 VALUES(7,'g'),(8,'h') RETURNING (SELECT * FROM t1); +--error ER_OPERAND_COLUMNS +REPLACE INTO t2 VALUES(9,'g'),(10,'h') RETURNING (SELECT * FROM t2); +REPLACE INTO t2 VALUES(11,'e'),(12,'f') RETURNING id2, (SELECT id1+id2 FROM +t1 WHERE id1=1); +--error ER_UPDATE_TABLE_USED +REPLACE INTO t2 VALUES(13,'f'),(14,'g') RETURNING (SELECT id2 FROM t2); +--error ER_BAD_TABLE_ERROR +REPLACE INTO t2 VALUES(13,'f'),(14,'g') RETURNING t1.*; + +--echo # +--echo # REPLACE ... SET +--echo # +--error ER_BAD_FIELD_ERROR +REPLACE INTO t2 SET id2=1, val2='a' RETURNING id1; +--error ER_INVALID_GROUP_FUNC_USE +REPLACE INTO t2 SET id2=2, val2='b' RETURNING COUNT(id2); +--error ER_SUBQUERY_NO_1_ROW +REPLACE INTO t2 SET id2=3, val2='c' RETURNING (SELECT id1 FROM t1); +--error ER_OPERAND_COLUMNS +REPLACE INTO t2 SET id2=4, val2='d' RETURNING (SELECT * FROM t1); +--error ER_OPERAND_COLUMNS +REPLACE INTO t2 SET id2=4, val2='d' RETURNING (SELECT * FROM t2); +REPLACE INTO t2 SET id2=5, val2='e' RETURNING id2, (SELECT id1+id2 FROM t1 +WHERE id1=1); +--error ER_UPDATE_TABLE_USED +REPLACE INTO t2 SET id2=5, val2='f' RETURNING (SELECT id2 FROM t2); +--error ER_BAD_TABLE_ERROR +REPLACE INTO t2 SET id2=5, val2='f' RETURNING t1.*; + +--echo # +--echo # REPLACE...SELECT +--echo # +--error ER_BAD_FIELD_ERROR +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=1 RETURNING id1; +--error ER_INVALID_GROUP_FUNC_USE +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING MAX(id2); +--error ER_SUBQUERY_NO_1_ROW +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT +id1 FROM t1); +--error ER_OPERAND_COLUMNS +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT +* FROM t1); +--error ER_OPERAND_COLUMNS +REPLACE INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING(SELECT +* FROM t2); +--error ER_SUBQUERY_NO_1_ROW +REPLACE INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT +id2 FROM t2); +--error ER_BAD_TABLE_ERROR +REPLACE INTO t2(id2,val2) SELECT t1.* FROM t1 WHERE id1=2 RETURNING t1.*; + + +DROP TABLE t1,t2; 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..3811b12a1be 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 1341 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/sp-row.result b/mysql-test/main/sp-row.result index 3751b70b260..2764b4cd999 100644 --- a/mysql-test/main/sp-row.result +++ b/mysql-test/main/sp-row.result @@ -228,6 +228,7 @@ CREATE FUNCTION f1(a INT) RETURNS INT BEGIN RETURN a; END; +$$ CREATE PROCEDURE p1() BEGIN DECLARE a ROW (a INT,b INT); diff --git a/mysql-test/main/sp-row.test b/mysql-test/main/sp-row.test index cbd1e940475..527ff9455bd 100644 --- a/mysql-test/main/sp-row.test +++ b/mysql-test/main/sp-row.test @@ -2,11 +2,6 @@ --echo # MDEV-10914 ROW data type for stored routine variables --echo # -if (`SELECT $PS_PROTOCOL != 0`) -{ - --skip Test temporarily disabled for ps-protocol -} - --echo # --echo # ROW of ROWs is not supported yet --echo # @@ -304,6 +299,7 @@ CREATE FUNCTION f1(a INT) RETURNS INT BEGIN RETURN a; END; +$$ CREATE PROCEDURE p1() BEGIN DECLARE a ROW (a INT,b INT); @@ -1340,6 +1336,7 @@ DROP PROCEDURE p1; --echo # ROW variable with a wrong column count +--enable_prepare_warnings CREATE TABLE t1 (a INT, b VARCHAR(32)); INSERT INTO t1 VALUES (10,'b10'); DELIMITER $$; @@ -1351,6 +1348,7 @@ BEGIN END; $$ DELIMITER ;$$ +--disable_prepare_warnings --error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT CALL p1(); DROP TABLE t1; @@ -1360,6 +1358,7 @@ DROP PROCEDURE p1; --echo # Multiple ROW variables CREATE TABLE t1 (a INT, b VARCHAR(32)); INSERT INTO t1 VALUES (10,'b10'); +--enable_prepare_warnings DELIMITER $$; CREATE PROCEDURE p1() BEGIN @@ -1369,6 +1368,7 @@ BEGIN END; $$ DELIMITER ;$$ +--disable_prepare_warnings --error ER_OPERAND_COLUMNS CALL p1(); DROP TABLE t1; @@ -1378,6 +1378,7 @@ DROP PROCEDURE p1; --echo # ROW variables working example CREATE TABLE t1 (a INT, b VARCHAR(32)); INSERT INTO t1 VALUES (10,'b10'); +--enable_prepare_warnings DELIMITER $$; CREATE PROCEDURE p1() BEGIN @@ -1387,6 +1388,7 @@ BEGIN END; $$ DELIMITER ;$$ +--disable_prepare_warnings CALL p1(); DROP TABLE t1; DROP PROCEDURE p1; 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 9f06be800e6..cbad7706ca5 100644 --- a/mysql-test/main/table_value_constr.test +++ b/mysql-test/main/table_value_constr.test @@ -1630,6 +1630,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/tc_heuristic_recover.result b/mysql-test/main/tc_heuristic_recover.result index 32c3a9779ad..5538781ad38 100644 --- a/mysql-test/main/tc_heuristic_recover.result +++ b/mysql-test/main/tc_heuristic_recover.result @@ -22,11 +22,11 @@ NOT FOUND /\[ERROR\] Can\'t init tc log/ in mysqld.1.err FOUND 2 /was in the XA prepared state/ in mysqld.1.err FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err FOUND 1 /\[ERROR\] Can\'t init tc log/ in mysqld.1.err -FOUND 1 /Please restart mysqld without --tc-heuristic-recover/ in mysqld.1.err +FOUND 1 /Please restart without --tc-heuristic-recover/ in mysqld.1.err FOUND 3 /was in the XA prepared state/ in mysqld.1.err FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err FOUND 2 /\[ERROR\] Can\'t init tc log/ in mysqld.1.err -FOUND 2 /Please restart mysqld without --tc-heuristic-recover/ in mysqld.1.err +FOUND 2 /Please restart without --tc-heuristic-recover/ in mysqld.1.err # restart FOUND 3 /was in the XA prepared state/ in mysqld.1.err FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err diff --git a/mysql-test/main/tc_heuristic_recover.test b/mysql-test/main/tc_heuristic_recover.test index 86fea084de8..a69dc5036af 100644 --- a/mysql-test/main/tc_heuristic_recover.test +++ b/mysql-test/main/tc_heuristic_recover.test @@ -66,7 +66,7 @@ SELECT * FROM t1; --source include/search_pattern_in_file.inc --let SEARCH_PATTERN= \\[ERROR\\] Can\\'t init tc log --source include/search_pattern_in_file.inc ---let SEARCH_PATTERN= Please restart mysqld without --tc-heuristic-recover +--let SEARCH_PATTERN= Please restart without --tc-heuristic-recover --source include/search_pattern_in_file.inc --error 1 @@ -78,7 +78,7 @@ SELECT * FROM t1; --source include/search_pattern_in_file.inc --let SEARCH_PATTERN= \\[ERROR\\] Can\\'t init tc log --source include/search_pattern_in_file.inc ---let SEARCH_PATTERN= Please restart mysqld without --tc-heuristic-recover +--let SEARCH_PATTERN= Please restart without --tc-heuristic-recover --source include/search_pattern_in_file.inc --source include/start_mysqld.inc diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result index ea1a55464d5..c0a45a2ac14 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 7e0147cd337..a34e76591ec 100644 --- a/mysql-test/main/union.test +++ b/mysql-test/main/union.test @@ -1888,6 +1888,31 @@ SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT CAST(1 AS SIGNED); --disable_metadata --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 @@ -2555,6 +2555,153 @@ INSERT INTO t1 VALUES (1),(2),(3); 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/mariadb-test-run.pl b/mysql-test/mariadb-test-run.pl index 7b9422565ab..6dcd25a9c86 100755 --- a/mysql-test/mariadb-test-run.pl +++ b/mysql-test/mariadb-test-run.pl @@ -2737,7 +2737,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; @@ -2760,10 +2762,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"; @@ -4080,9 +4082,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() @@ -4653,61 +4658,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'}); - - return 1; + mtr_verbose("Test says wait before restart") if $waits == 0; + next; } - # Loop ran through: we should keep waiting after a re-check - return 2; + + # 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 + return mysqld_start($mysqld, $mysqld->{'started_opts'}); } + # Loop ran through: we should keep waiting after a re-check + return 2; } # Not an expected crash @@ -5064,6 +5060,7 @@ sub mysqld_start ($$) { if ( defined $exe ) { + mtr_tofile($output, "\$ $exe @$args\n"); pre_write_errorlog($output); $mysqld->{'proc'}= My::SafeProcess->new ( @@ -5082,10 +5079,13 @@ sub mysqld_start ($$) { mtr_verbose("Started $mysqld->{proc}"); } - if (!sleep_until_file_created($mysqld->value('pid-file'), - $opt_start_timeout, $mysqld->{'proc'}, $warn_seconds)) + $mysqld->{'started_opts'}= $extra_opts; + + my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect"; + my $rc= sleep_until_file_created($mysqld->value('pid-file'), $expect_file, + $opt_start_timeout, $mysqld->{'proc'}, $warn_seconds); + if (!$rc) { - my $mname= $mysqld->name(); # Report failure about the last test case before exit my $test_name= mtr_grab_file($path_current_testlog); $test_name =~ s/^CURRENT_TEST:\s//; @@ -5095,13 +5095,8 @@ sub mysqld_start ($$) { $tinfo->{logfile}=get_log_from_proc($mysqld->{'proc'}, $tinfo->{name}); report_option('verbose', 1); mtr_report_test($tinfo); - mtr_error("Failed to start mysqld $mname with command $exe @$args"); } - - # Remember options used when starting - $mysqld->{'started_opts'}= $extra_opts; - - return; + return $rc; } diff --git a/mysql-test/std_data/mysql_install_db_win.ini.in b/mysql-test/std_data/mysql_install_db_win.ini similarity index 100% rename from mysql-test/std_data/mysql_install_db_win.ini.in rename to mysql-test/std_data/mysql_install_db_win.ini 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 09dff6503aa..fa111106cd6 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 bd980540411..f48b624ec21 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -670,3 +670,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/suite.pm b/mysql-test/suite/galera/suite.pm index 027100fdb30..2ef45b247b2 100644 --- a/mysql-test/suite/galera/suite.pm +++ b/mysql-test/suite/galera/suite.pm @@ -65,6 +65,7 @@ push @::global_suppressions, qr|WSREP: Sending JOIN failed: -107 \(Transport endpoint is not connected\). Will retry in new primary component.|, qr|WSREP: Trying to continue unpaused monitor|, qr|WSREP: Wait for gtid returned error 3 while waiting for prior transactions to commit before setting position|, + qr|WSREP: Failed to report last committed|, ); sub which($) { return `sh -c "command -v $_[0]"` } 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..50a743c0153 100644 --- a/mysql-test/suite/gcol/inc/gcol_partition.inc +++ b/mysql-test/suite/gcol/inc/gcol_partition.inc @@ -153,3 +153,31 @@ 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; + +--echo # +--echo # MDEV-26220 Server crashes with indexed by prefix virtual column +--echo # + +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(20), c CHAR(20) AS (b), + KEY (c(10),a)) PARTITION BY HASH(pk); +INSERT INTO t1 (pk,a,b) VALUES (1,10,'foo'),(2,11,'baz'); +SELECT a FROM t1; + +# Cleanup +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..e61c0a26417 100644 --- a/mysql-test/suite/gcol/r/gcol_partition_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_partition_innodb.result @@ -89,6 +89,32 @@ 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-26220 Server crashes with indexed by prefix virtual column +# +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(20), c CHAR(20) AS (b), +KEY (c(10),a)) PARTITION BY HASH(pk); +INSERT INTO t1 (pk,a,b) VALUES (1,10,'foo'),(2,11,'baz'); +SELECT a FROM t1; +a +11 +10 +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..e54b0ad83c6 100644 --- a/mysql-test/suite/gcol/r/gcol_partition_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_partition_myisam.result @@ -86,6 +86,32 @@ 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; +# +# MDEV-26220 Server crashes with indexed by prefix virtual column +# +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(20), c CHAR(20) AS (b), +KEY (c(10),a)) PARTITION BY HASH(pk); +INSERT INTO t1 (pk,a,b) VALUES (1,10,'foo'),(2,11,'baz'); +SELECT a FROM t1; +a +11 +10 +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/r/innodb_virtual_index.result b/mysql-test/suite/gcol/r/innodb_virtual_index.result index 2e9b762500d..aafe65b7fa3 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_index.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_index.result @@ -296,3 +296,17 @@ Table Op Msg_type Msg_text test.t1 optimize note Table does not support optimize, doing recreate + analyze instead test.t1 optimize status OK DROP TABLE t1; +# +# MDEV-20154 Assertion `len <= col->len || ((col->mtype) == 5 +# || (col->mtype) == 14)' failed in row_merge_buf_add +# +CREATE TABLE t1 ( +a VARCHAR(2500), +b VARCHAR(2499) AS (a) VIRTUAL +) ENGINE=InnoDB; +INSERT INTO t1 (a) VALUES ('foo'); +ALTER TABLE t1 MODIFY a VARCHAR(2600), ALGORITHM=INPLACE; +ALTER TABLE t1 ADD KEY (b), ALGORITHM=INPLACE; +# Cleanup +DROP TABLE t1; +# End of 10.2 tests 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/gcol/t/innodb_virtual_index.test b/mysql-test/suite/gcol/t/innodb_virtual_index.test index bb47379f3b2..4a41623264e 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_index.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_index.test @@ -321,3 +321,23 @@ CREATE TABLE t1 (id INT PRIMARY KEY, a CHAR(3), INSERT INTO t1 (id,a) VALUES (1,'foo'); OPTIMIZE TABLE t1; DROP TABLE t1; + +--echo # +--echo # MDEV-20154 Assertion `len <= col->len || ((col->mtype) == 5 +--echo # || (col->mtype) == 14)' failed in row_merge_buf_add +--echo # + +CREATE TABLE t1 ( + a VARCHAR(2500), + b VARCHAR(2499) AS (a) VIRTUAL +) ENGINE=InnoDB; +INSERT INTO t1 (a) VALUES ('foo'); + +ALTER TABLE t1 MODIFY a VARCHAR(2600), ALGORITHM=INPLACE; +ALTER TABLE t1 ADD KEY (b), ALGORITHM=INPLACE; + +--echo # Cleanup +DROP TABLE t1; + +--echo # End of 10.2 tests + 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/r/instant_alter_crash.result b/mysql-test/suite/innodb/r/instant_alter_crash.result index a2c388fa103..556e8d415f4 100644 --- a/mysql-test/suite/innodb/r/instant_alter_crash.result +++ b/mysql-test/suite/innodb/r/instant_alter_crash.result @@ -40,7 +40,6 @@ ALTER TABLE t2 DROP COLUMN c3, ADD COLUMN c5 TEXT DEFAULT 'naturam abhorrere'; connection default; SET DEBUG_SYNC='now WAIT_FOR ddl'; SET GLOBAL innodb_flush_log_at_trx_commit=1; -SET debug_dbug='+d,dict_sys_mutex_avoid'; UPDATE t1 SET c2=c2+1; # Kill the server disconnect ddl; @@ -69,7 +68,6 @@ ALTER TABLE t2 ADD COLUMN (c4 TEXT NOT NULL DEFAULT ' et malorum'); connection default; SET DEBUG_SYNC='now WAIT_FOR ddl'; SET GLOBAL innodb_flush_log_at_trx_commit=1; -SET debug_dbug='+d,dict_sys_mutex_avoid'; DELETE FROM t1; # Kill the server disconnect ddl; @@ -149,7 +147,6 @@ ALTER TABLE t3 ADD COLUMN c3 TEXT NOT NULL DEFAULT 'sic transit gloria mundi'; connection default; SET DEBUG_SYNC='now WAIT_FOR ddl'; SET GLOBAL innodb_flush_log_at_trx_commit=1; -SET debug_dbug='+d,dict_sys_mutex_avoid'; INSERT INTO t1 VALUES(0,0); # Kill the server disconnect ddl; 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 @@ -109,6 +109,17 @@ alter table t1 engine=innodb; 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..4b5c04e3056 --- /dev/null +++ b/mysql-test/suite/innodb/t/import_bugs.test @@ -0,0 +1,20 @@ +--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; +--remove_file $datadir/test/imp_t1.ibd + +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 828fc978a29..a091eb6ac31 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/instant_alter_crash.test b/mysql-test/suite/innodb/t/instant_alter_crash.test index 2a596342530..ddeaa6885e6 100644 --- a/mysql-test/suite/innodb/t/instant_alter_crash.test +++ b/mysql-test/suite/innodb/t/instant_alter_crash.test @@ -55,7 +55,6 @@ ALTER TABLE t2 DROP COLUMN c3, ADD COLUMN c5 TEXT DEFAULT 'naturam abhorrere'; connection default; SET DEBUG_SYNC='now WAIT_FOR ddl'; SET GLOBAL innodb_flush_log_at_trx_commit=1; -SET debug_dbug='+d,dict_sys_mutex_avoid'; UPDATE t1 SET c2=c2+1; --source include/kill_mysqld.inc @@ -84,7 +83,6 @@ ALTER TABLE t2 ADD COLUMN (c4 TEXT NOT NULL DEFAULT ' et malorum'); connection default; SET DEBUG_SYNC='now WAIT_FOR ddl'; SET GLOBAL innodb_flush_log_at_trx_commit=1; -SET debug_dbug='+d,dict_sys_mutex_avoid'; DELETE FROM t1; --source include/kill_mysqld.inc @@ -191,7 +189,6 @@ ALTER TABLE t3 ADD COLUMN c3 TEXT NOT NULL DEFAULT 'sic transit gloria mundi'; connection default; SET DEBUG_SYNC='now WAIT_FOR ddl'; SET GLOBAL innodb_flush_log_at_trx_commit=1; -SET debug_dbug='+d,dict_sys_mutex_avoid'; INSERT INTO t1 VALUES(0,0); --source include/kill_mysqld.inc diff --git a/mysql-test/suite/innodb_zip/r/innochecksum_3.result b/mysql-test/suite/innodb_zip/r/innochecksum_3.result index da9c3bbc343..280528f4200 100644 --- a/mysql-test/suite/innodb_zip/r/innochecksum_3.result +++ b/mysql-test/suite/innodb_zip/r/innochecksum_3.result @@ -158,10 +158,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 88898aea521..ef6d82253f4 100644 --- a/mysql-test/suite/innodb_zip/t/innochecksum_3.test +++ b/mysql-test/suite/innodb_zip/t/innochecksum_3.test @@ -206,22 +206,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/plugins/t/test_sql_service.test b/mysql-test/suite/plugins/t/test_sql_service.test index 2ff2db2fce0..9b9e29c6913 100644 --- a/mysql-test/suite/plugins/t/test_sql_service.test +++ b/mysql-test/suite/plugins/t/test_sql_service.test @@ -1,8 +1,3 @@ -if (`SELECT $PS_PROTOCOL != 0`) -{ - --skip Test temporarily disabled for ps-protocol -} - --source include/not_embedded.inc if (!$TEST_SQL_SERVICE_SO) { 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/s3/my.cnf b/mysql-test/suite/s3/my.cnf index 487aa65230f..f851aa18d6d 100644 --- a/mysql-test/suite/s3/my.cnf +++ b/mysql-test/suite/s3/my.cnf @@ -2,7 +2,6 @@ !include include/default_client.cnf [mysqld.1] -plugin-maturity = gamma plugin-load-add=@ENV.HA_S3_SO s3=ON s3-host-name=@ENV.S3_HOST_NAME diff --git a/mysql-test/suite/s3/slave.cnf b/mysql-test/suite/s3/slave.cnf index 28dc8572b30..4f4d3d39ac7 100644 --- a/mysql-test/suite/s3/slave.cnf +++ b/mysql-test/suite/s3/slave.cnf @@ -1,5 +1,4 @@ [mysqld.2] -plugin-maturity = gamma plugin-load-add=@ENV.HA_S3_SO s3=ON s3-slave-ignore-updates=1 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 b28f3c567ff..b1d2a6595b3 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -3479,7 +3479,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 bb3378139f2..7b811a011ff 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -4169,7 +4169,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 124b0c8563a..9cff94ed5bc 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 @@ -50,7 +50,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..1017db78a4b 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 Ignored +t1 0 PRIMARY 1 id # # # # # # NO +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 62f09b255f2..9e20aff1dc7 100644 --- a/mysql-test/suite/versioning/t/create.test +++ b/mysql-test/suite/versioning/t/create.test @@ -442,3 +442,15 @@ show create table t2; drop temporary table t2; drop table t1; --disable_prepare_warnings + +--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 006a65e1a16..61cfe702f8a 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -995,6 +995,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 34c98c48ff7..91dd278a2e1 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,18 +53,18 @@ 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'; --enable_prepare_warnings -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'; --disable_prepare_warnings 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'; @@ -70,28 +72,34 @@ 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'; --enable_prepare_warnings -set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119'; +set system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119'; --disable_prepare_warnings 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; @@ -104,6 +112,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; @@ -115,7 +164,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 73bb18bd214..82c480917f1 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 921f262c59c..fe2bffb3f08 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/type_inet/mysql-test/type_inet/type_inet6_plugin.result b/plugin/type_inet/mysql-test/type_inet/type_inet6_plugin.result index a51d0f0dd39..200ab30768f 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6_plugin.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_plugin.result @@ -24,7 +24,7 @@ PLUGIN_TYPE DATA TYPE PLUGIN_AUTHOR MariaDB Corporation PLUGIN_DESCRIPTION Data type INET6 PLUGIN_LICENSE GPL -PLUGIN_MATURITY Gamma +PLUGIN_MATURITY Stable PLUGIN_AUTH_VERSION 1.0 # # End of 10.5 tests diff --git a/plugin/type_inet/plugin.cc b/plugin/type_inet/plugin.cc index 2baa98f0594..77804c82af6 100644 --- a/plugin/type_inet/plugin.cc +++ b/plugin/type_inet/plugin.cc @@ -186,7 +186,7 @@ maria_declare_plugin(type_inet) NULL, // Status variables NULL, // System variables "1.0", // String version representation - MariaDB_PLUGIN_MATURITY_GAMMA // Maturity(see include/mysql/plugin.h)*/ + MariaDB_PLUGIN_MATURITY_STABLE// Maturity(see include/mysql/plugin.h)*/ }, { MariaDB_FUNCTION_PLUGIN, // the plugin type (see include/mysql/plugin.h) 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 f8e69e9a755..79ac37695a2 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -612,13 +612,9 @@ 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/mariadb-admin' -u root password 'new-password'" - echo "'$bindir/mariadb-admin' -u root -h $hostname password 'new-password'" - echo - echo "Alternatively you can run:" - echo "'$bindir/mariadb-secure-installation'" + echo "'$bindir/mysql_secure_installation'" echo echo "which will also give you the option of removing the test" echo "databases and anonymous user created by default. This is" diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index d1819e0b115..a461f217824 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -73,12 +73,14 @@ usage () { cat < #include // strconvert() +#include "wsrep_mysqld.h" static const char *stage_names[]= {"START", "FLUSH", "BLOCK_DDL", "BLOCK_COMMIT", "END", 0}; @@ -282,6 +283,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 @@ -361,6 +377,14 @@ bool backup_end(THD *thd) backup_flush_ticket= 0; thd->current_backup_stage= BACKUP_FINISHED; thd->mdl_context.release_lock(old_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 d7dbc827ce2..b500cffc4d2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6411,6 +6411,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); @@ -6422,7 +6423,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 84867f057ed..484e3ebc281 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5588,8 +5588,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 393f6234653..8e07349d600 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1759,13 +1759,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 @@ -2731,10 +2745,10 @@ int ha_recover(HASH *commit_list, MEM_ROOT *arg_mem_root) info.found_foreign_xids); if (info.dry_run && info.found_my_xids) { - sql_print_error("Found %d prepared transactions! It means that mysqld was " + sql_print_error("Found %d prepared transactions! It means that server was " "not shut down properly last time and critical recovery " "information (last binlog or %s file) was manually deleted " - "after a crash. You have to start mysqld with " + "after a crash. You have to start server with " "--tc-heuristic-recover switch to commit or rollback " "pending transactions.", info.found_my_xids, opt_tc_log_file); diff --git a/sql/item.cc b/sql/item.cc index 6033b29a10f..a1ca8a02b32 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4457,13 +4457,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: @@ -4537,7 +4539,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 4d8d1056656..82c42edfe17 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3507,7 +3507,7 @@ public: friend bool insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, const char *table_name, List_iterator *it, - bool any_privileges); + bool any_privileges, bool returning_field); }; @@ -4072,7 +4072,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); @@ -4168,7 +4168,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 { @@ -6619,12 +6619,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; @@ -6663,6 +6666,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 965809ff460..ed49733d15d 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5850,7 +5850,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; set_maybe_null(); max_length= 0; @@ -5884,9 +5884,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(var->value_ptr(current_thd, var_type, + &component)) : + *reinterpret_cast(var->value_ptr(current_thd, + var_type, + &component)); if (cptr) max_length= (uint32) system_charset_info->numchars(cptr, cptr + strlen(cptr)); @@ -5898,7 +5901,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(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 7e8ff667e75..93353e2a925 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -497,7 +497,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}; @@ -513,7 +513,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; @@ -598,7 +598,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); @@ -1512,7 +1512,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 @@ -3205,6 +3205,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) @@ -3221,9 +3229,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(' '); + default_pad_str(&pad_str, collation.collation); } DBUG_ASSERT(collation.collation->mbmaxlen > 0); @@ -3246,9 +3252,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()) @@ -3256,7 +3262,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) @@ -3296,7 +3303,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 @@ -3389,7 +3396,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 @@ -4220,7 +4227,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 9a28d5a99b4..f2cebfe6d82 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/log.cc b/sql/log.cc index 538f6ea86ac..2ab5bc31cda 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2534,7 +2534,7 @@ int check_binlog_magic(IO_CACHE* log, const char** errmsg) } if (bcmp(magic, BINLOG_MAGIC, sizeof(magic))) { - *errmsg = "Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL"; + *errmsg = "Binlog has bad magic number; It's not a binary log file that can be used by this version of MariaDB"; return 1; } return 0; @@ -9953,7 +9953,7 @@ err2: err1: sql_print_error("Crash recovery failed. Either correct the problem " "(if it's, for example, out of memory error) and restart, " - "or delete tc log and start mysqld with " + "or delete tc log and start server with " "--tc-heuristic-recover={commit|rollback}"); return 1; } @@ -9984,7 +9984,7 @@ int TC_LOG::using_heuristic_recover() sql_print_information("Heuristic crash recovery mode"); if (ha_recover(0)) sql_print_error("Heuristic crash recovery failed"); - sql_print_information("Please restart mysqld without --tc-heuristic-recover"); + sql_print_information("Please restart without --tc-heuristic-recover"); return 1; } @@ -11417,7 +11417,7 @@ err2: err1: sql_print_error("Crash recovery failed. Either correct the problem " "(if it's, for example, out of memory error) and restart, " - "or delete (or rename) binary log and start mysqld with " + "or delete (or rename) binary log and start serverwith " "--tc-heuristic-recover={commit|rollback}"); DBUG_RETURN(1); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ef632de5631..be741552da3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -440,7 +440,7 @@ ulong delay_key_write_options; uint protocol_version; uint lower_case_table_names; ulong tc_heuristic_recover= 0; -Atomic_counter thread_count; +Atomic_counter THD_count::count, CONNECT::count; bool shutdown_wait_for_slaves; Atomic_counter slave_open_temp_tables; ulong thread_created; @@ -1709,6 +1709,9 @@ static void close_connections(void) 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 @@ -1735,9 +1738,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) @@ -1750,15 +1753,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 @@ -2333,7 +2335,7 @@ static void activate_tcp_port(uint port, sprintf(buff, "Can't start server: Bind on TCP/IP port. Got error: %d", (int) socket_errno); sql_perror(buff); - sql_print_error("Do you already have another mysqld server running on " + sql_print_error("Do you already have another server running on " "port: %u ?", port); unireg_abort(1); } @@ -2591,7 +2593,7 @@ static void network_init(void) port_len) < 0) { sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */ - sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port); + sql_print_error("Do you already have another server running on socket: %s ?",mysqld_unix_port); unireg_abort(1); /* purecov: tested */ } umask(((~my_umask) & 0666)); @@ -3126,7 +3128,7 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) case SIGQUIT: case SIGKILL: #ifdef EXTRA_DEBUG - sql_print_information("Got signal %d to shutdown mysqld",sig); + sql_print_information("Got signal %d to shutdown server",sig); #endif /* switch to the old log message processing */ logger.set_handlers(LOG_FILE, global_system_variables.sql_log_slow ? LOG_FILE:LOG_NONE, @@ -3861,7 +3863,7 @@ static int init_common_variables() /* TODO: remove this when my_time_t is 64 bit compatible */ if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time)) { - sql_print_error("This MySQL server doesn't support dates later than 2038"); + sql_print_error("This server doesn't support dates later than 2038"); exit(1); } @@ -3952,13 +3954,13 @@ static int init_common_variables() if (!opt_abort) { if (IS_SYSVAR_AUTOSIZE(&server_version_ptr)) - sql_print_information("%s (mysqld %s) starting as process %lu ...", + sql_print_information("%s (server %s) starting as process %lu ...", my_progname, server_version, (ulong) getpid()); else { char real_server_version[SERVER_VERSION_LENGTH]; set_server_version(real_server_version, sizeof(real_server_version)); - sql_print_information("%s (mysqld %s as %s) starting as process %lu ...", + sql_print_information("%s (server %s as %s) starting as process %lu ...", my_progname, real_server_version, server_version, (ulong) getpid()); } @@ -5260,7 +5262,7 @@ static int init_server_components() #ifdef USE_ARIA_FOR_TMP_TABLES if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap) { - sql_print_error("Aria engine is not enabled or did not start. The Aria engine must be enabled to continue as mysqld was configured with --with-aria-tmp-tables"); + sql_print_error("Aria engine is not enabled or did not start. The Aria engine must be enabled to continue as server was configured with --with-aria-tmp-tables"); unireg_abort(1); } #endif @@ -6136,7 +6138,7 @@ void handle_connections_sockets() */ statistic_increment(connection_errors_accept, &LOCK_status); if (!select_errors++ && !abort_loop) /* purecov: inspected */ - sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */ + sql_print_error("Server: Got error %d from select",socket_errno); /* purecov: inspected */ } continue; } @@ -7579,8 +7581,8 @@ static void usage(void) "\nbecause execution stopped before plugins were initialized."); } - puts("\nTo see what variables a running MySQL server is using, type" - "\n'mysqladmin variables' instead of 'mysqld --verbose --help'."); + puts("\nTo see what variables a running server is using, type" + "\n'SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES' instead of 'mysqld --verbose --help' or 'mariadbd --verbose --help'."); } DBUG_VOID_RETURN; } @@ -7623,7 +7625,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 a74c6ce8bda..d0a33fabb51 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -191,7 +191,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 @@ -760,7 +761,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 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 f03152ace03..067abcb049e 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) @@ -1067,7 +1067,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); @@ -1137,8 +1137,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() @@ -291,6 +291,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. */ @@ -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 f233f8a3a82..e59a2ed6a58 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -188,7 +188,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 605723a3b96..c6b690d6d42 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 { @@ -9418,14 +9415,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(STRING_WITH_LEN(" FOR '")); - def_str.append(&acl_entry->user); + append_identifier(thd, &def_str, def_rolename.str, def_rolename.length); + def_str.append(STRING_WITH_LEN(" 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 1c32e9d57cc..9c13c8cb1cd 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -958,7 +958,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, @@ -986,7 +986,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 ac22a63bdba..8ae64d6d841 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6268,7 +6268,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); } @@ -7558,7 +7558,7 @@ static bool setup_natural_join_row_types(THD *thd, ****************************************************************************/ int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, - List *sum_func_list, SELECT_LEX *select_lex) + List *sum_func_list, SELECT_LEX *select_lex, bool returning_field) { Item *item; List_iterator it(fields); @@ -7598,7 +7598,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, else if (insert_fields(thd, ((Item_field*) item)->context, ((Item_field*) item)->db_name.str, ((Item_field*) item)->table_name.str, &it, - any_privileges, &select_lex->hidden_bit_fields)) + any_privileges, &select_lex->hidden_bit_fields, returning_field)) { if (arena) thd->restore_active_arena(arena, &backup); @@ -7744,7 +7744,7 @@ int setup_returning_fields(THD* thd, TABLE_LIST* table_list) if (!thd->lex->has_returning()) return 0; return setup_wild(thd, table_list, thd->lex->returning()->item_list, NULL, - thd->lex->returning()) + thd->lex->returning(), true) || setup_fields(thd, Ref_ptr_array(), thd->lex->returning()->item_list, MARK_COLUMNS_READ, NULL, NULL, false); } @@ -8071,7 +8071,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, bool insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, const char *table_name, List_iterator *it, - bool any_privileges, uint *hidden_bit_fields) + bool any_privileges, uint *hidden_bit_fields, bool returning_field) { Field_iterator_table_ref field_iterator; bool found; @@ -8098,12 +8098,14 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, else treat natural joins as leaves and do not iterate over their underlying tables. */ - for (TABLE_LIST *tables= (table_name ? context->table_list : - context->first_name_resolution_table); - tables; - tables= (table_name ? tables->next_local : - tables->next_name_resolution_table) - ) + TABLE_LIST *first= context->first_name_resolution_table; + TABLE_LIST *TABLE_LIST::* next= &TABLE_LIST::next_name_resolution_table; + if (table_name && !returning_field) + { + first= context->table_list; + next= &TABLE_LIST::next_local; + } + for (TABLE_LIST *tables= first; tables; tables= tables->*next) { Field *field; TABLE *table= tables->table; diff --git a/sql/sql_base.h b/sql/sql_base.h index cafb5967480..5b449fdddac 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -176,11 +176,11 @@ bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, bool insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, const char *table_name, List_iterator *it, bool any_privileges, - uint *hidden_bit_fields); + uint *hidden_bit_fields, bool returning_field); void make_leaves_list(THD *thd, List &list, TABLE_LIST *tables, bool full_table_list, TABLE_LIST *boundary); int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, - List *sum_func_list, SELECT_LEX *sl); + List *sum_func_list, SELECT_LEX *sl, bool returning_field); int setup_returning_fields(THD* thd, TABLE_LIST* table_list); bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array, List &item, enum_column_usage column_usage, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index dc7dcbf18c7..504703f4fc9 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1310,6 +1310,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) @@ -4905,7 +4906,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); @@ -4961,7 +4962,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); @@ -7139,8 +7140,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 bc9bb82866f..d1fa304b367 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1117,6 +1117,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 count; + static uint value() { return static_cast(count); } + THD_count() { count++; } + ~THD_count() { count--; } +}; + #ifdef MYSQL_SERVER void free_tmp_table(THD *thd, TABLE *entry); @@ -2358,21 +2375,6 @@ public: void init() { bill_to = NULL; } }; -/** - 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--; } -}; - /** Support structure for asynchronous group commit, or more generally any asynchronous operation that needs to finish before server writes @@ -3407,6 +3409,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 31297782f30..18db76e99cb 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 Dynamic_array listen_sockets; + DBUG_ASSERT(listen_sockets.size()); + while (listen_sockets.size()) + 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 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 7993cbe09a1..d299769c666 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 e258d46f78a..41902920d3e 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4698,8 +4698,20 @@ select_create::prepare(List &_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, + &create_info->org_storage_engine_name, + create_info->db_type == partition_hton, + &create_info->org_tabledef_version, + 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 c3f97fb34f8..cc2c43d3e71 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -11723,3 +11723,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 0d8251968e8..1fe8b869c11 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1027,20 +1027,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 2c6df6dbb03..e46e46f803c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2259,11 +2259,10 @@ dispatch_command_return dispatch_command(enum enum_server_command command, 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(), @@ -5667,6 +5666,11 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) /* 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 d7bb02bbd4e..0547331e7cd 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -3640,6 +3640,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 c7a93a72a99..ab13e8cc569 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) {} @@ -3428,7 +3428,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) { @@ -3502,7 +3502,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: @@ -3520,12 +3520,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 e7d02aaeb0d..4d7389e72bb 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1612,7 +1612,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 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 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)) @@ -1734,7 +1739,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); @@ -6244,6 +6249,7 @@ extern "C" int execute_sql_command(const char *command, THD *new_thd= 0; int result; my_bool qc_save= 0; + Reprepare_observer *save_reprepare_observer= nullptr; if (!thd) { @@ -6264,6 +6270,8 @@ extern "C" int execute_sql_command(const char *command, qc_save= thd->query_cache_is_applicable; thd->query_cache_is_applicable= 0; + save_reprepare_observer= thd->m_reprepare_observer; + thd->m_reprepare_observer= nullptr; } sql_text.str= (char *) command; sql_text.length= strlen(command); @@ -6301,7 +6309,10 @@ extern "C" int execute_sql_command(const char *command, if (new_thd) delete new_thd; else + { thd->query_cache_is_applicable= qc_save; + thd->m_reprepare_observer= save_reprepare_observer; + } *hosts= 0; return result; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 80d9cafe814..8d6b6391731 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -869,7 +869,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) @@ -1372,7 +1373,7 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num, real_og_num+= select_lex->order_list.elements; DBUG_ASSERT(select_lex->hidden_bit_fields == 0); - if (setup_wild(thd, tables_list, fields_list, &all_fields, select_lex)) + if (setup_wild(thd, tables_list, fields_list, &all_fields, select_lex, false)) DBUG_RETURN(-1); if (select_lex->setup_ref_array(thd, real_og_num)) DBUG_RETURN(-1); @@ -2229,7 +2230,7 @@ JOIN::optimize_inner() sel->attach_to_conds.empty(); } } - + if (optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_SUBQUERY)) { TABLE_LIST *tbl; @@ -2498,7 +2499,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); @@ -3441,8 +3442,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); @@ -7667,7 +7677,7 @@ best_access_path(JOIN *join, DBUG_ENTER("best_access_path"); Json_writer_object trace_wrapper(thd, "best_access_path"); - + bitmap_clear_all(eq_join_set); loose_scan_opt.init(join, s, remaining_tables); @@ -9463,7 +9473,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; @@ -9611,6 +9623,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; } @@ -9665,7 +9701,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; } @@ -18424,7 +18462,7 @@ static bool make_json_valid_expr(TABLE *table, Field *field) Item *expr, *item_field; if (!table->expr_arena && table->init_expr_arena(thd->mem_root)) - return NULL; + return 1; thd->set_n_backup_active_arena(table->expr_arena, &backup_arena); if ((item_field= new (thd->mem_root) Item_field(thd, field)) && @@ -24170,6 +24208,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) @@ -24182,6 +24226,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. */ @@ -28594,7 +28644,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) { @@ -28677,7 +28727,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) { /* @@ -28960,7 +29010,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. */ @@ -28969,7 +29019,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)); } @@ -29077,7 +29127,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, { possible_key.add("usable", false); possible_key.add("cause", "cost"); - } + } } else { @@ -29909,7 +29959,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 326f04dad29..f9049f47324 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3559,6 +3559,30 @@ ulonglong get_status_vars_version(void) return status_var_array_version; } +/** + 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* as_atomic_counter; +}; + /** @brief Returns the value of a system or a status variable. @@ -3582,16 +3606,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); } @@ -3601,72 +3627,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); @@ -3674,17 +3699,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(*static_cast*>(value)), - buff, 10); + end= int10_to_str(static_cast(*value.as_atomic_counter), buff, 10); break; case SHOW_UNDEF: break; // Return empty string @@ -6697,6 +6719,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 36f9c278702..76d1f35cd42 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) { @@ -8754,7 +8761,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) { @@ -9050,6 +9057,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 d1af12418a2..44225b41609 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; @@ -2455,6 +2456,8 @@ public: *(static_cast(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 { @@ -3886,7 +3889,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; } @@ -5386,7 +5389,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, @@ -6827,6 +6830,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 f75391c4503..a0f60532f32 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) @@ -1685,7 +1686,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(type))) goto err; } @@ -2559,7 +2561,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) @@ -2728,6 +2731,29 @@ static void cleanup_order(ORDER *order) } +static void cleanup_window_funcs(List &win_funcs) +{ + List_iterator_fast 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; @@ -2739,6 +2765,8 @@ bool st_select_lex::cleanup() cleanup_order(group_list.first); cleanup_ftfuncs(this); + cleanup_window_funcs(window_funcs); + if (join) { List_iterator ti(leaf_tables); @@ -2765,7 +2793,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 07171485da4..6214b42d56a 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 06fedce283a..17920519b41 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 *partition_list; + SQL_I_List *save_partition_list; SQL_I_List *order_list; + SQL_I_List *save_order_list; Window_frame *window_frame; @@ -123,7 +125,8 @@ class Window_spec : public Sql_alloc SQL_I_List *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 dc2eb4425f0..0c1c68cd644 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1478,7 +1478,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 @@ -2039,12 +2039,12 @@ execute_using: ; execute_params: - expr_or_default + expr_or_ignore_or_default { if (unlikely(!($$= List::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; @@ -9951,7 +9951,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; @@ -13320,7 +13320,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)) || @@ -13390,12 +13390,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; @@ -13403,7 +13403,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; @@ -13411,7 +13411,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; @@ -13421,14 +13421,8 @@ values_with_names: } ; -expr_or_default: +expr_or_ignore: expr { $$= $1;} - | DEFAULT - { - $$= new (thd->mem_root) Item_default_specification(thd); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } | IGNORE_SYM { $$= new (thd->mem_root) Item_ignore_specification(thd); @@ -13437,6 +13431,16 @@ expr_or_default: } ; +expr_or_ignore_or_default: + expr_or_ignore { $$= $1;} + | DEFAULT + { + $$= new (thd->mem_root) Item_default_specification(thd); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + ; + opt_insert_update: /* empty */ | ON DUPLICATE_SYM { Lex->duplicates= DUP_UPDATE; } @@ -13511,10 +13515,16 @@ update_list: ; update_elem: - simple_ident_nospvar equal expr_or_default + simple_ident_nospvar equal DEFAULT { - if (unlikely(add_item_to_list(thd, $1)) || - unlikely(add_value_to_list(thd, $3))) + 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 (add_item_to_list(thd, $1) || add_value_to_list(thd, $3)) MYSQL_YYABORT; } ; @@ -13525,7 +13535,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)) || @@ -14918,7 +14928,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 3ce01ebe3c2..34ac95b941d 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( @@ -1899,8 +1898,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); @@ -1927,8 +1927,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; @@ -2008,8 +2009,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; @@ -2132,8 +2134,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); @@ -2167,8 +2170,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); @@ -2342,9 +2345,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= @@ -5341,8 +5345,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); @@ -5462,7 +5467,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 Sys_var_int; @@ -272,25 +272,25 @@ typedef Sys_var_integer Sys_var_ulonglong; typedef Sys_var_integer 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(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(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(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(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(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(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(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(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; - } - default: break; } - 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"); + default: + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, "NULL (wrong range type)"); + value= thd->strdup("Error: wrong range type"); + } + return reinterpret_cast(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 071a0ef1f1f..ec950c582c3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4185,6 +4185,21 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, /* Update to use trigger fields */ switch_defaults_to_nullable_trigger_fields(outparam); + + for (uint k= 0; k < share->keys; k++) + { + KEY &key_info= outparam->key_info[k]; + uint parts = (share->use_ext_keys ? key_info.ext_key_parts : + key_info.user_defined_key_parts); + for (uint p= 0; p < parts; p++) + { + KEY_PART_INFO &kp= key_info.key_part[p]; + if (kp.field != outparam->field[kp.fieldnr - 1]) + { + kp.field->vcol_info = outparam->field[kp.fieldnr - 1]->vcol_info; + } + } + } } #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -7206,7 +7221,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(); } @@ -7222,7 +7237,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); @@ -7233,12 +7248,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; } @@ -7246,11 +7261,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) @@ -7262,23 +7277,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 @@ -7297,7 +7325,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(); } @@ -7348,7 +7376,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; } } @@ -7434,7 +7462,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; } } @@ -7594,7 +7622,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); } } @@ -7606,7 +7634,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 2e074abcea0..a8c0358b7c4 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1549,8 +1549,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 07555ac21ed..97c6c317cc4 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -250,6 +250,14 @@ static THD *threadpool_add_connection(CONNECT *connect, TP_connection *c) { THD *thd= NULL; + DBUG_EXECUTE_IF("CONNECT_wait", + { + extern Dynamic_array listen_sockets; + DBUG_ASSERT(listen_sockets.size()); + while (listen_sockets.size()) + my_sleep(1000); + }); + /* Create a new connection context: mysys_thread_var and PSI thread Store them in THD. @@ -267,10 +275,10 @@ static THD *threadpool_add_connection(CONNECT *connect, TP_connection *c) my_thread_end(); return NULL; } - delete connect; thd->event_scheduler.data= c; - 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); /* Login. */ diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index b72ed2ac352..0f2fa131f0a 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2752,8 +2752,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; } @@ -3093,15 +3093,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/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index a2cd035d336..c3418cca351 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -109,6 +109,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") # @@ -134,6 +135,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}) @@ -141,6 +143,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) @@ -150,6 +154,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) @@ -250,6 +256,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 @@ -259,7 +266,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}) @@ -275,6 +284,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 @@ -283,7 +293,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) # @@ -297,6 +310,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 @@ -313,6 +327,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}) @@ -320,14 +335,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 # @@ -359,6 +378,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 @@ -369,6 +389,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 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 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 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 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; + if (n < Colnames.size()) + return (String) Colnames.toArray()[n]; + else + return null; - for (String name : Colnames) - if (i++ == n) - return name; - - 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 -#else // !__WIN__ +#else // !_WIN32 #include #include #include #include // 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 -#else // !__WIN__ +#else // !_WIN32 #include #include #include -#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 5335b990fb4..ac2b3dfe3c2 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]; + 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); - } else if (BSON_ITER_HOLDS_DECIMAL128(iter)) { - char *str = NULL; - bson_decimal128_t dec; + 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); - } else if (BSON_ITER_HOLDS_DOCUMENT(iter)) { - bson_iter_t child; + 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); + 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; + } 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); - } // endif's + 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(); + 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 (!strcmp(jpath, "*")) { + 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); + 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); - if (value->IsTypeNum()) - value->SetValue(b ? 1 : 0); - else - value->SetValue_psz(b ? "true" : "false"); + 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]; + break; + case BSON_TYPE_OID: { + 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_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_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; + for (; i < 2; i++) { + if (b) // Try array first + bson_iter_array(&Desc, &len, &data); + else + bson_iter_document(&Desc, &len, &data); - bson_iter_document(&Desc, &len, &data); + if (!data) { + len = 0; + b = !b; + } else + break; - 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 - - } else if (BSON_ITER_HOLDS_ARRAY(&Iter)) { - bson_t *arr; - const uint8_t *data = NULL; - uint32_t len = 0; - - bson_iter_array(&Desc, &len, &data); - - 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_iter_document(&Desc, &len, &data); + } // 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 -#if defined(__WIN__) +#if defined(_WIN32) //#include #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 -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #include @@ -30,7 +30,7 @@ #include #endif // !UNIX #include -#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 9654c59f0fe..4686f7dcff2 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 #include //#include //#include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #include @@ -35,7 +35,7 @@ //#include #endif // !UNIX //#include -#endif // !__WIN__ +#endif // !_WIN32 #include #include #include @@ -650,7 +650,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 */ @@ -660,7 +660,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 #include #include @@ -25,7 +25,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #include @@ -34,7 +34,7 @@ #endif // !UNIX #include #include -#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 #include #if defined(__BORLANDC__) #define __MFC_COMPAT__ // To define min/max as macro #endif //#include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #else // !UNIX #include #endif #include -#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 #include #include @@ -25,7 +25,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) || defined(UNIV_LINUX) #include #include @@ -36,7 +36,7 @@ #include #endif // !UNIX #include -#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 #include #if defined(__BORLANDC__) @@ -29,7 +29,7 @@ #endif // __BORLAND__ //#include #include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #include @@ -40,7 +40,7 @@ #include #endif // !UNIX #include -#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 #include @@ -27,7 +27,7 @@ #include #endif // !UNIX #include -#endif // !__WIN__ +#endif // !_WIN32 #include /***********************************************************************/ @@ -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 -#else // !__WIN__ +#else // !_WIN32 #include #include #include -#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 -#ifndef __WIN__ +#ifndef _WIN32 #include #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_t type declaration */ #include /* 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 b47e1c97061..f49b6d692b3 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 #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; @@ -4548,11 +4547,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); @@ -5486,12 +5485,11 @@ static bool add_field(String* sql, TABTYPE ttp, const char* field_name, int typ, if (fmt && *fmt) { switch (ttp) { + case TAB_MONGO: + case TAB_BSON: case TAB_JSON: error |= sql->append(STRING_WITH_LEN(" JPATH='")); break; -#if defined(BSON_SUPPORT) - case TAB_BSON: error |= sql->append(STRING_WITH_LEN(" JPATH='")); break; -#endif // BSON_SUPPORT case TAB_XML: error |= sql->append(STRING_WITH_LEN(" XPATH='")); break; - default: error |= sql->append(STRING_WITH_LEN(" FIELD_FORMAT='")); + default: error |= sql->append(STRING_WITH_LEN(" FIELD_FORMAT='")); } // endswitch ttp error |= sql->append_for_single_quote(fmt, strlen(fmt)); @@ -5626,9 +5624,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; @@ -5644,7 +5642,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; @@ -5687,10 +5685,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); @@ -5724,7 +5722,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; @@ -5732,13 +5730,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: @@ -5921,11 +5919,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 @@ -5958,9 +5956,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: @@ -5973,7 +5972,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; @@ -6089,11 +6088,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: @@ -6193,7 +6192,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; @@ -6625,11 +6624,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': @@ -7012,11 +7011,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()); @@ -7533,7 +7532,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 //#include -#if defined(__WIN__) +#if defined(_WIN32) #include // for getcwd #if defined(__BORLANDC__) #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #else // !UNIX @@ -31,7 +31,7 @@ #include #include // 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 + // All wrappers are pre-compiled in JavaWrappers.jar in the 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 - 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 c50516a6af5..c3a30f3501e 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 #include -#if defined(__WIN__) +#if defined(_WIN32) //nclude //nclude #include // for getcwd @@ -26,7 +26,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #else // !UNIX @@ -36,7 +36,7 @@ #include // for getenv //nclude #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 //#include //#include @@ -25,7 +25,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) || defined(UNIV_LINUX) //#include #include @@ -36,7 +36,7 @@ //#include #endif // !UNIX //#include -#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")) @@ -638,49 +646,82 @@ jobject JMgoConn::MakeObject(PGLOBAL g, PCOL colp, bool&error ) return val; } // 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 (!Fpc || !(doc = MakeDoc(g, Fpc))) + if (line) { + int j; + jobject val = env->NewStringUTF(line); + + 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; + 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)) + 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 920543c7327..17c6ba9791a 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. */ @@ -77,6 +78,24 @@ bool IsNum(PSZ s) return true; } // 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. */ /***********************************************************************/ @@ -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 af12f42f1d4..d38cf52699a 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 -#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 5f73d1713ce..5f98a7950c4 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 @@ -123,6 +123,15 @@ char *GetPluginDir(void) return opt_plugin_dir; } // 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. */ /***********************************************************************/ @@ -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 fdf107fe224..f8d56f76524 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 -#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 -#else // !__WIN__ +#else // !_WIN32 #include -#endif // !__WIN__ +#endif // !_WIN32 #include #include #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 index 9be654bd4c8..d51cc5d2345 100644 Binary files a/storage/connect/mysql-test/connect/std_data/Mongo2.jar and b/storage/connect/mysql-test/connect/std_data/Mongo2.jar differ diff --git a/storage/connect/mysql-test/connect/std_data/Mongo3.jar b/storage/connect/mysql-test/connect/std_data/Mongo3.jar index 2850177a668..f84e089ef50 100644 Binary files a/storage/connect/mysql-test/connect/std_data/Mongo3.jar and b/storage/connect/mysql-test/connect/std_data/Mongo3.jar differ 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 -#if defined(__WIN__) +#if defined(_WIN32) //#include -#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 92f18aec348..c7843dfe245 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -11,7 +11,7 @@ /***********************************************************************/ #include #include -#if defined(__WIN__) +#if defined(_WIN32) //nclude //nclude #include // 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(); @@ -1283,15 +1283,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) @@ -1301,10 +1301,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 #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 #include #include #define BIGMEM 1048576 // 1 Megabyte -#else // !__WIN__ +#else // !_WIN32 #include #include //#if defined(THREAD) @@ -52,7 +52,7 @@ //#endif // THREAD #include #define BIGMEM 2147483647 // Max int value -#endif // !__WIN__ +#endif // !_WIN32 #include /***********************************************************************/ @@ -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 #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 6917f3c54b2..954c6b67549 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 #else //#include // 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 @@ -407,13 +406,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 @@ -626,7 +625,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 @@ -662,7 +661,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 @@ -704,7 +703,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; + 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 = 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)) + 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 - } else if (BSON_ITER_HOLDS_ARRAY(iter)) { - 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 - - } // 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 #include // For testing only #include @@ -26,7 +26,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #include @@ -34,7 +34,7 @@ #include #endif // !UNIX #include -#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 #include #include @@ -25,7 +25,7 @@ #define __MFC_COMPAT__ // To define min/max as macro #endif // __BORLANDC__ //#include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #include @@ -35,7 +35,7 @@ #include #endif // !UNIX #include -#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 #include #include @@ -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 #include #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 6ef39391849..07a4712e8b0 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 @@ -1143,25 +1173,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) @@ -1173,15 +1206,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; @@ -1206,7 +1239,7 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) } else Top = jsp; - return RC_OK; + return false; } // end of MakeTopTree /***********************************************************************/ @@ -1276,6 +1309,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 /***********************************************************************/ @@ -1295,6 +1329,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 /***********************************************************************/ @@ -1534,6 +1569,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 @@ -1567,8 +1606,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++) { @@ -1607,6 +1648,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) case '*': if (*(p2 - 1) == '.' && !*(p1 + 1)) { p2--; // Suppress last :* + Sgfy = true; break; } // endif p2 /* falls through */ @@ -1615,6 +1657,10 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj) break; } // endswitch p1; } + + if (*(p2 - 1) == '.') + p2--; + *p2 = 0; return mgopath; } else @@ -1743,10 +1789,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()); @@ -2125,10 +2177,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) @@ -2557,8 +2613,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); @@ -2566,15 +2622,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 -#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 #include -#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 #include #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 -#else // !__WIN__ +#else // !_WIN32 #include #include #include #include -#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 -#else // !__WIN__ +#else // !_WIN32 //#include //#include #include @@ -46,7 +46,7 @@ #include "osutil.h" //#include //#include -#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 #include #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 #include #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 // All MariaDB stuff #include #include -#if !defined(__WIN__) && !defined(_WINDOWS) +#if !defined(_WIN32) && !defined(_WINDOWS) #include #include -#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 6a6b874d5bf..1f6a288c27d 100644 --- a/storage/connect/tabrest.h +++ b/storage/connect/tabrest.h @@ -5,10 +5,10 @@ /***********************************************************************/ #pragma once -#if defined(__WIN__) +#if defined(_WIN32) #else // !__WIN__ #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 -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #include @@ -25,7 +25,7 @@ #include #endif // !UNIX #include -#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 #include #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 728ed9e305b..15305cc856b 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 #include #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 #include #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 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 #include #if defined(__BORLANDC__) diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp index 9575d917dd4..c56f2bea110 100644 --- a/storage/connect/tabxml.cpp +++ b/storage/connect/tabxml.cpp @@ -14,12 +14,12 @@ #include "my_global.h" #include #include -#if defined(__WIN__) +#if defined(_WIN32) #include #include //#include #include -#else // !__WIN__ +#else // !_WIN32 #include #include #include @@ -27,7 +27,7 @@ //#include #include "osutil.h" #define _O_RDONLY O_RDONLY -#endif // !__WIN__ +#endif // !_WIN32 #include "resource.h" // for IDS_COLUMNS #define INCLUDE_TDBXML @@ -52,11 +52,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*/ @@ -179,11 +179,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'); @@ -531,7 +531,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)); @@ -539,11 +539,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'); @@ -976,7 +976,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]; @@ -990,7 +990,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 #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 -#else // !__WIN__ +#else // !_WIN32 #include -#endif // !__WIN__ +#endif // !_WIN32 #include @@ -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::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(); @@ -2737,21 +2737,39 @@ 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 { // Constructors DTVAL(PGLOBAL g, int n, int p, PCSZ fmt); DTVAL(int n); + using TYPVAL::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 #include #include //#include -#else // !__WIN__ +#else // !_WIN32 #if defined(UNIX) #include #include @@ -25,7 +25,7 @@ #include #endif // !UNIX #include -#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 9d1ae7d76d1..6113b78012f 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -516,10 +516,10 @@ buf_page_is_checksum_valid_crc32( #ifdef UNIV_INNOCHECKSUM extern FILE* log_file; - extern unsigned long long cur_page_num; + extern uint32_t cur_page_num; if (log_file) { - 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); 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 f8a8253cf86..c1889d43b02 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1119,6 +1119,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; + mysql_mutex_assert_owner(&fil_system.mutex); + const ulong encrypt_tables= srv_encrypt_tables; + if (!crypt_data) + return !encrypt_tables; + if (!crypt_data->is_key_found()) + return true; + + mysql_mutex_lock(&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); + mysql_mutex_unlock(&crypt_data->mutex); + return remove; +} + /*********************************************************************** Check if space needs rotation given a key_state @param[in,out] state Key rotation state @@ -1419,8 +1446,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/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 8774acbf0f3..1d928b5f7b4 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -3010,8 +3010,7 @@ fil_space_validate_for_mtr_commit( /* We are serving mtr_commit(). While there is an active mini-transaction, we should have !space->stop_new_ops. This is - guaranteed by meta-data locks or transactional locks, or - dict_sys.latch (X-lock in DROP, S-lock in purge). */ + guaranteed by meta-data locks or transactional locks. */ ut_ad(!space->is_stopping() || space->is_being_truncated /* fil_truncate_prepare() */ || space->referenced()); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 21a3567f33a..be05e4fb521 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 @@ -1279,6 +1279,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; @@ -1305,6 +1308,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; @@ -1312,10 +1318,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; } @@ -1556,12 +1558,13 @@ static dberr_t fts_lock_table(trx_t *trx, const char *table_name) if (!--n) { err= DB_LOCK_WAIT_TIMEOUT; - break; + goto fail; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); dict_sys.mutex_lock(); } dict_sys.mutex_unlock(); +fail: table->release(); return err; } @@ -6106,58 +6109,3 @@ func_exit: dict_sys.mutex_unlock(); } } - -/** Check if the all the auxillary tables associated with FTS index are in -consistent state. For now consistency is check only by ensuring -index->page_no != FIL_NULL -@param[out] base_table table has host fts index -@param[in,out] trx trx handler */ -void -fts_check_corrupt( - dict_table_t* base_table, - trx_t* trx) -{ - bool sane = true; - fts_table_t fts_table; - - /* Iterate over the common table and check for their sanity. */ - FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, base_table); - - for (ulint i = 0; fts_common_tables[i] != NULL && sane; ++i) { - - char table_name[MAX_FULL_NAME_LEN]; - - fts_table.suffix = fts_common_tables[i]; - fts_get_table_name(&fts_table, table_name); - - dict_table_t* aux_table = dict_table_open_on_name( - table_name, true, FALSE, DICT_ERR_IGNORE_NONE); - - if (aux_table == NULL) { - dict_set_corrupted( - dict_table_get_first_index(base_table), - trx, "FTS_SANITY_CHECK"); - ut_ad(base_table->corrupted == TRUE); - sane = false; - continue; - } - - for (dict_index_t* aux_table_index = - UT_LIST_GET_FIRST(aux_table->indexes); - aux_table_index != NULL; - aux_table_index = - UT_LIST_GET_NEXT(indexes, aux_table_index)) { - - /* Check if auxillary table needed for FTS is sane. */ - if (aux_table_index->page == FIL_NULL) { - dict_set_corrupted( - dict_table_get_first_index(base_table), - trx, "FTS_SANITY_CHECK"); - ut_ad(base_table->corrupted == TRUE); - sane = false; - } - } - - dict_table_close(aux_table, FALSE, FALSE); - } -} diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 41fb62c6ba0..5a6ba7ca1e1 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -14369,8 +14369,6 @@ ha_innobase::info_low( stats.update_time = (ulong) ib_table->update_time; } - DBUG_EXECUTE_IF("dict_sys_mutex_avoid", goto func_exit;); - dict_stats_init(ib_table); if (flag & HA_STATUS_VARIABLE) { @@ -14543,7 +14541,7 @@ ha_innobase::info_low( sql_print_error( "Index %s of %s has %u columns" " unique inside InnoDB, but " - "MySQL is asking statistics for" + "server is asking statistics for" " %lu columns. Have you mixed " "up .frm files from different " " installations? %s", @@ -15286,32 +15284,13 @@ struct table_list_item { const char* name; }; -/*****************************************************************//** -Checks if ALTER TABLE may change the storage engine of the table. -Changing storage engines is not allowed for tables for which there -are foreign key constraints (parent or child tables). -@return TRUE if can switch engines */ - -bool -ha_innobase::can_switch_engines(void) -/*=================================*/ +/** @return whether ALTER TABLE may change the storage engine of the table */ +bool ha_innobase::can_switch_engines() { - DBUG_ENTER("ha_innobase::can_switch_engines"); - - update_thd(); - - m_prebuilt->trx->op_info = - "determining if there are foreign key constraints"; - - row_mysql_freeze_data_dictionary(m_prebuilt->trx); - - bool can_switch = m_prebuilt->table->referenced_set.empty() - && m_prebuilt->table->foreign_set.empty(); - - row_mysql_unfreeze_data_dictionary(m_prebuilt->trx); - m_prebuilt->trx->op_info = ""; - - DBUG_RETURN(can_switch); + DBUG_ENTER("ha_innobase::can_switch_engines"); + update_thd(); + DBUG_RETURN(m_prebuilt->table->foreign_set.empty() && + m_prebuilt->table->referenced_set.empty()); } /*******************************************************************//** diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 2ef58ceca74..5c44aee4be7 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2382,6 +2382,11 @@ 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((*af)->unireg_check != Field::NEXT_NUMBER + || f->unireg_check == Field::NEXT_NUMBER); if (!f->real_maybe_null() || (*af)->real_maybe_null()) goto next_column; /* We are changing an existing column @@ -2390,7 +2395,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: @@ -2410,14 +2414,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(((*af)->unireg_check - == Field::NEXT_NUMBER) - == (f->unireg_check - == Field::NEXT_NUMBER)); + values are not converted. */ goto next_column; } @@ -6158,7 +6155,7 @@ prepare_inplace_alter_table_dict( dict_table_t* user_table; dict_index_t* fts_index = NULL; bool new_clustered = false; - dberr_t error; + dberr_t error = DB_SUCCESS; ulint num_fts_index; dict_add_v_col_t* add_v = NULL; ha_innobase_inplace_ctx*ctx; @@ -6282,11 +6279,27 @@ prepare_inplace_alter_table_dict( /* Acquire a lock on the table before creating any indexes. */ bool table_lock_failed = false; - if (ctx->online) { - error = DB_SUCCESS; - } else { + if (!ctx->online) { +acquire_lock: ctx->prebuilt->trx->op_info = "acquiring table lock"; - error = lock_table_for_trx(ctx->new_table, ctx->trx, LOCK_S); + error = lock_table_for_trx(user_table, ctx->trx, LOCK_S); + } else if (add_key_nums) { + /* FIXME: trx_resurrect_table_locks() will not resurrect + MDL for any recovered transactions that may hold locks on + the table. We will prevent race conditions by "unnecessarily" + acquiring an InnoDB table lock even for online operation, + to ensure that the rollback of recovered transactions will + not run concurrently with online ADD INDEX. */ + user_table->lock_mutex_lock(); + for (lock_t *lock = UT_LIST_GET_FIRST(user_table->locks); + lock; + lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock)) { + if (lock->trx->is_recovered) { + user_table->lock_mutex_unlock(); + goto acquire_lock; + } + } + user_table->lock_mutex_unlock(); } if (fts_exist) { @@ -7482,6 +7495,10 @@ alter_fill_stored_column( } } +static bool alter_templ_needs_rebuild(const TABLE* altered_table, + const Alter_inplace_info* ha_alter_info, + const dict_table_t* table); + /** Allows InnoDB to update internal structures with concurrent writes blocked (provided that check_if_supported_inplace_alter() @@ -7512,7 +7529,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; @@ -7550,12 +7566,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); } @@ -7636,11 +7646,7 @@ ha_innobase::prepare_inplace_alter_table( ha_alter_info->key_count)) { err_exit_no_heap: 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); - } + online_retry_drop_indexes(m_prebuilt->table, m_user_thd); DBUG_RETURN(true); } @@ -7721,7 +7727,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 */ @@ -8083,6 +8095,8 @@ err_exit: const ha_table_option_struct& alt_opt= *ha_alter_info->create_info->option_struct; + ha_innobase_inplace_ctx *ctx = NULL; + if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA) || ((ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE | INNOBASE_ALTER_NOCREATE @@ -8090,15 +8104,11 @@ err_exit: == ALTER_OPTIONS && !alter_options_need_rebuild(ha_alter_info, table))) { - DBUG_ASSERT(!m_prebuilt->trx->dict_operation_lock_mode); - if (ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) { - online_retry_drop_indexes(m_prebuilt->table, - m_user_thd); - } + DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); + online_retry_drop_indexes(m_prebuilt->table, m_user_thd); if (heap) { - ha_alter_info->handler_ctx - = new ha_innobase_inplace_ctx( + ctx = new ha_innobase_inplace_ctx( m_prebuilt, drop_index, n_drop_index, drop_fk, n_drop_fk, @@ -8110,6 +8120,7 @@ err_exit: || !thd_is_strict_mode(m_user_thd)), alt_opt.page_compressed, alt_opt.page_compression_level); + ha_alter_info->handler_ctx = ctx; } if ((ha_alter_info->handler_flags @@ -8125,6 +8136,25 @@ err_exit: DBUG_RETURN(true); } + if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA) + && alter_templ_needs_rebuild(altered_table, ha_alter_info, + ctx->new_table) + && ctx->new_table->n_v_cols > 0) { + /* Changing maria record structure may end up here only + if virtual columns were altered. In this case, however, + vc_templ should be rebuilt. Since we don't actually + change any stored data, we can just dispose vc_templ; + it will be recreated on next ha_innobase::open(). */ + + DBUG_ASSERT(ctx->new_table == ctx->old_table); + + dict_free_vc_templ(ctx->new_table->vc_templ); + UT_DELETE(ctx->new_table->vc_templ); + + ctx->new_table->vc_templ = NULL; + } + + success: /* Memorize the future transaction ID for committing the data dictionary change, to be reported by @@ -8249,35 +8279,6 @@ found_col: DBUG_RETURN(true); } -/** Check that the column is part of a virtual index(index contains -virtual column) in the table -@param[in] table Table containing column -@param[in] col column to be checked -@return true if this column is indexed with other virtual columns */ -static -bool -dict_col_in_v_indexes( - dict_table_t* table, - dict_col_t* col) -{ - for (dict_index_t* index = dict_table_get_next_index( - dict_table_get_first_index(table)); index != NULL; - index = dict_table_get_next_index(index)) { - if (!dict_index_has_virtual(index)) { - continue; - } - for (ulint k = 0; k < index->n_fields; k++) { - dict_field_t* field - = dict_index_get_nth_field(index, k); - if (field->col->ind == col->ind) { - return(true); - } - } - } - - return(false); -} - /* Check whether a columnn length change alter operation requires to rebuild the template. @param[in] altered_table TABLE object for new version of table. @@ -8289,9 +8290,9 @@ to rebuild the template. static bool alter_templ_needs_rebuild( - TABLE* altered_table, - Alter_inplace_info* ha_alter_info, - dict_table_t* table) + const TABLE* altered_table, + const Alter_inplace_info* ha_alter_info, + const dict_table_t* table) { ulint i = 0; @@ -8301,8 +8302,7 @@ alter_templ_needs_rebuild( for (ulint j=0; j < table->n_cols; j++) { dict_col_t* cols = dict_table_get_nth_col(table, j); - if (cf.length > cols->len - && dict_col_in_v_indexes(table, cols)) { + if (cf.length > cols->len) { return(true); } } diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index b68aff98780..8d8ab582f05 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -2401,21 +2401,17 @@ i_s_fts_deleted_generic_fill( RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); - /* Prevent DROP of the internal tables for fulltext indexes. - FIXME: acquire DDL-blocking MDL on the user table name! */ - dict_sys.freeze(); - + MDL_ticket* mdl_ticket = nullptr; user_table = dict_table_open_on_id( - innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); + innodb_ft_aux_table_id, false, DICT_TABLE_OP_NORMAL, + thd, &mdl_ticket); if (!user_table) { -func_exit: - dict_sys.unfreeze(); DBUG_RETURN(0); } else if (!dict_table_has_fts_index(user_table) || !user_table->is_readable()) { - dict_table_close(user_table, FALSE, FALSE); - goto func_exit; + dict_table_close(user_table, false, false, thd, mdl_ticket); + DBUG_RETURN(0); } deleted = fts_doc_ids_create(); @@ -2429,9 +2425,7 @@ func_exit: fts_table_fetch_doc_ids(trx, &fts_table, deleted); - dict_table_close(user_table, FALSE, FALSE); - - dict_sys.unfreeze(); + dict_table_close(user_table, false, false, thd, mdl_ticket); trx->free(); @@ -2778,22 +2772,18 @@ i_s_fts_index_cache_fill( RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); - /* Prevent DROP of the internal tables for fulltext indexes. - FIXME: acquire DDL-blocking MDL on the user table name! */ - dict_sys.freeze(); - + MDL_ticket* mdl_ticket = nullptr; user_table = dict_table_open_on_id( - innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); + innodb_ft_aux_table_id, false, DICT_TABLE_OP_NORMAL, + thd, &mdl_ticket); if (!user_table) { -no_fts: - dict_sys.unfreeze(); DBUG_RETURN(0); } if (!user_table->fts || !user_table->fts->cache) { - dict_table_close(user_table, FALSE, FALSE); - goto no_fts; + dict_table_close(user_table, false, false, thd, mdl_ticket); + DBUG_RETURN(0); } cache = user_table->fts->cache; @@ -2817,8 +2807,7 @@ no_fts: } mysql_mutex_unlock(&cache->lock); - dict_table_close(user_table, FALSE, FALSE); - dict_sys.unfreeze(); + dict_table_close(user_table, false, false, thd, mdl_ticket); DBUG_RETURN(ret); } @@ -3226,15 +3215,12 @@ i_s_fts_index_table_fill( RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); - /* Prevent DROP of the internal tables for fulltext indexes. - FIXME: acquire DDL-blocking MDL on the user table name! */ - dict_sys.freeze(); - + MDL_ticket* mdl_ticket = nullptr; user_table = dict_table_open_on_id( - innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); + innodb_ft_aux_table_id, false, DICT_TABLE_OP_NORMAL, + thd, &mdl_ticket); if (!user_table) { - dict_sys.unfreeze(); DBUG_RETURN(0); } @@ -3252,9 +3238,7 @@ i_s_fts_index_table_fill( } } - dict_table_close(user_table, FALSE, FALSE); - - dict_sys.unfreeze(); + dict_table_close(user_table, false, false, thd, mdl_ticket); ut_free(conv_str.f_str); @@ -3380,22 +3364,18 @@ i_s_fts_config_fill( RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); - /* Prevent DROP of the internal tables for fulltext indexes. - FIXME: acquire DDL-blocking MDL on the user table name! */ - dict_sys.freeze(); - + MDL_ticket* mdl_ticket = nullptr; user_table = dict_table_open_on_id( - innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); + innodb_ft_aux_table_id, false, DICT_TABLE_OP_NORMAL, + thd, &mdl_ticket); if (!user_table) { -no_fts: - dict_sys.unfreeze(); DBUG_RETURN(0); } if (!dict_table_has_fts_index(user_table)) { - dict_table_close(user_table, FALSE, FALSE); - goto no_fts; + dict_table_close(user_table, false, false, thd, mdl_ticket); + DBUG_RETURN(0); } fields = table->field; @@ -3451,9 +3431,7 @@ no_fts: fts_sql_commit(trx); - dict_table_close(user_table, FALSE, FALSE); - - dict_sys.unfreeze(); + dict_table_close(user_table, false, false, thd, mdl_ticket); trx->free(); diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 8fe0c75309c..d3b65c83c60 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1524,24 +1524,6 @@ struct dict_foreign_with_index { const dict_index_t* m_index; }; -#ifdef WITH_WSREP -/** A function object to find a foreign key with the given index as the -foreign index. Return the foreign key with matching criteria or NULL */ -struct dict_foreign_with_foreign_index { - - dict_foreign_with_foreign_index(const dict_index_t* index) - : m_index(index) - {} - - bool operator()(const dict_foreign_t* foreign) const - { - return(foreign->foreign_index == m_index); - } - - const dict_index_t* m_index; -}; -#endif - /* A function object to check if the foreign constraint is between different tables. Returns true if foreign key constraint is between different tables, false otherwise. */ diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index bb61eae43f2..95b5131a526 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -931,16 +931,6 @@ fts_check_cached_index( /*===================*/ dict_table_t* table); /*!< in: Table where indexes are dropped */ -/** Check if the all the auxillary tables associated with FTS index are in -consistent state. For now consistency is check only by ensuring -index->page_no != FIL_NULL -@param[out] base_table table has host fts index -@param[in,out] trx trx handler */ -void -fts_check_corrupt( - dict_table_t* base_table, - trx_t* trx); - /** Fetch the document from tuple, tokenize the text data and insert the text data into fts auxiliary table and its cache. Moreover this tuple fields doesn't contain any information diff --git a/storage/innobase/include/pars0grm.h b/storage/innobase/include/pars0grm.h index 58d424abfdc..e7112d9996f 100644 --- a/storage/innobase/include/pars0grm.h +++ b/storage/innobase/include/pars0grm.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.4.2. */ +/* A Bison parser, made by GNU Bison 3.7.6. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -31,8 +31,9 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -/* Undocumented macros, especially those whose name start with YY_, - are private implementation details. Do not rely on them. */ +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ #ifndef YY_YY_PARS0GRM_TAB_H_INCLUDED # define YY_YY_PARS0GRM_TAB_H_INCLUDED @@ -44,90 +45,95 @@ extern int yydebug; #endif -/* Token type. */ +/* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { - PARS_INT_LIT = 258, - PARS_FLOAT_LIT = 259, - PARS_STR_LIT = 260, - PARS_NULL_LIT = 261, - PARS_ID_TOKEN = 262, - PARS_AND_TOKEN = 263, - PARS_OR_TOKEN = 264, - PARS_NOT_TOKEN = 265, - PARS_GE_TOKEN = 266, - PARS_LE_TOKEN = 267, - PARS_NE_TOKEN = 268, - PARS_PROCEDURE_TOKEN = 269, - PARS_IN_TOKEN = 270, - PARS_INT_TOKEN = 271, - PARS_CHAR_TOKEN = 272, - PARS_IS_TOKEN = 273, - PARS_BEGIN_TOKEN = 274, - PARS_END_TOKEN = 275, - PARS_IF_TOKEN = 276, - PARS_THEN_TOKEN = 277, - PARS_ELSE_TOKEN = 278, - PARS_ELSIF_TOKEN = 279, - PARS_LOOP_TOKEN = 280, - PARS_WHILE_TOKEN = 281, - PARS_RETURN_TOKEN = 282, - PARS_SELECT_TOKEN = 283, - PARS_COUNT_TOKEN = 284, - PARS_FROM_TOKEN = 285, - PARS_WHERE_TOKEN = 286, - PARS_FOR_TOKEN = 287, - PARS_DDOT_TOKEN = 288, - PARS_ORDER_TOKEN = 289, - PARS_BY_TOKEN = 290, - PARS_ASC_TOKEN = 291, - PARS_DESC_TOKEN = 292, - PARS_INSERT_TOKEN = 293, - PARS_INTO_TOKEN = 294, - PARS_VALUES_TOKEN = 295, - PARS_UPDATE_TOKEN = 296, - PARS_SET_TOKEN = 297, - PARS_DELETE_TOKEN = 298, - PARS_CURRENT_TOKEN = 299, - PARS_OF_TOKEN = 300, - PARS_CREATE_TOKEN = 301, - PARS_TABLE_TOKEN = 302, - PARS_INDEX_TOKEN = 303, - PARS_UNIQUE_TOKEN = 304, - PARS_CLUSTERED_TOKEN = 305, - PARS_ON_TOKEN = 306, - PARS_ASSIGN_TOKEN = 307, - PARS_DECLARE_TOKEN = 308, - PARS_CURSOR_TOKEN = 309, - PARS_SQL_TOKEN = 310, - PARS_OPEN_TOKEN = 311, - PARS_FETCH_TOKEN = 312, - PARS_CLOSE_TOKEN = 313, - PARS_NOTFOUND_TOKEN = 314, - PARS_TO_BINARY_TOKEN = 315, - PARS_SUBSTR_TOKEN = 316, - PARS_CONCAT_TOKEN = 317, - PARS_INSTR_TOKEN = 318, - PARS_LENGTH_TOKEN = 319, - PARS_COMMIT_TOKEN = 320, - PARS_ROLLBACK_TOKEN = 321, - PARS_WORK_TOKEN = 322, - PARS_EXIT_TOKEN = 323, - PARS_FUNCTION_TOKEN = 324, - PARS_LOCK_TOKEN = 325, - PARS_SHARE_TOKEN = 326, - PARS_MODE_TOKEN = 327, - PARS_LIKE_TOKEN = 328, - PARS_LIKE_TOKEN_EXACT = 329, - PARS_LIKE_TOKEN_PREFIX = 330, - PARS_LIKE_TOKEN_SUFFIX = 331, - PARS_LIKE_TOKEN_SUBSTR = 332, - PARS_TABLE_NAME_TOKEN = 333, - PARS_BIGINT_TOKEN = 334, - NEG = 335 + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + PARS_INT_LIT = 258, /* PARS_INT_LIT */ + PARS_FLOAT_LIT = 259, /* PARS_FLOAT_LIT */ + PARS_STR_LIT = 260, /* PARS_STR_LIT */ + PARS_NULL_LIT = 261, /* PARS_NULL_LIT */ + PARS_ID_TOKEN = 262, /* PARS_ID_TOKEN */ + PARS_AND_TOKEN = 263, /* PARS_AND_TOKEN */ + PARS_OR_TOKEN = 264, /* PARS_OR_TOKEN */ + PARS_NOT_TOKEN = 265, /* PARS_NOT_TOKEN */ + PARS_GE_TOKEN = 266, /* PARS_GE_TOKEN */ + PARS_LE_TOKEN = 267, /* PARS_LE_TOKEN */ + PARS_NE_TOKEN = 268, /* PARS_NE_TOKEN */ + PARS_PROCEDURE_TOKEN = 269, /* PARS_PROCEDURE_TOKEN */ + PARS_IN_TOKEN = 270, /* PARS_IN_TOKEN */ + PARS_INT_TOKEN = 271, /* PARS_INT_TOKEN */ + PARS_CHAR_TOKEN = 272, /* PARS_CHAR_TOKEN */ + PARS_IS_TOKEN = 273, /* PARS_IS_TOKEN */ + PARS_BEGIN_TOKEN = 274, /* PARS_BEGIN_TOKEN */ + PARS_END_TOKEN = 275, /* PARS_END_TOKEN */ + PARS_IF_TOKEN = 276, /* PARS_IF_TOKEN */ + PARS_THEN_TOKEN = 277, /* PARS_THEN_TOKEN */ + PARS_ELSE_TOKEN = 278, /* PARS_ELSE_TOKEN */ + PARS_ELSIF_TOKEN = 279, /* PARS_ELSIF_TOKEN */ + PARS_LOOP_TOKEN = 280, /* PARS_LOOP_TOKEN */ + PARS_WHILE_TOKEN = 281, /* PARS_WHILE_TOKEN */ + PARS_RETURN_TOKEN = 282, /* PARS_RETURN_TOKEN */ + PARS_SELECT_TOKEN = 283, /* PARS_SELECT_TOKEN */ + PARS_COUNT_TOKEN = 284, /* PARS_COUNT_TOKEN */ + PARS_FROM_TOKEN = 285, /* PARS_FROM_TOKEN */ + PARS_WHERE_TOKEN = 286, /* PARS_WHERE_TOKEN */ + PARS_FOR_TOKEN = 287, /* PARS_FOR_TOKEN */ + PARS_DDOT_TOKEN = 288, /* PARS_DDOT_TOKEN */ + PARS_ORDER_TOKEN = 289, /* PARS_ORDER_TOKEN */ + PARS_BY_TOKEN = 290, /* PARS_BY_TOKEN */ + PARS_ASC_TOKEN = 291, /* PARS_ASC_TOKEN */ + PARS_DESC_TOKEN = 292, /* PARS_DESC_TOKEN */ + PARS_INSERT_TOKEN = 293, /* PARS_INSERT_TOKEN */ + PARS_INTO_TOKEN = 294, /* PARS_INTO_TOKEN */ + PARS_VALUES_TOKEN = 295, /* PARS_VALUES_TOKEN */ + PARS_UPDATE_TOKEN = 296, /* PARS_UPDATE_TOKEN */ + PARS_SET_TOKEN = 297, /* PARS_SET_TOKEN */ + PARS_DELETE_TOKEN = 298, /* PARS_DELETE_TOKEN */ + PARS_CURRENT_TOKEN = 299, /* PARS_CURRENT_TOKEN */ + PARS_OF_TOKEN = 300, /* PARS_OF_TOKEN */ + PARS_CREATE_TOKEN = 301, /* PARS_CREATE_TOKEN */ + PARS_TABLE_TOKEN = 302, /* PARS_TABLE_TOKEN */ + PARS_INDEX_TOKEN = 303, /* PARS_INDEX_TOKEN */ + PARS_UNIQUE_TOKEN = 304, /* PARS_UNIQUE_TOKEN */ + PARS_CLUSTERED_TOKEN = 305, /* PARS_CLUSTERED_TOKEN */ + PARS_ON_TOKEN = 306, /* PARS_ON_TOKEN */ + PARS_ASSIGN_TOKEN = 307, /* PARS_ASSIGN_TOKEN */ + PARS_DECLARE_TOKEN = 308, /* PARS_DECLARE_TOKEN */ + PARS_CURSOR_TOKEN = 309, /* PARS_CURSOR_TOKEN */ + PARS_SQL_TOKEN = 310, /* PARS_SQL_TOKEN */ + PARS_OPEN_TOKEN = 311, /* PARS_OPEN_TOKEN */ + PARS_FETCH_TOKEN = 312, /* PARS_FETCH_TOKEN */ + PARS_CLOSE_TOKEN = 313, /* PARS_CLOSE_TOKEN */ + PARS_NOTFOUND_TOKEN = 314, /* PARS_NOTFOUND_TOKEN */ + PARS_TO_BINARY_TOKEN = 315, /* PARS_TO_BINARY_TOKEN */ + PARS_SUBSTR_TOKEN = 316, /* PARS_SUBSTR_TOKEN */ + PARS_CONCAT_TOKEN = 317, /* PARS_CONCAT_TOKEN */ + PARS_INSTR_TOKEN = 318, /* PARS_INSTR_TOKEN */ + PARS_LENGTH_TOKEN = 319, /* PARS_LENGTH_TOKEN */ + PARS_COMMIT_TOKEN = 320, /* PARS_COMMIT_TOKEN */ + PARS_ROLLBACK_TOKEN = 321, /* PARS_ROLLBACK_TOKEN */ + PARS_WORK_TOKEN = 322, /* PARS_WORK_TOKEN */ + PARS_EXIT_TOKEN = 323, /* PARS_EXIT_TOKEN */ + PARS_FUNCTION_TOKEN = 324, /* PARS_FUNCTION_TOKEN */ + PARS_LOCK_TOKEN = 325, /* PARS_LOCK_TOKEN */ + PARS_SHARE_TOKEN = 326, /* PARS_SHARE_TOKEN */ + PARS_MODE_TOKEN = 327, /* PARS_MODE_TOKEN */ + PARS_LIKE_TOKEN = 328, /* PARS_LIKE_TOKEN */ + PARS_LIKE_TOKEN_EXACT = 329, /* PARS_LIKE_TOKEN_EXACT */ + PARS_LIKE_TOKEN_PREFIX = 330, /* PARS_LIKE_TOKEN_PREFIX */ + PARS_LIKE_TOKEN_SUFFIX = 331, /* PARS_LIKE_TOKEN_SUFFIX */ + PARS_LIKE_TOKEN_SUBSTR = 332, /* PARS_LIKE_TOKEN_SUBSTR */ + PARS_TABLE_NAME_TOKEN = 333, /* PARS_TABLE_NAME_TOKEN */ + PARS_BIGINT_TOKEN = 334, /* PARS_BIGINT_TOKEN */ + NEG = 335 /* NEG */ }; + typedef enum yytokentype yytoken_kind_t; #endif /* Value type. */ diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h index 7a251d08464..c3cb23e44ca 100644 --- a/storage/innobase/include/pars0pars.h +++ b/storage/innobase/include/pars0pars.h @@ -367,16 +367,6 @@ pars_procedure_definition( table */ que_node_t* stat_list); /*!< in: statement list */ -/*************************************************************//** -Parses a stored procedure call, when this is not within another stored -procedure, that is, the client issues a procedure call directly. -In MySQL/InnoDB, stored InnoDB procedures are invoked via the -parsed procedure tree, not via InnoDB SQL, so this function is not used. -@return query graph */ -que_fork_t* -pars_stored_procedure_call( -/*=======================*/ - sym_node_t* sym_node); /*!< in: stored procedure name */ /** Completes a query graph by adding query thread and fork nodes above it and prepares the graph for running. @param[in] node root node for an incomplete query diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 6c783ec3495..998de196dd9 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -330,17 +330,6 @@ row_mysql_unlock_data_dictionary( /*=============================*/ trx_t* trx); /*!< in/out: transaction */ /*********************************************************************//** -Locks the data dictionary in shared mode from modifications, for performing -foreign key check, rollback, or other operation invisible to MySQL. */ -void row_mysql_freeze_data_dictionary(trx_t *trx); - -/*********************************************************************//** -Unlocks the data dictionary shared lock. */ -void -row_mysql_unfreeze_data_dictionary( -/*===============================*/ - trx_t* trx); /*!< in/out: transaction */ -/*********************************************************************//** Creates a table for MySQL. On failure the transaction will be rolled back and the 'table' object will be freed. @return error code or DB_SUCCESS */ diff --git a/storage/innobase/innodb.cmake b/storage/innobase/innodb.cmake index 5535be45645..73863ef13df 100644 --- a/storage/innobase/innodb.cmake +++ b/storage/innobase/innodb.cmake @@ -72,6 +72,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") @@ -82,15 +83,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) @@ -127,6 +134,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 @@ -152,8 +160,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/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 017ea939f08..bcdf430e476 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1703,8 +1703,7 @@ dberr_t lock_wait(que_thr_t *thr) const ulong innodb_lock_wait_timeout= trx_lock_wait_timeout_get(trx); const bool no_timeout= innodb_lock_wait_timeout >= 100000000; const my_hrtime_t suspend_time= my_hrtime_coarse(); - ut_ad(!trx->dict_operation_lock_mode || - trx->dict_operation_lock_mode == RW_S_LATCH); + ut_ad(!trx->dict_operation_lock_mode); /* The wait_lock can be cleared by another thread in lock_grant(), lock_rec_cancel(), or lock_cancel_waiting_and_release(). But, a wait @@ -1739,9 +1738,7 @@ dberr_t lock_wait(que_thr_t *thr) trx->lock.suspend_time= suspend_time; - const auto had_dict_lock= trx->dict_operation_lock_mode; - if (had_dict_lock) /* Release foreign key check latch */ - row_mysql_unfreeze_data_dictionary(trx); + ut_ad(!trx->dict_operation_lock_mode); IF_WSREP(if (trx->is_wsrep()) lock_wait_wsrep(trx),); @@ -1837,9 +1834,6 @@ end_wait: mysql_mutex_unlock(&lock_sys.wait_mutex); thd_wait_end(trx->mysql_thd); - if (had_dict_lock) - row_mysql_freeze_data_dictionary(trx); - trx->error_state= error_state; return error_state; } @@ -3791,11 +3785,7 @@ void lock_release(trx_t *trx) #if defined SAFE_MUTEX && defined UNIV_DEBUG std::set to_evict; if (innodb_evict_tables_on_commit_debug && !trx->is_recovered) -# if 1 /* if dict_stats_exec_sql() were not playing dirty tricks */ - if (!dict_sys.mutex_is_locked()) -# else /* this would be more proper way to do it */ if (!trx->dict_operation_lock_mode && !trx->dict_operation) -# endif for (const auto& p: trx->mod_tables) if (!p.first->is_temporary()) to_evict.emplace(p.first->id); 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 0c39b5318d2..0618d30c2b8 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -335,6 +335,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 547204003eb..d3862ceea3b 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -4630,12 +4630,12 @@ bool page_zip_verify_checksum(const byte *data, size_t size) #ifdef UNIV_INNOCHECKSUM extern FILE* log_file; - extern unsigned long long cur_page_num; + extern uint32_t cur_page_num; if (log_file) { - fprintf(log_file, "page::%llu;" - " checksum: calculated = %u;" - " recorded = %u\n", cur_page_num, + fprintf(log_file, "page::" UINT32PF ";" + " checksum: calculated = " UINT32PF ";" + " recorded = " UINT32PF "\n", cur_page_num, calc, stored); } #endif /* UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/pars/make_bison.sh b/storage/innobase/pars/make_bison.sh index 6b3cb693978..25c967aceda 100755 --- a/storage/innobase/pars/make_bison.sh +++ b/storage/innobase/pars/make_bison.sh @@ -25,6 +25,7 @@ mv pars0grm.tab.h ../include/pars0grm.h sed -e ' s/'"$TMPFILE"'/'"$OUTFILE"'/; +s/'"pars0grm.tab.h"'/'"pars0grm.h"'/; s/^\(\(YYSTYPE\|int\) yy\(char\|nerrs\)\)/static \1/; ' < "$TMPFILE" > "$OUTFILE" diff --git a/storage/innobase/pars/pars0grm.cc b/storage/innobase/pars/pars0grm.cc index 7e10a783310..1f5d8dad92e 100644 --- a/storage/innobase/pars/pars0grm.cc +++ b/storage/innobase/pars/pars0grm.cc @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.4.2. */ +/* A Bison parser, made by GNU Bison 3.7.6. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -34,6 +34,10 @@ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. @@ -41,14 +45,11 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ -/* Undocumented macros, especially those whose name start with YY_, - are private implementation details. Do not rely on them. */ +/* Identify Bison output, and Bison version. */ +#define YYBISON 30706 -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "3.4.2" +/* Bison version string. */ +#define YYBISON_VERSION "3.7.6" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -85,8 +86,17 @@ que_node_t */ int yylex(void); -#line 89 "pars0grm.cc" +#line 90 "pars0grm.cc" +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus @@ -99,125 +109,169 @@ yylex(void); # endif # endif -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif +#include "pars0grm.h" +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_PARS_INT_LIT = 3, /* PARS_INT_LIT */ + YYSYMBOL_PARS_FLOAT_LIT = 4, /* PARS_FLOAT_LIT */ + YYSYMBOL_PARS_STR_LIT = 5, /* PARS_STR_LIT */ + YYSYMBOL_PARS_NULL_LIT = 6, /* PARS_NULL_LIT */ + YYSYMBOL_PARS_ID_TOKEN = 7, /* PARS_ID_TOKEN */ + YYSYMBOL_PARS_AND_TOKEN = 8, /* PARS_AND_TOKEN */ + YYSYMBOL_PARS_OR_TOKEN = 9, /* PARS_OR_TOKEN */ + YYSYMBOL_PARS_NOT_TOKEN = 10, /* PARS_NOT_TOKEN */ + YYSYMBOL_PARS_GE_TOKEN = 11, /* PARS_GE_TOKEN */ + YYSYMBOL_PARS_LE_TOKEN = 12, /* PARS_LE_TOKEN */ + YYSYMBOL_PARS_NE_TOKEN = 13, /* PARS_NE_TOKEN */ + YYSYMBOL_PARS_PROCEDURE_TOKEN = 14, /* PARS_PROCEDURE_TOKEN */ + YYSYMBOL_PARS_IN_TOKEN = 15, /* PARS_IN_TOKEN */ + YYSYMBOL_PARS_INT_TOKEN = 16, /* PARS_INT_TOKEN */ + YYSYMBOL_PARS_CHAR_TOKEN = 17, /* PARS_CHAR_TOKEN */ + YYSYMBOL_PARS_IS_TOKEN = 18, /* PARS_IS_TOKEN */ + YYSYMBOL_PARS_BEGIN_TOKEN = 19, /* PARS_BEGIN_TOKEN */ + YYSYMBOL_PARS_END_TOKEN = 20, /* PARS_END_TOKEN */ + YYSYMBOL_PARS_IF_TOKEN = 21, /* PARS_IF_TOKEN */ + YYSYMBOL_PARS_THEN_TOKEN = 22, /* PARS_THEN_TOKEN */ + YYSYMBOL_PARS_ELSE_TOKEN = 23, /* PARS_ELSE_TOKEN */ + YYSYMBOL_PARS_ELSIF_TOKEN = 24, /* PARS_ELSIF_TOKEN */ + YYSYMBOL_PARS_LOOP_TOKEN = 25, /* PARS_LOOP_TOKEN */ + YYSYMBOL_PARS_WHILE_TOKEN = 26, /* PARS_WHILE_TOKEN */ + YYSYMBOL_PARS_RETURN_TOKEN = 27, /* PARS_RETURN_TOKEN */ + YYSYMBOL_PARS_SELECT_TOKEN = 28, /* PARS_SELECT_TOKEN */ + YYSYMBOL_PARS_COUNT_TOKEN = 29, /* PARS_COUNT_TOKEN */ + YYSYMBOL_PARS_FROM_TOKEN = 30, /* PARS_FROM_TOKEN */ + YYSYMBOL_PARS_WHERE_TOKEN = 31, /* PARS_WHERE_TOKEN */ + YYSYMBOL_PARS_FOR_TOKEN = 32, /* PARS_FOR_TOKEN */ + YYSYMBOL_PARS_DDOT_TOKEN = 33, /* PARS_DDOT_TOKEN */ + YYSYMBOL_PARS_ORDER_TOKEN = 34, /* PARS_ORDER_TOKEN */ + YYSYMBOL_PARS_BY_TOKEN = 35, /* PARS_BY_TOKEN */ + YYSYMBOL_PARS_ASC_TOKEN = 36, /* PARS_ASC_TOKEN */ + YYSYMBOL_PARS_DESC_TOKEN = 37, /* PARS_DESC_TOKEN */ + YYSYMBOL_PARS_INSERT_TOKEN = 38, /* PARS_INSERT_TOKEN */ + YYSYMBOL_PARS_INTO_TOKEN = 39, /* PARS_INTO_TOKEN */ + YYSYMBOL_PARS_VALUES_TOKEN = 40, /* PARS_VALUES_TOKEN */ + YYSYMBOL_PARS_UPDATE_TOKEN = 41, /* PARS_UPDATE_TOKEN */ + YYSYMBOL_PARS_SET_TOKEN = 42, /* PARS_SET_TOKEN */ + YYSYMBOL_PARS_DELETE_TOKEN = 43, /* PARS_DELETE_TOKEN */ + YYSYMBOL_PARS_CURRENT_TOKEN = 44, /* PARS_CURRENT_TOKEN */ + YYSYMBOL_PARS_OF_TOKEN = 45, /* PARS_OF_TOKEN */ + YYSYMBOL_PARS_CREATE_TOKEN = 46, /* PARS_CREATE_TOKEN */ + YYSYMBOL_PARS_TABLE_TOKEN = 47, /* PARS_TABLE_TOKEN */ + YYSYMBOL_PARS_INDEX_TOKEN = 48, /* PARS_INDEX_TOKEN */ + YYSYMBOL_PARS_UNIQUE_TOKEN = 49, /* PARS_UNIQUE_TOKEN */ + YYSYMBOL_PARS_CLUSTERED_TOKEN = 50, /* PARS_CLUSTERED_TOKEN */ + YYSYMBOL_PARS_ON_TOKEN = 51, /* PARS_ON_TOKEN */ + YYSYMBOL_PARS_ASSIGN_TOKEN = 52, /* PARS_ASSIGN_TOKEN */ + YYSYMBOL_PARS_DECLARE_TOKEN = 53, /* PARS_DECLARE_TOKEN */ + YYSYMBOL_PARS_CURSOR_TOKEN = 54, /* PARS_CURSOR_TOKEN */ + YYSYMBOL_PARS_SQL_TOKEN = 55, /* PARS_SQL_TOKEN */ + YYSYMBOL_PARS_OPEN_TOKEN = 56, /* PARS_OPEN_TOKEN */ + YYSYMBOL_PARS_FETCH_TOKEN = 57, /* PARS_FETCH_TOKEN */ + YYSYMBOL_PARS_CLOSE_TOKEN = 58, /* PARS_CLOSE_TOKEN */ + YYSYMBOL_PARS_NOTFOUND_TOKEN = 59, /* PARS_NOTFOUND_TOKEN */ + YYSYMBOL_PARS_TO_BINARY_TOKEN = 60, /* PARS_TO_BINARY_TOKEN */ + YYSYMBOL_PARS_SUBSTR_TOKEN = 61, /* PARS_SUBSTR_TOKEN */ + YYSYMBOL_PARS_CONCAT_TOKEN = 62, /* PARS_CONCAT_TOKEN */ + YYSYMBOL_PARS_INSTR_TOKEN = 63, /* PARS_INSTR_TOKEN */ + YYSYMBOL_PARS_LENGTH_TOKEN = 64, /* PARS_LENGTH_TOKEN */ + YYSYMBOL_PARS_COMMIT_TOKEN = 65, /* PARS_COMMIT_TOKEN */ + YYSYMBOL_PARS_ROLLBACK_TOKEN = 66, /* PARS_ROLLBACK_TOKEN */ + YYSYMBOL_PARS_WORK_TOKEN = 67, /* PARS_WORK_TOKEN */ + YYSYMBOL_PARS_EXIT_TOKEN = 68, /* PARS_EXIT_TOKEN */ + YYSYMBOL_PARS_FUNCTION_TOKEN = 69, /* PARS_FUNCTION_TOKEN */ + YYSYMBOL_PARS_LOCK_TOKEN = 70, /* PARS_LOCK_TOKEN */ + YYSYMBOL_PARS_SHARE_TOKEN = 71, /* PARS_SHARE_TOKEN */ + YYSYMBOL_PARS_MODE_TOKEN = 72, /* PARS_MODE_TOKEN */ + YYSYMBOL_PARS_LIKE_TOKEN = 73, /* PARS_LIKE_TOKEN */ + YYSYMBOL_PARS_LIKE_TOKEN_EXACT = 74, /* PARS_LIKE_TOKEN_EXACT */ + YYSYMBOL_PARS_LIKE_TOKEN_PREFIX = 75, /* PARS_LIKE_TOKEN_PREFIX */ + YYSYMBOL_PARS_LIKE_TOKEN_SUFFIX = 76, /* PARS_LIKE_TOKEN_SUFFIX */ + YYSYMBOL_PARS_LIKE_TOKEN_SUBSTR = 77, /* PARS_LIKE_TOKEN_SUBSTR */ + YYSYMBOL_PARS_TABLE_NAME_TOKEN = 78, /* PARS_TABLE_NAME_TOKEN */ + YYSYMBOL_PARS_BIGINT_TOKEN = 79, /* PARS_BIGINT_TOKEN */ + YYSYMBOL_80_ = 80, /* '=' */ + YYSYMBOL_81_ = 81, /* '<' */ + YYSYMBOL_82_ = 82, /* '>' */ + YYSYMBOL_83_ = 83, /* '-' */ + YYSYMBOL_84_ = 84, /* '+' */ + YYSYMBOL_85_ = 85, /* '*' */ + YYSYMBOL_86_ = 86, /* '/' */ + YYSYMBOL_NEG = 87, /* NEG */ + YYSYMBOL_88_ = 88, /* '%' */ + YYSYMBOL_89_ = 89, /* ';' */ + YYSYMBOL_90_ = 90, /* '(' */ + YYSYMBOL_91_ = 91, /* ')' */ + YYSYMBOL_92_ = 92, /* ',' */ + YYSYMBOL_YYACCEPT = 93, /* $accept */ + YYSYMBOL_top_statement = 94, /* top_statement */ + YYSYMBOL_statement = 95, /* statement */ + YYSYMBOL_statement_list = 96, /* statement_list */ + YYSYMBOL_exp = 97, /* exp */ + YYSYMBOL_function_name = 98, /* function_name */ + YYSYMBOL_user_function_call = 99, /* user_function_call */ + YYSYMBOL_table_list = 100, /* table_list */ + YYSYMBOL_variable_list = 101, /* variable_list */ + YYSYMBOL_exp_list = 102, /* exp_list */ + YYSYMBOL_select_item = 103, /* select_item */ + YYSYMBOL_select_item_list = 104, /* select_item_list */ + YYSYMBOL_select_list = 105, /* select_list */ + YYSYMBOL_search_condition = 106, /* search_condition */ + YYSYMBOL_for_update_clause = 107, /* for_update_clause */ + YYSYMBOL_lock_shared_clause = 108, /* lock_shared_clause */ + YYSYMBOL_order_direction = 109, /* order_direction */ + YYSYMBOL_order_by_clause = 110, /* order_by_clause */ + YYSYMBOL_select_statement = 111, /* select_statement */ + YYSYMBOL_insert_statement_start = 112, /* insert_statement_start */ + YYSYMBOL_insert_statement = 113, /* insert_statement */ + YYSYMBOL_column_assignment = 114, /* column_assignment */ + YYSYMBOL_column_assignment_list = 115, /* column_assignment_list */ + YYSYMBOL_cursor_positioned = 116, /* cursor_positioned */ + YYSYMBOL_update_statement_start = 117, /* update_statement_start */ + YYSYMBOL_update_statement_searched = 118, /* update_statement_searched */ + YYSYMBOL_update_statement_positioned = 119, /* update_statement_positioned */ + YYSYMBOL_delete_statement_start = 120, /* delete_statement_start */ + YYSYMBOL_delete_statement_searched = 121, /* delete_statement_searched */ + YYSYMBOL_delete_statement_positioned = 122, /* delete_statement_positioned */ + YYSYMBOL_assignment_statement = 123, /* assignment_statement */ + YYSYMBOL_elsif_element = 124, /* elsif_element */ + YYSYMBOL_elsif_list = 125, /* elsif_list */ + YYSYMBOL_else_part = 126, /* else_part */ + YYSYMBOL_if_statement = 127, /* if_statement */ + YYSYMBOL_while_statement = 128, /* while_statement */ + YYSYMBOL_for_statement = 129, /* for_statement */ + YYSYMBOL_exit_statement = 130, /* exit_statement */ + YYSYMBOL_return_statement = 131, /* return_statement */ + YYSYMBOL_open_cursor_statement = 132, /* open_cursor_statement */ + YYSYMBOL_close_cursor_statement = 133, /* close_cursor_statement */ + YYSYMBOL_fetch_statement = 134, /* fetch_statement */ + YYSYMBOL_column_def = 135, /* column_def */ + YYSYMBOL_column_def_list = 136, /* column_def_list */ + YYSYMBOL_opt_column_len = 137, /* opt_column_len */ + YYSYMBOL_opt_not_null = 138, /* opt_not_null */ + YYSYMBOL_create_table = 139, /* create_table */ + YYSYMBOL_column_list = 140, /* column_list */ + YYSYMBOL_unique_def = 141, /* unique_def */ + YYSYMBOL_clustered_def = 142, /* clustered_def */ + YYSYMBOL_create_index = 143, /* create_index */ + YYSYMBOL_table_name = 144, /* table_name */ + YYSYMBOL_commit_statement = 145, /* commit_statement */ + YYSYMBOL_rollback_statement = 146, /* rollback_statement */ + YYSYMBOL_type_name = 147, /* type_name */ + YYSYMBOL_variable_declaration = 148, /* variable_declaration */ + YYSYMBOL_variable_declaration_list = 149, /* variable_declaration_list */ + YYSYMBOL_cursor_declaration = 150, /* cursor_declaration */ + YYSYMBOL_function_declaration = 151, /* function_declaration */ + YYSYMBOL_declaration = 152, /* declaration */ + YYSYMBOL_declaration_list = 153, /* declaration_list */ + YYSYMBOL_procedure_definition = 154 /* procedure_definition */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; -/* Use api.header.include to #include this header - instead of duplicating it here. */ -#ifndef YY_YY_PARS0GRM_TAB_H_INCLUDED -# define YY_YY_PARS0GRM_TAB_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - PARS_INT_LIT = 258, - PARS_FLOAT_LIT = 259, - PARS_STR_LIT = 260, - PARS_NULL_LIT = 261, - PARS_ID_TOKEN = 262, - PARS_AND_TOKEN = 263, - PARS_OR_TOKEN = 264, - PARS_NOT_TOKEN = 265, - PARS_GE_TOKEN = 266, - PARS_LE_TOKEN = 267, - PARS_NE_TOKEN = 268, - PARS_PROCEDURE_TOKEN = 269, - PARS_IN_TOKEN = 270, - PARS_INT_TOKEN = 271, - PARS_CHAR_TOKEN = 272, - PARS_IS_TOKEN = 273, - PARS_BEGIN_TOKEN = 274, - PARS_END_TOKEN = 275, - PARS_IF_TOKEN = 276, - PARS_THEN_TOKEN = 277, - PARS_ELSE_TOKEN = 278, - PARS_ELSIF_TOKEN = 279, - PARS_LOOP_TOKEN = 280, - PARS_WHILE_TOKEN = 281, - PARS_RETURN_TOKEN = 282, - PARS_SELECT_TOKEN = 283, - PARS_COUNT_TOKEN = 284, - PARS_FROM_TOKEN = 285, - PARS_WHERE_TOKEN = 286, - PARS_FOR_TOKEN = 287, - PARS_DDOT_TOKEN = 288, - PARS_ORDER_TOKEN = 289, - PARS_BY_TOKEN = 290, - PARS_ASC_TOKEN = 291, - PARS_DESC_TOKEN = 292, - PARS_INSERT_TOKEN = 293, - PARS_INTO_TOKEN = 294, - PARS_VALUES_TOKEN = 295, - PARS_UPDATE_TOKEN = 296, - PARS_SET_TOKEN = 297, - PARS_DELETE_TOKEN = 298, - PARS_CURRENT_TOKEN = 299, - PARS_OF_TOKEN = 300, - PARS_CREATE_TOKEN = 301, - PARS_TABLE_TOKEN = 302, - PARS_INDEX_TOKEN = 303, - PARS_UNIQUE_TOKEN = 304, - PARS_CLUSTERED_TOKEN = 305, - PARS_ON_TOKEN = 306, - PARS_ASSIGN_TOKEN = 307, - PARS_DECLARE_TOKEN = 308, - PARS_CURSOR_TOKEN = 309, - PARS_SQL_TOKEN = 310, - PARS_OPEN_TOKEN = 311, - PARS_FETCH_TOKEN = 312, - PARS_CLOSE_TOKEN = 313, - PARS_NOTFOUND_TOKEN = 314, - PARS_TO_BINARY_TOKEN = 315, - PARS_SUBSTR_TOKEN = 316, - PARS_CONCAT_TOKEN = 317, - PARS_INSTR_TOKEN = 318, - PARS_LENGTH_TOKEN = 319, - PARS_COMMIT_TOKEN = 320, - PARS_ROLLBACK_TOKEN = 321, - PARS_WORK_TOKEN = 322, - PARS_EXIT_TOKEN = 323, - PARS_FUNCTION_TOKEN = 324, - PARS_LOCK_TOKEN = 325, - PARS_SHARE_TOKEN = 326, - PARS_MODE_TOKEN = 327, - PARS_LIKE_TOKEN = 328, - PARS_LIKE_TOKEN_EXACT = 329, - PARS_LIKE_TOKEN_PREFIX = 330, - PARS_LIKE_TOKEN_SUFFIX = 331, - PARS_LIKE_TOKEN_SUBSTR = 332, - PARS_TABLE_NAME_TOKEN = 333, - PARS_BIGINT_TOKEN = 334, - NEG = 335 - }; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef int YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE yylval; - -int yyparse (void); - -#endif /* !YY_YY_PARS0GRM_TAB_H_INCLUDED */ @@ -225,36 +279,95 @@ int yyparse (void); # undef short #endif -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif #endif -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t -# elif ! defined YYSIZE_T +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else @@ -262,7 +375,20 @@ typedef short yytype_int16; # endif #endif -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_int16 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS @@ -276,38 +402,37 @@ typedef short yytype_int16; # endif #endif -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else -# define YY_ATTRIBUTE(Spec) /* empty */ +# define YY_ATTRIBUTE_PURE # endif #endif -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - #ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YY_USE(E) ((void) (E)) #else -# define YYUSE(E) /* empty */ +# define YY_USE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value @@ -320,10 +445,22 @@ typedef short yytype_int16; # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + #define YY_ASSERT(E) ((void) (0 && (E))) -#if ! defined yyoverflow || YYERROR_VERBOSE +#if !defined yyoverflow /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -388,8 +525,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - +#endif /* !defined yyoverflow */ #if (! defined yyoverflow \ && (! defined __cplusplus \ @@ -398,17 +534,17 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss_alloc; + yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 @@ -421,11 +557,11 @@ union yyalloc # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ - YYSIZE_T yynewbytes; \ + YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) @@ -437,12 +573,12 @@ union yyalloc # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ - YYSIZE_T yyi; \ + YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ @@ -454,42 +590,45 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 5 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 603 +#define YYLAST 611 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 96 +#define YYNTOKENS 93 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 64 +#define YYNNTS 62 /* YYNRULES -- Number of rules. */ -#define YYNRULES 150 +#define YYNRULES 145 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 300 +#define YYNSTATES 290 -#define YYUNDEFTOK 2 +/* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 335 + /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ -#define YYTRANSLATE(YYX) \ - ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ -static const yytype_uint8 yytranslate[] = +static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 88, 2, 2, - 90, 91, 85, 84, 93, 83, 2, 86, 2, 2, + 90, 91, 85, 84, 92, 83, 2, 86, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 89, - 81, 80, 82, 92, 2, 2, 2, 2, 2, 2, + 81, 80, 82, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 94, 2, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -515,62 +654,68 @@ static const yytype_uint8 yytranslate[] = #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = +static const yytype_int16 yyrline[] = { 0, 140, 140, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 166, 167, 172, 173, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 199, - 204, 205, 206, 207, 208, 211, 213, 214, 218, 224, - 228, 229, 234, 235, 236, 241, 242, 243, 247, 248, - 256, 257, 258, 263, 265, 268, 272, 273, 277, 278, - 283, 284, 289, 290, 291, 295, 296, 303, 318, 323, - 326, 334, 340, 341, 346, 352, 361, 369, 377, 384, - 392, 400, 407, 413, 414, 419, 420, 422, 426, 433, - 439, 449, 453, 457, 464, 471, 475, 483, 492, 493, - 498, 499, 504, 505, 511, 519, 520, 525, 526, 530, - 531, 535, 549, 550, 554, 559, 564, 565, 566, 570, - 576, 578, 579, 583, 591, 597, 598, 601, 603, 604, - 608 + 160, 161, 165, 166, 171, 172, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 198, 203, + 204, 205, 206, 207, 211, 215, 216, 221, 222, 223, + 228, 229, 230, 234, 235, 243, 244, 245, 250, 252, + 255, 259, 260, 264, 265, 270, 271, 276, 277, 278, + 282, 283, 290, 305, 310, 313, 321, 327, 328, 333, + 339, 348, 356, 364, 371, 379, 387, 394, 400, 401, + 406, 407, 409, 413, 420, 426, 436, 440, 444, 451, + 458, 462, 470, 479, 480, 485, 486, 491, 492, 498, + 506, 507, 512, 513, 517, 518, 522, 536, 537, 541, + 546, 551, 552, 553, 557, 563, 565, 566, 570, 578, + 584, 585, 588, 590, 591, 595 }; #endif -#if YYDEBUG || YYERROR_VERBOSE || 0 +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if YYDEBUG || 0 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "PARS_INT_LIT", "PARS_FLOAT_LIT", - "PARS_STR_LIT", "PARS_NULL_LIT", "PARS_ID_TOKEN", "PARS_AND_TOKEN", - "PARS_OR_TOKEN", "PARS_NOT_TOKEN", "PARS_GE_TOKEN", "PARS_LE_TOKEN", - "PARS_NE_TOKEN", "PARS_PROCEDURE_TOKEN", "PARS_IN_TOKEN", - "PARS_INT_TOKEN", "PARS_CHAR_TOKEN", "PARS_IS_TOKEN", "PARS_BEGIN_TOKEN", - "PARS_END_TOKEN", "PARS_IF_TOKEN", "PARS_THEN_TOKEN", "PARS_ELSE_TOKEN", - "PARS_ELSIF_TOKEN", "PARS_LOOP_TOKEN", "PARS_WHILE_TOKEN", - "PARS_RETURN_TOKEN", "PARS_SELECT_TOKEN", "PARS_COUNT_TOKEN", - "PARS_FROM_TOKEN", "PARS_WHERE_TOKEN", "PARS_FOR_TOKEN", - "PARS_DDOT_TOKEN", "PARS_ORDER_TOKEN", "PARS_BY_TOKEN", "PARS_ASC_TOKEN", - "PARS_DESC_TOKEN", "PARS_INSERT_TOKEN", "PARS_INTO_TOKEN", - "PARS_VALUES_TOKEN", "PARS_UPDATE_TOKEN", "PARS_SET_TOKEN", - "PARS_DELETE_TOKEN", "PARS_CURRENT_TOKEN", "PARS_OF_TOKEN", - "PARS_CREATE_TOKEN", "PARS_TABLE_TOKEN", "PARS_INDEX_TOKEN", - "PARS_UNIQUE_TOKEN", "PARS_CLUSTERED_TOKEN", "PARS_ON_TOKEN", - "PARS_ASSIGN_TOKEN", "PARS_DECLARE_TOKEN", "PARS_CURSOR_TOKEN", - "PARS_SQL_TOKEN", "PARS_OPEN_TOKEN", "PARS_FETCH_TOKEN", - "PARS_CLOSE_TOKEN", "PARS_NOTFOUND_TOKEN", "PARS_TO_BINARY_TOKEN", - "PARS_SUBSTR_TOKEN", "PARS_CONCAT_TOKEN", "PARS_INSTR_TOKEN", - "PARS_LENGTH_TOKEN", "PARS_COMMIT_TOKEN", "PARS_ROLLBACK_TOKEN", - "PARS_WORK_TOKEN", "PARS_EXIT_TOKEN", "PARS_FUNCTION_TOKEN", - "PARS_LOCK_TOKEN", "PARS_SHARE_TOKEN", "PARS_MODE_TOKEN", - "PARS_LIKE_TOKEN", "PARS_LIKE_TOKEN_EXACT", "PARS_LIKE_TOKEN_PREFIX", - "PARS_LIKE_TOKEN_SUFFIX", "PARS_LIKE_TOKEN_SUBSTR", - "PARS_TABLE_NAME_TOKEN", "PARS_BIGINT_TOKEN", "'='", "'<'", "'>'", "'-'", - "'+'", "'*'", "'/'", "NEG", "'%'", "';'", "'('", "')'", "'?'", "','", - "'{'", "'}'", "$accept", "top_statement", "statement", "statement_list", - "exp", "function_name", "question_mark_list", "stored_procedure_call", - "user_function_call", "table_list", "variable_list", "exp_list", - "select_item", "select_item_list", "select_list", "search_condition", + "\"end of file\"", "error", "\"invalid token\"", "PARS_INT_LIT", + "PARS_FLOAT_LIT", "PARS_STR_LIT", "PARS_NULL_LIT", "PARS_ID_TOKEN", + "PARS_AND_TOKEN", "PARS_OR_TOKEN", "PARS_NOT_TOKEN", "PARS_GE_TOKEN", + "PARS_LE_TOKEN", "PARS_NE_TOKEN", "PARS_PROCEDURE_TOKEN", + "PARS_IN_TOKEN", "PARS_INT_TOKEN", "PARS_CHAR_TOKEN", "PARS_IS_TOKEN", + "PARS_BEGIN_TOKEN", "PARS_END_TOKEN", "PARS_IF_TOKEN", "PARS_THEN_TOKEN", + "PARS_ELSE_TOKEN", "PARS_ELSIF_TOKEN", "PARS_LOOP_TOKEN", + "PARS_WHILE_TOKEN", "PARS_RETURN_TOKEN", "PARS_SELECT_TOKEN", + "PARS_COUNT_TOKEN", "PARS_FROM_TOKEN", "PARS_WHERE_TOKEN", + "PARS_FOR_TOKEN", "PARS_DDOT_TOKEN", "PARS_ORDER_TOKEN", "PARS_BY_TOKEN", + "PARS_ASC_TOKEN", "PARS_DESC_TOKEN", "PARS_INSERT_TOKEN", + "PARS_INTO_TOKEN", "PARS_VALUES_TOKEN", "PARS_UPDATE_TOKEN", + "PARS_SET_TOKEN", "PARS_DELETE_TOKEN", "PARS_CURRENT_TOKEN", + "PARS_OF_TOKEN", "PARS_CREATE_TOKEN", "PARS_TABLE_TOKEN", + "PARS_INDEX_TOKEN", "PARS_UNIQUE_TOKEN", "PARS_CLUSTERED_TOKEN", + "PARS_ON_TOKEN", "PARS_ASSIGN_TOKEN", "PARS_DECLARE_TOKEN", + "PARS_CURSOR_TOKEN", "PARS_SQL_TOKEN", "PARS_OPEN_TOKEN", + "PARS_FETCH_TOKEN", "PARS_CLOSE_TOKEN", "PARS_NOTFOUND_TOKEN", + "PARS_TO_BINARY_TOKEN", "PARS_SUBSTR_TOKEN", "PARS_CONCAT_TOKEN", + "PARS_INSTR_TOKEN", "PARS_LENGTH_TOKEN", "PARS_COMMIT_TOKEN", + "PARS_ROLLBACK_TOKEN", "PARS_WORK_TOKEN", "PARS_EXIT_TOKEN", + "PARS_FUNCTION_TOKEN", "PARS_LOCK_TOKEN", "PARS_SHARE_TOKEN", + "PARS_MODE_TOKEN", "PARS_LIKE_TOKEN", "PARS_LIKE_TOKEN_EXACT", + "PARS_LIKE_TOKEN_PREFIX", "PARS_LIKE_TOKEN_SUFFIX", + "PARS_LIKE_TOKEN_SUBSTR", "PARS_TABLE_NAME_TOKEN", "PARS_BIGINT_TOKEN", + "'='", "'<'", "'>'", "'-'", "'+'", "'*'", "'/'", "NEG", "'%'", "';'", + "'('", "')'", "','", "$accept", "top_statement", "statement", + "statement_list", "exp", "function_name", "user_function_call", + "table_list", "variable_list", "exp_list", "select_item", + "select_item_list", "select_list", "search_condition", "for_update_clause", "lock_shared_clause", "order_direction", "order_by_clause", "select_statement", "insert_statement_start", "insert_statement", "column_assignment", "column_assignment_list", @@ -588,12 +733,18 @@ static const char *const yytname[] = "cursor_declaration", "function_declaration", "declaration", "declaration_list", "procedure_definition", YY_NULLPTR }; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + return yytname[yysymbol]; +} #endif -# ifdef YYPRINT +#ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ -static const yytype_uint16 yytoknum[] = +static const yytype_int16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, @@ -604,54 +755,53 @@ static const yytype_uint16 yytoknum[] = 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 61, 60, 62, 45, 43, 42, 47, 335, 37, 59, - 40, 41, 63, 44, 123, 125 + 40, 41, 44 }; -# endif +#endif -#define YYPACT_NINF -129 +#define YYPACT_NINF (-146) -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-129))) +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF -1 +#define YYTABLE_NINF (-1) -#define yytable_value_is_error(Yytable_value) \ +#define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { - 5, 34, 46, -28, -41, -129, -129, -12, 45, 57, - 23, -129, 9, -129, -129, -129, 20, -9, -129, -129, - -129, -129, 2, -129, 83, 87, 278, -129, 93, 28, - 71, 427, 427, -129, 335, 105, 85, -1, 104, -27, - 129, 132, 133, 76, 77, -129, 141, -129, 149, -129, - 61, 19, 62, 118, 65, 66, 118, 68, 69, 70, - 72, 73, 74, 75, 78, 79, 82, 84, 89, 90, - 91, 94, 138, -129, 427, -129, -129, -129, -129, 86, - 427, 96, -129, -129, -129, -129, -129, 427, 427, 438, - 92, 454, 95, -129, 1, -129, -24, 130, 157, -1, - -129, -129, 144, -1, -1, -129, 139, -129, 154, -129, - -129, -129, 98, -129, -129, -129, 108, -129, -129, 345, - -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, - -129, -129, -129, -129, -129, -129, -129, -129, -129, -129, - -129, 112, 1, 135, 285, 143, -8, 15, 427, 427, - 427, 427, 427, 278, 203, 427, 427, 427, 427, 427, - 427, 427, 427, 278, 124, 204, 381, -1, 427, -129, - 209, -129, 120, -129, 173, 215, 131, 427, 180, 1, - -129, -129, -129, -129, 285, 285, 30, 30, 1, 10, - -129, 30, 30, 30, 60, 60, -8, -8, 1, -39, - 192, 137, -129, 136, -129, -13, -129, 472, 146, -129, - 147, 225, 227, 151, -129, 136, -129, -21, 0, 229, - 278, 427, -129, 213, 219, -129, 427, 220, -129, 237, - 427, -1, 214, 427, 427, 209, 23, -129, 14, 196, - 160, 158, 162, -129, -129, 278, 486, -129, 231, 1, - -129, -129, -129, 218, 194, 517, 1, -129, 175, -129, - 225, -1, -129, -129, -129, 278, -129, -129, 251, 234, - 278, 266, 260, -129, 181, 278, 201, 239, -129, 235, - 184, 271, -129, 272, 208, 275, 258, -129, -129, -129, - 17, -129, -7, -129, -129, 277, -129, -129, -129, -129 + 8, 25, 40, -44, -43, -146, -146, -41, 37, 54, + 9, -146, 44, -146, -146, -146, -24, -30, -146, -146, + -146, -146, -5, -146, 63, 97, 543, -146, 93, 24, + 79, 148, 148, -146, 13, 126, 98, 0, 111, -3, + 135, 136, 138, 80, 83, -146, -146, 414, 67, -7, + 70, 130, 84, 85, 130, 86, 87, 88, 89, 90, + 91, 92, 94, 95, 99, 100, 104, 105, 107, 108, + 141, -146, 148, -146, -146, -146, -146, 112, 148, 119, + -146, -146, -146, -146, -146, 148, 148, 193, 123, 208, + 124, -146, 304, -146, -26, 152, 172, 0, -146, -146, + 181, 0, 0, -146, 174, -146, 186, -146, -146, -146, + -146, -146, -146, 137, -146, -146, 102, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, 139, 304, + 167, -1, 170, 17, 159, 148, 148, 148, 148, 148, + 543, 225, 148, 148, 148, 148, 148, 148, 148, 148, + 543, 149, 228, 31, 0, 148, -146, 229, -146, 147, + -146, 198, 240, 148, 203, 304, -146, -146, -146, -146, + -1, -1, 16, 16, 304, 371, -146, 16, 16, 16, + 49, 49, 17, 17, 304, -64, 457, 158, -146, 160, + -146, -25, -146, 247, 171, -146, 161, 250, 254, 164, + -146, 160, -38, 255, 543, 148, -146, 239, 244, -146, + 148, 242, -146, 258, 148, 0, 236, 148, 148, 229, + 9, -146, -33, 218, 179, -146, -146, 543, 274, -146, + 251, 304, -146, -146, -146, 230, 214, 289, 304, -146, + 205, -146, 250, 0, -146, 543, -146, -146, 284, 269, + 543, 301, 295, -146, 216, 543, 237, 272, -146, 500, + 219, 303, -146, 311, 249, 312, 286, -146, -146, -146, + -28, -146, 103, -146, -146, 315, -146, -146, -146, -146 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -659,278 +809,276 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 0, 0, 1, 2, 0, 0, 140, - 0, 141, 147, 136, 138, 137, 0, 0, 142, 145, - 146, 148, 0, 139, 0, 0, 0, 149, 0, 0, - 0, 0, 0, 112, 70, 0, 0, 0, 0, 127, - 0, 0, 0, 0, 0, 111, 0, 23, 0, 3, - 0, 0, 0, 76, 0, 0, 76, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 0, 0, 135, + 0, 136, 142, 131, 133, 132, 0, 0, 137, 140, + 141, 143, 0, 134, 0, 0, 0, 144, 0, 0, + 0, 0, 0, 107, 65, 0, 0, 0, 0, 122, + 0, 0, 0, 0, 0, 106, 22, 0, 0, 0, + 0, 71, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 144, 0, 27, 28, 29, 30, 25, - 0, 31, 50, 51, 52, 53, 54, 0, 0, 0, - 0, 0, 0, 73, 68, 71, 75, 0, 0, 0, - 132, 133, 0, 0, 0, 128, 129, 113, 0, 114, - 134, 135, 0, 150, 24, 10, 0, 90, 11, 0, - 96, 97, 14, 15, 99, 100, 12, 13, 9, 7, - 4, 5, 6, 8, 16, 18, 17, 21, 22, 19, - 20, 0, 101, 0, 47, 0, 36, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 65, 0, 0, 62, 0, 0, 0, 88, - 0, 98, 0, 130, 0, 62, 55, 65, 0, 77, - 143, 48, 49, 37, 45, 46, 42, 43, 44, 105, - 39, 38, 40, 41, 33, 32, 34, 35, 66, 0, - 0, 0, 63, 74, 72, 76, 60, 0, 0, 92, - 95, 0, 0, 63, 116, 115, 56, 0, 0, 0, - 0, 0, 103, 107, 0, 26, 0, 0, 69, 0, - 0, 0, 78, 0, 0, 0, 0, 118, 0, 0, - 0, 0, 0, 89, 94, 106, 0, 104, 0, 67, - 109, 64, 61, 0, 80, 0, 91, 93, 120, 124, - 0, 0, 59, 58, 57, 0, 108, 79, 0, 85, - 0, 0, 122, 119, 0, 102, 0, 0, 87, 0, - 0, 0, 117, 0, 0, 0, 0, 121, 123, 125, - 0, 81, 82, 110, 131, 0, 83, 84, 86, 126 + 0, 139, 0, 26, 27, 28, 29, 24, 0, 30, + 49, 50, 51, 52, 53, 0, 0, 0, 0, 0, + 0, 68, 63, 66, 70, 0, 0, 0, 127, 128, + 0, 0, 0, 123, 124, 108, 0, 109, 129, 130, + 145, 23, 9, 0, 85, 10, 0, 91, 92, 13, + 14, 94, 95, 11, 12, 8, 6, 3, 4, 5, + 7, 15, 17, 16, 20, 21, 18, 19, 0, 96, + 0, 46, 0, 35, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 57, 0, 0, 0, 83, 0, 93, 0, + 125, 0, 57, 60, 0, 72, 138, 47, 48, 36, + 44, 45, 41, 42, 43, 100, 38, 37, 39, 40, + 32, 31, 33, 34, 61, 0, 0, 0, 58, 69, + 67, 71, 55, 0, 0, 87, 90, 0, 0, 58, + 111, 110, 0, 0, 0, 0, 98, 102, 0, 25, + 0, 0, 64, 0, 0, 0, 73, 0, 0, 0, + 0, 113, 0, 0, 0, 84, 89, 101, 0, 99, + 0, 62, 104, 59, 56, 0, 75, 0, 86, 88, + 115, 119, 0, 0, 54, 0, 103, 74, 0, 80, + 0, 0, 117, 114, 0, 97, 0, 0, 82, 0, + 0, 0, 112, 0, 0, 0, 0, 116, 118, 120, + 0, 76, 77, 105, 126, 0, 78, 79, 81, 121 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -129, -129, -48, -128, -30, -129, -129, -129, -129, -129, - 113, 110, 123, -129, -129, -52, -129, -129, -129, -129, - -40, -129, -129, 55, -129, 238, -129, -129, -129, -129, - -129, -129, -129, 88, -129, -129, -129, -129, -129, -129, - -129, -129, -129, -129, 35, -129, -129, -129, -129, -129, - -129, -129, -129, -96, -129, -129, 81, 290, -129, -129, - -129, 286, -129, -129 + -146, -146, -47, -145, -29, -146, -146, -146, 151, 153, + 162, -146, -146, -53, -146, -146, -146, -146, -18, -146, + -146, 106, -146, 270, -146, -146, -146, -146, -146, -146, + -146, 117, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, 96, -146, -146, -146, -146, -146, -146, -146, + -146, -93, -146, -146, 109, 324, -146, -146, -146, 316, + -146, -146 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 2, 47, 48, 94, 90, 217, 49, 214, 205, - 203, 199, 95, 96, 97, 120, 254, 269, 298, 278, - 50, 51, 52, 209, 210, 121, 53, 54, 55, 56, - 57, 58, 59, 222, 223, 224, 60, 61, 62, 63, - 64, 65, 66, 67, 237, 238, 272, 282, 68, 290, - 106, 174, 69, 102, 70, 71, 16, 11, 12, 19, - 20, 21, 22, 3 + 0, 2, 46, 47, 92, 88, 210, 201, 199, 195, + 93, 94, 95, 117, 246, 259, 288, 268, 48, 49, + 50, 205, 206, 118, 51, 52, 53, 54, 55, 56, + 57, 216, 217, 218, 58, 59, 60, 61, 62, 63, + 64, 65, 231, 232, 262, 272, 66, 280, 104, 171, + 67, 100, 68, 69, 16, 11, 12, 19, 20, 21, + 22, 3 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_uint16 yytable[] = +static const yytype_int16 yytable[] = { - 114, 89, 91, 169, 124, 152, 100, 171, 172, 148, - 149, 117, 150, 151, 152, 165, 10, 30, 230, 1, - 104, 26, 105, 148, 149, 189, 150, 151, 152, 296, - 297, 31, 141, 220, 221, 200, 32, 33, 34, 13, - 14, 4, 35, 152, 142, 24, 5, 34, 36, 7, - 144, 37, 225, 38, 226, 17, 39, 146, 147, 116, - 25, 6, 17, 9, 10, 154, 40, 41, 42, 166, - 241, 206, 242, 152, 154, 43, 44, 101, 45, 8, - 231, 155, 156, 157, 158, 159, 160, 161, 154, 179, - 28, 243, 245, 226, 29, 155, 156, 157, 158, 159, - 160, 161, 15, 154, 46, 259, 183, 260, 294, 23, - 295, 72, 98, 158, 159, 160, 161, 73, 184, 185, - 186, 187, 188, 74, 99, 191, 192, 193, 194, 195, - 196, 197, 198, 154, 103, 252, 107, 275, 207, 108, - 109, 114, 279, 110, 111, 160, 161, 198, 112, 119, - 115, 118, 114, 232, 122, 123, 30, 126, 127, 128, - 167, 129, 130, 131, 132, 274, 34, 133, 134, 113, - 31, 135, 168, 136, 143, 32, 33, 34, 137, 138, - 139, 35, 162, 140, 145, 164, 170, 36, 176, 173, - 37, 246, 38, 175, 181, 39, 249, 114, 177, 30, - 179, 180, 182, 255, 256, 40, 41, 42, 190, 201, - 211, 202, 227, 31, 43, 44, 208, 45, 32, 33, - 34, 212, 213, 216, 35, 219, 234, 114, 228, 229, - 36, 114, 236, 37, 239, 38, 244, 221, 39, 248, - 235, 240, 30, 46, 251, 250, 253, 261, 40, 41, - 42, 262, 266, 263, 264, 286, 31, 43, 44, 267, - 45, 32, 33, 34, 268, 271, 276, 35, 277, 280, - 281, 283, 284, 36, 285, 287, 37, 288, 38, 289, - 291, 39, 292, 293, 299, 30, 46, 218, 215, 204, - 257, 40, 41, 42, 125, 273, 150, 151, 152, 31, - 43, 44, 18, 45, 32, 33, 34, 0, 27, 0, - 35, 247, 0, 0, 0, 0, 36, 258, 0, 37, - 0, 38, 0, 0, 39, 0, 0, 0, 0, 46, - 0, 0, 0, 0, 40, 41, 42, 0, 75, 76, - 77, 78, 79, 43, 44, 80, 45, 0, 75, 76, - 77, 78, 79, 0, 0, 80, 0, 0, 154, 0, - 0, 0, 0, 0, 92, 155, 156, 157, 158, 159, - 160, 161, 46, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 75, 76, 77, 78, 79, 178, - 81, 80, 0, 0, 0, 82, 83, 84, 85, 86, - 81, 0, 0, 0, 0, 82, 83, 84, 85, 86, - 92, 0, 0, 0, 0, 0, 0, 0, 87, 0, - 93, 0, 0, 0, 0, 88, 0, 0, 87, 0, - 75, 76, 77, 78, 79, 88, 81, 80, 0, 0, - 0, 82, 83, 84, 85, 86, 148, 149, 0, 150, - 151, 152, 0, 0, 0, 0, 0, 0, 0, 0, - 153, 0, 148, 149, 87, 150, 151, 152, 0, 0, - 0, 88, 0, 0, 0, 0, 0, 0, 0, 163, - 148, 149, 81, 150, 151, 152, 0, 82, 83, 84, - 85, 86, 0, 0, 148, 149, 0, 150, 151, 152, - 0, 0, 0, 0, 0, 233, 0, 0, 265, 0, - 87, 154, 0, 0, 0, 0, 0, 88, 155, 156, - 157, 158, 159, 160, 161, 148, 149, 154, 150, 151, - 152, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 0, 270, 0, 0, 154, 0, 0, 0, 0, - 0, 0, 155, 156, 157, 158, 159, 160, 161, 154, - 0, 0, 0, 0, 0, 0, 155, 156, 157, 158, - 159, 160, 161, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 154, 0, 0, 0, 0, 0, 0, 155, 156, 157, - 158, 159, 160, 161 + 111, 121, 87, 89, 166, 185, 224, 98, 168, 169, + 147, 148, 149, 162, 26, 196, 73, 74, 75, 76, + 77, 34, 1, 78, 24, 13, 14, 219, 220, 149, + 149, 114, 4, 113, 73, 74, 75, 76, 77, 25, + 5, 78, 90, 139, 102, 6, 103, 7, 17, 141, + 8, 10, 138, 235, 220, 9, 143, 144, 251, 252, + 90, 10, 149, 284, 285, 23, 163, 225, 79, 237, + 28, 202, 151, 80, 81, 82, 83, 84, 99, 152, + 153, 154, 155, 156, 157, 158, 79, 175, 15, 151, + 151, 80, 81, 82, 83, 84, 85, 17, 91, 155, + 156, 157, 158, 86, 29, 73, 74, 75, 76, 77, + 265, 70, 78, 71, 85, 269, 180, 181, 182, 183, + 184, 86, 151, 187, 188, 189, 190, 191, 192, 193, + 194, 72, 244, 96, 157, 158, 203, 97, 111, 286, + 287, 101, 105, 106, 194, 107, 174, 108, 226, 111, + 109, 73, 74, 75, 76, 77, 112, 79, 78, 115, + 264, 116, 80, 81, 82, 83, 84, 145, 146, 34, + 147, 148, 149, 119, 120, 123, 124, 125, 126, 127, + 128, 129, 164, 130, 131, 85, 238, 165, 132, 133, + 111, 241, 86, 134, 135, 175, 136, 137, 247, 248, + 140, 145, 146, 79, 147, 148, 149, 142, 80, 81, + 82, 83, 84, 159, 161, 150, 145, 146, 111, 147, + 148, 149, 111, 167, 170, 172, 177, 173, 176, 178, + 186, 85, 151, 160, 197, 198, 204, 207, 86, 152, + 153, 154, 155, 156, 157, 158, 208, 209, 213, 222, + 179, 228, 223, 229, 234, 145, 146, 230, 147, 148, + 149, 233, 236, 215, 240, 243, 151, 242, 245, 253, + 254, 257, 256, 152, 153, 154, 155, 156, 157, 158, + 227, 151, 145, 146, 258, 147, 148, 149, 152, 153, + 154, 155, 156, 157, 158, 261, 255, 145, 146, 266, + 147, 148, 149, 267, 270, 271, 273, 275, 274, 278, + 277, 283, 145, 146, 260, 147, 148, 149, 279, 282, + 151, 281, 289, 211, 122, 200, 212, 152, 153, 154, + 155, 156, 157, 158, 239, 249, 18, 0, 27, 250, + 0, 0, 0, 0, 0, 0, 0, 151, 263, 0, + 0, 0, 0, 0, 152, 153, 154, 155, 156, 157, + 158, 0, 151, 0, 0, 0, 0, 0, 0, 152, + 153, 154, 155, 156, 157, 158, 0, 151, 30, 0, + 0, 0, 0, 0, 152, 153, 154, 155, 156, 157, + 158, 0, 31, 0, 214, 215, 0, 32, 33, 34, + 0, 0, 0, 35, 0, 0, 0, 0, 0, 36, + 0, 0, 37, 0, 38, 0, 0, 39, 0, 0, + 0, 30, 0, 0, 0, 0, 0, 40, 41, 42, + 0, 0, 0, 0, 110, 31, 43, 44, 0, 45, + 32, 33, 34, 0, 0, 0, 35, 0, 0, 0, + 0, 0, 36, 0, 0, 37, 0, 38, 0, 0, + 39, 0, 0, 0, 30, 0, 0, 0, 0, 0, + 40, 41, 42, 0, 0, 0, 0, 221, 31, 43, + 44, 0, 45, 32, 33, 34, 0, 0, 0, 35, + 0, 0, 0, 0, 0, 36, 0, 0, 37, 0, + 38, 0, 0, 39, 0, 0, 0, 30, 0, 0, + 0, 0, 0, 40, 41, 42, 0, 0, 0, 0, + 276, 31, 43, 44, 0, 45, 32, 33, 34, 0, + 0, 0, 35, 0, 0, 0, 0, 0, 36, 0, + 0, 37, 0, 38, 0, 0, 39, 0, 0, 0, + 30, 0, 0, 0, 0, 0, 40, 41, 42, 0, + 0, 0, 0, 0, 31, 43, 44, 0, 45, 32, + 33, 34, 0, 0, 0, 35, 0, 0, 0, 0, + 0, 36, 0, 0, 37, 0, 38, 0, 0, 39, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, + 41, 42, 0, 0, 0, 0, 0, 0, 43, 44, + 0, 45 }; static const yytype_int16 yycheck[] = { - 48, 31, 32, 99, 56, 13, 7, 103, 104, 8, - 9, 51, 11, 12, 13, 39, 7, 7, 31, 14, - 47, 19, 49, 8, 9, 153, 11, 12, 13, 36, - 37, 21, 72, 23, 24, 163, 26, 27, 28, 16, - 17, 7, 32, 13, 74, 54, 0, 28, 38, 90, - 80, 41, 91, 43, 93, 53, 46, 87, 88, 40, - 69, 89, 53, 18, 7, 73, 56, 57, 58, 93, - 91, 167, 93, 13, 73, 65, 66, 78, 68, 91, - 93, 80, 81, 82, 83, 84, 85, 86, 73, 119, - 7, 91, 220, 93, 7, 80, 81, 82, 83, 84, - 85, 86, 79, 73, 94, 91, 91, 93, 91, 89, - 93, 18, 7, 83, 84, 85, 86, 89, 148, 149, - 150, 151, 152, 52, 39, 155, 156, 157, 158, 159, - 160, 161, 162, 73, 30, 231, 7, 265, 168, 7, - 7, 189, 270, 67, 67, 85, 86, 177, 7, 31, - 89, 89, 200, 205, 89, 89, 7, 89, 89, 89, - 30, 89, 89, 89, 89, 261, 28, 89, 89, 20, - 21, 89, 15, 89, 88, 26, 27, 28, 89, 89, - 89, 32, 90, 89, 88, 90, 42, 38, 90, 50, - 41, 221, 43, 39, 59, 46, 226, 245, 90, 7, - 230, 89, 59, 233, 234, 56, 57, 58, 5, 85, - 90, 7, 20, 21, 65, 66, 7, 68, 26, 27, - 28, 48, 7, 92, 32, 45, 80, 275, 91, 93, - 38, 279, 7, 41, 7, 43, 7, 24, 46, 20, - 93, 90, 7, 94, 7, 25, 32, 51, 56, 57, - 58, 91, 21, 95, 92, 20, 21, 65, 66, 41, - 68, 26, 27, 28, 70, 90, 15, 32, 34, 3, - 10, 90, 71, 38, 35, 91, 41, 6, 43, 7, - 72, 46, 7, 25, 7, 7, 94, 177, 175, 166, - 235, 56, 57, 58, 56, 260, 11, 12, 13, 21, - 65, 66, 12, 68, 26, 27, 28, -1, 22, -1, - 32, 223, -1, -1, -1, -1, 38, 236, -1, 41, - -1, 43, -1, -1, 46, -1, -1, -1, -1, 94, - -1, -1, -1, -1, 56, 57, 58, -1, 3, 4, - 5, 6, 7, 65, 66, 10, 68, -1, 3, 4, - 5, 6, 7, -1, -1, 10, -1, -1, 73, -1, - -1, -1, -1, -1, 29, 80, 81, 82, 83, 84, - 85, 86, 94, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3, 4, 5, 6, 7, 44, - 55, 10, -1, -1, -1, 60, 61, 62, 63, 64, - 55, -1, -1, -1, -1, 60, 61, 62, 63, 64, - 29, -1, -1, -1, -1, -1, -1, -1, 83, -1, - 85, -1, -1, -1, -1, 90, -1, -1, 83, -1, - 3, 4, 5, 6, 7, 90, 55, 10, -1, -1, - -1, 60, 61, 62, 63, 64, 8, 9, -1, 11, - 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, - 22, -1, 8, 9, 83, 11, 12, 13, -1, -1, - -1, 90, -1, -1, -1, -1, -1, -1, -1, 25, - 8, 9, 55, 11, 12, 13, -1, 60, 61, 62, - 63, 64, -1, -1, 8, 9, -1, 11, 12, 13, - -1, -1, -1, -1, -1, 33, -1, -1, 22, -1, - 83, 73, -1, -1, -1, -1, -1, 90, 80, 81, - 82, 83, 84, 85, 86, 8, 9, 73, 11, 12, - 13, -1, -1, -1, 80, 81, 82, 83, 84, 85, - 86, -1, 25, -1, -1, 73, -1, -1, -1, -1, - -1, -1, 80, 81, 82, 83, 84, 85, 86, 73, - -1, -1, -1, -1, -1, -1, 80, 81, 82, 83, - 84, 85, 86, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 73, -1, -1, -1, -1, -1, -1, 80, 81, 82, - 83, 84, 85, 86 + 47, 54, 31, 32, 97, 150, 31, 7, 101, 102, + 11, 12, 13, 39, 19, 160, 3, 4, 5, 6, + 7, 28, 14, 10, 54, 16, 17, 91, 92, 13, + 13, 49, 7, 40, 3, 4, 5, 6, 7, 69, + 0, 10, 29, 72, 47, 89, 49, 90, 53, 78, + 91, 7, 70, 91, 92, 18, 85, 86, 91, 92, + 29, 7, 13, 91, 92, 89, 92, 92, 55, 214, + 7, 164, 73, 60, 61, 62, 63, 64, 78, 80, + 81, 82, 83, 84, 85, 86, 55, 116, 79, 73, + 73, 60, 61, 62, 63, 64, 83, 53, 85, 83, + 84, 85, 86, 90, 7, 3, 4, 5, 6, 7, + 255, 18, 10, 89, 83, 260, 145, 146, 147, 148, + 149, 90, 73, 152, 153, 154, 155, 156, 157, 158, + 159, 52, 225, 7, 85, 86, 165, 39, 185, 36, + 37, 30, 7, 7, 173, 7, 44, 67, 201, 196, + 67, 3, 4, 5, 6, 7, 89, 55, 10, 89, + 253, 31, 60, 61, 62, 63, 64, 8, 9, 28, + 11, 12, 13, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 30, 89, 89, 83, 215, 15, 89, 89, + 237, 220, 90, 89, 89, 224, 89, 89, 227, 228, + 88, 8, 9, 55, 11, 12, 13, 88, 60, 61, + 62, 63, 64, 90, 90, 22, 8, 9, 265, 11, + 12, 13, 269, 42, 50, 39, 59, 90, 89, 59, + 5, 83, 73, 25, 85, 7, 7, 90, 90, 80, + 81, 82, 83, 84, 85, 86, 48, 7, 45, 91, + 91, 80, 92, 92, 90, 8, 9, 7, 11, 12, + 13, 7, 7, 24, 20, 7, 73, 25, 32, 51, + 91, 41, 21, 80, 81, 82, 83, 84, 85, 86, + 33, 73, 8, 9, 70, 11, 12, 13, 80, 81, + 82, 83, 84, 85, 86, 90, 22, 8, 9, 15, + 11, 12, 13, 34, 3, 10, 90, 35, 71, 6, + 91, 25, 8, 9, 25, 11, 12, 13, 7, 7, + 73, 72, 7, 172, 54, 163, 173, 80, 81, 82, + 83, 84, 85, 86, 217, 229, 12, -1, 22, 230, + -1, -1, -1, -1, -1, -1, -1, 73, 252, -1, + -1, -1, -1, -1, 80, 81, 82, 83, 84, 85, + 86, -1, 73, -1, -1, -1, -1, -1, -1, 80, + 81, 82, 83, 84, 85, 86, -1, 73, 7, -1, + -1, -1, -1, -1, 80, 81, 82, 83, 84, 85, + 86, -1, 21, -1, 23, 24, -1, 26, 27, 28, + -1, -1, -1, 32, -1, -1, -1, -1, -1, 38, + -1, -1, 41, -1, 43, -1, -1, 46, -1, -1, + -1, 7, -1, -1, -1, -1, -1, 56, 57, 58, + -1, -1, -1, -1, 20, 21, 65, 66, -1, 68, + 26, 27, 28, -1, -1, -1, 32, -1, -1, -1, + -1, -1, 38, -1, -1, 41, -1, 43, -1, -1, + 46, -1, -1, -1, 7, -1, -1, -1, -1, -1, + 56, 57, 58, -1, -1, -1, -1, 20, 21, 65, + 66, -1, 68, 26, 27, 28, -1, -1, -1, 32, + -1, -1, -1, -1, -1, 38, -1, -1, 41, -1, + 43, -1, -1, 46, -1, -1, -1, 7, -1, -1, + -1, -1, -1, 56, 57, 58, -1, -1, -1, -1, + 20, 21, 65, 66, -1, 68, 26, 27, 28, -1, + -1, -1, 32, -1, -1, -1, -1, -1, 38, -1, + -1, 41, -1, 43, -1, -1, 46, -1, -1, -1, + 7, -1, -1, -1, -1, -1, 56, 57, 58, -1, + -1, -1, -1, -1, 21, 65, 66, -1, 68, 26, + 27, 28, -1, -1, -1, 32, -1, -1, -1, -1, + -1, 38, -1, -1, 41, -1, 43, -1, -1, 46, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, + 57, 58, -1, -1, -1, -1, -1, -1, 65, 66, + -1, 68 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 14, 97, 159, 7, 0, 89, 90, 91, 18, - 7, 153, 154, 16, 17, 79, 152, 53, 153, 155, - 156, 157, 158, 89, 54, 69, 19, 157, 7, 7, + 0, 14, 94, 154, 7, 0, 89, 90, 91, 18, + 7, 148, 149, 16, 17, 79, 147, 53, 148, 150, + 151, 152, 153, 89, 54, 69, 19, 152, 7, 7, 7, 21, 26, 27, 28, 32, 38, 41, 43, 46, - 56, 57, 58, 65, 66, 68, 94, 98, 99, 103, - 116, 117, 118, 122, 123, 124, 125, 126, 127, 128, - 132, 133, 134, 135, 136, 137, 138, 139, 144, 148, - 150, 151, 18, 89, 52, 3, 4, 5, 6, 7, - 10, 55, 60, 61, 62, 63, 64, 83, 90, 100, - 101, 100, 29, 85, 100, 108, 109, 110, 7, 39, - 7, 78, 149, 30, 47, 49, 146, 7, 7, 7, - 67, 67, 7, 20, 98, 89, 40, 116, 89, 31, - 111, 121, 89, 89, 111, 121, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 116, 100, 88, 100, 88, 100, 100, 8, 9, - 11, 12, 13, 22, 73, 80, 81, 82, 83, 84, - 85, 86, 90, 25, 90, 39, 93, 30, 15, 149, - 42, 149, 149, 50, 147, 39, 90, 90, 44, 100, - 89, 59, 59, 91, 100, 100, 100, 100, 100, 99, - 5, 100, 100, 100, 100, 100, 100, 100, 100, 107, - 99, 85, 7, 106, 108, 105, 149, 100, 7, 119, - 120, 90, 48, 7, 104, 106, 92, 102, 107, 45, - 23, 24, 129, 130, 131, 91, 93, 20, 91, 93, - 31, 93, 111, 33, 80, 93, 7, 140, 141, 7, - 90, 91, 93, 91, 7, 99, 100, 129, 20, 100, - 25, 7, 149, 32, 112, 100, 100, 119, 152, 91, - 93, 51, 91, 95, 92, 22, 21, 41, 70, 113, - 25, 90, 142, 140, 149, 99, 15, 34, 115, 99, - 3, 10, 143, 90, 71, 35, 20, 91, 6, 7, - 145, 72, 7, 25, 91, 93, 36, 37, 114, 7 + 56, 57, 58, 65, 66, 68, 95, 96, 111, 112, + 113, 117, 118, 119, 120, 121, 122, 123, 127, 128, + 129, 130, 131, 132, 133, 134, 139, 143, 145, 146, + 18, 89, 52, 3, 4, 5, 6, 7, 10, 55, + 60, 61, 62, 63, 64, 83, 90, 97, 98, 97, + 29, 85, 97, 103, 104, 105, 7, 39, 7, 78, + 144, 30, 47, 49, 141, 7, 7, 7, 67, 67, + 20, 95, 89, 40, 111, 89, 31, 106, 116, 89, + 89, 106, 116, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 111, 97, + 88, 97, 88, 97, 97, 8, 9, 11, 12, 13, + 22, 73, 80, 81, 82, 83, 84, 85, 86, 90, + 25, 90, 39, 92, 30, 15, 144, 42, 144, 144, + 50, 142, 39, 90, 44, 97, 89, 59, 59, 91, + 97, 97, 97, 97, 97, 96, 5, 97, 97, 97, + 97, 97, 97, 97, 97, 102, 96, 85, 7, 101, + 103, 100, 144, 97, 7, 114, 115, 90, 48, 7, + 99, 101, 102, 45, 23, 24, 124, 125, 126, 91, + 92, 20, 91, 92, 31, 92, 106, 33, 80, 92, + 7, 135, 136, 7, 90, 91, 7, 96, 97, 124, + 20, 97, 25, 7, 144, 32, 107, 97, 97, 114, + 147, 91, 92, 51, 91, 22, 21, 41, 70, 108, + 25, 90, 137, 135, 144, 96, 15, 34, 110, 96, + 3, 10, 138, 90, 71, 35, 20, 91, 6, 7, + 140, 72, 7, 25, 91, 92, 36, 37, 109, 7 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 96, 97, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 99, 99, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 101, 101, 101, 101, 101, 102, 102, 102, 103, 104, - 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, - 109, 109, 109, 110, 110, 110, 111, 111, 112, 112, - 113, 113, 114, 114, 114, 115, 115, 116, 117, 118, - 118, 119, 120, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 130, 131, 131, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 139, 140, 141, 141, - 142, 142, 143, 143, 144, 145, 145, 146, 146, 147, - 147, 148, 149, 149, 150, 151, 152, 152, 152, 153, - 154, 154, 154, 155, 156, 157, 157, 158, 158, 158, - 159 + 0, 93, 94, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 96, 96, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, + 98, 98, 98, 98, 99, 100, 100, 101, 101, 101, + 102, 102, 102, 103, 103, 104, 104, 104, 105, 105, + 105, 106, 106, 107, 107, 108, 108, 109, 109, 109, + 110, 110, 111, 112, 113, 113, 114, 115, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 125, + 126, 126, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 134, 135, 136, 136, 137, 137, 138, 138, 139, + 140, 140, 141, 141, 142, 142, 143, 144, 144, 145, + 146, 147, 147, 147, 148, 149, 149, 149, 150, 151, + 152, 152, 153, 153, 153, 154 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = +static const yytype_int8 yyr2[] = { - 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 1, 2, 1, 4, 1, 1, 1, - 1, 1, 3, 3, 3, 3, 2, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, - 1, 1, 1, 1, 1, 0, 1, 3, 6, 3, - 1, 3, 0, 1, 3, 0, 1, 3, 1, 4, - 0, 1, 3, 1, 3, 1, 0, 2, 0, 2, - 0, 4, 0, 1, 1, 0, 4, 8, 3, 5, - 2, 3, 1, 3, 4, 4, 2, 2, 3, 2, - 2, 3, 4, 1, 2, 0, 2, 1, 7, 6, - 10, 1, 1, 2, 2, 4, 4, 4, 1, 3, - 0, 3, 0, 2, 6, 1, 3, 0, 1, 0, - 1, 10, 1, 1, 2, 2, 1, 1, 1, 3, - 0, 1, 2, 6, 4, 1, 1, 0, 1, 2, - 10 + 2, 2, 1, 2, 1, 4, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 3, 3, 1, + 1, 1, 1, 1, 3, 1, 3, 0, 1, 3, + 0, 1, 3, 1, 4, 0, 1, 3, 1, 3, + 1, 0, 2, 0, 2, 0, 4, 0, 1, 1, + 0, 4, 8, 3, 5, 2, 3, 1, 3, 4, + 4, 2, 2, 3, 2, 2, 3, 4, 1, 2, + 0, 2, 1, 7, 6, 10, 1, 1, 2, 2, + 4, 4, 4, 1, 3, 0, 3, 0, 2, 6, + 1, 3, 0, 1, 0, 1, 10, 1, 1, 2, + 2, 1, 1, 1, 3, 0, 1, 2, 6, 4, + 1, 1, 0, 1, 2, 10 }; +enum { YYENOMEM = -2 }; + #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab @@ -956,10 +1104,9 @@ static const yytype_uint8 yyr2[] = } \ while (0) -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF /* Enable debugging if requested. */ @@ -977,18 +1124,18 @@ do { \ } while (0) /* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif +# ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ - Type, Value); \ + Kind, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) @@ -999,18 +1146,19 @@ do { \ `-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) { FILE *yyoutput = yyo; - YYUSE (yyoutput); + YY_USE (yyoutput); if (!yyvaluep) return; # ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyo, yytoknum[yytype], *yyvaluep); + if (yykind < YYNTOKENS) + YYPRINT (yyo, yytoknum[yykind], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1020,12 +1168,13 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) `---------------------------*/ static void -yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyo, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - yy_symbol_value_print (yyo, yytype, yyvaluep); + yy_symbol_value_print (yyo, yykind, yyvaluep); YYFPRINTF (yyo, ")"); } @@ -1035,7 +1184,7 @@ yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) `------------------------------------------------------------------*/ static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) @@ -1058,21 +1207,21 @@ do { \ `------------------------------------------------*/ static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule) { - unsigned long yylno = yyrline[yyrule]; + int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &yyvsp[(yyi + 1) - (yynrhs)] - ); + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)]); YYFPRINTF (stderr, "\n"); } } @@ -1087,8 +1236,8 @@ do { \ multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ @@ -1111,254 +1260,30 @@ int yydebug; #endif -#if YYERROR_VERBOSE -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -yystrlen (const char *yystr) -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - else - goto append; - - append: - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) - yysize = yysize1; - else - return 2; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - default: /* Avoid compiler warnings. */ - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) - yysize = yysize1; - else - return 2; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep) { - YYUSE (yyvaluep); + YY_USE (yyvaluep); if (!yymsg) yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } - - -/* The lookahead symbol. */ +/* Lookahead token kind. */ static int yychar; /* The semantic value of the lookahead symbol. */ @@ -1367,6 +1292,8 @@ YYSTYPE yylval; static int yynerrs; + + /*----------. | yyparse. | `----------*/ @@ -1374,43 +1301,36 @@ static int yynerrs; int yyparse (void) { - int yystate; + yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; + int yyerrstatus = 0; - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow + /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; - /* The semantic value stack. */ + /* The state stack: array, bottom, top. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; + + /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; int yyn; + /* The return value of yyparse. */ int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif + #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) @@ -1418,15 +1338,8 @@ yyparse (void) Keep to zero when no symbol should be popped. */ int yylen = 0; - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - YYDPRINTF ((stderr, "Starting parse\n")); - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; @@ -1441,12 +1354,15 @@ yynewstate: /*--------------------------------------------------------------------. -| yynewstate -- set current state (the top of the stack) to yystate. | +| yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); - *yyssp = (yytype_int16) yystate; + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE @@ -1454,23 +1370,23 @@ yysetstate: #else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); + YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ + yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; @@ -1484,14 +1400,15 @@ yysetstate: yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; + yy_state_t *yyss1 = yyss; union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE +# undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } @@ -1500,8 +1417,10 @@ yysetstate: yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long) yystacksize)); + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; @@ -1528,18 +1447,29 @@ yybackup: /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); + YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (); } if (yychar <= YYEOF) { - yychar = yytoken = YYEOF; + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } else { yytoken = YYTRANSLATE (yychar); @@ -1567,14 +1497,13 @@ yybackup: /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END + + /* Discard the shifted token. */ + yychar = YYEMPTY; goto yynewstate; @@ -1609,778 +1538,771 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 23: -#line 166 "pars0grm.y" - { yyval = que_node_list_add_last(NULL, yyvsp[0]); } -#line 1616 "pars0grm.cc" + case 22: /* statement_list: statement */ +#line 165 "pars0grm.y" + { yyval = que_node_list_add_last(NULL, yyvsp[0]); } +#line 1545 "pars0grm.cc" break; - case 24: -#line 168 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-1], yyvsp[0]); } -#line 1622 "pars0grm.cc" + case 23: /* statement_list: statement_list statement */ +#line 167 "pars0grm.y" + { yyval = que_node_list_add_last(yyvsp[-1], yyvsp[0]); } +#line 1551 "pars0grm.cc" break; - case 25: -#line 172 "pars0grm.y" - { yyval = yyvsp[0];} -#line 1628 "pars0grm.cc" + case 24: /* exp: PARS_ID_TOKEN */ +#line 171 "pars0grm.y" + { yyval = yyvsp[0];} +#line 1557 "pars0grm.cc" break; - case 26: + case 25: /* exp: function_name '(' exp_list ')' */ +#line 173 "pars0grm.y" + { yyval = pars_func(yyvsp[-3], yyvsp[-1]); } +#line 1563 "pars0grm.cc" + break; + + case 26: /* exp: PARS_INT_LIT */ #line 174 "pars0grm.y" - { yyval = pars_func(yyvsp[-3], yyvsp[-1]); } -#line 1634 "pars0grm.cc" + { yyval = yyvsp[0];} +#line 1569 "pars0grm.cc" break; - case 27: + case 27: /* exp: PARS_FLOAT_LIT */ #line 175 "pars0grm.y" - { yyval = yyvsp[0];} -#line 1640 "pars0grm.cc" + { yyval = yyvsp[0];} +#line 1575 "pars0grm.cc" break; - case 28: + case 28: /* exp: PARS_STR_LIT */ #line 176 "pars0grm.y" - { yyval = yyvsp[0];} -#line 1646 "pars0grm.cc" + { yyval = yyvsp[0];} +#line 1581 "pars0grm.cc" break; - case 29: + case 29: /* exp: PARS_NULL_LIT */ #line 177 "pars0grm.y" - { yyval = yyvsp[0];} -#line 1652 "pars0grm.cc" + { yyval = yyvsp[0];} +#line 1587 "pars0grm.cc" break; - case 30: + case 30: /* exp: PARS_SQL_TOKEN */ #line 178 "pars0grm.y" - { yyval = yyvsp[0];} -#line 1658 "pars0grm.cc" + { yyval = yyvsp[0];} +#line 1593 "pars0grm.cc" break; - case 31: + case 31: /* exp: exp '+' exp */ #line 179 "pars0grm.y" - { yyval = yyvsp[0];} -#line 1664 "pars0grm.cc" + { yyval = pars_op('+', yyvsp[-2], yyvsp[0]); } +#line 1599 "pars0grm.cc" break; - case 32: + case 32: /* exp: exp '-' exp */ #line 180 "pars0grm.y" - { yyval = pars_op('+', yyvsp[-2], yyvsp[0]); } -#line 1670 "pars0grm.cc" + { yyval = pars_op('-', yyvsp[-2], yyvsp[0]); } +#line 1605 "pars0grm.cc" break; - case 33: + case 33: /* exp: exp '*' exp */ #line 181 "pars0grm.y" - { yyval = pars_op('-', yyvsp[-2], yyvsp[0]); } -#line 1676 "pars0grm.cc" + { yyval = pars_op('*', yyvsp[-2], yyvsp[0]); } +#line 1611 "pars0grm.cc" break; - case 34: + case 34: /* exp: exp '/' exp */ #line 182 "pars0grm.y" - { yyval = pars_op('*', yyvsp[-2], yyvsp[0]); } -#line 1682 "pars0grm.cc" + { yyval = pars_op('/', yyvsp[-2], yyvsp[0]); } +#line 1617 "pars0grm.cc" break; - case 35: + case 35: /* exp: '-' exp */ #line 183 "pars0grm.y" - { yyval = pars_op('/', yyvsp[-2], yyvsp[0]); } -#line 1688 "pars0grm.cc" + { yyval = pars_op('-', yyvsp[0], NULL); } +#line 1623 "pars0grm.cc" break; - case 36: + case 36: /* exp: '(' exp ')' */ #line 184 "pars0grm.y" - { yyval = pars_op('-', yyvsp[0], NULL); } -#line 1694 "pars0grm.cc" + { yyval = yyvsp[-1]; } +#line 1629 "pars0grm.cc" break; - case 37: + case 37: /* exp: exp '=' exp */ #line 185 "pars0grm.y" - { yyval = yyvsp[-1]; } -#line 1700 "pars0grm.cc" + { yyval = pars_op('=', yyvsp[-2], yyvsp[0]); } +#line 1635 "pars0grm.cc" break; - case 38: -#line 186 "pars0grm.y" - { yyval = pars_op('=', yyvsp[-2], yyvsp[0]); } -#line 1706 "pars0grm.cc" + case 38: /* exp: exp PARS_LIKE_TOKEN PARS_STR_LIT */ +#line 187 "pars0grm.y" + { yyval = pars_op(PARS_LIKE_TOKEN, yyvsp[-2], yyvsp[0]); } +#line 1641 "pars0grm.cc" break; - case 39: + case 39: /* exp: exp '<' exp */ #line 188 "pars0grm.y" - { yyval = pars_op(PARS_LIKE_TOKEN, yyvsp[-2], yyvsp[0]); } -#line 1712 "pars0grm.cc" + { yyval = pars_op('<', yyvsp[-2], yyvsp[0]); } +#line 1647 "pars0grm.cc" break; - case 40: + case 40: /* exp: exp '>' exp */ #line 189 "pars0grm.y" - { yyval = pars_op('<', yyvsp[-2], yyvsp[0]); } -#line 1718 "pars0grm.cc" + { yyval = pars_op('>', yyvsp[-2], yyvsp[0]); } +#line 1653 "pars0grm.cc" break; - case 41: + case 41: /* exp: exp PARS_GE_TOKEN exp */ #line 190 "pars0grm.y" - { yyval = pars_op('>', yyvsp[-2], yyvsp[0]); } -#line 1724 "pars0grm.cc" + { yyval = pars_op(PARS_GE_TOKEN, yyvsp[-2], yyvsp[0]); } +#line 1659 "pars0grm.cc" break; - case 42: + case 42: /* exp: exp PARS_LE_TOKEN exp */ #line 191 "pars0grm.y" - { yyval = pars_op(PARS_GE_TOKEN, yyvsp[-2], yyvsp[0]); } -#line 1730 "pars0grm.cc" + { yyval = pars_op(PARS_LE_TOKEN, yyvsp[-2], yyvsp[0]); } +#line 1665 "pars0grm.cc" break; - case 43: + case 43: /* exp: exp PARS_NE_TOKEN exp */ #line 192 "pars0grm.y" - { yyval = pars_op(PARS_LE_TOKEN, yyvsp[-2], yyvsp[0]); } -#line 1736 "pars0grm.cc" + { yyval = pars_op(PARS_NE_TOKEN, yyvsp[-2], yyvsp[0]); } +#line 1671 "pars0grm.cc" break; - case 44: + case 44: /* exp: exp PARS_AND_TOKEN exp */ #line 193 "pars0grm.y" - { yyval = pars_op(PARS_NE_TOKEN, yyvsp[-2], yyvsp[0]); } -#line 1742 "pars0grm.cc" + { yyval = pars_op(PARS_AND_TOKEN, yyvsp[-2], yyvsp[0]); } +#line 1677 "pars0grm.cc" break; - case 45: + case 45: /* exp: exp PARS_OR_TOKEN exp */ #line 194 "pars0grm.y" - { yyval = pars_op(PARS_AND_TOKEN, yyvsp[-2], yyvsp[0]); } -#line 1748 "pars0grm.cc" + { yyval = pars_op(PARS_OR_TOKEN, yyvsp[-2], yyvsp[0]); } +#line 1683 "pars0grm.cc" break; - case 46: + case 46: /* exp: PARS_NOT_TOKEN exp */ #line 195 "pars0grm.y" - { yyval = pars_op(PARS_OR_TOKEN, yyvsp[-2], yyvsp[0]); } -#line 1754 "pars0grm.cc" + { yyval = pars_op(PARS_NOT_TOKEN, yyvsp[0], NULL); } +#line 1689 "pars0grm.cc" break; - case 47: -#line 196 "pars0grm.y" - { yyval = pars_op(PARS_NOT_TOKEN, yyvsp[0], NULL); } -#line 1760 "pars0grm.cc" + case 47: /* exp: PARS_ID_TOKEN '%' PARS_NOTFOUND_TOKEN */ +#line 197 "pars0grm.y" + { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); } +#line 1695 "pars0grm.cc" break; - case 48: -#line 198 "pars0grm.y" - { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); } -#line 1766 "pars0grm.cc" + case 48: /* exp: PARS_SQL_TOKEN '%' PARS_NOTFOUND_TOKEN */ +#line 199 "pars0grm.y" + { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); } +#line 1701 "pars0grm.cc" break; - case 49: -#line 200 "pars0grm.y" - { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); } -#line 1772 "pars0grm.cc" + case 49: /* function_name: PARS_TO_BINARY_TOKEN */ +#line 203 "pars0grm.y" + { yyval = &pars_to_binary_token; } +#line 1707 "pars0grm.cc" break; - case 50: + case 50: /* function_name: PARS_SUBSTR_TOKEN */ #line 204 "pars0grm.y" - { yyval = &pars_to_binary_token; } -#line 1778 "pars0grm.cc" + { yyval = &pars_substr_token; } +#line 1713 "pars0grm.cc" break; - case 51: + case 51: /* function_name: PARS_CONCAT_TOKEN */ #line 205 "pars0grm.y" - { yyval = &pars_substr_token; } -#line 1784 "pars0grm.cc" + { yyval = &pars_concat_token; } +#line 1719 "pars0grm.cc" break; - case 52: + case 52: /* function_name: PARS_INSTR_TOKEN */ #line 206 "pars0grm.y" - { yyval = &pars_concat_token; } -#line 1790 "pars0grm.cc" + { yyval = &pars_instr_token; } +#line 1725 "pars0grm.cc" break; - case 53: + case 53: /* function_name: PARS_LENGTH_TOKEN */ #line 207 "pars0grm.y" - { yyval = &pars_instr_token; } -#line 1796 "pars0grm.cc" + { yyval = &pars_length_token; } +#line 1731 "pars0grm.cc" break; - case 54: -#line 208 "pars0grm.y" - { yyval = &pars_length_token; } -#line 1802 "pars0grm.cc" + case 54: /* user_function_call: PARS_ID_TOKEN '(' ')' */ +#line 211 "pars0grm.y" + { yyval = yyvsp[-2]; } +#line 1737 "pars0grm.cc" break; - case 58: -#line 219 "pars0grm.y" - { yyval = pars_stored_procedure_call( - static_cast(yyvsp[-4])); } -#line 1809 "pars0grm.cc" + case 55: /* table_list: table_name */ +#line 215 "pars0grm.y" + { yyval = que_node_list_add_last(NULL, yyvsp[0]); } +#line 1743 "pars0grm.cc" break; - case 59: + case 56: /* table_list: table_list ',' table_name */ +#line 217 "pars0grm.y" + { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } +#line 1749 "pars0grm.cc" + break; + + case 57: /* variable_list: %empty */ +#line 221 "pars0grm.y" + { yyval = NULL; } +#line 1755 "pars0grm.cc" + break; + + case 58: /* variable_list: PARS_ID_TOKEN */ +#line 222 "pars0grm.y" + { yyval = que_node_list_add_last(NULL, yyvsp[0]); } +#line 1761 "pars0grm.cc" + break; + + case 59: /* variable_list: variable_list ',' PARS_ID_TOKEN */ #line 224 "pars0grm.y" - { yyval = yyvsp[-2]; } -#line 1815 "pars0grm.cc" + { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } +#line 1767 "pars0grm.cc" break; - case 60: + case 60: /* exp_list: %empty */ #line 228 "pars0grm.y" - { yyval = que_node_list_add_last(NULL, yyvsp[0]); } -#line 1821 "pars0grm.cc" + { yyval = NULL; } +#line 1773 "pars0grm.cc" break; - case 61: + case 61: /* exp_list: exp */ +#line 229 "pars0grm.y" + { yyval = que_node_list_add_last(NULL, yyvsp[0]);} +#line 1779 "pars0grm.cc" + break; + + case 62: /* exp_list: exp_list ',' exp */ #line 230 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } -#line 1827 "pars0grm.cc" + { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } +#line 1785 "pars0grm.cc" break; - case 62: + case 63: /* select_item: exp */ #line 234 "pars0grm.y" - { yyval = NULL; } -#line 1833 "pars0grm.cc" + { yyval = yyvsp[0]; } +#line 1791 "pars0grm.cc" break; - case 63: -#line 235 "pars0grm.y" - { yyval = que_node_list_add_last(NULL, yyvsp[0]); } -#line 1839 "pars0grm.cc" - break; - - case 64: -#line 237 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } -#line 1845 "pars0grm.cc" - break; - - case 65: -#line 241 "pars0grm.y" - { yyval = NULL; } -#line 1851 "pars0grm.cc" - break; - - case 66: -#line 242 "pars0grm.y" - { yyval = que_node_list_add_last(NULL, yyvsp[0]);} -#line 1857 "pars0grm.cc" - break; - - case 67: -#line 243 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } -#line 1863 "pars0grm.cc" - break; - - case 68: -#line 247 "pars0grm.y" - { yyval = yyvsp[0]; } -#line 1869 "pars0grm.cc" - break; - - case 69: -#line 249 "pars0grm.y" - { yyval = pars_func(&pars_count_token, + case 64: /* select_item: PARS_COUNT_TOKEN '(' '*' ')' */ +#line 236 "pars0grm.y" + { yyval = pars_func(&pars_count_token, que_node_list_add_last(NULL, sym_tab_add_int_lit( pars_sym_tab_global, 1))); } -#line 1878 "pars0grm.cc" +#line 1800 "pars0grm.cc" break; - case 70: -#line 256 "pars0grm.y" - { yyval = NULL; } -#line 1884 "pars0grm.cc" + case 65: /* select_item_list: %empty */ +#line 243 "pars0grm.y" + { yyval = NULL; } +#line 1806 "pars0grm.cc" break; - case 71: -#line 257 "pars0grm.y" - { yyval = que_node_list_add_last(NULL, yyvsp[0]); } -#line 1890 "pars0grm.cc" + case 66: /* select_item_list: select_item */ +#line 244 "pars0grm.y" + { yyval = que_node_list_add_last(NULL, yyvsp[0]); } +#line 1812 "pars0grm.cc" break; - case 72: -#line 259 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } -#line 1896 "pars0grm.cc" + case 67: /* select_item_list: select_item_list ',' select_item */ +#line 246 "pars0grm.y" + { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } +#line 1818 "pars0grm.cc" break; - case 73: -#line 263 "pars0grm.y" - { yyval = pars_select_list(&pars_star_denoter, + case 68: /* select_list: '*' */ +#line 250 "pars0grm.y" + { yyval = pars_select_list(&pars_star_denoter, NULL); } -#line 1903 "pars0grm.cc" +#line 1825 "pars0grm.cc" break; - case 74: -#line 266 "pars0grm.y" - { yyval = pars_select_list( + case 69: /* select_list: select_item_list PARS_INTO_TOKEN variable_list */ +#line 253 "pars0grm.y" + { yyval = pars_select_list( yyvsp[-2], static_cast(yyvsp[0])); } -#line 1910 "pars0grm.cc" +#line 1832 "pars0grm.cc" break; - case 75: -#line 268 "pars0grm.y" - { yyval = pars_select_list(yyvsp[0], NULL); } -#line 1916 "pars0grm.cc" + case 70: /* select_list: select_item_list */ +#line 255 "pars0grm.y" + { yyval = pars_select_list(yyvsp[0], NULL); } +#line 1838 "pars0grm.cc" break; - case 76: + case 71: /* search_condition: %empty */ +#line 259 "pars0grm.y" + { yyval = NULL; } +#line 1844 "pars0grm.cc" + break; + + case 72: /* search_condition: PARS_WHERE_TOKEN exp */ +#line 260 "pars0grm.y" + { yyval = yyvsp[0]; } +#line 1850 "pars0grm.cc" + break; + + case 73: /* for_update_clause: %empty */ +#line 264 "pars0grm.y" + { yyval = NULL; } +#line 1856 "pars0grm.cc" + break; + + case 74: /* for_update_clause: PARS_FOR_TOKEN PARS_UPDATE_TOKEN */ +#line 266 "pars0grm.y" + { yyval = &pars_update_token; } +#line 1862 "pars0grm.cc" + break; + + case 75: /* lock_shared_clause: %empty */ +#line 270 "pars0grm.y" + { yyval = NULL; } +#line 1868 "pars0grm.cc" + break; + + case 76: /* lock_shared_clause: PARS_LOCK_TOKEN PARS_IN_TOKEN PARS_SHARE_TOKEN PARS_MODE_TOKEN */ #line 272 "pars0grm.y" - { yyval = NULL; } -#line 1922 "pars0grm.cc" + { yyval = &pars_share_token; } +#line 1874 "pars0grm.cc" break; - case 77: -#line 273 "pars0grm.y" - { yyval = yyvsp[0]; } -#line 1928 "pars0grm.cc" + case 77: /* order_direction: %empty */ +#line 276 "pars0grm.y" + { yyval = &pars_asc_token; } +#line 1880 "pars0grm.cc" break; - case 78: + case 78: /* order_direction: PARS_ASC_TOKEN */ #line 277 "pars0grm.y" - { yyval = NULL; } -#line 1934 "pars0grm.cc" + { yyval = &pars_asc_token; } +#line 1886 "pars0grm.cc" break; - case 79: -#line 279 "pars0grm.y" - { yyval = &pars_update_token; } -#line 1940 "pars0grm.cc" + case 79: /* order_direction: PARS_DESC_TOKEN */ +#line 278 "pars0grm.y" + { yyval = &pars_desc_token; } +#line 1892 "pars0grm.cc" break; - case 80: -#line 283 "pars0grm.y" - { yyval = NULL; } -#line 1946 "pars0grm.cc" + case 80: /* order_by_clause: %empty */ +#line 282 "pars0grm.y" + { yyval = NULL; } +#line 1898 "pars0grm.cc" break; - case 81: -#line 285 "pars0grm.y" - { yyval = &pars_share_token; } -#line 1952 "pars0grm.cc" - break; - - case 82: -#line 289 "pars0grm.y" - { yyval = &pars_asc_token; } -#line 1958 "pars0grm.cc" - break; - - case 83: -#line 290 "pars0grm.y" - { yyval = &pars_asc_token; } -#line 1964 "pars0grm.cc" - break; - - case 84: -#line 291 "pars0grm.y" - { yyval = &pars_desc_token; } -#line 1970 "pars0grm.cc" - break; - - case 85: -#line 295 "pars0grm.y" - { yyval = NULL; } -#line 1976 "pars0grm.cc" - break; - - case 86: -#line 297 "pars0grm.y" - { yyval = pars_order_by( + case 81: /* order_by_clause: PARS_ORDER_TOKEN PARS_BY_TOKEN PARS_ID_TOKEN order_direction */ +#line 284 "pars0grm.y" + { yyval = pars_order_by( static_cast(yyvsp[-1]), static_cast(yyvsp[0])); } -#line 1984 "pars0grm.cc" +#line 1906 "pars0grm.cc" break; - case 87: -#line 308 "pars0grm.y" - { yyval = pars_select_statement( + case 82: /* select_statement: PARS_SELECT_TOKEN select_list PARS_FROM_TOKEN table_list search_condition for_update_clause lock_shared_clause order_by_clause */ +#line 295 "pars0grm.y" + { yyval = pars_select_statement( static_cast(yyvsp[-6]), static_cast(yyvsp[-4]), static_cast(yyvsp[-3]), static_cast(yyvsp[-2]), static_cast(yyvsp[-1]), static_cast(yyvsp[0])); } -#line 1996 "pars0grm.cc" +#line 1918 "pars0grm.cc" break; - case 88: -#line 319 "pars0grm.y" - { yyval = yyvsp[0]; } -#line 2002 "pars0grm.cc" + case 83: /* insert_statement_start: PARS_INSERT_TOKEN PARS_INTO_TOKEN table_name */ +#line 306 "pars0grm.y" + { yyval = yyvsp[0]; } +#line 1924 "pars0grm.cc" break; - case 89: -#line 324 "pars0grm.y" - { yyval = pars_insert_statement( + case 84: /* insert_statement: insert_statement_start PARS_VALUES_TOKEN '(' exp_list ')' */ +#line 311 "pars0grm.y" + { yyval = pars_insert_statement( static_cast(yyvsp[-4]), yyvsp[-1], NULL); } -#line 2009 "pars0grm.cc" +#line 1931 "pars0grm.cc" break; - case 90: -#line 327 "pars0grm.y" - { yyval = pars_insert_statement( + case 85: /* insert_statement: insert_statement_start select_statement */ +#line 314 "pars0grm.y" + { yyval = pars_insert_statement( static_cast(yyvsp[-1]), NULL, static_cast(yyvsp[0])); } -#line 2018 "pars0grm.cc" +#line 1940 "pars0grm.cc" break; - case 91: -#line 334 "pars0grm.y" - { yyval = pars_column_assignment( + case 86: /* column_assignment: PARS_ID_TOKEN '=' exp */ +#line 321 "pars0grm.y" + { yyval = pars_column_assignment( static_cast(yyvsp[-2]), static_cast(yyvsp[0])); } -#line 2026 "pars0grm.cc" +#line 1948 "pars0grm.cc" break; - case 92: -#line 340 "pars0grm.y" - { yyval = que_node_list_add_last(NULL, yyvsp[0]); } -#line 2032 "pars0grm.cc" + case 87: /* column_assignment_list: column_assignment */ +#line 327 "pars0grm.y" + { yyval = que_node_list_add_last(NULL, yyvsp[0]); } +#line 1954 "pars0grm.cc" break; - case 93: -#line 342 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } -#line 2038 "pars0grm.cc" + case 88: /* column_assignment_list: column_assignment_list ',' column_assignment */ +#line 329 "pars0grm.y" + { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } +#line 1960 "pars0grm.cc" break; - case 94: -#line 348 "pars0grm.y" - { yyval = yyvsp[0]; } -#line 2044 "pars0grm.cc" + case 89: /* cursor_positioned: PARS_WHERE_TOKEN PARS_CURRENT_TOKEN PARS_OF_TOKEN PARS_ID_TOKEN */ +#line 335 "pars0grm.y" + { yyval = yyvsp[0]; } +#line 1966 "pars0grm.cc" break; - case 95: -#line 354 "pars0grm.y" - { yyval = pars_update_statement_start( + case 90: /* update_statement_start: PARS_UPDATE_TOKEN table_name PARS_SET_TOKEN column_assignment_list */ +#line 341 "pars0grm.y" + { yyval = pars_update_statement_start( FALSE, static_cast(yyvsp[-2]), static_cast(yyvsp[0])); } -#line 2053 "pars0grm.cc" +#line 1975 "pars0grm.cc" break; - case 96: -#line 362 "pars0grm.y" - { yyval = pars_update_statement( + case 91: /* update_statement_searched: update_statement_start search_condition */ +#line 349 "pars0grm.y" + { yyval = pars_update_statement( static_cast(yyvsp[-1]), NULL, static_cast(yyvsp[0])); } -#line 2062 "pars0grm.cc" +#line 1984 "pars0grm.cc" break; - case 97: -#line 370 "pars0grm.y" - { yyval = pars_update_statement( + case 92: /* update_statement_positioned: update_statement_start cursor_positioned */ +#line 357 "pars0grm.y" + { yyval = pars_update_statement( static_cast(yyvsp[-1]), static_cast(yyvsp[0]), NULL); } -#line 2071 "pars0grm.cc" +#line 1993 "pars0grm.cc" break; - case 98: -#line 378 "pars0grm.y" - { yyval = pars_update_statement_start( + case 93: /* delete_statement_start: PARS_DELETE_TOKEN PARS_FROM_TOKEN table_name */ +#line 365 "pars0grm.y" + { yyval = pars_update_statement_start( TRUE, static_cast(yyvsp[0]), NULL); } -#line 2079 "pars0grm.cc" +#line 2001 "pars0grm.cc" break; - case 99: -#line 385 "pars0grm.y" - { yyval = pars_update_statement( + case 94: /* delete_statement_searched: delete_statement_start search_condition */ +#line 372 "pars0grm.y" + { yyval = pars_update_statement( static_cast(yyvsp[-1]), NULL, static_cast(yyvsp[0])); } -#line 2088 "pars0grm.cc" +#line 2010 "pars0grm.cc" break; - case 100: -#line 393 "pars0grm.y" - { yyval = pars_update_statement( + case 95: /* delete_statement_positioned: delete_statement_start cursor_positioned */ +#line 380 "pars0grm.y" + { yyval = pars_update_statement( static_cast(yyvsp[-1]), static_cast(yyvsp[0]), NULL); } -#line 2097 "pars0grm.cc" +#line 2019 "pars0grm.cc" break; - case 101: -#line 401 "pars0grm.y" - { yyval = pars_assignment_statement( + case 96: /* assignment_statement: PARS_ID_TOKEN PARS_ASSIGN_TOKEN exp */ +#line 388 "pars0grm.y" + { yyval = pars_assignment_statement( static_cast(yyvsp[-2]), static_cast(yyvsp[0])); } -#line 2105 "pars0grm.cc" +#line 2027 "pars0grm.cc" break; - case 102: + case 97: /* elsif_element: PARS_ELSIF_TOKEN exp PARS_THEN_TOKEN statement_list */ +#line 396 "pars0grm.y" + { yyval = pars_elsif_element(yyvsp[-2], yyvsp[0]); } +#line 2033 "pars0grm.cc" + break; + + case 98: /* elsif_list: elsif_element */ +#line 400 "pars0grm.y" + { yyval = que_node_list_add_last(NULL, yyvsp[0]); } +#line 2039 "pars0grm.cc" + break; + + case 99: /* elsif_list: elsif_list elsif_element */ +#line 402 "pars0grm.y" + { yyval = que_node_list_add_last(yyvsp[-1], yyvsp[0]); } +#line 2045 "pars0grm.cc" + break; + + case 100: /* else_part: %empty */ +#line 406 "pars0grm.y" + { yyval = NULL; } +#line 2051 "pars0grm.cc" + break; + + case 101: /* else_part: PARS_ELSE_TOKEN statement_list */ +#line 408 "pars0grm.y" + { yyval = yyvsp[0]; } +#line 2057 "pars0grm.cc" + break; + + case 102: /* else_part: elsif_list */ #line 409 "pars0grm.y" - { yyval = pars_elsif_element(yyvsp[-2], yyvsp[0]); } + { yyval = yyvsp[0]; } +#line 2063 "pars0grm.cc" + break; + + case 103: /* if_statement: PARS_IF_TOKEN exp PARS_THEN_TOKEN statement_list else_part PARS_END_TOKEN PARS_IF_TOKEN */ +#line 416 "pars0grm.y" + { yyval = pars_if_statement(yyvsp[-5], yyvsp[-3], yyvsp[-2]); } +#line 2069 "pars0grm.cc" + break; + + case 104: /* while_statement: PARS_WHILE_TOKEN exp PARS_LOOP_TOKEN statement_list PARS_END_TOKEN PARS_LOOP_TOKEN */ +#line 422 "pars0grm.y" + { yyval = pars_while_statement(yyvsp[-4], yyvsp[-2]); } +#line 2075 "pars0grm.cc" + break; + + case 105: /* for_statement: PARS_FOR_TOKEN PARS_ID_TOKEN PARS_IN_TOKEN exp PARS_DDOT_TOKEN exp PARS_LOOP_TOKEN statement_list PARS_END_TOKEN PARS_LOOP_TOKEN */ +#line 430 "pars0grm.y" + { yyval = pars_for_statement( + static_cast(yyvsp[-8]), + yyvsp[-6], yyvsp[-4], yyvsp[-2]); } +#line 2083 "pars0grm.cc" + break; + + case 106: /* exit_statement: PARS_EXIT_TOKEN */ +#line 436 "pars0grm.y" + { yyval = pars_exit_statement(); } +#line 2089 "pars0grm.cc" + break; + + case 107: /* return_statement: PARS_RETURN_TOKEN */ +#line 440 "pars0grm.y" + { yyval = pars_return_statement(); } +#line 2095 "pars0grm.cc" + break; + + case 108: /* open_cursor_statement: PARS_OPEN_TOKEN PARS_ID_TOKEN */ +#line 445 "pars0grm.y" + { yyval = pars_open_statement( + ROW_SEL_OPEN_CURSOR, + static_cast(yyvsp[0])); } +#line 2103 "pars0grm.cc" + break; + + case 109: /* close_cursor_statement: PARS_CLOSE_TOKEN PARS_ID_TOKEN */ +#line 452 "pars0grm.y" + { yyval = pars_open_statement( + ROW_SEL_CLOSE_CURSOR, + static_cast(yyvsp[0])); } #line 2111 "pars0grm.cc" break; - case 103: -#line 413 "pars0grm.y" - { yyval = que_node_list_add_last(NULL, yyvsp[0]); } -#line 2117 "pars0grm.cc" - break; - - case 104: -#line 415 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-1], yyvsp[0]); } -#line 2123 "pars0grm.cc" - break; - - case 105: -#line 419 "pars0grm.y" - { yyval = NULL; } -#line 2129 "pars0grm.cc" - break; - - case 106: -#line 421 "pars0grm.y" - { yyval = yyvsp[0]; } -#line 2135 "pars0grm.cc" - break; - - case 107: -#line 422 "pars0grm.y" - { yyval = yyvsp[0]; } -#line 2141 "pars0grm.cc" - break; - - case 108: -#line 429 "pars0grm.y" - { yyval = pars_if_statement(yyvsp[-5], yyvsp[-3], yyvsp[-2]); } -#line 2147 "pars0grm.cc" - break; - - case 109: -#line 435 "pars0grm.y" - { yyval = pars_while_statement(yyvsp[-4], yyvsp[-2]); } -#line 2153 "pars0grm.cc" - break; - - case 110: -#line 443 "pars0grm.y" - { yyval = pars_for_statement( - static_cast(yyvsp[-8]), - yyvsp[-6], yyvsp[-4], yyvsp[-2]); } -#line 2161 "pars0grm.cc" - break; - - case 111: -#line 449 "pars0grm.y" - { yyval = pars_exit_statement(); } -#line 2167 "pars0grm.cc" - break; - - case 112: -#line 453 "pars0grm.y" - { yyval = pars_return_statement(); } -#line 2173 "pars0grm.cc" - break; - - case 113: -#line 458 "pars0grm.y" - { yyval = pars_open_statement( - ROW_SEL_OPEN_CURSOR, - static_cast(yyvsp[0])); } -#line 2181 "pars0grm.cc" - break; - - case 114: -#line 465 "pars0grm.y" - { yyval = pars_open_statement( - ROW_SEL_CLOSE_CURSOR, - static_cast(yyvsp[0])); } -#line 2189 "pars0grm.cc" - break; - - case 115: -#line 472 "pars0grm.y" - { yyval = pars_fetch_statement( + case 110: /* fetch_statement: PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN variable_list */ +#line 459 "pars0grm.y" + { yyval = pars_fetch_statement( static_cast(yyvsp[-2]), static_cast(yyvsp[0]), NULL); } -#line 2197 "pars0grm.cc" +#line 2119 "pars0grm.cc" break; - case 116: -#line 476 "pars0grm.y" - { yyval = pars_fetch_statement( + case 111: /* fetch_statement: PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN user_function_call */ +#line 463 "pars0grm.y" + { yyval = pars_fetch_statement( static_cast(yyvsp[-2]), NULL, static_cast(yyvsp[0])); } -#line 2206 "pars0grm.cc" +#line 2128 "pars0grm.cc" break; - case 117: -#line 484 "pars0grm.y" - { yyval = pars_column_def( + case 112: /* column_def: PARS_ID_TOKEN type_name opt_column_len opt_not_null */ +#line 471 "pars0grm.y" + { yyval = pars_column_def( static_cast(yyvsp[-3]), static_cast(yyvsp[-2]), static_cast(yyvsp[-1]), yyvsp[0]); } -#line 2216 "pars0grm.cc" +#line 2138 "pars0grm.cc" break; - case 118: -#line 492 "pars0grm.y" - { yyval = que_node_list_add_last(NULL, yyvsp[0]); } -#line 2222 "pars0grm.cc" + case 113: /* column_def_list: column_def */ +#line 479 "pars0grm.y" + { yyval = que_node_list_add_last(NULL, yyvsp[0]); } +#line 2144 "pars0grm.cc" break; - case 119: -#line 494 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } -#line 2228 "pars0grm.cc" + case 114: /* column_def_list: column_def_list ',' column_def */ +#line 481 "pars0grm.y" + { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } +#line 2150 "pars0grm.cc" break; - case 120: -#line 498 "pars0grm.y" - { yyval = NULL; } -#line 2234 "pars0grm.cc" + case 115: /* opt_column_len: %empty */ +#line 485 "pars0grm.y" + { yyval = NULL; } +#line 2156 "pars0grm.cc" break; - case 121: -#line 500 "pars0grm.y" - { yyval = yyvsp[-1]; } -#line 2240 "pars0grm.cc" + case 116: /* opt_column_len: '(' PARS_INT_LIT ')' */ +#line 487 "pars0grm.y" + { yyval = yyvsp[-1]; } +#line 2162 "pars0grm.cc" break; - case 122: -#line 504 "pars0grm.y" - { yyval = NULL; } -#line 2246 "pars0grm.cc" + case 117: /* opt_not_null: %empty */ +#line 491 "pars0grm.y" + { yyval = NULL; } +#line 2168 "pars0grm.cc" break; - case 123: -#line 506 "pars0grm.y" - { yyval = &pars_int_token; + case 118: /* opt_not_null: PARS_NOT_TOKEN PARS_NULL_LIT */ +#line 493 "pars0grm.y" + { yyval = &pars_int_token; /* pass any non-NULL pointer */ } -#line 2253 "pars0grm.cc" +#line 2175 "pars0grm.cc" break; - case 124: -#line 513 "pars0grm.y" - { yyval = pars_create_table( + case 119: /* create_table: PARS_CREATE_TOKEN PARS_TABLE_TOKEN table_name '(' column_def_list ')' */ +#line 500 "pars0grm.y" + { yyval = pars_create_table( static_cast(yyvsp[-3]), static_cast(yyvsp[-1])); } -#line 2261 "pars0grm.cc" +#line 2183 "pars0grm.cc" break; - case 125: -#line 519 "pars0grm.y" - { yyval = que_node_list_add_last(NULL, yyvsp[0]); } -#line 2267 "pars0grm.cc" + case 120: /* column_list: PARS_ID_TOKEN */ +#line 506 "pars0grm.y" + { yyval = que_node_list_add_last(NULL, yyvsp[0]); } +#line 2189 "pars0grm.cc" break; - case 126: -#line 521 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } -#line 2273 "pars0grm.cc" + case 121: /* column_list: column_list ',' PARS_ID_TOKEN */ +#line 508 "pars0grm.y" + { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); } +#line 2195 "pars0grm.cc" break; - case 127: -#line 525 "pars0grm.y" - { yyval = NULL; } -#line 2279 "pars0grm.cc" + case 122: /* unique_def: %empty */ +#line 512 "pars0grm.y" + { yyval = NULL; } +#line 2201 "pars0grm.cc" break; - case 128: -#line 526 "pars0grm.y" - { yyval = &pars_unique_token; } -#line 2285 "pars0grm.cc" + case 123: /* unique_def: PARS_UNIQUE_TOKEN */ +#line 513 "pars0grm.y" + { yyval = &pars_unique_token; } +#line 2207 "pars0grm.cc" break; - case 129: -#line 530 "pars0grm.y" - { yyval = NULL; } -#line 2291 "pars0grm.cc" + case 124: /* clustered_def: %empty */ +#line 517 "pars0grm.y" + { yyval = NULL; } +#line 2213 "pars0grm.cc" break; - case 130: -#line 531 "pars0grm.y" - { yyval = &pars_clustered_token; } -#line 2297 "pars0grm.cc" + case 125: /* clustered_def: PARS_CLUSTERED_TOKEN */ +#line 518 "pars0grm.y" + { yyval = &pars_clustered_token; } +#line 2219 "pars0grm.cc" break; - case 131: -#line 540 "pars0grm.y" - { yyval = pars_create_index( + case 126: /* create_index: PARS_CREATE_TOKEN unique_def clustered_def PARS_INDEX_TOKEN PARS_ID_TOKEN PARS_ON_TOKEN table_name '(' column_list ')' */ +#line 527 "pars0grm.y" + { yyval = pars_create_index( static_cast(yyvsp[-8]), static_cast(yyvsp[-7]), static_cast(yyvsp[-5]), static_cast(yyvsp[-3]), static_cast(yyvsp[-1])); } -#line 2308 "pars0grm.cc" +#line 2230 "pars0grm.cc" break; - case 132: -#line 549 "pars0grm.y" - { yyval = yyvsp[0]; } -#line 2314 "pars0grm.cc" + case 127: /* table_name: PARS_ID_TOKEN */ +#line 536 "pars0grm.y" + { yyval = yyvsp[0]; } +#line 2236 "pars0grm.cc" break; - case 133: -#line 550 "pars0grm.y" - { yyval = yyvsp[0]; } -#line 2320 "pars0grm.cc" + case 128: /* table_name: PARS_TABLE_NAME_TOKEN */ +#line 537 "pars0grm.y" + { yyval = yyvsp[0]; } +#line 2242 "pars0grm.cc" break; - case 134: -#line 555 "pars0grm.y" - { yyval = pars_commit_statement(); } -#line 2326 "pars0grm.cc" + case 129: /* commit_statement: PARS_COMMIT_TOKEN PARS_WORK_TOKEN */ +#line 542 "pars0grm.y" + { yyval = pars_commit_statement(); } +#line 2248 "pars0grm.cc" break; - case 135: -#line 560 "pars0grm.y" - { yyval = pars_rollback_statement(); } -#line 2332 "pars0grm.cc" + case 130: /* rollback_statement: PARS_ROLLBACK_TOKEN PARS_WORK_TOKEN */ +#line 547 "pars0grm.y" + { yyval = pars_rollback_statement(); } +#line 2254 "pars0grm.cc" break; - case 136: -#line 564 "pars0grm.y" - { yyval = &pars_int_token; } -#line 2338 "pars0grm.cc" + case 131: /* type_name: PARS_INT_TOKEN */ +#line 551 "pars0grm.y" + { yyval = &pars_int_token; } +#line 2260 "pars0grm.cc" break; - case 137: -#line 565 "pars0grm.y" - { yyval = &pars_bigint_token; } -#line 2344 "pars0grm.cc" + case 132: /* type_name: PARS_BIGINT_TOKEN */ +#line 552 "pars0grm.y" + { yyval = &pars_bigint_token; } +#line 2266 "pars0grm.cc" break; - case 138: -#line 566 "pars0grm.y" - { yyval = &pars_char_token; } -#line 2350 "pars0grm.cc" + case 133: /* type_name: PARS_CHAR_TOKEN */ +#line 553 "pars0grm.y" + { yyval = &pars_char_token; } +#line 2272 "pars0grm.cc" break; - case 139: -#line 571 "pars0grm.y" - { yyval = pars_variable_declaration( + case 134: /* variable_declaration: PARS_ID_TOKEN type_name ';' */ +#line 558 "pars0grm.y" + { yyval = pars_variable_declaration( static_cast(yyvsp[-2]), static_cast(yyvsp[-1])); } -#line 2358 "pars0grm.cc" +#line 2280 "pars0grm.cc" break; - case 143: -#line 585 "pars0grm.y" - { yyval = pars_cursor_declaration( + case 138: /* cursor_declaration: PARS_DECLARE_TOKEN PARS_CURSOR_TOKEN PARS_ID_TOKEN PARS_IS_TOKEN select_statement ';' */ +#line 572 "pars0grm.y" + { yyval = pars_cursor_declaration( static_cast(yyvsp[-3]), static_cast(yyvsp[-1])); } -#line 2366 "pars0grm.cc" +#line 2288 "pars0grm.cc" break; - case 144: -#line 592 "pars0grm.y" - { yyval = pars_function_declaration( + case 139: /* function_declaration: PARS_DECLARE_TOKEN PARS_FUNCTION_TOKEN PARS_ID_TOKEN ';' */ +#line 579 "pars0grm.y" + { yyval = pars_function_declaration( static_cast(yyvsp[-1])); } -#line 2373 "pars0grm.cc" +#line 2295 "pars0grm.cc" break; - case 150: -#line 614 "pars0grm.y" - { yyval = pars_procedure_definition( + case 145: /* procedure_definition: PARS_PROCEDURE_TOKEN PARS_ID_TOKEN '(' ')' PARS_IS_TOKEN variable_declaration_list declaration_list PARS_BEGIN_TOKEN statement_list PARS_END_TOKEN */ +#line 601 "pars0grm.y" + { yyval = pars_procedure_definition( static_cast(yyvsp[-8]), yyvsp[-1]); } -#line 2380 "pars0grm.cc" +#line 2302 "pars0grm.cc" break; -#line 2384 "pars0grm.cc" +#line 2306 "pars0grm.cc" default: break; } @@ -2395,11 +2317,10 @@ yyreduce: case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; - YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; @@ -2423,50 +2344,14 @@ yyreduce: yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; -#if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif } - - if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an @@ -2515,13 +2400,14 @@ yyerrorlab: yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ + /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) @@ -2535,7 +2421,7 @@ yyerrlab1: yydestruct ("Error: popping", - yystos[yystate], yyvsp); + YY_ACCESSING_SYMBOL (yystate), yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); @@ -2547,7 +2433,7 @@ yyerrlab1: /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; @@ -2569,20 +2455,20 @@ yyabortlab: goto yyreturn; -#if !defined yyoverflow || YYERROR_VERBOSE +#if !defined yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; - /* Fall through. */ + goto yyreturn; #endif -/*-----------------------------------------------------. -| yyreturn -- parsing is finished, return the result. | -`-----------------------------------------------------*/ +/*-------------------------------------------------------. +| yyreturn -- parsing is finished, clean up and return. | +`-------------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { @@ -2599,18 +2485,16 @@ yyreturn: while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif + return yyresult; } -#line 618 "pars0grm.y" + +#line 605 "pars0grm.y" diff --git a/storage/innobase/pars/pars0grm.y b/storage/innobase/pars/pars0grm.y index 625ed41bbd4..cfa654adfd0 100644 --- a/storage/innobase/pars/pars0grm.y +++ b/storage/innobase/pars/pars0grm.y @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2019, MariaDB Corporation. +Copyright (c) 2017, 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 the Free Software @@ -140,8 +140,7 @@ top_statement: procedure_definition ';' statement: - stored_procedure_call - | while_statement ';' + while_statement ';' | for_statement ';' | exit_statement ';' | if_statement ';' @@ -208,18 +207,6 @@ function_name: | PARS_LENGTH_TOKEN { $$ = &pars_length_token; } ; -question_mark_list: - /* Nothing */ - | '?' - | question_mark_list ',' '?' -; - -stored_procedure_call: - '{' PARS_ID_TOKEN '(' question_mark_list ')' '}' - { $$ = pars_stored_procedure_call( - static_cast($2)); } -; - user_function_call: PARS_ID_TOKEN '(' ')' { $$ = $1; } ; diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index abd8dd9b26a..1c3802f05e4 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -1915,22 +1915,6 @@ pars_procedure_definition( return(fork); } -/*************************************************************//** -Parses a stored procedure call, when this is not within another stored -procedure, that is, the client issues a procedure call directly. -In MySQL/InnoDB, stored InnoDB procedures are invoked via the -parsed procedure tree, not via InnoDB SQL, so this function is not used. -@return query graph */ -que_fork_t* -pars_stored_procedure_call( -/*=======================*/ - sym_node_t* sym_node MY_ATTRIBUTE((unused))) - /*!< in: stored procedure name */ -{ - ut_error; - return(NULL); -} - /*************************************************************//** Retrieves characters to the lexical analyzer. */ int diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 7a5074b5b71..76fd025e5fb 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -705,6 +705,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; @@ -3954,10 +3962,6 @@ row_import_for_mysql( prebuilt->trx->op_info = "read meta-data file"; - /* Prevent DDL operations while we are checking. */ - - dict_sys.freeze(); - row_import cfg; err = row_import_read_cfg(table, trx->mysql_thd, cfg); @@ -3981,15 +3985,10 @@ row_import_for_mysql( autoinc = cfg.m_autoinc; } - dict_sys.unfreeze(); - DBUG_EXECUTE_IF("ib_import_set_index_root_failure", err = DB_TOO_MANY_CONCURRENT_TRXS;); } else if (cfg.m_missing) { - - dict_sys.unfreeze(); - /* We don't have a schema file, we will have to discover the index root pages from the .ibd file and skip the schema matching step. */ @@ -4016,8 +4015,6 @@ row_import_for_mysql( err = cfg.set_root_by_heuristic(); } } - } else { - dict_sys.unfreeze(); } if (err != DB_SUCCESS) { diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 42e37ee5af6..4312e95d110 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -934,8 +934,8 @@ row_ins_foreign_fill_virtual( upd_field = update->fields + n_diff; upd_field->old_v_val = static_cast( - 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); @@ -1342,16 +1342,6 @@ row_ins_foreign_check_on_constraint( err = row_update_cascade_for_mysql(thr, cascade, foreign->foreign_table); - /* Release the data dictionary latch for a while, so that we do not - starve other threads from doing CREATE TABLE etc. if we have a huge - cascaded operation running. */ - - row_mysql_unfreeze_data_dictionary(thr_get_trx(thr)); - - DEBUG_SYNC_C("innodb_dml_cascade_dict_unfreeze"); - - row_mysql_freeze_data_dictionary(thr_get_trx(thr)); - mtr_start(mtr); /* Restore pcur position */ diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index b8f78775624..f84755a5c4a 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1626,33 +1626,24 @@ init_fts_doc_id_for_ref( dict_table_t* table, /*!< in: table */ ulint* depth) /*!< in: recusive call depth */ { - dict_foreign_t* foreign; - table->fk_max_recusive_level = 0; - (*depth)++; - /* Limit on tables involved in cascading delete/update */ - if (*depth > FK_MAX_CASCADE_DEL) { + if (++*depth > FK_MAX_CASCADE_DEL) { return; } /* Loop through this table's referenced list and also recursively traverse each table's foreign table list */ - for (dict_foreign_set::iterator it = table->referenced_set.begin(); - it != table->referenced_set.end(); - ++it) { + for (dict_foreign_t* foreign : table->referenced_set) { + ut_ad(foreign->foreign_table); - foreign = *it; - - ut_ad(foreign->foreign_table != NULL); - - if (foreign->foreign_table->fts != NULL) { + if (foreign->foreign_table->fts) { fts_init_doc_id(foreign->foreign_table); } - if (!foreign->foreign_table->referenced_set.empty() - && foreign->foreign_table != table) { + if (foreign->foreign_table != table + && !foreign->foreign_table->referenced_set.empty()) { init_fts_doc_id_for_ref( foreign->foreign_table, depth); } @@ -1673,7 +1664,6 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) dict_table_t* table = prebuilt->table; trx_t* trx = prebuilt->trx; ulint fk_depth = 0; - bool got_s_lock = false; DBUG_ENTER("row_update_for_mysql"); @@ -1703,18 +1693,6 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) trx_start_if_not_started_xa(trx, true); } - if (dict_table_is_referenced_by_foreign_key(table)) { - /* Share lock the data dictionary to prevent any - table dictionary (for foreign constraint) change. - This is similar to row_ins_check_foreign_constraint - check protect by the dictionary lock as well. - In the future, this can be removed once the Foreign - key MDL is implemented */ - row_mysql_freeze_data_dictionary(trx); - init_fts_doc_id_for_ref(table, &fk_depth); - row_mysql_unfreeze_data_dictionary(trx); - } - node = prebuilt->upd_node; const bool is_delete = node->is_delete == PLAIN_DELETE; ut_ad(node->table == table); @@ -1795,10 +1773,6 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) } /* Completed cascading operations (if any) */ - if (got_s_lock) { - row_mysql_unfreeze_data_dictionary(trx); - } - bool update_statistics; ut_ad(is_delete == (node->is_delete == PLAIN_DELETE)); @@ -1834,16 +1808,8 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) prebuilt->table->stat_modified_counter++; } - trx->op_info = ""; - - DBUG_RETURN(err); - error: trx->op_info = ""; - if (got_s_lock) { - row_mysql_unfreeze_data_dictionary(trx); - } - DBUG_RETURN(err); } @@ -1970,29 +1936,6 @@ no_unlock: trx->op_info = ""; } -/*********************************************************************//** -Locks the data dictionary in shared mode from modifications, for performing -foreign key check, rollback, or other operation invisible to MySQL. */ -void row_mysql_freeze_data_dictionary(trx_t *trx) -{ - ut_a(trx->dict_operation_lock_mode == 0); - trx->dict_operation_lock_mode = RW_S_LATCH; - dict_sys.freeze(); -} - -/*********************************************************************//** -Unlocks the data dictionary shared lock. */ -void -row_mysql_unfreeze_data_dictionary( -/*===============================*/ - trx_t* trx) /*!< in/out: transaction */ -{ - ut_ad(!lock_trx_has_sys_table_locks(trx)); - ut_ad(trx->dict_operation_lock_mode == RW_S_LATCH); - dict_sys.unfreeze(); - trx->dict_operation_lock_mode = 0; -} - /** Write query start time as SQL field data to a buffer. Needed by InnoDB. @param thd Thread object @param buf Buffer to hold start time data */ diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index fce9575aa9d..704c067fc43 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -101,8 +101,7 @@ restart: online = dict_index_is_online_ddl(index); if (online) { ut_ad(node->rec_type == TRX_UNDO_INSERT_REC); - ut_ad(node->trx->dict_operation_lock_mode - != RW_X_LATCH); + ut_ad(!node->trx->dict_operation_lock_mode); ut_ad(node->table->id != DICT_INDEXES_ID); ut_ad(node->table->id != DICT_COLUMNS_ID); mtr_s_lock_index(index, &mtr); @@ -617,6 +616,9 @@ row_undo_ins( return DB_SUCCESS; } + ut_ad(node->table->is_temporary() + || lock_table_has_locks(node->table)); + /* Iterate over all the indexes and undo the insert.*/ node->index = dict_table_get_first_index(node->table); diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 5452229d9cb..ba675c927eb 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -267,7 +267,6 @@ row_undo_mod_clust( bool online; ut_ad(thr_get_trx(thr) == node->trx); - ut_ad(node->trx->dict_operation_lock_mode); ut_ad(node->trx->in_rollback); log_free_check(); @@ -285,7 +284,7 @@ row_undo_mod_clust( online = dict_index_is_online_ddl(index); if (online) { - ut_ad(node->trx->dict_operation_lock_mode != RW_X_LATCH); + ut_ad(!node->trx->dict_operation_lock_mode); mtr_s_lock_index(index, &mtr); } @@ -324,13 +323,7 @@ row_undo_mod_clust( ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE); } - /* Online rebuild cannot be initiated while we are holding - dict_sys.latch and index->lock. (It can be aborted.) */ - ut_ad(online || !dict_index_is_online_ddl(index)); - - if (err == DB_SUCCESS && online) { - ut_ad(index->lock.have_any()); - + if (err == DB_SUCCESS && online && dict_index_is_online_ddl(index)) { switch (node->rec_type) { case TRX_UNDO_DEL_MARK_REC: row_log_table_insert( @@ -920,37 +913,6 @@ func_exit_no_pcur: return(err); } -/***********************************************************//** -Flags a secondary index corrupted. */ -static MY_ATTRIBUTE((nonnull)) -void -row_undo_mod_sec_flag_corrupted( -/*============================*/ - trx_t* trx, /*!< in/out: transaction */ - dict_index_t* index) /*!< in: secondary index */ -{ - ut_ad(!dict_index_is_clust(index)); - - switch (trx->dict_operation_lock_mode) { - case RW_S_LATCH: - /* Because row_undo() is holding an S-latch - on the data dictionary during normal rollback, - we can only mark the index corrupted in the - data dictionary cache. TODO: fix this somehow.*/ - dict_sys.mutex_lock(); - dict_set_corrupted_index_cache_only(index); - dict_sys.mutex_unlock(); - break; - default: - ut_ad(0); - /* fall through */ - case RW_X_LATCH: - /* This should be the rollback of a data dictionary - transaction. */ - dict_set_corrupted(index, trx, "rollback"); - } -} - /***********************************************************//** Undoes a modify in secondary indexes when undo record type is UPD_DEL. @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ @@ -1064,8 +1026,7 @@ row_undo_mod_del_mark_sec( } if (err == DB_DUPLICATE_KEY) { - row_undo_mod_sec_flag_corrupted( - thr_get_trx(thr), index); + index->type |= DICT_CORRUPT; err = DB_SUCCESS; /* Do not return any error to the caller. The duplicate will be reported by ALTER TABLE or @@ -1210,8 +1171,7 @@ row_undo_mod_upd_exist_sec( } if (err == DB_DUPLICATE_KEY) { - row_undo_mod_sec_flag_corrupted( - thr_get_trx(thr), index); + index->type |= DICT_CORRUPT; err = DB_SUCCESS; } else if (err != DB_SUCCESS) { break; @@ -1374,6 +1334,8 @@ row_undo_mod( return DB_SUCCESS; } + ut_ad(node->table->is_temporary() + || lock_table_has_locks(node->table)); node->index = dict_table_get_first_index(node->table); ut_ad(dict_index_is_clust(node->index)); diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc index 4e51a811a49..f36287c7c8d 100644 --- a/storage/innobase/row/row0undo.cc +++ b/storage/innobase/row/row0undo.cc @@ -401,19 +401,6 @@ row_undo( return DB_SUCCESS; } - /* Prevent prepare_inplace_alter_table_dict() from adding - dict_table_t::indexes while we are processing the record. - Recovered transactions are not protected by MDL, and the - secondary index creation is not protected by table locks - for online operation. (A table lock would only be acquired - when committing the ALTER TABLE operation.) */ - trx_t* trx = node->trx; - const bool locked_data_dict = !trx->dict_operation_lock_mode; - - if (UNIV_UNLIKELY(locked_data_dict)) { - row_mysql_freeze_data_dictionary(trx); - } - dberr_t err; switch (node->state) { @@ -430,11 +417,6 @@ row_undo( err = DB_CORRUPTION; } - if (locked_data_dict) { - - row_mysql_unfreeze_data_dictionary(trx); - } - node->state = UNDO_NODE_FETCH_NEXT; btr_pcur_close(&(node->pcur)); diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index d68280cbeb3..ee88ee7a4a6 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -52,6 +52,11 @@ Created 12/27/1996 Heikki Tuuri #include #include #include +#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 ------------------------------------------------------------------- @@ -122,10 +127,6 @@ row_upd_changes_first_fields_binary( Checks if index currently is mentioned as a referenced index in a foreign key constraint. -NOTE that since we do not hold dict_sys.latch when leaving the -function, it may be that the referencing table has been dropped when -we leave this function: this function is only for heuristic use! - @return true if referenced */ static bool @@ -134,64 +135,44 @@ row_upd_index_is_referenced( dict_index_t* index, /*!< in: index */ trx_t* trx) /*!< in: transaction */ { - dict_table_t* table = index->table; - - if (table->referenced_set.empty()) { - return false; - } - - const bool froze_data_dict = !trx->dict_operation_lock_mode; - if (froze_data_dict) { - row_mysql_freeze_data_dictionary(trx); - } - - dict_foreign_set::iterator it - = std::find_if(table->referenced_set.begin(), - table->referenced_set.end(), - dict_foreign_with_index(index)); - - const bool is_referenced = (it != table->referenced_set.end()); - - if (froze_data_dict) { - row_mysql_unfreeze_data_dictionary(trx); - } - - return is_referenced; + dict_table_t *table= index->table; + /* The pointers in table->referenced_set are safe to dereference + thanks to the SQL layer having acquired MDL on all (grand)parent tables. */ + dict_foreign_set::iterator end= table->referenced_set.end(); + return end != std::find_if(table->referenced_set.begin(), end, + dict_foreign_with_index(index)); } #ifdef WITH_WSREP static -ibool +bool wsrep_row_upd_index_is_foreign( /*========================*/ dict_index_t* index, /*!< in: index */ trx_t* trx) /*!< in: transaction */ { - dict_table_t* table = index->table; - ibool froze_data_dict = FALSE; - ibool is_referenced = FALSE; + if (!trx->is_wsrep()) + return false; - if (table->foreign_set.empty()) { - return(FALSE); - } + dict_table_t *table= index->table; - if (trx->dict_operation_lock_mode == 0) { - row_mysql_freeze_data_dictionary(trx); - froze_data_dict = TRUE; - } + if (table->foreign_set.empty()) + return false; - dict_foreign_set::iterator it - = std::find_if(table->foreign_set.begin(), - table->foreign_set.end(), - dict_foreign_with_foreign_index(index)); + /* No MDL protects dereferencing the members of table->foreign_set. */ + const bool no_lock= !trx->dict_operation_lock_mode; + if (no_lock) + dict_sys.freeze(); - is_referenced = (it != table->foreign_set.end()); + auto end= table->foreign_set.end(); + const bool is_referenced= end != + std::find_if(table->foreign_set.begin(), end, + [index](const dict_foreign_t* f) + {return f->foreign_index == index;}); + if (no_lock) + dict_sys.unfreeze(); - if (froze_data_dict) { - row_mysql_unfreeze_data_dictionary(trx); - } - - return(is_referenced); + return is_referenced; } #endif /* WITH_WSREP */ @@ -219,10 +200,8 @@ row_upd_check_references_constraints( dict_foreign_t* foreign; mem_heap_t* heap; dtuple_t* entry; - trx_t* trx; const rec_t* rec; dberr_t err; - ibool got_s_lock = FALSE; DBUG_ENTER("row_upd_check_references_constraints"); @@ -230,8 +209,6 @@ row_upd_check_references_constraints( DBUG_RETURN(DB_SUCCESS); } - trx = thr_get_trx(thr); - rec = btr_pcur_get_rec(pcur); ut_ad(rec_offs_validate(rec, index, offsets)); @@ -245,12 +222,6 @@ row_upd_check_references_constraints( mtr->start(); - if (trx->dict_operation_lock_mode == 0) { - got_s_lock = TRUE; - - row_mysql_freeze_data_dictionary(trx); - } - DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd, "foreign_constraint_check_for_insert"); @@ -297,10 +268,6 @@ row_upd_check_references_constraints( err = DB_SUCCESS; func_exit: - if (got_s_lock) { - row_mysql_unfreeze_data_dictionary(trx); - } - mem_heap_free(heap); DEBUG_SYNC_C("foreign_constraint_check_for_update_done"); @@ -324,18 +291,14 @@ wsrep_row_upd_check_foreign_constraints( dict_foreign_t* foreign; mem_heap_t* heap; dtuple_t* entry; - trx_t* trx; const rec_t* rec; dberr_t err; - ibool got_s_lock = FALSE; ibool opened = FALSE; if (table->foreign_set.empty()) { return(DB_SUCCESS); } - trx = thr_get_trx(thr); - /* TODO: make native slave thread bail out here */ rec = btr_pcur_get_rec(pcur); @@ -349,12 +312,6 @@ wsrep_row_upd_check_foreign_constraints( mtr_start(mtr); - if (trx->dict_operation_lock_mode == 0) { - got_s_lock = TRUE; - - row_mysql_freeze_data_dictionary(trx); - } - for (dict_foreign_set::iterator it = table->foreign_set.begin(); it != table->foreign_set.end(); ++it) { @@ -402,10 +359,6 @@ wsrep_row_upd_check_foreign_constraints( err = DB_SUCCESS; func_exit: - if (got_s_lock) { - row_mysql_unfreeze_data_dictionary(trx); - } - mem_heap_free(heap); return(err); @@ -1957,7 +1910,7 @@ row_upd_sec_index_entry( const bool referenced = row_upd_index_is_referenced(index, trx); #ifdef WITH_WSREP - bool foreign = wsrep_row_upd_index_is_foreign(index, trx); + const bool foreign = wsrep_row_upd_index_is_foreign(index, trx); #endif /* WITH_WSREP */ heap = mem_heap_create(1024); @@ -2136,34 +2089,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( @@ -2484,17 +2433,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 */ @@ -2711,18 +2664,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 3763ed67c98..4a6c7ed42a0 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1135,8 +1135,8 @@ static void trx_flush_log_if_needed_low(lsn_t lsn, trx_state_t trx_state) if (log_sys.get_flushed_lsn() > lsn) return; - bool flush= srv_file_flush_method != SRV_NOSYNC && - srv_flush_log_at_trx_commit == 1; + const bool flush= srv_file_flush_method != SRV_NOSYNC && + (srv_flush_log_at_trx_commit & 1); if (trx_state == TRX_STATE_PREPARED) { @@ -1695,7 +1695,9 @@ trx_print_low( fprintf(f, ", state %lu", (ulong) trx->state); ut_ad(0); state_ok: - if (const char *op_info = trx->op_info) { + const char* op_info = trx->op_info; + + if (*op_info) { putc(' ', f); fputs(op_info, f); } diff --git a/storage/maria/ha_s3.cc b/storage/maria/ha_s3.cc index e7428385a60..d5efcbafd86 100644 --- a/storage/maria/ha_s3.cc +++ b/storage/maria/ha_s3.cc @@ -1119,6 +1119,6 @@ maria_declare_plugin(s3) status_variables, /* status variables */ system_variables, /* system variables */ "1.0", /* string version */ - MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ + MariaDB_PLUGIN_MATURITY_STABLE/* maturity */ } maria_declare_plugin_end; diff --git a/storage/maria/libmarias3 b/storage/maria/libmarias3 index c71898f8259..3846890513d 160000 --- a/storage/maria/libmarias3 +++ b/storage/maria/libmarias3 @@ -1 +1 @@ -Subproject commit c71898f8259829bf4b2e01072000491281e5206d +Subproject commit 3846890513df0653b8919bc45a7600f9b55cab31 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 similarity index 100% rename from storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version rename to storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version_full diff --git a/storage/mroonga/version b/storage/mroonga/version_full similarity index 100% rename from storage/mroonga/version rename to 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 be687478b9b..26533fae648 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 53e0e943678..fd23b7ba470 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/rocksdb/rdb_utils.cc b/storage/rocksdb/rdb_utils.cc index dc1b7c8892e..ad6fdf5825f 100644 --- a/storage/rocksdb/rdb_utils.cc +++ b/storage/rocksdb/rdb_utils.cc @@ -346,7 +346,7 @@ void rdb_persist_corruption_marker() { } else { // NO_LINT_DEBUG sql_print_information( - "RocksDB: Creating the file %s to abort mysqld " + "RocksDB: Creating the file %s to abort server " "restarts. Remove this file from the data directory " "after fixing the corruption to recover. ", fileName.c_str()); 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 0732ca0d2bf..bff2e574cc4 100644 --- a/storage/spider/mysql-test/spider/t/spider_fixes_part.test +++ b/storage/spider/mysql-test/spider/t/spider_fixes_part.test @@ -728,6 +728,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 2a7e799e97d..fd0f3efe6dd 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 c66f39d9f70..0dfe9b16fad 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 7bc3a310c5f..10b4fb7cee4 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -5876,72 +5876,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) + /* 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->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 (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_THEN_STR, SPIDER_SQL_THEN_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[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) @@ -6788,6 +6822,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/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 851f0394f4a..90e79954fd1 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -79,7 +79,7 @@ IF(UNIX AND NOT WITHOUT_SERVER) 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/support-files/mysql.server.sh b/support-files/mysql.server.sh index cefb3225e9e..cbd6b472148 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -200,11 +200,11 @@ su_kill() { extra_args="" if test -r "$basedir/my.cnf" then - extra_args="-e $basedir/my.cnf" + extra_args="--defaults-extra-file= $basedir/my.cnf" else if test -r "$datadir/my.cnf" then - extra_args="-e $datadir/my.cnf" + extra_args="--defaults-extra-file= $datadir/my.cnf" fi fi diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index e6c5f4ab654..59ed669217d 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) { @@ -21439,6 +21504,7 @@ static void test_cache_metadata() 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 index 85b81503214..c45b1eff940 160000 --- a/wsrep-lib +++ b/wsrep-lib @@ -1 +1 @@ -Subproject commit 85b815032145ef5c18b7a8931d84becf6df8cd18 +Subproject commit c45b1eff940077e2b2f364f30ba04930f134da8d