diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 28a6d6b6aed..cab2c0d5f3d 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -147,7 +147,7 @@ elif [ "x$warning_mode" = "xmaintainer" ]; then debug_extra_cflags="-g3" else # Both C and C++ warnings - warnings="-Wall -Wextra -Wunused -Wwrite-strings -Wno-uninitialized -Wno-strict-aliasing -Wimplicit-fallthrough=2 -Wformat-security -Wvla" + warnings="-Wall -Wextra -Wunused -Wwrite-strings -Wno-uninitialized -Wno-strict-aliasing -Wformat-security -Wvla" # For more warnings, uncomment the following line # warnings="$warnings -Wshadow" diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 2fbd8c95e9f..b3a728a6e10 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -80,6 +80,9 @@ static my_bool non_blocking_api_enabled= 0; #define DIE_BUFF_SIZE 256*1024 +#define RESULT_STRING_INIT_MEM 2048 +#define RESULT_STRING_INCREMENT_MEM 2048 + /* Flags controlling send and reap */ #define QUERY_SEND_FLAG 1 #define QUERY_REAP_FLAG 2 @@ -1729,7 +1732,7 @@ void log_msg(const char *fmt, ...) va_end(args); dynstr_append_mem(&ds_res, buff, len); - dynstr_append(&ds_res, "\n"); + dynstr_append_mem(&ds_res, STRING_WITH_LEN("\n")); DBUG_VOID_RETURN; } @@ -1865,7 +1868,7 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) die("Out of memory"); dynstr_append_os_quoted(&ds_cmdline, tool_path, NullS); - dynstr_append(&ds_cmdline, " "); + dynstr_append_mem(&ds_cmdline, STRING_WITH_LEN(" ")); va_start(args, ds_res); @@ -1876,13 +1879,13 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) dynstr_append_os_quoted(&ds_cmdline, arg, NullS); else dynstr_append(&ds_cmdline, arg); - dynstr_append(&ds_cmdline, " "); + dynstr_append_mem(&ds_cmdline, STRING_WITH_LEN(" ")); } va_end(args); #ifdef _WIN32 - dynstr_append(&ds_cmdline, "\""); + dynstr_append_mem(&ds_cmdline, STRING_WITH_LEN("\"")); #endif DBUG_PRINT("info", ("Running: %s", ds_cmdline.str)); @@ -2017,8 +2020,8 @@ void show_diff(DYNAMIC_STRING* ds, Fallback to dump both files to result file and inform about installing "diff" */ - dynstr_append(&ds_tmp, "\n"); - dynstr_append(&ds_tmp, + char message[]= +"\n" "\n" "The two files differ but it was not possible to execute 'diff' in\n" "order to show only the difference. Instead the whole content of the\n" @@ -2028,17 +2031,18 @@ void show_diff(DYNAMIC_STRING* ds, #ifdef _WIN32 "or http://gnuwin32.sourceforge.net/packages/diffutils.htm\n" #endif -"\n"); +"\n"; + dynstr_append_mem(&ds_tmp, message, sizeof(message)); - dynstr_append(&ds_tmp, " --- "); + dynstr_append_mem(&ds_tmp, STRING_WITH_LEN(" --- ")); dynstr_append(&ds_tmp, filename1); - dynstr_append(&ds_tmp, " >>>\n"); + dynstr_append_mem(&ds_tmp, STRING_WITH_LEN(" >>>\n")); cat_file(&ds_tmp, filename1); - dynstr_append(&ds_tmp, "<<<\n --- "); + dynstr_append_mem(&ds_tmp, STRING_WITH_LEN("<<<\n --- ")); dynstr_append(&ds_tmp, filename1); - dynstr_append(&ds_tmp, " >>>\n"); + dynstr_append_mem(&ds_tmp, STRING_WITH_LEN(" >>>\n")); cat_file(&ds_tmp, filename2); - dynstr_append(&ds_tmp, "<<<<\n"); + dynstr_append_mem(&ds_tmp, STRING_WITH_LEN("<<<<\n")); } if (ds) @@ -2818,9 +2822,9 @@ do_result_format_version(struct st_command *command) set_result_format_version(version); - dynstr_append(&ds_res, "result_format: "); + dynstr_append_mem(&ds_res, STRING_WITH_LEN("result_format: ")); dynstr_append_mem(&ds_res, ds_version.str, ds_version.length); - dynstr_append(&ds_res, "\n"); + dynstr_append_mem(&ds_res, STRING_WITH_LEN("\n")); dynstr_free(&ds_version); } @@ -3371,7 +3375,7 @@ void do_exec(struct st_command *command) if (disable_result_log) { /* Collect stderr output as well, for the case app. crashes or returns error.*/ - dynstr_append(&ds_cmd, " 2>&1"); + dynstr_append_mem(&ds_cmd, STRING_WITH_LEN(" 2>&1")); } DBUG_PRINT("info", ("Executing '%s' as '%s'", @@ -3573,9 +3577,9 @@ void do_system(struct st_command *command) else { /* If ! abort_on_error, log message and continue */ - dynstr_append(&ds_res, "system command '"); + dynstr_append_mem(&ds_res, STRING_WITH_LEN("system command '")); replace_dynstr_append(&ds_res, command->first_argument); - dynstr_append(&ds_res, "' failed\n"); + dynstr_append_mem(&ds_res, STRING_WITH_LEN("' failed\n")); } } @@ -4042,7 +4046,7 @@ static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname, wild_compare(file->name, ds_wild->str, 0)) continue; replace_dynstr_append(ds, file->name); - dynstr_append(ds, "\n"); + dynstr_append_mem(ds, STRING_WITH_LEN("\n")); } set_wild_chars(0); my_dirend(dir_info); @@ -7729,9 +7733,10 @@ void append_metadata(DYNAMIC_STRING *ds, uint num_fields) { MYSQL_FIELD *field_end; - dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t" - "Column_alias\tType\tLength\tMax length\tIs_null\t" - "Flags\tDecimals\tCharsetnr\n"); + dynstr_append_mem(ds, STRING_WITH_LEN( + "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 ; @@ -7794,9 +7799,9 @@ void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows, dynstr_append(ds, buf); if (info) { - dynstr_append(ds, "info: "); + dynstr_append_mem(ds, STRING_WITH_LEN("info: ")); dynstr_append(ds, info); - dynstr_append_mem(ds, "\n", 1); + dynstr_append_mem(ds, STRING_WITH_LEN("\n")); } } @@ -7842,7 +7847,7 @@ static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) (enum_session_state_type) type, &data, &data_length)) { - dynstr_append(ds, "-- "); + dynstr_append_mem(ds, STRING_WITH_LEN("-- ")); if (type <= SESSION_TRACK_END) { dynstr_append(ds, trking_info_desc[type]); @@ -7850,10 +7855,10 @@ static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) else { DBUG_ASSERT(0); - dynstr_append(ds, "Tracker???\n"); + dynstr_append_mem(ds, STRING_WITH_LEN("Tracker???\n")); } - dynstr_append(ds, "-- "); + dynstr_append_mem(ds, STRING_WITH_LEN("-- ")); dynstr_append_mem(ds, data, data_length); } else @@ -7862,16 +7867,16 @@ static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) (enum_session_state_type) type, &data, &data_length)) { - dynstr_append(ds, "\n-- "); + dynstr_append_mem(ds, STRING_WITH_LEN("\n-- ")); if (data == NULL) { DBUG_ASSERT(data_length == 0); - dynstr_append_mem(ds, "", sizeof("") - 1); + dynstr_append_mem(ds, STRING_WITH_LEN("")); } else dynstr_append_mem(ds, data, data_length); } - dynstr_append(ds, "\n\n"); + dynstr_append_mem(ds, STRING_WITH_LEN("\n\n")); } #endif /* EMBEDDED_LIBRARY */ } @@ -8271,7 +8276,8 @@ void handle_error(struct st_command *command, else if (command->expected_errors.err[0].type == ERR_SQLSTATE || (command->expected_errors.err[0].type == ERR_ERRNO && command->expected_errors.err[0].code.errnum != 0)) - dynstr_append(ds,"Got one of the listed errors\n"); + dynstr_append_mem(ds, STRING_WITH_LEN("Got one of the listed " + "errors\n")); } /* OK */ revert_properties(); @@ -8350,6 +8356,85 @@ void handle_no_error(struct st_command *command) } +/* + Read result set after prepare statement execution + + SYNOPSIS + read_stmt_results + stmt - prepare statemet + mysql - mysql handle + command - current command pointer + ds - output buffer where to store result form query + + RETURN VALUE + 1 - if there is an error in result set +*/ + +int read_stmt_results(MYSQL_STMT* stmt, + DYNAMIC_STRING* ds, + struct st_command *command) +{ + MYSQL_RES *res= NULL; + + /* + We instruct that we want to update the "max_length" field in + mysql_stmt_store_result(), this is our only way to know how much + buffer to allocate for result data + */ + { + my_bool one= 1; + if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one)) + die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s", + mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + } + + /* + If we got here the statement succeeded and was expected to do so, + get data. Note that this can still give errors found during execution! + Store the result of the query if if will return any fields + */ + if (mysql_stmt_field_count(stmt) && mysql_stmt_store_result(stmt)) + { + handle_error(command, mysql_stmt_errno(stmt), + mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); + return 1; + } + + if (!disable_result_log) + { + /* + Not all statements creates a result set. If there is one we can + now create another normal result set that contains the meta + data. This set can be handled almost like any other non prepared + statement result set. + */ + if ((res= mysql_stmt_result_metadata(stmt)) != NULL) + { + /* Take the column count from meta info */ + MYSQL_FIELD *fields= mysql_fetch_fields(res); + uint num_fields= mysql_num_fields(res); + + if (display_metadata) + append_metadata(ds, fields, num_fields); + + if (!display_result_vertically) + append_table_headings(ds, fields, num_fields); + + append_stmt_result(ds, stmt, fields, num_fields); + + mysql_free_result(res); /* Free normal result set with meta data */ + + } + else + { + /* + This is a query without resultset + */ + } + } + return 0; +} + /* Run query using prepared statement C API @@ -8370,11 +8455,17 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, DYNAMIC_STRING *ds_warnings) { my_bool ignore_second_execution= 0; - MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */ MYSQL *mysql= cn->mysql; MYSQL_STMT *stmt; DYNAMIC_STRING ds_prepare_warnings; DYNAMIC_STRING ds_execute_warnings; + DYNAMIC_STRING ds_res_1st_execution; + DYNAMIC_STRING ds_res_2_execution_unsorted; + DYNAMIC_STRING *ds_res_2_output; + my_bool ds_res_1st_execution_init = FALSE; + my_bool compare_2nd_execution = TRUE; + int query_match_ps2_re; + DBUG_ENTER("run_query_stmt"); DBUG_PRINT("query", ("'%-.60s'", query)); DBUG_PRINT("info", @@ -8390,7 +8481,7 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, /* Init a new stmt if it's not already one created for this connection */ - if(!(stmt= cn->stmt)) + if (!(stmt= cn->stmt)) { if (!(stmt= mysql_stmt_init(mysql))) die("unable to init stmt structure"); @@ -8404,6 +8495,12 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, init_dynamic_string(&ds_execute_warnings, NULL, 0, 256); } + /* Check and remove potential trash */ + if (strlen(ds->str) != 0) + { + dynstr_trunc(ds, 0); + } + /* Prepare the query */ @@ -8439,10 +8536,12 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, } #endif + query_match_ps2_re = match_re(&ps2_re, query); + /* Execute the query first time if second execution enable */ - if(ps2_protocol_enabled && match_re(&ps2_re, query)) + if (ps2_protocol_enabled && query_match_ps2_re) { if (do_stmt_execute(cn)) { @@ -8450,12 +8549,32 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); goto end; } + /* We cannot run query twice if we get prepare warnings as these will otherwise be disabled */ ignore_second_execution= (prepare_warnings_enabled && mysql_warning_count(mysql) != 0); + + if (ignore_second_execution) + compare_2nd_execution = 0; + else + { + init_dynamic_string(&ds_res_1st_execution, "", + RESULT_STRING_INIT_MEM, RESULT_STRING_INCREMENT_MEM); + ds_res_1st_execution_init = TRUE; + if (read_stmt_results(stmt, &ds_res_1st_execution, command)) + { + /* + There was an error during execution + and there is no result set to compare + */ + compare_2nd_execution = 0; + } + else + handle_no_error(command); + } } /* @@ -8468,6 +8587,8 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, goto end; } + DBUG_ASSERT(ds->length == 0); + int err; do { @@ -8478,75 +8599,82 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, if (cursor_protocol_enabled && !disable_warnings) append_warnings(&ds_execute_warnings, mysql); - /* - We instruct that we want to update the "max_length" field in - mysql_stmt_store_result(), this is our only way to know how much - buffer to allocate for result data - */ + if (!disable_result_log && + compare_2nd_execution && + ps2_protocol_enabled && + query_match_ps2_re && + display_result_sorted) { - my_bool one= 1; - if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one)) - die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s", - mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + init_dynamic_string(&ds_res_2_execution_unsorted, "", + RESULT_STRING_INIT_MEM, + RESULT_STRING_INCREMENT_MEM); + ds_res_2_output= &ds_res_2_execution_unsorted; } + else + ds_res_2_output= ds; - /* - If we got here the statement succeeded and was expected to do so, - get data. Note that this can still give errors found during execution! - Store the result of the query if if will return any fields - */ - if (mysql_stmt_field_count(stmt) && mysql_stmt_store_result(stmt)) + if (read_stmt_results(stmt, ds_res_2_output, command)) { - handle_error(command, mysql_stmt_errno(stmt), - mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); - goto end; + if (ds_res_2_output != ds) + { + dynstr_append_mem(ds, ds_res_2_output->str, ds_res_2_output->length); + dynstr_free(ds_res_2_output); + } + goto end; } if (!disable_result_log) { /* - Not all statements creates a result set. If there is one we can - now create another normal result set that contains the meta - data. This set can be handled almost like any other non prepared - statement result set. + The results of the first and second execution are compared + only if result logging is enabled */ - if ((res= mysql_stmt_result_metadata(stmt)) != NULL) + if (compare_2nd_execution && ps2_protocol_enabled && query_match_ps2_re) { - /* Take the column count from meta info */ - MYSQL_FIELD *fields= mysql_fetch_fields(res); - uint num_fields= mysql_num_fields(res); - - if (display_metadata) - append_metadata(ds, fields, num_fields); - - if (!display_result_vertically) - append_table_headings(ds, fields, num_fields); - - append_stmt_result(ds, stmt, fields, num_fields); - - mysql_free_result(res); /* Free normal result set with meta data */ - - /* - Normally, if there is a result set, we do not show warnings from the - prepare phase. This is because some warnings are generated both during - prepare and execute; this would generate different warning output - between normal and ps-protocol test runs. - - The --enable_prepare_warnings command can be used to change this so - that warnings from both the prepare and execute phase are shown. - */ - if (!disable_warnings && !prepare_warnings_enabled) + DYNAMIC_STRING *ds_res_1_execution_compare; + DYNAMIC_STRING ds_res_1_execution_sorted; + if (display_result_sorted) { - DBUG_PRINT("info", ("warnings disabled")); - dynstr_set(&ds_prepare_warnings, NULL); + init_dynamic_string(&ds_res_1_execution_sorted, "", + RESULT_STRING_INIT_MEM, + RESULT_STRING_INCREMENT_MEM); + dynstr_append_sorted(&ds_res_1_execution_sorted, + &ds_res_1st_execution, 1); + dynstr_append_sorted(ds, &ds_res_2_execution_unsorted, 1); + ds_res_1_execution_compare= &ds_res_1_execution_sorted; + } + else + { + ds_res_1_execution_compare= &ds_res_1st_execution; + } + if (ds->length != ds_res_1_execution_compare->length || + !(memcmp(ds_res_1_execution_compare->str, ds->str, ds->length) == 0)) + { + die("The result of the 1st execution does not match with \n" + "the result of the 2nd execution of ps-protocol:\n 1st:\n" + "%s\n 2nd:\n %s", + ds_res_1_execution_compare->str, + ds->str); + } + if (display_result_sorted) + { + dynstr_free(&ds_res_1_execution_sorted); + dynstr_free(&ds_res_2_execution_unsorted); } } - else - { - /* - This is a query without resultset - */ - } + + /* + Normally, if there is a result set, we do not show warnings from the + prepare phase. This is because some warnings are generated both during + prepare and execute; this would generate different warning output + between normal and ps-protocol test runs. + The --enable_prepare_warnings command can be used to change this so + that warnings from both the prepare and execute phase are shown. + */ + if ((mysql_stmt_result_metadata(stmt) != NULL) && + !disable_warnings && + !prepare_warnings_enabled) + dynstr_set(&ds_prepare_warnings, NULL); /* Fetch info before fetching warnings, since it will be reset @@ -8558,7 +8686,6 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, if (display_session_track_info) append_session_track_info(ds, mysql); - if (!disable_warnings && !mysql_more_results(stmt->mysql)) { /* Get the warnings from execute */ @@ -8590,7 +8717,15 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, mysql_sqlstate(mysql), ds); else handle_no_error(command); + end: + + if (ds_res_1st_execution_init) + { + dynstr_free(&ds_res_1st_execution); + ds_res_1st_execution_init= FALSE; + } + if (!disable_warnings) { dynstr_free(&ds_prepare_warnings); @@ -9101,11 +9236,14 @@ int util_query(MYSQL* org_mysql, const char* query){ void run_query(struct st_connection *cn, struct st_command *command, int flags) { MYSQL *mysql= cn->mysql; - DYNAMIC_STRING *ds; - DYNAMIC_STRING *save_ds= NULL; - DYNAMIC_STRING ds_result; - DYNAMIC_STRING ds_sorted; - DYNAMIC_STRING ds_warnings; + DYNAMIC_STRING *rs_output; /* where to put results */ + DYNAMIC_STRING rs_cmp_result; /* here we put results to compare with + pre-recrded file */ + DYNAMIC_STRING rs_unsorted; /* if we need sorted results, here we store + results before sorting them */ + DYNAMIC_STRING *rs_sorted_save= NULL; /* here we store where to put sorted + result if needed */ + DYNAMIC_STRING rs_warnings; char *query; size_t query_len; my_bool view_created= 0, sp_created= 0; @@ -9118,10 +9256,10 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) if (!(flags & QUERY_SEND_FLAG) && !cn->pending) die("Cannot reap on a connection without pending send"); - - init_dynamic_string(&ds_warnings, NULL, 0, 256); - ds_warn= &ds_warnings; - + + init_dynamic_string(&rs_warnings, NULL, 0, 256); + ds_warn= &rs_warnings; + /* Evaluate query if this is an eval command */ @@ -9151,11 +9289,11 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) */ if (command->require_file) { - init_dynamic_string(&ds_result, "", 1024, 1024); - ds= &ds_result; + init_dynamic_string(&rs_cmp_result, "", 1024, 1024); + rs_output= &rs_cmp_result; } else - ds= &ds_res; + rs_output= &ds_res; // will be shown to colsole /* Log the query into the output buffer @@ -9169,9 +9307,9 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) print_query= command->query; print_len= (int)(command->end - command->query); } - replace_dynstr_append_mem(ds, print_query, print_len); - dynstr_append_mem(ds, delimiter, delimiter_length); - dynstr_append_mem(ds, "\n", 1); + replace_dynstr_append_mem(rs_output, print_query, print_len); + dynstr_append_mem(rs_output, delimiter, delimiter_length); + dynstr_append_mem(rs_output, "\n", 1); } /* We're done with this flag */ @@ -9226,7 +9364,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) Collect warnings from create of the view that should otherwise have been produced when the SELECT was executed */ - append_warnings(&ds_warnings, + append_warnings(&rs_warnings, service_connection_enabled ? cur_con->util_mysql : mysql); @@ -9282,9 +9420,9 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) that can be sorted before it's added to the global result string */ - init_dynamic_string(&ds_sorted, "", 1024, 1024); - save_ds= ds; /* Remember original ds */ - ds= &ds_sorted; + init_dynamic_string(&rs_unsorted, "", 1024, 1024); + rs_sorted_save= rs_output; /* Remember original ds */ + rs_output= &rs_unsorted; } /* @@ -9305,20 +9443,20 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) All other statements can be run using prepared statement C API. */ !match_re(&ps_re, query)) - run_query_stmt(cn, command, query, query_len, ds, &ds_warnings); + run_query_stmt(cn, command, query, query_len, rs_output, &rs_warnings); else run_query_normal(cn, command, flags, query, query_len, - ds, &ds_warnings); + rs_output, &rs_warnings); - dynstr_free(&ds_warnings); + dynstr_free(&rs_warnings); ds_warn= 0; if (display_result_sorted) { /* Sort the result set and append it to result */ - dynstr_append_sorted(save_ds, &ds_sorted, 1); - ds= save_ds; - dynstr_free(&ds_sorted); + dynstr_append_sorted(rs_sorted_save, &rs_unsorted, 1); + rs_output= rs_sorted_save; + dynstr_free(&rs_unsorted); } if (sp_created) @@ -9341,11 +9479,11 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) and the output should be checked against an already existing file which has been specified using --require or --result */ - check_require(ds, command->require_file); + check_require(rs_output, command->require_file); } - if (ds == &ds_result) - dynstr_free(&ds_result); + if (rs_output == &rs_cmp_result) + dynstr_free(&rs_cmp_result); DBUG_VOID_RETURN; } @@ -9802,7 +9940,7 @@ int main(int argc, char **argv) read_command_buf= (char*)my_malloc(PSI_NOT_INSTRUMENTED, read_command_buflen= 65536, MYF(MY_FAE)); - init_dynamic_string(&ds_res, "", 2048, 2048); + init_dynamic_string(&ds_res, "", RESULT_STRING_INIT_MEM, RESULT_STRING_INCREMENT_MEM); init_alloc_root(PSI_NOT_INSTRUMENTED, &require_file_root, 1024, 1024, MYF(0)); parse_args(argc, argv); @@ -10233,7 +10371,7 @@ int main(int argc, char **argv) if (p && *p == '#' && *(p+1) == '#') { dynstr_append_mem(&ds_res, command->query, command->query_len); - dynstr_append(&ds_res, "\n"); + dynstr_append_mem(&ds_res, STRING_WITH_LEN("\n")); } break; } @@ -10246,7 +10384,7 @@ int main(int argc, char **argv) if (disable_query_log) break; - dynstr_append(&ds_res, "\n"); + dynstr_append_mem(&ds_res, STRING_WITH_LEN("\n")); break; case Q_PING: handle_command_error(command, mysql_ping(cur_con->mysql), -1); @@ -11909,7 +12047,7 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, { const char **line= dynamic_element(&lines, i, const char**); dynstr_append(ds, *line); - dynstr_append(ds, "\n"); + dynstr_append_mem(ds, STRING_WITH_LEN("\n")); } delete_dynamic(&lines); diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake index a55c27b4d4c..9f1534a72e4 100644 --- a/cmake/mysql_version.cmake +++ b/cmake/mysql_version.cmake @@ -90,7 +90,7 @@ IF(NOT CPACK_PACKAGE_FILE_NAME) ENDIF() SET_IF_UNSET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-${VERSION}") -SET_IF_UNSET(CPACK_PACKAGE_CONTACT "MariaDB Developers ") +SET_IF_UNSET(CPACK_PACKAGE_CONTACT "MariaDB Developers ") SET_IF_UNSET(CPACK_PACKAGE_VENDOR "MariaDB Foundation") SET_IF_UNSET(CPACK_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY} diff --git a/debian/control b/debian/control index 91d8b0ce48d..7ba4d82e9e1 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: mariadb-10.6 Section: database Priority: optional -Maintainer: MariaDB Developers +Maintainer: MariaDB Developers Build-Depends: bison, cmake, cracklib-runtime , diff --git a/debian/copyright b/debian/copyright index 836fe89f4c3..a35a25dcdbe 100644 --- a/debian/copyright +++ b/debian/copyright @@ -2,12 +2,11 @@ == MariaDB == The Debian package of MySQL was first debianzed on 1997-04-12 by Christian -Schwarz and ist maintained since 1999-04-20 by +Schwarz and is maintained since 1999-04-20 by Christian Hammers . The MariaDB packages were initially made by http://ourdelta.org/, and -are now managed by the MariaDB development team, -maria-developers@lists.launchpad.net +are now managed by the MariaDB development team, developers@lists.mariadb.org MariaDB can be downloaded from https://downloads.mariadb.org/ diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index ef63f914343..3bc9f68225a 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -126,7 +126,8 @@ int sd_notifyf() { return 0; } int sys_var_init(); /* === xtrabackup specific options === */ -char xtrabackup_real_target_dir[FN_REFLEN] = "./xtrabackup_backupfiles/"; +#define DEFAULT_TARGET_DIR "./xtrabackup_backupfiles/" +char xtrabackup_real_target_dir[FN_REFLEN] = DEFAULT_TARGET_DIR; char *xtrabackup_target_dir= xtrabackup_real_target_dir; static my_bool xtrabackup_version; static my_bool verbose; @@ -411,6 +412,9 @@ uint opt_safe_slave_backup_timeout = 0; const char *opt_history = NULL; +/* Whether xtrabackup_binlog_info should be created on recovery */ +static bool recover_binlog_info; + char mariabackup_exe[FN_REFLEN]; char orig_argv1[FN_REFLEN]; @@ -1268,22 +1272,25 @@ struct my_option xb_client_options[]= { {"compress", OPT_XTRA_COMPRESS, "Compress individual backup files using the " - "specified compression algorithm. Currently the only supported algorithm " - "is 'quicklz'. It is also the default algorithm, i.e. the one used when " - "--compress is used without an argument.", + "specified compression algorithm. It uses no longer maintained QuickLZ " + "library hence this option was deprecated with MariaDB 10.1.31 and 10.2.13.", (G_PTR *) &xtrabackup_compress_alg, (G_PTR *) &xtrabackup_compress_alg, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"compress-threads", OPT_XTRA_COMPRESS_THREADS, "Number of threads for parallel data compression. The default value is " - "1.", + "1. " + "This option was deprecated as it relies on the no longer " + "maintained QuickLZ library.", (G_PTR *) &xtrabackup_compress_threads, (G_PTR *) &xtrabackup_compress_threads, 0, GET_UINT, REQUIRED_ARG, 1, 1, UINT_MAX, 0, 0, 0}, {"compress-chunk-size", OPT_XTRA_COMPRESS_CHUNK_SIZE, "Size of working buffer(s) for compression threads in bytes. The default " - "value is 64K.", + "value is 64K. " + "This option was deprecated as it relies on the no longer " + "maintained QuickLZ library.", (G_PTR *) &xtrabackup_compress_chunk_size, (G_PTR *) &xtrabackup_compress_chunk_size, 0, GET_ULL, REQUIRED_ARG, (1 << 16), 1024, ULONGLONG_MAX, 0, 0, 0}, @@ -1404,7 +1411,9 @@ struct my_option xb_client_options[]= { {"decompress", OPT_DECOMPRESS, "Decompresses all files with the .qp " - "extension in a backup previously made with the --compress option.", + "extension in a backup previously made with the --compress option. " + "This option was deprecated as it relies on the no longer " + "maintained QuickLZ library.", (uchar *) &opt_decompress, (uchar *) &opt_decompress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -2380,6 +2389,7 @@ xtrabackup_read_metadata(char *filename) { FILE *fp; my_bool r = TRUE; + int t; fp = fopen(filename,"r"); if(!fp) { @@ -2410,6 +2420,9 @@ xtrabackup_read_metadata(char *filename) } /* Optional fields */ + if (fscanf(fp, "recover_binlog_info = %d\n", &t) == 1) { + recover_binlog_info = (t == 1); + } end: fclose(fp); @@ -2428,11 +2441,13 @@ xtrabackup_print_metadata(char *buf, size_t buf_len) "backup_type = %s\n" "from_lsn = " UINT64PF "\n" "to_lsn = " UINT64PF "\n" - "last_lsn = " UINT64PF "\n", + "last_lsn = " UINT64PF "\n" + "recover_binlog_info = %d\n", metadata_type, metadata_from_lsn, metadata_to_lsn, - metadata_last_lsn); + metadata_last_lsn, + MY_TEST(opt_binlog_info == BINLOG_INFO_LOCKLESS)); } /*********************************************************************** @@ -6053,6 +6068,26 @@ static ibool prepare_handle_del_files(const char *datadir, const char *db, const return TRUE; } + +/************************************************************************** +Store the current binary log coordinates in a specified file. +@return 'false' on error. */ +static bool +store_binlog_info(const char *filename, const char* name, ulonglong pos) +{ + FILE *fp = fopen(filename, "w"); + + if (!fp) { + msg("mariabackup: failed to open '%s'\n", filename); + return(false); + } + + fprintf(fp, "%s\t%llu\n", name, pos); + fclose(fp); + + return(true); +} + /** Implement --prepare @return whether the operation succeeded */ static bool xtrabackup_prepare_func(char** argv) @@ -6242,6 +6277,20 @@ static bool xtrabackup_prepare_func(char** argv) msg("Last binlog file %s, position %lld", trx_sys.recovered_binlog_filename, longlong(trx_sys.recovered_binlog_offset)); + + /* output to xtrabackup_binlog_pos_innodb and (if + backup_safe_binlog_info was available on the server) to + xtrabackup_binlog_info. In the latter case + xtrabackup_binlog_pos_innodb becomes redundant and is created + only for compatibility. */ + ok = store_binlog_info( + "xtrabackup_binlog_pos_innodb", + trx_sys.recovered_binlog_filename, + trx_sys.recovered_binlog_offset) + && (!recover_binlog_info || store_binlog_info( + XTRABACKUP_BINLOG_INFO, + trx_sys.recovered_binlog_filename, + trx_sys.recovered_binlog_offset)); } /* Check whether the log is applied enough or not. */ @@ -6444,7 +6493,7 @@ static bool check_all_privileges() } /* KILL ... */ - if (!opt_no_lock && (opt_kill_long_queries_timeout || opt_kill_long_query_type)) { + if (!opt_no_lock && opt_kill_long_queries_timeout) { check_result |= check_privilege( granted_privileges, "CONNECTION ADMIN", "*", "*", @@ -6465,7 +6514,7 @@ static bool check_all_privileges() if (opt_galera_info || opt_slave_info || opt_safe_slave_backup) { check_result |= check_privilege(granted_privileges, - "SLAVE MONITOR", "*", "*", + "REPLICA MONITOR", "*", "*", PRIVILEGE_WARNING); } @@ -6673,9 +6722,10 @@ void handle_options(int argc, char **argv, char ***argv_server, server_default_groups.push_back(NULL); snprintf(conf_file, sizeof(conf_file), "my"); - if (prepare && target_dir) { + if (prepare) { snprintf(conf_file, sizeof(conf_file), - "%s/backup-my.cnf", target_dir); + "%s/backup-my.cnf", target_dir ? target_dir: + DEFAULT_TARGET_DIR); if (!strncmp(argv[1], "--defaults-file=", 16)) { /* Remove defaults-file*/ for (int i = 2; ; i++) { diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h index f4873d5865a..a7c36b415bb 100644 --- a/extra/mariabackup/xtrabackup.h +++ b/extra/mariabackup/xtrabackup.h @@ -173,7 +173,7 @@ extern uint opt_safe_slave_backup_timeout; extern const char *opt_history; -enum binlog_info_enum { BINLOG_INFO_OFF, BINLOG_INFO_ON, +enum binlog_info_enum { BINLOG_INFO_OFF, BINLOG_INFO_LOCKLESS, BINLOG_INFO_ON, BINLOG_INFO_AUTO}; extern ulong opt_binlog_info; diff --git a/include/byte_order_generic_x86_64.h b/include/byte_order_generic_x86_64.h index a25e6a2ab08..305ba2b430e 100644 --- a/include/byte_order_generic_x86_64.h +++ b/include/byte_order_generic_x86_64.h @@ -83,7 +83,7 @@ static inline ulonglong uint6korr(const void *p) #define HAVE_mi_uint5korr #define HAVE_mi_uint6korr #define HAVE_mi_uint7korr -#define HAVE_mi_uint78orr +#define HAVE_mi_uint8korr /* Read numbers stored in high-bytes-first order */ diff --git a/include/m_ctype.h b/include/m_ctype.h index d5a274367a8..0ec6a1ba507 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -345,7 +345,8 @@ enum my_lex_states MY_LEX_IDENT_OR_KEYWORD, MY_LEX_IDENT_OR_HEX, MY_LEX_IDENT_OR_BIN, MY_LEX_IDENT_OR_NCHAR, MY_LEX_STRING_OR_DELIMITER, MY_LEX_MINUS_OR_COMMENT, MY_LEX_PLACEHOLDER, - MY_LEX_COMMA + MY_LEX_COMMA, + MY_LEX_IDENT_OR_QUALIFIED_SPECIAL_FUNC }; struct charset_info_st; diff --git a/include/mariadb_capi_rename.h b/include/mariadb_capi_rename.h index 616a9142fe6..58e16fdc0c0 100644 --- a/include/mariadb_capi_rename.h +++ b/include/mariadb_capi_rename.h @@ -22,7 +22,7 @@ #ifndef MARIADB_CAPI_RENAME_INCLUDED #define MARIADB_CAPI_RENAME_INCLUDED -#if !defined(EMBEDDED_LIBRARY) +#if !defined(EMBEDDED_LIBRARY) && !defined(MYSQL_DYNAMIC_PLUGIN) #define MARIADB_ADD_PREFIX(_SYMBOL) server_##_SYMBOL #define mysql_real_connect MARIADB_ADD_PREFIX(mysql_real_connect) diff --git a/include/my_alloc.h b/include/my_alloc.h index 3da3a56a8fb..c3d619757d8 100644 --- a/include/my_alloc.h +++ b/include/my_alloc.h @@ -20,11 +20,13 @@ #ifndef _my_alloc_h #define _my_alloc_h -#include +#include "mysql/psi/psi_base.h" #define ALLOC_MAX_BLOCK_TO_DROP 4096 #define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10 +#define ROOT_FLAG_READ_ONLY 4 + #ifdef __cplusplus extern "C" { #endif @@ -50,11 +52,8 @@ typedef struct st_mem_root first free block in queue test counter (if it exceed MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list) */ - unsigned int first_block_usage; - -#ifdef PROTECT_STATEMENT_MEMROOT - int read_only; -#endif + unsigned short first_block_usage; + unsigned short flags; void (*error_handler)(void); diff --git a/include/my_pthread.h b/include/my_pthread.h index 3e68538b424..380fa70e4ee 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -667,15 +667,19 @@ extern void my_mutex_end(void); We need to have at least 256K stack to handle calls to myisamchk_init() with the current number of keys and key parts. */ -#if defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN) -#ifndef DBUG_OFF -#define DEFAULT_THREAD_STACK (1024*1024L) -#else -#define DEFAULT_THREAD_STACK (383*1024L) /* 392192 */ -#endif -#else -#define DEFAULT_THREAD_STACK (292*1024L) /* 299008 */ -#endif +# if defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN) +/* + Optimized WITH_ASAN=ON executables produced + by GCC 12.3.0, GCC 13.2.0, or clang 16.0.6 + would fail ./mtr main.1st when the stack size is 5 MiB. + The minimum is more than 6 MiB for CMAKE_BUILD_TYPE=RelWithDebInfo and + more than 8 MiB for CMAKE_BUILD_TYPE=Debug. + Let us add some safety margin. +*/ +# define DEFAULT_THREAD_STACK (10L<<20) +# else +# define DEFAULT_THREAD_STACK (292*1024L) /* 299008 */ +# endif #endif #define MY_PTHREAD_LOCK_READ 0 diff --git a/include/my_sys.h b/include/my_sys.h index 4e4dc5c6c3f..da336bdf8c9 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -883,6 +883,7 @@ extern void init_alloc_root(PSI_memory_key key, MEM_ROOT *mem_root, extern void *alloc_root(MEM_ROOT *mem_root, size_t Size); extern void *multi_alloc_root(MEM_ROOT *mem_root, ...); extern void free_root(MEM_ROOT *root, myf MyFLAGS); +extern void move_root(MEM_ROOT *to, MEM_ROOT *from); extern void set_prealloc_root(MEM_ROOT *root, char *ptr); extern void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, size_t prealloc_size); diff --git a/include/myisamchk.h b/include/myisamchk.h index c494c672ec7..85f7c0a56f7 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -112,6 +112,7 @@ typedef struct st_handler_check_param uint progress_counter; /* How often to call _report_progress() */ ulonglong progress, max_progress; + void (*init_fix_record)(void *); int (*fix_record)(struct st_myisam_info *info, uchar *record, int keynum); mysql_mutex_t print_msg_mutex; diff --git a/include/mysql.h b/include/mysql.h index ec8458cba32..de91517ad02 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -267,7 +267,6 @@ typedef struct st_mysql char *host,*user,*passwd,*unix_socket,*server_version,*host_info; char *info, *db; const struct charset_info_st *charset; - MYSQL_FIELD *fields; MEM_ROOT field_alloc; my_ulonglong affected_rows; my_ulonglong insert_id; /* id if insert on table with NEXTNR */ @@ -289,7 +288,8 @@ typedef struct st_mysql /* session-wide random string */ char scramble[SCRAMBLE_LENGTH+1]; my_bool auto_local_infile; - void *unused2, *unused3, *unused4, *unused5; + void *unused2, *unused3, *unused4; + MYSQL_FIELD *fields; LIST *stmts; /* list of all statements */ const struct st_mysql_methods *methods; @@ -324,7 +324,7 @@ typedef struct st_mysql_res { } MYSQL_RES; -#if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT) +#if !defined(MYSQL_SERVICE_SQL) && !defined(MYSQL_CLIENT) #define MYSQL_CLIENT #endif @@ -356,7 +356,7 @@ typedef struct st_mysql_parameters */ #define MYSQL_WAIT_TIMEOUT 8 -#if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) +#if !defined(MYSQL_SERVICE_SQL) #define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet) #define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length) #endif diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 26799e9031a..57ba61d3911 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -464,6 +464,35 @@ int json_escape_string(const char *str,const char *str_end, int json_unescape_json(const char *json_str, const char *json_end, char *res, char *res_end); } +extern "C" { +extern struct sql_service_st { + MYSQL *(STDCALL *mysql_init_func)(MYSQL *mysql); + MYSQL *(*mysql_real_connect_local_func)(MYSQL *mysql); + MYSQL *(STDCALL *mysql_real_connect_func)(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, unsigned int port, + const char *unix_socket, unsigned long clientflag); + unsigned int(STDCALL *mysql_errno_func)(MYSQL *mysql); + const char *(STDCALL *mysql_error_func)(MYSQL *mysql); + int (STDCALL *mysql_real_query_func)(MYSQL *mysql, const char *q, + unsigned long length); + my_ulonglong (STDCALL *mysql_affected_rows_func)(MYSQL *mysql); + my_ulonglong (STDCALL *mysql_num_rows_func)(MYSQL_RES *res); + MYSQL_RES *(STDCALL *mysql_store_result_func)(MYSQL *mysql); + void (STDCALL *mysql_free_result_func)(MYSQL_RES *result); + MYSQL_ROW (STDCALL *mysql_fetch_row_func)(MYSQL_RES *result); + void (STDCALL *mysql_close_func)(MYSQL *mysql); + int (STDCALL *mysql_options_func)(MYSQL *mysql, enum mysql_option option, + const void *arg); + unsigned long *(STDCALL *mysql_fetch_lengths_func)(MYSQL_RES *res); + int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); + unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); + int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +} *sql_service; +MYSQL *mysql_real_connect_local(MYSQL *mysql); +} } struct st_mysql_xid { long formatID; diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 31b3f723fff..15e4c0cde4d 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -464,6 +464,35 @@ int json_escape_string(const char *str,const char *str_end, int json_unescape_json(const char *json_str, const char *json_end, char *res, char *res_end); } +extern "C" { +extern struct sql_service_st { + MYSQL *(STDCALL *mysql_init_func)(MYSQL *mysql); + MYSQL *(*mysql_real_connect_local_func)(MYSQL *mysql); + MYSQL *(STDCALL *mysql_real_connect_func)(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, unsigned int port, + const char *unix_socket, unsigned long clientflag); + unsigned int(STDCALL *mysql_errno_func)(MYSQL *mysql); + const char *(STDCALL *mysql_error_func)(MYSQL *mysql); + int (STDCALL *mysql_real_query_func)(MYSQL *mysql, const char *q, + unsigned long length); + my_ulonglong (STDCALL *mysql_affected_rows_func)(MYSQL *mysql); + my_ulonglong (STDCALL *mysql_num_rows_func)(MYSQL_RES *res); + MYSQL_RES *(STDCALL *mysql_store_result_func)(MYSQL *mysql); + void (STDCALL *mysql_free_result_func)(MYSQL_RES *result); + MYSQL_ROW (STDCALL *mysql_fetch_row_func)(MYSQL_RES *result); + void (STDCALL *mysql_close_func)(MYSQL *mysql); + int (STDCALL *mysql_options_func)(MYSQL *mysql, enum mysql_option option, + const void *arg); + unsigned long *(STDCALL *mysql_fetch_lengths_func)(MYSQL_RES *res); + int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); + unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); + int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +} *sql_service; +MYSQL *mysql_real_connect_local(MYSQL *mysql); +} } struct st_mysql_xid { long formatID; diff --git a/include/mysql/plugin_data_type.h.pp b/include/mysql/plugin_data_type.h.pp index 4716b0dc255..7938bf3c475 100644 --- a/include/mysql/plugin_data_type.h.pp +++ b/include/mysql/plugin_data_type.h.pp @@ -464,6 +464,35 @@ int json_escape_string(const char *str,const char *str_end, int json_unescape_json(const char *json_str, const char *json_end, char *res, char *res_end); } +extern "C" { +extern struct sql_service_st { + MYSQL *(STDCALL *mysql_init_func)(MYSQL *mysql); + MYSQL *(*mysql_real_connect_local_func)(MYSQL *mysql); + MYSQL *(STDCALL *mysql_real_connect_func)(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, unsigned int port, + const char *unix_socket, unsigned long clientflag); + unsigned int(STDCALL *mysql_errno_func)(MYSQL *mysql); + const char *(STDCALL *mysql_error_func)(MYSQL *mysql); + int (STDCALL *mysql_real_query_func)(MYSQL *mysql, const char *q, + unsigned long length); + my_ulonglong (STDCALL *mysql_affected_rows_func)(MYSQL *mysql); + my_ulonglong (STDCALL *mysql_num_rows_func)(MYSQL_RES *res); + MYSQL_RES *(STDCALL *mysql_store_result_func)(MYSQL *mysql); + void (STDCALL *mysql_free_result_func)(MYSQL_RES *result); + MYSQL_ROW (STDCALL *mysql_fetch_row_func)(MYSQL_RES *result); + void (STDCALL *mysql_close_func)(MYSQL *mysql); + int (STDCALL *mysql_options_func)(MYSQL *mysql, enum mysql_option option, + const void *arg); + unsigned long *(STDCALL *mysql_fetch_lengths_func)(MYSQL_RES *res); + int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); + unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); + int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +} *sql_service; +MYSQL *mysql_real_connect_local(MYSQL *mysql); +} } struct st_mysql_xid { long formatID; diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp index c29dc20efda..97191c4a09c 100644 --- a/include/mysql/plugin_encryption.h.pp +++ b/include/mysql/plugin_encryption.h.pp @@ -464,6 +464,35 @@ int json_escape_string(const char *str,const char *str_end, int json_unescape_json(const char *json_str, const char *json_end, char *res, char *res_end); } +extern "C" { +extern struct sql_service_st { + MYSQL *(STDCALL *mysql_init_func)(MYSQL *mysql); + MYSQL *(*mysql_real_connect_local_func)(MYSQL *mysql); + MYSQL *(STDCALL *mysql_real_connect_func)(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, unsigned int port, + const char *unix_socket, unsigned long clientflag); + unsigned int(STDCALL *mysql_errno_func)(MYSQL *mysql); + const char *(STDCALL *mysql_error_func)(MYSQL *mysql); + int (STDCALL *mysql_real_query_func)(MYSQL *mysql, const char *q, + unsigned long length); + my_ulonglong (STDCALL *mysql_affected_rows_func)(MYSQL *mysql); + my_ulonglong (STDCALL *mysql_num_rows_func)(MYSQL_RES *res); + MYSQL_RES *(STDCALL *mysql_store_result_func)(MYSQL *mysql); + void (STDCALL *mysql_free_result_func)(MYSQL_RES *result); + MYSQL_ROW (STDCALL *mysql_fetch_row_func)(MYSQL_RES *result); + void (STDCALL *mysql_close_func)(MYSQL *mysql); + int (STDCALL *mysql_options_func)(MYSQL *mysql, enum mysql_option option, + const void *arg); + unsigned long *(STDCALL *mysql_fetch_lengths_func)(MYSQL_RES *res); + int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); + unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); + int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +} *sql_service; +MYSQL *mysql_real_connect_local(MYSQL *mysql); +} } struct st_mysql_xid { long formatID; diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index be270d096f4..cc2c276c579 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -464,6 +464,35 @@ int json_escape_string(const char *str,const char *str_end, int json_unescape_json(const char *json_str, const char *json_end, char *res, char *res_end); } +extern "C" { +extern struct sql_service_st { + MYSQL *(STDCALL *mysql_init_func)(MYSQL *mysql); + MYSQL *(*mysql_real_connect_local_func)(MYSQL *mysql); + MYSQL *(STDCALL *mysql_real_connect_func)(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, unsigned int port, + const char *unix_socket, unsigned long clientflag); + unsigned int(STDCALL *mysql_errno_func)(MYSQL *mysql); + const char *(STDCALL *mysql_error_func)(MYSQL *mysql); + int (STDCALL *mysql_real_query_func)(MYSQL *mysql, const char *q, + unsigned long length); + my_ulonglong (STDCALL *mysql_affected_rows_func)(MYSQL *mysql); + my_ulonglong (STDCALL *mysql_num_rows_func)(MYSQL_RES *res); + MYSQL_RES *(STDCALL *mysql_store_result_func)(MYSQL *mysql); + void (STDCALL *mysql_free_result_func)(MYSQL_RES *result); + MYSQL_ROW (STDCALL *mysql_fetch_row_func)(MYSQL_RES *result); + void (STDCALL *mysql_close_func)(MYSQL *mysql); + int (STDCALL *mysql_options_func)(MYSQL *mysql, enum mysql_option option, + const void *arg); + unsigned long *(STDCALL *mysql_fetch_lengths_func)(MYSQL_RES *res); + int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); + unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); + int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +} *sql_service; +MYSQL *mysql_real_connect_local(MYSQL *mysql); +} } struct st_mysql_xid { long formatID; diff --git a/include/mysql/plugin_function.h.pp b/include/mysql/plugin_function.h.pp index 7a2d06918c9..afdcb5344e3 100644 --- a/include/mysql/plugin_function.h.pp +++ b/include/mysql/plugin_function.h.pp @@ -464,6 +464,35 @@ int json_escape_string(const char *str,const char *str_end, int json_unescape_json(const char *json_str, const char *json_end, char *res, char *res_end); } +extern "C" { +extern struct sql_service_st { + MYSQL *(STDCALL *mysql_init_func)(MYSQL *mysql); + MYSQL *(*mysql_real_connect_local_func)(MYSQL *mysql); + MYSQL *(STDCALL *mysql_real_connect_func)(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, unsigned int port, + const char *unix_socket, unsigned long clientflag); + unsigned int(STDCALL *mysql_errno_func)(MYSQL *mysql); + const char *(STDCALL *mysql_error_func)(MYSQL *mysql); + int (STDCALL *mysql_real_query_func)(MYSQL *mysql, const char *q, + unsigned long length); + my_ulonglong (STDCALL *mysql_affected_rows_func)(MYSQL *mysql); + my_ulonglong (STDCALL *mysql_num_rows_func)(MYSQL_RES *res); + MYSQL_RES *(STDCALL *mysql_store_result_func)(MYSQL *mysql); + void (STDCALL *mysql_free_result_func)(MYSQL_RES *result); + MYSQL_ROW (STDCALL *mysql_fetch_row_func)(MYSQL_RES *result); + void (STDCALL *mysql_close_func)(MYSQL *mysql); + int (STDCALL *mysql_options_func)(MYSQL *mysql, enum mysql_option option, + const void *arg); + unsigned long *(STDCALL *mysql_fetch_lengths_func)(MYSQL_RES *res); + int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); + unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); + int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +} *sql_service; +MYSQL *mysql_real_connect_local(MYSQL *mysql); +} } struct st_mysql_xid { long formatID; diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index 39218d737a2..6c8b6ec00cd 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -464,6 +464,35 @@ int json_escape_string(const char *str,const char *str_end, int json_unescape_json(const char *json_str, const char *json_end, char *res, char *res_end); } +extern "C" { +extern struct sql_service_st { + MYSQL *(STDCALL *mysql_init_func)(MYSQL *mysql); + MYSQL *(*mysql_real_connect_local_func)(MYSQL *mysql); + MYSQL *(STDCALL *mysql_real_connect_func)(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, unsigned int port, + const char *unix_socket, unsigned long clientflag); + unsigned int(STDCALL *mysql_errno_func)(MYSQL *mysql); + const char *(STDCALL *mysql_error_func)(MYSQL *mysql); + int (STDCALL *mysql_real_query_func)(MYSQL *mysql, const char *q, + unsigned long length); + my_ulonglong (STDCALL *mysql_affected_rows_func)(MYSQL *mysql); + my_ulonglong (STDCALL *mysql_num_rows_func)(MYSQL_RES *res); + MYSQL_RES *(STDCALL *mysql_store_result_func)(MYSQL *mysql); + void (STDCALL *mysql_free_result_func)(MYSQL_RES *result); + MYSQL_ROW (STDCALL *mysql_fetch_row_func)(MYSQL_RES *result); + void (STDCALL *mysql_close_func)(MYSQL *mysql); + int (STDCALL *mysql_options_func)(MYSQL *mysql, enum mysql_option option, + const void *arg); + unsigned long *(STDCALL *mysql_fetch_lengths_func)(MYSQL_RES *res); + int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); + unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); + int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +} *sql_service; +MYSQL *mysql_real_connect_local(MYSQL *mysql); +} } struct st_mysql_xid { long formatID; diff --git a/include/mysql/psi/psi_abi_v1.h.pp b/include/mysql/psi/psi_abi_v1.h.pp index 2dc27e09ca4..ca0d0206cb9 100644 --- a/include/mysql/psi/psi_abi_v1.h.pp +++ b/include/mysql/psi/psi_abi_v1.h.pp @@ -1,8 +1,8 @@ extern "C" { +typedef unsigned int PSI_memory_key; } extern "C" { struct PSI_thread; -typedef unsigned int PSI_memory_key; struct PSI_memory_info_v1 { PSI_memory_key *m_key; diff --git a/include/mysql/psi/psi_abi_v2.h.pp b/include/mysql/psi/psi_abi_v2.h.pp index a670e53a8b7..9188954885f 100644 --- a/include/mysql/psi/psi_abi_v2.h.pp +++ b/include/mysql/psi/psi_abi_v2.h.pp @@ -1,8 +1,8 @@ extern "C" { +typedef unsigned int PSI_memory_key; } extern "C" { struct PSI_thread; -typedef unsigned int PSI_memory_key; struct PSI_memory_info_v2 { int placeholder; diff --git a/include/mysql/psi/psi_base.h b/include/mysql/psi/psi_base.h index 618776b11cd..6cf531950f0 100644 --- a/include/mysql/psi/psi_base.h +++ b/include/mysql/psi/psi_base.h @@ -170,6 +170,13 @@ extern "C" { /** @} */ +/** + Instrumented memory key. + To instrument memory, a memory key must be obtained using @c register_memory. + Using a zero key always disable the instrumentation. +*/ +typedef unsigned int PSI_memory_key; + #ifdef __cplusplus } #endif diff --git a/include/mysql/psi/psi_memory.h b/include/mysql/psi/psi_memory.h index 80477a86371..f06ec525e08 100644 --- a/include/mysql/psi/psi_memory.h +++ b/include/mysql/psi/psi_memory.h @@ -53,13 +53,6 @@ extern "C" { struct PSI_thread; -/** - Instrumented memory key. - To instrument memory, a memory key must be obtained using @c register_memory. - Using a zero key always disable the instrumentation. -*/ -typedef unsigned int PSI_memory_key; - #ifdef HAVE_PSI_1 /** diff --git a/include/mysql/service_sql.h b/include/mysql/service_sql.h new file mode 100644 index 00000000000..0a3a2294fa1 --- /dev/null +++ b/include/mysql/service_sql.h @@ -0,0 +1,119 @@ +/* Copyright (C) 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 Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + +#ifndef MYSQL_SERVICE_SQL +#define MYSQL_SERVICE_SQL + +#ifndef MYSQL_ABI_CHECK +#include +#endif + +/** + @file + SQL service + + Interface for plugins to execute SQL queries on the local server. + + Functions of the service are the 'server-limited' client library: + mysql_init + mysql_real_connect_local + mysql_real_connect + mysql_errno + mysql_error + mysql_real_query + mysql_affected_rows + mysql_num_rows + mysql_store_result + mysql_free_result + mysql_fetch_row + mysql_close +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct sql_service_st { + MYSQL *(STDCALL *mysql_init_func)(MYSQL *mysql); + MYSQL *(*mysql_real_connect_local_func)(MYSQL *mysql); + MYSQL *(STDCALL *mysql_real_connect_func)(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, unsigned int port, + const char *unix_socket, unsigned long clientflag); + unsigned int(STDCALL *mysql_errno_func)(MYSQL *mysql); + const char *(STDCALL *mysql_error_func)(MYSQL *mysql); + int (STDCALL *mysql_real_query_func)(MYSQL *mysql, const char *q, + unsigned long length); + my_ulonglong (STDCALL *mysql_affected_rows_func)(MYSQL *mysql); + my_ulonglong (STDCALL *mysql_num_rows_func)(MYSQL_RES *res); + MYSQL_RES *(STDCALL *mysql_store_result_func)(MYSQL *mysql); + void (STDCALL *mysql_free_result_func)(MYSQL_RES *result); + MYSQL_ROW (STDCALL *mysql_fetch_row_func)(MYSQL_RES *result); + void (STDCALL *mysql_close_func)(MYSQL *mysql); + int (STDCALL *mysql_options_func)(MYSQL *mysql, enum mysql_option option, + const void *arg); + unsigned long *(STDCALL *mysql_fetch_lengths_func)(MYSQL_RES *res); + int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); + unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); + int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +} *sql_service; + +#ifdef MYSQL_DYNAMIC_PLUGIN + +#define mysql_init(M) sql_service->mysql_init_func(M) +#define mysql_real_connect_local(M) sql_service->mysql_real_connect_local_func(M) +#define mysql_real_connect(M,H,U,PW,D,P,S,F) sql_service->mysql_real_connect_func(M,H,U,PW,D,P,S,F) +#define mysql_errno(M) sql_service->mysql_errno_func(M) +#define mysql_error(M) sql_service->mysql_error_func(M) +#define mysql_real_query sql_service->mysql_real_query_func +#define mysql_affected_rows(M) sql_service->mysql_affected_rows_func(M) +#define mysql_num_rows(R) sql_service->mysql_num_rows_func(R) +#define mysql_store_result(M) sql_service->mysql_store_result_func(M) +#define mysql_free_result(R) sql_service->mysql_free_result_func(R) +#define mysql_fetch_row(R) sql_service->mysql_fetch_row_func(R) +#define mysql_close(M) sql_service->mysql_close_func(M) +#define mysql_options(M,O,V) sql_service->mysql_options_func(M,O,V) +#define mysql_fetch_lengths(R) sql_service->mysql_fetch_lengths_func(R) +#define mysql_set_character_set(M,C) sql_service->mysql_set_character_set_func(M,C) +#define mysql_num_fields(R) sql_service->mysql_num_fields_func(R) +#define mysql_select_db(M,D) sql_service->mysql_select_db_func(M,D) +#define mysql_ssl_set(M,K,C,A,P,H) sql_service->mysql_ssl_set_func(M,K,C,A,P,H) + +#else + +/* + Establishes the connection to the 'local' server that started the plugin. + Like the mysql_real_connect() does for the remote server. + The established connection has no user/host associated to it, + neither it has the current db, so the queries should have + database/table name specified. +*/ +MYSQL *mysql_real_connect_local(MYSQL *mysql); + +/* The rest of the function declarations must be taken from the mysql.h */ + +#endif /*MYSQL_DYNAMIC_PLUGIN*/ + + +#ifdef __cplusplus +} +#endif + +#endif /*MYSQL_SERVICE_SQL */ + + diff --git a/include/mysql/services.h b/include/mysql/services.h index 2c3a0ae421b..94f7bb3b2da 100644 --- a/include/mysql/services.h +++ b/include/mysql/services.h @@ -41,6 +41,7 @@ extern "C" { #include #include /*#include */ +#include #ifdef __cplusplus } diff --git a/include/service_versions.h b/include/service_versions.h index 34e4952c94c..ee250864287 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -43,4 +43,5 @@ #define VERSION_thd_wait 0x0100 #define VERSION_wsrep 0x0500 #define VERSION_json 0x0100 +#define VERSION_sql_service 0x0100 #define VERSION_thd_mdl 0x0100 diff --git a/include/sql_common.h b/include/sql_common.h index a21af683e2e..2a79261c6e8 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -62,13 +62,13 @@ typedef struct st_mysql_methods MYSQL_ROW column, unsigned int field_count); void (*flush_use_result)(MYSQL *mysql, my_bool flush_all_results); int (*read_change_user_result)(MYSQL *mysql); + void (*on_close_free)(MYSQL *mysql); #if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) MYSQL_FIELD * (*list_fields)(MYSQL *mysql); my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); int (*stmt_execute)(MYSQL_STMT *stmt); int (*read_binary_rows)(MYSQL_STMT *stmt); int (*unbuffered_fetch)(MYSQL *mysql, char **row); - void (*free_embedded_thd)(MYSQL *mysql); const char *(*read_statistics)(MYSQL *mysql); my_bool (*next_result)(MYSQL *mysql); int (*read_rows_from_cursor)(MYSQL_STMT *stmt); diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 86309ab91b4..cc73cc174ac 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -43,7 +43,7 @@ C_MODE_START extern unsigned int mysql_server_last_errno; extern char mysql_server_last_error[MYSQL_ERRMSG_SIZE]; static my_bool emb_read_query_result(MYSQL *mysql); -static void emb_free_embedded_thd(MYSQL *mysql); +static void free_embedded_thd(MYSQL *mysql); static bool embedded_print_errors= 0; extern "C" void unireg_clear(int exit_code) @@ -121,7 +121,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, thd->killed= NOT_KILLED; else { - emb_free_embedded_thd(mysql); + free_embedded_thd(mysql); thd= 0; } } @@ -430,7 +430,7 @@ int emb_unbuffered_fetch(MYSQL *mysql, char **row) return 0; } -static void emb_free_embedded_thd(MYSQL *mysql) +static void free_embedded_thd(MYSQL *mysql) { THD *thd= (THD*)mysql->thd; server_threads.erase(thd); @@ -453,12 +453,25 @@ static MYSQL_RES * emb_store_result(MYSQL *mysql) return mysql_store_result(mysql); } -int emb_read_change_user_result(MYSQL *mysql) +static int emb_read_change_user_result(MYSQL *mysql) { mysql->net.read_pos= (uchar*)""; // fake an OK packet return mysql_errno(mysql) ? (int)packet_error : 1 /* length of the OK packet */; } + +static void emb_on_close_free(MYSQL *mysql) +{ + my_free(mysql->info_buffer); + mysql->info_buffer= 0; + if (mysql->thd) + { + free_embedded_thd(mysql); + mysql->thd= 0; + } +} + + MYSQL_METHODS embedded_methods= { emb_read_query_result, @@ -468,12 +481,12 @@ MYSQL_METHODS embedded_methods= emb_fetch_lengths, emb_flush_use_result, emb_read_change_user_result, + emb_on_close_free, emb_list_fields, emb_read_prepare_result, emb_stmt_execute, emb_read_binary_rows, emb_unbuffered_fetch, - emb_free_embedded_thd, emb_read_statistics, emb_read_query_result, emb_read_rows_from_cursor @@ -694,8 +707,7 @@ void *create_embedded_thd(ulong client_flag) if (thd->variables.max_join_size == HA_POS_ERROR) thd->variables.option_bits |= OPTION_BIG_SELECTS; - thd->proc_info=0; // Remove 'login' - thd->set_command(COM_SLEEP); + thd->mark_connection_idle(); thd->set_time(); thd->init_for_queries(); thd->client_capabilities= client_flag | MARIADB_CLIENT_EXTENDED_METADATA; diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt index 274c8ce6dac..6b47bb53fdb 100644 --- a/libservices/CMakeLists.txt +++ b/libservices/CMakeLists.txt @@ -38,6 +38,7 @@ SET(MYSQLSERVICES_SOURCES thd_wait_service.c wsrep_service.c json_service.c + sql_service.c ) ADD_CONVENIENCE_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES}) diff --git a/libservices/sql_service.c b/libservices/sql_service.c new file mode 100644 index 00000000000..5c0102bfadf --- /dev/null +++ b/libservices/sql_service.c @@ -0,0 +1,19 @@ + +/* Copyright (c) 2018, Monty Program Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +SERVICE_VERSION sql_service= (void*)VERSION_sql_service; diff --git a/mysql-test/README b/mysql-test/README index ae1d6d56433..ef9e07fa0da 100644 --- a/mysql-test/README +++ b/mysql-test/README @@ -84,8 +84,8 @@ edit the test result to the correct results so that we can verify that the bug is corrected in future releases. If you want to submit your test case you can send it -to maria-developers@lists.launchpad.net or attach it to a bug report on -https://mariadb.org/jira/. +to developers@lists.mariadb.org or attach it to a bug report on +http://mariadb.org/jira/. If the test case is really big or if it contains 'not public' data, then put your .test file and .result file(s) into a tar.gz archive, diff --git a/mysql-test/include/innodb_stable_estimates.inc b/mysql-test/include/innodb_stable_estimates.inc new file mode 100644 index 00000000000..dc3bc4de9ee --- /dev/null +++ b/mysql-test/include/innodb_stable_estimates.inc @@ -0,0 +1,12 @@ +# +# Include this file in your .test file if your testcase uses InnoDB tables +# requiring stable query plans, which likely requires that InnoDB produces +# stable estimates for #records in tables. +# +# How it works: +# Unstable InnoDB estimates are caused by InnoDB's background statistics +# collection. When you include this file, MTR will use server options from +# include/innodb_stable_estimates.opt, which disables background statistics +# collection. +# (and no, InnoDB team objects to using this configuration for all MTR tests) +# diff --git a/mysql-test/include/innodb_stable_estimates.opt b/mysql-test/include/innodb_stable_estimates.opt new file mode 100644 index 00000000000..896950f4ae5 --- /dev/null +++ b/mysql-test/include/innodb_stable_estimates.opt @@ -0,0 +1 @@ +--innodb_stats_auto_recalc=0 diff --git a/mysql-test/include/wait_for_slave_io_error.inc b/mysql-test/include/wait_for_slave_io_error.inc index 96844106fa9..158594304ea 100644 --- a/mysql-test/include/wait_for_slave_io_error.inc +++ b/mysql-test/include/wait_for_slave_io_error.inc @@ -59,7 +59,7 @@ let $_wfsie_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1); if ($slave_io_errno == '') { --echo !!!ERROR IN TEST: you must set \$slave_io_errno before you source - --echo !!!wait_for_slave_sql_error.inc. The error we got this time was '$_wfsie_errno', + --echo !!!wait_for_slave_io_error.inc. The error we got this time was '$_wfsie_errno', --echo !!!so you probably want to add the following line to your test case: --echo !!! --let \$slave_io_errno= $_wfsie_errno --die !!!ERROR IN TEST: you must set \$slave_io_errno before sourcing wait_for_slave_io_error.inc diff --git a/mysql-test/include/wait_for_slave_io_to_stop.inc b/mysql-test/include/wait_for_slave_io_to_stop.inc index d25c2ac071d..760e032eeb1 100644 --- a/mysql-test/include/wait_for_slave_io_to_stop.inc +++ b/mysql-test/include/wait_for_slave_io_to_stop.inc @@ -21,6 +21,17 @@ # $slave_timeout # See include/wait_for_slave_param.inc. # +# $rpl_allow_error +# By default, this file fails if there is an error in the IO +# thread. However, if an error in the IO thread is possible and allowed, +# setting $rpl_allow_error=1 will prevent this file from failing if +# there is an error in the IO thread. +# (If an error is _always_ expected, a better alternative might be to +# use wait_for_slave_io_error.inc instead of this file). +# Note: This is currently always enabled, since a simple STOP SLAVE +# IO_THREAD can cause an error if it interrupts the slave's initial +# communication with the master (MDEV-32892). +# # $rpl_debug # See include/rpl_init.inc @@ -31,9 +42,15 @@ --let $slave_param= Slave_IO_Running --let $slave_param_value= No ---let $slave_error_param= Last_IO_Errno +--let $_io_stop_save_allow_error= $slave_error_param +# Disabled, as IO errors are left behind when a normal STOP SLAVE interrupts +# the initial communication between the IO thread and the master (MDEV-32892). +#if (!$rpl_allow_error) +#{ +# --let $slave_error_param= Last_IO_Errno +#} --source include/wait_for_slave_param.inc ---let $slave_error_param= +--let $slave_error_param= $_io_stop_save_allow_error --let $include_filename= wait_for_slave_io_to_stop.inc diff --git a/mysql-test/include/wait_for_slave_param.inc b/mysql-test/include/wait_for_slave_param.inc index b06dee3c640..ed81c55963f 100644 --- a/mysql-test/include/wait_for_slave_param.inc +++ b/mysql-test/include/wait_for_slave_param.inc @@ -35,7 +35,7 @@ # $slave_error_param # If set, this script will check if the column of the output from # SHOW SLAVE STATUS named $slave_error_param is nonzero. If it is, -# this script will faile immediately. Typically, this should be set +# this script will fail immediately. Typically, this should be set # to Last_IO_Errno or Last_SQL_Errno. # # $rpl_debug @@ -56,11 +56,6 @@ if (!$_slave_timeout) } } -if ($slave_error_param == '') -{ - --let $slave_error_param= 1 -} - let $_slave_param_comparison= $slave_param_comparison; if (!$_slave_param_comparison) { @@ -90,7 +85,7 @@ while ($_slave_continue) --let $_show_slave_status_value= query_get_value("SHOW SLAVE STATUS", $slave_param, 1) # Check if an error condition is reached. - if (!$slave_error_param) + if ($slave_error_param) { --let $_show_slave_status_error_value= query_get_value("SHOW SLAVE STATUS", $slave_error_param, 1) if ($_show_slave_status_error_value) diff --git a/mysql-test/include/wait_for_slave_sql_to_stop.inc b/mysql-test/include/wait_for_slave_sql_to_stop.inc index 492b3237be5..0a05464ce42 100644 --- a/mysql-test/include/wait_for_slave_sql_to_stop.inc +++ b/mysql-test/include/wait_for_slave_sql_to_stop.inc @@ -21,6 +21,14 @@ # $slave_timeout # See include/wait_for_slave_param.inc # +# $rpl_allow_error +# By default, this file fails if there is an error in the SQL +# thread. However, if an error in the SQL thread is possible and allowed, +# setting $rpl_allow_error=1 will prevent this file from failing if +# there is an error in the SQL thread. +# (If an error is _always_ expected, a better alternative might be to +# use wait_for_slave_sql_error.inc instead of this file). +# # $rpl_debug # See include/rpl_init.inc @@ -31,7 +39,10 @@ --let $slave_param= Slave_SQL_Running --let $slave_param_value= No ---let $slave_error_param= Last_SQL_Errno +if (!$rpl_allow_error) +{ + --let $slave_error_param= Last_SQL_Errno +} --source include/wait_for_slave_param.inc --let $slave_error_param= diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index b8f85e33944..38fe52348c5 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -1999,8 +1999,7 @@ ALTER TABLE ti1 DROP FOREIGN KEY fi1; affected rows: 0 info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tm1 DROP FOREIGN KEY fm1; -affected rows: 2 -info: Records: 2 Duplicates: 0 Warnings: 0 +ERROR 42000: Can't DROP FOREIGN KEY `fm1`; check that it exists ALTER TABLE ti1 RENAME TO ti3; affected rows: 0 ALTER TABLE tm1 RENAME TO tm3; diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index 40f48ac87bd..051a0b9fd08 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -1696,6 +1696,7 @@ ALTER TABLE ti1 DROP PRIMARY KEY; ALTER TABLE tm1 DROP PRIMARY KEY; ALTER TABLE ti1 DROP FOREIGN KEY fi1; +--error ER_CANT_DROP_FIELD_OR_KEY ALTER TABLE tm1 DROP FOREIGN KEY fm1; ALTER TABLE ti1 RENAME TO ti3; diff --git a/mysql-test/main/backup_interaction.result b/mysql-test/main/backup_interaction.result index a6fe7cf448d..c775c5ebc49 100644 --- a/mysql-test/main/backup_interaction.result +++ b/mysql-test/main/backup_interaction.result @@ -95,7 +95,7 @@ drop table t1; # # BACKUP STAGE performs implicit commits # -create table t1(a int) engine=InnoDB; +create table t1(a int) stats_persistent=0, engine=InnoDB; begin; insert into t1 values(1); select lock_mode from information_schema.metadata_lock_info where thread_id>0; @@ -197,8 +197,9 @@ drop table t1; # CHECK: RO transaction under BACKUP STAGE is a potential deadlock # OTOH we most probably allow them under FTWRL as well # -CREATE TABLE t1 (col1 INT) ENGINE = InnoDB; +CREATE TABLE t1 (col1 INT)stats_persistent=0, ENGINE = InnoDB; insert into t1 values (1); +InnoDB 0 transactions not purged backup stage start; backup stage block_commit; begin; diff --git a/mysql-test/main/backup_interaction.test b/mysql-test/main/backup_interaction.test index c755bdf8f95..25f22f66a5d 100644 --- a/mysql-test/main/backup_interaction.test +++ b/mysql-test/main/backup_interaction.test @@ -120,7 +120,7 @@ drop table t1; --echo # BACKUP STAGE performs implicit commits --echo # --disable_view_protocol -create table t1(a int) engine=InnoDB; +create table t1(a int) stats_persistent=0, engine=InnoDB; begin; insert into t1 values(1); select lock_mode from information_schema.metadata_lock_info where thread_id>0; @@ -221,8 +221,9 @@ drop table t1; --echo # OTOH we most probably allow them under FTWRL as well --echo # --disable_view_protocol -CREATE TABLE t1 (col1 INT) ENGINE = InnoDB; +CREATE TABLE t1 (col1 INT)stats_persistent=0, ENGINE = InnoDB; insert into t1 values (1); +--source ../suite/innodb/include/wait_all_purged.inc backup stage start; backup stage block_commit; begin; diff --git a/mysql-test/main/backup_lock.result b/mysql-test/main/backup_lock.result index 16806148c67..488e81fd6d4 100644 --- a/mysql-test/main/backup_lock.result +++ b/mysql-test/main/backup_lock.result @@ -1,6 +1,7 @@ # # Testing which locks we get from all stages # +InnoDB 0 transactions not purged BACKUP STAGE START; SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; @@ -34,7 +35,8 @@ connection default; # # testing if BACKUP STAGE FLUSH causes deadlocks with ALTER TABLE # -create table t1 (a int) engine=innodb; +create table t1 (a int) stats_persistent= 0, engine=innodb; +InnoDB 0 transactions not purged connection con2; backup stage start; connection default; @@ -104,7 +106,8 @@ drop table t1; # # testing if BACKUP STAGE FLUSH causes deadlocks with DROP TABLE # -create table t1 (a int) engine=innodb; +create table t1 (a int)stats_persistent=0, engine=innodb; +InnoDB 0 transactions not purged start transaction; insert into t1 values (1); connection con1; @@ -132,6 +135,7 @@ connection default; # Check if backup stage block_dll + concurrent drop table blocks select # create table t1 (a int) engine=innodb; +InnoDB 0 transactions not purged backup stage start; backup stage block_ddl; connection con1; diff --git a/mysql-test/main/backup_lock.test b/mysql-test/main/backup_lock.test index 5453e5b0e7d..f86f2f3670e 100644 --- a/mysql-test/main/backup_lock.test +++ b/mysql-test/main/backup_lock.test @@ -15,6 +15,8 @@ let $mdl= LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; +--source ../suite/innodb/include/wait_all_purged.inc + BACKUP STAGE START; eval SELECT $mdl; BACKUP STAGE FLUSH; @@ -39,7 +41,8 @@ connection default; --echo # testing if BACKUP STAGE FLUSH causes deadlocks with ALTER TABLE --echo # -create table t1 (a int) engine=innodb; +create table t1 (a int) stats_persistent= 0, engine=innodb; +--source ../suite/innodb/include/wait_all_purged.inc connection con2; backup stage start; @@ -129,7 +132,8 @@ drop table t1; --echo # testing if BACKUP STAGE FLUSH causes deadlocks with DROP TABLE --echo # -create table t1 (a int) engine=innodb; +create table t1 (a int)stats_persistent=0, engine=innodb; +--source ../suite/innodb/include/wait_all_purged.inc start transaction; # Acquires MDL lock insert into t1 values (1); @@ -165,6 +169,7 @@ connection default; --echo # create table t1 (a int) engine=innodb; +--source ../suite/innodb/include/wait_all_purged.inc backup stage start; backup stage block_ddl; connection con1; diff --git a/mysql-test/main/backup_locks.result b/mysql-test/main/backup_locks.result index 31aed5f3cc8..4d5de53c1fb 100644 --- a/mysql-test/main/backup_locks.result +++ b/mysql-test/main/backup_locks.result @@ -23,7 +23,7 @@ BACKUP UNLOCK; # connect con1,localhost,root,,; connection default; -create table t1 (a int) engine=innodb; +create table t1 (a int) stats_persistent=0,engine=innodb; insert into t1 values (1); backup lock t1; select * from t1; @@ -184,5 +184,82 @@ ERROR HY000: Can't execute the query because you have a conflicting read lock BACKUP UNLOCK; DROP TABLE t3; # +# MDEV-28367: BACKUP LOCKS on table to be accessible to those +# with database LOCK TABLES privileges +# +create database db1; +create table db1.t1(t int); +create user user1@localhost; +select user,host from mysql.user where user='user1'; +User Host +user1 localhost +connect(localhost,user1,,db1,MASTER_PORT,MASTER_SOCKET); +connect con1, localhost, user1, ,db1; +ERROR 42000: Access denied for user 'user1'@'localhost' to database 'db1' +grant reload on *.* to user1@localhost; +grant select on db1.* to user1@localhost; +show grants for user1@localhost; +Grants for user1@localhost +GRANT RELOAD ON *.* TO `user1`@`localhost` +GRANT SELECT ON `db1`.* TO `user1`@`localhost` +connect con1, localhost, user1, ,db1; +BACKUP UNLOCK; +BACKUP LOCK db1.t1; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; +LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME +MDL_SHARED_HIGH_PRIO Table metadata lock db1 t1 +BACKUP UNLOCK; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; +LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME +connection default; +disconnect con1; +grant lock tables on db1.* to user1@localhost; +show grants for user1@localhost; +Grants for user1@localhost +GRANT RELOAD ON *.* TO `user1`@`localhost` +GRANT SELECT, LOCK TABLES ON `db1`.* TO `user1`@`localhost` +connect con1, localhost, user1, ,db1; +BACKUP UNLOCK; +BACKUP LOCK db1.t1; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; +LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME +MDL_SHARED_HIGH_PRIO Table metadata lock db1 t1 +BACKUP UNLOCK; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; +LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME +connection default; +disconnect con1; +revoke reload on *.* from user1@localhost; +show grants for user1@localhost; +Grants for user1@localhost +GRANT USAGE ON *.* TO `user1`@`localhost` +GRANT SELECT, LOCK TABLES ON `db1`.* TO `user1`@`localhost` +connect con1, localhost, user1, ,db1; +BACKUP UNLOCK; +ERROR 42000: Access denied; you need (at least one of) the RELOAD, LOCK TABLES privilege(s) for this operation +BACKUP LOCK db1.t1; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; +LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME +MDL_SHARED_HIGH_PRIO Table metadata lock db1 t1 +BACKUP UNLOCK; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; +LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME +connection default; +disconnect con1; +revoke lock tables on db1.* from user1@localhost; +show grants for user1@localhost; +Grants for user1@localhost +GRANT USAGE ON *.* TO `user1`@`localhost` +GRANT SELECT ON `db1`.* TO `user1`@`localhost` +connect con1, localhost, user1, ,db1; +BACKUP LOCK db1.t1; +ERROR 42000: Access denied; you need (at least one of) the RELOAD, LOCK TABLES privilege(s) for this operation +BACKUP UNLOCK; +ERROR 42000: Access denied; you need (at least one of) the RELOAD, LOCK TABLES privilege(s) for this operation +connection default; +disconnect con1; +drop database db1; +drop user user1@localhost; +# # End of MariaDB 10.4 tests # diff --git a/mysql-test/main/backup_locks.test b/mysql-test/main/backup_locks.test index 2c2c226f847..40f12bb7ef8 100644 --- a/mysql-test/main/backup_locks.test +++ b/mysql-test/main/backup_locks.test @@ -29,7 +29,7 @@ BACKUP UNLOCK; connect (con1,localhost,root,,); connection default; -create table t1 (a int) engine=innodb; +create table t1 (a int) stats_persistent=0,engine=innodb; insert into t1 values (1); backup lock t1; select * from t1; @@ -214,7 +214,78 @@ LOCK TABLES t3 AS a2 WRITE, t3 AS a1 READ LOCAL; DROP TABLE t3; BACKUP UNLOCK; DROP TABLE t3; +--echo # +--echo # MDEV-28367: BACKUP LOCKS on table to be accessible to those +--echo # with database LOCK TABLES privileges +--echo # +--source include/have_metadata_lock_info.inc +create database db1; +create table db1.t1(t int); +create user user1@localhost; +select user,host from mysql.user where user='user1'; +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_DBACCESS_DENIED_ERROR +--connect (con1, localhost, user1, ,db1) + +grant reload on *.* to user1@localhost; +# To access DB one need select privileges +grant select on db1.* to user1@localhost; +show grants for user1@localhost; +--connect (con1, localhost, user1, ,db1) + +# This should work we have RELOAD privilege +BACKUP UNLOCK; +BACKUP LOCK db1.t1; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; +BACKUP UNLOCK; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; + +# Add LOCK TABLES DB privileges (all privileges for BACKUP LOCK are there) +connection default; +disconnect con1; +grant lock tables on db1.* to user1@localhost; +show grants for user1@localhost; +--connect (con1, localhost, user1, ,db1) +# This should work we have RELOAD & LOCK privilege +BACKUP UNLOCK; +BACKUP LOCK db1.t1; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; +BACKUP UNLOCK; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; + +# Remove reload privilege, leave only LOCK TABLES privilege +connection default; +disconnect con1; +revoke reload on *.* from user1@localhost; +show grants for user1@localhost; +--connect (con1, localhost, user1, ,db1) +# There is no reload priv needed for unlock and there is no mdl_backup_lock taken +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +BACKUP UNLOCK; +# BACKUP LOCK should work, since we have LOCK privilege +BACKUP LOCK db1.t1; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; +# This works since there was taken mdl_backup_lock before +BACKUP UNLOCK; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info where table_name not like "innodb_%"; + +# Remove LOCK TABLES privilege +connection default; +disconnect con1; +revoke lock tables on db1.* from user1@localhost; +show grants for user1@localhost; +--connect (con1, localhost, user1, ,db1) +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +BACKUP LOCK db1.t1; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +BACKUP UNLOCK; + +connection default; +disconnect con1; + +drop database db1; +drop user user1@localhost; --echo # --echo # End of MariaDB 10.4 tests --echo # diff --git a/mysql-test/main/backup_stages.result b/mysql-test/main/backup_stages.result index 823e5d7e462..3fb912afa98 100644 --- a/mysql-test/main/backup_stages.result +++ b/mysql-test/main/backup_stages.result @@ -17,6 +17,7 @@ FROM information_schema.processlist WHERE id = @con1_id; ID USER COMMAND STATE INFO STAGE MAX_STAGE INFO_BINARY root Query Waiting for backup lock BACKUP STAGE START 0 0 BACKUP STAGE START BACKUP STAGE END; +InnoDB 0 transactions not purged connection con1; # The connection default has removed the backup lock. # And so the current connection con1 can reap for its BACKUP STAGE START diff --git a/mysql-test/main/backup_stages.test b/mysql-test/main/backup_stages.test index 77d410b6caf..56be6205ee2 100644 --- a/mysql-test/main/backup_stages.test +++ b/mysql-test/main/backup_stages.test @@ -50,6 +50,7 @@ FROM information_schema.processlist WHERE id = @con1_id; # con1 uses @@global.lock_wait_timeout BACKUP STAGE END; +--source ../suite/innodb/include/wait_all_purged.inc --connection con1 --echo # The connection default has removed the backup lock. diff --git a/mysql-test/main/cast.result b/mysql-test/main/cast.result index b87b70657c1..49422314a71 100644 --- a/mysql-test/main/cast.result +++ b/mysql-test/main/cast.result @@ -814,7 +814,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, - `b` char(5) GENERATED ALWAYS AS (cast('a' as char(10) charset latin1) + `a`) VIRTUAL + `b` char(5) GENERATED ALWAYS AS (cast('a' as char(10) charset latin1 binary) + `a`) VIRTUAL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; select collation(cast("a" as char(10) binary)); diff --git a/mysql-test/main/cast.test b/mysql-test/main/cast.test index 478c59a58f7..ce4b1f6a574 100644 --- a/mysql-test/main/cast.test +++ b/mysql-test/main/cast.test @@ -158,10 +158,9 @@ select cast(1 as double(64,63)); # set names binary; select cast(_latin1'test' as char character set latin2); -#enable after MDEV-32461 fix ---disable_view_protocol +--disable_service_connection select cast(_koi8r'ÔÅÓÔ' as char character set cp1251); ---enable_view_protocol +--enable_service_connection create table t1 select cast(_koi8r'ÔÅÓÔ' as char character set cp1251) as t; show create table t1; drop table t1; @@ -169,8 +168,7 @@ drop table t1; # # CAST to CHAR with/without length # -#enable after MDEV-32461 fix ---disable_view_protocol +--disable_service_connection select cast(_latin1'ab' AS char) as c1, cast(_latin1'a ' AS char) as c2, @@ -178,7 +176,7 @@ select cast(_latin1'a ' AS char(2)) as c4, hex(cast(_latin1'a' AS char(2))) as c5; select cast(1000 as CHAR(3)); ---enable_view_protocol +--enable_service_connection SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR create table t1 select @@ -239,15 +237,14 @@ select cast("1:2:3" as TIME) = "1:02:03"; # CREATE TABLE t1 (a enum ('aac','aab','aaa') not null); INSERT INTO t1 VALUES ('aaa'),('aab'),('aac'); -#enable after MDEV-32461 fix ---disable_view_protocol +--disable_service_connection # these two should be in enum order SELECT a, CAST(a AS CHAR) FROM t1 ORDER BY CAST(a AS UNSIGNED) ; SELECT a, CAST(a AS CHAR(3)) FROM t1 ORDER BY CAST(a AS CHAR(2)), a; # these two should be in alphabetic order SELECT a, CAST(a AS UNSIGNED) FROM t1 ORDER BY CAST(a AS CHAR) ; SELECT a, CAST(a AS CHAR(2)) FROM t1 ORDER BY CAST(a AS CHAR(3)), a; ---enable_view_protocol +--enable_service_connection DROP TABLE t1; # @@ -349,12 +346,11 @@ select cast(NULL as decimal(6)) as t1; # Bug #17903: cast to char results in binary # set names latin1; -#enable after MDEV-32461 fix ---disable_view_protocol +--disable_service_connection select hex(cast('a' as char(2) binary)); select hex(cast('a' as binary(2))); select hex(cast('a' as char(2) binary)); ---enable_view_protocol +--enable_service_connection # # Bug#29898: Item_date_typecast::val_int doesn't reset the null_value flag. @@ -484,14 +480,13 @@ drop table t1; # # CAST (... BINARY) # -#enable after MDEV-32461 fix ---disable_view_protocol +--disable_service_connection select collation(cast("a" as char(10) binary)); select collation(cast("a" as char(10) charset utf8 binary)); select collation(cast("a" as char(10) ascii binary)); select collation(cast("a" as char(10) binary charset utf8)); select collation(cast("a" as char(10) binary ascii)); ---enable_view_protocol +--enable_service_connection --echo # --echo # MDEV-11030 Assertion `precision > 0' failed in decimal_bin_size @@ -773,14 +768,14 @@ INSERT INTO t1 VALUES (-1.0); SELECT * FROM t1; DROP TABLE t1; -#enable after MDEV-32461 fix +#enable after MDEV-32645 is fixed --disable_view_protocol SELECT CAST(-1e0 AS UNSIGNED); ---enable_view_protocol CREATE TABLE t1 (a BIGINT UNSIGNED); INSERT INTO t1 VALUES (-1e0); SELECT * FROM t1; DROP TABLE t1; +--enable_view_protocol SELECT CAST(-1e308 AS UNSIGNED); CREATE TABLE t1 (a BIGINT UNSIGNED); diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index e7170632fd6..692c9d3e322 100644 --- a/mysql-test/main/create_or_replace.result +++ b/mysql-test/main/create_or_replace.result @@ -260,6 +260,7 @@ Note 1051 Unknown table 'test.t1,mysqltest2.t2' create table test.t1 (i int) engine=myisam; create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; +InnoDB 0 transactions not purged select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test index 58221dde4fe..5758620de71 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -216,6 +216,7 @@ drop table if exists test.t1,mysqltest2.t2; create table test.t1 (i int) engine=myisam; create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; +--source ../suite/innodb/include/wait_all_purged.inc --replace_column 1 # --sorted_result select * from information_schema.metadata_lock_info; diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result index e05120fa60d..7bca6a44823 100644 --- a/mysql-test/main/cte_nonrecursive.result +++ b/mysql-test/main/cte_nonrecursive.result @@ -2599,4 +2599,29 @@ src path dest distance population E FD D 251 80000 drop procedure sp; drop table distances, city_population; +# +# MDEV-28615: Multi-table UPDATE over derived table containing +# row that uses subquery with hanging CTE +# +CREATE TABLE t1 (a int) ENGINE=MYISAM; +INSERT INTO t1 VALUES (3), (7), (1); +UPDATE +(SELECT (5, (WITH cte AS (SELECT 1) SELECT a FROM t1))) dt +JOIN t1 t +ON t.a=dt.a +SET t.a = 1; +ERROR 21000: Operand should contain 1 column(s) +UPDATE +(SELECT a FROM t1 +WHERE (5, (WITH cte AS (SELECT 1) SELECT a FROM t1 WHERE a > 4)) <= +(5,a)) dt +JOIN t1 t +ON t.a=dt.a +SET t.a = 1; +SELECT * FROM t1; +a +3 +1 +1 +DROP TABLE t1; # End of 10.4 tests diff --git a/mysql-test/main/cte_nonrecursive.test b/mysql-test/main/cte_nonrecursive.test index 1d29f3d4caa..aa573a76454 100644 --- a/mysql-test/main/cte_nonrecursive.test +++ b/mysql-test/main/cte_nonrecursive.test @@ -1796,8 +1796,6 @@ with data as (select 1 as id) select id into @myid from data; set sql_mode= @save_sql_mode; - - --echo # --echo # MDEV-31995 Bogus error executing PS for query using CTE with renaming of columns --echo # @@ -1954,4 +1952,31 @@ drop procedure sp; drop table distances, city_population; +--echo # +--echo # MDEV-28615: Multi-table UPDATE over derived table containing +--echo # row that uses subquery with hanging CTE +--echo # + +CREATE TABLE t1 (a int) ENGINE=MYISAM; +INSERT INTO t1 VALUES (3), (7), (1); + +--error ER_OPERAND_COLUMNS +UPDATE + (SELECT (5, (WITH cte AS (SELECT 1) SELECT a FROM t1))) dt + JOIN t1 t + ON t.a=dt.a +SET t.a = 1; + +UPDATE + (SELECT a FROM t1 + WHERE (5, (WITH cte AS (SELECT 1) SELECT a FROM t1 WHERE a > 4)) <= + (5,a)) dt + JOIN t1 t + ON t.a=dt.a +SET t.a = 1; + +SELECT * FROM t1; + +DROP TABLE t1; + --echo # End of 10.4 tests diff --git a/mysql-test/main/ctype_cp932.result b/mysql-test/main/ctype_cp932.result index 08c94abf74d..415e1ff4f79 100644 --- a/mysql-test/main/ctype_cp932.result +++ b/mysql-test/main/ctype_cp932.result @@ -613,7 +613,7 @@ ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT('SET STATEMENT ',@seq, '.a=1 SELECT 1'); ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT('SET STATEMENT a.',@seq, '=1 SELECT 1'); -ERROR HY000: Invalid cp932 character string: '\x81\xAD' +ERROR HY000: Invalid cp932 character string: '\x81' # # SET SESSION (bad|good.bad|bad.good)=1 # @@ -622,7 +622,7 @@ ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT('SET SESSION ',@seq, '.a=1 SELECT 1'); ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT('SET SESSION a.',@seq, '=1 SELECT 1'); -ERROR HY000: Invalid cp932 character string: '\x81\xAD' +ERROR HY000: Invalid cp932 character string: '\x81' # # SET (bad|good.bad|bad.good)=1 # @@ -631,7 +631,7 @@ ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT('SET ', @seq, '.a=1'); ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT('SET a.', @seq, '=1'); -ERROR HY000: Invalid cp932 character string: '\x81\xAD' +ERROR HY000: Invalid cp932 character string: '\x81' # # Oracle SP call: BEGIN (bad|good.bad|bad.good)(params); END # @@ -641,7 +641,7 @@ ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT('BEGIN ',@seq, '.a(1); END;'); ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT('BEGIN a.',@seq, '(1); END;'); -ERROR HY000: Invalid cp932 character string: '\x81\xAD' +ERROR HY000: Invalid cp932 character string: '\x81' # # Oracle assignment: (bad|good.bad|bad.good):= value # @@ -650,7 +650,7 @@ ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT(@seq, '.a:=1'); ERROR HY000: Invalid cp932 character string: '\x81\xAD' EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); -ERROR HY000: Invalid cp932 character string: '\x81\xAD' +ERROR HY000: Invalid cp932 character string: '\x81' SET sql_mode=DEFAULT; # # End of 10.5 tests diff --git a/mysql-test/main/ctype_sjis.result b/mysql-test/main/ctype_sjis.result index d5a66d728a1..11470894553 100644 --- a/mysql-test/main/ctype_sjis.result +++ b/mysql-test/main/ctype_sjis.result @@ -19349,7 +19349,7 @@ ERROR HY000: Invalid sjis character string: ' EXECUTE IMMEDIATE CONCAT('SET STATEMENT ',@seq, '.a=1 SELECT 1'); ERROR HY000: Invalid sjis character string: '_x81_xAD' EXECUTE IMMEDIATE CONCAT('SET STATEMENT a.',@seq, '=1 SELECT 1'); -ERROR HY000: Invalid sjis character string: '_x81_xAD' +ERROR HY000: Invalid sjis character string: '_x81' # # SET SESSION (bad|good.bad|bad.good)=1 # @@ -19358,7 +19358,7 @@ ERROR HY000: Invalid sjis character string: ' EXECUTE IMMEDIATE CONCAT('SET SESSION ',@seq, '.a=1 SELECT 1'); ERROR HY000: Invalid sjis character string: '_x81_xAD' EXECUTE IMMEDIATE CONCAT('SET SESSION a.',@seq, '=1 SELECT 1'); -ERROR HY000: Invalid sjis character string: '_x81_xAD' +ERROR HY000: Invalid sjis character string: '_x81' # # SET (bad|good.bad|bad.good)=1 # @@ -19367,7 +19367,7 @@ ERROR HY000: Invalid sjis character string: ' EXECUTE IMMEDIATE CONCAT('SET ', @seq, '.a=1'); ERROR HY000: Invalid sjis character string: '_x81_xAD' EXECUTE IMMEDIATE CONCAT('SET a.', @seq, '=1'); -ERROR HY000: Invalid sjis character string: '_x81_xAD' +ERROR HY000: Invalid sjis character string: '_x81' # # Oracle SP call: BEGIN (bad|good.bad|bad.good)(params); END # @@ -19377,7 +19377,7 @@ ERROR HY000: Invalid sjis character string: ' EXECUTE IMMEDIATE CONCAT('BEGIN ',@seq, '.a(1); END;'); ERROR HY000: Invalid sjis character string: '_x81_xAD' EXECUTE IMMEDIATE CONCAT('BEGIN a.',@seq, '(1); END;'); -ERROR HY000: Invalid sjis character string: '_x81_xAD' +ERROR HY000: Invalid sjis character string: '_x81' # # Oracle assignment: (bad|good.bad|bad.good):= value # @@ -19386,7 +19386,7 @@ ERROR HY000: Invalid sjis character string: ' EXECUTE IMMEDIATE CONCAT(@seq, '.a:=1'); ERROR HY000: Invalid sjis character string: '_x81_xAD' EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); -ERROR HY000: Invalid sjis character string: '_x81_xAD' +ERROR HY000: Invalid sjis character string: '_x81' SET sql_mode=DEFAULT; # # End of 10.5 tests diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result index 4cb567ccab0..4ac51fc5ad3 100644 --- a/mysql-test/main/derived_view.result +++ b/mysql-test/main/derived_view.result @@ -4170,6 +4170,51 @@ a deallocate prepare stmt; drop view v; drop table t1,t2,t3; +# +# MDEV-32829 Crash when executing PS for query with eliminated subquery +# using view +# +create view v1 as select 1 as a; +prepare stmt from +'SELECT EXISTS (SELECT 1 FROM v1 GROUP BY a IN (SELECT a FROM v1))'; +execute stmt; +EXISTS (SELECT 1 FROM v1 GROUP BY a IN (SELECT a FROM v1)) +1 +drop view v1; +create table t1 (a int, b int); +insert into t1 values (1,2),(3,4),(5,6); +create view v1 as select * from t1; +create table t2 select * from t1; +prepare stmt from "select t2.a from t2 where exists +( +select * from t1 where t2.b = t1.b and t1.b != 6 +group by a in (select a from v1 where v1.a = t2.a) +)"; +execute stmt; +a +1 +3 +execute stmt; +a +1 +3 +deallocate prepare stmt; +create procedure aproc() select t2.a from t2 where exists +( +select * from t1 where t2.b = t1.b and t1.b != 6 +group by a in (select a from v1 where v1.a = t2.a) +); +call aproc(); +a +1 +3 +call aproc(); +a +1 +3 +drop table t1, t2; +drop view v1; +drop procedure aproc; # End of 10.4 tests # # MDEV-31143: view with ORDER BY used in query with rownum() in WHERE diff --git a/mysql-test/main/derived_view.test b/mysql-test/main/derived_view.test index 03565ae02f3..ddead30a589 100644 --- a/mysql-test/main/derived_view.test +++ b/mysql-test/main/derived_view.test @@ -2759,6 +2759,42 @@ deallocate prepare stmt; drop view v; drop table t1,t2,t3; +--echo # +--echo # MDEV-32829 Crash when executing PS for query with eliminated subquery +--echo # using view +--echo # + +create view v1 as select 1 as a; +prepare stmt from + 'SELECT EXISTS (SELECT 1 FROM v1 GROUP BY a IN (SELECT a FROM v1))'; +execute stmt; +drop view v1; + +create table t1 (a int, b int); +insert into t1 values (1,2),(3,4),(5,6); +create view v1 as select * from t1; +create table t2 select * from t1; + +let $q= +select t2.a from t2 where exists +( + select * from t1 where t2.b = t1.b and t1.b != 6 + group by a in (select a from v1 where v1.a = t2.a) +); + +eval prepare stmt from "$q"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +eval create procedure aproc() $q; +call aproc(); +call aproc(); + +drop table t1, t2; +drop view v1; +drop procedure aproc; + --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/disabled.def b/mysql-test/main/disabled.def index 02104f6a680..8ba5b271c2b 100644 --- a/mysql-test/main/disabled.def +++ b/mysql-test/main/disabled.def @@ -17,4 +17,3 @@ mysql_embedded : Bug#12561297 2011-05-14 Anitha Dependent on PB2 chang file_contents : MDEV-6526 these files are not installed anymore max_statement_time : cannot possibly work, depends on timing partition_open_files_limit : open_files_limit check broken by MDEV-18360 -partition_innodb : Waiting for fix MDEV-20169 diff --git a/mysql-test/main/dyncol.test b/mysql-test/main/dyncol.test index cb983bd3676..8b3164217d1 100644 --- a/mysql-test/main/dyncol.test +++ b/mysql-test/main/dyncol.test @@ -670,18 +670,16 @@ SELECT COLUMN_GET(`x`, 'y' AS DECIMAL(5,50)); --echo # --echo # creation test (names) set names utf8; -#enable after MDEV-32465 fix ---disable_view_protocol +--disable_service_connection select hex(column_create("адын", 1212)); ---enable_view_protocol +--enable_service_connection select hex(column_create("1212", 1212)); select hex(column_create(1212, 2, "www", 3)); select hex(column_create("1212", 2, "www", 3)); select hex(column_create("1212", 2, 3, 3)); -#enable after MDEV-32465 fix ---disable_view_protocol +--disable_service_connection select hex(column_create("1212", 2, "адын", 1, 3, 3)); ---enable_view_protocol +--enable_service_connection set names latin1; --echo # fetching column test (names) @@ -708,15 +706,14 @@ select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4") as ex; set names latin1; --echo # column changing test (names) -#enable after MDEV-32465 fix ---disable_view_protocol +--disable_service_connection select hex(column_add(column_create(1, "AAA"), "b", "BBB")) as ex; select hex(column_add(column_create("1", "AAA"), "b", "BBB")) as ex; select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char) as ex; select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char) as ex; select hex(column_add(column_create("a", "AAA"), 1, "BBB")) as ex; select hex(column_add(column_create("a", "AAA"), "1", "BBB")) as ex; ---enable_view_protocol +--enable_service_connection select hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)) as ex; select hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)) as ex; select hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)) as ex; diff --git a/mysql-test/main/enforce_storage_engine.result b/mysql-test/main/enforce_storage_engine.result index c761277a5b0..cc91daa73b9 100644 --- a/mysql-test/main/enforce_storage_engine.result +++ b/mysql-test/main/enforce_storage_engine.result @@ -158,5 +158,12 @@ t3 CREATE TABLE `t3` ( PRIMARY KEY (`c1`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t3; +# +# MDEV-21618 CREATE UNIQUE INDEX fails with "ERROR 1286 (42000): Unknown storage engine 'partition'" +# +SET SESSION enforce_storage_engine=MyISAM; +CREATE TABLE t4 (a INT) ENGINE=MyISAM PARTITION BY HASH(a); +CREATE INDEX x on t4 (a); +DROP TABLE t4; SET SESSION enforce_storage_engine=NULL; SET GLOBAL enforce_storage_engine=NULL; diff --git a/mysql-test/main/enforce_storage_engine.test b/mysql-test/main/enforce_storage_engine.test index 6b422477fe6..7768ed1bf46 100644 --- a/mysql-test/main/enforce_storage_engine.test +++ b/mysql-test/main/enforce_storage_engine.test @@ -1,4 +1,5 @@ --- source include/not_embedded.inc +--source include/not_embedded.inc +--source include/have_partition.inc set local sql_mode=""; set global sql_mode=""; @@ -107,5 +108,15 @@ ALTER TABLE t3 ADD COLUMN c3 INT; SHOW CREATE TABLE t3; DROP TABLE t3; +--echo # +--echo # MDEV-21618 CREATE UNIQUE INDEX fails with "ERROR 1286 (42000): Unknown storage engine 'partition'" +--echo # +SET SESSION enforce_storage_engine=MyISAM; + +CREATE TABLE t4 (a INT) ENGINE=MyISAM PARTITION BY HASH(a); +CREATE INDEX x on t4 (a); + +DROP TABLE t4; + SET SESSION enforce_storage_engine=NULL; -SET GLOBAL enforce_storage_engine=NULL; \ No newline at end of file +SET GLOBAL enforce_storage_engine=NULL; diff --git a/mysql-test/main/func_replace.result b/mysql-test/main/func_replace.result new file mode 100644 index 00000000000..7f354d529df --- /dev/null +++ b/mysql-test/main/func_replace.result @@ -0,0 +1,124 @@ +# +# Start of 10.5 tests +# +# +# MDEV-17226 Column Data in Truncated on UNION to the length of the first value if using REPLACE +# +CREATE TABLE t1 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +col1 VARCHAR (2), +col2 VARCHAR (2), +PRIMARY KEY (id) +); +CREATE TABLE t2 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +col1 VARCHAR (1), +col2 VARCHAR (2), +PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ("a", "ba"); +INSERT INTO t2 (col1, col2) VALUES ("a", "ba"); +SELECT 'a' UNION ALL SELECT REPLACE('a', col1, col2) FROM t1; +a +a +ba +SELECT 'a' UNION ALL SELECT REPLACE('a', col1, col2) FROM t2; +a +a +ba +SELECT REPLACE('z', col1, col2) FROM t1 UNION ALL SELECT REPLACE('a', col1, col2) FROM t1; +REPLACE('z', col1, col2) +z +ba +SELECT REPLACE('z', col1, col2) FROM t2 UNION ALL SELECT REPLACE('a', col1, col2) FROM t2; +REPLACE('z', col1, col2) +z +ba +DROP TABLE t1, t2; +CREATE TABLE t1 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +col1 VARCHAR (2), +col2 VARCHAR (2), +PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ('a', 'ba'); +SELECT REPLACE('a', col1, col2) FROM t1; +REPLACE('a', col1, col2) +ba +CREATE TABLE t2 AS SELECT 'a' UNION ALL SELECT REPLACE('a', col1, col2) FROM t1; +SELECT * FROM t2; +a +a +ba +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` varchar(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1, t2; +CREATE TABLE t1 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +col1 VARCHAR (1), +col2 VARCHAR (10), +PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ('a', '0123456789'); +SELECT REPLACE('aa', col1, col2) FROM t1; +REPLACE('aa', col1, col2) +01234567890123456789 +CREATE TABLE t2 AS SELECT 'a' UNION ALL SELECT REPLACE('aa', col1, col2) FROM t1; +SELECT * FROM t2; +a +a +01234567890123456789 +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` varchar(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1, t2; +CREATE TABLE t1 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +col1 VARCHAR (1), +col2 VARCHAR (20), +PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ('a', 'aaaaaaaaaabbbbbbbbbb'); +SELECT REPLACE('aa', col1, col2) FROM t1; +REPLACE('aa', col1, col2) +aaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbb +CREATE TABLE t2 AS SELECT 'a' UNION ALL SELECT REPLACE('aa', col1, col2) FROM t1; +SELECT * FROM t2; +a +a +aaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbb +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` varchar(40) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1, t2; +CREATE TABLE t1 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +col1 VARCHAR (1), +col2 VARCHAR (30), +PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ('a', 'aaaaaaaaaabbbbbbbbbbcccccccccc'); +SELECT REPLACE('aaa', col1, col2) FROM t1; +REPLACE('aaa', col1, col2) +aaaaaaaaaabbbbbbbbbbccccccccccaaaaaaaaaabbbbbbbbbbccccccccccaaaaaaaaaabbbbbbbbbbcccccccccc +CREATE TABLE t2 AS SELECT 'a' UNION ALL SELECT REPLACE('aaa', col1, col2) FROM t1; +SELECT * FROM t2; +a +a +aaaaaaaaaabbbbbbbbbbccccccccccaaaaaaaaaabbbbbbbbbbccccccccccaaaaaaaaaabbbbbbbbbbcccccccccc +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` varchar(90) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1, t2; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/func_replace.test b/mysql-test/main/func_replace.test new file mode 100644 index 00000000000..f06ef99261a --- /dev/null +++ b/mysql-test/main/func_replace.test @@ -0,0 +1,86 @@ +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-17226 Column Data in Truncated on UNION to the length of the first value if using REPLACE +--echo # + +CREATE TABLE t1 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + col1 VARCHAR (2), + col2 VARCHAR (2), + PRIMARY KEY (id) +); +CREATE TABLE t2 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + col1 VARCHAR (1), + col2 VARCHAR (2), + PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ("a", "ba"); +INSERT INTO t2 (col1, col2) VALUES ("a", "ba"); +SELECT 'a' UNION ALL SELECT REPLACE('a', col1, col2) FROM t1; +SELECT 'a' UNION ALL SELECT REPLACE('a', col1, col2) FROM t2; +SELECT REPLACE('z', col1, col2) FROM t1 UNION ALL SELECT REPLACE('a', col1, col2) FROM t1; +SELECT REPLACE('z', col1, col2) FROM t2 UNION ALL SELECT REPLACE('a', col1, col2) FROM t2; +DROP TABLE t1, t2; + + + +CREATE TABLE t1 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + col1 VARCHAR (2), + col2 VARCHAR (2), + PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ('a', 'ba'); +SELECT REPLACE('a', col1, col2) FROM t1; +CREATE TABLE t2 AS SELECT 'a' UNION ALL SELECT REPLACE('a', col1, col2) FROM t1; +SELECT * FROM t2; +SHOW CREATE TABLE t2; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + col1 VARCHAR (1), + col2 VARCHAR (10), + PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ('a', '0123456789'); +SELECT REPLACE('aa', col1, col2) FROM t1; +CREATE TABLE t2 AS SELECT 'a' UNION ALL SELECT REPLACE('aa', col1, col2) FROM t1; +SELECT * FROM t2; +SHOW CREATE TABLE t2; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + col1 VARCHAR (1), + col2 VARCHAR (20), + PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ('a', 'aaaaaaaaaabbbbbbbbbb'); +SELECT REPLACE('aa', col1, col2) FROM t1; +CREATE TABLE t2 AS SELECT 'a' UNION ALL SELECT REPLACE('aa', col1, col2) FROM t1; +SELECT * FROM t2; +SHOW CREATE TABLE t2; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + col1 VARCHAR (1), + col2 VARCHAR (30), + PRIMARY KEY (id) +); +INSERT INTO t1 (col1, col2) VALUES ('a', 'aaaaaaaaaabbbbbbbbbbcccccccccc'); +SELECT REPLACE('aaa', col1, col2) FROM t1; +CREATE TABLE t2 AS SELECT 'a' UNION ALL SELECT REPLACE('aaa', col1, col2) FROM t1; +SELECT * FROM t2; +SHOW CREATE TABLE t2; +DROP TABLE t1, t2; + + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result index 585e927a0d4..3666a458c98 100644 --- a/mysql-test/main/grant.result +++ b/mysql-test/main/grant.result @@ -1960,6 +1960,11 @@ GRANT EXECUTE ON mysqltest_db1.* TO mysqltest_u1@localhost; GRANT FILE ON *.* TO mysqltest_u1@localhost; GRANT CREATE USER ON *.* TO mysqltest_u1@localhost; GRANT PROCESS ON *.* TO mysqltest_u1@localhost; +GRANT RELOAD ON mysqltest_db1.* TO mysqltest_u1@localhost; +ERROR HY000: Incorrect usage of DB GRANT and GLOBAL PRIVILEGES +connect(localhost,mysqltest_u1,,db1,MASTER_PORT,MASTER_SOCKET); +connect con1, localhost, mysqltest_u1, ,db1; +ERROR 42000: Access denied for user 'mysqltest_u1'@'localhost' to database 'db1' GRANT RELOAD ON *.* TO mysqltest_u1@localhost; GRANT REPLICATION CLIENT ON *.* TO mysqltest_u1@localhost; GRANT REPLICATION SLAVE ON *.* TO mysqltest_u1@localhost; diff --git a/mysql-test/main/grant.test b/mysql-test/main/grant.test index a243967a9c7..1c5e2502e3b 100644 --- a/mysql-test/main/grant.test +++ b/mysql-test/main/grant.test @@ -1823,6 +1823,13 @@ GRANT EXECUTE ON mysqltest_db1.* TO mysqltest_u1@localhost; GRANT FILE ON *.* TO mysqltest_u1@localhost; GRANT CREATE USER ON *.* TO mysqltest_u1@localhost; GRANT PROCESS ON *.* TO mysqltest_u1@localhost; +# Global privileges should be granted to all schemas, not individual DB +--error ER_WRONG_USAGE +GRANT RELOAD ON mysqltest_db1.* TO mysqltest_u1@localhost; +# Select privilege is needed beside RELOAD privilege +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_DBACCESS_DENIED_ERROR +--connect (con1, localhost, mysqltest_u1, ,db1) GRANT RELOAD ON *.* TO mysqltest_u1@localhost; GRANT REPLICATION CLIENT ON *.* TO mysqltest_u1@localhost; GRANT REPLICATION SLAVE ON *.* TO mysqltest_u1@localhost; diff --git a/mysql-test/main/group_min_max_innodb.result b/mysql-test/main/group_min_max_innodb.result index fed3d30b16a..27656374aee 100644 --- a/mysql-test/main/group_min_max_innodb.result +++ b/mysql-test/main/group_min_max_innodb.result @@ -330,6 +330,113 @@ JOIN t1 ON dt.a=t1.b; a Australia DROP TABLES t1, t2; +# +# MDEV-15656: Assertion `is_last_prefix <= 0' failed in +# QUICK_GROUP_MIN_MAX_SELECT::get_next +# +SET @lru_depth.save= @@innodb_lru_scan_depth; +SET GLOBAL innodb_lru_scan_depth= 1024; +CREATE TABLE t1 ( +pk_part1 INT AUTO_INCREMENT, +a VARCHAR(4), +row_start timestamp(6) default current_timestamp, +PRIMARY KEY (pk_part1, row_start) +) ENGINE=InnoDB; +INSERT INTO t1 (a) VALUES +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'); +connect con1,localhost,root,,test; +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +SELECT DISTINCT pk_part1 FROM t1; +connection default; +INSERT INTO t1 (pk_part1) VALUES (NULL); +connection con1; +disconnect con1; +connection default; +DROP TABLE t1; +SET GLOBAL innodb_lru_scan_depth= @lru_depth.save; set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/group_min_max_innodb.test b/mysql-test/main/group_min_max_innodb.test index fcecbec41b3..33a3a8888a5 100644 --- a/mysql-test/main/group_min_max_innodb.test +++ b/mysql-test/main/group_min_max_innodb.test @@ -273,6 +273,53 @@ eval $query; DROP TABLES t1, t2; +--echo # +--echo # MDEV-15656: Assertion `is_last_prefix <= 0' failed in +--echo # QUICK_GROUP_MIN_MAX_SELECT::get_next +--echo # +SET @lru_depth.save= @@innodb_lru_scan_depth; +SET GLOBAL innodb_lru_scan_depth= 1024; + +CREATE TABLE t1 ( + pk_part1 INT AUTO_INCREMENT, + a VARCHAR(4), + row_start timestamp(6) default current_timestamp, + PRIMARY KEY (pk_part1, row_start) +) ENGINE=InnoDB; + +INSERT INTO t1 (a) VALUES +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'), +('foo'),('bar'),('foo'),('bar'),('foo'); + +--connect (con1,localhost,root,,test) + +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; + +--let $run= 20 +--disable_result_log +while ($run) +{ + --send + SELECT DISTINCT pk_part1 FROM t1; + --connection default + INSERT INTO t1 (pk_part1) VALUES (NULL); + --connection con1 + --reap + --dec $run +} +--enable_result_log + +--disconnect con1 +--connection default +DROP TABLE t1; +SET GLOBAL innodb_lru_scan_depth= @lru_depth.save; + set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/innodb_ext_key,covering,innodb,on.rdiff b/mysql-test/main/innodb_ext_key,covering,innodb,on.rdiff new file mode 100644 index 00000000000..0d8bcc6ce3c --- /dev/null +++ b/mysql-test/main/innodb_ext_key,covering,innodb,on.rdiff @@ -0,0 +1,20 @@ +--- ./main/innodb_ext_key.result ++++ ./main/innodb_ext_key.reject +@@ -244,7 +244,7 @@ + Variable_name Value + Handler_read_first 0 + Handler_read_key 21 +-Handler_read_last 1 ++Handler_read_last 0 + Handler_read_next 0 + Handler_read_prev 0 + Handler_read_retry 0 +@@ -266,7 +266,7 @@ + Variable_name Value + Handler_read_first 0 + Handler_read_key 6 +-Handler_read_last 1 ++Handler_read_last 0 + Handler_read_next 0 + Handler_read_prev 0 + Handler_read_retry 0 diff --git a/mysql-test/main/innodb_ext_key,innodb,on,unoptimized.rdiff b/mysql-test/main/innodb_ext_key,innodb,on,unoptimized.rdiff new file mode 100644 index 00000000000..0d8bcc6ce3c --- /dev/null +++ b/mysql-test/main/innodb_ext_key,innodb,on,unoptimized.rdiff @@ -0,0 +1,20 @@ +--- ./main/innodb_ext_key.result ++++ ./main/innodb_ext_key.reject +@@ -244,7 +244,7 @@ + Variable_name Value + Handler_read_first 0 + Handler_read_key 21 +-Handler_read_last 1 ++Handler_read_last 0 + Handler_read_next 0 + Handler_read_prev 0 + Handler_read_retry 0 +@@ -266,7 +266,7 @@ + Variable_name Value + Handler_read_first 0 + Handler_read_key 6 +-Handler_read_last 1 ++Handler_read_last 0 + Handler_read_next 0 + Handler_read_prev 0 + Handler_read_retry 0 diff --git a/mysql-test/main/keywords.result b/mysql-test/main/keywords.result index 483a8f7e7e8..4e246e38299 100644 --- a/mysql-test/main/keywords.result +++ b/mysql-test/main/keywords.result @@ -500,21 +500,21 @@ SELECT @@global.rpad(); -- Unknown system variable 'rpad' -------- SELECT @@global.adddate(); -- Unknown system variable 'adddate' -------- -SELECT @@global.substr(); -- Unknown system variable 'substr' +SELECT @@global.substr(); -- ..syntax.. near 'substr()' at line 1 -------- -SELECT @@global.substring(); -- Unknown system variable 'substring' +SELECT @@global.substring(); -- ..syntax.. near 'substring()' at line 1 -------- SELECT @@global.trim_oracle(); -- Unknown system variable 'trim_oracle' -------- SELECT @@global.ascii(); -- Unknown system variable 'ascii' -------- -SELECT @@global.replace(); -- Unknown system variable 'replace' +SELECT @@global.replace(); -- ..syntax.. near 'replace()' at line 1 -------- SELECT @@global.weight_string(); -- Unknown system variable 'weight_string' -------- SELECT @@global.char(); -- Unknown system variable 'char' -------- -SELECT @@global.trim(); -- Unknown system variable 'trim' +SELECT @@global.trim(); -- ..syntax.. near 'trim()' at line 1 -------- SELECT @@global.year(); -- Unknown system variable 'year' -------- @@ -732,21 +732,21 @@ CREATE FUNCTION test.rpad() RETURNS OOPS; -- Unknown data type: 'OOPS' -------- CREATE FUNCTION test.adddate() RETURNS OOPS; -- Unknown data type: 'OOPS' -------- -CREATE FUNCTION test.substr() RETURNS OOPS; -- Unknown data type: 'OOPS' +CREATE FUNCTION test.substr() RETURNS OOPS; -- ..syntax.. near 'substr() RETURNS OOPS' -------- -CREATE FUNCTION test.substring() RETURNS OOPS; -- Unknown data type: 'OOPS' +CREATE FUNCTION test.substring() RETURNS OOPS; -- ..syntax.. near 'substring() RETURNS OOP -------- CREATE FUNCTION test.trim_oracle() RETURNS OOPS; -- Unknown data type: 'OOPS' -------- CREATE FUNCTION test.ascii() RETURNS OOPS; -- Unknown data type: 'OOPS' -------- -CREATE FUNCTION test.replace() RETURNS OOPS; -- Unknown data type: 'OOPS' +CREATE FUNCTION test.replace() RETURNS OOPS; -- ..syntax.. near 'replace() RETURNS OOPS' -------- CREATE FUNCTION test.weight_string() RETURNS OOPS; -- Unknown data type: 'OOPS' -------- CREATE FUNCTION test.char() RETURNS OOPS; -- Unknown data type: 'OOPS' -------- -CREATE FUNCTION test.trim() RETURNS OOPS; -- Unknown data type: 'OOPS' +CREATE FUNCTION test.trim() RETURNS OOPS; -- ..syntax.. near 'trim() RETURNS OOPS' at -------- CREATE FUNCTION test.year() RETURNS OOPS; -- Unknown data type: 'OOPS' -------- diff --git a/mysql-test/main/log_slow_debug.result b/mysql-test/main/log_slow_debug.result index 920b1641d1d..bc934c04bb5 100644 --- a/mysql-test/main/log_slow_debug.result +++ b/mysql-test/main/log_slow_debug.result @@ -287,15 +287,18 @@ SET @old_dbug= @@GLOBAL.debug_dbug; SET GLOBAL log_output= "TABLE"; SET GLOBAL slow_query_log= ON; SET SESSION long_query_time= 0; -SET GLOBAL debug_dbug="+d,debug_huge_number_of_examined_rows"; +SET debug_dbug="+d,debug_huge_number_of_examined_rows"; SELECT * FROM tab_MDEV_30820 ORDER BY 1; ID A 1 0 2 0 -SET GLOBAL debug_dbug=@old_dbug; +SET debug_dbug=@old_dbug; SET @@long_query_time= @old_long_query_time; SET @@global.log_output= @old_log_output; SET @@global.slow_query_log= @old_slow_query_log; +SELECT rows_examined, sql_text from mysql.slow_log where sql_text like "SELECT%FROM tab_MDEV_30820%"; +rows_examined sql_text +18446744073708551615 SELECT * FROM tab_MDEV_30820 ORDER BY 1 drop table tab_MDEV_30820; # # End of 10.4 test diff --git a/mysql-test/main/log_slow_debug.test b/mysql-test/main/log_slow_debug.test index ee0406112d2..456b29536a5 100644 --- a/mysql-test/main/log_slow_debug.test +++ b/mysql-test/main/log_slow_debug.test @@ -170,16 +170,21 @@ SET GLOBAL log_output= "TABLE"; SET GLOBAL slow_query_log= ON; SET SESSION long_query_time= 0; -SET GLOBAL debug_dbug="+d,debug_huge_number_of_examined_rows"; +SET debug_dbug="+d,debug_huge_number_of_examined_rows"; +--disable_ps_protocol +--disable_view_protocol SELECT * FROM tab_MDEV_30820 ORDER BY 1; -SET GLOBAL debug_dbug=@old_dbug; - +--enable_view_protocol +--enable_ps_protocol +SET debug_dbug=@old_dbug; ## Reset to initial values SET @@long_query_time= @old_long_query_time; SET @@global.log_output= @old_log_output; SET @@global.slow_query_log= @old_slow_query_log; +SELECT rows_examined, sql_text from mysql.slow_log where sql_text like "SELECT%FROM tab_MDEV_30820%"; + drop table tab_MDEV_30820; --echo # diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index ce44ae2b6fb..6b5ffc704a6 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -574,5 +574,84 @@ insert into t1 values (1,10),(2,20); update t1 set b = 30 limit 1; drop table t1; # +# MDEV-32839 LONG UNIQUE gives error when used with REPLACE +# +create table t1 ( +f1 bigint(20) not null auto_increment primary key, +f2 varchar(30) default null, +f3 varchar(30) default null, +f4 varchar(255) default null, +f5 varchar(30) default null, +f6 varchar(255) default null, +f7 varchar(255) default null, +unique problem_key (f3,f5,f6,f2,f4,f7) using hash +) engine=myisam; +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +select * from t1; +f1 f2 f3 f4 f5 f6 f7 +2 00004 0001009089999 netstes psit d +4 00004 0001009089999 netstes psit e +drop table t1; +create table t1 ( +f1 bigint(20) not null auto_increment primary key, +f2 varchar(30) default null, +f3 varchar(30) default null, +f4 varchar(255) default null, +f5 varchar(30) default null, +f6 varchar(255) default null, +f7 varchar(255) default null, +unique problem_key (f3,f5,f6,f2,f4,f7) using hash +) engine=innodb; +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +select * from t1; +f1 f2 f3 f4 f5 f6 f7 +2 00004 0001009089999 netstes psit d +4 00004 0001009089999 netstes psit e +drop table t1; +create table t1 ( +f1 bigint(20) not null auto_increment primary key, +f2 varchar(30) default null, +f3 varchar(30) default null, +f4 varchar(255) default null, +f5 varchar(30) default null, +f6 varchar(255) default null, +f7 varchar(255) default null, +unique problem_key (f3,f5,f6,f2,f4,f7) using hash +) engine=myisam partition by key(f1) partitions 2; +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +select * from t1; +f1 f2 f3 f4 f5 f6 f7 +2 00004 0001009089999 netstes psit d +4 00004 0001009089999 netstes psit e +drop table t1; +create table t1 ( +f1 bigint(20) not null auto_increment primary key, +f2 varchar(30) default null, +f3 varchar(30) default null, +f4 varchar(255) default null, +f5 varchar(30) default null, +f6 varchar(255) default null, +f7 varchar(255) default null, +unique problem_key (f3,f5,f6,f2,f4,f7) using hash +) engine=innodb partition by key(f1) partitions 2; +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +select * from t1; +f1 f2 f3 f4 f5 f6 f7 +2 00004 0001009089999 netstes psit d +4 00004 0001009089999 netstes psit e +drop table t1; +# # End of 10.5 tests # diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index ed283424404..5fed7c72d9a 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -563,6 +563,77 @@ insert into t1 values (1,10),(2,20); update t1 set b = 30 limit 1; drop table t1; +--echo # +--echo # MDEV-32839 LONG UNIQUE gives error when used with REPLACE +--echo # +create table t1 ( + f1 bigint(20) not null auto_increment primary key, + f2 varchar(30) default null, + f3 varchar(30) default null, + f4 varchar(255) default null, + f5 varchar(30) default null, + f6 varchar(255) default null, + f7 varchar(255) default null, + unique problem_key (f3,f5,f6,f2,f4,f7) using hash +) engine=myisam; +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +select * from t1; +drop table t1; + +create table t1 ( + f1 bigint(20) not null auto_increment primary key, + f2 varchar(30) default null, + f3 varchar(30) default null, + f4 varchar(255) default null, + f5 varchar(30) default null, + f6 varchar(255) default null, + f7 varchar(255) default null, + unique problem_key (f3,f5,f6,f2,f4,f7) using hash +) engine=innodb; +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +select * from t1; +drop table t1; + +create table t1 ( + f1 bigint(20) not null auto_increment primary key, + f2 varchar(30) default null, + f3 varchar(30) default null, + f4 varchar(255) default null, + f5 varchar(30) default null, + f6 varchar(255) default null, + f7 varchar(255) default null, + unique problem_key (f3,f5,f6,f2,f4,f7) using hash +) engine=myisam partition by key(f1) partitions 2; +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +select * from t1; +drop table t1; + +create table t1 ( + f1 bigint(20) not null auto_increment primary key, + f2 varchar(30) default null, + f3 varchar(30) default null, + f4 varchar(255) default null, + f5 varchar(30) default null, + f6 varchar(255) default null, + f7 varchar(255) default null, + unique problem_key (f3,f5,f6,f2,f4,f7) using hash +) engine=innodb partition by key(f1) partitions 2; +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'd'); +insert t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netstes', 'psit', 'e'); +select * from t1; +drop table t1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/mdl.result b/mysql-test/main/mdl.result index c0f5671c6d4..dd3d9239366 100644 --- a/mysql-test/main/mdl.result +++ b/mysql-test/main/mdl.result @@ -61,7 +61,7 @@ DROP TABLE t1,t3; # # Check MDL locks taken for different kind of tables by open # -CREATE TABLE t1(a INT) ENGINE=InnoDB; +CREATE TABLE t1(a INT) stats_persistent=0, ENGINE=InnoDB; CREATE TABLE t3(a INT) ENGINE=myisam; connect purge_control,localhost,root,,; START TRANSACTION WITH CONSISTENT SNAPSHOT; diff --git a/mysql-test/main/mdl.test b/mysql-test/main/mdl.test index 65d02d77739..6b0c769014e 100644 --- a/mysql-test/main/mdl.test +++ b/mysql-test/main/mdl.test @@ -43,7 +43,7 @@ DROP TABLE t1,t3; --echo # Check MDL locks taken for different kind of tables by open --echo # -CREATE TABLE t1(a INT) ENGINE=InnoDB; +CREATE TABLE t1(a INT) stats_persistent=0, ENGINE=InnoDB; CREATE TABLE t3(a INT) ENGINE=myisam; connect(purge_control,localhost,root,,); START TRANSACTION WITH CONSISTENT SNAPSHOT; diff --git a/mysql-test/main/mdl_sync.result b/mysql-test/main/mdl_sync.result index 0ffe2f745a0..0324c261749 100644 --- a/mysql-test/main/mdl_sync.result +++ b/mysql-test/main/mdl_sync.result @@ -2403,6 +2403,7 @@ connection con2; SET DEBUG_SYNC= 'now WAIT_FOR table_opened'; # Check that FLUSH must wait to get the GRL # and let DROP PROCEDURE continue +InnoDB 0 transactions not purged SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_DDL Backup lock @@ -2427,7 +2428,7 @@ SET DEBUG_SYNC= 'RESET'; # UPDATE should wait for FTWRL with non transactional table second # create table t1 (a int) engine=myisam; -create table t2 (a int) engine=innodb; +create table t2 (a int) stats_persistent=0, engine=innodb; insert into t1 values (1); insert into t2 values (1); SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait execute 2'; diff --git a/mysql-test/main/mdl_sync.test b/mysql-test/main/mdl_sync.test index 557fbe261a2..bfce49d65e3 100644 --- a/mysql-test/main/mdl_sync.test +++ b/mysql-test/main/mdl_sync.test @@ -3085,6 +3085,7 @@ connection con2; SET DEBUG_SYNC= 'now WAIT_FOR table_opened'; --echo # Check that FLUSH must wait to get the GRL --echo # and let DROP PROCEDURE continue +--source ../suite/innodb/include/wait_all_purged.inc SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait'; --send FLUSH TABLES WITH READ LOCK @@ -3110,7 +3111,7 @@ SET DEBUG_SYNC= 'RESET'; --echo # create table t1 (a int) engine=myisam; -create table t2 (a int) engine=innodb; +create table t2 (a int) stats_persistent=0, engine=innodb; insert into t1 values (1); insert into t2 values (1); diff --git a/mysql-test/main/mysql_install_db_win.test b/mysql-test/main/mysql_install_db_win.test index 173e0cc3171..9ead8d7c482 100644 --- a/mysql-test/main/mysql_install_db_win.test +++ b/mysql-test/main/mysql_install_db_win.test @@ -22,7 +22,9 @@ rmdir $ddir; # MDEV-23052 # 1. mysql_install_db works on existing, empty directory mkdir $ddir; -exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --password=foo -R > /dev/null; +disable_result_log; +exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --password=foo -R --verbose-bootstrap; +enable_result_log; rmdir $ddir; # 2. mysql_install_db rejects existing, non-empty directory, and does not diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 1c851b9d06c..62119751ac2 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -543,9 +543,8 @@ The following specify which files/extra groups are read (specified before remain when binary log is disabled). --log-tc-size=# Size of transaction coordinator log. -W, --log-warnings[=#] - Log some not critical warnings to the general log - file.Value can be between 0 and 11. Higher values mean - more verbosity + Log some non critical warnings to the error log.Value can + be between 0 and 11. Higher values mean more verbosity --long-query-time=# Log all queries that have taken more than long_query_time seconds to execute to the slow query log file. The argument will be treated as a decimal value with diff --git a/mysql-test/main/order_by.result b/mysql-test/main/order_by.result index 4039b06d3fa..86060229a84 100644 --- a/mysql-test/main/order_by.result +++ b/mysql-test/main/order_by.result @@ -3727,6 +3727,126 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.t2.b 1 Using where DROP TABLE t1,t2; +# +# MDEV-29681 Server crashes when optimizing SQL with ORDER BY +# +CREATE TABLE t1 (b INT); +CREATE TABLE t2 (a INT, c INT); +# First test empty tables +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a+1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY system NULL NULL NULL NULL 0 0.00 Const row not found +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table +Warnings: +Note 1003 /* select#1 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from ((/* select#2 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from `test`.`t1` join `test`.`t2` where 0 limit 3)) `__2` order by NULL + 1 +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY system NULL NULL NULL NULL 0 0.00 Const row not found +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table +Warnings: +Note 1003 /* select#1 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from ((/* select#2 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from `test`.`t1` join `test`.`t2` where 0 limit 3)) `__2` order by NULL = 2 +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) +ORDER BY a+1, a-b DESC, c<>a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY system NULL NULL NULL NULL 0 0.00 Const row not found +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table +Warnings: +Note 1003 /* select#1 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from ((/* select#2 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from `test`.`t1` join `test`.`t2` where 0 limit 3)) `__2` order by NULL + 1,NULL - NULL desc,NULL <> NULL +# Insert some data +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3),(4,4); +(SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=b, a-10 DESC, b+a, c+a+a+b; +b a c +1 1 1 +2 2 2 +3 3 3 +(SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=2; +b a c +1 1 1 +2 2 2 +3 3 3 +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) +ORDER BY a=b, a-10, b+a, c+a+a+b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 3 100.00 Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00 +2 DERIVED t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 /* select#1 */ select `__2`.`b` AS `b`,`__2`.`a` AS `a`,`__2`.`c` AS `c` from ((/* select#2 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` limit 3)) `__2` order by `__2`.`a` = `__2`.`b`,`__2`.`a` - 10,`__2`.`b` + `__2`.`a`,`__2`.`c` + `__2`.`a` + `__2`.`a` + `__2`.`b` +# When there is no LIMIT clause the derived table must be merged +(SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a+16, b+a, c<>b; +b a c +1 1 1 +2 2 2 +3 3 3 +4 4 4 +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a+16 DESC, b+a, c<>b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using temporary; Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 (select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` order by `test`.`t2`.`a` + 16 desc,`test`.`t1`.`b` + `test`.`t2`.`a`,`test`.`t2`.`c` <> `test`.`t1`.`b`) +# Test UNIONs: +(SELECT * FROM t1 JOIN t2 ON a=b UNION +SELECT * FROM t1 JOIN t2 ON a!=b +LIMIT 3) +ORDER BY a+16, b+a, c<>b; +b a c +1 1 1 +2 2 2 +3 3 3 +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION +SELECT * FROM t1 JOIN t2 ON a!=b +LIMIT 3) +ORDER BY a+16, b+a, c<>b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 32 100.00 Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00 +2 DERIVED t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +3 UNION t1 ALL NULL NULL NULL NULL 4 100.00 +3 UNION t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select `__3`.`b` AS `b`,`__3`.`a` AS `a`,`__3`.`c` AS `c` from (/* select#2 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` union /* select#3 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` <> `test`.`t1`.`b` limit 3) `__3` order by `__3`.`a` + 16,`__3`.`b` + `__3`.`a`,`__3`.`c` <> `__3`.`b` +(SELECT * FROM t1 JOIN t2 ON a=b UNION +SELECT NULL, NULL, NULL +LIMIT 3) +ORDER BY b-a-c; +b a c +1 1 1 +2 2 2 +3 3 3 +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION +SELECT NULL, NULL, NULL +LIMIT 3) +ORDER BY b-a-c; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 16 100.00 Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00 +2 DERIVED t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select `__3`.`b` AS `b`,`__3`.`a` AS `a`,`__3`.`c` AS `c` from (/* select#2 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` union /* select#3 */ select NULL AS `NULL`,NULL AS `NULL`,NULL AS `NULL` limit 3) `__3` order by `__3`.`b` - `__3`.`a` - `__3`.`c` +(SELECT * FROM t1 JOIN t2 ON a=b UNION +SELECT NULL, NULL, NULL +ORDER BY a LIMIT 3) +ORDER BY b-a-c LIMIT 1; +b a c +NULL NULL NULL +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION +SELECT NULL, NULL, NULL +ORDER BY a LIMIT 3) +ORDER BY b-a-c LIMIT 1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 16 100.00 Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00 +2 DERIVED t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 /* select#1 */ select `__3`.`b` AS `b`,`__3`.`a` AS `a`,`__3`.`c` AS `c` from (/* select#2 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` union /* select#3 */ select NULL AS `NULL`,NULL AS `NULL`,NULL AS `NULL` order by `a` limit 3) `__3` order by `__3`.`b` - `__3`.`a` - `__3`.`c` limit 1 +DROP TABLE t1, t2; # End of 10.4 tests # # MDEV-21655: Server crashes in my_qsort2 / Filesort_buffer::sort_buffer diff --git a/mysql-test/main/order_by.test b/mysql-test/main/order_by.test index ac5e99c555c..7603e912408 100644 --- a/mysql-test/main/order_by.test +++ b/mysql-test/main/order_by.test @@ -2469,6 +2469,65 @@ EXPLAIN SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FRO DROP TABLE t1,t2; +--echo # +--echo # MDEV-29681 Server crashes when optimizing SQL with ORDER BY +--echo # +CREATE TABLE t1 (b INT); +CREATE TABLE t2 (a INT, c INT); + +--echo # First test empty tables +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a+1; +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=2; +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) + ORDER BY a+1, a-b DESC, c<>a; + +--echo # Insert some data +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3),(4,4); + +--sorted_result +(SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=b, a-10 DESC, b+a, c+a+a+b; +--sorted_result +(SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=2; + +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) + ORDER BY a=b, a-10, b+a, c+a+a+b; + +--echo # When there is no LIMIT clause the derived table must be merged +--sorted_result +(SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a+16, b+a, c<>b; +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a+16 DESC, b+a, c<>b; + +--echo # Test UNIONs: +--sorted_result +(SELECT * FROM t1 JOIN t2 ON a=b UNION + SELECT * FROM t1 JOIN t2 ON a!=b + LIMIT 3) + ORDER BY a+16, b+a, c<>b; +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION + SELECT * FROM t1 JOIN t2 ON a!=b + LIMIT 3) + ORDER BY a+16, b+a, c<>b; +--sorted_result +(SELECT * FROM t1 JOIN t2 ON a=b UNION + SELECT NULL, NULL, NULL + LIMIT 3) + ORDER BY b-a-c; +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION + SELECT NULL, NULL, NULL + LIMIT 3) + ORDER BY b-a-c; +--sorted_result +(SELECT * FROM t1 JOIN t2 ON a=b UNION + SELECT NULL, NULL, NULL + ORDER BY a LIMIT 3) + ORDER BY b-a-c LIMIT 1; +EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION + SELECT NULL, NULL, NULL + ORDER BY a LIMIT 3) + ORDER BY b-a-c LIMIT 1; +DROP TABLE t1, t2; + --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/partition_innodb.result b/mysql-test/main/partition_innodb.result index 95ca989eabf..606355741a4 100644 --- a/mysql-test/main/partition_innodb.result +++ b/mysql-test/main/partition_innodb.result @@ -198,6 +198,10 @@ INSERT INTO t1 VALUES (100); ERROR HY000: Table has no partition for value 100 insert INTO t1 VALUES (110); ERROR HY000: Table has no partition for value 110 +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 90; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables @@ -401,7 +405,7 @@ t1 InnoDB 10 Dynamic 2 8192 16384 0 0 0 NULL Create_time NULL NULL latin1_swedis insert into t1 values (0), (1), (2), (3); show table status; 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 10 Dynamic 4 4096 16384 0 0 0 NULL Create_time Update_time NULL latin1_swedish_ci NULL partitioned 0 N +t1 InnoDB 10 Dynamic Rows Avg_row_length 16384 0 0 0 NULL Create_time Update_time NULL latin1_swedish_ci NULL partitioned 0 N drop table t1; create table t1 (a int auto_increment primary key) engine = innodb @@ -412,11 +416,11 @@ t1 InnoDB 10 Dynamic 2 8192 16384 0 0 0 1 Create_time NULL NULL latin1_swedish_c insert into t1 values (NULL), (NULL), (NULL), (NULL); show table status; 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 10 Dynamic 4 4096 16384 0 0 0 5 Create_time Update_time NULL latin1_swedish_ci NULL partitioned 0 N +t1 InnoDB 10 Dynamic Rows Avg_row_length 16384 0 0 0 5 Create_time Update_time NULL latin1_swedish_ci NULL partitioned 0 N insert into t1 values (NULL), (NULL), (NULL), (NULL); show table status; 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 10 Dynamic 8 2048 16384 0 0 0 9 Create_time Update_time NULL latin1_swedish_ci NULL partitioned 0 N +t1 InnoDB 10 Dynamic Rows Avg_row_length 16384 0 0 0 9 Create_time Update_time NULL latin1_swedish_ci NULL partitioned 0 N drop table t1; create table t1 (a int) partition by key (a) diff --git a/mysql-test/main/partition_innodb.test b/mysql-test/main/partition_innodb.test index 563a750b81b..e9771811534 100644 --- a/mysql-test/main/partition_innodb.test +++ b/mysql-test/main/partition_innodb.test @@ -208,6 +208,7 @@ INSERT INTO t1 VALUES (90); INSERT INTO t1 VALUES (100); --error ER_NO_PARTITION_FOR_GIVEN_VALUE insert INTO t1 VALUES (110); +ANALYZE TABLE t1; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 90; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 90; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 90; @@ -420,7 +421,9 @@ partition by key (a); --replace_column 12 Create_time show table status; insert into t1 values (0), (1), (2), (3); ---replace_column 12 Create_time 13 Update_time +# Mask `Rows`, as it can fluctuate slightly if background statistics are +# running simultaneously with insert (MDEV-20169). +--replace_column 5 Rows 6 Avg_row_length 12 Create_time 13 Update_time show table status; drop table t1; @@ -430,10 +433,10 @@ partition by key (a); --replace_column 12 Create_time show table status; insert into t1 values (NULL), (NULL), (NULL), (NULL); ---replace_column 12 Create_time 13 Update_time +--replace_column 5 Rows 6 Avg_row_length 12 Create_time 13 Update_time show table status; insert into t1 values (NULL), (NULL), (NULL), (NULL); ---replace_column 12 Create_time 13 Update_time +--replace_column 5 Rows 6 Avg_row_length 12 Create_time 13 Update_time show table status; drop table t1; diff --git a/mysql-test/main/ps_mem_leaks.result b/mysql-test/main/ps_mem_leaks.result index 8d66a025c1a..2ddf47a992c 100644 --- a/mysql-test/main/ps_mem_leaks.result +++ b/mysql-test/main/ps_mem_leaks.result @@ -3,6 +3,20 @@ # CREATE TABLE t1 (a VARCHAR(10)) ENGINE=MYISAM; CREATE TABLE t2 (b VARCHAR(10) CHARACTER SET utf8) ENGINE=MYISAM; +INSERT INTO t1 VALUES ('b'), ('a'), ('c'); +INSERT INTO t2 VALUES ('c'), ('d'), ('b'); +PREPARE stmt FROM "SELECT t1.a FROM t1 WHERE t1.a IN (SELECT t2.b FROM t2)"; +EXECUTE stmt; +a +c +b +EXECUTE stmt; +a +c +b +DEALLOCATE PREPARE stmt; +DELETE FROM t1; +DELETE FROM t2; INSERT INTO t1 VALUES ('b'); INSERT INTO t2 VALUES ('b'); PREPARE stmt FROM "SELECT t1.a FROM t1 WHERE t1.a IN (SELECT t2.b FROM t2)"; @@ -14,3 +28,64 @@ a b DEALLOCATE PREPARE stmt; DROP TABLE t1, t2; +# +# MDEV-32569: Failure when executing PS for query using IN subquery +# +CREATE TABLE t1 (a varchar(10)) ENGINE=MYISAM; +CREATE TABLE t2 (b varchar(10) CHARACTER SET utf8) ENGINE=MYISAM; +INSERT INTO t1 VALUES ('b'); +INSERT INTO t2 VALUES ('b'); +PREPARE stmt FROM +"SELECT STRAIGHT_JOIN t1.a FROM t1 WHERE t1.a IN (SELECT t2.b FROM t2)"; +EXECUTE stmt; +a +b +EXECUTE stmt; +a +b +DEALLOCATE PREPARE stmt; +DROP TABLE t1,t2; +# +# MDEV-32733: Two JSON related tests running in PS mode fail on server +# built with -DWITH_PROTECT_STATEMENT_MEMROOT=YES +# +PREPARE stmt FROM "select json_contains_path('{\"key1\":1}', 'oNE', '$.key2[1]') as exp"; +EXECUTE stmt; +exp +0 +EXECUTE stmt; +exp +0 +DEALLOCATE PREPARE stmt; +# +# MDEV-32466: Potential memory leak on execuing of create view statement +# +CREATE FUNCTION f1 () RETURNS VARCHAR(1) +BEGIN +DECLARE rec1 ROW TYPE OF v1; +SELECT z INTO rec1 FROM v1; +RETURN 1; +END| +CREATE FUNCTION f2 () RETURNS VARCHAR(1) RETURN '!'; +CREATE VIEW v1 AS SELECT f2() z; +PREPARE stmt FROM "SELECT f1()"; +EXECUTE stmt; +f1() +1 +EXECUTE stmt; +f1() +1 +DEALLOCATE PREPARE stmt; +DROP FUNCTION f1; +DROP VIEW v1; +DROP FUNCTION f2; +# +# MDEV-32867: ASAN errors in Item_func_json_contains_path::val_int upon PS execution +# +CREATE TABLE t1 (f BLOB) ENGINE=MyISAM; +PREPARE stmt FROM "SELECT * FROM t1 WHERE JSON_EXISTS(JSON_ARRAY('[true,1234567890]'), '$**.*') != JSON_CONTAINS_PATH(JSON_INSERT('{}', '$[1]', NULL), 'all', '$[1]')"; +EXECUTE stmt; +f +DEALLOCATE PREPARE stmt; +DROP TABLE t1; +# End of 10.4 tests diff --git a/mysql-test/main/ps_mem_leaks.test b/mysql-test/main/ps_mem_leaks.test index 2e357f9400c..dacb4ecabba 100644 --- a/mysql-test/main/ps_mem_leaks.test +++ b/mysql-test/main/ps_mem_leaks.test @@ -13,6 +13,19 @@ CREATE TABLE t1 (a VARCHAR(10)) ENGINE=MYISAM; CREATE TABLE t2 (b VARCHAR(10) CHARACTER SET utf8) ENGINE=MYISAM; +INSERT INTO t1 VALUES ('b'), ('a'), ('c'); +INSERT INTO t2 VALUES ('c'), ('d'), ('b'); + +PREPARE stmt FROM "SELECT t1.a FROM t1 WHERE t1.a IN (SELECT t2.b FROM t2)"; + +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; + +DELETE FROM t1; +DELETE FROM t2; + INSERT INTO t1 VALUES ('b'); INSERT INTO t2 VALUES ('b'); @@ -25,3 +38,75 @@ DEALLOCATE PREPARE stmt; DROP TABLE t1, t2; +--echo # +--echo # MDEV-32569: Failure when executing PS for query using IN subquery +--echo # + +CREATE TABLE t1 (a varchar(10)) ENGINE=MYISAM; +CREATE TABLE t2 (b varchar(10) CHARACTER SET utf8) ENGINE=MYISAM; + +INSERT INTO t1 VALUES ('b'); +INSERT INTO t2 VALUES ('b'); + +PREPARE stmt FROM +"SELECT STRAIGHT_JOIN t1.a FROM t1 WHERE t1.a IN (SELECT t2.b FROM t2)"; + +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; + +DROP TABLE t1,t2; + +--echo # +--echo # MDEV-32733: Two JSON related tests running in PS mode fail on server +--echo # built with -DWITH_PROTECT_STATEMENT_MEMROOT=YES +--echo # +PREPARE stmt FROM "select json_contains_path('{\"key1\":1}', 'oNE', '$.key2[1]') as exp"; + +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; + +--echo # +--echo # MDEV-32466: Potential memory leak on execuing of create view statement +--echo # + +--delimiter | + +CREATE FUNCTION f1 () RETURNS VARCHAR(1) +BEGIN + DECLARE rec1 ROW TYPE OF v1; + SELECT z INTO rec1 FROM v1; + RETURN 1; +END| +--delimiter ; + +CREATE FUNCTION f2 () RETURNS VARCHAR(1) RETURN '!'; +CREATE VIEW v1 AS SELECT f2() z; + +PREPARE stmt FROM "SELECT f1()"; +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; + +# Clean up +DROP FUNCTION f1; +DROP VIEW v1; +DROP FUNCTION f2; + +--echo # +--echo # MDEV-32867: ASAN errors in Item_func_json_contains_path::val_int upon PS execution +--echo # +CREATE TABLE t1 (f BLOB) ENGINE=MyISAM; + +PREPARE stmt FROM "SELECT * FROM t1 WHERE JSON_EXISTS(JSON_ARRAY('[true,1234567890]'), '$**.*') != JSON_CONTAINS_PATH(JSON_INSERT('{}', '$[1]', NULL), 'all', '$[1]')"; +EXECUTE stmt; + +# Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + +--echo # End of 10.4 tests diff --git a/mysql-test/main/rpl_mysqldump_slave.result b/mysql-test/main/rpl_mysqldump_slave.result index 903b671178f..9f93e3c405e 100644 --- a/mysql-test/main/rpl_mysqldump_slave.result +++ b/mysql-test/main/rpl_mysqldump_slave.result @@ -65,4 +65,20 @@ SET GLOBAL gtid_slave_pos='0-2-1003'; -- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; CHANGE MASTER TO MASTER_USE_GTID=slave_pos; SET GLOBAL gtid_slave_pos='0-2-1003'; +connection master; +CREATE TABLE t ( +id int +); +insert into t values (1); +insert into t values (2); +drop table t; +connection slave; +include/stop_slave.inc +change master to master_use_gtid=slave_pos; +connection master; +# Ensuring the binlog dump thread is killed on primary... +-- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000002', MASTER_LOG_POS=BINLOG_START; +-- SET GLOBAL gtid_slave_pos='0-1-1005'; +connection slave; +include/start_slave.inc include/rpl_end.inc diff --git a/mysql-test/main/rpl_mysqldump_slave.test b/mysql-test/main/rpl_mysqldump_slave.test index 345bdb82535..0273e196db5 100644 --- a/mysql-test/main/rpl_mysqldump_slave.test +++ b/mysql-test/main/rpl_mysqldump_slave.test @@ -83,6 +83,76 @@ DROP TABLE t2; --replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ --exec $MYSQL_DUMP_SLAVE --compact --master-data --single-transaction --gtid test +# +# MDEV-32611 Added test for mysqldump --delete-master-logs option. +# This options is alias of +# get binlogs: show master status -> flush logs -> purge binary logs to +# sequence and this test is derived using the same pattern. +# +connection master; + +CREATE TABLE t ( + id int +); + +insert into t values (1); +insert into t values (2); + +drop table t; + +--sync_slave_with_master + +# MDEV-32953: Because --delete-master-logs immediately purges logs after +# flushing, it is possible the binlog dump threads will still be using the old +# log when the purge executes, disallowing the file from being deleted. +# Therefore, we temporarily stop the slave so there is no chance the old binlog +# is still being referenced. master_use_gtid=Slave_pos is necessary to still +# appear up-to-date to the master on restart after the master has flushed the +# logs (while the slave is offline). Otherwise (i.e. if using binlog file/pos), +# the slave would point to a purged log file, and receive an error immediately +# upon connecting to the master. +--source include/stop_slave.inc +change master to master_use_gtid=slave_pos; + +connection master; + +--echo # Ensuring the binlog dump thread is killed on primary... +--disable_query_log +--let $binlog_dump_thd_tid= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND LIKE 'Binlog Dump'` +if ($binlog_dump_thd_tid) +{ + --eval kill $binlog_dump_thd_tid +} +--let $wait_condition= SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND LIKE 'Binlog Dump' +--source include/wait_condition.inc +--enable_query_log + +--let $predump_binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) + +# Execute mysqldump with delete-master-logs option +--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ +--exec $MYSQL_DUMP --compact --no-create-info --no-data --delete-master-logs test + +--let $postdump_binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) + +--let $postdump_first_binary_log_filename= query_get_value(SHOW BINARY LOGS, Log_name, 1) + +if ($predump_binlog_filename == $postdump_binlog_filename) +{ + --echo # predump_binlog_filename: $predump_binlog_filename + --echo # postdump_binlog_filename: $postdump_binlog_filename + --die Master state didn't change after mariadb-dump with --delete-master-logs. +} + +if ($postdump_first_binary_log_filename != $postdump_binlog_filename) +{ + --echo # postdump_first_binary_log_filename: $postdump_first_binary_log_filename + --echo # postdump_binlog_filename: $postdump_binlog_filename + --die Master binlog wasn't deleted after mariadb-dump with --delete-master-logs. +} + +connection slave; +--source include/start_slave.inc --source include/rpl_end.inc diff --git a/mysql-test/main/show_check.result b/mysql-test/main/show_check.result index 26c96a5114b..10f3014a497 100644 --- a/mysql-test/main/show_check.result +++ b/mysql-test/main/show_check.result @@ -104,19 +104,19 @@ drop table t1; show variables like "wait_timeout%"; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def information_schema SESSION_VARIABLES SESSION_VARIABLES VARIABLE_NAME Variable_name 253 64 12 N 4097 0 8 -def information_schema SESSION_VARIABLES SESSION_VARIABLES VARIABLE_VALUE Value 253 2048 5 N 4097 0 8 +def information_schema SESSION_VARIABLES SESSION_VARIABLES VARIABLE_VALUE Value 253 4096 5 N 4097 0 8 Variable_name Value wait_timeout 28800 show variables like "WAIT_timeout%"; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def information_schema SESSION_VARIABLES SESSION_VARIABLES VARIABLE_NAME Variable_name 253 64 12 N 4097 0 8 -def information_schema SESSION_VARIABLES SESSION_VARIABLES VARIABLE_VALUE Value 253 2048 5 N 4097 0 8 +def information_schema SESSION_VARIABLES SESSION_VARIABLES VARIABLE_VALUE Value 253 4096 5 N 4097 0 8 Variable_name Value wait_timeout 28800 show variables like "this_doesn't_exists%"; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def information_schema SESSION_VARIABLES SESSION_VARIABLES VARIABLE_NAME Variable_name 253 64 0 N 4097 0 8 -def information_schema SESSION_VARIABLES SESSION_VARIABLES VARIABLE_VALUE Value 253 2048 0 N 4097 0 8 +def information_schema SESSION_VARIABLES SESSION_VARIABLES VARIABLE_VALUE Value 253 4096 0 N 4097 0 8 Variable_name Value show table status from test like "this_doesn't_exists%"; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr diff --git a/mysql-test/main/subselect.result b/mysql-test/main/subselect.result index 32652244353..9fbf36e3d6e 100644 --- a/mysql-test/main/subselect.result +++ b/mysql-test/main/subselect.result @@ -1318,7 +1318,7 @@ a SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(3) DEFAULT NULL + `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; create table t1 (a int); @@ -7161,23 +7161,26 @@ drop table t1; # # MDEV-7565: Server crash with Signal 6 (part 2) # +create table t1 (id int not null primary key); Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` Group By TestCase.Revenue, TestCase.TemplateID; ControlRev NULL +drop table t1; # # MDEV-7445:Server crash with Signal 6 # +create table t1 (id int not null primary key); CREATE PROCEDURE procedure2() BEGIN Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` @@ -7190,6 +7193,7 @@ call procedure2(); ControlRev NULL drop procedure procedure2; +drop table t1; # # MDEV-7846:Server crashes in Item_subselect::fix #_fields or fails with Thread stack overrun @@ -7495,6 +7499,45 @@ ERROR HY000: Illegal parameter data types row and boolean for operation '=' SELECT ROW(1,2) = (1 = ANY (SELECT 1 UNION SELECT 2)); ERROR HY000: Illegal parameter data types row and boolean for operation '=' # +# MDEV-29070 SIGSEGV in my_decimal::operator= and Assertion `0' failed +# in Item_type_holder::val_decimal on SELECT +# +CREATE TABLE t1(a INT UNIQUE); +INSERT INTO t1(a) VALUES (1); +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT 1, 1); +a +1 +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT a, a); +a +1 +UPDATE t1 SET a = 0 +WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT +1 / +1, a FROM t1 WHERE a > -0+1) IN (SELECT a, a); +SELECT a FROM t1 WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT + 1 / + 1, a FROM t1 +WHERE a > -0 + 1) IN (SELECT a, a); +a +CREATE TABLE x (x INT); +INSERT INTO x (x) VALUES (1); +UPDATE x SET x = 1 WHERE x = 1; +INSERT INTO x (x) VALUES (1), (1); +WITH RECURSIVE x (x) AS ( +SELECT 1 INTERSECT +SELECT -(SELECT 1.000000 AS x +UNION +SELECT 1.000000 ORDER BY NOT x < 'x', +-(SELECT 1 + x/1.000000 IN (1, 1) FROM x +WHERE x ORDER BY 1 - x) DESC LIMIT 1 OFFSET 1 +) + 1 FROM x +) +SELECT DISTINCT x, 1, NULL, 1.000000 +FROM x +WHERE (SELECT (SELECT x WHERE x IN (SELECT x FROM x))) > +(SELECT (SELECT x ORDER BY x = x OR (x = 1 AND x = 1) DESC)) +ORDER BY x ASC, x DESC, x; +ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'x' +DROP TABLE t1, x; +# # End of 10.4 tests # # diff --git a/mysql-test/main/subselect.test b/mysql-test/main/subselect.test index 97869a702c5..002d5ced6e3 100644 --- a/mysql-test/main/subselect.test +++ b/mysql-test/main/subselect.test @@ -1180,8 +1180,10 @@ create table t1 (a int, b decimal(13, 3)); insert into t1 values (1, 0.123); let $outfile_abs= $MYSQLTEST_VARDIR/tmp/subselect.out.file.1; let $outfile_rel= ../../tmp/subselect.out.file.1; +--disable_warnings --error 0,1 --remove_file $outfile_abs +--enable_warnings eval select a, (select max(b) from t1) into outfile "$outfile_rel" from t1; delete from t1; eval load data infile "$outfile_rel" into table t1; @@ -6000,24 +6002,28 @@ drop table t1; --echo # --echo # MDEV-7565: Server crash with Signal 6 (part 2) --echo # + +create table t1 (id int not null primary key); Select - (Select Sum(`TestCase`.Revenue) From mysql.slow_log E - Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) + (Select Sum(`TestCase`.Revenue) From t1 E + Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` Group By TestCase.Revenue, TestCase.TemplateID; +drop table t1; --echo # --echo # MDEV-7445:Server crash with Signal 6 --echo # +create table t1 (id int not null primary key); --delimiter | CREATE PROCEDURE procedure2() BEGIN Select - (Select Sum(`TestCase`.Revenue) From mysql.slow_log E - Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) + (Select Sum(`TestCase`.Revenue) From t1 E + Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` @@ -6029,6 +6035,7 @@ call procedure2(); call procedure2(); drop procedure procedure2; +drop table t1; --echo # @@ -6350,6 +6357,50 @@ SELECT ROW(1,2) = 1 IN (SELECT 1 UNION SELECT 2); --error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION SELECT ROW(1,2) = (1 = ANY (SELECT 1 UNION SELECT 2)); +--echo # +--echo # MDEV-29070 SIGSEGV in my_decimal::operator= and Assertion `0' failed +--echo # in Item_type_holder::val_decimal on SELECT +--echo # + +CREATE TABLE t1(a INT UNIQUE); +INSERT INTO t1(a) VALUES (1); + +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT 1, 1); + +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT a, a); + +UPDATE t1 SET a = 0 + WHERE (SELECT a, a WHERE a < 0 INTERSECT + SELECT +1 / +1, a FROM t1 WHERE a > -0+1) IN (SELECT a, a); + +SELECT a FROM t1 WHERE (SELECT a, a WHERE a < 0 INTERSECT + SELECT + 1 / + 1, a FROM t1 + WHERE a > -0 + 1) IN (SELECT a, a); + +CREATE TABLE x (x INT); +INSERT INTO x (x) VALUES (1); +UPDATE x SET x = 1 WHERE x = 1; +INSERT INTO x (x) VALUES (1), (1); +let $q= WITH RECURSIVE x (x) AS ( + SELECT 1 INTERSECT + SELECT -(SELECT 1.000000 AS x + UNION + SELECT 1.000000 ORDER BY NOT x < 'x', + -(SELECT 1 + x/1.000000 IN (1, 1) FROM x + WHERE x ORDER BY 1 - x) DESC LIMIT 1 OFFSET 1 + ) + 1 FROM x + ) + SELECT DISTINCT x, 1, NULL, 1.000000 + FROM x + WHERE (SELECT (SELECT x WHERE x IN (SELECT x FROM x))) > + (SELECT (SELECT x ORDER BY x = x OR (x = 1 AND x = 1) DESC)) + ORDER BY x ASC, x DESC, x; + +--error ER_NOT_STANDARD_COMPLIANT_RECURSIVE +eval $q; + +DROP TABLE t1, x; + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/subselect_no_exists_to_in.result b/mysql-test/main/subselect_no_exists_to_in.result index 2f9b36d19f6..0fdd573b339 100644 --- a/mysql-test/main/subselect_no_exists_to_in.result +++ b/mysql-test/main/subselect_no_exists_to_in.result @@ -1322,7 +1322,7 @@ a SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(3) DEFAULT NULL + `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; create table t1 (a int); @@ -7161,23 +7161,26 @@ drop table t1; # # MDEV-7565: Server crash with Signal 6 (part 2) # +create table t1 (id int not null primary key); Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` Group By TestCase.Revenue, TestCase.TemplateID; ControlRev NULL +drop table t1; # # MDEV-7445:Server crash with Signal 6 # +create table t1 (id int not null primary key); CREATE PROCEDURE procedure2() BEGIN Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` @@ -7190,6 +7193,7 @@ call procedure2(); ControlRev NULL drop procedure procedure2; +drop table t1; # # MDEV-7846:Server crashes in Item_subselect::fix #_fields or fails with Thread stack overrun @@ -7495,6 +7499,45 @@ ERROR HY000: Illegal parameter data types row and boolean for operation '=' SELECT ROW(1,2) = (1 = ANY (SELECT 1 UNION SELECT 2)); ERROR HY000: Illegal parameter data types row and boolean for operation '=' # +# MDEV-29070 SIGSEGV in my_decimal::operator= and Assertion `0' failed +# in Item_type_holder::val_decimal on SELECT +# +CREATE TABLE t1(a INT UNIQUE); +INSERT INTO t1(a) VALUES (1); +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT 1, 1); +a +1 +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT a, a); +a +1 +UPDATE t1 SET a = 0 +WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT +1 / +1, a FROM t1 WHERE a > -0+1) IN (SELECT a, a); +SELECT a FROM t1 WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT + 1 / + 1, a FROM t1 +WHERE a > -0 + 1) IN (SELECT a, a); +a +CREATE TABLE x (x INT); +INSERT INTO x (x) VALUES (1); +UPDATE x SET x = 1 WHERE x = 1; +INSERT INTO x (x) VALUES (1), (1); +WITH RECURSIVE x (x) AS ( +SELECT 1 INTERSECT +SELECT -(SELECT 1.000000 AS x +UNION +SELECT 1.000000 ORDER BY NOT x < 'x', +-(SELECT 1 + x/1.000000 IN (1, 1) FROM x +WHERE x ORDER BY 1 - x) DESC LIMIT 1 OFFSET 1 +) + 1 FROM x +) +SELECT DISTINCT x, 1, NULL, 1.000000 +FROM x +WHERE (SELECT (SELECT x WHERE x IN (SELECT x FROM x))) > +(SELECT (SELECT x ORDER BY x = x OR (x = 1 AND x = 1) DESC)) +ORDER BY x ASC, x DESC, x; +ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'x' +DROP TABLE t1, x; +# # End of 10.4 tests # # diff --git a/mysql-test/main/subselect_no_mat.result b/mysql-test/main/subselect_no_mat.result index 7e692c1a5e1..5183d50cd49 100644 --- a/mysql-test/main/subselect_no_mat.result +++ b/mysql-test/main/subselect_no_mat.result @@ -1325,7 +1325,7 @@ a SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(3) DEFAULT NULL + `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; create table t1 (a int); @@ -7154,23 +7154,26 @@ drop table t1; # # MDEV-7565: Server crash with Signal 6 (part 2) # +create table t1 (id int not null primary key); Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` Group By TestCase.Revenue, TestCase.TemplateID; ControlRev NULL +drop table t1; # # MDEV-7445:Server crash with Signal 6 # +create table t1 (id int not null primary key); CREATE PROCEDURE procedure2() BEGIN Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` @@ -7183,6 +7186,7 @@ call procedure2(); ControlRev NULL drop procedure procedure2; +drop table t1; # # MDEV-7846:Server crashes in Item_subselect::fix #_fields or fails with Thread stack overrun @@ -7488,6 +7492,45 @@ ERROR HY000: Illegal parameter data types row and boolean for operation '=' SELECT ROW(1,2) = (1 = ANY (SELECT 1 UNION SELECT 2)); ERROR HY000: Illegal parameter data types row and boolean for operation '=' # +# MDEV-29070 SIGSEGV in my_decimal::operator= and Assertion `0' failed +# in Item_type_holder::val_decimal on SELECT +# +CREATE TABLE t1(a INT UNIQUE); +INSERT INTO t1(a) VALUES (1); +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT 1, 1); +a +1 +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT a, a); +a +1 +UPDATE t1 SET a = 0 +WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT +1 / +1, a FROM t1 WHERE a > -0+1) IN (SELECT a, a); +SELECT a FROM t1 WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT + 1 / + 1, a FROM t1 +WHERE a > -0 + 1) IN (SELECT a, a); +a +CREATE TABLE x (x INT); +INSERT INTO x (x) VALUES (1); +UPDATE x SET x = 1 WHERE x = 1; +INSERT INTO x (x) VALUES (1), (1); +WITH RECURSIVE x (x) AS ( +SELECT 1 INTERSECT +SELECT -(SELECT 1.000000 AS x +UNION +SELECT 1.000000 ORDER BY NOT x < 'x', +-(SELECT 1 + x/1.000000 IN (1, 1) FROM x +WHERE x ORDER BY 1 - x) DESC LIMIT 1 OFFSET 1 +) + 1 FROM x +) +SELECT DISTINCT x, 1, NULL, 1.000000 +FROM x +WHERE (SELECT (SELECT x WHERE x IN (SELECT x FROM x))) > +(SELECT (SELECT x ORDER BY x = x OR (x = 1 AND x = 1) DESC)) +ORDER BY x ASC, x DESC, x; +ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'x' +DROP TABLE t1, x; +# # End of 10.4 tests # # diff --git a/mysql-test/main/subselect_no_opts.result b/mysql-test/main/subselect_no_opts.result index 790e0f847ee..603958d2815 100644 --- a/mysql-test/main/subselect_no_opts.result +++ b/mysql-test/main/subselect_no_opts.result @@ -1321,7 +1321,7 @@ a SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(3) DEFAULT NULL + `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; create table t1 (a int); @@ -7152,23 +7152,26 @@ drop table t1; # # MDEV-7565: Server crash with Signal 6 (part 2) # +create table t1 (id int not null primary key); Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` Group By TestCase.Revenue, TestCase.TemplateID; ControlRev NULL +drop table t1; # # MDEV-7445:Server crash with Signal 6 # +create table t1 (id int not null primary key); CREATE PROCEDURE procedure2() BEGIN Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` @@ -7181,6 +7184,7 @@ call procedure2(); ControlRev NULL drop procedure procedure2; +drop table t1; # # MDEV-7846:Server crashes in Item_subselect::fix #_fields or fails with Thread stack overrun @@ -7486,6 +7490,45 @@ ERROR HY000: Illegal parameter data types row and boolean for operation '=' SELECT ROW(1,2) = (1 = ANY (SELECT 1 UNION SELECT 2)); ERROR HY000: Illegal parameter data types row and boolean for operation '=' # +# MDEV-29070 SIGSEGV in my_decimal::operator= and Assertion `0' failed +# in Item_type_holder::val_decimal on SELECT +# +CREATE TABLE t1(a INT UNIQUE); +INSERT INTO t1(a) VALUES (1); +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT 1, 1); +a +1 +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT a, a); +a +1 +UPDATE t1 SET a = 0 +WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT +1 / +1, a FROM t1 WHERE a > -0+1) IN (SELECT a, a); +SELECT a FROM t1 WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT + 1 / + 1, a FROM t1 +WHERE a > -0 + 1) IN (SELECT a, a); +a +CREATE TABLE x (x INT); +INSERT INTO x (x) VALUES (1); +UPDATE x SET x = 1 WHERE x = 1; +INSERT INTO x (x) VALUES (1), (1); +WITH RECURSIVE x (x) AS ( +SELECT 1 INTERSECT +SELECT -(SELECT 1.000000 AS x +UNION +SELECT 1.000000 ORDER BY NOT x < 'x', +-(SELECT 1 + x/1.000000 IN (1, 1) FROM x +WHERE x ORDER BY 1 - x) DESC LIMIT 1 OFFSET 1 +) + 1 FROM x +) +SELECT DISTINCT x, 1, NULL, 1.000000 +FROM x +WHERE (SELECT (SELECT x WHERE x IN (SELECT x FROM x))) > +(SELECT (SELECT x ORDER BY x = x OR (x = 1 AND x = 1) DESC)) +ORDER BY x ASC, x DESC, x; +ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'x' +DROP TABLE t1, x; +# # End of 10.4 tests # # diff --git a/mysql-test/main/subselect_no_scache.result b/mysql-test/main/subselect_no_scache.result index 96d68a94a14..67d738a8a78 100644 --- a/mysql-test/main/subselect_no_scache.result +++ b/mysql-test/main/subselect_no_scache.result @@ -1324,7 +1324,7 @@ a SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(3) DEFAULT NULL + `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; create table t1 (a int); @@ -7167,23 +7167,26 @@ drop table t1; # # MDEV-7565: Server crash with Signal 6 (part 2) # +create table t1 (id int not null primary key); Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` Group By TestCase.Revenue, TestCase.TemplateID; ControlRev NULL +drop table t1; # # MDEV-7445:Server crash with Signal 6 # +create table t1 (id int not null primary key); CREATE PROCEDURE procedure2() BEGIN Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` @@ -7196,6 +7199,7 @@ call procedure2(); ControlRev NULL drop procedure procedure2; +drop table t1; # # MDEV-7846:Server crashes in Item_subselect::fix #_fields or fails with Thread stack overrun @@ -7501,6 +7505,45 @@ ERROR HY000: Illegal parameter data types row and boolean for operation '=' SELECT ROW(1,2) = (1 = ANY (SELECT 1 UNION SELECT 2)); ERROR HY000: Illegal parameter data types row and boolean for operation '=' # +# MDEV-29070 SIGSEGV in my_decimal::operator= and Assertion `0' failed +# in Item_type_holder::val_decimal on SELECT +# +CREATE TABLE t1(a INT UNIQUE); +INSERT INTO t1(a) VALUES (1); +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT 1, 1); +a +1 +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT a, a); +a +1 +UPDATE t1 SET a = 0 +WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT +1 / +1, a FROM t1 WHERE a > -0+1) IN (SELECT a, a); +SELECT a FROM t1 WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT + 1 / + 1, a FROM t1 +WHERE a > -0 + 1) IN (SELECT a, a); +a +CREATE TABLE x (x INT); +INSERT INTO x (x) VALUES (1); +UPDATE x SET x = 1 WHERE x = 1; +INSERT INTO x (x) VALUES (1), (1); +WITH RECURSIVE x (x) AS ( +SELECT 1 INTERSECT +SELECT -(SELECT 1.000000 AS x +UNION +SELECT 1.000000 ORDER BY NOT x < 'x', +-(SELECT 1 + x/1.000000 IN (1, 1) FROM x +WHERE x ORDER BY 1 - x) DESC LIMIT 1 OFFSET 1 +) + 1 FROM x +) +SELECT DISTINCT x, 1, NULL, 1.000000 +FROM x +WHERE (SELECT (SELECT x WHERE x IN (SELECT x FROM x))) > +(SELECT (SELECT x ORDER BY x = x OR (x = 1 AND x = 1) DESC)) +ORDER BY x ASC, x DESC, x; +ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'x' +DROP TABLE t1, x; +# # End of 10.4 tests # # diff --git a/mysql-test/main/subselect_no_semijoin.result b/mysql-test/main/subselect_no_semijoin.result index 5a460281e44..0ec32e0fbf8 100644 --- a/mysql-test/main/subselect_no_semijoin.result +++ b/mysql-test/main/subselect_no_semijoin.result @@ -1321,7 +1321,7 @@ a SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(3) DEFAULT NULL + `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; create table t1 (a int); @@ -7152,23 +7152,26 @@ drop table t1; # # MDEV-7565: Server crash with Signal 6 (part 2) # +create table t1 (id int not null primary key); Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` Group By TestCase.Revenue, TestCase.TemplateID; ControlRev NULL +drop table t1; # # MDEV-7445:Server crash with Signal 6 # +create table t1 (id int not null primary key); CREATE PROCEDURE procedure2() BEGIN Select -(Select Sum(`TestCase`.Revenue) From mysql.slow_log E -Where TestCase.TemplateID not in (Select 1 from mysql.slow_log where 2=2) +(Select Sum(`TestCase`.Revenue) From t1 E +Where TestCase.TemplateID not in (Select 1 from t1 where 2=2) ) As `ControlRev` From (Select 3 as Revenue, 4 as TemplateID) As `TestCase` @@ -7181,6 +7184,7 @@ call procedure2(); ControlRev NULL drop procedure procedure2; +drop table t1; # # MDEV-7846:Server crashes in Item_subselect::fix #_fields or fails with Thread stack overrun @@ -7486,6 +7490,45 @@ ERROR HY000: Illegal parameter data types row and boolean for operation '=' SELECT ROW(1,2) = (1 = ANY (SELECT 1 UNION SELECT 2)); ERROR HY000: Illegal parameter data types row and boolean for operation '=' # +# MDEV-29070 SIGSEGV in my_decimal::operator= and Assertion `0' failed +# in Item_type_holder::val_decimal on SELECT +# +CREATE TABLE t1(a INT UNIQUE); +INSERT INTO t1(a) VALUES (1); +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT 1, 1); +a +1 +SELECT a FROM t1 WHERE (SELECT a, a UNION SELECT 1, a FROM t1) IN (SELECT a, a); +a +1 +UPDATE t1 SET a = 0 +WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT +1 / +1, a FROM t1 WHERE a > -0+1) IN (SELECT a, a); +SELECT a FROM t1 WHERE (SELECT a, a WHERE a < 0 INTERSECT +SELECT + 1 / + 1, a FROM t1 +WHERE a > -0 + 1) IN (SELECT a, a); +a +CREATE TABLE x (x INT); +INSERT INTO x (x) VALUES (1); +UPDATE x SET x = 1 WHERE x = 1; +INSERT INTO x (x) VALUES (1), (1); +WITH RECURSIVE x (x) AS ( +SELECT 1 INTERSECT +SELECT -(SELECT 1.000000 AS x +UNION +SELECT 1.000000 ORDER BY NOT x < 'x', +-(SELECT 1 + x/1.000000 IN (1, 1) FROM x +WHERE x ORDER BY 1 - x) DESC LIMIT 1 OFFSET 1 +) + 1 FROM x +) +SELECT DISTINCT x, 1, NULL, 1.000000 +FROM x +WHERE (SELECT (SELECT x WHERE x IN (SELECT x FROM x))) > +(SELECT (SELECT x ORDER BY x = x OR (x = 1 AND x = 1) DESC)) +ORDER BY x ASC, x DESC, x; +ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'x' +DROP TABLE t1, x; +# # End of 10.4 tests # # diff --git a/mysql-test/main/type_ranges.result b/mysql-test/main/type_ranges.result index 02b6c79bdf5..efd83423bff 100644 --- a/mysql-test/main/type_ranges.result +++ b/mysql-test/main/type_ranges.result @@ -144,8 +144,10 @@ alter short drop default, DROP INDEX utiny, DROP INDEX ushort, DROP PRIMARY KEY, -DROP FOREIGN KEY any_name, +DROP FOREIGN KEY IF EXISTS any_name, ADD INDEX (auto); +Warnings: +Note 1091 Can't DROP FOREIGN KEY `any_name`; check that it exists LOCK TABLES t1 WRITE; ALTER TABLE t1 RENAME as t2, diff --git a/mysql-test/main/type_ranges.test b/mysql-test/main/type_ranges.test index 7bf29321d06..a69e3ac5796 100644 --- a/mysql-test/main/type_ranges.test +++ b/mysql-test/main/type_ranges.test @@ -76,7 +76,7 @@ alter short drop default, DROP INDEX utiny, DROP INDEX ushort, DROP PRIMARY KEY, -DROP FOREIGN KEY any_name, +DROP FOREIGN KEY IF EXISTS any_name, ADD INDEX (auto); LOCK TABLES t1 WRITE; diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result index 294e96e5997..d697788047f 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result @@ -1,3 +1,4 @@ +RESET MASTER; # # MDEV-30698 Cover missing test cases for mariadb-binlog options # --raw [and] --flashback diff --git a/mysql-test/suite/binlog/r/binlog_show_binlog_events_invalid_offset_silent.result b/mysql-test/suite/binlog/r/binlog_show_binlog_events_invalid_offset_silent.result new file mode 100644 index 00000000000..ec86cc8ea16 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_show_binlog_events_invalid_offset_silent.result @@ -0,0 +1,21 @@ +# +# Initialize test data +set @save_master_verify_checksum = @@global.master_verify_checksum; +set @@global.master_verify_checksum = 1; +create table t1 (a int); +insert into t1 values (1); +insert into t1 values (2); +SHOW BINLOG EVENTS FROM invalid_pos; +ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error +include/assert_grep.inc [Ensure the client error is not in the server log] +SHOW BINLOG EVENTS FROM 500; +ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error +include/assert_grep.inc [Ensure the client error is not in the server log] +SHOW BINLOG EVENTS FROM 498; +ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error +include/assert_grep.inc [Ensure the client error is not in the server log] +include/assert_grep.inc [Ensure there is not a specific checksum failure error] +# +# Cleanup +set @@global.master_verify_checksum = @save_master_verify_checksum; +drop table t1; diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test index 252a8577b6c..539a8fe5e28 100644 --- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test @@ -20,6 +20,8 @@ --source include/linux.inc --source include/have_log_bin.inc +# Test needs to reset the binlog as it is checking specific GTID. +RESET MASTER; --echo # --echo # MDEV-30698 Cover missing test cases for mariadb-binlog options @@ -35,7 +37,7 @@ FLUSH LOGS; INSERT INTO t1 VALUES (1); # Read binlog data from master to intermediary result file ---let TIMEOUT=1 +--let TIMEOUT=5 --echo # timeout TIMEOUT MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=MASTER_MYPORT --stop-never --result-file=MYSQLTEST_VARDIR/tmp/ master-bin.000001 --error 124 # Error 124 means timeout was reached --exec timeout $TIMEOUT $MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --stop-never --result-file=$MYSQLTEST_VARDIR/tmp/ master-bin.000001 diff --git a/mysql-test/suite/binlog/t/binlog_show_binlog_events_invalid_offset_silent.test b/mysql-test/suite/binlog/t/binlog_show_binlog_events_invalid_offset_silent.test new file mode 100644 index 00000000000..d3b31596051 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_show_binlog_events_invalid_offset_silent.test @@ -0,0 +1,53 @@ +# +# Ensure that calling SHOW BINLOG EVENTS FROM with an invalid offset +# will not result in error messages in the server log. That is, this call is a +# read operation for a user, and if it fails due to invalid usage, that is not +# a server error, but only one to report to the user. +# +# References: +# MDEV-32628: Cryptic ERROR message & inconsistent behavior on incorrect +# SHOW BINLOG EVENTS FROM ... +# +--source include/have_binlog_format_row.inc + +--echo # +--echo # Initialize test data +set @save_master_verify_checksum = @@global.master_verify_checksum; +set @@global.master_verify_checksum = 1; +create table t1 (a int); +insert into t1 values (1); +--let $middle_binlog_pos= query_get_value(SHOW BINARY LOGS, File_size, 1) +insert into t1 values (2); + +--let $assert_text= Ensure the client error is not in the server log +--let $assert_select= Error in Log_event +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_count= 0 +--let $assert_only_after = CURRENT_TEST: + + +# Pre MDEV-32628, this would write an event truncated error in the logs +--let $invalid_pos= `SELECT $middle_binlog_pos - 1` +--replace_result $invalid_pos invalid_pos +--error 1220 +--eval SHOW BINLOG EVENTS FROM $invalid_pos +--source include/assert_grep.inc + +# Pre MDEV-32628, this would write an event too big error in the logs +--error 1220 +SHOW BINLOG EVENTS FROM 500; +--source include/assert_grep.inc + + +# Pre MDEV-32628, this would write a checksum verification failed error in the logs +--error 1220 +SHOW BINLOG EVENTS FROM 498; +--source include/assert_grep.inc +--let $assert_text= Ensure there is not a specific checksum failure error +--let $assert_select= Replication event checksum verification failed while reading from a log file +--source include/assert_grep.inc + +--echo # +--echo # Cleanup +set @@global.master_verify_checksum = @save_master_verify_checksum; +drop table t1; diff --git a/mysql-test/suite/binlog/t/flashback.test b/mysql-test/suite/binlog/t/flashback.test index 7c58b56c935..8daf3f43a23 100644 --- a/mysql-test/suite/binlog/t/flashback.test +++ b/mysql-test/suite/binlog/t/flashback.test @@ -1,4 +1,4 @@ ---source include/have_log_bin.inc +--source include/have_binlog_format_row.inc --source include/have_innodb.inc --echo # @@ -101,7 +101,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --exec $MYSQL_BINLOG -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_original_1.sql --exec $MYSQL_BINLOG -B -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_1.sql ---exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_1.sql;" +--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_1.sql;" SELECT * FROM t1; @@ -126,7 +126,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --exec $MYSQL_BINLOG -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_original_2.sql --exec $MYSQL_BINLOG -B -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_2.sql ---exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_2.sql;" +--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_2.sql;" SELECT * FROM t1; @@ -160,7 +160,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --exec $MYSQL_BINLOG -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_original_3.sql --exec $MYSQL_BINLOG -B -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_3.sql ---exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_3.sql;" +--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_3.sql;" SELECT * FROM t1; @@ -202,7 +202,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --exec $MYSQL_BINLOG -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_original_4.sql --exec $MYSQL_BINLOG -B $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_4.sql ---exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_4.sql;" +--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_4.sql;" SELECT * FROM t1; SELECT * FROM t2; @@ -247,7 +247,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --exec $MYSQL_BINLOG -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_original_5.sql --exec $MYSQL_BINLOG -B $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_5.sql ---exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_5.sql;" +--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_5.sql;" SELECT * FROM t1; @@ -323,7 +323,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --exec $MYSQL_BINLOG --database=world --table=city -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_original_6.sql --exec $MYSQL_BINLOG --database=world --table=city -B $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_6.sql ---exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_6.sql;" +--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_6.sql;" SELECT * FROM world.city; @@ -355,7 +355,7 @@ FLUSH LOGS; --source include/assert.inc --exec $MYSQL_BINLOG -vv -B --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002> $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_7.sql ---exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_7.sql;" +--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_7.sql;" --echo # 6- Rows must be present upon restoring from flashback --let $assert_cond= COUNT(*) = 6 FROM t1 diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.result b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.result index 33c1f1413b4..25212024623 100644 --- a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.result +++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.result @@ -63,7 +63,7 @@ include/wait_for_slave_io_error.inc [errno=1236] SHOW TABLES; Tables_in_test table1_no_encryption -include/stop_slave.inc +include/stop_slave_sql.inc reset slave; ########## # Cleanup diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.test b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.test index a34c9715239..b74632690ca 100644 --- a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.test +++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_coords.test @@ -136,7 +136,8 @@ start slave; SHOW TABLES; --disable_connect_log ---source include/stop_slave.inc +# IO thread is stopped, stop SQL thread only +--source include/stop_slave_sql.inc --enable_connect_log reset slave; diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.result b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.result index 16ea30557e7..c6835ff90f4 100644 --- a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.result +++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.result @@ -62,7 +62,7 @@ include/wait_for_slave_io_error.inc [errno=1236] # ..success SHOW TABLES; Tables_in_test -include/stop_slave.inc +include/stop_slave_sql.inc reset slave; ########## # Cleanup diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.test b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.test index f882e8f3440..9991fb9b1b9 100644 --- a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.test +++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted_gtid.test @@ -132,7 +132,8 @@ if (`SELECT strcmp("$gsp","")`) SHOW TABLES; --disable_connect_log ---source include/stop_slave.inc +# IO thread is stopped, wait for SQL thread to be stopped +--source include/stop_slave_sql.inc --enable_connect_log reset slave; diff --git a/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.result b/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.result index 944ad9331ad..7ce98cbcc10 100644 --- a/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.result +++ b/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.result @@ -192,7 +192,7 @@ SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; -include/stop_slave.inc +include/stop_slave_io.inc include/start_slave.inc connection master; connection slave; diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.result b/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.result index ce11b814d44..57654d1596b 100644 --- a/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.result +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.result @@ -36,7 +36,8 @@ connection server_2; connection con_temp2; COMMIT; connection server_2; -include/stop_slave.inc +include/wait_for_slave_sql_error.inc [errno=1062] +include/stop_slave_io.inc include/assert.inc [table t1 should have zero rows where a>32] SELECT * FROM t1 WHERE a>32; a diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.result b/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.result index e9d04c02d7a..c9094c8b8cc 100644 --- a/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.result +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.result @@ -38,7 +38,6 @@ connection con2; SET debug_sync='RESET'; connection server_2; include/wait_for_slave_sql_error.inc [errno=1062] -include/wait_for_slave_sql_to_stop.inc SELECT * FROM t3 WHERE a >= 110 ORDER BY a; a b 110 1 diff --git a/mysql-test/suite/compat/oracle/r/func_concat.result b/mysql-test/suite/compat/oracle/r/func_concat.result index 392d579707a..17ca4be078a 100644 --- a/mysql-test/suite/compat/oracle/r/func_concat.result +++ b/mysql-test/suite/compat/oracle/r/func_concat.result @@ -3,12 +3,12 @@ EXPLAIN EXTENDED SELECT 'a'||'b'||'c'; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select concat_operator_oracle(concat_operator_oracle('a','b'),'c') AS "'a'||'b'||'c'" +Note 1003 select concat(concat('a','b'),'c') AS "'a'||'b'||'c'" EXPLAIN EXTENDED SELECT CONCAT('a'||'b'||'c'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select concat_operator_oracle(concat_operator_oracle(concat_operator_oracle('a','b'),'c')) AS "CONCAT('a'||'b'||'c')" +Note 1003 select concat(concat(concat('a','b'),'c')) AS "CONCAT('a'||'b'||'c')" SELECT '' || ''; '' || '' @@ -211,14 +211,14 @@ SET sql_mode=ORACLE; CREATE VIEW v1 AS SELECT 'foo'||NULL||'bar' AS test; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection -v1 CREATE VIEW "v1" AS select concat_operator_oracle(concat_operator_oracle('foo',NULL),'bar') AS "test" latin1 latin1_swedish_ci +v1 CREATE VIEW "v1" AS select concat(concat('foo',NULL),'bar') AS "test" latin1 latin1_swedish_ci SELECT * FROM v1; test foobar SET sql_mode=DEFAULT; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select concat_operator_oracle(concat_operator_oracle('foo',NULL),'bar') AS `test` latin1 latin1_swedish_ci +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select oracle_schema.concat(oracle_schema.concat('foo',NULL),'bar') AS `test` latin1 latin1_swedish_ci SELECT * FROM v1; test foobar @@ -234,7 +234,7 @@ NULL SET sql_mode=ORACLE; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection -v1 CREATE VIEW "v1" AS select concat('foo',NULL,'bar') AS "test" latin1 latin1_swedish_ci +v1 CREATE VIEW "v1" AS select mariadb_schema.concat('foo',NULL,'bar') AS "test" latin1 latin1_swedish_ci SELECT * FROM v1; test NULL @@ -268,12 +268,12 @@ EXPLAIN EXTENDED SELECT -1<<1||1 AS a FROM DUAL; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select -1 << concat_operator_oracle(1,1) AS "a" +Note 1003 select -1 << concat(1,1) AS "a" EXPLAIN EXTENDED SELECT -1||0<<1 AS a FROM DUAL; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select concat_operator_oracle(-1,0) << 1 AS "a" +Note 1003 select concat(-1,0) << 1 AS "a" SELECT -1+1||1 AS a FROM DUAL; a 01 @@ -284,12 +284,12 @@ EXPLAIN EXTENDED SELECT -1+1||1 AS a FROM DUAL; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select concat_operator_oracle(-1 + 1,1) AS "a" +Note 1003 select concat(-1 + 1,1) AS "a" EXPLAIN EXTENDED SELECT -1||0+1 AS a FROM DUAL; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select concat_operator_oracle(-1,0) + 1 AS "a" +Note 1003 select concat(-1,0) + 1 AS "a" SELECT 1*1||-1 AS a FROM DUAL; a 1-1 @@ -300,12 +300,12 @@ EXPLAIN EXTENDED SELECT 1*1||-1 AS a FROM DUAL; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select concat_operator_oracle(1 * 1,-1) AS "a" +Note 1003 select concat(1 * 1,-1) AS "a" EXPLAIN EXTENDED SELECT 1||1*-1 AS a FROM DUAL; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select concat_operator_oracle(1,1 * -1) AS "a" +Note 1003 select concat(1,1 * -1) AS "a" SELECT -1^1||1 AS a FROM DUAL; a 184467440737095516141 @@ -316,12 +316,12 @@ EXPLAIN EXTENDED SELECT -1^1||1 AS a FROM DUAL; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select concat_operator_oracle(-1 ^ 1,1) AS "a" +Note 1003 select concat(-1 ^ 1,1) AS "a" EXPLAIN EXTENDED SELECT -1||0^1 AS a FROM DUAL; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select concat_operator_oracle(-1,0 ^ 1) AS "a" +Note 1003 select concat(-1,0 ^ 1) AS "a" # # MDEV-17359 Concatenation operator || in like expression failed in sql_mode=ORACLE # @@ -332,7 +332,7 @@ EXPLAIN EXTENDED SELECT 'abc' LIKE 'a'||'%'; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select 'abc' like concat_operator_oracle('a','%') AS "'abc' LIKE 'a'||'%'" +Note 1003 select 'abc' like concat('a','%') AS "'abc' LIKE 'a'||'%'" SELECT 'x' FROM DUAL WHERE 11 LIKE 1||1; x x @@ -353,7 +353,7 @@ EXPLAIN EXTENDED SELECT c1 FROM t1 WHERE c1 LIKE '%'||'b' ORDER BY ord; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort Warnings: -Note 1003 select "test"."t1"."c1" AS "c1" from "test"."t1" where "test"."t1"."c1" like (concat_operator_oracle('%','b')) order by "test"."t1"."ord" +Note 1003 select "test"."t1"."c1" AS "c1" from "test"."t1" where "test"."t1"."c1" like (concat('%','b')) order by "test"."t1"."ord" SELECT c1 FROM t1 WHERE c1 LIKE c2||'%'||'c' ORDER BY ord; c1 abc @@ -361,7 +361,7 @@ EXPLAIN EXTENDED SELECT c1 FROM t1 WHERE c1 LIKE c2||'%'||'c' ORDER BY ord; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort Warnings: -Note 1003 select "test"."t1"."c1" AS "c1" from "test"."t1" where "test"."t1"."c1" like concat_operator_oracle(concat_operator_oracle("test"."t1"."c2",'%'),'c') order by "test"."t1"."ord" +Note 1003 select "test"."t1"."c1" AS "c1" from "test"."t1" where "test"."t1"."c1" like concat(concat("test"."t1"."c2",'%'),'c') order by "test"."t1"."ord" SELECT 'x' FROM t1 WHERE c1||c2 LIKE 'aa%'; x x @@ -369,7 +369,7 @@ EXPLAIN EXTENDED SELECT 'x' FROM t1 WHERE c1||c2 LIKE 'aa%'; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where Warnings: -Note 1003 select 'x' AS "x" from "test"."t1" where concat_operator_oracle("test"."t1"."c1","test"."t1"."c2") like 'aa%' +Note 1003 select 'x' AS "x" from "test"."t1" where concat("test"."t1"."c1","test"."t1"."c2") like 'aa%' SELECT 'x' FROM t1 WHERE c1||c2 LIKE c2||c1; x x @@ -377,7 +377,7 @@ EXPLAIN EXTENDED SELECT 'x' FROM t1 WHERE c1||c2 LIKE c2||c1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where Warnings: -Note 1003 select 'x' AS "x" from "test"."t1" where concat_operator_oracle("test"."t1"."c1","test"."t1"."c2") like concat_operator_oracle("test"."t1"."c2","test"."t1"."c1") +Note 1003 select 'x' AS "x" from "test"."t1" where concat("test"."t1"."c1","test"."t1"."c2") like concat("test"."t1"."c2","test"."t1"."c1") CREATE VIEW v1 AS SELECT c1, c2, c1 LIKE c2||'_' FROM t1 ORDER BY ord; SELECT * FROM v1; c1 c2 c1 LIKE c2||'_' @@ -388,6 +388,6 @@ EXPLAIN EXTENDED SELECT * FROM v1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: -Note 1003 select "test"."t1"."c1" AS "c1","test"."t1"."c2" AS "c2","test"."t1"."c1" like concat_operator_oracle("test"."t1"."c2",'_') AS "c1 LIKE c2||'_'" from "test"."t1" order by "test"."t1"."ord" +Note 1003 select "test"."t1"."c1" AS "c1","test"."t1"."c2" AS "c2","test"."t1"."c1" like concat("test"."t1"."c2",'_') AS "c1 LIKE c2||'_'" from "test"."t1" order by "test"."t1"."ord" DROP VIEW v1; DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/func_decode.result b/mysql-test/suite/compat/oracle/r/func_decode.result index 2809e971be3..afbba204e1b 100644 --- a/mysql-test/suite/compat/oracle/r/func_decode.result +++ b/mysql-test/suite/compat/oracle/r/func_decode.result @@ -28,7 +28,7 @@ EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11','def'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select decode_oracle(12,10,'x10',11,'x11','def') AS "DECODE(12,10,'x10',11,'x11','def')" +Note 1003 select decode(12,10,'x10',11,'x11','def') AS "DECODE(12,10,'x10',11,'x11','def')" CREATE TABLE decode (decode int); DROP TABLE decode; # @@ -46,22 +46,22 @@ EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select decode_oracle(12,10,'x10',11,'x11') AS "DECODE(12,10,'x10',11,'x11')" +Note 1003 select decode(12,10,'x10',11,'x11') AS "DECODE(12,10,'x10',11,'x11')" EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11','def'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select decode_oracle(12,10,'x10',11,'x11','def') AS "DECODE(12,10,'x10',11,'x11','def')" +Note 1003 select decode(12,10,'x10',11,'x11','def') AS "DECODE(12,10,'x10',11,'x11','def')" EXPLAIN EXTENDED SELECT DECODE_ORACLE(12,10,'x10',11,'x11'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select decode_oracle(12,10,'x10',11,'x11') AS "DECODE_ORACLE(12,10,'x10',11,'x11')" +Note 1003 select decode(12,10,'x10',11,'x11') AS "DECODE_ORACLE(12,10,'x10',11,'x11')" EXPLAIN EXTENDED SELECT DECODE_ORACLE(12,10,'x10',11,'x11','def'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select decode_oracle(12,10,'x10',11,'x11','def') AS "DECODE_ORACLE(12,10,'x10',11,'x11','def')" +Note 1003 select decode(12,10,'x10',11,'x11','def') AS "DECODE_ORACLE(12,10,'x10',11,'x11','def')" CREATE TABLE t1 (a INT); CREATE VIEW v1 AS SELECT @@ -72,7 +72,7 @@ DECODE_ORACLE(a,1,'x1',NULL,'xNULL','xELSE') AS d4 FROM t1; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection -v1 CREATE VIEW "v1" AS select decode_oracle("t1"."a",1,'x1',NULL,'xNULL') AS "d1",decode_oracle("t1"."a",1,'x1',NULL,'xNULL','xELSE') AS "d2",decode_oracle("t1"."a",1,'x1',NULL,'xNULL') AS "d3",decode_oracle("t1"."a",1,'x1',NULL,'xNULL','xELSE') AS "d4" from "t1" latin1 latin1_swedish_ci +v1 CREATE VIEW "v1" AS select decode("t1"."a",1,'x1',NULL,'xNULL') AS "d1",decode("t1"."a",1,'x1',NULL,'xNULL','xELSE') AS "d2",decode("t1"."a",1,'x1',NULL,'xNULL') AS "d3",decode("t1"."a",1,'x1',NULL,'xNULL','xELSE') AS "d4" from "t1" latin1 latin1_swedish_ci DROP VIEW v1; DROP TABLE t1; SELECT DECODE(TIME'10:20:31','10:20:31','then1','10:20:32','then2','def'); diff --git a/mysql-test/suite/compat/oracle/r/func_pad.result b/mysql-test/suite/compat/oracle/r/func_pad.result index ca7d52cd542..63952959945 100644 --- a/mysql-test/suite/compat/oracle/r/func_pad.result +++ b/mysql-test/suite/compat/oracle/r/func_pad.result @@ -44,11 +44,11 @@ EXPLAIN EXTENDED SELECT RPAD('a',0,'.'), LPAD('a',0,'.'), LPAD(c1,c2,c3), LPAD(c id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 7 100.00 Using filesort Warnings: -Note 1003 select rpad_oracle('a',0,'.') AS "RPAD('a',0,'.')",lpad_oracle('a',0,'.') AS "LPAD('a',0,'.')",lpad_oracle("test"."t1"."c1","test"."t1"."c2","test"."t1"."c3") AS "LPAD(c1,c2,c3)",lpad_oracle("test"."t1"."c1","test"."t1"."c2") AS "LPAD(c1,c2)",rpad_oracle("test"."t1"."c1","test"."t1"."c2","test"."t1"."c3") AS "RPAD(c1,c2,c3)",rpad_oracle("test"."t1"."c1","test"."t1"."c2") AS "RPAD(c1,c2)" from "test"."t1" order by "test"."t1"."ord" +Note 1003 select rpad('a',0,'.') AS "RPAD('a',0,'.')",lpad('a',0,'.') AS "LPAD('a',0,'.')",lpad("test"."t1"."c1","test"."t1"."c2","test"."t1"."c3") AS "LPAD(c1,c2,c3)",lpad("test"."t1"."c1","test"."t1"."c2") AS "LPAD(c1,c2)",rpad("test"."t1"."c1","test"."t1"."c2","test"."t1"."c3") AS "RPAD(c1,c2,c3)",rpad("test"."t1"."c1","test"."t1"."c2") AS "RPAD(c1,c2)" from "test"."t1" order by "test"."t1"."ord" CREATE VIEW v1 AS SELECT RPAD('a',0,'.') AS "C1", LPAD('a',0,'.') AS "C2", LPAD(c1,c2,c3) AS "C3", LPAD(c1,c2) AS "C4", RPAD(c1,c2,c3) AS "C5", RPAD(c1,c2) AS "C6" FROM t1 ORDER BY ord; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection -v1 CREATE VIEW "v1" AS select rpad_oracle('a',0,'.') AS "C1",lpad_oracle('a',0,'.') AS "C2",lpad_oracle("t1"."c1","t1"."c2","t1"."c3") AS "C3",lpad_oracle("t1"."c1","t1"."c2") AS "C4",rpad_oracle("t1"."c1","t1"."c2","t1"."c3") AS "C5",rpad_oracle("t1"."c1","t1"."c2") AS "C6" from "t1" order by "t1"."ord" latin1 latin1_swedish_ci +v1 CREATE VIEW "v1" AS select rpad('a',0,'.') AS "C1",lpad('a',0,'.') AS "C2",lpad("t1"."c1","t1"."c2","t1"."c3") AS "C3",lpad("t1"."c1","t1"."c2") AS "C4",rpad("t1"."c1","t1"."c2","t1"."c3") AS "C5",rpad("t1"."c1","t1"."c2") AS "C6" from "t1" order by "t1"."ord" latin1 latin1_swedish_ci SELECT * FROM v1; C1 C2 C3 C4 C5 C6 NULL NULL NULL a NULL a diff --git a/mysql-test/suite/compat/oracle/r/func_qualified.result b/mysql-test/suite/compat/oracle/r/func_qualified.result new file mode 100644 index 00000000000..f8224b7ce81 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_qualified.result @@ -0,0 +1,2468 @@ +# +# MDEV-27744 LPAD in vcol created in ORACLE mode makes table corrupted in non-ORACLE +# +SET sql_mode=DEFAULT; +SELECT decode_oracle(1); +ERROR 42000: Incorrect parameter count in the call to native function 'decode_oracle' +SELECT DECODE_ORACLE(1); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE_ORACLE' +SET sql_mode=ORACLE; +SELECT decode_oracle(1); +ERROR 42000: Incorrect parameter count in the call to native function 'decode_oracle' +SELECT DECODE_ORACLE(1); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE_ORACLE' +SET sql_mode=DEFAULT; +SELECT decode(1); +ERROR 42000: Incorrect parameter count in the call to native function 'decode' +SELECT DECODE(1); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +SET sql_mode=ORACLE; +SELECT decode(1); +ERROR 42000: Incorrect parameter count in the call to native function 'decode' +SELECT DECODE(1); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +SELECT mariadb_schema.decode(1); +ERROR 42000: Incorrect parameter count in the call to native function 'decode' +SELECT mariadb_schema.DECODE(1); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +SELECT mariadb_schema.decode_oracle(1); +ERROR 42000: Incorrect parameter count in the call to native function 'decode_oracle' +SELECT mariadb_schema.DECODE_ORACLE(1); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE_ORACLE' +SET sql_mode=DEFAULT; +SELECT unknown.TRIM(1); +ERROR 42000: FUNCTION unknown.TRIM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT unknown.trim(1); +ERROR 42000: FUNCTION unknown.trim does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT oracle_schema.TRIM(); +ERROR HY000: Function 'TRIM' is not defined +SELECT oracle_schema.TRIM('a','b'); +ERROR HY000: Function 'TRIM' is not defined +SELECT oracle_schema.TRIM('a','b','c','d'); +ERROR HY000: Function 'TRIM' is not defined +SELECT unknown.SUBSTR('a',1,2); +ERROR 42000: FUNCTION unknown.SUBSTR does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT unknown.substr('a',1,2); +ERROR 42000: FUNCTION unknown.substr does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT unknown.SUBSTRING('a',1,2); +ERROR 42000: FUNCTION unknown.SUBSTRING does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT unknown.substring('a',1,2); +ERROR 42000: FUNCTION unknown.substring does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT unknown.REPLACE('a','b','c'); +ERROR 42000: FUNCTION unknown.REPLACE does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT unknown.replace('a','b','c'); +ERROR 42000: FUNCTION unknown.replace does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT oracle_schema.REPLACE(); +ERROR HY000: Function 'REPLACE' is not defined +SELECT oracle_schema.REPLACE('a'); +ERROR HY000: Function 'REPLACE' is not defined +SELECT oracle_schema.REPLACE('a','b'); +ERROR HY000: Function 'REPLACE' is not defined +SELECT oracle_schema.REPLACE('a','b','c','d'); +ERROR HY000: Function 'REPLACE' is not defined +SET sql_mode=DEFAULT; +CREATE PROCEDURE p1(sqlmode TEXT, qualifier TEXT, expr TEXT) +BEGIN +DECLARE query TEXT DEFAULT 'SELECT $(QUALIFIER)$(EXPR)'; +DECLARE errmsg TEXT DEFAULT NULL; +DECLARE CONTINUE HANDLER FOR 1064, 1128, 1305, 1582, 1630 +BEGIN +GET DIAGNOSTICS CONDITION 1 errmsg = MESSAGE_TEXT; +END; +SET sql_mode=sqlmode; +SET query=REPLACE(query, '$(QUALIFIER)', qualifier); +SET query=REPLACE(query, '$(EXPR)', expr); +SET query= CONCAT('EXPLAIN EXTENDED ', query); +SELECT CONCAT('sql_mode=''',sqlmode,'''', ' ', +'qualifier=''',qualifier,'''') AS `----------`; +SELECT query; +EXECUTE IMMEDIATE query; +IF errmsg IS NOT NULL THEN +SELECT CONCAT('ERROR: ', errmsg) AS errmsg; +ELSE +SHOW WARNINGS; +END IF; +END; +$$ +CREATE PROCEDURE p2(sqlmode TEXT, expr TEXT) +BEGIN +CALL p1(sqlmode, '', expr); +CALL p1(sqlmode, 'unknown_schema.', expr); +CALL p1(sqlmode, 'mariadb_schema.', expr); +CALL p1(sqlmode, 'maxdb_schema.', expr); +CALL p1(sqlmode, 'oracle_schema.', expr); +END; +$$ +CREATE PROCEDURE p3(expr TEXT) +BEGIN +CALL p2('', expr); +CALL p2('ORACLE', expr); +END; +$$ +CALL p3('CONCAT(''a'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT CONCAT('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select concat('a') AS `CONCAT('a')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.CONCAT('a') +errmsg +ERROR: FUNCTION unknown_schema.CONCAT does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.CONCAT('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select concat('a') AS `mariadb_schema.CONCAT('a')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.CONCAT('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select concat('a') AS `maxdb_schema.CONCAT('a')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.CONCAT('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.concat('a') AS `oracle_schema.CONCAT('a')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT CONCAT('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select concat('a') AS "CONCAT('a')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.CONCAT('a') +errmsg +ERROR: FUNCTION unknown_schema.CONCAT does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.CONCAT('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.concat('a') AS "mariadb_schema.CONCAT('a')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.CONCAT('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.concat('a') AS "maxdb_schema.CONCAT('a')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.CONCAT('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select concat('a') AS "oracle_schema.CONCAT('a')" +Warnings: +Note 1003 select concat('a') AS "oracle_schema.CONCAT('a')" +CALL p3('DECODE(''1'',''2'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT DECODE('1','2') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select decode('1','2') AS `DECODE('1','2')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.DECODE('1','2') +errmsg +ERROR: FUNCTION unknown_schema.DECODE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.DECODE('1','2') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select decode('1','2') AS `mariadb_schema.DECODE('1','2')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.DECODE('1','2') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select decode('1','2') AS `maxdb_schema.DECODE('1','2')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.DECODE('1','2') +errmsg +ERROR: Incorrect parameter count in the call to native function 'DECODE' +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT DECODE('1','2') +errmsg +ERROR: Incorrect parameter count in the call to native function 'DECODE' +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.DECODE('1','2') +errmsg +ERROR: FUNCTION unknown_schema.DECODE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.DECODE('1','2') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.decode('1','2') AS "mariadb_schema.DECODE('1','2')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.DECODE('1','2') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.decode('1','2') AS "maxdb_schema.DECODE('1','2')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.DECODE('1','2') +errmsg +ERROR: Incorrect parameter count in the call to native function 'DECODE' +CALL p3('DECODE(1,1,10)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT DECODE(1,1,10) +errmsg +ERROR: Incorrect parameter count in the call to native function 'DECODE' +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.DECODE(1,1,10) +errmsg +ERROR: FUNCTION unknown_schema.DECODE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.DECODE(1,1,10) +errmsg +ERROR: Incorrect parameter count in the call to native function 'DECODE' +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.DECODE(1,1,10) +errmsg +ERROR: Incorrect parameter count in the call to native function 'DECODE' +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.DECODE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.decode(1,1,10) AS `oracle_schema.DECODE(1,1,10)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT DECODE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select decode(1,1,10) AS "DECODE(1,1,10)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.DECODE(1,1,10) +errmsg +ERROR: FUNCTION unknown_schema.DECODE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.DECODE(1,1,10) +errmsg +ERROR: Incorrect parameter count in the call to native function 'DECODE' +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.DECODE(1,1,10) +errmsg +ERROR: Incorrect parameter count in the call to native function 'DECODE' +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.DECODE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select decode(1,1,10) AS "oracle_schema.DECODE(1,1,10)" +Warnings: +Note 1003 select decode(1,1,10) AS "oracle_schema.DECODE(1,1,10)" +CALL p3('LTRIM(''a'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT LTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select ltrim('a') AS `LTRIM('a')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LTRIM('a') +errmsg +ERROR: FUNCTION unknown_schema.LTRIM does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select ltrim('a') AS `mariadb_schema.LTRIM('a')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select ltrim('a') AS `maxdb_schema.LTRIM('a')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.ltrim('a') AS `oracle_schema.LTRIM('a')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT LTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select ltrim('a') AS "LTRIM('a')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LTRIM('a') +errmsg +ERROR: FUNCTION unknown_schema.LTRIM does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.ltrim('a') AS "mariadb_schema.LTRIM('a')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.ltrim('a') AS "maxdb_schema.LTRIM('a')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select ltrim('a') AS "oracle_schema.LTRIM('a')" +Warnings: +Note 1003 select ltrim('a') AS "oracle_schema.LTRIM('a')" +CALL p3('RTRIM(''a'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT RTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rtrim('a') AS `RTRIM('a')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RTRIM('a') +errmsg +ERROR: FUNCTION unknown_schema.RTRIM does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rtrim('a') AS `mariadb_schema.RTRIM('a')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rtrim('a') AS `maxdb_schema.RTRIM('a')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rtrim('a') AS `oracle_schema.RTRIM('a')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT RTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rtrim('a') AS "RTRIM('a')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RTRIM('a') +errmsg +ERROR: FUNCTION unknown_schema.RTRIM does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.rtrim('a') AS "mariadb_schema.RTRIM('a')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.rtrim('a') AS "maxdb_schema.RTRIM('a')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RTRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rtrim('a') AS "oracle_schema.RTRIM('a')" +Warnings: +Note 1003 select rtrim('a') AS "oracle_schema.RTRIM('a')" +CALL p3('LPAD(''a'',3)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT LPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3) AS `LPAD('a',3)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LPAD('a',3) +errmsg +ERROR: FUNCTION unknown_schema.LPAD does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3) AS `mariadb_schema.LPAD('a',3)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3) AS `maxdb_schema.LPAD('a',3)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.lpad('a',3) AS `oracle_schema.LPAD('a',3)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT LPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3) AS "LPAD('a',3)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LPAD('a',3) +errmsg +ERROR: FUNCTION unknown_schema.LPAD does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.lpad('a',3) AS "mariadb_schema.LPAD('a',3)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.lpad('a',3) AS "maxdb_schema.LPAD('a',3)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3) AS "oracle_schema.LPAD('a',3)" +Warnings: +Note 1003 select lpad('a',3) AS "oracle_schema.LPAD('a',3)" +CALL p3('LPAD(''a'',3, '' '')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT LPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3,' ') AS `LPAD('a',3, ' ')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LPAD('a',3, ' ') +errmsg +ERROR: FUNCTION unknown_schema.LPAD does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3,' ') AS `mariadb_schema.LPAD('a',3, ' ')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3,' ') AS `maxdb_schema.LPAD('a',3, ' ')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.lpad('a',3,' ') AS `oracle_schema.LPAD('a',3, ' ')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT LPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3,' ') AS "LPAD('a',3, ' ')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LPAD('a',3, ' ') +errmsg +ERROR: FUNCTION unknown_schema.LPAD does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.lpad('a',3,' ') AS "mariadb_schema.LPAD('a',3, ' ')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.lpad('a',3,' ') AS "maxdb_schema.LPAD('a',3, ' ')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3,' ') AS "oracle_schema.LPAD('a',3, ' ')" +Warnings: +Note 1003 select lpad('a',3,' ') AS "oracle_schema.LPAD('a',3, ' ')" +CALL p3('RPAD(''a'',3)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT RPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3) AS `RPAD('a',3)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RPAD('a',3) +errmsg +ERROR: FUNCTION unknown_schema.RPAD does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3) AS `mariadb_schema.RPAD('a',3)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3) AS `maxdb_schema.RPAD('a',3)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rpad('a',3) AS `oracle_schema.RPAD('a',3)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT RPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3) AS "RPAD('a',3)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RPAD('a',3) +errmsg +ERROR: FUNCTION unknown_schema.RPAD does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.rpad('a',3) AS "mariadb_schema.RPAD('a',3)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.rpad('a',3) AS "maxdb_schema.RPAD('a',3)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RPAD('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3) AS "oracle_schema.RPAD('a',3)" +Warnings: +Note 1003 select rpad('a',3) AS "oracle_schema.RPAD('a',3)" +CALL p3('RPAD(''a'',3, '' '')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT RPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3,' ') AS `RPAD('a',3, ' ')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RPAD('a',3, ' ') +errmsg +ERROR: FUNCTION unknown_schema.RPAD does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3,' ') AS `mariadb_schema.RPAD('a',3, ' ')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3,' ') AS `maxdb_schema.RPAD('a',3, ' ')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rpad('a',3,' ') AS `oracle_schema.RPAD('a',3, ' ')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT RPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3,' ') AS "RPAD('a',3, ' ')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RPAD('a',3, ' ') +errmsg +ERROR: FUNCTION unknown_schema.RPAD does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.rpad('a',3,' ') AS "mariadb_schema.RPAD('a',3, ' ')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.rpad('a',3,' ') AS "maxdb_schema.RPAD('a',3, ' ')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RPAD('a',3, ' ') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3,' ') AS "oracle_schema.RPAD('a',3, ' ')" +Warnings: +Note 1003 select rpad('a',3,' ') AS "oracle_schema.RPAD('a',3, ' ')" +CALL p3('REPLACE()'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE() +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE() +errmsg +ERROR: FUNCTION unknown_schema.REPLACE does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE() +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE() +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE() +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE() +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE() +errmsg +ERROR: FUNCTION unknown_schema.REPLACE does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE() +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE() +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE() +errmsg +ERROR: Function 'REPLACE' is not defined +CALL p3('REPLACE(''a'',''b'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE('a','b') +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE('a','b') +errmsg +ERROR: FUNCTION unknown_schema.REPLACE does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE('a','b') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE('a','b') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE('a','b') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE('a','b') +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE('a','b') +errmsg +ERROR: FUNCTION unknown_schema.REPLACE does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE('a','b') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE('a','b') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE('a','b') +errmsg +ERROR: Function 'REPLACE' is not defined +CALL p3('REPLACE(''a'',''b'',''c'',''d'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE('a','b','c','d') +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''d')' at line 1 +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE('a','b','c','d') +errmsg +ERROR: FUNCTION unknown_schema.REPLACE does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE('a','b','c','d') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE('a','b','c','d') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE('a','b','c','d') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE('a','b','c','d') +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''d')' at line 1 +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE('a','b','c','d') +errmsg +ERROR: FUNCTION unknown_schema.REPLACE does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE('a','b','c','d') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE('a','b','c','d') +errmsg +ERROR: Function 'REPLACE' is not defined +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE('a','b','c','d') +errmsg +ERROR: Function 'REPLACE' is not defined +CALL p3('REPLACE(''a'',''b'',''c'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select replace('a','b','c') AS `REPLACE('a','b','c')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE('a','b','c') +errmsg +ERROR: FUNCTION unknown_schema.REPLACE does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select replace('a','b','c') AS `mariadb_schema.REPLACE('a','b','c')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select replace('a','b','c') AS `maxdb_schema.REPLACE('a','b','c')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.replace('a','b','c') AS `oracle_schema.REPLACE('a','b','c')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select replace('a','b','c') AS "REPLACE('a','b','c')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE('a','b','c') +errmsg +ERROR: FUNCTION unknown_schema.REPLACE does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.replace('a','b','c') AS "mariadb_schema.REPLACE('a','b','c')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.replace('a','b','c') AS "maxdb_schema.REPLACE('a','b','c')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select replace('a','b','c') AS "oracle_schema.REPLACE('a','b','c')" +Warnings: +Note 1003 select replace('a','b','c') AS "oracle_schema.REPLACE('a','b','c')" +CALL p3('SUBSTR()'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR() +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR() +errmsg +ERROR: FUNCTION unknown_schema.SUBSTR does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR() +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR() +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR() +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR() +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR() +errmsg +ERROR: FUNCTION unknown_schema.SUBSTR does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR() +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR() +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR() +errmsg +ERROR: Function 'SUBSTR' is not defined +CALL p3('SUBSTR(''a'',1,2,3)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR('a',1,2,3) +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '3)' at line 1 +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR('a',1,2,3) +errmsg +ERROR: FUNCTION unknown_schema.SUBSTR does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR('a',1,2,3) +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR('a',1,2,3) +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR('a',1,2,3) +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR('a',1,2,3) +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '3)' at line 1 +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR('a',1,2,3) +errmsg +ERROR: FUNCTION unknown_schema.SUBSTR does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR('a',1,2,3) +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR('a',1,2,3) +errmsg +ERROR: Function 'SUBSTR' is not defined +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR('a',1,2,3) +errmsg +ERROR: Function 'SUBSTR' is not defined +CALL p3('SUBSTR(''a'',1,2)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS `SUBSTR('a',1,2)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR('a',1,2) +errmsg +ERROR: FUNCTION unknown_schema.SUBSTR does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS `mariadb_schema.SUBSTR('a',1,2)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS `maxdb_schema.SUBSTR('a',1,2)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.substr('a',1,2) AS `oracle_schema.SUBSTR('a',1,2)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS "SUBSTR('a',1,2)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR('a',1,2) +errmsg +ERROR: FUNCTION unknown_schema.SUBSTR does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.substr('a',1,2) AS "mariadb_schema.SUBSTR('a',1,2)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.substr('a',1,2) AS "maxdb_schema.SUBSTR('a',1,2)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS "oracle_schema.SUBSTR('a',1,2)" +Warnings: +Note 1003 select substr('a',1,2) AS "oracle_schema.SUBSTR('a',1,2)" +CALL p3('SUBSTR(''a'' FROM 1)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS `SUBSTR('a' FROM 1)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR('a' FROM 1) +errmsg +ERROR: Function 'unknown_schema.SUBSTR' is not defined +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS `mariadb_schema.SUBSTR('a' FROM 1)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS `maxdb_schema.SUBSTR('a' FROM 1)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.substr('a',1) AS `oracle_schema.SUBSTR('a' FROM 1)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS "SUBSTR('a' FROM 1)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR('a' FROM 1) +errmsg +ERROR: Function 'unknown_schema.SUBSTR' is not defined +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.substr('a',1) AS "mariadb_schema.SUBSTR('a' FROM 1)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.substr('a',1) AS "maxdb_schema.SUBSTR('a' FROM 1)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS "oracle_schema.SUBSTR('a' FROM 1)" +Warnings: +Note 1003 select substr('a',1) AS "oracle_schema.SUBSTR('a' FROM 1)" +CALL p3('SUBSTRING(''a'',1,2)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTRING('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS `SUBSTRING('a',1,2)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTRING('a',1,2) +errmsg +ERROR: FUNCTION unknown_schema.SUBSTRING does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTRING('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS `mariadb_schema.SUBSTRING('a',1,2)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTRING('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS `maxdb_schema.SUBSTRING('a',1,2)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTRING('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.substr('a',1,2) AS `oracle_schema.SUBSTRING('a',1,2)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTRING('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS "SUBSTRING('a',1,2)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTRING('a',1,2) +errmsg +ERROR: FUNCTION unknown_schema.SUBSTRING does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTRING('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.substr('a',1,2) AS "mariadb_schema.SUBSTRING('a',1,2)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTRING('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.substr('a',1,2) AS "maxdb_schema.SUBSTRING('a',1,2)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTRING('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS "oracle_schema.SUBSTRING('a',1,2)" +Warnings: +Note 1003 select substr('a',1,2) AS "oracle_schema.SUBSTRING('a',1,2)" +CALL p3('SUBSTRING(''a'' FROM 1)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTRING('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS `SUBSTRING('a' FROM 1)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTRING('a' FROM 1) +errmsg +ERROR: Function 'unknown_schema.SUBSTRING' is not defined +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTRING('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS `mariadb_schema.SUBSTRING('a' FROM 1)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTRING('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS `maxdb_schema.SUBSTRING('a' FROM 1)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTRING('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.substr('a',1) AS `oracle_schema.SUBSTRING('a' FROM 1)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTRING('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS "SUBSTRING('a' FROM 1)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTRING('a' FROM 1) +errmsg +ERROR: Function 'unknown_schema.SUBSTRING' is not defined +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTRING('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.substr('a',1) AS "mariadb_schema.SUBSTRING('a' FROM 1)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTRING('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.substr('a',1) AS "maxdb_schema.SUBSTRING('a' FROM 1)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTRING('a' FROM 1) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1) AS "oracle_schema.SUBSTRING('a' FROM 1)" +Warnings: +Note 1003 select substr('a',1) AS "oracle_schema.SUBSTRING('a' FROM 1)" +CALL p3('TRIM()'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT TRIM() +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.TRIM() +errmsg +ERROR: FUNCTION unknown_schema.TRIM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.TRIM() +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.TRIM() +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.TRIM() +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT TRIM() +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.TRIM() +errmsg +ERROR: FUNCTION unknown_schema.TRIM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.TRIM() +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.TRIM() +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.TRIM() +errmsg +ERROR: Function 'TRIM' is not defined +CALL p3('TRIM(1,2)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT TRIM(1,2) +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '2)' at line 1 +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.TRIM(1,2) +errmsg +ERROR: FUNCTION unknown_schema.TRIM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.TRIM(1,2) +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.TRIM(1,2) +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.TRIM(1,2) +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT TRIM(1,2) +errmsg +ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '2)' at line 1 +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.TRIM(1,2) +errmsg +ERROR: FUNCTION unknown_schema.TRIM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.TRIM(1,2) +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.TRIM(1,2) +errmsg +ERROR: Function 'TRIM' is not defined +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.TRIM(1,2) +errmsg +ERROR: Function 'TRIM' is not defined +CALL p3('TRIM(''a'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT TRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim('a') AS `TRIM('a')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.TRIM('a') +errmsg +ERROR: FUNCTION unknown_schema.TRIM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.TRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim('a') AS `mariadb_schema.TRIM('a')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.TRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim('a') AS `maxdb_schema.TRIM('a')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.TRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.trim('a') AS `oracle_schema.TRIM('a')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT TRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim('a') AS "TRIM('a')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.TRIM('a') +errmsg +ERROR: FUNCTION unknown_schema.TRIM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.TRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.trim('a') AS "mariadb_schema.TRIM('a')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.TRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.trim('a') AS "maxdb_schema.TRIM('a')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.TRIM('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim('a') AS "oracle_schema.TRIM('a')" +Warnings: +Note 1003 select trim('a') AS "oracle_schema.TRIM('a')" +CALL p3('TRIM(BOTH '' '' FROM ''a'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT TRIM(BOTH ' ' FROM 'a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim(both ' ' from 'a') AS `TRIM(BOTH ' ' FROM 'a')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.TRIM(BOTH ' ' FROM 'a') +errmsg +ERROR: Function 'unknown_schema.TRIM' is not defined +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.TRIM(BOTH ' ' FROM 'a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim(both ' ' from 'a') AS `mariadb_schema.TRIM(BOTH ' ' FROM 'a')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.TRIM(BOTH ' ' FROM 'a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim(both ' ' from 'a') AS `maxdb_schema.TRIM(BOTH ' ' FROM 'a')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.TRIM(BOTH ' ' FROM 'a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.trim(both ' ' from 'a') AS `oracle_schema.TRIM(BOTH ' ' FROM 'a')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT TRIM(BOTH ' ' FROM 'a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim(both ' ' from 'a') AS "TRIM(BOTH ' ' FROM 'a')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.TRIM(BOTH ' ' FROM 'a') +errmsg +ERROR: Function 'unknown_schema.TRIM' is not defined +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.TRIM(BOTH ' ' FROM 'a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.trim(both ' ' from 'a') AS "mariadb_schema.TRIM(BOTH ' ' FROM 'a')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.TRIM(BOTH ' ' FROM 'a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.trim(both ' ' from 'a') AS "maxdb_schema.TRIM(BOTH ' ' FROM 'a')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.TRIM(BOTH ' ' FROM 'a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select trim(both ' ' from 'a') AS "oracle_schema.TRIM(BOTH ' ' FROM 'a')" +Warnings: +Note 1003 select trim(both ' ' from 'a') AS "oracle_schema.TRIM(BOTH ' ' FROM 'a')" +CALL p3('CONCAT_OPERATOR_ORACLE(''a'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT CONCAT_OPERATOR_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.concat('a') AS `CONCAT_OPERATOR_ORACLE('a')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.CONCAT_OPERATOR_ORACLE('a') +errmsg +ERROR: FUNCTION unknown_schema.CONCAT_OPERATOR_ORACLE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.CONCAT_OPERATOR_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.concat('a') AS `mariadb_schema.CONCAT_OPERATOR_ORACLE('a')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.CONCAT_OPERATOR_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.concat('a') AS `maxdb_schema.CONCAT_OPERATOR_ORACLE('a')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.CONCAT_OPERATOR_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.concat('a') AS `oracle_schema.CONCAT_OPERATOR_ORACLE('a')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT CONCAT_OPERATOR_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select concat('a') AS "CONCAT_OPERATOR_ORACLE('a')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.CONCAT_OPERATOR_ORACLE('a') +errmsg +ERROR: FUNCTION unknown_schema.CONCAT_OPERATOR_ORACLE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.CONCAT_OPERATOR_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select concat('a') AS "mariadb_schema.CONCAT_OPERATOR_ORACLE('a')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.CONCAT_OPERATOR_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select concat('a') AS "maxdb_schema.CONCAT_OPERATOR_ORACLE('a')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.CONCAT_OPERATOR_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select concat('a') AS "oracle_schema.CONCAT_OPERATOR_ORACLE('a')" +Warnings: +Note 1003 select concat('a') AS "oracle_schema.CONCAT_OPERATOR_ORACLE('a')" +CALL p3('DECODE_ORACLE(1,1,10)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT DECODE_ORACLE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.decode(1,1,10) AS `DECODE_ORACLE(1,1,10)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.DECODE_ORACLE(1,1,10) +errmsg +ERROR: FUNCTION unknown_schema.DECODE_ORACLE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.DECODE_ORACLE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.decode(1,1,10) AS `mariadb_schema.DECODE_ORACLE(1,1,10)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.DECODE_ORACLE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.decode(1,1,10) AS `maxdb_schema.DECODE_ORACLE(1,1,10)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.DECODE_ORACLE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.decode(1,1,10) AS `oracle_schema.DECODE_ORACLE(1,1,10)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT DECODE_ORACLE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select decode(1,1,10) AS "DECODE_ORACLE(1,1,10)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.DECODE_ORACLE(1,1,10) +errmsg +ERROR: FUNCTION unknown_schema.DECODE_ORACLE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.DECODE_ORACLE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select decode(1,1,10) AS "mariadb_schema.DECODE_ORACLE(1,1,10)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.DECODE_ORACLE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select decode(1,1,10) AS "maxdb_schema.DECODE_ORACLE(1,1,10)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.DECODE_ORACLE(1,1,10) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select decode(1,1,10) AS "oracle_schema.DECODE_ORACLE(1,1,10)" +Warnings: +Note 1003 select decode(1,1,10) AS "oracle_schema.DECODE_ORACLE(1,1,10)" +CALL p3('LTRIM_ORACLE(''a'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT LTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.ltrim('a') AS `LTRIM_ORACLE('a')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LTRIM_ORACLE('a') +errmsg +ERROR: FUNCTION unknown_schema.LTRIM_ORACLE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.ltrim('a') AS `mariadb_schema.LTRIM_ORACLE('a')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.ltrim('a') AS `maxdb_schema.LTRIM_ORACLE('a')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.ltrim('a') AS `oracle_schema.LTRIM_ORACLE('a')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT LTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select ltrim('a') AS "LTRIM_ORACLE('a')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LTRIM_ORACLE('a') +errmsg +ERROR: FUNCTION unknown_schema.LTRIM_ORACLE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select ltrim('a') AS "mariadb_schema.LTRIM_ORACLE('a')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select ltrim('a') AS "maxdb_schema.LTRIM_ORACLE('a')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select ltrim('a') AS "oracle_schema.LTRIM_ORACLE('a')" +Warnings: +Note 1003 select ltrim('a') AS "oracle_schema.LTRIM_ORACLE('a')" +CALL p3('RTRIM_ORACLE(''a'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT RTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rtrim('a') AS `RTRIM_ORACLE('a')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RTRIM_ORACLE('a') +errmsg +ERROR: FUNCTION unknown_schema.RTRIM_ORACLE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rtrim('a') AS `mariadb_schema.RTRIM_ORACLE('a')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rtrim('a') AS `maxdb_schema.RTRIM_ORACLE('a')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rtrim('a') AS `oracle_schema.RTRIM_ORACLE('a')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT RTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rtrim('a') AS "RTRIM_ORACLE('a')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RTRIM_ORACLE('a') +errmsg +ERROR: FUNCTION unknown_schema.RTRIM_ORACLE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rtrim('a') AS "mariadb_schema.RTRIM_ORACLE('a')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rtrim('a') AS "maxdb_schema.RTRIM_ORACLE('a')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RTRIM_ORACLE('a') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rtrim('a') AS "oracle_schema.RTRIM_ORACLE('a')" +Warnings: +Note 1003 select rtrim('a') AS "oracle_schema.RTRIM_ORACLE('a')" +CALL p3('LPAD_ORACLE(''a'',3)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT LPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.lpad('a',3) AS `LPAD_ORACLE('a',3)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LPAD_ORACLE('a',3) +errmsg +ERROR: FUNCTION unknown_schema.LPAD_ORACLE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.lpad('a',3) AS `mariadb_schema.LPAD_ORACLE('a',3)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.lpad('a',3) AS `maxdb_schema.LPAD_ORACLE('a',3)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.lpad('a',3) AS `oracle_schema.LPAD_ORACLE('a',3)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT LPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3) AS "LPAD_ORACLE('a',3)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.LPAD_ORACLE('a',3) +errmsg +ERROR: FUNCTION unknown_schema.LPAD_ORACLE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.LPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3) AS "mariadb_schema.LPAD_ORACLE('a',3)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.LPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3) AS "maxdb_schema.LPAD_ORACLE('a',3)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.LPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select lpad('a',3) AS "oracle_schema.LPAD_ORACLE('a',3)" +Warnings: +Note 1003 select lpad('a',3) AS "oracle_schema.LPAD_ORACLE('a',3)" +CALL p3('RPAD_ORACLE(''a'',3)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT RPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rpad('a',3) AS `RPAD_ORACLE('a',3)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RPAD_ORACLE('a',3) +errmsg +ERROR: FUNCTION unknown_schema.RPAD_ORACLE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rpad('a',3) AS `mariadb_schema.RPAD_ORACLE('a',3)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rpad('a',3) AS `maxdb_schema.RPAD_ORACLE('a',3)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.rpad('a',3) AS `oracle_schema.RPAD_ORACLE('a',3)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT RPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3) AS "RPAD_ORACLE('a',3)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.RPAD_ORACLE('a',3) +errmsg +ERROR: FUNCTION unknown_schema.RPAD_ORACLE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.RPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3) AS "mariadb_schema.RPAD_ORACLE('a',3)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.RPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3) AS "maxdb_schema.RPAD_ORACLE('a',3)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.RPAD_ORACLE('a',3) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select rpad('a',3) AS "oracle_schema.RPAD_ORACLE('a',3)" +Warnings: +Note 1003 select rpad('a',3) AS "oracle_schema.RPAD_ORACLE('a',3)" +CALL p3('REPLACE_ORACLE(''a'',''b'',''c'')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE_ORACLE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.replace('a','b','c') AS `REPLACE_ORACLE('a','b','c')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE_ORACLE('a','b','c') +errmsg +ERROR: FUNCTION unknown_schema.REPLACE_ORACLE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE_ORACLE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.replace('a','b','c') AS `mariadb_schema.REPLACE_ORACLE('a','b','c')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE_ORACLE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.replace('a','b','c') AS `maxdb_schema.REPLACE_ORACLE('a','b','c')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE_ORACLE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.replace('a','b','c') AS `oracle_schema.REPLACE_ORACLE('a','b','c')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT REPLACE_ORACLE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select replace('a','b','c') AS "REPLACE_ORACLE('a','b','c')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REPLACE_ORACLE('a','b','c') +errmsg +ERROR: FUNCTION unknown_schema.REPLACE_ORACLE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REPLACE_ORACLE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select replace('a','b','c') AS "mariadb_schema.REPLACE_ORACLE('a','b','c')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REPLACE_ORACLE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select replace('a','b','c') AS "maxdb_schema.REPLACE_ORACLE('a','b','c')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REPLACE_ORACLE('a','b','c') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select replace('a','b','c') AS "oracle_schema.REPLACE_ORACLE('a','b','c')" +Warnings: +Note 1003 select replace('a','b','c') AS "oracle_schema.REPLACE_ORACLE('a','b','c')" +CALL p3('SUBSTR_ORACLE(''a'',1,2)'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR_ORACLE('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.substr('a',1,2) AS `SUBSTR_ORACLE('a',1,2)` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR_ORACLE('a',1,2) +errmsg +ERROR: FUNCTION unknown_schema.SUBSTR_ORACLE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR_ORACLE('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.substr('a',1,2) AS `mariadb_schema.SUBSTR_ORACLE('a',1,2)` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR_ORACLE('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.substr('a',1,2) AS `maxdb_schema.SUBSTR_ORACLE('a',1,2)` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR_ORACLE('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.substr('a',1,2) AS `oracle_schema.SUBSTR_ORACLE('a',1,2)` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT SUBSTR_ORACLE('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS "SUBSTR_ORACLE('a',1,2)" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.SUBSTR_ORACLE('a',1,2) +errmsg +ERROR: FUNCTION unknown_schema.SUBSTR_ORACLE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.SUBSTR_ORACLE('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS "mariadb_schema.SUBSTR_ORACLE('a',1,2)" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.SUBSTR_ORACLE('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS "maxdb_schema.SUBSTR_ORACLE('a',1,2)" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.SUBSTR_ORACLE('a',1,2) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select substr('a',1,2) AS "oracle_schema.SUBSTR_ORACLE('a',1,2)" +Warnings: +Note 1003 select substr('a',1,2) AS "oracle_schema.SUBSTR_ORACLE('a',1,2)" +SELECT oracle_schema.SUBSTR_ORACLE('a' FROM 1 FOR 2); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FROM 1 FOR 2)' at line 1 +SELECT oracle_schema.SUBSTR('a' FROM 1 FOR 2); +oracle_schema.SUBSTR('a' FROM 1 FOR 2) +a +SELECT oracle_schema.TRIM_ORACLE(LEADING ' ' FROM 'a'); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'LEADING ' ' FROM 'a')' at line 1 +SELECT oracle_schema.TRIM(LEADING ' ' FROM 'a'); +oracle_schema.TRIM(LEADING ' ' FROM 'a') +a +SELECT oracle_schema.TRIM_ORACLE('a'); +ERROR HY000: Function 'TRIM_ORACLE' is not defined +SELECT oracle_schema.TRIM('a'); +oracle_schema.TRIM('a') +a +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; +SET sql_mode=''; +CREATE VIEW v1 AS SELECT +concat('a','b'), +decode('1','2'), +ltrim('1'), +rtrim('1'), +lpad('1','2', 3), +rpad('1','2', 3), +replace('1','2','3'), +substr('a',1,2), +trim(both 'a' FROM 'b'); +CREATE TABLE kv (v BLOB); +LOAD DATA INFILE 'MYSQLD_DATADIR/test/v1.frm' REPLACE INTO TABLE kv; +SELECT v FROM kv WHERE v RLIKE '^(query|view_body_utf8)=' ORDER BY v; +v +query=select concat('a','b') AS `concat('a','b')`,decode('1','2') AS `decode('1','2')`,ltrim('1') AS `ltrim('1')`,rtrim('1') AS `rtrim('1')`,lpad('1','2',3) AS `lpad('1','2', 3)`,rpad('1','2',3) AS `rpad('1','2', 3)`,replace('1','2','3') AS `replace('1','2','3')`,substr('a',1,2) AS `substr('a',1,2)`,trim(both 'a' from 'b') AS `trim(both 'a' FROM 'b')` +view_body_utf8=select concat('a','b') AS `concat('a','b')`,decode('1','2') AS `decode('1','2')`,ltrim('1') AS `ltrim('1')`,rtrim('1') AS `rtrim('1')`,lpad('1','2',3) AS `lpad('1','2', 3)`,rpad('1','2',3) AS `rpad('1','2', 3)`,replace('1','2','3') AS `replace('1','2','3')`,substr('a',1,2) AS `substr('a',1,2)`,trim(both 'a' from 'b') AS `trim(both 'a' FROM 'b')` +SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME='v1' AND TABLE_SCHEMA='test'; +VIEW_DEFINITION +select concat('a','b') AS `concat('a','b')`,decode('1','2') AS `decode('1','2')`,ltrim('1') AS `ltrim('1')`,rtrim('1') AS `rtrim('1')`,lpad('1','2',3) AS `lpad('1','2', 3)`,rpad('1','2',3) AS `rpad('1','2', 3)`,replace('1','2','3') AS `replace('1','2','3')`,substr('a',1,2) AS `substr('a',1,2)`,trim(both 'a' from 'b') AS `trim(both 'a' FROM 'b')` +DROP TABLE kv; +DROP VIEW v1; +SET sql_mode='ORACLE'; +CREATE VIEW v1 AS SELECT +concat('a','b'), +decode('1',2,3), +ltrim('1'), +rtrim('1'), +lpad('1','2', 3), +rpad('1','2', 3), +replace('1','2','3'), +substr('a',1,2), +trim(both 'a' FROM 'b'); +CREATE TABLE kv (v BLOB); +LOAD DATA INFILE 'MYSQLD_DATADIR/test/v1.frm' REPLACE INTO TABLE kv; +SELECT v FROM kv WHERE v RLIKE '^(query|view_body_utf8)=' ORDER BY v; +v +query=select concat_operator_oracle('a','b') AS `concat('a','b')`,decode_oracle('1',2,3) AS `decode('1',2,3)`,ltrim_oracle('1') AS `ltrim('1')`,rtrim_oracle('1') AS `rtrim('1')`,lpad_oracle('1','2',3) AS `lpad('1','2', 3)`,rpad_oracle('1','2',3) AS `rpad('1','2', 3)`,replace_oracle('1','2','3') AS `replace('1','2','3')`,substr_oracle('a',1,2) AS `substr('a',1,2)`,trim_oracle(both 'a' from 'b') AS `trim(both 'a' FROM 'b')` +view_body_utf8=select oracle_schema.concat('a','b') AS `concat('a','b')`,oracle_schema.decode('1',2,3) AS `decode('1',2,3)`,oracle_schema.ltrim('1') AS `ltrim('1')`,oracle_schema.rtrim('1') AS `rtrim('1')`,oracle_schema.lpad('1','2',3) AS `lpad('1','2', 3)`,oracle_schema.rpad('1','2',3) AS `rpad('1','2', 3)`,oracle_schema.replace('1','2','3') AS `replace('1','2','3')`,oracle_schema.substr('a',1,2) AS `substr('a',1,2)`,oracle_schema.trim(both 'a' from 'b') AS `trim(both 'a' FROM 'b')` +SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME='v1' AND TABLE_SCHEMA='test'; +VIEW_DEFINITION +select oracle_schema.concat('a','b') AS `concat('a','b')`,oracle_schema.decode('1',2,3) AS `decode('1',2,3)`,oracle_schema.ltrim('1') AS `ltrim('1')`,oracle_schema.rtrim('1') AS `rtrim('1')`,oracle_schema.lpad('1','2',3) AS `lpad('1','2', 3)`,oracle_schema.rpad('1','2',3) AS `rpad('1','2', 3)`,oracle_schema.replace('1','2','3') AS `replace('1','2','3')`,oracle_schema.substr('a',1,2) AS `substr('a',1,2)`,oracle_schema.trim(both 'a' from 'b') AS `trim(both 'a' FROM 'b')` +DROP TABLE kv; +DROP VIEW v1; diff --git a/mysql-test/suite/compat/oracle/r/func_replace.result b/mysql-test/suite/compat/oracle/r/func_replace.result index 02516096286..012db2a7500 100644 --- a/mysql-test/suite/compat/oracle/r/func_replace.result +++ b/mysql-test/suite/compat/oracle/r/func_replace.result @@ -21,11 +21,11 @@ EXPLAIN EXTENDED SELECT REPLACE('ab','a',null) ; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select replace_oracle('ab','a',NULL) AS "REPLACE('ab','a',null)" +Note 1003 select replace('ab','a',NULL) AS "REPLACE('ab','a',null)" CREATE VIEW v1 AS SELECT REPLACE('ab','a',null) ; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection -v1 CREATE VIEW "v1" AS select replace_oracle('ab','a',NULL) AS "REPLACE('ab','a',null)" latin1 latin1_swedish_ci +v1 CREATE VIEW "v1" AS select replace('ab','a',NULL) AS "REPLACE('ab','a',null)" latin1 latin1_swedish_ci SELECT * FROM v1; REPLACE('ab','a',null) b diff --git a/mysql-test/suite/compat/oracle/r/func_substr.result b/mysql-test/suite/compat/oracle/r/func_substr.result index 5d9fdd5f2b9..cbb0e74cc3a 100644 --- a/mysql-test/suite/compat/oracle/r/func_substr.result +++ b/mysql-test/suite/compat/oracle/r/func_substr.result @@ -76,11 +76,11 @@ EXPLAIN EXTENDED SELECT SUBSTR('abc',2,1) ; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select substr_oracle('abc',2,1) AS "SUBSTR('abc',2,1)" +Note 1003 select substr('abc',2,1) AS "SUBSTR('abc',2,1)" CREATE VIEW v1 AS SELECT SUBSTR('abc',2,1) ; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection -v1 CREATE VIEW "v1" AS select substr_oracle('abc',2,1) AS "SUBSTR('abc',2,1)" latin1 latin1_swedish_ci +v1 CREATE VIEW "v1" AS select substr('abc',2,1) AS "SUBSTR('abc',2,1)" latin1 latin1_swedish_ci SELECT * FROM v1; SUBSTR('abc',2,1) b diff --git a/mysql-test/suite/compat/oracle/r/func_trim.result b/mysql-test/suite/compat/oracle/r/func_trim.result index bed8dadf97f..965531db288 100644 --- a/mysql-test/suite/compat/oracle/r/func_trim.result +++ b/mysql-test/suite/compat/oracle/r/func_trim.result @@ -116,13 +116,13 @@ TRIM(TRAILING 'a' FROM 'abc') ; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select trim_oracle('abc') AS "TRIM('abc')",trim_oracle(both 'a' from 'abc') AS "TRIM(BOTH 'a' FROM 'abc')",trim_oracle(leading 'a' from 'abc') AS "TRIM(LEADING 'a' FROM 'abc')",trim_oracle(trailing 'a' from 'abc') AS "TRIM(TRAILING 'a' FROM 'abc')" +Note 1003 select trim('abc') AS "TRIM('abc')",trim(both 'a' from 'abc') AS "TRIM(BOTH 'a' FROM 'abc')",trim(leading 'a' from 'abc') AS "TRIM(LEADING 'a' FROM 'abc')",trim(trailing 'a' from 'abc') AS "TRIM(TRAILING 'a' FROM 'abc')" EXPLAIN EXTENDED SELECT RTRIM('abc'), LTRIM('abc'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select rtrim_oracle('abc') AS "RTRIM('abc')",ltrim_oracle('abc') AS "LTRIM('abc')" +Note 1003 select rtrim('abc') AS "RTRIM('abc')",ltrim('abc') AS "LTRIM('abc')" CREATE VIEW v1 AS SELECT ord,TRIM('abc'),RTRIM('abc'),LTRIM('abc'), '['||c1||']', TRIM(LEADING 'a' FROM c1), @@ -133,7 +133,7 @@ RTRIM(c1) FROM t1 ORDER BY ord ; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection -v1 CREATE VIEW "v1" AS select "t1"."ord" AS "ord",trim_oracle('abc') AS "TRIM('abc')",rtrim_oracle('abc') AS "RTRIM('abc')",ltrim_oracle('abc') AS "LTRIM('abc')",concat_operator_oracle(concat_operator_oracle('[',"t1"."c1"),']') AS "'['||c1||']'",trim_oracle(leading 'a' from "t1"."c1") AS "TRIM(LEADING 'a' FROM c1)",trim_oracle(trailing 'a' from "t1"."c1") AS "TRIM(TRAILING 'a' FROM c1)",trim_oracle(both 'a' from "t1"."c1") AS "TRIM(BOTH 'a' FROM c1)",ltrim_oracle("t1"."c1") AS "LTRIM(c1)",rtrim_oracle("t1"."c1") AS "RTRIM(c1)" from "t1" order by "t1"."ord" latin1 latin1_swedish_ci +v1 CREATE VIEW "v1" AS select "t1"."ord" AS "ord",trim('abc') AS "TRIM('abc')",rtrim('abc') AS "RTRIM('abc')",ltrim('abc') AS "LTRIM('abc')",concat(concat('[',"t1"."c1"),']') AS "'['||c1||']'",trim(leading 'a' from "t1"."c1") AS "TRIM(LEADING 'a' FROM c1)",trim(trailing 'a' from "t1"."c1") AS "TRIM(TRAILING 'a' FROM c1)",trim(both 'a' from "t1"."c1") AS "TRIM(BOTH 'a' FROM c1)",ltrim("t1"."c1") AS "LTRIM(c1)",rtrim("t1"."c1") AS "RTRIM(c1)" from "t1" order by "t1"."ord" latin1 latin1_swedish_ci SELECT * FROM v1; ord TRIM('abc') RTRIM('abc') LTRIM('abc') '['||c1||']' TRIM(LEADING 'a' FROM c1) TRIM(TRAILING 'a' FROM c1) TRIM(BOTH 'a' FROM c1) LTRIM(c1) RTRIM(c1) 1 abc abc abc [abc] bc abc bc abc abc diff --git a/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result b/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result new file mode 100644 index 00000000000..fd3dd787f1e --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result @@ -0,0 +1,112 @@ +# +# Start of 10.4 tests +# +# +# MDEV-27744 LPAD in vcol created in ORACLE mode makes table corrupted in non-ORACLE +# +SET sql_mode=DEFAULT; +CREATE TABLE t1 ( +a0 VARCHAR(64) NOT NULL DEFAULT LTRIM(now()), +a1 VARCHAR(64) AS (LTRIM(a0)) PERSISTENT, +b0 VARCHAR(64) NOT NULL DEFAULT LPAD(now(),10), +b1 VARCHAR(64) AS (LPAD(b0,10)) PERSISTENT +); +CREATE VIEW v1 AS SELECT +LTRIM(now()) AS a0, +LPAD(now(),10) AS b0; +SET sql_mode=ORACLE; +CREATE TABLE t2 ( +a0 VARCHAR(64) NOT NULL DEFAULT LTRIM(now()), +a1 VARCHAR(64) AS (LTRIM(a0)) PERSISTENT, +b0 VARCHAR(64) NOT NULL DEFAULT LPAD(now(),10), +b1 VARCHAR(64) AS (LPAD(b0,10)) PERSISTENT +); +CREATE VIEW v2 AS SELECT +LTRIM(now()) AS a0, +LPAD(now(),10) AS b0; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `a0` varchar(64) NOT NULL DEFAULT ltrim(current_timestamp()), + `a1` varchar(64) GENERATED ALWAYS AS (ltrim(`a0`)) STORED, + `b0` varchar(64) NOT NULL DEFAULT lpad(current_timestamp(),10), + `b1` varchar(64) GENERATED ALWAYS AS (lpad(`b0`,10)) STORED +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t2` ( + `a0` varchar(64) NOT NULL DEFAULT ltrim_oracle(current_timestamp()), + `a1` varchar(64) GENERATED ALWAYS AS (ltrim_oracle(`a0`)) STORED, + `b0` varchar(64) NOT NULL DEFAULT lpad_oracle(current_timestamp(),10), + `b1` varchar(64) GENERATED ALWAYS AS (lpad_oracle(`b0`,10)) STORED +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +/*!50001 CREATE VIEW `v1` AS SELECT + 1 AS `a0`, + 1 AS `b0` */; +SET character_set_client = @saved_cs_client; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +/*!50001 CREATE VIEW `v2` AS SELECT + 1 AS `a0`, + 1 AS `b0` */; +SET character_set_client = @saved_cs_client; +/*!50001 DROP VIEW IF EXISTS `v1`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = latin1 */; +/*!50001 SET character_set_results = latin1 */; +/*!50001 SET collation_connection = latin1_swedish_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ +/*!50001 VIEW `v1` AS select ltrim(current_timestamp()) AS `a0`,lpad(current_timestamp(),10) AS `b0` */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +/*!50001 DROP VIEW IF EXISTS `v2`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = latin1 */; +/*!50001 SET character_set_results = latin1 */; +/*!50001 SET collation_connection = latin1_swedish_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ +/*!50001 VIEW `v2` AS select oracle_schema.ltrim(current_timestamp()) AS `a0`,oracle_schema.lpad(current_timestamp(),10) AS `b0` */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +DROP TABLE t1,t2; +DROP VIEW v1,v2; +SET sql_mode=DEFAULT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a0` varchar(64) NOT NULL DEFAULT ltrim(current_timestamp()), + `a1` varchar(64) GENERATED ALWAYS AS (ltrim(`a0`)) STORED, + `b0` varchar(64) NOT NULL DEFAULT lpad(current_timestamp(),10), + `b1` varchar(64) GENERATED ALWAYS AS (lpad(`b0`,10)) STORED +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a0` varchar(64) NOT NULL DEFAULT ltrim_oracle(current_timestamp()), + `a1` varchar(64) GENERATED ALWAYS AS (ltrim_oracle(`a0`)) STORED, + `b0` varchar(64) NOT NULL DEFAULT lpad_oracle(current_timestamp(),10), + `b1` varchar(64) GENERATED ALWAYS AS (lpad_oracle(`b0`,10)) STORED +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select ltrim(current_timestamp()) AS `a0`,lpad(current_timestamp(),10) AS `b0` latin1 latin1_swedish_ci +SHOW CREATE VIEW v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select oracle_schema.ltrim(current_timestamp()) AS `a0`,oracle_schema.lpad(current_timestamp(),10) AS `b0` latin1 latin1_swedish_ci +DROP TABLE t1,t2; +DROP VIEW v1, v2; +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/compat/oracle/r/ps.result b/mysql-test/suite/compat/oracle/r/ps.result index 818c97b06ab..2d0c4da9554 100644 --- a/mysql-test/suite/compat/oracle/r/ps.result +++ b/mysql-test/suite/compat/oracle/r/ps.result @@ -178,9 +178,9 @@ EXECUTE IMMEDIATE 'SELECT :1 FROM DUAL' USING 10; # Testing erroneous and diallowed prepare source # EXECUTE IMMEDIATE _latin1'SELECT 1 AS c FROM ' || _latin2 'DUAL'; -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat_operator_oracle' +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat' PREPARE stmt FROM _latin1'SELECT 1 AS c FROM ' || _latin2 'DUAL'; -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat_operator_oracle' +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat' EXECUTE IMMEDIATE (SELECT 'SELECT 1'); ERROR 42000: EXECUTE IMMEDIATE does not support subqueries or stored functions PREPARE stmt FROM (SELECT 'SELECT 1'); diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result index 31d794c9f61..93300cc375b 100644 --- a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result +++ b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result @@ -758,7 +758,7 @@ END; END; $$ CALL p1(); -ERROR HY000: Illegal mix of collations (latin1_bin,EXPLICIT) and (latin1_swedish_ci,EXPLICIT) for operation 'concat_operator_oracle' +ERROR HY000: Illegal mix of collations (latin1_bin,EXPLICIT) and (latin1_swedish_ci,EXPLICIT) for operation 'concat' DROP PROCEDURE p1; # # Non-existing field diff --git a/mysql-test/suite/compat/oracle/r/vcol_innodb.result b/mysql-test/suite/compat/oracle/r/vcol_innodb.result new file mode 100644 index 00000000000..112d1b4ad53 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/vcol_innodb.result @@ -0,0 +1,54 @@ +# +# MDEV-27744 LPAD in vcol created in ORACLE mode makes table corrupted in non-ORACLE +# +FLUSH TABLES; +SET sql_mode=''; +CREATE TABLE t (d INT,b VARCHAR(1),c CHAR(1),g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,PRIMARY KEY(b),KEY g(g)) ENGINE=InnoDB; +INSERT INTO t VALUES (0); +ERROR 21S01: Column count doesn't match value count at row 1 +SET sql_mode='ORACLE'; +INSERT INTO t SET c=REPEAT (1,0); +Warnings: +Warning 1364 Field 'b' doesn't have a default value +ALTER TABLE t CHANGE COLUMN a b INT; +ERROR 42S22: Unknown column 'a' in 't' +DELETE FROM t; +SET sql_mode=''; +FLUSH TABLES; +INSERT INTO t SET c='0'; +Warnings: +Warning 1364 Field 'b' doesn't have a default value +DROP TABLE t; +FLUSH TABLES; +SET sql_mode=''; +CREATE TABLE t (a INT(1),d INT(1),b VARCHAR(1),c CHAR(1),vadc INT(1) GENERATED ALWAYS AS ( (a + length (d))) STORED,vbc CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,vbidxc CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,PRIMARY KEY(b (1),a,d),KEY d (d),KEY a (a),KEY c_renamed (c (1),b (1)),KEY b (b (1),c (1),a),KEY vbidxc (vbidxc),KEY a_2 (a,vbidxc),KEY vbidxc_2 (vbidxc,d)) DEFAULT CHARSET=latin1 ENGINE=InnoDB; +INSERT INTO t VALUES (0,0,1,0,1,0,1,0,0); +ERROR 21S01: Column count doesn't match value count at row 1 +SET SESSION sql_mode='ORACLE'; +INSERT INTO t SET c=REPEAT (1,0); +Warnings: +Warning 1364 Field 'a' doesn't have a default value +Warning 1364 Field 'd' doesn't have a default value +Warning 1364 Field 'b' doesn't have a default value +ALTER TABLE t CHANGE COLUMN a b CHAR(1); +ERROR 42S21: Duplicate column name 'b' +DELETE FROM t; +SET SESSION sql_mode=DEFAULT; +DROP TABLE t; +SET sql_mode=''; +CREATE TABLE t1 (d INT,b VARCHAR(1),c CHAR(1),g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,PRIMARY KEY(b),KEY g(g)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (0); +ERROR 21S01: Column count doesn't match value count at row 1 +SET sql_mode='ORACLE'; +INSERT INTO t1 SET c=REPEAT (1,0); +Warnings: +Warning 1364 Field 'b' doesn't have a default value +ALTER TABLE t1 CHANGE COLUMN a b INT; +ERROR 42S22: Unknown column 'a' in 't1' +DELETE FROM t1; +SET sql_mode=''; +FLUSH TABLES; +INSERT INTO t1 SET c='0'; +Warnings: +Warning 1364 Field 'b' doesn't have a default value +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/t/func_qualified.test b/mysql-test/suite/compat/oracle/t/func_qualified.test new file mode 100644 index 00000000000..842015dbbd6 --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/func_qualified.test @@ -0,0 +1,247 @@ +--let $MYSQLD_DATADIR= `select @@datadir` + +--echo # +--echo # MDEV-27744 LPAD in vcol created in ORACLE mode makes table corrupted in non-ORACLE +--echo # + +# +# Testing that the error message for DECODE preserves +# the exact letter case as typed by the user +# + +SET sql_mode=DEFAULT; +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT decode_oracle(1); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT DECODE_ORACLE(1); + +SET sql_mode=ORACLE; +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT decode_oracle(1); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT DECODE_ORACLE(1); + +SET sql_mode=DEFAULT; +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT decode(1); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT DECODE(1); + +SET sql_mode=ORACLE; +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT decode(1); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT DECODE(1); + +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT mariadb_schema.decode(1); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT mariadb_schema.DECODE(1); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT mariadb_schema.decode_oracle(1); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT mariadb_schema.DECODE_ORACLE(1); + +# +# Testing that REPLACE, SUBSTR, TRIM print the exact name +# as typed by the user in "Function .. is not defined" +# + +SET sql_mode=DEFAULT; + +--error ER_FUNC_INEXISTENT_NAME_COLLISION +SELECT unknown.TRIM(1); +--error ER_FUNC_INEXISTENT_NAME_COLLISION +SELECT unknown.trim(1); + +--error ER_FUNCTION_NOT_DEFINED +SELECT oracle_schema.TRIM(); +--error ER_FUNCTION_NOT_DEFINED +SELECT oracle_schema.TRIM('a','b'); +--error ER_FUNCTION_NOT_DEFINED +SELECT oracle_schema.TRIM('a','b','c','d'); + +--error ER_FUNC_INEXISTENT_NAME_COLLISION +SELECT unknown.SUBSTR('a',1,2); +--error ER_FUNC_INEXISTENT_NAME_COLLISION +SELECT unknown.substr('a',1,2); +--error ER_FUNC_INEXISTENT_NAME_COLLISION +SELECT unknown.SUBSTRING('a',1,2); +--error ER_FUNC_INEXISTENT_NAME_COLLISION +SELECT unknown.substring('a',1,2); + +--error ER_FUNC_INEXISTENT_NAME_COLLISION +SELECT unknown.REPLACE('a','b','c'); +--error ER_FUNC_INEXISTENT_NAME_COLLISION +SELECT unknown.replace('a','b','c'); + +--error ER_FUNCTION_NOT_DEFINED +SELECT oracle_schema.REPLACE(); +--error ER_FUNCTION_NOT_DEFINED +SELECT oracle_schema.REPLACE('a'); +--error ER_FUNCTION_NOT_DEFINED +SELECT oracle_schema.REPLACE('a','b'); +--error ER_FUNCTION_NOT_DEFINED +SELECT oracle_schema.REPLACE('a','b','c','d'); + +# +# Testing EXPLAIN EXTENDED SELECT +# + +SET sql_mode=DEFAULT; +DELIMITER $$; +CREATE PROCEDURE p1(sqlmode TEXT, qualifier TEXT, expr TEXT) +BEGIN + DECLARE query TEXT DEFAULT 'SELECT $(QUALIFIER)$(EXPR)'; + DECLARE errmsg TEXT DEFAULT NULL; + DECLARE CONTINUE HANDLER FOR 1064, 1128, 1305, 1582, 1630 + BEGIN + GET DIAGNOSTICS CONDITION 1 errmsg = MESSAGE_TEXT; + END; + + SET sql_mode=sqlmode; + SET query=REPLACE(query, '$(QUALIFIER)', qualifier); + SET query=REPLACE(query, '$(EXPR)', expr); + SET query= CONCAT('EXPLAIN EXTENDED ', query); + SELECT CONCAT('sql_mode=''',sqlmode,'''', ' ', + 'qualifier=''',qualifier,'''') AS `----------`; + SELECT query; + EXECUTE IMMEDIATE query; + IF errmsg IS NOT NULL THEN + SELECT CONCAT('ERROR: ', errmsg) AS errmsg; + ELSE + SHOW WARNINGS; + END IF; +END; +$$ +CREATE PROCEDURE p2(sqlmode TEXT, expr TEXT) +BEGIN + CALL p1(sqlmode, '', expr); + CALL p1(sqlmode, 'unknown_schema.', expr); + CALL p1(sqlmode, 'mariadb_schema.', expr); + CALL p1(sqlmode, 'maxdb_schema.', expr); + CALL p1(sqlmode, 'oracle_schema.', expr); +END; +$$ +CREATE PROCEDURE p3(expr TEXT) +BEGIN + CALL p2('', expr); + CALL p2('ORACLE', expr); +END; +$$ +DELIMITER ;$$ + +CALL p3('CONCAT(''a'')'); + +# MariaDB style +CALL p3('DECODE(''1'',''2'')'); +# Oracle style +CALL p3('DECODE(1,1,10)'); + +CALL p3('LTRIM(''a'')'); +CALL p3('RTRIM(''a'')'); + +CALL p3('LPAD(''a'',3)'); +CALL p3('LPAD(''a'',3, '' '')'); + +CALL p3('RPAD(''a'',3)'); +CALL p3('RPAD(''a'',3, '' '')'); + +CALL p3('REPLACE()'); +CALL p3('REPLACE(''a'',''b'')'); +CALL p3('REPLACE(''a'',''b'',''c'',''d'')'); +CALL p3('REPLACE(''a'',''b'',''c'')'); + +CALL p3('SUBSTR()'); +CALL p3('SUBSTR(''a'',1,2,3)'); +CALL p3('SUBSTR(''a'',1,2)'); +CALL p3('SUBSTR(''a'' FROM 1)'); + +CALL p3('SUBSTRING(''a'',1,2)'); +CALL p3('SUBSTRING(''a'' FROM 1)'); + +CALL p3('TRIM()'); +CALL p3('TRIM(1,2)'); +CALL p3('TRIM(''a'')'); +CALL p3('TRIM(BOTH '' '' FROM ''a'')'); + + +# Deprecated compatibility XXX_ORACLE functions. +# These functions are implemented as simple native functions +# and have no special grammar rules in sql_yacc.yy. +# So they support the qualified syntax automatically, +# which is not absolutely required, but is not harmful. + +CALL p3('CONCAT_OPERATOR_ORACLE(''a'')'); +CALL p3('DECODE_ORACLE(1,1,10)'); +CALL p3('LTRIM_ORACLE(''a'')'); +CALL p3('RTRIM_ORACLE(''a'')'); +CALL p3('LPAD_ORACLE(''a'',3)'); +CALL p3('RPAD_ORACLE(''a'',3)'); +CALL p3('REPLACE_ORACLE(''a'',''b'',''c'')'); +CALL p3('SUBSTR_ORACLE(''a'',1,2)'); + + +# Deprecated compatibility XXX_ORACLE variants for functions +# with a special syntax in sql_yacc.yy. +# These compatibility functions do not support qualified syntax. +# One should use a qualified variant without the _ORACLE suffix instead. + +--error ER_PARSE_ERROR +SELECT oracle_schema.SUBSTR_ORACLE('a' FROM 1 FOR 2); +# Use this instead: +SELECT oracle_schema.SUBSTR('a' FROM 1 FOR 2); + +--error ER_PARSE_ERROR +SELECT oracle_schema.TRIM_ORACLE(LEADING ' ' FROM 'a'); +# Use this instead: +SELECT oracle_schema.TRIM(LEADING ' ' FROM 'a'); + +--error ER_FUNCTION_NOT_DEFINED +SELECT oracle_schema.TRIM_ORACLE('a'); +# Use this instead: +SELECT oracle_schema.TRIM('a'); + + +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; + + +SET sql_mode=''; +CREATE VIEW v1 AS SELECT + concat('a','b'), + decode('1','2'), + ltrim('1'), + rtrim('1'), + lpad('1','2', 3), + rpad('1','2', 3), + replace('1','2','3'), + substr('a',1,2), + trim(both 'a' FROM 'b'); +CREATE TABLE kv (v BLOB); +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA INFILE '$MYSQLD_DATADIR/test/v1.frm' REPLACE INTO TABLE kv; +SELECT v FROM kv WHERE v RLIKE '^(query|view_body_utf8)=' ORDER BY v; +SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME='v1' AND TABLE_SCHEMA='test'; +DROP TABLE kv; +DROP VIEW v1; + +SET sql_mode='ORACLE'; +CREATE VIEW v1 AS SELECT + concat('a','b'), + decode('1',2,3), + ltrim('1'), + rtrim('1'), + lpad('1','2', 3), + rpad('1','2', 3), + replace('1','2','3'), + substr('a',1,2), + trim(both 'a' FROM 'b'); +CREATE TABLE kv (v BLOB); +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA INFILE '$MYSQLD_DATADIR/test/v1.frm' REPLACE INTO TABLE kv; +SELECT v FROM kv WHERE v RLIKE '^(query|view_body_utf8)=' ORDER BY v; +SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME='v1' AND TABLE_SCHEMA='test'; +DROP TABLE kv; +DROP VIEW v1; diff --git a/mysql-test/suite/compat/oracle/t/mysqldump_restore_func_qualified.test b/mysql-test/suite/compat/oracle/t/mysqldump_restore_func_qualified.test new file mode 100644 index 00000000000..36ab3543ea1 --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/mysqldump_restore_func_qualified.test @@ -0,0 +1,50 @@ +# See comments in mysql-test/main/mysqldump_restore.test +--source include/not_embedded.inc + +let $mysqldumpfile = $MYSQLTEST_VARDIR/tmp/mysqldump_func_qualified.sql; + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-27744 LPAD in vcol created in ORACLE mode makes table corrupted in non-ORACLE +--echo # + +SET sql_mode=DEFAULT; +CREATE TABLE t1 ( + a0 VARCHAR(64) NOT NULL DEFAULT LTRIM(now()), + a1 VARCHAR(64) AS (LTRIM(a0)) PERSISTENT, + b0 VARCHAR(64) NOT NULL DEFAULT LPAD(now(),10), + b1 VARCHAR(64) AS (LPAD(b0,10)) PERSISTENT +); +CREATE VIEW v1 AS SELECT + LTRIM(now()) AS a0, + LPAD(now(),10) AS b0; +SET sql_mode=ORACLE; +CREATE TABLE t2 ( + a0 VARCHAR(64) NOT NULL DEFAULT LTRIM(now()), + a1 VARCHAR(64) AS (LTRIM(a0)) PERSISTENT, + b0 VARCHAR(64) NOT NULL DEFAULT LPAD(now(),10), + b1 VARCHAR(64) AS (LPAD(b0,10)) PERSISTENT +); +CREATE VIEW v2 AS SELECT + LTRIM(now()) AS a0, + LPAD(now(),10) AS b0; +--exec $MYSQL_DUMP --skip-extended-insert test --skip-comments --compact t1 t2 v1 v2 +--exec $MYSQL_DUMP --skip-extended-insert test --skip-comments t1 t2 v1 v2 > $mysqldumpfile +DROP TABLE t1,t2; +DROP VIEW v1,v2; +--exec $MYSQL test < $mysqldumpfile +SET sql_mode=DEFAULT; +SHOW CREATE TABLE t1; +SHOW CREATE TABLE t2; +SHOW CREATE VIEW v1; +SHOW CREATE VIEW v2; +--remove_file $mysqldumpfile +DROP TABLE t1,t2; +DROP VIEW v1, v2; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/suite/compat/oracle/t/vcol_innodb.test b/mysql-test/suite/compat/oracle/t/vcol_innodb.test new file mode 100644 index 00000000000..bd923f9bec1 --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/vcol_innodb.test @@ -0,0 +1,47 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-27744 LPAD in vcol created in ORACLE mode makes table corrupted in non-ORACLE +--echo # + +FLUSH TABLES; +SET sql_mode=''; +CREATE TABLE t (d INT,b VARCHAR(1),c CHAR(1),g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,PRIMARY KEY(b),KEY g(g)) ENGINE=InnoDB; +--error ER_WRONG_VALUE_COUNT_ON_ROW +INSERT INTO t VALUES (0); +SET sql_mode='ORACLE'; +INSERT INTO t SET c=REPEAT (1,0); +--error ER_BAD_FIELD_ERROR +ALTER TABLE t CHANGE COLUMN a b INT; +DELETE FROM t; +SET sql_mode=''; +FLUSH TABLES; +INSERT INTO t SET c='0'; +DROP TABLE t; +FLUSH TABLES; + +SET sql_mode=''; +CREATE TABLE t (a INT(1),d INT(1),b VARCHAR(1),c CHAR(1),vadc INT(1) GENERATED ALWAYS AS ( (a + length (d))) STORED,vbc CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,vbidxc CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,PRIMARY KEY(b (1),a,d),KEY d (d),KEY a (a),KEY c_renamed (c (1),b (1)),KEY b (b (1),c (1),a),KEY vbidxc (vbidxc),KEY a_2 (a,vbidxc),KEY vbidxc_2 (vbidxc,d)) DEFAULT CHARSET=latin1 ENGINE=InnoDB; +--error ER_WRONG_VALUE_COUNT_ON_ROW +INSERT INTO t VALUES (0,0,1,0,1,0,1,0,0); +SET SESSION sql_mode='ORACLE'; +INSERT INTO t SET c=REPEAT (1,0); +--error ER_DUP_FIELDNAME +ALTER TABLE t CHANGE COLUMN a b CHAR(1); +DELETE FROM t; +SET SESSION sql_mode=DEFAULT; +DROP TABLE t; + +SET sql_mode=''; +CREATE TABLE t1 (d INT,b VARCHAR(1),c CHAR(1),g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,PRIMARY KEY(b),KEY g(g)) ENGINE=InnoDB; +--error ER_WRONG_VALUE_COUNT_ON_ROW +INSERT INTO t1 VALUES (0); +SET sql_mode='ORACLE'; +INSERT INTO t1 SET c=REPEAT (1,0); +--error ER_BAD_FIELD_ERROR +ALTER TABLE t1 CHANGE COLUMN a b INT; +DELETE FROM t1; +SET sql_mode=''; +FLUSH TABLES; +INSERT INTO t1 SET c='0'; +DROP TABLE t1; diff --git a/mysql-test/suite/engines/funcs/r/rpl_row_until.result b/mysql-test/suite/engines/funcs/r/rpl_row_until.result index 82268ce72eb..d5085a4feaf 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_row_until.result +++ b/mysql-test/suite/engines/funcs/r/rpl_row_until.result @@ -51,7 +51,9 @@ ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UN START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', MASTER_LOG_POS=MASTER_LOG_POS; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=MASTER_LOG_POS; -include/stop_slave.inc +include/wait_for_slave_io_to_start.inc +include/wait_for_slave_sql_to_stop.inc +include/stop_slave_io.inc RESET SLAVE; include/start_slave.inc include/rpl_reset.inc diff --git a/mysql-test/suite/engines/funcs/r/rpl_server_id1.result b/mysql-test/suite/engines/funcs/r/rpl_server_id1.result index 33d1abb39c6..b4d0855a264 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_server_id1.result +++ b/mysql-test/suite/engines/funcs/r/rpl_server_id1.result @@ -15,7 +15,7 @@ insert into t1 values (1); include/wait_for_slave_param.inc [Last_IO_Errno] Last_IO_Errno = '1593' Last_IO_Error = 'Fatal error: The slave I/O thread stops because master and slave have equal MariaDB server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).' -include/stop_slave.inc +include/stop_slave_sql.inc reset slave; reset master; drop table t1; diff --git a/mysql-test/suite/engines/funcs/r/rpl_slave_status.result b/mysql-test/suite/engines/funcs/r/rpl_slave_status.result index 1c81cec2577..ef122b9ca92 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_slave_status.result +++ b/mysql-test/suite/engines/funcs/r/rpl_slave_status.result @@ -36,7 +36,6 @@ connection slave; include/stop_slave.inc START SLAVE; include/wait_for_slave_sql_to_start.inc -include/wait_for_slave_io_to_stop.inc ==== Verify that Slave IO thread stopped with error ==== include/wait_for_slave_io_error.inc [errno=1045] ==== Cleanup (Note that slave IO thread is not running) ==== diff --git a/mysql-test/suite/engines/funcs/t/rpl_server_id1.test b/mysql-test/suite/engines/funcs/t/rpl_server_id1.test index 1412db46d3a..8f0248ebbde 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_server_id1.test +++ b/mysql-test/suite/engines/funcs/t/rpl_server_id1.test @@ -25,7 +25,7 @@ insert into t1 values (1); --let $status_items= Last_IO_Errno, Last_IO_Error --source include/show_slave_status.inc ---source include/stop_slave.inc +--source include/stop_slave_sql.inc reset slave; reset master; drop table t1; diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index 2f22f0b6f70..dbb620ed1df 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -175,9 +175,9 @@ def information_schema GEOMETRY_COLUMNS MAX_PPR 12 NULL NO tinyint NULL NULL 3 0 def information_schema GEOMETRY_COLUMNS SRID 13 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) select NEVER NULL def information_schema GEOMETRY_COLUMNS STORAGE_TYPE 9 NULL NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) select NEVER NULL def information_schema GLOBAL_STATUS VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL -def information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL NO varchar 2048 6144 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(2048) select NEVER NULL +def information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) select NEVER NULL def information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL -def information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 2048 6144 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(2048) select NEVER NULL +def information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) select NEVER NULL def information_schema INDEX_STATISTICS INDEX_NAME 3 NULL NO varchar 192 576 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(192) select NEVER NULL def information_schema INDEX_STATISTICS ROWS_READ 4 NULL NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select NEVER NULL def information_schema INDEX_STATISTICS TABLE_NAME 2 NULL NO varchar 192 576 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(192) select NEVER NULL @@ -337,9 +337,9 @@ def information_schema SCHEMA_PRIVILEGES PRIVILEGE_TYPE 4 NULL NO varchar 64 192 def information_schema SCHEMA_PRIVILEGES TABLE_CATALOG 2 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL def information_schema SCHEMA_PRIVILEGES TABLE_SCHEMA 3 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL def information_schema SESSION_STATUS VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL -def information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL NO varchar 2048 6144 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(2048) select NEVER NULL +def information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) select NEVER NULL def information_schema SESSION_VARIABLES VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL -def information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 2048 6144 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(2048) select NEVER NULL +def information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) select NEVER NULL def information_schema SPATIAL_REF_SYS AUTH_NAME 2 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL def information_schema SPATIAL_REF_SYS AUTH_SRID 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(5) select NEVER NULL def information_schema SPATIAL_REF_SYS SRID 1 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) select NEVER NULL @@ -723,9 +723,9 @@ NULL information_schema GEOMETRY_COLUMNS COORD_DIMENSION tinyint NULL NULL NULL NULL information_schema GEOMETRY_COLUMNS MAX_PPR tinyint NULL NULL NULL NULL tinyint(2) NULL information_schema GEOMETRY_COLUMNS SRID smallint NULL NULL NULL NULL smallint(5) 3.0000 information_schema GLOBAL_STATUS VARIABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema GLOBAL_STATUS VARIABLE_VALUE varchar 2048 6144 utf8mb3 utf8mb3_general_ci varchar(2048) +3.0000 information_schema GLOBAL_STATUS VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) 3.0000 information_schema GLOBAL_VARIABLES VARIABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema GLOBAL_VARIABLES VARIABLE_VALUE varchar 2048 6144 utf8mb3 utf8mb3_general_ci varchar(2048) +3.0000 information_schema GLOBAL_VARIABLES VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) 3.0000 information_schema INDEX_STATISTICS TABLE_SCHEMA varchar 192 576 utf8mb3 utf8mb3_general_ci varchar(192) 3.0000 information_schema INDEX_STATISTICS TABLE_NAME varchar 192 576 utf8mb3 utf8mb3_general_ci varchar(192) 3.0000 information_schema INDEX_STATISTICS INDEX_NAME varchar 192 576 utf8mb3 utf8mb3_general_ci varchar(192) @@ -885,9 +885,9 @@ NULL information_schema ROUTINES LAST_ALTERED datetime NULL NULL NULL NULL datet 3.0000 information_schema SCHEMA_PRIVILEGES PRIVILEGE_TYPE varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) 3.0000 information_schema SCHEMA_PRIVILEGES IS_GRANTABLE varchar 3 9 utf8mb3 utf8mb3_general_ci varchar(3) 3.0000 information_schema SESSION_STATUS VARIABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema SESSION_STATUS VARIABLE_VALUE varchar 2048 6144 utf8mb3 utf8mb3_general_ci varchar(2048) +3.0000 information_schema SESSION_STATUS VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) 3.0000 information_schema SESSION_VARIABLES VARIABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema SESSION_VARIABLES VARIABLE_VALUE varchar 2048 6144 utf8mb3 utf8mb3_general_ci varchar(2048) +3.0000 information_schema SESSION_VARIABLES VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) NULL information_schema SPATIAL_REF_SYS SRID smallint NULL NULL NULL NULL smallint(5) 3.0000 information_schema SPATIAL_REF_SYS AUTH_NAME varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) NULL information_schema SPATIAL_REF_SYS AUTH_SRID int NULL NULL NULL NULL int(5) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result index 14ad9fa6331..1f22c67a597 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result @@ -175,9 +175,9 @@ def information_schema GEOMETRY_COLUMNS MAX_PPR 12 NULL NO tinyint NULL NULL 3 0 def information_schema GEOMETRY_COLUMNS SRID 13 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) NEVER NULL def information_schema GEOMETRY_COLUMNS STORAGE_TYPE 9 NULL NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) NEVER NULL def information_schema GLOBAL_STATUS VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL -def information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL NO varchar 2048 6144 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(2048) NEVER NULL +def information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) NEVER NULL def information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL -def information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 2048 6144 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(2048) NEVER NULL +def information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) NEVER NULL def information_schema INDEX_STATISTICS INDEX_NAME 3 NULL NO varchar 192 576 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(192) NEVER NULL def information_schema INDEX_STATISTICS ROWS_READ 4 NULL NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) NEVER NULL def information_schema INDEX_STATISTICS TABLE_NAME 2 NULL NO varchar 192 576 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(192) NEVER NULL @@ -337,9 +337,9 @@ def information_schema SCHEMA_PRIVILEGES PRIVILEGE_TYPE 4 NULL NO varchar 64 192 def information_schema SCHEMA_PRIVILEGES TABLE_CATALOG 2 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) NEVER NULL def information_schema SCHEMA_PRIVILEGES TABLE_SCHEMA 3 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL def information_schema SESSION_STATUS VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL -def information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL NO varchar 2048 6144 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(2048) NEVER NULL +def information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) NEVER NULL def information_schema SESSION_VARIABLES VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL -def information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 2048 6144 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(2048) NEVER NULL +def information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) NEVER NULL def information_schema SPATIAL_REF_SYS AUTH_NAME 2 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) NEVER NULL def information_schema SPATIAL_REF_SYS AUTH_SRID 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(5) NEVER NULL def information_schema SPATIAL_REF_SYS SRID 1 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) NEVER NULL @@ -723,9 +723,9 @@ NULL information_schema GEOMETRY_COLUMNS COORD_DIMENSION tinyint NULL NULL NULL NULL information_schema GEOMETRY_COLUMNS MAX_PPR tinyint NULL NULL NULL NULL tinyint(2) NULL information_schema GEOMETRY_COLUMNS SRID smallint NULL NULL NULL NULL smallint(5) 3.0000 information_schema GLOBAL_STATUS VARIABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema GLOBAL_STATUS VARIABLE_VALUE varchar 2048 6144 utf8mb3 utf8mb3_general_ci varchar(2048) +3.0000 information_schema GLOBAL_STATUS VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) 3.0000 information_schema GLOBAL_VARIABLES VARIABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema GLOBAL_VARIABLES VARIABLE_VALUE varchar 2048 6144 utf8mb3 utf8mb3_general_ci varchar(2048) +3.0000 information_schema GLOBAL_VARIABLES VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) 3.0000 information_schema INDEX_STATISTICS TABLE_SCHEMA varchar 192 576 utf8mb3 utf8mb3_general_ci varchar(192) 3.0000 information_schema INDEX_STATISTICS TABLE_NAME varchar 192 576 utf8mb3 utf8mb3_general_ci varchar(192) 3.0000 information_schema INDEX_STATISTICS INDEX_NAME varchar 192 576 utf8mb3 utf8mb3_general_ci varchar(192) @@ -885,9 +885,9 @@ NULL information_schema ROUTINES LAST_ALTERED datetime NULL NULL NULL NULL datet 3.0000 information_schema SCHEMA_PRIVILEGES PRIVILEGE_TYPE varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) 3.0000 information_schema SCHEMA_PRIVILEGES IS_GRANTABLE varchar 3 9 utf8mb3 utf8mb3_general_ci varchar(3) 3.0000 information_schema SESSION_STATUS VARIABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema SESSION_STATUS VARIABLE_VALUE varchar 2048 6144 utf8mb3 utf8mb3_general_ci varchar(2048) +3.0000 information_schema SESSION_STATUS VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) 3.0000 information_schema SESSION_VARIABLES VARIABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema SESSION_VARIABLES VARIABLE_VALUE varchar 2048 6144 utf8mb3 utf8mb3_general_ci varchar(2048) +3.0000 information_schema SESSION_VARIABLES VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) NULL information_schema SPATIAL_REF_SYS SRID smallint NULL NULL NULL NULL smallint(5) 3.0000 information_schema SPATIAL_REF_SYS AUTH_NAME varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) NULL information_schema SPATIAL_REF_SYS AUTH_SRID int NULL NULL NULL NULL int(5) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 6f5143e1655..8b8170a8ebd 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -23,6 +23,8 @@ versioning_trx_id : MDEV-18590 : galera.versioning_trx_id: Test failure: mysqlte galera_concurrent_ctas : MDEV-32779 galera_concurrent_ctas: assertion in the galera::ReplicatorSMM::finish_cert() galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() -galera_bf_lock_wait : MDEV-32781 galera_bf_lock_wait test failed galera_sst_mysqldump_with_key : MDEV-32782 galera_sst_mysqldump_with_key test failed mdev-31285 : MDEV-25089 Assertion `error.len > 0' failed in galera::ReplicatorSMM::handle_apply_error() +galera_var_ignore_apply_errors : MENT-1997 galera_var_ignore_apply_errors test freezes +MW-402 : temporarily disabled at the request of Codership +MDEV-22232 : temporarily disabled at the request of Codership diff --git a/mysql-test/suite/galera/r/MDEV-22232.result b/mysql-test/suite/galera/r/MDEV-22232.result new file mode 100644 index 00000000000..a6a619458f0 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-22232.result @@ -0,0 +1,27 @@ +connection node_2; +connection node_1; +connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1; +--- CTAS with empty result set --- +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_alter WAIT_FOR bf_abort'; +CREATE TABLE t2 SELECT * FROM t1; +connection node_1; +SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; +ALTER TABLE t1 DROP FOREIGN KEY b, ALGORITHM=COPY; +connection con1; +ERROR 70100: Query execution was interrupted +SET DEBUG_SYNC = 'RESET'; +--- CTAS with non-empty result set --- +INSERT INTO t1 VALUES (10), (20), (30); +SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_alter WAIT_FOR bf_abort'; +CREATE TABLE t2 SELECT * FROM t1; +connection node_1; +SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; +ALTER TABLE t1 DROP FOREIGN KEY b, ALGORITHM=COPY; +connection con1; +ERROR 70100: Query execution was interrupted +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1; +disconnect con1; +disconnect node_2; +disconnect node_1; diff --git a/mysql-test/suite/galera/r/MDEV-32938.result b/mysql-test/suite/galera/r/MDEV-32938.result new file mode 100644 index 00000000000..5e310eb7843 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-32938.result @@ -0,0 +1,21 @@ +connection node_2; +connection node_1; +connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1; +call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); +CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT) ENGINE=InnoDB; +SET DEBUG_SYNC = 'wsrep_append_fk_toi_keys_before_close_tables SIGNAL may_alter WAIT_FOR bf_abort'; +ALTER TABLE t1 DROP COLUMN c2; +connection node_1; +SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; +ALTER TABLE t1 ADD COLUMN c3 INT; +connection con1; +ERROR 70100: Query execution was interrupted +INSERT INTO t1 (c1, c2, c3) VALUES (1, 0, 0); +connection node_2; +INSERT INTO t1 (c1, c2, c3) VALUES (2, 0, 0); +connection node_1; +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1; +disconnect con1; +disconnect node_2; +disconnect node_1; diff --git a/mysql-test/suite/galera/r/galera_bf_lock_wait.result b/mysql-test/suite/galera/r/galera_bf_lock_wait.result index 757fbf50cad..9e5cb2d9266 100644 --- a/mysql-test/suite/galera/r/galera_bf_lock_wait.result +++ b/mysql-test/suite/galera/r/galera_bf_lock_wait.result @@ -33,6 +33,26 @@ SET SESSION wsrep_sync_wait=0; call p1(1000); connection node_1; checking error log for 'BF lock wait long' message for 10 times every 10 seconds ... +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] +include/assert_grep.inc [BF lock wait long] connection node_1_p1; connection node_1_p2; connection node_2_p1; diff --git a/mysql-test/suite/galera/r/galera_ist_mariabackup_verify_ca.result b/mysql-test/suite/galera/r/galera_ist_mariabackup_verify_ca.result new file mode 100644 index 00000000000..955d5af7827 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_ist_mariabackup_verify_ca.result @@ -0,0 +1,21 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +CREATE TABLE t1 (f1 INT PRIMARY KEY); +connection node_2; +# Verify that graceful shutdown succeeds... +connection node_1; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +connection node_2; +# Start node_2 again... +SELECT * FROM t1; +f1 +1 +2 +3 +connection node_1; +include/assert_grep.inc [mariabackup IST completed on joiner] +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_ist_rsync_verify_ca.result b/mysql-test/suite/galera/r/galera_ist_rsync_verify_ca.result new file mode 100644 index 00000000000..51dfa7bcd18 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_ist_rsync_verify_ca.result @@ -0,0 +1,21 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +CREATE TABLE t1 (f1 INT PRIMARY KEY); +connection node_2; +# Verify that graceful shutdown succeeds... +connection node_1; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +connection node_2; +# Start node_2 again... +SELECT * FROM t1; +f1 +1 +2 +3 +connection node_1; +include/assert_grep.inc [rsync IST completed on joiner] +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MDEV-22232.test b/mysql-test/suite/galera/t/MDEV-22232.test new file mode 100644 index 00000000000..edb42ee603c --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-22232.test @@ -0,0 +1,72 @@ +# +# MDEV-22232: CTAS execution crashes during replay. +# +# There were multiple problems and two failing scenarios with empty result set +# and with non-empty result set: +# - CTAS didn't add shared keys for selected tables +# - Security context wasn't set on the replayer thread +# - CTAS was retried after failure - now retry disabled + +--source include/galera_cluster.inc +--source include/have_debug_sync.inc +--source include/have_debug.inc + +--connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1 + +# Scenario 1 +--echo --- CTAS with empty result set --- +CREATE TABLE t1 (a INT) ENGINE=InnoDB; + +# Run CTAS until the resulting table gets created, +# then it gets BF aborted by ALTER. +SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_alter WAIT_FOR bf_abort'; +--send + CREATE TABLE t2 SELECT * FROM t1; + +# Wait for CTAS to reach the table create point, +# start executing ALTER and BF abort CTAS. +--connection node_1 +SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; +--disable_result_log +--error ER_ERROR_ON_RENAME +ALTER TABLE t1 DROP FOREIGN KEY b, ALGORITHM=COPY; +--enable_result_log + +--connection con1 +# CTAS gets BF aborted. +--error ER_QUERY_INTERRUPTED +--reap + +# Cleanup +SET DEBUG_SYNC = 'RESET'; + + +# Scenario 2 +--echo --- CTAS with non-empty result set --- +INSERT INTO t1 VALUES (10), (20), (30); + +# Run CTAS until the resulting table gets created, +# then it gets BF aborted by ALTER. +SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_alter WAIT_FOR bf_abort'; +--send + CREATE TABLE t2 SELECT * FROM t1; + +# Wait for CTAS to reach the table create point, +# start executing ALTER and BF abort CTAS. +--connection node_1 +SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; +--disable_result_log +--error ER_ERROR_ON_RENAME +ALTER TABLE t1 DROP FOREIGN KEY b, ALGORITHM=COPY; +--enable_result_log + +--connection con1 +# CTAS gets BF aborted. +--error ER_QUERY_INTERRUPTED +--reap + +# Cleanup +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1; +--disconnect con1 +--source include/galera_end.inc diff --git a/mysql-test/suite/galera/t/MDEV-32938.test b/mysql-test/suite/galera/t/MDEV-32938.test new file mode 100644 index 00000000000..cb41f21a58a --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-32938.test @@ -0,0 +1,57 @@ +# +# MDEV-32938: ALTER command is replicated and successfully applied while being BF-aborted locally. +# +# Why it happend: +# - ALTER went to prepare FK-referenced tables as TOI keys +# - to do this, it would open the main table with SHARED_HIGH_PRIO MDL lock which disregarded any +# other locks (including X-lock) waiting in the queue in case someone was already holding a +# compatible lock type (like any DML operation) +# - if there was other TOI operation on the same table, it would go through BF-abort cycle to grab +# the lock for itself +# - since the initial ALTER had not reached TOI yet, it would loose to real TOI operation and got +# BF-aborted with its THD marked as killed +# - then, ALTER would enter TOI and get replicated with no checks that it has already been aborted +# - after entering TOI mode, it would later find it'd been killed, and complete with an error +# - at the same time, the command would successfully apply on every other node except the initiator. +# +# Fixed by checking killed state on THD before entering TOI. +# + +--source include/galera_cluster.inc +--source include/have_debug_sync.inc +--source include/have_debug.inc + +--connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1 + +call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); + +CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT) ENGINE=InnoDB; + +# Run ALTER DROP COLUMN and hang before closing tables on adding FK keys and before entering TOI. +# Wait until it gets BF-aborted. +SET DEBUG_SYNC = 'wsrep_append_fk_toi_keys_before_close_tables SIGNAL may_alter WAIT_FOR bf_abort'; +--send + ALTER TABLE t1 DROP COLUMN c2; + +--connection node_1 +# Run ALTER ADD COLUMN and BF-abort the previous ALTER DROP COLUMN. +SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; +ALTER TABLE t1 ADD COLUMN c3 INT; + +--connection con1 +# ALTER DROP COLUMN gets BF aborted. +--error ER_QUERY_INTERRUPTED +--reap + +INSERT INTO t1 (c1, c2, c3) VALUES (1, 0, 0); + +--connection node_2 +# ALTER DROP COLUMN must not be replicated. +INSERT INTO t1 (c1, c2, c3) VALUES (2, 0, 0); + +# Cleanup. +--connection node_1 +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1; +--disconnect con1 +--source include/galera_end.inc diff --git a/mysql-test/suite/galera/t/galera_bf_lock_wait.test b/mysql-test/suite/galera/t/galera_bf_lock_wait.test index 0562b4361ff..8ef2fee78ed 100644 --- a/mysql-test/suite/galera/t/galera_bf_lock_wait.test +++ b/mysql-test/suite/galera/t/galera_bf_lock_wait.test @@ -52,6 +52,12 @@ let $counter=10; let $sleep_period=10; echo checking error log for 'BF lock wait long' message for $counter times every $sleep_period seconds ...; + +--let assert_text= BF lock wait long +--let assert_select= BF lock wait long +--let assert_count= 0 +--let assert_only_after= CURRENT_TEST: galera.galera_bf_lock_wait + while($counter > 0) { --disable_query_log @@ -60,9 +66,11 @@ while($counter > 0) --enable_query_log --enable_result_log -# use error 0,1 instead if want test to continue - --error 1 - exec grep 'BF lock wait long' $MYSQLTEST_VARDIR/log/mysqld.*.err; +--let assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--source include/assert_grep.inc + +--let assert_file= $MYSQLTEST_VARDIR/log/mysqld.2.err +--source include/assert_grep.inc dec $counter; } diff --git a/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.cnf b/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.cnf new file mode 100644 index 00000000000..f2187b83486 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.cnf @@ -0,0 +1,20 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=mariabackup +wsrep_sst_auth=root: + +ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem +ssl-key=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem +ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true' + +[sst] +ssl-mode=VERIFY_CA +transferfmt=@ENV.MTR_GALERA_TFMT +streamfmt=mbstream diff --git a/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.test b/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.test new file mode 100644 index 00000000000..4e2d25b1770 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.test @@ -0,0 +1,61 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_mariabackup.inc + +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--let $LOG_FILE=$MYSQL_TMP_DIR/galera_node2.log +--error 0,1 +--remove_file $LOG_FILE + +CREATE TABLE t1 (f1 INT PRIMARY KEY); + +--connection node_2 + +--echo # Verify that graceful shutdown succeeds... +--source include/shutdown_mysqld.inc + +--connection node_1 + +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); + +--connection node_2 +--echo # Start node_2 again... +--let $restart_noprint=2 +--let $start_mysqld_params=--log-error=$LOG_FILE +--source include/start_mysqld.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +SELECT * FROM t1; + +--let $start_mysqld_params= +--source include/restart_mysqld.inc + +--connection node_1 + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +# Confirm that IST took place +--let $assert_text = mariabackup IST completed on joiner +--let $assert_select = mariabackup IST completed on joiner +--let $assert_count = 1 +--let $assert_file = $LOG_FILE +--let $assert_only_after = Prepared IST receiver for +--source include/assert_grep.inc + +DROP TABLE t1; + +--source include/auto_increment_offset_restore.inc + +--remove_file $LOG_FILE diff --git a/mysql-test/suite/galera/t/galera_ist_rsync_verify_ca.cnf b/mysql-test/suite/galera/t/galera_ist_rsync_verify_ca.cnf new file mode 100644 index 00000000000..9125f6708fe --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ist_rsync_verify_ca.cnf @@ -0,0 +1,17 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=rsync + +ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem +ssl-key=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem +ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true' + +[sst] +ssl-mode=VERIFY_CA diff --git a/mysql-test/suite/galera/t/galera_ist_rsync_verify_ca.test b/mysql-test/suite/galera/t/galera_ist_rsync_verify_ca.test new file mode 100644 index 00000000000..d9f7bb152fc --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ist_rsync_verify_ca.test @@ -0,0 +1,60 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--let $LOG_FILE=$MYSQL_TMP_DIR/galera_node2.log +--error 0,1 +--remove_file $LOG_FILE + +CREATE TABLE t1 (f1 INT PRIMARY KEY); + +--connection node_2 + +--echo # Verify that graceful shutdown succeeds... +--source include/shutdown_mysqld.inc + +--connection node_1 + +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); + +--connection node_2 +--echo # Start node_2 again... +--let $restart_noprint=2 +--let $start_mysqld_params=--log-error=$LOG_FILE +--source include/start_mysqld.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +SELECT * FROM t1; + +--let $start_mysqld_params= +--source include/restart_mysqld.inc + +--connection node_1 + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +# Confirm that IST took place +--let $assert_text = rsync IST completed on joiner +--let $assert_select = rsync IST completed on joiner +--let $assert_count = 1 +--let $assert_file = $LOG_FILE +--let $assert_only_after = Prepared IST receiver for +--source include/assert_grep.inc + +DROP TABLE t1; + +--source include/auto_increment_offset_restore.inc + +--remove_file $LOG_FILE diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index dd457ef2808..cef0f41a05c 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -14,6 +14,9 @@ galera_2_cluster : MDEV-32631 galera_2_cluster: before_rollback(): Assertion `0' galera_gtid_2_cluster : MDEV-32633 galera_gtid_2_cluster: Assertion `thd->wsrep_next_trx_id() != (0x7fffffffffffffffLL * 2ULL + 1)' galera_vote_rejoin_mysqldump : MDEV-24481: galera_3nodes.galera_vote_rejoin_mysqldump MTR failed: mysql_shutdown failed galera_ssl_reload : MDEV-32778 galera_ssl_reload failed with warning message +galera_ipv6_mariabackup : temporarily disabled at the request of Codership +galera_pc_bootstrap : temporarily disabled at the request of Codership +galera_ipv6_mariabackup_section : temporarily disabled at the request of Codership # Opensuse/suse/rocky9/rocky84/rhel9/rhel8-ppc64le .. - all same IPv6 isn't configured right or skipping or galera galera_ipv6_rsync : Can't connect to server on '::1' (115) galera_ipv6_rsync_section : Can't connect to server on '::1' (115) diff --git a/mysql-test/suite/gcol/r/gcol_bugfixes.result b/mysql-test/suite/gcol/r/gcol_bugfixes.result index f124ebe611c..5dfa416a540 100644 --- a/mysql-test/suite/gcol/r/gcol_bugfixes.result +++ b/mysql-test/suite/gcol/r/gcol_bugfixes.result @@ -744,3 +744,41 @@ SELECT id, ts, vc INTO OUTFILE 'load_t1' FROM t1; LOAD DATA INFILE 'load_t1' REPLACE INTO TABLE t1 (id, ts, vc); INSERT IGNORE INTO t1 (id) VALUES (2); DROP TABLE t1; +# +# MDEV-28566 Assertion `!expr->is_fixed()' failed in bool +# Virtual_column_info::fix_session_expr(THD*) +# +CREATE TABLE t1 (c1 CHAR(1)); +FLUSH TABLES WITH READ LOCK; +UPDATE t1 SET c1=1; +ERROR HY000: Can't execute the query because you have a conflicting read lock +unlock tables; +SELECT * FROM t1; +c1 +DROP TABLE t1; +CREATE TABLE t1 (c1 CHAR AS (CONCAT (0,DAYNAME (0)))); +FLUSH TABLES WITH READ LOCK; +UPDATE t1 SET c1=1; +ERROR HY000: Can't execute the query because you have a conflicting read lock +unlock tables; +UPDATE t1 SET c1=1; +SELECT * FROM t1; +c1 +DROP TABLE t1; +CREATE TABLE t1 (a int primary key, c1 CHAR AS (CONCAT (0,DAYNAME (0)))); +insert into t1 (a) values (1); +FLUSH TABLES WITH READ LOCK; +UPDATE t1 SET c1=1; +ERROR HY000: Can't execute the query because you have a conflicting read lock +UPDATE t1 SET a=2; +ERROR HY000: Can't execute the query because you have a conflicting read lock +unlock tables; +UPDATE t1 SET a=2; +UPDATE t1 SET c1=1; +ERROR HY000: The value specified for generated column 'c1' in table 't1' has been ignored +SELECT * FROM t1; +a c1 +2 NULL +Warnings: +Warning 1292 Incorrect datetime value: '0' +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/innodb_prefix_index_check.result b/mysql-test/suite/gcol/r/innodb_prefix_index_check.result index 01dbe4a6592..ea84cd154ad 100644 --- a/mysql-test/suite/gcol/r/innodb_prefix_index_check.result +++ b/mysql-test/suite/gcol/r/innodb_prefix_index_check.result @@ -13,3 +13,32 @@ key(f1,f2(1)) )ENGINE=INNODB; REPLACE INTO t1(f3) VALUES (1),(1); DROP TABLE t1; +#Create and alter table examples for full column index followed by prefix index. +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1,f2), +KEY(f1(5)))ENGINE=INNODB; +REPLACE INTO t1(f2) VALUES (1),(1); +ALTER TABLE t1 ADD INDEX(f2,f1); +DROP TABLE t1; +#Create and alter table examples for small prefix index followed by large +#prefix index. +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1(5),f2), +KEY(f1(10)))ENGINE=INNODB; +REPLACE INTO t1(f2) VALUES (1),(1); +ALTER TABLE t1 ADD INDEX(f2,f1); +DROP TABLE t1; +#Create and alter table examples for prefix index followed by full column +#index. +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1(5),f2), +KEY(f1))ENGINE=INNODB; +REPLACE INTO t1(f2) VALUES (1),(1); +ALTER TABLE t1 ADD INDEX(f2,f1); +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/t/gcol_bugfixes.test b/mysql-test/suite/gcol/t/gcol_bugfixes.test index 4c1b00a878a..1edc9779d41 100644 --- a/mysql-test/suite/gcol/t/gcol_bugfixes.test +++ b/mysql-test/suite/gcol/t/gcol_bugfixes.test @@ -724,3 +724,38 @@ DROP TABLE t1; --remove_file $datadir/test/load_t1 +--echo # +--echo # MDEV-28566 Assertion `!expr->is_fixed()' failed in bool +--echo # Virtual_column_info::fix_session_expr(THD*) +--echo # + +CREATE TABLE t1 (c1 CHAR(1)); +FLUSH TABLES WITH READ LOCK; +--error ER_CANT_UPDATE_WITH_READLOCK +UPDATE t1 SET c1=1; +unlock tables; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (c1 CHAR AS (CONCAT (0,DAYNAME (0)))); +FLUSH TABLES WITH READ LOCK; +--error ER_CANT_UPDATE_WITH_READLOCK +UPDATE t1 SET c1=1; +unlock tables; +UPDATE t1 SET c1=1; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a int primary key, c1 CHAR AS (CONCAT (0,DAYNAME (0)))); +insert into t1 (a) values (1); +FLUSH TABLES WITH READ LOCK; +--error ER_CANT_UPDATE_WITH_READLOCK +UPDATE t1 SET c1=1; +--error ER_CANT_UPDATE_WITH_READLOCK +UPDATE t1 SET a=2; +unlock tables; +UPDATE t1 SET a=2; +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +UPDATE t1 SET c1=1; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/t/innodb_prefix_index_check.test b/mysql-test/suite/gcol/t/innodb_prefix_index_check.test index 4923ead91ac..5cc46e16dde 100644 --- a/mysql-test/suite/gcol/t/innodb_prefix_index_check.test +++ b/mysql-test/suite/gcol/t/innodb_prefix_index_check.test @@ -20,3 +20,46 @@ REPLACE INTO t1(f3) VALUES (1),(1); DROP TABLE t1; +--echo #Create and alter table examples for full column index followed by prefix index. + +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1,f2), +KEY(f1(5)))ENGINE=INNODB; + +REPLACE INTO t1(f2) VALUES (1),(1); + +ALTER TABLE t1 ADD INDEX(f2,f1); + +DROP TABLE t1; + +--echo #Create and alter table examples for small prefix index followed by large +--echo #prefix index. + +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1(5),f2), +KEY(f1(10)))ENGINE=INNODB; + +REPLACE INTO t1(f2) VALUES (1),(1); + +ALTER TABLE t1 ADD INDEX(f2,f1); + +DROP TABLE t1; + +--echo #Create and alter table examples for prefix index followed by full column +--echo #index. + +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1(5),f2), +KEY(f1))ENGINE=INNODB; + +REPLACE INTO t1(f2) VALUES (1),(1); + +ALTER TABLE t1 ADD INDEX(f2,f1); + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/include/crc32.pl b/mysql-test/suite/innodb/include/crc32.pl index c2bce09dd36..b26f1057e2a 100644 --- a/mysql-test/suite/innodb/include/crc32.pl +++ b/mysql-test/suite/innodb/include/crc32.pl @@ -31,3 +31,26 @@ sub mycrc32 { return $crc; } + + +# Fix the checksum of an InnoDB tablespace page. +# Inputs: +# $page A bytestring with the page data. +# $full_crc32 Checksum type, see get_full_crc32() in innodb-util.pl +# Returns: the modified page as a bytestring. +sub fix_page_crc { + my ($page, $full_crc32)= @_; + my $ps= length($page); + my $polynomial = 0x82f63b78; # CRC-32C + if ($full_crc32) { + my $ck = mycrc32(substr($page, 0, $ps - 4), 0, $polynomial); + substr($page, $ps - 4, 4) = pack("N", $ck); + } else { + my $ck= pack("N", + mycrc32(substr($page, 4, 22), 0, $polynomial) ^ + mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial)); + substr($page, 0, 4)= $ck; + substr($page, $ps-8, 4)= $ck; + } + return $page; +} diff --git a/mysql-test/suite/innodb/include/innodb-util.pl b/mysql-test/suite/innodb/include/innodb-util.pl index 241545dac18..328ce5c7f36 100644 --- a/mysql-test/suite/innodb/include/innodb-util.pl +++ b/mysql-test/suite/innodb/include/innodb-util.pl @@ -124,3 +124,22 @@ sub ib_restore_ibd_files { ib_restore_ibd_file($tmpd, $datadir, $db, $table); } } + +# Read the flag whether a tablespace is using full_crc32. +# Input: filehandle opened on the tablespace. +sub get_full_crc32 { + my ($TBLSPC)= @_; + my $old_pos= sysseek($TBLSPC, 0, 1); + die "tell() failed on tablespace filehandle: $!\n" + unless defined($old_pos); + sysseek($TBLSPC, 0, 0) + or die "sysseek() failed on tablespace filehandle: $!\n"; + my $tblspc_hdr; + sysread($TBLSPC, $tblspc_hdr, 58) + or die "Cannot read tablespace header: $!\n"; + sysseek($TBLSPC, $old_pos, 0) + or die "sysseek() failed on tablespace filehandle: $!\n"; + my $full_crc32= + unpack("N", substr($tblspc_hdr, 54, 4)) & 0x10; # FIL_SPACE_FLAGS + return $full_crc32; +} diff --git a/mysql-test/suite/innodb/r/add_foreign_key.result b/mysql-test/suite/innodb/r/add_foreign_key.result new file mode 100644 index 00000000000..75177478e60 --- /dev/null +++ b/mysql-test/suite/innodb/r/add_foreign_key.result @@ -0,0 +1,31 @@ +# +# Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE ADD +# FOREIGN KEY +# +CREATE TABLE `parent` (`parent_id` INT, PRIMARY KEY (`parent_id`)); +CREATE TABLE `child1` (`id` INT ,`child1_fk1` INT, `child1_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child2` (`id` INT, `child2_fk1` INT, `child2_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child3` (`id` INT , `child3_fk1` INT, PRIMARY KEY (`id`)); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES +`parent` (`parent_id`); +drop table child3, child2, child1, parent; diff --git a/mysql-test/suite/innodb/r/cascade_lock_wait.result b/mysql-test/suite/innodb/r/cascade_lock_wait.result new file mode 100644 index 00000000000..9cc05df739e --- /dev/null +++ b/mysql-test/suite/innodb/r/cascade_lock_wait.result @@ -0,0 +1,76 @@ +create table t1 (f1 int primary key) engine=innodb; +create table t2 (f1 int primary key, +constraint c1 foreign key (f1) references t1(f1) +on update cascade +on delete cascade) engine=innodb; +create table t3 (f1 int primary key, +constraint c2 foreign key (f1) references t1(f1) +on update cascade +on delete cascade) engine=innodb; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + PRIMARY KEY (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f1` int(11) NOT NULL, + PRIMARY KEY (`f1`), + CONSTRAINT `c1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `f1` int(11) NOT NULL, + PRIMARY KEY (`f1`), + CONSTRAINT `c2` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +insert into t1 values (1); +insert into t1 values (2); +insert into t1 values (3); +insert into t2 values (1); +insert into t2 values (2); +insert into t2 values (3); +insert into t3 values (1); +insert into t3 values (2); +insert into t3 values (3); +select f1 from t1; +f1 +1 +2 +3 +select f1 from t2; +f1 +1 +2 +3 +select f1 from t3; +f1 +1 +2 +3 +set @save_dbug = @@debug_dbug; +set debug_dbug = '+d,dml_cascade_only_once'; +set debug_dbug = '+d,row_upd_cascade_lock_wait_err'; +update t1 set f1 = 100 where f1 = 2; +select f1 from t1; +f1 +1 +3 +100 +select f1 from t2; +f1 +1 +3 +100 +select f1 from t3; +f1 +1 +3 +100 +set debug_dbug = @save_dbug; +drop table t2; +drop table t3; +drop table t1; diff --git a/mysql-test/suite/innodb/r/doublewrite.result b/mysql-test/suite/innodb/r/doublewrite.result index ba1965ed4cd..0c4f2c3fe65 100644 --- a/mysql-test/suite/innodb/r/doublewrite.result +++ b/mysql-test/suite/innodb/r/doublewrite.result @@ -1,22 +1,6 @@ # -# Bug #17335427 INNODB CAN NOT USE THE DOUBLEWRITE BUFFER PROPERLY -# Bug #18144349 INNODB CANNOT USE THE DOUBLEWRITE BUFFER FOR THE FIRST -# PAGE OF SYSTEM TABLESPACE +# MDEV-32242 innodb.doublewrite test case always is skipped # -SET GLOBAL innodb_fast_shutdown = 0; -# restart -show variables like 'innodb_doublewrite'; -Variable_name Value -innodb_doublewrite ON -show variables like 'innodb_fil_make_page_dirty_debug'; -Variable_name Value -innodb_fil_make_page_dirty_debug 0 -show variables like 'innodb_saved_page_number_debug'; -Variable_name Value -innodb_saved_page_number_debug 0 -connect stop_purge,localhost,root,,; -START TRANSACTION WITH CONSISTENT SNAPSHOT; -connection default; create table t1 (f1 int primary key, f2 blob) engine=innodb stats_persistent=0; start transaction; insert into t1 values(1, repeat('#',12)); @@ -25,27 +9,20 @@ insert into t1 values(3, repeat('/',12)); insert into t1 values(4, repeat('-',12)); insert into t1 values(5, repeat('.',12)); commit work; -# --------------------------------------------------------------- -# Test Begin: Test if recovery works if first page of user -# tablespace is full of zeroes. -select space into @space_id from information_schema.innodb_sys_tables -where name = 'test/t1'; -begin; -insert into t1 values (6, repeat('%', 12)); -# Ensure that dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; -# Make the first page dirty for table t1 -set global innodb_saved_page_number_debug = 0; -set global innodb_fil_make_page_dirty_debug = @space_id; -# Ensure that dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; -# Kill the server -disconnect stop_purge; -# Make the first page (page_no=0) of the user tablespace -# full of zeroes. -# -# MDEV-11623: Use old FSP_SPACE_FLAGS in the doublewrite buffer. +SET GLOBAL innodb_fast_shutdown = 0; # restart +connect dml,localhost,root,,; +XA START 'x'; +insert into t1 values (6, repeat('%', @@innodb_page_size/2)); +XA END 'x'; +XA PREPARE 'x'; +disconnect dml; +connection default; +flush table t1 for export; +# restart +FOUND 1 /InnoDB: Restoring page \[page id: space=[1-9][0-9]*, page number=0\] of datafile/ in mysqld.1.err +FOUND 1 /InnoDB: Recovered page \[page id: space=[1-9][0-9]*, page number=3\]/ in mysqld.1.err +XA ROLLBACK 'x'; check table t1; Table Op Msg_type Msg_text test.t1 check status OK @@ -56,211 +33,5 @@ f1 f2 3 //////////// 4 ------------ 5 ............ -# Test End -# --------------------------------------------------------------- -# Test Begin: Test if recovery works if first page of user -# tablespace is corrupted. -select space into @space_id from information_schema.innodb_sys_tables -where name = 'test/t1'; -# Ensure that dirty pages of table t1 is flushed. -flush tables t1 for export; -unlock tables; -set global innodb_log_checkpoint_now=1; -begin; -insert into t1 values (6, repeat('%', 12)); -# Make the first page dirty for table t1 -set global innodb_saved_page_number_debug = 0; -set global innodb_fil_make_page_dirty_debug = @space_id; -# Ensure that dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; -# Kill the server -# Corrupt the first page (page_no=0) of the user tablespace. -# restart -check table t1; -Table Op Msg_type Msg_text -test.t1 check status OK -select f1, f2 from t1; -f1 f2 -1 ############ -2 ++++++++++++ -3 //////////// -4 ------------ -5 ............ -# Test End -# --------------------------------------------------------------- -# Test Begin: Test if recovery works if 2nd page of user -# tablespace is full of zeroes. -select space into @space_id from information_schema.innodb_sys_tables -where name = 'test/t1'; -# Ensure that dirty pages of table t1 is flushed. -flush tables t1 for export; -unlock tables; -begin; -insert into t1 values (6, repeat('%', 400)); -# Make the 2nd page dirty for table t1 -set global innodb_saved_page_number_debug = 1; -set global innodb_fil_make_page_dirty_debug = @space_id; -# Ensure that dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; -# Kill the server -# Make the 2nd page (page_no=1) of the tablespace all zeroes. -# restart -check table t1; -Table Op Msg_type Msg_text -test.t1 check status OK -select f1, f2 from t1; -f1 f2 -1 ############ -2 ++++++++++++ -3 //////////// -4 ------------ -5 ............ -# Test End -# --------------------------------------------------------------- -# Test Begin: Test if recovery works if 2nd page of user -# tablespace is corrupted. -select space into @space_id from information_schema.innodb_sys_tables -where name = 'test/t1'; -# Ensure that dirty pages of table t1 is flushed. -flush tables t1 for export; -unlock tables; -begin; -insert into t1 values (6, repeat('%', 400)); -# Make the 2nd page dirty for table t1 -set global innodb_saved_page_number_debug = 1; -set global innodb_fil_make_page_dirty_debug = @space_id; -# Ensure that the dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; -# Kill the server -# Corrupt the 2nd page (page_no=1) of the user tablespace. -# restart -check table t1; -Table Op Msg_type Msg_text -test.t1 check status OK -select f1, f2 from t1; -f1 f2 -1 ############ -2 ++++++++++++ -3 //////////// -4 ------------ -5 ............ -# Test End -# --------------------------------------------------------------- -# Test Begin: Test if recovery works if first page of -# system tablespace is full of zeroes. -begin; -insert into t1 values (6, repeat('%', 400)); -# Ensure that all dirty pages in the system are flushed. -set global innodb_buf_flush_list_now = 1; -# Make the first page dirty for system tablespace -set global innodb_saved_page_number_debug = 0; -set global innodb_fil_make_page_dirty_debug = 0; -# Ensure that the dirty page of system tablespace is also flushed. -set global innodb_buf_flush_list_now = 1; -# Kill the server -# Make the first page (page_no=0) of the system tablespace -# all zeroes. -# restart -check table t1; -Table Op Msg_type Msg_text -test.t1 check status OK -select f1, f2 from t1; -f1 f2 -1 ############ -2 ++++++++++++ -3 //////////// -4 ------------ -5 ............ -# Test End -# --------------------------------------------------------------- -# Test Begin: Test if recovery works if first page of -# system tablespace is corrupted. -begin; -insert into t1 values (6, repeat('%', 400)); -# Ensure that all dirty pages in the system are flushed. -set global innodb_buf_flush_list_now = 1; -# Make the first page dirty for system tablespace -set global innodb_saved_page_number_debug = 0; -set global innodb_fil_make_page_dirty_debug = 0; -# Ensure that the dirty page of system tablespace is also flushed. -set global innodb_buf_flush_list_now = 1; -# Kill the server -# Corrupt the first page (page_no=0) of the system tablespace. -# restart -check table t1; -Table Op Msg_type Msg_text -test.t1 check status OK -select f1, f2 from t1; -f1 f2 -1 ############ -2 ++++++++++++ -3 //////////// -4 ------------ -5 ............ -# Test End -# --------------------------------------------------------------- -# Test Begin: Test if recovery works if 2nd page of -# system tablespace is full of zeroes. -begin; -insert into t1 values (6, repeat('%', 400)); -# Ensure that all dirty pages in the system are flushed. -set global innodb_buf_flush_list_now = 1; -# Make the second page dirty for system tablespace -set global innodb_saved_page_number_debug = 1; -set global innodb_fil_make_page_dirty_debug = 0; -# Ensure that the dirty page of system tablespace is also flushed. -set global innodb_buf_flush_list_now = 1; -# Kill the server -# Make the 2nd page (page_no=1) of the system tablespace -# all zeroes. -# restart -check table t1; -Table Op Msg_type Msg_text -test.t1 check status OK -select f1, f2 from t1; -f1 f2 -1 ############ -2 ++++++++++++ -3 //////////// -4 ------------ -5 ............ -# Test End -# --------------------------------------------------------------- -# Test Begin: Test if recovery works if 2nd page of -# system tablespace is corrupted. -begin; -insert into t1 values (6, repeat('%', 400)); -# Ensure that all dirty pages in the system are flushed. -set global innodb_buf_flush_list_now = 1; -# Make the second page dirty for system tablespace -set global innodb_saved_page_number_debug = 1; -set global innodb_fil_make_page_dirty_debug = 0; -# Ensure that the dirty page of system tablespace is also flushed. -set global innodb_buf_flush_list_now = 1; -# Kill the server -# Make the 2nd page (page_no=1) of the system tablespace -# all zeroes. -# restart -check table t1; -Table Op Msg_type Msg_text -test.t1 check status OK -FOUND 1 /InnoDB: .*test.t1\.ibd/ in mysqld.1.err -select f1, f2 from t1; -f1 f2 -1 ############ -2 ++++++++++++ -3 //////////// -4 ------------ -5 ............ drop table t1; -# -# MDEV-12600 crash during install_db with innodb_page_size=32K -# and ibdata1=3M -# -# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend -SELECT * FROM INFORMATION_SCHEMA.ENGINES -WHERE engine = 'innodb' -AND support IN ('YES', 'DEFAULT', 'ENABLED'); -ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS -FOUND 1 /\[ERROR\] InnoDB: Cannot create doublewrite buffer/ in mysqld.1.err -# restart +# End of 10.5 tests diff --git a/mysql-test/suite/innodb/r/doublewrite_debug.result b/mysql-test/suite/innodb/r/doublewrite_debug.result new file mode 100644 index 00000000000..960610a7091 --- /dev/null +++ b/mysql-test/suite/innodb/r/doublewrite_debug.result @@ -0,0 +1,92 @@ +# +# Bug #17335427 INNODB CAN NOT USE THE DOUBLEWRITE BUFFER PROPERLY +# Bug #18144349 INNODB CANNOT USE THE DOUBLEWRITE BUFFER FOR THE FIRST +# PAGE OF SYSTEM TABLESPACE +# +show variables like 'innodb_doublewrite'; +Variable_name Value +innodb_doublewrite ON +show variables like 'innodb_fil_make_page_dirty_debug'; +Variable_name Value +innodb_fil_make_page_dirty_debug 0 +show variables like 'innodb_saved_page_number_debug'; +Variable_name Value +innodb_saved_page_number_debug 0 +create table t1 (f1 int primary key, f2 blob) engine=innodb; +start transaction; +insert into t1 values(1, repeat('#',12)); +insert into t1 values(2, repeat('+',12)); +insert into t1 values(3, repeat('/',12)); +insert into t1 values(4, repeat('-',12)); +insert into t1 values(5, repeat('.',12)); +commit work; +# Test Begin: Test if recovery works if 1st page and 2nd page +# of system tablespace is full of zeroes. +SET GLOBAL innodb_fast_shutdown = 0; +# restart +begin; +insert into t1 values (6, repeat('%', 400)); +# Make the first page dirty for system tablespace +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 0; +# Make the second page dirty for system tablespace +set global innodb_saved_page_number_debug = 1; +set global innodb_fil_make_page_dirty_debug = 0; +set global innodb_buf_flush_list_now = 1; +# Make the 1st page (page_no=0) and 2nd page (page_no=1) +# of the system tablespace all zeroes. +# restart +FOUND 1 /InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile/ in mysqld.1.err +FOUND 1 /InnoDB: Recovered page \[page id: space=0, page number=1\]/ in mysqld.1.err +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +select f1, f2 from t1; +f1 f2 +1 ############ +2 ++++++++++++ +3 //////////// +4 ------------ +5 ............ +# Test End +# --------------------------------------------------------------- +# Test Begin: Test if recovery works if 1st page of +# system tablespace is corrupted and 2nd page as corrupted. +set global innodb_log_checkpoint_now = 1; +begin; +insert into t1 values (6, repeat('%', 400)); +# Make the first page dirty for system tablespace +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 0; +# Make the second page dirty for system tablespace +set global innodb_saved_page_number_debug = 1; +set global innodb_fil_make_page_dirty_debug = 0; +set global innodb_buf_flush_list_now = 1; +# Corrupt the 1st page (page_no=0) and 2nd page of the system tablespace. +# restart +FOUND 2 /InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile/ in mysqld.1.err +FOUND 2 /InnoDB: Recovered page \[page id: space=0, page number=1\]/ in mysqld.1.err +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +select f1, f2 from t1; +f1 f2 +1 ############ +2 ++++++++++++ +3 //////////// +4 ------------ +5 ............ +drop table t1; +# Test End +# --------------------------------------------------------------- +# +# MDEV-12600 crash during install_db with innodb_page_size=32K +# and ibdata1=3M +# +# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend +SELECT * FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /\[ERROR\] InnoDB: Cannot create doublewrite buffer/ in mysqld.1.err +# restart diff --git a/mysql-test/suite/innodb/r/fk_col_alter.result b/mysql-test/suite/innodb/r/fk_col_alter.result index 403bef6a67a..c6fdc3231e0 100644 --- a/mysql-test/suite/innodb/r/fk_col_alter.result +++ b/mysql-test/suite/innodb/r/fk_col_alter.result @@ -115,4 +115,17 @@ ALTER TABLE t2 DROP INDEX idx; ALTER TABLE t2 MODIFY f2 VARCHAR(1023); SET SESSION FOREIGN_KEY_CHECKS = ON; DROP TABLE t2, t1; +# +# MDEV-32638 MariaDB crashes with foreign_key_checks=0 +# when changing a column and adding a foreign +# key at the same time +# +CREATE TABLE t1(f1 VARCHAR(2) NOT NULL, PRIMARY KEY(f1))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY, +f2 VARCHAR(10) NOT NULL DEFAULT '')ENGINE=InnoDB; +SET SESSION FOREIGN_KEY_CHECKS = OFF; +ALTER TABLE t2 CHANGE COLUMN f2 f3 VARCHAR(20) NOT NULL, +ADD CONSTRAINT t2_fk FOREIGN KEY(f3) REFERENCES t1(f1); +DROP TABLE t2, t1; +SET SESSION FOREIGN_KEY_CHECKS = ON; # End of 10.4 tests diff --git a/mysql-test/suite/innodb/r/fk_drop_alter.result b/mysql-test/suite/innodb/r/fk_drop_alter.result new file mode 100644 index 00000000000..414f44f2c48 --- /dev/null +++ b/mysql-test/suite/innodb/r/fk_drop_alter.result @@ -0,0 +1,44 @@ +# +# MDEV-22230 : Unexpected ER_ERROR_ON_RENAME upon DROP +# non-existing FOREIGN KEY +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=COPY; +ERROR 42000: Can't DROP FOREIGN KEY `x`; check that it exists +ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=INPLACE; +ERROR 42000: Can't DROP FOREIGN KEY `x`; check that it exists +DROP TABLE t1; +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, FOREIGN KEY fk_id (a) REFERENCES t1(a))ENGINE=InnoDB; +CREATE TABLE t3 (a INT, FOREIGN KEY fk_1 (a) REFERENCES t1(a))ENGINE=InnoDB; +ALTER TABLE t3 DROP FOREIGN KEY IF EXISTS fk_id; +Warnings: +Note 1091 Can't DROP FOREIGN KEY `fk_id`; check that it exists +DROP TABLE t3, t2; +ALTER TABLE t1 MODIFY COLUMN a VARCHAR(2), DROP FOREIGN KEY IF EXISTS x; +Warnings: +Note 1091 Can't DROP FOREIGN KEY `x`; check that it exists +DROP TABLE t1; +CREATE DATABASE best; +CREATE TABLE best.t1(f1 INT, KEY(f1))ENGINE=InnoDB; +CREATE TABLE best.t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB; +CREATE TABLE t1(f1 INT, KEY(f1))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB; +ALTER TABLE t2 DROP FOREIGN KEY foo; +ALTER TABLE t2 DROP FOREIGN KEY foo; +ERROR 42000: Can't DROP FOREIGN KEY `foo`; check that it exists +ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS foo; +Warnings: +Note 1091 Can't DROP FOREIGN KEY `foo`; check that it exists +SHOW CREATE TABLE best.t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f1` int(11) DEFAULT NULL, + KEY `foo` (`f1`), + CONSTRAINT `foo` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; +ID FOR_NAME REF_NAME N_COLS TYPE +best/foo best/t2 best/t1 1 0 +DROP TABLE best.t2, best.t1, t2, t1; +DROP DATABASE best; diff --git a/mysql-test/suite/innodb/r/foreign-keys.result b/mysql-test/suite/innodb/r/foreign-keys.result index 503825dbeee..f7f87bd7898 100644 --- a/mysql-test/suite/innodb/r/foreign-keys.result +++ b/mysql-test/suite/innodb/r/foreign-keys.result @@ -236,3 +236,10 @@ INSERT INTO t2 VALUES('G', 3); ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`)) DROP TABLE t2, t1; SET FOREIGN_KEY_CHECKS=DEFAULT; +CREATE TABLE t1(a SERIAL) ENGINE=InnoDB ROW_FORMAT=COMPRESSED PAGE_COMPRESSED=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +SHOW WARNINGS; +Level Code Message +Warning 140 InnoDB: PAGE_COMPRESSED table can't have ROW_TYPE=COMPRESSED +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") +Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index adf528af6f3..808e2270e27 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -725,7 +725,9 @@ pk a b 13 0 1 14 0 1 15 1 0 -disconnect con1; +connection con1; +COMMIT; +connection default; InnoDB 0 transactions not purged CHECK TABLE t1; Table Op Msg_type Msg_text @@ -903,8 +905,29 @@ CONSTRAINT FK_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ALTER TABLE t1 MODIFY id INT unsigned AUTO_INCREMENT; DROP TABLE t1,t2; # -# End of 10.4 tests +# MDEV-31441 BLOB corruption on UPDATE of PRIMARY KEY with FOREIGN KEY # +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT) ENGINE=InnoDB; +CREATE TABLE t2 (pk INT PRIMARY KEY, FOREIGN KEY (pk) REFERENCES t1(pk)) +ENGINE=InnoDB; +SET @blob = REPEAT('A', @@innodb_page_size / 2); +INSERT INTO t1 SET pk=1, t=@blob; +INSERT INTO t2 SET pk=1; +connection con1; +BEGIN; +DELETE FROM t2; +connection default; +UPDATE t1 SET pk=12; +connection con1; +COMMIT; +disconnect con1; +connection default; +UPDATE t1 SET pk=1; +SELECT pk,t=@blob FROM t1; +pk t=@blob +1 1 +DROP TABLE t2, t1; +# End of 10.4 tests # # MDEV-20729 Fix REFERENCES constraint in column definition # diff --git a/mysql-test/suite/innodb/r/import_update_stats.result b/mysql-test/suite/innodb/r/import_update_stats.result new file mode 100644 index 00000000000..ddf78f180f7 --- /dev/null +++ b/mysql-test/suite/innodb/r/import_update_stats.result @@ -0,0 +1,72 @@ +SET @old_innodb_file_per_table = @@innodb_file_per_table; +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; +@@innodb_file_per_table +1 +CREATE TABLE t1 ( +col_1 CHAR (255), +col_2 VARCHAR (255) +) ENGINE = InnoDB; +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); +SHOW INDEXES 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 1 idx1 1 col_1 A 0 NULL NULL YES BTREE NO +t1 1 idx2 1 col_2 A 0 NULL NULL YES BTREE NO +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"), ("col1_00002", "col2_00002"); +SHOW INDEXES 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 1 idx1 1 col_1 A 2 NULL NULL YES BTREE NO +t1 1 idx2 1 col_2 A 2 NULL NULL YES BTREE NO +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SHOW INDEXES 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 1 idx1 1 col_1 A 2 NULL NULL YES BTREE NO +t1 1 idx2 1 col_2 A 2 NULL NULL YES BTREE NO +FLUSH TABLES t1 FOR EXPORT; +backup: t1 +UNLOCK TABLES; +DROP TABLE t1; +CREATE TABLE t1 ( +col_1 CHAR (255), +col_2 VARCHAR (255) +) ENGINE = InnoDB STATS_PERSISTENT=1; +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); +SHOW INDEXES 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 1 idx1 1 col_1 A 0 NULL NULL YES BTREE NO +t1 1 idx2 1 col_2 A 0 NULL NULL YES BTREE NO +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"); +SHOW INDEXES 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 1 idx1 1 col_1 A 1 NULL NULL YES BTREE NO +t1 1 idx2 1 col_2 A 1 NULL NULL YES BTREE NO +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +SHOW INDEXES 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 1 idx1 1 col_1 A 1 NULL NULL YES BTREE NO +t1 1 idx2 1 col_2 A 1 NULL NULL YES BTREE NO +ALTER TABLE t1 DISCARD TABLESPACE; +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +SHOW INDEXES 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 1 idx1 1 col_1 A 2 NULL NULL YES BTREE NO +t1 1 idx2 1 col_2 A 2 NULL NULL YES BTREE NO +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +SHOW INDEXES 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 1 idx1 1 col_1 A 2 NULL NULL YES BTREE NO +t1 1 idx2 1 col_2 A 2 NULL NULL YES BTREE NO +DROP TABLE t1; +SET GLOBAL innodb_file_per_table = @old_innodb_file_per_table; diff --git a/mysql-test/suite/innodb/r/index_length.result b/mysql-test/suite/innodb/r/index_length.result new file mode 100644 index 00000000000..cc92780ac32 --- /dev/null +++ b/mysql-test/suite/innodb/r/index_length.result @@ -0,0 +1,23 @@ +connect stop_purge,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(1024)) +ENGINE=InnoDB STATS_PERSISTENT=1; +INSERT INTO t1 VALUES (1,REPEAT('b',1024)); +SELECT index_length FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +index_length +0 +ALTER TABLE t1 ADD INDEX b (b(800)); +SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +FLOOR(index_length/@@innodb_page_size) +1 +ALTER TABLE t1 ADD INDEX ba (b(800),a); +SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +FLOOR(index_length/@@innodb_page_size) +2 +disconnect stop_purge; +DROP TABLE t1; +# End of 10.4 tests diff --git a/mysql-test/suite/innodb/r/innodb-32k.result b/mysql-test/suite/innodb/r/innodb-32k.result index dd19616bf24..8742a769a50 100644 --- a/mysql-test/suite/innodb/r/innodb-32k.result +++ b/mysql-test/suite/innodb/r/innodb-32k.result @@ -1,5 +1,25 @@ SET GLOBAL innodb_stats_persistent = 0; call mtr.add_suppression("Innodb: Cannot add field.*row size is"); +SET SESSION innodb_strict_mode=ON; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +Warnings: +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +DROP TABLE t1; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +Warnings: +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +DROP TABLE t1; # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; diff --git a/mysql-test/suite/innodb/r/innodb-64k.result b/mysql-test/suite/innodb/r/innodb-64k.result index 758179568b9..c172483905e 100644 --- a/mysql-test/suite/innodb/r/innodb-64k.result +++ b/mysql-test/suite/innodb/r/innodb-64k.result @@ -1,4 +1,24 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the row size is'); +SET SESSION innodb_strict_mode=ON; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +Warnings: +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +DROP TABLE t1; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +Warnings: +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +DROP TABLE t1; # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; diff --git a/mysql-test/suite/innodb/r/innodb-ac-non-locking-select.result b/mysql-test/suite/innodb/r/innodb-ac-non-locking-select.result new file mode 100644 index 00000000000..5d12c1076e7 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-ac-non-locking-select.result @@ -0,0 +1,62 @@ +CREATE TABLE t1 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t1 VALUES(0, "0"); +INSERT INTO t1 VALUES(1, "1"); +INSERT INTO t1 VALUES(2, "2"); +INSERT INTO t1 VALUES(3, "3"); +connect con1,localhost,root,,; +connect con2,localhost,root,,; +connect con3,localhost,root,,; +connect con4,localhost,root,,; +connect con5,localhost,root,,; +connect con6,localhost,root,,; +connection default; +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t1 FOR UPDATE; +c1 c2 +0 0 +1 1 +2 2 +3 3 +SELECT * FROM t1 WHERE c1 <= 3; +c1 c2 +0 0 +1 1 +2 2 +3 3 +connection default; +SET DEBUG_SYNC='now WAIT_FOR waiting4'; +SET DEBUG_SYNC= 'RESET'; +SELECT trx_state, trx_query, trx_autocommit_non_locking +FROM INFORMATION_SCHEMA.INNODB_TRX +WHERE trx_state = 'LOCK WAIT' +ORDER BY trx_query; +trx_state trx_query trx_autocommit_non_locking +LOCK WAIT SELECT COUNT(*) FROM t1 LOCK IN SHARE MODE 0 +LOCK WAIT SELECT COUNT(*) FROM t1 WHERE c1 >= 0 0 +INSERT INTO t1 VALUES(4, '4'); +COMMIT; +connection con6; +SELECT * FROM t1 WHERE c1 <= 4; +c1 c2 +0 0 +1 1 +2 2 +3 3 +XA END '1'; +XA PREPARE '1'; +XA ROLLBACK '1'; +disconnect con6; +disconnect con2; +disconnect con3; +disconnect con5; +connection con1; +COUNT(*) +5 +disconnect con1; +connection con4; +COUNT(*) +5 +disconnect con4; +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result index 5bcb7cf963f..c1dcdd82fd7 100644 --- a/mysql-test/suite/innodb/r/innodb-alter.result +++ b/mysql-test/suite/innodb/r/innodb-alter.result @@ -1090,3 +1090,59 @@ ALTER TABLE t1 ADD COLUMN b DATETIME NOT NULL, LOCK=NONE; # Cleanup SET @@SQL_MODE= @OLD_SQL_MODE; DROP TABLE t1; +# +# Bug#20977779 CANNOT IMPORT TABLES CONTAINING PREFIX INDEXES +# +CREATE TABLE t1 (c1 VARCHAR(32), c2 VARCHAR(32), c3 VARCHAR(32), +PRIMARY KEY (c1, c2, c3)) +ENGINE=InnoDB; +ALTER TABLE t1 ADD INDEX ind1(c1(5), c2, c3); +ALTER TABLE t1 ADD INDEX ind2(c3, c1(10), c2); +ALTER TABLE t1 ADD INDEX ind3(c2, c3, c1(20)); +INSERT INTO t1 VALUES ('Test Data -1', 'Test Data -2', 'Test Data -3'); +# Test with 2ndary index having prefix +FLUSH TABLES test.t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE test.t1 DISCARD TABLESPACE; +ALTER TABLE test.t1 IMPORT TABLESPACE; +CHECK TABLE test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW CREATE TABLE test.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` varchar(32) NOT NULL, + `c2` varchar(32) NOT NULL, + `c3` varchar(32) NOT NULL, + PRIMARY KEY (`c1`,`c2`,`c3`), + KEY `ind1` (`c1`(5),`c2`,`c3`), + KEY `ind2` (`c3`,`c1`(10),`c2`), + KEY `ind3` (`c2`,`c3`,`c1`(20)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM test.t1; +c1 c2 c3 +Test Data -1 Test Data -2 Test Data -3 +# Test with PK & 2ndary index with prefix +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1(5), c2(10), c3(20)); +FLUSH TABLES test.t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE test.t1 DISCARD TABLESPACE; +ALTER TABLE test.t1 IMPORT TABLESPACE; +CHECK TABLE test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW CREATE TABLE test.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` varchar(32) NOT NULL, + `c2` varchar(32) NOT NULL, + `c3` varchar(32) NOT NULL, + PRIMARY KEY (`c1`(5),`c2`(10),`c3`(20)), + KEY `ind1` (`c1`(5),`c2`,`c3`), + KEY `ind2` (`c3`,`c1`(10),`c2`), + KEY `ind3` (`c2`,`c3`,`c1`(20)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM test.t1; +c1 c2 c3 +Test Data -1 Test Data -2 Test Data -3 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-index-online-fk.result b/mysql-test/suite/innodb/r/innodb-index-online-fk.result index 84e8ea89635..4903a6c1833 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online-fk.result +++ b/mysql-test/suite/innodb/r/innodb-index-online-fk.result @@ -608,3 +608,70 @@ test/e d a 0 test/fw c a 0 DROP TABLE t2; DROP TABLE t3; +# Bug #17449901 TABLE DISAPPEARS WHEN ALTERING +# WITH FOREIGN KEY CHECKS OFF +create table t1(f1 int,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int,key t(f2,f3),foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks=0; +drop index t on t2; +drop table t2; +drop table t1; +create table t1(f1 int ,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int, key t(f2),foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks = 0; +alter table t2 drop key t,algorithm=inplace; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f2` int(11) DEFAULT NULL, + `f3` int(11) DEFAULT NULL, + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +drop table t2; +drop table t1; +create table t1(f1 int ,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int, key t(f2),key t1(f2,f3), +foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks = 0; +alter table t2 drop key t,algorithm=inplace; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f2` int(11) DEFAULT NULL, + `f3` int(11) DEFAULT NULL, + KEY `t1` (`f2`,`f3`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +drop table t2; +drop table t1; +# +# MDEV-29092 FOREIGN_KEY_CHECKS does not prevent non-copy +# alter from creating invalid FK structures +# +CREATE TABLE t1(f1 INT, KEY(f1), +FOREIGN KEY(f1) references t1(f1))ENGINE=InnoDB; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL, + KEY `f1` (`f1`), + CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; +CREATE TABLE t1(f1 INT, KEY(f1), +FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=InnoDB; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL, + KEY `f1` (`f1`), + CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +ALTER TABLE t1 DROP KEY f1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL, + CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-lock-inherit-read_commited.result b/mysql-test/suite/innodb/r/innodb-lock-inherit-read_commited.result new file mode 100644 index 00000000000..ab0427caec9 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-lock-inherit-read_commited.result @@ -0,0 +1,121 @@ +# +# Bug #21025880 DUPLICATE UK VALUES IN READ-COMMITTED(AGAIN) +# +CREATE TABLE t1 ( +a INT NOT NULL, +b INT NOT NULL, +PRIMARY KEY(b), +UNIQUE KEY(a)) +ENGINE=INNODB; +SET @old_innodb_stats_auto_recalc = @@innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc = OFF; +connect purge_control,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +SET @old_tx_isolation = @@tx_isolation; +SET GLOBAL tx_isolation = 'READ-COMMITTED'; +SET @old_innodb_lock_wait_timeout = @@innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout = 1; +connect con1,localhost,root,,; +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1; +SET debug_sync = 'row_ins_sec_index_entry_dup_locks_created SIGNAL +con1_locks_done WAIT_FOR con1_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock SIGNAL +con1_insert_done WAIT_FOR con1_finish'; +REPLACE INTO t1 VALUES (1,2); +connect con2,localhost,root,,; +SET debug_sync = 'now WAIT_FOR con1_locks_done'; +SET debug_sync = 'lock_wait_start SIGNAL con2_blocked +WAIT_FOR con2_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock +WAIT_FOR con2_finish'; +SET debug_sync = 'ib_after_row_insert SIGNAL con2_insert_done'; +REPLACE INTO t1 VALUES (1,3); +connection default; +SET debug_sync = 'now WAIT_FOR con2_blocked'; +connection purge_control; +COMMIT; +disconnect purge_control; +connection default; +InnoDB 0 transactions not purged +SET debug_sync = 'now SIGNAL con2_go WAIT_FOR con2_insert_done'; +SET debug_sync = 'now SIGNAL con1_go WAIT_FOR con1_insert_done'; +SET debug_sync = 'now SIGNAL con1_finish'; +connection con1; +disconnect con1; +connection default; +SET debug_sync = 'now SIGNAL con2_finish'; +connection con2; +disconnect con2; +connection default; +SET DEBUG_SYNC= 'RESET'; +SELECT * FROM t1; +a b +1 2 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +SET GLOBAL innodb_stats_auto_recalc = @old_innodb_stats_auto_recalc; +SET GLOBAL tx_isolation = @old_tx_isolation; +SET GLOBAL innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; +CREATE TABLE t1 ( +a INT NOT NULL, +b INT NOT NULL, +PRIMARY KEY(b), +UNIQUE KEY(a)) +ENGINE=INNODB; +SET @old_innodb_stats_auto_recalc = @@innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc = OFF; +connect purge_control,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +SET @old_tx_isolation = @@tx_isolation; +SET GLOBAL tx_isolation = 'READ-COMMITTED'; +SET @old_innodb_lock_wait_timeout = @@innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout = 1; +connect con1,localhost,root,,; +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1; +SET debug_sync = 'row_ins_sec_index_entry_dup_locks_created SIGNAL +con1_locks_done WAIT_FOR con1_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock SIGNAL +con1_insert_done WAIT_FOR con1_finish'; +INSERT INTO t1 values (1,2) ON DUPLICATE KEY UPDATE a=2; +connect con2,localhost,root,,; +SET debug_sync = 'now WAIT_FOR con1_locks_done'; +SET debug_sync = 'lock_wait_start SIGNAL con2_blocked +WAIT_FOR con2_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock +WAIT_FOR con2_finish'; +SET debug_sync = 'ib_after_row_insert SIGNAL con2_insert_done'; +REPLACE INTO t1 VALUES (1,3); +connection default; +SET debug_sync = 'now WAIT_FOR con2_blocked'; +connection purge_control; +COMMIT; +disconnect purge_control; +connection default; +InnoDB 0 transactions not purged +SET debug_sync = 'now SIGNAL con2_go WAIT_FOR con2_insert_done'; +SET debug_sync = 'now SIGNAL con1_go WAIT_FOR con1_insert_done'; +SET debug_sync = 'now SIGNAL con1_finish'; +connection con1; +disconnect con1; +connection default; +SET debug_sync = 'now SIGNAL con2_finish'; +connection con2; +disconnect con2; +connection default; +SET DEBUG_SYNC= 'RESET'; +SELECT * FROM t1; +a b +1 2 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +SET GLOBAL innodb_stats_auto_recalc = @old_innodb_stats_auto_recalc; +SET GLOBAL tx_isolation = @old_tx_isolation; +SET GLOBAL innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; diff --git a/mysql-test/suite/innodb/r/innodb-read-view.result b/mysql-test/suite/innodb/r/innodb-read-view.result index e01d8a110e6..f3084fbdc52 100644 --- a/mysql-test/suite/innodb/r/innodb-read-view.result +++ b/mysql-test/suite/innodb/r/innodb-read-view.result @@ -9,9 +9,6 @@ INSERT INTO t2 VALUES(1, "b"); INSERT INTO t2 VALUES(2, "c"); INSERT INTO t2 VALUES(3, "d"); connect con1,localhost,root,,; -connect con2,localhost,root,,; -connection con1; -'T1' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t2; @@ -21,7 +18,6 @@ c1 c2 2 c 3 d connection default; -'T2' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t1; @@ -30,8 +26,7 @@ c1 c2 1 1 2 2 3 3 -connection con2; -'T3' +connect con2,localhost,root,,; SET AUTOCOMMIT=0; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; @@ -48,7 +43,6 @@ c1 c2 2 c 3 d connection con1; -'T1' UPDATE t2 SET c1 = c1 + 100; SELECT * FROM t2; c1 c2 @@ -58,7 +52,6 @@ c1 c2 103 d COMMIT; connection default; -'T2' UPDATE t1 SET c1 = c1 + 100; SELECT * FROM t1; c1 c2 @@ -68,42 +61,29 @@ c1 c2 103 3 COMMIT; connection con2; -'T3' SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; SELECT * FROM t1;; connection default; -'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; -'Signalled T3' connection con2; -'T3' c1 c2 0 0 1 1 2 2 3 3 connection con2; -'T3' SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; SELECT * FROM t2;; connection default; -'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; -'Signalled T3' connection con2; -'T3' c1 c2 0 a 1 b 2 c 3 d connection default; -disconnect con1; -disconnect con2; -connect con1,localhost,root,,; -connect con2,localhost,root,,; connection con1; -'T1' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t1; @@ -113,7 +93,6 @@ c1 c2 102 2 103 3 connection default; -'T2' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t2; @@ -131,7 +110,6 @@ c1 c2 203 d COMMIT; connection con2; -'T3' SET AUTOCOMMIT=0; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; @@ -148,7 +126,6 @@ c1 c2 202 c 203 d connection con1; -'T1' UPDATE t1 SET c1 = c1 + 100; SELECT * FROM t1; c1 c2 @@ -158,44 +135,34 @@ c1 c2 203 3 COMMIT; connection con2; -'T3' SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; SELECT * FROM t1;; connection con1; -'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; -'Signalled T3' connection con2; -'T3' c1 c2 100 0 101 1 102 2 103 3 -connection con2; -'T3' SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; SELECT * FROM t2;; connection default; -'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; -'Signalled T3' connection con2; -'T3' c1 c2 200 a 201 b 202 c 203 d -connection default; -disconnect con1; disconnect con2; +connection default; DROP TABLE t1; DROP TABLE t2; # # Bug 21433768: NON-REPEATABLE READ WITH REPEATABLE READ ISOLATION # -connect con1,localhost,root,,; +connection con1; CREATE TABLE t1(col1 INT PRIMARY KEY, col2 INT) ENGINE = InnoDB; INSERT INTO t1 values (1, 0), (2, 0); SELECT * FROM t1 ORDER BY col1; @@ -218,5 +185,5 @@ SET DEBUG_SYNC = 'now SIGNAL s2'; connection con1; disconnect con1; connection default; -DROP TABLE t1; SET DEBUG_SYNC= 'RESET'; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result index de42ecd7979..76811ced060 100644 --- a/mysql-test/suite/innodb/r/innodb-table-online.result +++ b/mysql-test/suite/innodb/r/innodb-table-online.result @@ -1,3 +1,5 @@ +SET GLOBAL innodb_monitor_reset_all=all; +SET GLOBAL innodb_monitor_reset_all=default; call mtr.add_suppression("InnoDB: Warning: Small buffer pool size"); call mtr.add_suppression("InnoDB: Error: table 'test/t1'"); call mtr.add_suppression("MariaDB is trying to open a table handle but the .ibd file for"); @@ -173,13 +175,13 @@ Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK SET @merge_encrypt_0= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted'); SET @merge_decrypt_0= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted'); SET @rowlog_encrypt_0= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); connection con1; SHOW CREATE TABLE t1; @@ -231,13 +233,13 @@ ddl_pending_alter_table 1 ddl_sort_file_alter_table 0 ddl_log_file_alter_table 1 SET @merge_encrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted'); SET @merge_decrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted'); SET @rowlog_encrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); SELECT (@merge_encrypt_1-@merge_encrypt_0)- @@ -257,16 +259,16 @@ ddl_pending_alter_table 0 ddl_sort_file_alter_table 0 ddl_log_file_alter_table 1 SET @merge_encrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted'); SET @merge_decrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted'); SET @rowlog_encrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); SET @rowlog_decrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted'); SET GLOBAL innodb_max_purge_lag_wait=0; SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt3 WAIT_FOR dml3_done'; @@ -314,16 +316,16 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK SET @merge_encrypt_2= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted'); SET @merge_decrypt_2= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted'); SET @rowlog_encrypt_2= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); SET @rowlog_decrypt_2= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted'); SELECT (@merge_encrypt_2-@merge_encrypt_1)- diff --git a/mysql-test/suite/innodb/r/innodb-truncate.result b/mysql-test/suite/innodb/r/innodb-truncate.result index 3bcee0e8ed4..5b7d052bca3 100644 --- a/mysql-test/suite/innodb/r/innodb-truncate.result +++ b/mysql-test/suite/innodb/r/innodb-truncate.result @@ -86,11 +86,10 @@ CREATE TABLE t2 (f2 INT, FOREIGN KEY(f2) REFERENCES t1 (f2)) ENGINE=InnoDB; CREATE TABLE t3 (a INT) ENGINE=InnoDB; ERROR HY000: Can't create table `test`.`t3` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t1 RENAME TO t3; -ERROR HY000: Error on rename of './test/t1' to './test/t3' (errno: 150 "Foreign key constraint is incorrectly formed") -ALTER TABLE t1 FORCE; -TRUNCATE TABLE t1; -ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `test`.`t1` (`f2`)) -DROP TABLE t2, t1; +ALTER TABLE t3 FORCE; +TRUNCATE TABLE t3; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `test`.`t3` (`f2`)) +DROP TABLE t2, t3; # # MDEV-24861 Assertion `trx->rsegs.m_redo.rseg' failed # in innodb_prepare_commit_versioned diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 0f848cf21b3..3115b5ab101 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -2481,7 +2481,7 @@ INSERT INTO t2 VALUES(1); DELETE FROM t1 WHERE id = 1; ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`)) DROP TABLE t1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails SET FOREIGN_KEY_CHECKS=0; DROP TABLE t1; SET FOREIGN_KEY_CHECKS=1; diff --git a/mysql-test/suite/innodb/r/innodb_bug12902967.result b/mysql-test/suite/innodb/r/innodb_bug12902967.result deleted file mode 100644 index ddb2e12f26a..00000000000 --- a/mysql-test/suite/innodb/r/innodb_bug12902967.result +++ /dev/null @@ -1,6 +0,0 @@ -call mtr.add_suppression("In ALTER TABLE .* has or is referenced in foreign key constraints which are not compatible with the new table definition."); -# restart -create table t1 (f1 integer primary key) engine innodb; -alter table t1 add constraint c1 foreign key (f1) references t1(f1); -ERROR HY000: Error on rename of '#sql-alter' to './test/t1' (errno: 150 "Foreign key constraint is incorrectly formed") -drop table t1; diff --git a/mysql-test/suite/innodb/r/innodb_i_s_innodb_locks.result b/mysql-test/suite/innodb/r/innodb_i_s_innodb_locks.result new file mode 100644 index 00000000000..a410362ab52 Binary files /dev/null and b/mysql-test/suite/innodb/r/innodb_i_s_innodb_locks.result differ diff --git a/mysql-test/suite/innodb/r/innodb_i_s_innodb_trx.result b/mysql-test/suite/innodb/r/innodb_i_s_innodb_trx.result new file mode 100644 index 00000000000..99de7d5fa1d --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_i_s_innodb_trx.result @@ -0,0 +1,90 @@ +SET @save_timeout=@@GLOBAL.innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout=100000000; +DESCRIBE INFORMATION_SCHEMA.INNODB_TRX; +Field Type Null Key Default Extra +trx_id bigint(21) unsigned NO NULL +trx_state varchar(13) NO NULL +trx_started datetime NO NULL +trx_requested_lock_id varchar(81) YES NULL +trx_wait_started datetime YES NULL +trx_weight bigint(21) unsigned NO NULL +trx_mysql_thread_id bigint(21) unsigned NO NULL +trx_query varchar(1024) YES NULL +trx_operation_state varchar(64) YES NULL +trx_tables_in_use bigint(21) unsigned NO NULL +trx_tables_locked bigint(21) unsigned NO NULL +trx_lock_structs bigint(21) unsigned NO NULL +trx_lock_memory_bytes bigint(21) unsigned NO NULL +trx_rows_locked bigint(21) unsigned NO NULL +trx_rows_modified bigint(21) unsigned NO NULL +trx_concurrency_tickets bigint(21) unsigned NO NULL +trx_isolation_level enum('READ UNCOMMITTED','READ COMMITTED','REPEATABLE READ','SERIALIZABLE') NO NULL +trx_unique_checks int(1) NO NULL +trx_foreign_key_checks int(1) NO NULL +trx_last_foreign_key_error varchar(256) YES NULL +trx_is_read_only int(1) NO NULL +trx_autocommit_non_locking int(1) NO NULL +CREATE TABLE t1 ( +c01 INT, +c02 INT, +PRIMARY KEY (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; +INSERT INTO t1 VALUES +(1,2),(2,4),(3,6),(4,8); +CREATE TABLE t2 ( +c01 INT, +c02 INT, +PRIMARY KEY (c01), +FOREIGN KEY fk1 (c02) REFERENCES t1 (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; +INSERT INTO t2 VALUES +(1,1),(2,2),(3,3); +connect con_trx,localhost,root,,; +connect con_verify_innodb_trx,localhost,root,,; +connection con_trx; +SET autocommit=0; +INSERT INTO t1 VALUES (5,10); +SELECT * FROM t1 FOR UPDATE; +c01 c02 +1 2 +2 4 +3 6 +4 8 +5 10 +connection con_verify_innodb_trx; +SELECT trx_state, trx_weight, trx_tables_in_use, trx_tables_locked, +trx_rows_locked, trx_rows_modified, trx_concurrency_tickets, +trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; +trx_state trx_weight trx_tables_in_use trx_tables_locked trx_rows_locked trx_rows_modified trx_concurrency_tickets trx_isolation_level trx_unique_checks trx_foreign_key_checks +RUNNING 3 0 1 6 1 0 REPEATABLE READ 1 1 +connection con_trx; +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 0; +SET UNIQUE_CHECKS = 0; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; +INSERT INTO t1 VALUES (6,12); +connection con_verify_innodb_trx; +SELECT trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; +trx_isolation_level trx_unique_checks trx_foreign_key_checks +SERIALIZABLE 0 0 +connection con_trx; +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 1; +SET UNIQUE_CHECKS = 1; +BEGIN; +INSERT INTO t2 VALUES (4,10); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk1` FOREIGN KEY (`c02`) REFERENCES `t1` (`c01`)) +disconnect con_trx; +connection con_verify_innodb_trx; +SELECT trx_state, trx_isolation_level, trx_last_foreign_key_error +FROM INFORMATION_SCHEMA.INNODB_TRX; +trx_state trx_isolation_level trx_last_foreign_key_error +RUNNING REPEATABLE READ `test`.`t2`, CONSTRAINT `fk1` FOREIGN KEY (`c02`) REFERENCES `t1` (`c01`) +disconnect con_verify_innodb_trx; +connection default; +DROP TABLE t2; +DROP TABLE t1; +SET GLOBAL innodb_lock_wait_timeout=@save_timeout; diff --git a/mysql-test/suite/innodb/r/innodb_information_schema_tables.result b/mysql-test/suite/innodb/r/innodb_information_schema_tables.result index ea713ea6f6a..87ff94a9ab1 100644 --- a/mysql-test/suite/innodb/r/innodb_information_schema_tables.result +++ b/mysql-test/suite/innodb/r/innodb_information_schema_tables.result @@ -1,2 +1,3 @@ +FOUND 1 /\[Warning\] InnoDB: innodb_open_files 1000000 should not be greater than the open_files_limit [0-9]+/ in mysqld.1.err CREATE TABLE t1 ENGINE=InnoDB AS SELECT * FROM mysql.help_topic; DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result new file mode 100644 index 00000000000..40eae0a9385 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result @@ -0,0 +1,44 @@ +CREATE TABLE autorecalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; +SELECT n_rows, clustered_index_size FROM mysql.innodb_table_stats WHERE table_name = 'autorecalc'; +n_rows 0 +clustered_index_size 1 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc'; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 0 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +INSERT INTO autorecalc VALUES (1); +INSERT INTO autorecalc VALUES (2); +SELECT n_rows, clustered_index_size FROM mysql.innodb_table_stats WHERE table_name = 'autorecalc'; +n_rows 2 +clustered_index_size 1 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc'; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 2 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +DELETE FROM autorecalc; +SELECT n_rows, clustered_index_size FROM mysql.innodb_table_stats WHERE table_name = 'autorecalc'; +n_rows 0 +clustered_index_size 1 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc'; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 0 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +DROP TABLE autorecalc; diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result new file mode 100644 index 00000000000..8c68fe74504 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result @@ -0,0 +1,34 @@ +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a)) ENGINE=INNODB; +INSERT INTO arddl VALUES (1, 10); +INSERT INTO arddl VALUES (2, 10); +ALTER TABLE arddl ADD INDEX (b); +SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'arddl' ORDER BY 1; +n_rows 2 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' ORDER BY 1, 2, 3; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 2 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +DROP TABLE arddl; +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a), KEY (b)) ENGINE=INNODB; +INSERT INTO arddl VALUES (3, 10); +INSERT INTO arddl VALUES (4, 10); +ALTER TABLE arddl DROP INDEX b; +SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'arddl' ORDER BY 1; +n_rows 2 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' ORDER BY 1, 2, 3; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 2 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +DROP TABLE arddl; diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_lots.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_lots.result new file mode 100644 index 00000000000..746bce5687e --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_lots.result @@ -0,0 +1,202 @@ +SELECT table_name, n_rows FROM mysql.innodb_table_stats WHERE table_name LIKE 'ar_%' ORDER BY table_name; +table_name n_rows +ar_1001 0 +ar_1002 0 +ar_1003 0 +ar_1004 0 +ar_1005 0 +ar_1006 0 +ar_1007 0 +ar_1008 0 +ar_1009 0 +ar_1010 0 +ar_1011 0 +ar_1012 0 +ar_1013 0 +ar_1014 0 +ar_1015 0 +ar_1016 0 +ar_1017 0 +ar_1018 0 +ar_1019 0 +ar_1020 0 +ar_1021 0 +ar_1022 0 +ar_1023 0 +ar_1024 0 +ar_1025 0 +ar_1026 0 +ar_1027 0 +ar_1028 0 +ar_1029 0 +ar_1030 0 +ar_1031 0 +ar_1032 0 +ar_1033 0 +ar_1034 0 +ar_1035 0 +ar_1036 0 +ar_1037 0 +ar_1038 0 +ar_1039 0 +ar_1040 0 +ar_1041 0 +ar_1042 0 +ar_1043 0 +ar_1044 0 +ar_1045 0 +ar_1046 0 +ar_1047 0 +ar_1048 0 +ar_1049 0 +ar_1050 0 +ar_1051 0 +ar_1052 0 +ar_1053 0 +ar_1054 0 +ar_1055 0 +ar_1056 0 +ar_1057 0 +ar_1058 0 +ar_1059 0 +ar_1060 0 +ar_1061 0 +ar_1062 0 +ar_1063 0 +ar_1064 0 +ar_1065 0 +ar_1066 0 +ar_1067 0 +ar_1068 0 +ar_1069 0 +ar_1070 0 +ar_1071 0 +ar_1072 0 +ar_1073 0 +ar_1074 0 +ar_1075 0 +ar_1076 0 +ar_1077 0 +ar_1078 0 +ar_1079 0 +ar_1080 0 +ar_1081 0 +ar_1082 0 +ar_1083 0 +ar_1084 0 +ar_1085 0 +ar_1086 0 +ar_1087 0 +ar_1088 0 +ar_1089 0 +ar_1090 0 +ar_1091 0 +ar_1092 0 +ar_1093 0 +ar_1094 0 +ar_1095 0 +ar_1096 0 +ar_1097 0 +ar_1098 0 +ar_1099 0 +ar_1100 0 +ar_1101 0 +ar_1102 0 +ar_1103 0 +ar_1104 0 +ar_1105 0 +ar_1106 0 +ar_1107 0 +ar_1108 0 +ar_1109 0 +ar_1110 0 +ar_1111 0 +ar_1112 0 +ar_1113 0 +ar_1114 0 +ar_1115 0 +ar_1116 0 +ar_1117 0 +ar_1118 0 +ar_1119 0 +ar_1120 0 +ar_1121 0 +ar_1122 0 +ar_1123 0 +ar_1124 0 +ar_1125 0 +ar_1126 0 +ar_1127 0 +ar_1128 0 +ar_1129 0 +ar_1130 0 +ar_1131 0 +ar_1132 0 +ar_1133 0 +ar_1134 0 +ar_1135 0 +ar_1136 0 +ar_1137 0 +ar_1138 0 +ar_1139 0 +ar_1140 0 +ar_1141 0 +ar_1142 0 +ar_1143 0 +ar_1144 0 +ar_1145 0 +ar_1146 0 +ar_1147 0 +ar_1148 0 +ar_1149 0 +ar_1150 0 +ar_1151 0 +ar_1152 0 +ar_1153 0 +ar_1154 0 +ar_1155 0 +ar_1156 0 +ar_1157 0 +ar_1158 0 +ar_1159 0 +ar_1160 0 +ar_1161 0 +ar_1162 0 +ar_1163 0 +ar_1164 0 +ar_1165 0 +ar_1166 0 +ar_1167 0 +ar_1168 0 +ar_1169 0 +ar_1170 0 +ar_1171 0 +ar_1172 0 +ar_1173 0 +ar_1174 0 +ar_1175 0 +ar_1176 0 +ar_1177 0 +ar_1178 0 +ar_1179 0 +ar_1180 0 +ar_1181 0 +ar_1182 0 +ar_1183 0 +ar_1184 0 +ar_1185 0 +ar_1186 0 +ar_1187 0 +ar_1188 0 +ar_1189 0 +ar_1190 0 +ar_1191 0 +ar_1192 0 +ar_1193 0 +ar_1194 0 +ar_1195 0 +ar_1196 0 +ar_1197 0 +ar_1198 0 +ar_1199 0 +ar_1200 0 diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result new file mode 100644 index 00000000000..6b2397432df --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result @@ -0,0 +1,60 @@ +Test with default setting +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +SELECT * FROM t; +FLUSH TABLE t; +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT * FROM t; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +DROP TABLE t; +Test with explicit enable +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=1; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +SELECT * FROM t; +FLUSH TABLE t; +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT * FROM t; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +DROP TABLE t; +Test with explicit disable +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=0; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +SELECT * FROM t; +FLUSH TABLE t; +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT * FROM t; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 0 +DROP TABLE t; diff --git a/mysql-test/suite/innodb/r/innodb_stats_external_pages.result b/mysql-test/suite/innodb/r/innodb_stats_external_pages.result new file mode 100644 index 00000000000..52e1e153059 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_external_pages.result @@ -0,0 +1,10 @@ +CREATE TABLE bug18384390 ( +id INT AUTO_INCREMENT PRIMARY KEY, +txt VARCHAR(10000) +) ENGINE=INNODB STATS_PERSISTENT=1 STATS_AUTO_RECALC=0; +INSERT INTO bug18384390 (txt) SELECT REPEAT('0', 10000) FROM seq_1_to_1024; +set use_stat_tables=never; +ANALYZE TABLE bug18384390; +Table Op Msg_type Msg_text +test.bug18384390 analyze status OK +DROP TABLE bug18384390; diff --git a/mysql-test/suite/innodb/r/innodb_stats_fetch.result b/mysql-test/suite/innodb/r/innodb_stats_fetch.result index d7b7d78ec71..df6bc4b0cf7 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_fetch.result +++ b/mysql-test/suite/innodb/r/innodb_stats_fetch.result @@ -150,3 +150,27 @@ max_data_length 0 index_length 16384 DROP TABLE test_ps_fetch; set @@use_stat_tables = @save_use_stat_tables; +# +# MDEV-28613 LeakSanitizer caused by I_S query using LIMIT ROWS EXAMINED +# +CREATE TABLE t1(f1 VARCHAR(255), FULLTEXT(f1))ENGINE=InnoDB; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES LIMIT ROWS EXAMINED 5; +Warnings: +Level Warning +Code 1931 +Message Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 5. The query result may be incomplete +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES LIMIT ROWS EXAMINED 5; +Warnings: +Level Warning +Code 1931 +Message Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 5. The query result may be incomplete +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS LIMIT ROWS EXAMINED 5; +Warnings: +Level Warning +Code 1931 +Message Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 5. The query result may be incomplete +SELECT SPACE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES LIMIT ROWS EXAMINED 5; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL LIMIT ROWS EXAMINED 5; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN LIMIT ROWS EXAMINED 5; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS LIMIT ROWS EXAMINED 5; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb_stats_flag_global,off.rdiff b/mysql-test/suite/innodb/r/innodb_stats_flag_global,off.rdiff new file mode 100644 index 00000000000..f5b235438aa --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_flag_global,off.rdiff @@ -0,0 +1,34 @@ +@@ -18,7 +18,7 @@ + test.test_ps_flag analyze status OK + SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + cnt_after +-1 ++0 + DROP TABLE test_ps_flag; + CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=default; + SHOW CREATE TABLE test_ps_flag; +@@ -37,7 +37,7 @@ + test.test_ps_flag analyze status OK + SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + cnt_after +-1 ++0 + DROP TABLE test_ps_flag; + ===== + === Test ANALYZE behavior after creation with explicit PS=OFF +@@ -142,7 +142,7 @@ + test.test_ps_flag analyze status OK + SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + cnt_after +-1 ++0 + DROP TABLE test_ps_flag; + ===== + === Test ANALYZE behavior after creation with explicit PS=ON, +@@ -203,5 +203,5 @@ + test.test_ps_flag analyze status OK + SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + cnt_after +-1 ++0 + DROP TABLE test_ps_flag; diff --git a/mysql-test/suite/innodb/r/innodb_stats_flag_global.result b/mysql-test/suite/innodb/r/innodb_stats_flag_global.result new file mode 100644 index 00000000000..8bafb725d89 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_flag_global.result @@ -0,0 +1,207 @@ +===== +=== Test ANALYZE behavior after default creation +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=default; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; +===== +=== Test ANALYZE behavior after creation with explicit PS=OFF +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +0 +DROP TABLE test_ps_flag; +===== +=== Test ANALYZE behavior after creation with explicit PS=ON +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=1 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; +===== +=== Test ANALYZE behavior after creation with explicit PS=OFF, +=== then ALTER to ON, then ALTER to OFF, then ALTER to default +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0; +ALTER TABLE test_ps_flag STATS_PERSISTENT=1; +# restart +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=1 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +ALTER TABLE test_ps_flag STATS_PERSISTENT=0; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +0 +ALTER TABLE test_ps_flag STATS_PERSISTENT=default; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; +===== +=== Test ANALYZE behavior after creation with explicit PS=ON, +=== then ALTER to OFF, then ALTER to ON, then ALTER to default +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1; +ALTER TABLE test_ps_flag STATS_PERSISTENT=0; +# restart +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +0 +ALTER TABLE test_ps_flag STATS_PERSISTENT=1; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=1 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +ALTER TABLE test_ps_flag STATS_PERSISTENT=default; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; diff --git a/mysql-test/suite/innodb/r/innodb_stats_persistent.result b/mysql-test/suite/innodb/r/innodb_stats_persistent.result index 72cd4df5cb3..4ce1b59e0ba 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_persistent.result +++ b/mysql-test/suite/innodb/r/innodb_stats_persistent.result @@ -8,9 +8,9 @@ CREATE TABLE t1 (id SERIAL, val INT UNSIGNED NOT NULL, KEY(val)) ENGINE=INNODB STATS_PERSISTENT=1,STATS_AUTO_RECALC=1; CREATE TABLE t2 LIKE t1; INSERT INTO t1 (val) SELECT 4 FROM seq_1_to_16; +SET STATEMENT use_stat_tables=never FOR ANALYZE TABLE t1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK connect con1, localhost, root,,; START TRANSACTION; @@ -89,7 +89,7 @@ COUNT(*) # ha_innobase::records_in_range() would count the delete-marked records. EXPLAIN SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL val 4 NULL 16 Using index +1 SIMPLE t1 index NULL val 4 NULL 1 Using index ROLLBACK; EXPLAIN SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra @@ -103,3 +103,25 @@ DROP TABLE t1,t2; SET GLOBAL innodb_stats_include_delete_marked = @saved_include_delete_marked; SET GLOBAL innodb_stats_traditional = @saved_traditional; SET GLOBAL innodb_stats_modified_counter = @saved_modified_counter; +CREATE TABLE bug12429573 (i INTEGER PRIMARY KEY, j INTEGER, KEY(j)) +ENGINE=INNODB STATS_PERSISTENT=1; +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE bug12429573; +Table Op Msg_type Msg_text +test.bug12429573 analyze status OK +SELECT last_update INTO @last FROM mysql.innodb_table_stats +WHERE table_name = 'bug12429573'; +SELECT * FROM mysql.innodb_index_stats +WHERE table_name = 'bug12429573' AND last_update!=@last; +database_name table_name index_name last_update stat_name stat_value sample_size stat_description +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE bug12429573; +Table Op Msg_type Msg_text +test.bug12429573 analyze status OK +SELECT * FROM mysql.innodb_table_stats +WHERE table_name = 'bug12429573' AND last_update=@last; +database_name table_name last_update n_rows clustered_index_size sum_of_other_index_sizes +SELECT * FROM mysql.innodb_index_stats +WHERE table_name = 'bug12429573' AND last_update=@last; +database_name table_name index_name last_update stat_name stat_value sample_size stat_description +DROP TABLE bug12429573; diff --git a/mysql-test/suite/innodb/r/innodb_stats_sample_pages.result b/mysql-test/suite/innodb/r/innodb_stats_sample_pages.result new file mode 100644 index 00000000000..a24d9aa8b62 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_sample_pages.result @@ -0,0 +1,29 @@ +SET GLOBAL innodb_stats_persistent_sample_pages=17; +CREATE TABLE test_ps_sample_pages_used ( +a VARCHAR(512), PRIMARY KEY (a) +) ENGINE=INNODB STATS_SAMPLE_PAGES=default; +BEGIN; +COMMIT; +ANALYZE TABLE test_ps_sample_pages_used; +Table Op Msg_type Msg_text +test.test_ps_sample_pages_used analyze status Engine-independent statistics collected +test.test_ps_sample_pages_used analyze status OK +SELECT stat_name, stat_value FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_leaf_pages'; +stat_name stat_value +n_leaf_pages 37 +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; +sample_size +17 +ALTER TABLE test_ps_sample_pages_used STATS_SAMPLE_PAGES=14; +ANALYZE TABLE test_ps_sample_pages_used; +Table Op Msg_type Msg_text +test.test_ps_sample_pages_used analyze status Engine-independent statistics collected +test.test_ps_sample_pages_used analyze status OK +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; +sample_size +14 +DROP TABLE test_ps_sample_pages_used; +SET GLOBAL innodb_stats_persistent_sample_pages=default; diff --git a/mysql-test/suite/innodb/r/innodb_stats_table_flag_auto_recalc.result b/mysql-test/suite/innodb/r/innodb_stats_table_flag_auto_recalc.result new file mode 100644 index 00000000000..5585d3f654e --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_table_flag_auto_recalc.result @@ -0,0 +1,82 @@ +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=1 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=1 +DROP TABLE test_ps_auto_recalc; +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=default; +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options +DROP TABLE test_ps_auto_recalc; +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=0; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=0 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=0 +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=1 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=1 +DROP TABLE test_ps_auto_recalc; +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=1; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=1 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=1 +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=0; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=0 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=0 +DROP TABLE test_ps_auto_recalc; diff --git a/mysql-test/suite/innodb/r/innodb_stats_table_flag_sample_pages.result b/mysql-test/suite/innodb/r/innodb_stats_table_flag_sample_pages.result new file mode 100644 index 00000000000..b26b0150c8d --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_table_flag_sample_pages.result @@ -0,0 +1,95 @@ +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB; +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=12345; +# restart +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_SAMPLE_PAGES=12345 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options stats_sample_pages=12345 +DROP TABLE test_ps_sample_pages; +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=default; +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options +DROP TABLE test_ps_sample_pages; +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=-5; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-5' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=0; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '0' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=67000; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '67000' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=670000; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '670000' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65536; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '65536' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65535; +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_SAMPLE_PAGES=65535 +DROP TABLE test_ps_sample_pages; +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=1; +# restart +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_SAMPLE_PAGES=1 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options stats_sample_pages=1 +DROP TABLE test_ps_sample_pages; +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=5678; +# restart +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_SAMPLE_PAGES=5678 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options stats_sample_pages=5678 +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=default; +# restart +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options +DROP TABLE test_ps_sample_pages; diff --git a/mysql-test/suite/innodb/r/innodb_ut_format_name.result b/mysql-test/suite/innodb/r/innodb_ut_format_name.result new file mode 100644 index 00000000000..41a5b0f7149 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_ut_format_name.result @@ -0,0 +1,5 @@ +CREATE TABLE t (c INT) ENGINE=INNODB; +SET @save_dbug = @@debug_dbug; +SET debug_dbug = '+d,test_ut_format_name'; +DROP TABLE t; +SET debug_dbug = @save_dbug; diff --git a/mysql-test/suite/innodb/r/no_pad.result b/mysql-test/suite/innodb/r/no_pad.result index 0c039c30a5e..2af5eb0207f 100644 --- a/mysql-test/suite/innodb/r/no_pad.result +++ b/mysql-test/suite/innodb/r/no_pad.result @@ -5,3 +5,49 @@ ALTER TABLE t1 ROW_FORMAT=DYNAMIC; INSERT INTO t1 VALUES ('',2); ALTER TABLE t1 ROW_FORMAT=REDUNDANT; DROP TABLE t1; +# +# MDEV-26743 InnoDB: CHAR+nopad does not work well +# +# +# Basic Latin letter vs equal accented letter +# +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(2), PRIMARY KEY(a)) COLLATE utf8_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT; +INSERT INTO t1 VALUES ('a'),('ä'); +ERROR 23000: Duplicate entry 'ä' for key 'PRIMARY' +DROP TABLE t1; +# +# Two letters vs equal (but space padded) expansion +# +CREATE TABLE t1 (a CHAR(2), PRIMARY KEY(a)) COLLATE utf8_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT; +INSERT INTO t1 VALUES ('ss'),('ß'); +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +SELECT HEX(a) FROM t1; +HEX(a) +7373 +C39F20 +SET sql_mode=DEFAULT; +DROP TABLE t1; +# +# Basic Latin letter (but followed by an ignorable character) vs equal accented letter +# +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(3), PRIMARY KEY(a)) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT; +INSERT INTO t1 VALUES (CONCAT('a',_utf8mb3 0x01)),('ä'); +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +SELECT HEX(a) FROM t1 ORDER BY HEX(a); +HEX(a) +610120 +C3A42020 +SET sql_mode=DEFAULT; +DROP TABLE t1; +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(2), PRIMARY KEY(a)) COLLATE utf8_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT; +INSERT INTO t1 VALUES (CONCAT('a',_utf8mb3 0x01)),('ä'); +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +SELECT HEX(a) FROM t1 ORDER BY HEX(a); +HEX(a) +6101 +C3A420 +SET sql_mode=DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/purge_thread_shutdown.result b/mysql-test/suite/innodb/r/purge_thread_shutdown.result deleted file mode 100644 index 85ac77e6d49..00000000000 --- a/mysql-test/suite/innodb/r/purge_thread_shutdown.result +++ /dev/null @@ -1,27 +0,0 @@ -connect con1, localhost, root; -create table t1 (a int) engine=innodb; -insert t1 values (1),(2),(3),(4); -delete from t1 where a=1; -select user,state from information_schema.processlist order by 2; -user state -root -root Filling schema table -set global debug_dbug='+d,only_kill_system_threads'; -set global innodb_fast_shutdown=0; -shutdown; -connection default; -disconnect con1; -select user,state from information_schema.processlist order by 2; -user state -root Filling schema table -set global innodb_fast_shutdown=1; -select user,state from information_schema.processlist order by 2; -user state -root Filling schema table -delete from t1 where a=3; -set global innodb_fast_shutdown=0; -ERROR 42000: Variable 'innodb_fast_shutdown' can't be set to the value of '0' -kill ID; -ERROR 70100: Connection was killed -# restart -drop table t1; diff --git a/mysql-test/suite/innodb/r/records_in_range,4k.rdiff b/mysql-test/suite/innodb/r/records_in_range,4k.rdiff new file mode 100644 index 00000000000..12b857ece22 --- /dev/null +++ b/mysql-test/suite/innodb/r/records_in_range,4k.rdiff @@ -0,0 +1,8 @@ +@@ -39,7 +39,7 @@ + WHERE + table_name='records_in_range_test' AND stat_name = 'size'; + index_name stat_name stat_value +-PRIMARY size 1 ++PRIMARY size 5 + SET @save_dbug = @@debug_dbug; + SET DEBUG_DBUG='+d,print_btr_estimate_n_rows_in_range_return_value'; diff --git a/mysql-test/suite/innodb/r/records_in_range,8k.rdiff b/mysql-test/suite/innodb/r/records_in_range,8k.rdiff new file mode 100644 index 00000000000..bd24af160ba --- /dev/null +++ b/mysql-test/suite/innodb/r/records_in_range,8k.rdiff @@ -0,0 +1,8 @@ +@@ -39,7 +39,7 @@ + WHERE + table_name='records_in_range_test' AND stat_name = 'size'; + index_name stat_name stat_value +-PRIMARY size 1 ++PRIMARY size 3 + SET @save_dbug = @@debug_dbug; + SET DEBUG_DBUG='+d,print_btr_estimate_n_rows_in_range_return_value'; diff --git a/mysql-test/suite/innodb/r/records_in_range.result b/mysql-test/suite/innodb/r/records_in_range.result new file mode 100644 index 00000000000..e5a698f59cc --- /dev/null +++ b/mysql-test/suite/innodb/r/records_in_range.result @@ -0,0 +1,1275 @@ +CREATE TABLE records_in_range_test ( +c1 VARCHAR(16), +c2 VARCHAR(512), +PRIMARY KEY (c1) +) ENGINE=INNODB STATS_PERSISTENT=1; +INSERT INTO records_in_range_test VALUES +('ccc', REPEAT('v', 512)), +('kkk01', REPEAT('v', 512)), +('kkk02', REPEAT('v', 512)), +('kkk03', REPEAT('v', 512)), +('kkk04', REPEAT('v', 512)), +('kkk05', REPEAT('v', 512)), +('kkk06', REPEAT('v', 512)), +('kkk07', REPEAT('v', 512)), +('kkk08', REPEAT('v', 512)), +('mmm', REPEAT('v', 512)), +('nnn', REPEAT('v', 512)), +('uuu01', REPEAT('v', 512)), +('uuu02', REPEAT('v', 512)), +('uuu03', REPEAT('v', 512)), +('uuu04', REPEAT('v', 512)), +('uuu05', REPEAT('v', 512)), +('uuu06', REPEAT('v', 512)), +('uuu07', REPEAT('v', 512)), +('uuu08', REPEAT('v', 512)), +('xxx', REPEAT('v', 512)); +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE records_in_range_test; +Table Op Msg_type Msg_text +test.records_in_range_test analyze status OK +SELECT index_name, stat_name, stat_value +FROM mysql.innodb_index_stats +WHERE +table_name='records_in_range_test' AND stat_name = 'n_leaf_pages'; +index_name stat_name stat_value +PRIMARY n_leaf_pages 1 +SELECT index_name, stat_name, stat_value +FROM mysql.innodb_index_stats +WHERE +table_name='records_in_range_test' AND stat_name = 'size'; +index_name stat_name stat_value +PRIMARY size 1 +SET @save_dbug = @@debug_dbug; +SET DEBUG_DBUG='+d,print_btr_estimate_n_rows_in_range_return_value'; + +In all SELECTs below the number of the records in the range returned +by COUNT(*) must be the same as the number returned by +btr_estimate_n_rows_in_range() which can be seen inside the artificial +warning + +Test left-unbounded, right-open intervals + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'aaa'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'ccc'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +Test left-unbounded, right-closed intervals + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'aaa'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'ccc'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'nnn'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'xxx'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +Test left-open, right-unbounded intervals + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 + +Test left-closed, right-unbounded intervals + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 + +Test left-open, right-open intervals +In some cases here the optimizer is smart enough not to call +ha_innobase::records_in_range() at all, so we get no warning containing +the value returned from btr_estimate_n_rows_in_range() + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'bbb'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'ccc'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'eee'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'mmm'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'nnn'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'xxx'; +COUNT(*) +18 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 18 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'mmm'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'nnn'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'xxx'; +COUNT(*) +18 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 18 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'nnn'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'qqq'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'zzz'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'qqq'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'xxx'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'xxx'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'zzz'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'zzz'; +COUNT(*) +0 + +Test left-closed, right-open intervals +In some cases here the optimizer is smart enough not to call +ha_innobase::records_in_range() at all, so we get no warning containing +the value returned from btr_estimate_n_rows_in_range() + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'bbb'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'ccc'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'mmm'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'nnn'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'xxx'; +COUNT(*) +18 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 18 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'nnn'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'qqq'; +COUNT(*) +2 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 2 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'xxx'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'zzz'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'qqq'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'zzz'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'xxx'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'zzz'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'zzz'; +COUNT(*) +0 + +Test left-open, right-closed intervals +In some cases here the optimizer is smart enough not to call +ha_innobase::records_in_range() at all, so we get no warning containing +the value returned from btr_estimate_n_rows_in_range() + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'bbb'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'ccc'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'nnn'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'xxx'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'eee'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'nnn'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'qqq'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'xxx'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'zzz'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'qqq'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'zzz'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'zzz'; +COUNT(*) +0 + +Test left-closed, right-closed intervals +In some cases here the optimizer is smart enough not to call +ha_innobase::records_in_range() at all, so we get no warning containing +the value returned from btr_estimate_n_rows_in_range() + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'bbb'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'ccc'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'nnn'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'xxx'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'ccc'; +COUNT(*) +1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'nnn'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'xxx'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'mmm'; +COUNT(*) +1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'nnn'; +COUNT(*) +2 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 2 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'qqq'; +COUNT(*) +2 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 2 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'xxx'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'zzz'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'nnn'; +COUNT(*) +1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'qqq'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'xxx'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'zzz'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'xxx'; +COUNT(*) +1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'zzz'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'zzz'; +COUNT(*) +0 +SET DEBUG_DBUG = @save_dbug; +DROP TABLE records_in_range_test; diff --git a/mysql-test/suite/innodb/r/tablespace_per_table_not_windows.result b/mysql-test/suite/innodb/r/tablespace_per_table_not_windows.result new file mode 100644 index 00000000000..7b1d0f915b6 --- /dev/null +++ b/mysql-test/suite/innodb/r/tablespace_per_table_not_windows.result @@ -0,0 +1,128 @@ +# +# Test the limits of a file-per-table tablespace name. MySQL combines +# the database name with the table name to make a unique table name. +# +SET default_storage_engine=InnoDB; +# +# MySQL limits each database and tablename identifier to 64 characters +# of up to 3 bytes per character, corresponding to 192 bytes. +# +CREATE DATABASE `this_sixty_five_byte_name_is_too_long____________________________`; +ERROR 42000: Incorrect database name 'this_sixty_five_byte_name_is_too_long____________________________' +CREATE DATABASE `this_sixty_four_byte_name_is_not_too_long_______________________`; +USE `this_sixty_four_byte_name_is_not_too_long_______________________`; +# +# A 64 character tablename can be created in a 64 character database name +# +CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_four_byte_name_is_not_too_long_______________________` (a SERIAL); +# +# A 65 character tablename is too long. +# +CREATE TABLE `test`.`this_sixty_five_byte_name_is_too_long____________________________` (a SERIAL); +ERROR 42000: Incorrect table name 'this_sixty_five_byte_name_is_too_long____________________________' +CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_five_byte_name_is_too_long____________________________` (a SERIAL); +ERROR 42000: Incorrect table name 'this_sixty_five_byte_name_is_too_long____________________________' +# +# Non-non-filename-safe characters like '#' are expanded to '@0023'. +# On many file systems, such as Linux extfs, you can create a database name +# that expands to up to 255 bytes long. +# `##################################################_long` is expanded to +# (50 * 5) + 5 = 255. +# +CREATE DATABASE `##################################################_long`;; +USE `##################################################_long`; +# +# This 256-byte name is only one byte longer but fails with an error code +# from the stat operation. +# `##################################################_long_` is expanded to +# (50 * 5) + 6 = 256. +# +CREATE DATABASE `##################################################_long_`; +ERROR HY000: Can't get stat of './##################################################_long_' (Errcode: ## "File name too long") +# +# This 300-byte name which is the longest name that gets an error code +# from the stat operation. +# `###########################################################_long` is expanded to +# (59 * 5) + 5 = 300. +# +CREATE DATABASE `###########################################################_long`; +ERROR HY000: Can't get stat of './###########################################################_long' (Errcode: ## "File name too long") +# +# This 301-byte name which is only one byte longer but fails with ER_TOO_LONG_IDENT. +# `###########################################################_long_` is expanded to +# (59 * 5) + 6 = 301. +# +CREATE DATABASE `###########################################################_long_`; +ERROR 42000: Incorrect database name '###########################################################_long_' +USE test; +# +# An expanded table name is limited to 251 bytes +# +CREATE TABLE `test`.`#################################################_long_` (a SERIAL); +# +# A 252-byte tablename is too long +# +CREATE TABLE `test`.`#################################################_long___` (a SERIAL); +ERROR HY000: Can't create table `test`.`#################################################_long___` (errno: ## "File name too long") +CREATE DATABASE twenty_byte_db_name_; +USE `twenty_byte_db_name_`; +# +# A 251 byte expanded table name will fit with a longer database name +# +CREATE TABLE `twenty_byte_db_name_`.`#################################################_long_` (a SERIAL); +# +# A 252 byte expanded table name is also too long in a longer database name +# +CREATE TABLE `twenty_byte_db_name_`.`#################################################_long___` (a SERIAL); +ERROR HY000: Can't create table `twenty_byte_db_name_`.`#################################################_long___` (errno: ## "File name too long") +# +# Another limitation is a 512 byte length to an expanded path that includes +# the datadir which is './' in this test, the expanded database name, +# the directory separator '/', the expanded table name, and the file extension. +# './long_db_name.long_250_byte_table_name.frm' +# 2+ 255 +1+ 250 +1+3 = 512 +# +CREATE TABLE `##################################################_long`.`#################################################_long` (a SERIAL); +CREATE TABLE `##################################################_long`.`#################################################_long_` (a SERIAL); +ERROR HY000: Long database name and identifier for object resulted in path length exceeding 512 characters. Path: './@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023_long/@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@ +SHOW WARNINGS; +Level Code Message +Error 1860 Long database name and identifier for object resulted in path length exceeding 512 characters. Path: './@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023_long/@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@ +# +# Show the successfully created databases and tables +# +---- list_files MYSQLD_DATADIR/test +#################################################_long_.frm +#################################################_long_.ibd +db.opt +---- list_files MYSQLD_DATADIR/this_sixty_four_byte_name_is_not_too_long_______________________ +db.opt +this_sixty_four_byte_name_is_not_too_long_______________________.frm +this_sixty_four_byte_name_is_not_too_long_______________________.ibd +---- list_files MYSQLD_DATADIR/##################################################_long +#################################################_long.frm +#################################################_long.ibd +db.opt +SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%'; +name +##################################################_long/#################################################_long +test/#################################################_long_ +this_sixty_four_byte_name_is_not_too_long_______________________/this_sixty_four_byte_name_is_not_too_long_______________________ +twenty_byte_db_name_/#################################################_long_ +SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%'; +name +this_sixty_four_byte_name_is_not_too_long_______________________/this_sixty_four_byte_name_is_not_too_long_______________________ +test/#################################################_long_ +twenty_byte_db_name_/#################################################_long_ +##################################################_long/#################################################_long +SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%'; +# +# Cleanup +# +DROP TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_four_byte_name_is_not_too_long_______________________`; +DROP TABLE `test`.`#################################################_long_`; +DROP TABLE `twenty_byte_db_name_`.`#################################################_long_`; +DROP TABLE `##################################################_long`.`#################################################_long`; +DROP DATABASE `this_sixty_four_byte_name_is_not_too_long_______________________`; +DROP DATABASE `##################################################_long`; +DROP DATABASE `twenty_byte_db_name_`; diff --git a/mysql-test/suite/innodb/r/tablespace_per_table_windows.result b/mysql-test/suite/innodb/r/tablespace_per_table_windows.result new file mode 100644 index 00000000000..14253baae3e --- /dev/null +++ b/mysql-test/suite/innodb/r/tablespace_per_table_windows.result @@ -0,0 +1,48 @@ +# +# Test the limits of a file-per-table tablespace name. MySQL combines +# the database name with the table name to make a unique table name. +# +SET default_storage_engine=InnoDB; +# +# MySQL limits each database and tablename identifier to 64 characters +# of up to 3 bytes per character, corresponding to 192 bytes. +# +CREATE DATABASE `this_sixty_five_byte_name_is_too_long____________________________`; +ERROR 42000: Incorrect database name 'this_sixty_five_byte_name_is_too_long____________________________' +CREATE DATABASE `this_sixty_four_byte_name_is_not_too_long_______________________`; +USE `this_sixty_four_byte_name_is_not_too_long_______________________`; +# +# A 64 character tablename can be created in a 64 character database name +# +CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_four_byte_name_is_not_too_long_______________________` (a SERIAL); +# +# A 65 character tablename is too long. +# +CREATE TABLE `test`.`this_sixty_five_byte_name_is_too_long____________________________` (a SERIAL); +ERROR 42000: Incorrect table name 'this_sixty_five_byte_name_is_too_long____________________________' +CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_five_byte_name_is_too_long____________________________` (a SERIAL); +ERROR 42000: Incorrect table name 'this_sixty_five_byte_name_is_too_long____________________________' +# +# Show the successfully created database and table +# +SHOW CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_four_byte_name_is_not_too_long_______________________`; +Table Create Table +this_sixty_four_byte_name_is_not_too_long_______________________ CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________` ( + `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + UNIQUE KEY `a` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +---- list_files MYSQLD_DATADIR/this_sixty_four_byte_name_is_not_too_long_______________________ +db.opt +this_sixty_four_byte_name_is_not_too_long_______________________.frm +this_sixty_four_byte_name_is_not_too_long_______________________.ibd +SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%'; +name +this_sixty_four_byte_name_is_not_too_long_______________________/this_sixty_four_byte_name_is_not_too_long_______________________ +SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%'; +name +this_sixty_four_byte_name_is_not_too_long_______________________/this_sixty_four_byte_name_is_not_too_long_______________________ +SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%'; +# +# Cleanup +# +DROP DATABASE `this_sixty_four_byte_name_is_not_too_long_______________________`; diff --git a/mysql-test/suite/innodb/t/add_foreign_key.test b/mysql-test/suite/innodb/t/add_foreign_key.test new file mode 100644 index 00000000000..d0febfd62f0 --- /dev/null +++ b/mysql-test/suite/innodb/t/add_foreign_key.test @@ -0,0 +1,38 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE ADD +--echo # FOREIGN KEY +--echo # + +CREATE TABLE `parent` (`parent_id` INT, PRIMARY KEY (`parent_id`)); +CREATE TABLE `child1` (`id` INT ,`child1_fk1` INT, `child1_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child2` (`id` INT, `child2_fk1` INT, `child2_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child3` (`id` INT , `child3_fk1` INT, PRIMARY KEY (`id`)); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES `parent` +(`parent_id`); + +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES `parent` +(`parent_id`); + +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES `parent` +(`parent_id`); + +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES +`parent` (`parent_id`); + +drop table child3, child2, child1, parent; diff --git a/mysql-test/suite/innodb/t/cascade_lock_wait.test b/mysql-test/suite/innodb/t/cascade_lock_wait.test new file mode 100644 index 00000000000..4489c9aefac --- /dev/null +++ b/mysql-test/suite/innodb/t/cascade_lock_wait.test @@ -0,0 +1,45 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +create table t1 (f1 int primary key) engine=innodb; +create table t2 (f1 int primary key, + constraint c1 foreign key (f1) references t1(f1) + on update cascade + on delete cascade) engine=innodb; +create table t3 (f1 int primary key, + constraint c2 foreign key (f1) references t1(f1) + on update cascade + on delete cascade) engine=innodb; +show create table t1; +show create table t2; +show create table t3; + +insert into t1 values (1); +insert into t1 values (2); +insert into t1 values (3); + +insert into t2 values (1); +insert into t2 values (2); +insert into t2 values (3); + +insert into t3 values (1); +insert into t3 values (2); +insert into t3 values (3); + +select f1 from t1; +select f1 from t2; +select f1 from t3; + +set @save_dbug = @@debug_dbug; +set debug_dbug = '+d,dml_cascade_only_once'; +set debug_dbug = '+d,row_upd_cascade_lock_wait_err'; +update t1 set f1 = 100 where f1 = 2; + +select f1 from t1; +select f1 from t2; +select f1 from t3; + +set debug_dbug = @save_dbug; +drop table t2; +drop table t3; +drop table t1; diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test index d8dac955348..33813dabdc4 100644 --- a/mysql-test/suite/innodb/t/doublewrite.test +++ b/mysql-test/suite/innodb/t/doublewrite.test @@ -1,17 +1,11 @@ + --echo # ---echo # Bug #17335427 INNODB CAN NOT USE THE DOUBLEWRITE BUFFER PROPERLY ---echo # Bug #18144349 INNODB CANNOT USE THE DOUBLEWRITE BUFFER FOR THE FIRST ---echo # PAGE OF SYSTEM TABLESPACE +--echo # MDEV-32242 innodb.doublewrite test case always is skipped --echo # --source include/innodb_page_size.inc ---source include/have_debug.inc --source include/not_embedded.inc -# This test is slow on buildbot. ---source include/big_test.inc -# Slow shutdown and restart to make sure ibuf merge is finished -SET GLOBAL innodb_fast_shutdown = 0; --disable_query_log call mtr.add_suppression("InnoDB: Data file .* uses page size .* but the innodb_page_size start-up parameter is"); call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS"); @@ -22,22 +16,14 @@ call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registra call mtr.add_suppression("InnoDB: A bad Space ID was found in datafile"); call mtr.add_suppression("InnoDB: Checksum mismatch in datafile: "); call mtr.add_suppression("InnoDB: Inconsistent tablespace ID in .*t1\\.ibd"); +call mtr.add_suppression("\\[Warning\\] Found 1 prepared XA transactions"); --enable_query_log ---source include/restart_mysqld.inc let INNODB_PAGE_SIZE=`select @@innodb_page_size`; let MYSQLD_DATADIR=`select @@datadir`; let ALGO=`select @@innodb_checksum_algorithm`; let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; -show variables like 'innodb_doublewrite'; -show variables like 'innodb_fil_make_page_dirty_debug'; -show variables like 'innodb_saved_page_number_debug'; - -connect (stop_purge,localhost,root,,); -START TRANSACTION WITH CONSISTENT SNAPSHOT; -connection default; - create table t1 (f1 int primary key, f2 blob) engine=innodb stats_persistent=0; start transaction; @@ -48,35 +34,24 @@ insert into t1 values(4, repeat('-',12)); insert into t1 values(5, repeat('.',12)); commit work; ---echo # --------------------------------------------------------------- ---echo # Test Begin: Test if recovery works if first page of user ---echo # tablespace is full of zeroes. +# Slow shutdown and restart to make sure ibuf merge is finished +SET GLOBAL innodb_fast_shutdown = 0; +let $shutdown_timeout=; +--source include/restart_mysqld.inc -select space into @space_id from information_schema.innodb_sys_tables -where name = 'test/t1'; +connect (dml,localhost,root,,); +XA START 'x'; +insert into t1 values (6, repeat('%', @@innodb_page_size/2)); +XA END 'x'; +XA PREPARE 'x'; +disconnect dml; +connection default; -begin; -insert into t1 values (6, repeat('%', 12)); ---echo # Ensure that dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; +flush table t1 for export; ---source ../include/no_checkpoint_start.inc - ---echo # Make the first page dirty for table t1 -set global innodb_saved_page_number_debug = 0; -set global innodb_fil_make_page_dirty_debug = @space_id; - ---echo # Ensure that dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; - ---let CLEANUP_IF_CHECKPOINT=drop table t1; ---source ../include/no_checkpoint_end.inc -disconnect stop_purge; - ---echo # Make the first page (page_no=0) of the user tablespace ---echo # full of zeroes. ---echo # ---echo # MDEV-11623: Use old FSP_SPACE_FLAGS in the doublewrite buffer. +let $restart_parameters=; +let $shutdown_timeout=0; +--source include/shutdown_mysqld.inc perl; use IO::Handle; @@ -90,16 +65,15 @@ my $page_size = $ENV{INNODB_PAGE_SIZE}; my $page; do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl"; open(FILE, "+<", $fname) or die; +sysseek(FILE, ($page_size/2), 0); +syswrite(FILE, chr(0) x ($page_size/2)); +sysseek(FILE, 3*$page_size, 0); sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n"; -my $page1 = $page; -substr($page1, 34, 4) = pack("N", 0); -my $polynomial0 = 0x82f63b78; # CRC-32C -my $ck0 = mycrc32(substr($page1, 0, ($page_size-4)), 0, $polynomial0); -substr($page1, ($page_size - 4), 4) = pack("N", $ck0); -sysseek(FILE, 0, 0)||die "Unable to seek $fname\n"; -die unless syswrite(FILE, $page1, $page_size) == $page_size; +sysseek(FILE, 3*$page_size, 0)||die "Unable to seek $fname\n"; +syswrite(FILE, chr(0) x ($page_size/2)); close FILE; +# Change the flag offset of page 0 in doublewrite buffer open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n"; sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek ibdata1\n"; sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n"; @@ -112,28 +86,23 @@ for (my $d = $d1; $d < $d2 + 64; $d++) sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n"; next unless $_ eq $page; sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n"; - # Write buggy MariaDB 10.1.x FSP_SPACE_FLAGS to the doublewrite buffer - my($flags) = unpack "x[54]N", $_; - my $badflags = ($flags & 0x3f); - my $compression_level=6; - $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16); - $badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE - + # Write buggy FSP_SPACE_FLAGS to the doublewrite buffer for page + my $badflags = 0x0006FFFF; substr ($_, 54, 4) = pack("N", $badflags); if ($algo =~ /full_crc32/) { - my $ck = mycrc32(substr($_, 0, $page_size - 4), 0, $polynomial); - substr($_, $page_size - 4, 4) = pack("N", $ck); + my $ck = mycrc32(substr($_, 0, $page_size - 4), 0, $polynomial); + substr($_, $page_size - 4, 4) = pack("N", $ck); } else { - # Replace the innodb_checksum_algorithm=crc32 checksum - my $ck= pack("N", - mycrc32(substr($_, 4, 22), 0, $polynomial) ^ - mycrc32(substr($_, 38, $page_size - 38 - 8), 0, - $polynomial)); - substr ($_, 0, 4) = $ck; - substr ($_, $page_size - 8, 4) = $ck; + # Replace the innodb_checksum_algorithm=crc32 checksum + my $ck= pack("N", + mycrc32(substr($_, 4, 22), 0, $polynomial) ^ + mycrc32(substr($_, 38, $page_size - 38 - 8), 0, + $polynomial)); + substr ($_, 0, 4) = $ck; + substr ($_, $page_size - 8, 4) = $ck; } syswrite(FILE, $_, $page_size)==$page_size||die; close(FILE); @@ -143,325 +112,13 @@ die "Did not find the page in the doublewrite buffer ($d1,$d2)\n"; EOF --source include/start_mysqld.inc - -check table t1; -select f1, f2 from t1; - ---echo # Test End ---echo # --------------------------------------------------------------- ---echo # Test Begin: Test if recovery works if first page of user ---echo # tablespace is corrupted. - -select space into @space_id from information_schema.innodb_sys_tables -where name = 'test/t1'; - ---echo # Ensure that dirty pages of table t1 is flushed. -flush tables t1 for export; -unlock tables; - -set global innodb_log_checkpoint_now=1; - -begin; -insert into t1 values (6, repeat('%', 12)); - ---source ../include/no_checkpoint_start.inc - ---echo # Make the first page dirty for table t1 -set global innodb_saved_page_number_debug = 0; -set global innodb_fil_make_page_dirty_debug = @space_id; - ---echo # Ensure that dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; - ---source include/no_checkpoint_end.inc - ---echo # Corrupt the first page (page_no=0) of the user tablespace. -perl; -use IO::Handle; -my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd"; -my $page_size = $ENV{INNODB_PAGE_SIZE}; -open(FILE, "+<", $fname) or die; -sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n"; -substr($page, 28, 4) = pack("N", 1000); -sysseek(FILE, 0, 0)||die "Unable to seek $fname\n"; -die unless syswrite(FILE, $page, $page_size) == $page_size; -close FILE; -EOF - ---source include/start_mysqld.inc - -check table t1; -select f1, f2 from t1; - ---echo # Test End ---echo # --------------------------------------------------------------- ---echo # Test Begin: Test if recovery works if 2nd page of user ---echo # tablespace is full of zeroes. - -select space into @space_id from information_schema.innodb_sys_tables -where name = 'test/t1'; - ---echo # Ensure that dirty pages of table t1 is flushed. -flush tables t1 for export; -unlock tables; - -begin; -insert into t1 values (6, repeat('%', 400)); - ---source ../include/no_checkpoint_start.inc - ---echo # Make the 2nd page dirty for table t1 -set global innodb_saved_page_number_debug = 1; -set global innodb_fil_make_page_dirty_debug = @space_id; - ---echo # Ensure that dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; - ---source include/no_checkpoint_end.inc - ---echo # Make the 2nd page (page_no=1) of the tablespace all zeroes. -perl; -use IO::Handle; -my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd"; -open(FILE, "+<", $fname) or die; -FILE->autoflush(1); -binmode FILE; -seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); -print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); -close FILE; -EOF - ---source include/start_mysqld.inc - -check table t1; -select f1, f2 from t1; - ---echo # Test End ---echo # --------------------------------------------------------------- ---echo # Test Begin: Test if recovery works if 2nd page of user ---echo # tablespace is corrupted. - -select space into @space_id from information_schema.innodb_sys_tables -where name = 'test/t1'; - ---echo # Ensure that dirty pages of table t1 is flushed. -flush tables t1 for export; -unlock tables; - -begin; -insert into t1 values (6, repeat('%', 400)); - ---source ../include/no_checkpoint_start.inc - ---echo # Make the 2nd page dirty for table t1 -set global innodb_saved_page_number_debug = 1; -set global innodb_fil_make_page_dirty_debug = @space_id; - ---echo # Ensure that the dirty pages of table t1 are flushed. -set global innodb_buf_flush_list_now = 1; - ---source include/no_checkpoint_end.inc - ---echo # Corrupt the 2nd page (page_no=1) of the user tablespace. -perl; -use IO::Handle; -my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd"; -open(FILE, "+<", $fname) or die; -FILE->autoflush(1); -binmode FILE; -seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); -print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); -close FILE; -EOF - ---source include/start_mysqld.inc - -check table t1; -select f1, f2 from t1; - ---echo # Test End ---echo # --------------------------------------------------------------- ---echo # Test Begin: Test if recovery works if first page of ---echo # system tablespace is full of zeroes. - -begin; -insert into t1 values (6, repeat('%', 400)); - ---echo # Ensure that all dirty pages in the system are flushed. -set global innodb_buf_flush_list_now = 1; - ---echo # Make the first page dirty for system tablespace -set global innodb_saved_page_number_debug = 0; -set global innodb_fil_make_page_dirty_debug = 0; - ---echo # Ensure that the dirty page of system tablespace is also flushed. -# We do this after the transaction starts and all dirty pages have been flushed -# already. So flushing of this specified dirty page will surely keep the -# copy in doublewrite buffer, and no more writes to doublewrite buffer would -# overwrite the copy. Thus, we can safely modify the original page when server -# is down. So do the following testings. -set global innodb_buf_flush_list_now = 1; - ---source include/kill_mysqld.inc - ---echo # Make the first page (page_no=0) of the system tablespace ---echo # all zeroes. -perl; -use IO::Handle; -my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; -open(FILE, "+<", $fname) or die; -FILE->autoflush(1); -binmode FILE; -print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); -close FILE; -EOF - ---source include/start_mysqld.inc - -check table t1; -select f1, f2 from t1; - ---echo # Test End ---echo # --------------------------------------------------------------- ---echo # Test Begin: Test if recovery works if first page of ---echo # system tablespace is corrupted. - -begin; -insert into t1 values (6, repeat('%', 400)); - ---echo # Ensure that all dirty pages in the system are flushed. -set global innodb_buf_flush_list_now = 1; - ---echo # Make the first page dirty for system tablespace -set global innodb_saved_page_number_debug = 0; -set global innodb_fil_make_page_dirty_debug = 0; - ---echo # Ensure that the dirty page of system tablespace is also flushed. -set global innodb_buf_flush_list_now = 1; - ---source include/kill_mysqld.inc - ---echo # Corrupt the first page (page_no=0) of the system tablespace. -perl; -use IO::Handle; -my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; -open(FILE, "+<", $fname) or die; -FILE->autoflush(1); -binmode FILE; -print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); -close FILE; -EOF - ---source include/start_mysqld.inc - -check table t1; -select f1, f2 from t1; - ---echo # Test End ---echo # --------------------------------------------------------------- ---echo # Test Begin: Test if recovery works if 2nd page of ---echo # system tablespace is full of zeroes. - -begin; -insert into t1 values (6, repeat('%', 400)); - ---echo # Ensure that all dirty pages in the system are flushed. -set global innodb_buf_flush_list_now = 1; - ---echo # Make the second page dirty for system tablespace -set global innodb_saved_page_number_debug = 1; -set global innodb_fil_make_page_dirty_debug = 0; - ---echo # Ensure that the dirty page of system tablespace is also flushed. -set global innodb_buf_flush_list_now = 1; - ---source include/kill_mysqld.inc - ---echo # Make the 2nd page (page_no=1) of the system tablespace ---echo # all zeroes. -perl; -use IO::Handle; -my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; -open(FILE, "+<", $fname) or die; -FILE->autoflush(1); -binmode FILE; -seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); -print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); -close FILE; -EOF - ---source include/start_mysqld.inc - -check table t1; -select f1, f2 from t1; - ---echo # Test End ---echo # --------------------------------------------------------------- ---echo # Test Begin: Test if recovery works if 2nd page of ---echo # system tablespace is corrupted. - -begin; -insert into t1 values (6, repeat('%', 400)); - ---echo # Ensure that all dirty pages in the system are flushed. -set global innodb_buf_flush_list_now = 1; - ---echo # Make the second page dirty for system tablespace -set global innodb_saved_page_number_debug = 1; -set global innodb_fil_make_page_dirty_debug = 0; - ---echo # Ensure that the dirty page of system tablespace is also flushed. -set global innodb_buf_flush_list_now = 1; - ---source include/kill_mysqld.inc - ---echo # Make the 2nd page (page_no=1) of the system tablespace ---echo # all zeroes. -perl; -use IO::Handle; -my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; -open(FILE, "+<", $fname) or die; -FILE->autoflush(1); -binmode FILE; -seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); -print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); -close FILE; -EOF - ---source include/start_mysqld.inc - -check table t1; ---let SEARCH_PATTERN= InnoDB: .*test.t1\\.ibd +let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=[1-9][0-9]*, page number=0\] of datafile; --source include/search_pattern_in_file.inc - +let SEARCH_PATTERN=InnoDB: Recovered page \[page id: space=[1-9][0-9]*, page number=3\]; +--source include/search_pattern_in_file.inc +XA ROLLBACK 'x'; +check table t1; select f1, f2 from t1; - drop table t1; ---echo # ---echo # MDEV-12600 crash during install_db with innodb_page_size=32K ---echo # and ibdata1=3M ---echo # -let bugdir= $MYSQLTEST_VARDIR/tmp/doublewrite; ---mkdir $bugdir - -let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES -WHERE engine = 'innodb' -AND support IN ('YES', 'DEFAULT', 'ENABLED'); - ---let $ibp=--innodb-log-group-home-dir=$bugdir --innodb-data-home-dir=$bugdir ---let $ibd=$ibp --innodb-undo-tablespaces=0 ---let $ibp=$ibp --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend - ---let $restart_parameters= $ibp ---source include/restart_mysqld.inc -eval $check_no_innodb; ---let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot create doublewrite buffer ---source include/search_pattern_in_file.inc ---let $restart_parameters= ---source include/restart_mysqld.inc - ---remove_file $bugdir/ibdata1 ---remove_file $bugdir/ibdata2 ---remove_file $bugdir/ib_logfile0 ---rmdir $bugdir +--echo # End of 10.5 tests diff --git a/mysql-test/suite/innodb/t/doublewrite_debug.combinations b/mysql-test/suite/innodb/t/doublewrite_debug.combinations new file mode 100644 index 00000000000..4f52013f6fc --- /dev/null +++ b/mysql-test/suite/innodb/t/doublewrite_debug.combinations @@ -0,0 +1,7 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 +--innodb-use-atomic-writes=0 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 +--innodb-use-atomic-writes=0 diff --git a/mysql-test/suite/innodb/t/doublewrite_debug.test b/mysql-test/suite/innodb/t/doublewrite_debug.test new file mode 100644 index 00000000000..86809cc43c0 --- /dev/null +++ b/mysql-test/suite/innodb/t/doublewrite_debug.test @@ -0,0 +1,162 @@ +--echo # +--echo # Bug #17335427 INNODB CAN NOT USE THE DOUBLEWRITE BUFFER PROPERLY +--echo # Bug #18144349 INNODB CANNOT USE THE DOUBLEWRITE BUFFER FOR THE FIRST +--echo # PAGE OF SYSTEM TABLESPACE +--echo # + +--source include/innodb_page_size.inc +--source include/have_debug.inc +--source include/not_embedded.inc +--disable_query_log +call mtr.add_suppression("InnoDB: Data file .* uses page size .* but the innodb_page_size start-up parameter is"); +call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS"); +call mtr.add_suppression("InnoDB: New log files created"); +call mtr.add_suppression("InnoDB: Cannot create doublewrite buffer: the first file in innodb_data_file_path must be at least (3|6|12)M\\."); +call mtr.add_suppression("InnoDB: Database creation was aborted"); +call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registration as a STORAGE ENGINE failed)"); +call mtr.add_suppression("InnoDB: A bad Space ID was found in datafile"); +call mtr.add_suppression("InnoDB: Checksum mismatch in datafile: "); +call mtr.add_suppression("InnoDB: Inconsistent tablespace ID in .*t1\\.ibd"); +--enable_query_log + +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; +let ALGO=`select @@innodb_checksum_algorithm`; +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; + +show variables like 'innodb_doublewrite'; +show variables like 'innodb_fil_make_page_dirty_debug'; +show variables like 'innodb_saved_page_number_debug'; + +create table t1 (f1 int primary key, f2 blob) engine=innodb; + +start transaction; +insert into t1 values(1, repeat('#',12)); +insert into t1 values(2, repeat('+',12)); +insert into t1 values(3, repeat('/',12)); +insert into t1 values(4, repeat('-',12)); +insert into t1 values(5, repeat('.',12)); +commit work; + +--echo # Test Begin: Test if recovery works if 1st page and 2nd page +--echo # of system tablespace is full of zeroes. + +# Slow shutdown and restart to make sure ibuf merge is finished +SET GLOBAL innodb_fast_shutdown = 0; +let $shutdown_timeout=; +--source include/restart_mysqld.inc +begin; +insert into t1 values (6, repeat('%', 400)); + +--echo # Make the first page dirty for system tablespace +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 0; + +--echo # Make the second page dirty for system tablespace +set global innodb_saved_page_number_debug = 1; +set global innodb_fil_make_page_dirty_debug = 0; + +set global innodb_buf_flush_list_now = 1; +let $shutdown_timeout=0; +--source include/shutdown_mysqld.inc + +--echo # Make the 1st page (page_no=0) and 2nd page (page_no=1) +--echo # of the system tablespace all zeroes. +perl; +use IO::Handle; +my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; +open(FILE, "+<", $fname) or die; +FILE->autoflush(1); +binmode FILE; +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); +seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); +close FILE; +EOF + +--source include/start_mysqld.inc + +let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile; +--source include/search_pattern_in_file.inc + +let SEARCH_PATTERN=InnoDB: Recovered page \[page id: space=0, page number=1\]; +--source include/search_pattern_in_file.inc + +check table t1; +select f1, f2 from t1; + +--echo # Test End +--echo # --------------------------------------------------------------- +--echo # Test Begin: Test if recovery works if 1st page of +--echo # system tablespace is corrupted and 2nd page as corrupted. + +set global innodb_log_checkpoint_now = 1; +begin; +insert into t1 values (6, repeat('%', 400)); + +--echo # Make the first page dirty for system tablespace +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 0; + +--echo # Make the second page dirty for system tablespace +set global innodb_saved_page_number_debug = 1; +set global innodb_fil_make_page_dirty_debug = 0; + +set global innodb_buf_flush_list_now = 1; +let $shutdown_timeout=0; +--source include/shutdown_mysqld.inc + +--echo # Corrupt the 1st page (page_no=0) and 2nd page of the system tablespace. +perl; +use IO::Handle; +my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; +open(FILE, "+<", $fname) or die; +FILE->autoflush(1); +binmode FILE; +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); +seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); +close FILE; +EOF + +--source include/start_mysqld.inc + +let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile; +--source include/search_pattern_in_file.inc + +let SEARCH_PATTERN=InnoDB: Recovered page \[page id: space=0, page number=1\]; +--source include/search_pattern_in_file.inc + +check table t1; +select f1, f2 from t1; +drop table t1; +let $shutdown_timeout=; +--echo # Test End +--echo # --------------------------------------------------------------- +--echo # +--echo # MDEV-12600 crash during install_db with innodb_page_size=32K +--echo # and ibdata1=3M +--echo # +let bugdir= $MYSQLTEST_VARDIR/tmp/doublewrite; +--mkdir $bugdir + +let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); + +--let $ibp=--innodb-log-group-home-dir=$bugdir --innodb-data-home-dir=$bugdir +--let $ibd=$ibp --innodb-undo-tablespaces=0 +--let $ibp=$ibp --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend + +--let $restart_parameters= $ibp +--source include/restart_mysqld.inc +eval $check_no_innodb; +--let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot create doublewrite buffer +--source include/search_pattern_in_file.inc +--let $restart_parameters= +--source include/restart_mysqld.inc + +--remove_file $bugdir/ibdata1 +--remove_file $bugdir/ibdata2 +--remove_file $bugdir/ib_logfile0 +--rmdir $bugdir diff --git a/mysql-test/suite/innodb/t/fk_col_alter.test b/mysql-test/suite/innodb/t/fk_col_alter.test index 2ed10a956d0..21fd470eaa8 100644 --- a/mysql-test/suite/innodb/t/fk_col_alter.test +++ b/mysql-test/suite/innodb/t/fk_col_alter.test @@ -149,4 +149,18 @@ ALTER TABLE t2 DROP INDEX idx; ALTER TABLE t2 MODIFY f2 VARCHAR(1023); SET SESSION FOREIGN_KEY_CHECKS = ON; DROP TABLE t2, t1; + +--echo # +--echo # MDEV-32638 MariaDB crashes with foreign_key_checks=0 +--echo # when changing a column and adding a foreign +--echo # key at the same time +--echo # +CREATE TABLE t1(f1 VARCHAR(2) NOT NULL, PRIMARY KEY(f1))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY, + f2 VARCHAR(10) NOT NULL DEFAULT '')ENGINE=InnoDB; +SET SESSION FOREIGN_KEY_CHECKS = OFF; +ALTER TABLE t2 CHANGE COLUMN f2 f3 VARCHAR(20) NOT NULL, + ADD CONSTRAINT t2_fk FOREIGN KEY(f3) REFERENCES t1(f1); +DROP TABLE t2, t1; +SET SESSION FOREIGN_KEY_CHECKS = ON; --echo # End of 10.4 tests diff --git a/mysql-test/suite/innodb/t/fk_drop_alter.test b/mysql-test/suite/innodb/t/fk_drop_alter.test new file mode 100644 index 00000000000..c79eb873d62 --- /dev/null +++ b/mysql-test/suite/innodb/t/fk_drop_alter.test @@ -0,0 +1,35 @@ +--source include/have_innodb.inc +--echo # +--echo # MDEV-22230 : Unexpected ER_ERROR_ON_RENAME upon DROP +--echo # non-existing FOREIGN KEY +--echo # +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +--error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=COPY; +--error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=INPLACE; +# Cleanup +DROP TABLE t1; + +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, FOREIGN KEY fk_id (a) REFERENCES t1(a))ENGINE=InnoDB; +CREATE TABLE t3 (a INT, FOREIGN KEY fk_1 (a) REFERENCES t1(a))ENGINE=InnoDB; +ALTER TABLE t3 DROP FOREIGN KEY IF EXISTS fk_id; +DROP TABLE t3, t2; +ALTER TABLE t1 MODIFY COLUMN a VARCHAR(2), DROP FOREIGN KEY IF EXISTS x; +DROP TABLE t1; + +CREATE DATABASE best; +CREATE TABLE best.t1(f1 INT, KEY(f1))ENGINE=InnoDB; +CREATE TABLE best.t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB; + +CREATE TABLE t1(f1 INT, KEY(f1))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB; +ALTER TABLE t2 DROP FOREIGN KEY foo; +--error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t2 DROP FOREIGN KEY foo; +ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS foo; +SHOW CREATE TABLE best.t2; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; +DROP TABLE best.t2, best.t1, t2, t1; +DROP DATABASE best; diff --git a/mysql-test/suite/innodb/t/foreign-keys.test b/mysql-test/suite/innodb/t/foreign-keys.test index b93f82c93ef..aeff7009402 100644 --- a/mysql-test/suite/innodb/t/foreign-keys.test +++ b/mysql-test/suite/innodb/t/foreign-keys.test @@ -268,3 +268,7 @@ SET FOREIGN_KEY_CHECKS=1; INSERT INTO t2 VALUES('G', 3); DROP TABLE t2, t1; SET FOREIGN_KEY_CHECKS=DEFAULT; + +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(a SERIAL) ENGINE=InnoDB ROW_FORMAT=COMPRESSED PAGE_COMPRESSED=1; +SHOW WARNINGS; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 35b88434323..0db3a7ca377 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -733,7 +733,9 @@ SELECT a FROM t1 FORCE INDEX(a); # the "goto rollback_to_savept" in row_mysql_handle_errors() is reverted. SELECT * FROM t1; # Allow purge to continue by closing the read view. -disconnect con1; +connection con1; +COMMIT; +connection default; # Wait for purge. With the fix reverted, the server would crash here. --source include/wait_all_purged.inc @@ -954,9 +956,37 @@ ALTER TABLE t1 MODIFY id INT unsigned AUTO_INCREMENT; DROP TABLE t1,t2; --echo # ---echo # End of 10.4 tests +--echo # MDEV-31441 BLOB corruption on UPDATE of PRIMARY KEY with FOREIGN KEY --echo # +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT) ENGINE=InnoDB; +CREATE TABLE t2 (pk INT PRIMARY KEY, FOREIGN KEY (pk) REFERENCES t1(pk)) +ENGINE=InnoDB; + +SET @blob = REPEAT('A', @@innodb_page_size / 2); +INSERT INTO t1 SET pk=1, t=@blob; +INSERT INTO t2 SET pk=1; +--connection con1 +BEGIN; +DELETE FROM t2; +--connection default +# The following will be blocked by a FOREIGN KEY check on pk=1 in t2. +--send +UPDATE t1 SET pk=12; +--connection con1 +let $wait_condition= +SELECT count(*) > 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state='Updating'; +--source include/wait_condition.inc +COMMIT; +--disconnect con1 +--connection default +--reap +UPDATE t1 SET pk=1; +SELECT pk,t=@blob FROM t1; +DROP TABLE t2, t1; + +--echo # End of 10.4 tests + --echo # --echo # MDEV-20729 Fix REFERENCES constraint in column definition --echo # diff --git a/mysql-test/suite/innodb/t/import_update_stats.test b/mysql-test/suite/innodb/t/import_update_stats.test new file mode 100644 index 00000000000..128213c77b2 --- /dev/null +++ b/mysql-test/suite/innodb/t/import_update_stats.test @@ -0,0 +1,81 @@ +# +# BUG#20125349 - PERSISTANT STATS IS NOT UPDATED WHEN TTS IS IMPORTED. +# + +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/not_valgrind.inc # MDEV-32725 FIXME + +let MYSQLD_DATADIR =`SELECT @@datadir`; +SET @old_innodb_file_per_table = @@innodb_file_per_table; + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +CREATE TABLE t1 ( + col_1 CHAR (255), + col_2 VARCHAR (255) +) ENGINE = InnoDB; + +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); + +SHOW INDEXES FROM t1; + +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"), ("col1_00002", "col2_00002"); + +SHOW INDEXES FROM t1; + +ANALYZE TABLE t1; +SHOW INDEXES FROM t1; + +FLUSH TABLES t1 FOR EXPORT; +perl; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF + +UNLOCK TABLES; + +DROP TABLE t1; + +CREATE TABLE t1 ( + col_1 CHAR (255), + col_2 VARCHAR (255) +) ENGINE = InnoDB STATS_PERSISTENT=1; + +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); + +SHOW INDEXES FROM t1; + +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"); + +SHOW INDEXES FROM t1; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +SHOW INDEXES FROM t1; + +ALTER TABLE t1 DISCARD TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; + +SHOW INDEXES FROM t1; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +SHOW INDEXES FROM t1; + +DROP TABLE t1; + +SET GLOBAL innodb_file_per_table = @old_innodb_file_per_table; + +--remove_files_wildcard $MYSQLTEST_VARDIR/tmp t1*.ibd +--remove_files_wildcard $MYSQLTEST_VARDIR/tmp t1*.cfg diff --git a/mysql-test/suite/innodb/t/index_length.test b/mysql-test/suite/innodb/t/index_length.test new file mode 100644 index 00000000000..bf4940d4b39 --- /dev/null +++ b/mysql-test/suite/innodb/t/index_length.test @@ -0,0 +1,23 @@ +--source include/have_innodb.inc + +--connect (stop_purge,localhost,root) +# Prevent the purge of history from acquiring a table handle. +START TRANSACTION WITH CONSISTENT SNAPSHOT; +--connection default + +CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(1024)) +ENGINE=InnoDB STATS_PERSISTENT=1; +INSERT INTO t1 VALUES (1,REPEAT('b',1024)); + +SELECT index_length FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +ALTER TABLE t1 ADD INDEX b (b(800)); +SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +ALTER TABLE t1 ADD INDEX ba (b(800),a); +SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +disconnect stop_purge; +DROP TABLE t1; + +--echo # End of 10.4 tests diff --git a/mysql-test/suite/innodb/t/innodb-32k.test b/mysql-test/suite/innodb/t/innodb-32k.test index 6e765ee833d..a5fd78fdfc2 100644 --- a/mysql-test/suite/innodb/t/innodb-32k.test +++ b/mysql-test/suite/innodb/t/innodb-32k.test @@ -8,6 +8,19 @@ call mtr.add_suppression("Innodb: Cannot add field.*row size is"); let $MYSQLD_DATADIR= `select @@datadir`; +SET SESSION innodb_strict_mode=ON; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +DROP TABLE t1; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +DROP TABLE t1; + --echo # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; diff --git a/mysql-test/suite/innodb/t/innodb-64k.test b/mysql-test/suite/innodb/t/innodb-64k.test index 972ba6bb8b8..d89370ff538 100644 --- a/mysql-test/suite/innodb/t/innodb-64k.test +++ b/mysql-test/suite/innodb/t/innodb-64k.test @@ -8,6 +8,19 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the let $MYSQLD_DATADIR= `select @@datadir`; +SET SESSION innodb_strict_mode=ON; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +DROP TABLE t1; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +DROP TABLE t1; + --echo # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; diff --git a/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test b/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test new file mode 100644 index 00000000000..3376367b0ba --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test @@ -0,0 +1,117 @@ +# DEBUG_SYNC must be compiled in. +--source include/have_debug_sync.inc +--source include/have_debug.inc +--source include/have_innodb.inc + +CREATE TABLE t1 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t1 VALUES(0, "0"); +INSERT INTO t1 VALUES(1, "1"); +INSERT INTO t1 VALUES(2, "2"); +INSERT INTO t1 VALUES(3, "3"); + +--connect (con1,localhost,root,,) +--connect (con2,localhost,root,,) +--connect (con3,localhost,root,,) +--connect (con4,localhost,root,,) +--connect (con5,localhost,root,,) +--connect (con6,localhost,root,,) + +connection default; +# Disable query log to avoid non-deterministic output conflicts +SET AUTOCOMMIT=0; +BEGIN; +# Lock all the records +SELECT * FROM t1 FOR UPDATE; +--disable_query_log + +connection con1; +SET AUTOCOMMIT=1; +# Test if locking autocommit selects end up in the trx_sys_t::trx_list. +# We check this via the INFORMATION_SCHEMA.INNODB_TRX. +# This should block and show up in the I_S. +SET DEBUG_SYNC='lock_wait_start SIGNAL waiting1'; +--send +SELECT COUNT(*) FROM t1 LOCK IN SHARE MODE; + +connection con2; +SET AUTOCOMMIT=1; +# Test if non-locking autocommit selects end up in the trx_sys_t::trx_list. +# We check this via the INFORMATION_SCHEMA.INNODB_TRX. +# This should not block and should not show up in the I_S. +--send +SELECT COUNT(*) FROM t1; + +connection con3; +SET AUTOCOMMIT=1; +# Note: autocommit non-locking selects are not converted to locking selects +# Therefore this should not block; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +--send +SELECT COUNT(*) FROM t1; + +connection con4; +SET AUTOCOMMIT=0; +# Note: Non-locking selects are converted to locking selects +# therefore this should block; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +SET DEBUG_SYNC='now WAIT_FOR waiting1'; +SET DEBUG_SYNC='lock_wait_start SIGNAL waiting4'; +--send +SELECT COUNT(*) FROM t1 WHERE c1 >= 0; + +connection con5; +SET AUTOCOMMIT=1; +# This should not block +BEGIN; +--send +SELECT COUNT(*) FROM t1; + +connection con6; +SET AUTOCOMMIT=1; +# This will ignore the auto-commit setting but wont block because it is +# a non-locking select. +XA START '1'; +--enable_query_log +SELECT * FROM t1 WHERE c1 <= 3; + +connection default; +# Wait for SELECTs to get into the lock wait queue +SET DEBUG_SYNC='now WAIT_FOR waiting4'; +SET DEBUG_SYNC= 'RESET'; + +# Check the number of non-locking transactions +let $wait_condition = + SELECT COUNT(*) = 5 + FROM INFORMATION_SCHEMA.INNODB_TRX + WHERE trx_autocommit_non_locking = 0; +--source include/wait_condition.inc + +# Check the waiting transactions +SELECT trx_state, trx_query, trx_autocommit_non_locking +FROM INFORMATION_SCHEMA.INNODB_TRX +WHERE trx_state = 'LOCK WAIT' +ORDER BY trx_query; + +INSERT INTO t1 VALUES(4, '4'); +COMMIT; + +connection con6; +SELECT * FROM t1 WHERE c1 <= 4; +XA END '1'; +XA PREPARE '1'; +XA ROLLBACK '1'; +disconnect con6; +disconnect con2; +disconnect con3; +disconnect con5; + +connection con1; +reap; +disconnect con1; + +connection con4; +reap; +disconnect con4; + +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-alter.test b/mysql-test/suite/innodb/t/innodb-alter.test index 60af7c9df80..f5b26905c7c 100644 --- a/mysql-test/suite/innodb/t/innodb-alter.test +++ b/mysql-test/suite/innodb/t/innodb-alter.test @@ -701,6 +701,32 @@ ALTER TABLE t1 ADD COLUMN b DATETIME NOT NULL, LOCK=NONE; SET @@SQL_MODE= @OLD_SQL_MODE; DROP TABLE t1; +--echo # +--echo # Bug#20977779 CANNOT IMPORT TABLES CONTAINING PREFIX INDEXES +--echo # + +CREATE TABLE t1 (c1 VARCHAR(32), c2 VARCHAR(32), c3 VARCHAR(32), +PRIMARY KEY (c1, c2, c3)) +ENGINE=InnoDB; + +ALTER TABLE t1 ADD INDEX ind1(c1(5), c2, c3); +ALTER TABLE t1 ADD INDEX ind2(c3, c1(10), c2); +ALTER TABLE t1 ADD INDEX ind3(c2, c3, c1(20)); + +INSERT INTO t1 VALUES ('Test Data -1', 'Test Data -2', 'Test Data -3'); + +let $source_db = test; +let $dest_db = test; + +--echo # Test with 2ndary index having prefix +--source suite/innodb/include/import.inc + +--echo # Test with PK & 2ndary index with prefix +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1(5), c2(10), c3(20)); +--source suite/innodb/include/import.inc + +DROP TABLE t1; + # # End of 10.2 tests # diff --git a/mysql-test/suite/innodb/t/innodb-index-online-fk.test b/mysql-test/suite/innodb/t/innodb-index-online-fk.test index 5c8954064ce..00333db0d8f 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online-fk.test +++ b/mysql-test/suite/innodb/t/innodb-index-online-fk.test @@ -482,3 +482,48 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; DROP TABLE t2; DROP TABLE t3; + +--echo # Bug #17449901 TABLE DISAPPEARS WHEN ALTERING +--echo # WITH FOREIGN KEY CHECKS OFF + +# Drop index via inplace algorithm +create table t1(f1 int,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int,key t(f2,f3),foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks=0; +drop index t on t2; +drop table t2; +drop table t1; + +# Drop index using alter statement via inplace +create table t1(f1 int ,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int, key t(f2),foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks = 0; +alter table t2 drop key t,algorithm=inplace; +show create table t2; +drop table t2; +drop table t1; + +create table t1(f1 int ,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int, key t(f2),key t1(f2,f3), +foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks = 0; +alter table t2 drop key t,algorithm=inplace; +show create table t2; +drop table t2; +drop table t1; + +--echo # +--echo # MDEV-29092 FOREIGN_KEY_CHECKS does not prevent non-copy +--echo # alter from creating invalid FK structures +--echo # +CREATE TABLE t1(f1 INT, KEY(f1), + FOREIGN KEY(f1) references t1(f1))ENGINE=InnoDB; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT, KEY(f1), + FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=InnoDB; +SHOW CREATE TABLE t1; +ALTER TABLE t1 DROP KEY f1; +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test b/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test new file mode 100644 index 00000000000..31bf8a73d8d --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test @@ -0,0 +1,110 @@ +--echo # +--echo # Bug #21025880 DUPLICATE UK VALUES IN READ-COMMITTED(AGAIN) +--echo # + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +let $i=0; + +while ($i <=1 ) +{ + +CREATE TABLE t1 ( + a INT NOT NULL, + b INT NOT NULL, + PRIMARY KEY(b), + UNIQUE KEY(a)) +ENGINE=INNODB; + +SET @old_innodb_stats_auto_recalc = @@innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc = OFF; + +# Block purge +connect purge_control,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; + +SET @old_tx_isolation = @@tx_isolation; +SET GLOBAL tx_isolation = 'READ-COMMITTED'; + +SET @old_innodb_lock_wait_timeout = @@innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout = 1; + +--connect(con1,localhost,root,,) + +# Create and delete-mark an index record + +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1; + +SET debug_sync = 'row_ins_sec_index_entry_dup_locks_created SIGNAL +con1_locks_done WAIT_FOR con1_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock SIGNAL +con1_insert_done WAIT_FOR con1_finish'; +--send + +if ($i == 0) +{ +REPLACE INTO t1 VALUES (1,2); +} + +if ( $i == 1) +{ +INSERT INTO t1 values (1,2) ON DUPLICATE KEY UPDATE a=2; +} +--connect(con2,localhost,root,,) + +SET debug_sync = 'now WAIT_FOR con1_locks_done'; + +SET debug_sync = 'lock_wait_start SIGNAL con2_blocked +WAIT_FOR con2_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock +WAIT_FOR con2_finish'; +SET debug_sync = 'ib_after_row_insert SIGNAL con2_insert_done'; + +--send +REPLACE INTO t1 VALUES (1,3); + +--connection default +SET debug_sync = 'now WAIT_FOR con2_blocked'; + +connection purge_control; +COMMIT; +disconnect purge_control; +connection default; + +# Wait for purge to delete the delete-marked record +--source ../../innodb/include/wait_all_purged.inc + +SET debug_sync = 'now SIGNAL con2_go WAIT_FOR con2_insert_done'; +SET debug_sync = 'now SIGNAL con1_go WAIT_FOR con1_insert_done'; + +SET debug_sync = 'now SIGNAL con1_finish'; + +--connection con1 +--reap +--disconnect con1 +--connection default +SET debug_sync = 'now SIGNAL con2_finish'; + +--connection con2 +--error 0,ER_LOCK_WAIT_TIMEOUT +--reap +--disconnect con2 + +--connection default +SET DEBUG_SYNC= 'RESET'; + +SELECT * FROM t1; +CHECK TABLE t1; + +DROP TABLE t1; + +SET GLOBAL innodb_stats_auto_recalc = @old_innodb_stats_auto_recalc; +SET GLOBAL tx_isolation = @old_tx_isolation; +SET GLOBAL innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; + +--inc $i +} diff --git a/mysql-test/suite/innodb/t/innodb-read-view.test b/mysql-test/suite/innodb/t/innodb-read-view.test index 425cbeb08c8..21c79cf6566 100644 --- a/mysql-test/suite/innodb/t/innodb-read-view.test +++ b/mysql-test/suite/innodb/t/innodb-read-view.test @@ -1,7 +1,6 @@ # DEBUG_SYNC must be compiled in. --source include/have_debug_sync.inc --source include/have_debug.inc - # We need to test the use case: # a. Create a transaction T1 that will be promoted to RW. # b. Create a transaction T2 that will be promoted to RW. @@ -27,22 +26,16 @@ INSERT INTO t2 VALUES(2, "c"); INSERT INTO t2 VALUES(3, "d"); --connect (con1,localhost,root,,) ---connect (con2,localhost,root,,) - -connection con1; ---echo 'T1' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t2; connection default; ---echo 'T2' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t1; -connection con2; ---echo 'T3' +--connect (con2,localhost,root,,) SET AUTOCOMMIT=0; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; @@ -50,48 +43,36 @@ SELECT * FROM t1; SELECT * FROM t2; connection con1; ---echo 'T1' UPDATE t2 SET c1 = c1 + 100; SELECT * FROM t2; COMMIT; connection default; ---echo 'T2' UPDATE t1 SET c1 = c1 + 100; SELECT * FROM t1; COMMIT; connection con2; ---echo 'T3' SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; --send SELECT * FROM t1; connection default; ---echo 'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; ---echo 'Signalled T3' connection con2; ---echo 'T3' reap; connection con2; ---echo 'T3' SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; --send SELECT * FROM t2; connection default; ---echo 'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; ---echo 'Signalled T3' connection con2; ---echo 'T3' reap; connection default; -disconnect con1; -disconnect con2; # We need to test the use case: # a. Create a transaction T1 that will be promoted to RW. @@ -105,17 +86,12 @@ disconnect con2; # i. T3 Does a select - it should not see the changes made by T1 but should # see the changes by T2 ---connect (con1,localhost,root,,) ---connect (con2,localhost,root,,) - connection con1; ---echo 'T1' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t1; connection default; ---echo 'T2' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t2; @@ -124,7 +100,6 @@ SELECT * FROM t2; COMMIT; connection con2; ---echo 'T3' SET AUTOCOMMIT=0; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; @@ -132,42 +107,30 @@ SELECT * FROM t1; SELECT * FROM t2; connection con1; ---echo 'T1' UPDATE t1 SET c1 = c1 + 100; SELECT * FROM t1; COMMIT; connection con2; ---echo 'T3' SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; --send SELECT * FROM t1; connection con1; ---echo 'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; ---echo 'Signalled T3' connection con2; ---echo 'T3' reap; - -connection con2; ---echo 'T3' SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; --send SELECT * FROM t2; connection default; ---echo 'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; ---echo 'Signalled T3' connection con2; ---echo 'T3' reap; +disconnect con2; connection default; -disconnect con1; -disconnect con2; DROP TABLE t1; DROP TABLE t2; @@ -176,8 +139,7 @@ DROP TABLE t2; --echo # Bug 21433768: NON-REPEATABLE READ WITH REPEATABLE READ ISOLATION --echo # ---connect (con1,localhost,root,,) - +connection con1; CREATE TABLE t1(col1 INT PRIMARY KEY, col2 INT) ENGINE = InnoDB; INSERT INTO t1 values (1, 0), (2, 0); SELECT * FROM t1 ORDER BY col1; @@ -200,9 +162,7 @@ reap; disconnect con1; connection default; - +SET DEBUG_SYNC= 'RESET'; DROP TABLE t1; -# Clean up resources used in this test case. -SET DEBUG_SYNC= 'RESET'; --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test index 551b71c4883..798cefd0c25 100644 --- a/mysql-test/suite/innodb/t/innodb-table-online.test +++ b/mysql-test/suite/innodb/t/innodb-table-online.test @@ -4,6 +4,10 @@ --source include/have_debug_sync.inc --source include/have_sequence.inc +SET GLOBAL innodb_monitor_reset_all=all; +--disable_warnings +SET GLOBAL innodb_monitor_reset_all=default; +--enable_warnings let $innodb_metrics_select= SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl'; @@ -171,13 +175,13 @@ EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3; ANALYZE TABLE t1; SET @merge_encrypt_0= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted'); SET @merge_decrypt_0= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted'); SET @rowlog_encrypt_0= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); connection con1; @@ -215,13 +219,13 @@ while ($c) eval $innodb_metrics_select; SET @merge_encrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted'); SET @merge_decrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted'); SET @rowlog_encrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); SELECT @@ -243,16 +247,16 @@ reap; eval $innodb_metrics_select; SET @merge_encrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted'); SET @merge_decrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted'); SET @rowlog_encrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); SET @rowlog_decrypt_1= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted'); SET GLOBAL innodb_max_purge_lag_wait=0; @@ -287,16 +291,16 @@ SELECT COUNT(c22f) FROM t1; CHECK TABLE t1; SET @merge_encrypt_2= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted'); SET @merge_decrypt_2= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted'); SET @rowlog_encrypt_2= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); SET @rowlog_decrypt_2= -(SELECT variable_value FROM information_schema.global_status +(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted'); SELECT diff --git a/mysql-test/suite/innodb/t/innodb-truncate.test b/mysql-test/suite/innodb/t/innodb-truncate.test index 4d39fcaef6d..cbd6139fbf3 100644 --- a/mysql-test/suite/innodb/t/innodb-truncate.test +++ b/mysql-test/suite/innodb/t/innodb-truncate.test @@ -85,13 +85,11 @@ SET FOREIGN_KEY_CHECKS= ON; CREATE TABLE t2 (f2 INT, FOREIGN KEY(f2) REFERENCES t1 (f2)) ENGINE=InnoDB; --error ER_CANT_CREATE_TABLE CREATE TABLE t3 (a INT) ENGINE=InnoDB; ---replace_result $datadir ./ ---error ER_ERROR_ON_RENAME ALTER TABLE t1 RENAME TO t3; -ALTER TABLE t1 FORCE; +ALTER TABLE t3 FORCE; --error ER_TRUNCATE_ILLEGAL_FK -TRUNCATE TABLE t1; -DROP TABLE t2, t1; +TRUNCATE TABLE t3; +DROP TABLE t2, t3; --echo # --echo # MDEV-24861 Assertion `trx->rsegs.m_redo.rseg' failed diff --git a/mysql-test/suite/innodb/t/innodb_bug12902967.test b/mysql-test/suite/innodb/t/innodb_bug12902967.test deleted file mode 100644 index 5bd32cdf627..00000000000 --- a/mysql-test/suite/innodb/t/innodb_bug12902967.test +++ /dev/null @@ -1,25 +0,0 @@ -# Bug 12902967: Creating self referencing fk on same index unhandled, -# confusing error -# -# Creating a self referencing foreign key on the same -# column/index is an unhandled exception, it should throw a sensible -# error but instead implies that your data dictionary may now be out -# of sync: - ---source include/have_innodb.inc ---source include/not_embedded.inc - -call mtr.add_suppression("In ALTER TABLE .* has or is referenced in foreign key constraints which are not compatible with the new table definition."); - -let error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err; ---source include/restart_mysqld.inc - -create table t1 (f1 integer primary key) engine innodb; - -# The below statement should produce error message in error log. -# This error message should mention problem with foreign keys -# rather than with data dictionary. ---replace_regex /'\.\/test\/#sql-alter-[0-9a-f_\-]*'/'#sql-alter'/ ---error ER_ERROR_ON_RENAME -alter table t1 add constraint c1 foreign key (f1) references t1(f1); -drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test b/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test new file mode 100644 index 00000000000..e6e46dbf556 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test @@ -0,0 +1,169 @@ +# +# Test that user data is correctly "visualized" in +# INFORMATION_SCHEMA.innodb_locks.lock_data +# + +-- source include/have_innodb.inc + +SET @save_timeout=@@GLOBAL.innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout=100000000; + +let $table_def = +( + c01 TINYINT, + c02 TINYINT UNSIGNED, + c03 SMALLINT, + c04 SMALLINT UNSIGNED, + c05 MEDIUMINT, + c06 MEDIUMINT UNSIGNED, + c07 INT, + c08 INT UNSIGNED, + c09 BIGINT, + c10 BIGINT UNSIGNED, + PRIMARY KEY(c01, c02, c03, c04, c05, c06, c07, c08, c09, c10) +) ENGINE=INNODB; + +-- eval CREATE TABLE t_min $table_def; +INSERT INTO t_min VALUES +(-128, 0, + -32768, 0, + -8388608, 0, + -2147483648, 0, + -9223372036854775808, 0); + +-- eval CREATE TABLE t_max $table_def; +INSERT INTO t_max VALUES +(127, 255, + 32767, 65535, + 8388607, 16777215, + 2147483647, 4294967295, + 9223372036854775807, 18446744073709551615); + +CREATE TABLE ```t'\"_str` ( + c1 VARCHAR(32), + c2 VARCHAR(32), + c3 VARCHAR(32), + c4 VARCHAR(32), + c5 VARCHAR(32), + c6 VARCHAR(32), + c7 VARCHAR(32), + PRIMARY KEY(c1, c2, c3, c4, c5, c6, c7) +) ENGINE=INNODB; +INSERT INTO ```t'\"_str` VALUES +('1', 'abc', '''abc', 'abc''', 'a''bc', 'a''bc''', '''abc'''''); +INSERT INTO ```t'\"_str` VALUES +('2', 'abc', '"abc', 'abc"', 'a"bc', 'a"bc"', '"abc""'); +INSERT INTO ```t'\"_str` VALUES +('3', 'abc', '\\abc', 'abc\\', 'a\\bc', 'a\\bc\\', '\\abc\\\\'); +INSERT INTO ```t'\"_str` VALUES +('4', 'abc', 0x00616263, 0x61626300, 0x61006263, 0x6100626300, 0x610062630000); + +-- source include/count_sessions.inc + +-- connect (con_lock,localhost,root,,) +-- connect (con_min_trylock,localhost,root,,) +-- connect (con_max_trylock,localhost,root,,) +-- connect (con_str_insert_supremum,localhost,root,,) +-- connect (con_str_lock_row1,localhost,root,,) +-- connect (con_str_lock_row2,localhost,root,,) +-- connect (con_str_lock_row3,localhost,root,,) +-- connect (con_str_lock_row4,localhost,root,,) +-- connect (con_verify_innodb_locks,localhost,root,,) + +-- connection con_lock +SET autocommit=0; +SELECT * FROM t_min FOR UPDATE; +SELECT * FROM t_max FOR UPDATE; +SELECT * FROM ```t'\"_str` FOR UPDATE; + +-- connection con_min_trylock +-- send +SELECT * FROM t_min FOR UPDATE; + +-- connection con_max_trylock +-- send +SELECT * FROM t_max FOR UPDATE; + +-- connection con_str_insert_supremum +-- send +INSERT INTO ```t'\"_str` VALUES +('z', 'z', 'z', 'z', 'z', 'z', 'z'); + +-- connection con_str_lock_row1 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '1' FOR UPDATE; + +-- connection con_str_lock_row2 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '2' FOR UPDATE; + +-- connection con_str_lock_row3 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '3' FOR UPDATE; + +-- connection con_str_lock_row4 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE; + +-- connection con_verify_innodb_locks +# Wait for the above queries to execute before continuing. +# Without this, it sometimes happens that the SELECT from innodb_locks +# executes before some of them, resulting in less than expected number +# of rows being selected from innodb_locks. If there is a bug and there +# are no 14 rows in innodb_locks then this test will fail with timeout. +# Notice that if we query INNODB_LOCKS more often than once per 0.1 sec +# then its contents will never change because the cache from which it is +# filled is updated only if it has not been read for 0.1 seconds. See +# CACHE_MIN_IDLE_TIME_US in trx/trx0i_s.c. +let $cnt=10; +while ($cnt) +{ + let $success=`SELECT COUNT(*) = 14 FROM INFORMATION_SCHEMA.INNODB_LOCKS`; + if ($success) + { + let $cnt=0; + } + if (!$success) + { + real_sleep 0.2; + dec $cnt; + } +} +if (!$success) +{ + -- echo Timeout waiting for rows in INNODB_LOCKS to appear +} + +SELECT lock_mode, lock_type, lock_table, lock_index, lock_rec, lock_data +FROM INFORMATION_SCHEMA.INNODB_LOCKS ORDER BY lock_data; + +SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS +GROUP BY lock_table; + +set @save_sql_mode = @@sql_mode; +SET SQL_MODE='ANSI_QUOTES'; +SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS +GROUP BY lock_table; +SET @@sql_mode=@save_sql_mode; + +# Release all the locks; +-- connection con_lock +COMMIT; + +-- connection default + +-- disconnect con_lock +-- disconnect con_min_trylock +-- disconnect con_max_trylock +-- disconnect con_str_insert_supremum +-- disconnect con_str_lock_row1 +-- disconnect con_str_lock_row2 +-- disconnect con_str_lock_row3 +-- disconnect con_str_lock_row4 +-- disconnect con_verify_innodb_locks + +DROP TABLE t_min, t_max, ```t'\"_str`; + +-- source include/wait_until_count_sessions.inc + +SET GLOBAL innodb_lock_wait_timeout=@save_timeout; diff --git a/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test b/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test new file mode 100644 index 00000000000..745e1d94a12 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test @@ -0,0 +1,95 @@ +--source include/have_innodb.inc + +# +# Test that transaction data is correctly "visualized" in +# INFORMATION_SCHEMA.INNODB_TRX +# + +SET @save_timeout=@@GLOBAL.innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout=100000000; + +DESCRIBE INFORMATION_SCHEMA.INNODB_TRX; + +CREATE TABLE t1 ( + c01 INT, + c02 INT, + PRIMARY KEY (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; + +INSERT INTO t1 VALUES +(1,2),(2,4),(3,6),(4,8); + +CREATE TABLE t2 ( + c01 INT, + c02 INT, + PRIMARY KEY (c01), + FOREIGN KEY fk1 (c02) REFERENCES t1 (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; + +INSERT INTO t2 VALUES +(1,1),(2,2),(3,3); + +-- source include/count_sessions.inc + +-- connect (con_trx,localhost,root,,) +-- connect (con_verify_innodb_trx,localhost,root,,) + +-- connection con_trx +SET autocommit=0; +INSERT INTO t1 VALUES (5,10); +SELECT * FROM t1 FOR UPDATE; + +let $wait_timeout= 300; +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; +-- source include/wait_condition.inc + +-- connection con_verify_innodb_trx +SELECT trx_state, trx_weight, trx_tables_in_use, trx_tables_locked, +trx_rows_locked, trx_rows_modified, trx_concurrency_tickets, +trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; + +-- connection con_trx +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 0; +SET UNIQUE_CHECKS = 0; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; +INSERT INTO t1 VALUES (6,12); + +let $wait_timeout= 300; +let $wait_condition= + SELECT trx_unique_checks = 0 FROM INFORMATION_SCHEMA.INNODB_TRX; +-- source include/wait_condition.inc + +-- connection con_verify_innodb_trx +SELECT trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; + +-- connection con_trx +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 1; +SET UNIQUE_CHECKS = 1; +BEGIN; +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2 VALUES (4,10); + +let $wait_timeout= 300; +let $wait_condition= + SELECT trx_unique_checks = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; +-- source include/wait_condition.inc +-- disconnect con_trx + +-- connection con_verify_innodb_trx +SELECT trx_state, trx_isolation_level, trx_last_foreign_key_error +FROM INFORMATION_SCHEMA.INNODB_TRX; +-- disconnect con_verify_innodb_trx + +-- connection default +DROP TABLE t2; +DROP TABLE t1; + +-- source include/wait_until_count_sessions.inc + +SET GLOBAL innodb_lock_wait_timeout=@save_timeout; diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt index 4edc71b6217..101f6eaed99 100644 --- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt +++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt @@ -26,3 +26,4 @@ --loose-innodb_buffer_pool_pages --loose-innodb_buffer_pool_pages_index --loose-innodb_buffer_pool_pages_blob +--innodb-open-files=1000000 diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test index 15b3bf4f561..c62705da84b 100644 --- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test +++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test @@ -1,6 +1,10 @@ -- source include/have_innodb.inc -- source include/not_embedded.inc +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_PATTERN= \[Warning\] InnoDB: innodb_open_files 1000000 should not be greater than the open_files_limit [0-9]+; +--source include/search_pattern_in_file.inc + # # MDEV-7762 InnoDB: Failing assertion: block->page.buf_fix_count > 0 in buf0buf.ic line 730 # diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test new file mode 100644 index 00000000000..e441a795540 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test @@ -0,0 +1,48 @@ +# +# Test the persistent stats auto recalc +# + +-- source include/have_innodb.inc +# Page numbers printed by this test depend on the page size +-- source include/have_innodb_16k.inc + +-- vertical_results + +-- let $check_stats1 = SELECT n_rows, clustered_index_size FROM mysql.innodb_table_stats WHERE table_name = 'autorecalc' +-- let $check_stats2 = SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc' + +CREATE TABLE autorecalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +INSERT INTO autorecalc VALUES (1); +INSERT INTO autorecalc VALUES (2); + +# wait for the bg stats thread to update the stats, notice we wait on +# innodb_index_stats because innodb_table_stats gets updated first and +# it is possible that (if we wait on innodb_table_stats) the wait cond +# gets satisfied before innodb_index_stats is updated +let $wait_condition = SELECT stat_value = 2 FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +# the second INSERT from above should have triggered an auto-recalc +-- eval $check_stats1 +-- eval $check_stats2 + +# now DELETE the rows and trigger a second auto-recalc, InnoDB may wait a +# few seconds before triggering an auto-recalc again (it tries not to be too +# aggressive) + +DELETE FROM autorecalc; + +let $wait_timeout = 25; +let $wait_condition = SELECT stat_value = 0 FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +# the DELETE from above should have triggered an auto-recalc +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE autorecalc; diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test new file mode 100644 index 00000000000..aeb5b5c291e --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test @@ -0,0 +1,49 @@ +# +# Test the persistent stats auto recalc during DDL +# + +-- source include/have_innodb.inc + +-- vertical_results + +-- let $check_stats1 = SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'arddl' ORDER BY 1 +-- let $check_stats2 = SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' ORDER BY 1, 2, 3 + +# Test ADD INDEX during background stats gathering + +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a)) ENGINE=INNODB; + +INSERT INTO arddl VALUES (1, 10); +INSERT INTO arddl VALUES (2, 10); + +ALTER TABLE arddl ADD INDEX (b); + +# wait for the bg stats thread to update the stats, notice we wait on +# innodb_index_stats because innodb_table_stats gets updated first and +# it is possible that (if we wait on innodb_table_stats) the wait cond +# gets satisfied before innodb_index_stats is updated +let $wait_condition = SELECT stat_value = 2 FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +# the second INSERT from above should have triggered an auto-recalc +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE arddl; + +# Test DROP INDEX during background stats gathering + +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a), KEY (b)) ENGINE=INNODB; + +INSERT INTO arddl VALUES (3, 10); +INSERT INTO arddl VALUES (4, 10); + +ALTER TABLE arddl DROP INDEX b; + +let $wait_condition = SELECT stat_value = 2 FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE arddl; diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test new file mode 100644 index 00000000000..88ca8910cd2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test @@ -0,0 +1,45 @@ +# +# Test the persistent stats auto recalc on lots of tables +# + +--source include/no_valgrind_without_big.inc +-- source include/have_innodb.inc + +let $check_stats = SELECT table_name, n_rows FROM mysql.innodb_table_stats WHERE table_name LIKE 'ar_%' ORDER BY table_name; + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval CREATE TABLE ar_$i (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + dec $i; +} +-- enable_query_log + +# the CREATEs above should have inserted zeroed stats +-- eval $check_stats + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval INSERT INTO ar_$i VALUES (1), (2); + dec $i; +} +-- enable_query_log + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval INSERT INTO ar_$i VALUES (3), (4); + dec $i; +} +-- enable_query_log + +# would be too long to wait for stats to become up to date here + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval DROP TABLE ar_$i; + dec $i; +} +-- enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test new file mode 100644 index 00000000000..4cd910071e8 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test @@ -0,0 +1,88 @@ +# +# Test the persistent stats auto recalc when persistent stats do not exist +# + +-- source include/have_innodb.inc + +-- vertical_results + +-- let $check_stats1 = SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't' +-- let $check_stats2 = SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't' + +-- echo Test with default setting + +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +# open and close the table +SELECT * FROM t; +FLUSH TABLE t; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; + +-- eval $check_stats1 +-- eval $check_stats2 + +# open the table, causing stats recalc/save +SELECT * FROM t; + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE t; + +-- echo Test with explicit enable + +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=1; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +# open and close the table +SELECT * FROM t; +FLUSH TABLE t; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; + +-- eval $check_stats1 +-- eval $check_stats2 + +# open the table, causing stats recalc/save +SELECT * FROM t; + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE t; + +-- echo Test with explicit disable + +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=0; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +# open and close the table +SELECT * FROM t; +FLUSH TABLE t; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; + +-- eval $check_stats1 +-- eval $check_stats2 + +# open the table, stats should not be present, since autorecalc is disabled +SELECT * FROM t; + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/innodb_stats_external_pages.test b/mysql-test/suite/innodb/t/innodb_stats_external_pages.test new file mode 100644 index 00000000000..da0dce9a454 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_external_pages.test @@ -0,0 +1,79 @@ +# +# Bug#18384390 WRONG STATISTICS WITH BIG ROW LENGTH AND PERSISTENT STATS +# + +--source include/have_innodb.inc +--source include/have_innodb_max_16k.inc +--source include/have_sequence.inc + +CREATE TABLE bug18384390 ( + id INT AUTO_INCREMENT PRIMARY KEY, + txt VARCHAR(10000) +) ENGINE=INNODB STATS_PERSISTENT=1 STATS_AUTO_RECALC=0; + +let $count=1024; +eval +INSERT INTO bug18384390 (txt) SELECT REPEAT('0', 10000) FROM seq_1_to_$count; + +set use_stat_tables=never; +ANALYZE TABLE bug18384390; + +-- let $n_rows = `SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'bug18384390'` + +-- let $table_rows = `SELECT table_rows FROM information_schema.tables WHERE table_name = 'bug18384390'` + +-- let $n_diff = `SELECT stat_value FROM mysql.innodb_index_stats WHERE table_name = 'bug18384390' AND stat_name = 'n_diff_pfx01'` + +-- let $cardinality = `SELECT cardinality FROM information_schema.statistics WHERE table_name = 'bug18384390'` + +-- let $margin_of_err_pct = 30 +-- let $margin_of_err_rows = `SELECT ROUND($count * $margin_of_err_pct / 100)` + +-- let $min_allowed = `SELECT $count - $margin_of_err_rows` +-- let $max_allowed = `SELECT $count + $margin_of_err_rows` + +-- let $dump_sql = SELECT COUNT(*) FROM bug18384390; SELECT * FROM mysql.innodb_table_stats; SELECT * FROM mysql.innodb_index_stats; SELECT * FROM information_schema.tables WHERE table_name = 'bug18384390'; SELECT * FROM information_schema.statistics WHERE table_name = 'bug18384390'; + +-- vertical_results + +if ($n_rows < $min_allowed) { + -- echo mysql.innodb_table_stats.n_rows is too small ($n_rows < $min_allowed) + -- eval $dump_sql +} + +if ($n_rows > $max_allowed) { + -- echo mysql.innodb_table_stats.n_rows is too big ($n_rows > $max_allowed) + -- eval $dump_sql +} + +if ($table_rows < $min_allowed) { + -- echo information_schema.tables.table_rows is too small ($table_rows < $min_allowed) + -- eval $dump_sql +} + +if ($table_rows > $max_allowed) { + -- echo information_schema.tables.table_rows is too big ($table_rows > $max_allowed) + -- eval $dump_sql +} + +if ($n_diff < $min_allowed) { + -- echo mysql.innodb_index_stats.stat_value is too small ($n_diff < $min_allowed) + -- eval $dump_sql +} + +if ($n_diff > $max_allowed) { + -- echo mysql.innodb_index_stats.stat_value is too big ($n_diff > $max_allowed) + -- eval $dump_sql +} + +if ($cardinality < $min_allowed) { + -- echo information_schema.statistics.cardinality is too small ($cardinality < $min_allowed) + -- eval $dump_sql +} + +if ($cardinality > $max_allowed) { + -- echo information_schema.statistics.cardinality is too big ($cardinality > $max_allowed) + -- eval $dump_sql +} + +DROP TABLE bug18384390; diff --git a/mysql-test/suite/innodb/t/innodb_stats_fetch.opt b/mysql-test/suite/innodb/t/innodb_stats_fetch.opt new file mode 100644 index 00000000000..faa681c8dd7 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_fetch.opt @@ -0,0 +1,7 @@ +--innodb_sys_tables +--innodb_sys_indexes +--innodb_sys_virtual +--innodb_sys_foreign +--innodb_sys_foreign_cols +--innodb_sys_tablestats +--innodb_sys_tablespaces diff --git a/mysql-test/suite/innodb/t/innodb_stats_fetch.test b/mysql-test/suite/innodb/t/innodb_stats_fetch.test index 549ad65feff..99fc115af1d 100644 --- a/mysql-test/suite/innodb/t/innodb_stats_fetch.test +++ b/mysql-test/suite/innodb/t/innodb_stats_fetch.test @@ -81,3 +81,18 @@ FROM information_schema.tables WHERE table_name = 'test_ps_fetch'; DROP TABLE test_ps_fetch; set @@use_stat_tables = @save_use_stat_tables; + +--echo # +--echo # MDEV-28613 LeakSanitizer caused by I_S query using LIMIT ROWS EXAMINED +--echo # +CREATE TABLE t1(f1 VARCHAR(255), FULLTEXT(f1))ENGINE=InnoDB; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES LIMIT ROWS EXAMINED 5; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES LIMIT ROWS EXAMINED 5; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS LIMIT ROWS EXAMINED 5; +--disable_result_log +SELECT SPACE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES LIMIT ROWS EXAMINED 5; +--enable_result_log +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL LIMIT ROWS EXAMINED 5; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN LIMIT ROWS EXAMINED 5; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS LIMIT ROWS EXAMINED 5; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations b/mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations new file mode 100644 index 00000000000..561eb72d9a9 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations @@ -0,0 +1,4 @@ +[on] +--innodb-stats-persistent=1 +[off] +--innodb-stats-persistent=0 diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global.test b/mysql-test/suite/innodb/t/innodb_stats_flag_global.test new file mode 100644 index 00000000000..88f0ed7c16d --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global.test @@ -0,0 +1,91 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc + +# +-- echo ===== +-- echo === Test ANALYZE behavior after default creation +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=default; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +# +-- echo ===== +-- echo === Test ANALYZE behavior after creation with explicit PS=OFF +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +# +-- echo ===== +-- echo === Test ANALYZE behavior after creation with explicit PS=ON +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +# +-- echo ===== +-- echo === Test ANALYZE behavior after creation with explicit PS=OFF, +-- echo === then ALTER to ON, then ALTER to OFF, then ALTER to default +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0; + +ALTER TABLE test_ps_flag STATS_PERSISTENT=1; + +# also check that the change from the ALTER TABLE survives server restart +-- source include/restart_mysqld.inc + +-- source innodb_stats_flag_global_analyze.inc + +ALTER TABLE test_ps_flag STATS_PERSISTENT=0; + +-- source innodb_stats_flag_global_analyze.inc + +ALTER TABLE test_ps_flag STATS_PERSISTENT=default; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +# +-- echo ===== +-- echo === Test ANALYZE behavior after creation with explicit PS=ON, +-- echo === then ALTER to OFF, then ALTER to ON, then ALTER to default +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1; + +ALTER TABLE test_ps_flag STATS_PERSISTENT=0; + +# also check that the change from the ALTER TABLE survives server restart +-- source include/restart_mysqld.inc + +-- source innodb_stats_flag_global_analyze.inc + +ALTER TABLE test_ps_flag STATS_PERSISTENT=1; + +-- source innodb_stats_flag_global_analyze.inc + +ALTER TABLE test_ps_flag STATS_PERSISTENT=default; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc b/mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc new file mode 100644 index 00000000000..8a68677e8ee --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc @@ -0,0 +1,13 @@ +SHOW CREATE TABLE test_ps_flag; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + +# must be 0, we have just deleted the rows +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; + +# if the table is PS enabled, then this should be 1 and 0 otherwise +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; diff --git a/mysql-test/suite/innodb/t/innodb_stats_persistent.test b/mysql-test/suite/innodb/t/innodb_stats_persistent.test index b923b49637e..294f283b259 100644 --- a/mysql-test/suite/innodb/t/innodb_stats_persistent.test +++ b/mysql-test/suite/innodb/t/innodb_stats_persistent.test @@ -13,6 +13,7 @@ ENGINE=INNODB STATS_PERSISTENT=1,STATS_AUTO_RECALC=1; CREATE TABLE t2 LIKE t1; INSERT INTO t1 (val) SELECT 4 FROM seq_1_to_16; +SET STATEMENT use_stat_tables=never FOR ANALYZE TABLE t1; connect(con1, localhost, root,,); @@ -82,3 +83,41 @@ DROP TABLE t1,t2; SET GLOBAL innodb_stats_include_delete_marked = @saved_include_delete_marked; SET GLOBAL innodb_stats_traditional = @saved_traditional; SET GLOBAL innodb_stats_modified_counter = @saved_modified_counter; + +# +# Bug#12429573 TIMESTAMP COLUMN OF INNODB.INDEX_STATS ARE NOT UPDATED +# WHEN RE-RUNNING ANALYZE +# +CREATE TABLE bug12429573 (i INTEGER PRIMARY KEY, j INTEGER, KEY(j)) +ENGINE=INNODB STATS_PERSISTENT=1; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE bug12429573; + +# Cannot check the exact timestamp here because it is always different +# but at least check that both timestamps in innodb_table_stats and in +# innodb_index_stats have been updated to the same value. If the bug is +# present this check will fail. + +SELECT last_update INTO @last FROM mysql.innodb_table_stats +WHERE table_name = 'bug12429573'; +SELECT * FROM mysql.innodb_index_stats +WHERE table_name = 'bug12429573' AND last_update!=@last; + +# The first ANALYZE would insert timestamp e.g. 17:23:39 in both +# innodb_table_stats and innodb_index_stats. The bug is that the second +# ANALYZE only updates the timestamp in innodb_table_stats. In order to +# check if the timestamp in innodb_index_stats has really been updated we +# need it to be different from the previous one (17:23:39) with at least +# one second. +-- sleep 1 + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE bug12429573; + +SELECT * FROM mysql.innodb_table_stats +WHERE table_name = 'bug12429573' AND last_update=@last; +SELECT * FROM mysql.innodb_index_stats +WHERE table_name = 'bug12429573' AND last_update=@last; + +DROP TABLE bug12429573; diff --git a/mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_sample_pages.test b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.test new file mode 100644 index 00000000000..1aac71a0450 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.test @@ -0,0 +1,53 @@ +# +# Test that the table option STATS_SAMPLE_PAGES=N|default is indeed +# used by InnoDB +# + +-- source include/have_innodb.inc +# Page numbers printed by this test depend on the page size +-- source include/have_innodb_16k.inc + +SET GLOBAL innodb_stats_persistent_sample_pages=17; + +CREATE TABLE test_ps_sample_pages_used ( + a VARCHAR(512), PRIMARY KEY (a) +) ENGINE=INNODB STATS_SAMPLE_PAGES=default; + +# Insert enough records into the table so that it has more than 2*17+1 pages +# If we ask to scan more than the half of the leaf pages, then the sampling +# will do full scan and we cannot check whether the sample_pages variable was +# honored. +BEGIN; +-- disable_query_log +let $i=999; +while ($i) { + eval INSERT INTO test_ps_sample_pages_used VALUES (REPEAT(1000+$i, 128)); + dec $i; +} +-- enable_query_log +COMMIT; + +ANALYZE TABLE test_ps_sample_pages_used; + +# confirm the big number of leaf pages in the index +SELECT stat_name, stat_value FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_leaf_pages'; + +# confirm that 17 pages were sampled, that is - the global +# innodb_stats_persistent_sample_pages is used when the table option +# STATS_SAMPLE_PAGES is set to 'default'. +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; + +ALTER TABLE test_ps_sample_pages_used STATS_SAMPLE_PAGES=14; + +ANALYZE TABLE test_ps_sample_pages_used; + +# confirm that 14 pages were sampled, that is - the table option +# STATS_SAMPLE_PAGES is used when it is set. +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; + +DROP TABLE test_ps_sample_pages_used; + +SET GLOBAL innodb_stats_persistent_sample_pages=default; diff --git a/mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test b/mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test new file mode 100644 index 00000000000..01fe4331926 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test @@ -0,0 +1,83 @@ +# +# Test CREATE TABLE ... STATS_AUTO_RECALC=0|1|default +# + +-- source include/no_valgrind_without_big.inc +-- source include/have_innodb.inc +-- source include/not_embedded.inc + +-- vertical_results + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; + +## + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=default; + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; + +## + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=0; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; + +## + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=0; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; diff --git a/mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test b/mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test new file mode 100644 index 00000000000..a5c3c8624b1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test @@ -0,0 +1,103 @@ +# +# Test CREATE TABLE ... STATS_SAMPLE_PAGES=N|default +# + +-- source include/have_innodb.inc +# include/restart_mysqld.inc does not work in embedded mode +-- source include/not_embedded.inc + +-- vertical_results + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=12345; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; + +## + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=default; + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; + +## + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=-5; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=0; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=67000; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=670000; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65536; + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65535; + +SHOW CREATE TABLE test_ps_sample_pages; + +DROP TABLE test_ps_sample_pages; + +## + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; + +## + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=5678; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=default; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; diff --git a/mysql-test/suite/innodb/t/innodb_ut_format_name.test b/mysql-test/suite/innodb/t/innodb_ut_format_name.test new file mode 100644 index 00000000000..6e4023c7088 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_ut_format_name.test @@ -0,0 +1,17 @@ +# +# Test ut_format_name() +# + +-- source include/have_debug.inc +-- source include/have_innodb.inc + +CREATE TABLE t (c INT) ENGINE=INNODB; + +# This will invoke test_ut_format_name() in debug builds + +SET @save_dbug = @@debug_dbug; +SET debug_dbug = '+d,test_ut_format_name'; + +DROP TABLE t; + +SET debug_dbug = @save_dbug; diff --git a/mysql-test/suite/innodb/t/mdev-14846.test b/mysql-test/suite/innodb/t/mdev-14846.test index b1f32302591..e9698cc0594 100644 --- a/mysql-test/suite/innodb/t/mdev-14846.test +++ b/mysql-test/suite/innodb/t/mdev-14846.test @@ -2,6 +2,8 @@ --source include/count_sessions.inc --source include/have_debug_sync.inc +--source include/innodb_stable_estimates.inc + CREATE TABLE t1 ( pk INT, f1 VARCHAR(10) NOT NULL, diff --git a/mysql-test/suite/innodb/t/no_pad.test b/mysql-test/suite/innodb/t/no_pad.test index 1be1972c9ca..15ab71b6c7f 100644 --- a/mysql-test/suite/innodb/t/no_pad.test +++ b/mysql-test/suite/innodb/t/no_pad.test @@ -8,3 +8,49 @@ ALTER TABLE t1 ROW_FORMAT=DYNAMIC; INSERT INTO t1 VALUES ('',2); ALTER TABLE t1 ROW_FORMAT=REDUNDANT; DROP TABLE t1; + + +--echo # +--echo # MDEV-26743 InnoDB: CHAR+nopad does not work well +--echo # + +--echo # +--echo # Basic Latin letter vs equal accented letter +--echo # + +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(2), PRIMARY KEY(a)) COLLATE utf8_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT; +--error ER_DUP_ENTRY +INSERT INTO t1 VALUES ('a'),('ä'); +DROP TABLE t1; + +--echo # +--echo # Two letters vs equal (but space padded) expansion +--echo # + +CREATE TABLE t1 (a CHAR(2), PRIMARY KEY(a)) COLLATE utf8_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT; +INSERT INTO t1 VALUES ('ss'),('ß'); +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +SELECT HEX(a) FROM t1; +SET sql_mode=DEFAULT; +DROP TABLE t1; + +--echo # +--echo # Basic Latin letter (but followed by an ignorable character) vs equal accented letter +--echo # + +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(3), PRIMARY KEY(a)) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT; +INSERT INTO t1 VALUES (CONCAT('a',_utf8mb3 0x01)),('ä'); +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +SELECT HEX(a) FROM t1 ORDER BY HEX(a); +SET sql_mode=DEFAULT; +DROP TABLE t1; + +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(2), PRIMARY KEY(a)) COLLATE utf8_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT; +INSERT INTO t1 VALUES (CONCAT('a',_utf8mb3 0x01)),('ä'); +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +SELECT HEX(a) FROM t1 ORDER BY HEX(a); +SET sql_mode=DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/purge_thread_shutdown.test b/mysql-test/suite/innodb/t/purge_thread_shutdown.test deleted file mode 100644 index 762336cf0d1..00000000000 --- a/mysql-test/suite/innodb/t/purge_thread_shutdown.test +++ /dev/null @@ -1,43 +0,0 @@ -source include/have_innodb.inc; -source include/not_embedded.inc; -source include/have_debug.inc; - -connect con1, localhost, root; -create table t1 (a int) engine=innodb; -insert t1 values (1),(2),(3),(4); -delete from t1 where a=1; - -select user,state from information_schema.processlist order by 2; - -set global debug_dbug='+d,only_kill_system_threads'; -set global innodb_fast_shutdown=0; - ---let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` ---let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect -exec echo "wait" > $_expect_file_name; -send shutdown; - -connection default; -disconnect con1; - -sleep 5; -select user,state from information_schema.processlist order by 2; -set global innodb_fast_shutdown=1; - -let $wait_condition=select count(*) = 0 from information_schema.processlist where user='system user'; -source include/wait_condition.inc; -select user,state from information_schema.processlist order by 2; - -delete from t1 where a=3; -error ER_WRONG_VALUE_FOR_VAR; -set global innodb_fast_shutdown=0; - -# Get id with space prefix to ensure that replace_result doesn't replace -# the error code -let $me=`select concat(' ', connection_id())`; -replace_result $me ID; -error ER_CONNECTION_KILLED; -eval kill $me; - -source include/start_mysqld.inc; -drop table t1; diff --git a/mysql-test/suite/innodb/t/records_in_range.test b/mysql-test/suite/innodb/t/records_in_range.test new file mode 100644 index 00000000000..697dbc1e8dd --- /dev/null +++ b/mysql-test/suite/innodb/t/records_in_range.test @@ -0,0 +1,432 @@ +# +# Test btr_estimate_n_rows_in_range() which is used by +# ha_innobase::records_in_range() +# + +-- source include/have_debug.inc +-- source include/have_innodb.inc +-- source include/innodb_page_size_small.inc + +CREATE TABLE records_in_range_test ( + c1 VARCHAR(16), + c2 VARCHAR(512), + PRIMARY KEY (c1) +) ENGINE=INNODB STATS_PERSISTENT=1; + +# Insert some records so that they cannot fit in one page for some page sizes +# in order to exercise records_in_range() where 1, 2 or more pages are sampled +INSERT INTO records_in_range_test VALUES +('ccc', REPEAT('v', 512)), +('kkk01', REPEAT('v', 512)), +('kkk02', REPEAT('v', 512)), +('kkk03', REPEAT('v', 512)), +('kkk04', REPEAT('v', 512)), +('kkk05', REPEAT('v', 512)), +('kkk06', REPEAT('v', 512)), +('kkk07', REPEAT('v', 512)), +('kkk08', REPEAT('v', 512)), +('mmm', REPEAT('v', 512)), +('nnn', REPEAT('v', 512)), +('uuu01', REPEAT('v', 512)), +('uuu02', REPEAT('v', 512)), +('uuu03', REPEAT('v', 512)), +('uuu04', REPEAT('v', 512)), +('uuu05', REPEAT('v', 512)), +('uuu06', REPEAT('v', 512)), +('uuu07', REPEAT('v', 512)), +('uuu08', REPEAT('v', 512)), +('xxx', REPEAT('v', 512)); + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE records_in_range_test; + +# 16k or bigger page size: 1 leaf page +# 8k page size: 2 leaf pages +# 4k page size: 4 leaf pages +SELECT index_name, stat_name, stat_value +FROM mysql.innodb_index_stats +WHERE +table_name='records_in_range_test' AND stat_name = 'n_leaf_pages'; + +# 16k or bigger page size: 1 page in total (leaf + nonleaf) +# 8k page size: 3 pages in total (leaf + nonleaf) +# 4k page size: 5 pages in total (leaf + nonleaf) +SELECT index_name, stat_name, stat_value +FROM mysql.innodb_index_stats +WHERE +table_name='records_in_range_test' AND stat_name = 'size'; + +# We exploit the warning mechanism here to display the return value from +# btr_estimate_n_rows_in_range() +SET @save_dbug = @@debug_dbug; +SET DEBUG_DBUG='+d,print_btr_estimate_n_rows_in_range_return_value'; + +-- echo +-- echo In all SELECTs below the number of the records in the range returned +-- echo by COUNT(*) must be the same as the number returned by +-- echo btr_estimate_n_rows_in_range() which can be seen inside the artificial +-- echo warning + +-- echo +-- echo Test left-unbounded, right-open intervals +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'aaa'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'zzz'; + +-- echo +-- echo Test left-unbounded, right-closed intervals +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'aaa'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'zzz'; + +-- echo +-- echo Test left-open, right-unbounded intervals +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz'; + +-- echo +-- echo Test left-closed, right-unbounded intervals +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz'; + +-- echo +-- echo Test left-open, right-open intervals +-- echo In some cases here the optimizer is smart enough not to call +-- echo ha_innobase::records_in_range() at all, so we get no warning containing +-- echo the value returned from btr_estimate_n_rows_in_range() +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'zzz'; + +-- echo +-- echo Test left-closed, right-open intervals +-- echo In some cases here the optimizer is smart enough not to call +-- echo ha_innobase::records_in_range() at all, so we get no warning containing +-- echo the value returned from btr_estimate_n_rows_in_range() +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'zzz'; + +-- echo +-- echo Test left-open, right-closed intervals +-- echo In some cases here the optimizer is smart enough not to call +-- echo ha_innobase::records_in_range() at all, so we get no warning containing +-- echo the value returned from btr_estimate_n_rows_in_range() +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'zzz'; + +-- echo +-- echo Test left-closed, right-closed intervals +-- echo In some cases here the optimizer is smart enough not to call +-- echo ha_innobase::records_in_range() at all, so we get no warning containing +-- echo the value returned from btr_estimate_n_rows_in_range() +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'zzz'; + +SET DEBUG_DBUG = @save_dbug; + +DROP TABLE records_in_range_test; diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt new file mode 100644 index 00000000000..66bceccc683 --- /dev/null +++ b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt @@ -0,0 +1 @@ +--innodb-sys-tablespaces diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test new file mode 100644 index 00000000000..dc87e3fa165 --- /dev/null +++ b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test @@ -0,0 +1,162 @@ +--echo # +--echo # Test the limits of a file-per-table tablespace name. MySQL combines +--echo # the database name with the table name to make a unique table name. +--echo # + +--source include/have_innodb.inc +--source include/not_windows.inc +# This will test the limit of a filename in MySQL at 512 bytes. +# We control that by making it a relative path starting with "./". +# The embedded server uses an absolute path as the datadir +# which has a non-deterministic length. +--source include/not_embedded.inc + +SET default_storage_engine=InnoDB; +LET $MYSQLD_DATADIR = `select @@datadir`; + +--echo # +--echo # MySQL limits each database and tablename identifier to 64 characters +--echo # of up to 3 bytes per character, corresponding to 192 bytes. +--echo # +LET $too_long_name = this_sixty_five_byte_name_is_too_long____________________________; +--error ER_WRONG_DB_NAME +--eval CREATE DATABASE `$too_long_name` + +LET $long_name = this_sixty_four_byte_name_is_not_too_long_______________________; +--eval CREATE DATABASE `$long_name` +--eval USE `$long_name` + +--echo # +--echo # A 64 character tablename can be created in a 64 character database name +--echo # +--eval CREATE TABLE `$long_name`.`$long_name` (a SERIAL) + +--echo # +--echo # A 65 character tablename is too long. +--echo # +--error ER_WRONG_TABLE_NAME +--eval CREATE TABLE `test`.`$too_long_name` (a SERIAL) +--error ER_WRONG_TABLE_NAME +--eval CREATE TABLE `$long_name`.`$too_long_name` (a SERIAL) + +--echo # +--echo # Non-non-filename-safe characters like '#' are expanded to '@0023'. +--echo # On many file systems, such as Linux extfs, you can create a database name +--echo # that expands to up to 255 bytes long. +--echo # `##################################################_long` is expanded to +--echo # (50 * 5) + 5 = 255. +--echo # +LET $long_db_name = ##################################################_long; +--eval CREATE DATABASE `$long_db_name`; +--eval USE `$long_db_name` + +--echo # +--echo # This 256-byte name is only one byte longer but fails with an error code +--echo # from the stat operation. +--echo # `##################################################_long_` is expanded to +--echo # (50 * 5) + 6 = 256. +--echo # +--replace_regex /Errcode: [0-9]+/Errcode: ##/ /@0023/#/ +--error 13 +CREATE DATABASE `##################################################_long_`; + +--echo # +--echo # This 300-byte name which is the longest name that gets an error code +--echo # from the stat operation. +--echo # `###########################################################_long` is expanded to +--echo # (59 * 5) + 5 = 300. +--echo # +--replace_regex /Errcode: [0-9]+/Errcode: ##/ /@0023/#/ +--error 13 +CREATE DATABASE `###########################################################_long`; + +--echo # +--echo # This 301-byte name which is only one byte longer but fails with ER_TOO_LONG_IDENT. +--echo # `###########################################################_long_` is expanded to +--echo # (59 * 5) + 6 = 301. +--echo # +--replace_result @0023 # +--error ER_WRONG_DB_NAME +CREATE DATABASE `###########################################################_long_`; + +USE test; + +LET $long_249_byte_table_name = #################################################long; +LET $long_250_byte_table_name = #################################################_long; +LET $long_251_byte_table_name = #################################################_long_; +LET $long_252_byte_table_name = #################################################_long___; + +--echo # +--echo # An expanded table name is limited to 251 bytes +--echo # +--eval CREATE TABLE `test`.`$long_251_byte_table_name` (a SERIAL) + +--echo # +--echo # A 252-byte tablename is too long +--echo # +--replace_regex /errno: [0-9]+/errno: ##/ /@0023/#/ +--error ER_CANT_CREATE_TABLE +--eval CREATE TABLE `test`.`$long_252_byte_table_name` (a SERIAL) + +CREATE DATABASE twenty_byte_db_name_; +USE `twenty_byte_db_name_`; + +--echo # +--echo # A 251 byte expanded table name will fit with a longer database name +--echo # +--eval CREATE TABLE `twenty_byte_db_name_`.`$long_251_byte_table_name` (a SERIAL) + +--echo # +--echo # A 252 byte expanded table name is also too long in a longer database name +--echo # +--replace_regex /errno: [0-9]+/errno: ##/ /@0023/#/ +--error ER_CANT_CREATE_TABLE +--eval CREATE TABLE `twenty_byte_db_name_`.`$long_252_byte_table_name` (a SERIAL) + +--echo # +--echo # Another limitation is a 512 byte length to an expanded path that includes +--echo # the datadir which is './' in this test, the expanded database name, +--echo # the directory separator '/', the expanded table name, and the file extension. +--echo # './long_db_name.long_250_byte_table_name.frm' +--echo # 2+ 255 +1+ 250 +1+3 = 512 +--echo # +--eval CREATE TABLE `$long_db_name`.`$long_250_byte_table_name` (a SERIAL) + +--error ER_IDENT_CAUSES_TOO_LONG_PATH +--eval CREATE TABLE `$long_db_name`.`$long_251_byte_table_name` (a SERIAL) +SHOW WARNINGS; + +--echo # +--echo # Show the successfully created databases and tables +--echo # +--echo ---- list_files MYSQLD_DATADIR/test +--replace_result @0023 # +--list_files $MYSQLD_DATADIR/test +--echo ---- list_files MYSQLD_DATADIR/$long_name +--replace_result @0023 # +--list_files $MYSQLD_DATADIR/$long_name +--echo ---- list_files MYSQLD_DATADIR/$long_db_name +--replace_result @0023 # +--list_files $MYSQLD_DATADIR/@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023_long + +--replace_result @0023 # +SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%'; +--replace_result @0023 # +SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%'; +--vertical_results +--replace_regex /innodb_file_per_table_[0-9]*/innodb_file_per_table_##/ +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR @0023 # +SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%'; +--horizontal_results + +--echo # +--echo # Cleanup +--echo # + +--eval DROP TABLE `$long_name`.`$long_name` +--eval DROP TABLE `test`.`$long_251_byte_table_name` +--eval DROP TABLE `twenty_byte_db_name_`.`$long_251_byte_table_name` +--eval DROP TABLE `$long_db_name`.`$long_250_byte_table_name` +--eval DROP DATABASE `$long_name` +--eval DROP DATABASE `$long_db_name` +DROP DATABASE `twenty_byte_db_name_`; diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_windows.opt b/mysql-test/suite/innodb/t/tablespace_per_table_windows.opt new file mode 100644 index 00000000000..66bceccc683 --- /dev/null +++ b/mysql-test/suite/innodb/t/tablespace_per_table_windows.opt @@ -0,0 +1 @@ +--innodb-sys-tablespaces diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_windows.test b/mysql-test/suite/innodb/t/tablespace_per_table_windows.test new file mode 100644 index 00000000000..eee7209c067 --- /dev/null +++ b/mysql-test/suite/innodb/t/tablespace_per_table_windows.test @@ -0,0 +1,77 @@ +--echo # +--echo # Test the limits of a file-per-table tablespace name. MySQL combines +--echo # the database name with the table name to make a unique table name. +--echo # + +# There is no use in testing the maximum expanded filename using "#" or +# some other character that is expanded by MySQL to "@0023" because +# Windows imposes a maximum absolute path length of 260 bytes. So the +# results will depend upon what local directory this test is run in. +# See https://msdn.microsoft.com/en-us/library/aa365247.aspx +# "Maximum Path Length Limitation +# In the Windows API, the maximum length for a path is MAX_PATH, which is +# defined as 260 characters. A local path is structured in the following +# order: drive letter, colon, backslash, name components separated by +# backslashes, and a terminating null character. For example, the maximum +# path on drive D is "D:\some 256-character path string" where +# "" represents the invisible terminating null character for the +# current system codepage. (The characters < > are used here for visual +# clarity and cannot be part of a valid path string.)" + +--source include/have_innodb.inc +--source include/windows.inc +# This will test the limit of a filename in MySQL at 512 bytes. +# We control that by making it a relative path starting with "./". +# The embedded server uses an absolute path as the datadir +# which has a non-deterministic length. +--source include/not_embedded.inc + +SET default_storage_engine=InnoDB; +LET $MYSQLD_DATADIR = `select @@datadir`; + +--echo # +--echo # MySQL limits each database and tablename identifier to 64 characters +--echo # of up to 3 bytes per character, corresponding to 192 bytes. +--echo # +LET $too_long_name = this_sixty_five_byte_name_is_too_long____________________________; +--error ER_WRONG_DB_NAME +--eval CREATE DATABASE `$too_long_name` + +LET $long_name = this_sixty_four_byte_name_is_not_too_long_______________________; +--eval CREATE DATABASE `$long_name` +--eval USE `$long_name` + +--echo # +--echo # A 64 character tablename can be created in a 64 character database name +--echo # +--eval CREATE TABLE `$long_name`.`$long_name` (a SERIAL) + +--echo # +--echo # A 65 character tablename is too long. +--echo # +--error ER_WRONG_TABLE_NAME +--eval CREATE TABLE `test`.`$too_long_name` (a SERIAL) +--error ER_WRONG_TABLE_NAME +--eval CREATE TABLE `$long_name`.`$too_long_name` (a SERIAL) + +--echo # +--echo # Show the successfully created database and table +--echo # +--eval SHOW CREATE TABLE `$long_name`.`$long_name` + +--echo ---- list_files MYSQLD_DATADIR/$long_name +--list_files $MYSQLD_DATADIR/$long_name + +SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%'; +SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%'; +--vertical_results +--replace_regex /innodb_file_per_table_[0-9]*/innodb_file_per_table_##/ +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%'; +--horizontal_results + +--echo # +--echo # Cleanup +--echo # + +--eval DROP DATABASE `$long_name` diff --git a/mysql-test/suite/innodb_fts/r/foreign_key_check.result b/mysql-test/suite/innodb_fts/r/foreign_key_check.result new file mode 100644 index 00000000000..38f46d5ff3c --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/foreign_key_check.result @@ -0,0 +1,27 @@ +CREATE TABLE t1 ( +id INT NOT NULL, +title TEXT, +PRIMARY KEY (id), +FULLTEXT KEY (title), +FOREIGN KEY (id) REFERENCES t2 (id) +) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") +CREATE TABLE t1 ( +id INT NOT NULL, +title TEXT, +PRIMARY KEY (id) +) ENGINE=InnoDB; +ALTER TABLE t1 ADD FULLTEXT KEY (title), ADD FOREIGN KEY (id) REFERENCES t2 (id); +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") +SET FOREIGN_KEY_CHECKS = 0; +ALTER TABLE t1 ADD FULLTEXT KEY (title), ADD FOREIGN KEY (id) REFERENCES t2 (id); +DROP TABLE t1; +CREATE TABLE t1 ( +id INT NOT NULL, +title TEXT, +PRIMARY KEY (id), +FULLTEXT KEY (title), +FOREIGN KEY (id) REFERENCES t2 (id) +) ENGINE=InnoDB; +DROP TABLE t1; +SET FOREIGN_KEY_CHECKS = 1; diff --git a/mysql-test/suite/innodb_fts/r/foreign_key_update.result b/mysql-test/suite/innodb_fts/r/foreign_key_update.result new file mode 100644 index 00000000000..f2d47da78c5 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/foreign_key_update.result @@ -0,0 +1,34 @@ +CREATE TABLE t1 ( +a varchar(40), +KEY a(a) +) ENGINE=InnoDB; +CREATE TABLE t1_fk ( +a varchar(40), +KEY a(a), +FULLTEXT KEY (a), +CONSTRAINT fk FOREIGN KEY (a) REFERENCES t1 (a) ON UPDATE CASCADE +) ENGINE=InnoDB; +INSERT INTO t1 VALUES('mysql'); +INSERT INTO t1_fk VALUES('mysql'); +INSERT INTO t1_fk VALUES('mysql'); +SELECT * FROM t1_fk; +a +mysql +mysql +SELECT * FROM t1_fk WHERE MATCH(a) AGAINST('mysql'); +a +mysql +mysql +UPDATE t1 SET a = 'database' WHERE a = 'mysql'; +SELECT * FROM t1_fk; +a +database +database +SELECT * FROM t1_fk WHERE MATCH(a) AGAINST('mysql'); +a +SELECT * FROM t1_fk WHERE MATCH(a) AGAINST('database'); +a +database +database +DROP TABLE t1_fk; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/index_table.result b/mysql-test/suite/innodb_fts/r/index_table.result new file mode 100644 index 00000000000..570e367a7d4 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/index_table.result @@ -0,0 +1,265 @@ +SET @optimize=@@GLOBAL.INNODB_OPTIMIZE_FULLTEXT_ONLY; +SET GLOBAL INNODB_OPTIMIZE_FULLTEXT_ONLY=1; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +content TEXT +) ENGINE= InnoDB; +CREATE FULLTEXT INDEX idx ON articles (title, content); +INSERT INTO articles (title, content) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','How to use full-text search engine'), +('Go MySQL Tricks','How to use full text search engine'); +SET @aux=@@GLOBAL.innodb_ft_aux_table; +SET GLOBAL innodb_ft_aux_table='test/articles'; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +after 2 2 1 2 22 +database 1 1 1 1 37 +dbms 1 1 1 1 15 +engine 4 5 2 4 46 +engine 4 5 2 5 44 +full 4 5 2 4 29 +full 4 5 2 5 27 +mysql 1 5 5 1 0 +mysql 1 5 5 1 31 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +search 4 5 2 4 39 +search 4 5 2 5 37 +show 3 3 1 3 42 +stands 1 1 1 1 20 +text 4 5 2 4 34 +text 4 5 2 5 32 +through 2 2 1 2 37 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 3 2 1 6 +tutorial 1 3 2 3 25 +use 2 5 3 2 7 +use 2 5 3 4 25 +use 2 5 3 5 23 +well 2 2 1 2 17 +went 2 2 1 2 32 +you 2 2 1 2 28 +OPTIMIZE TABLE articles; +Table Op Msg_type Msg_text +test.articles optimize status OK +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +after 2 2 1 2 22 +database 1 1 1 1 37 +dbms 1 1 1 1 15 +engine 4 5 2 4 46 +engine 4 5 2 5 44 +full 4 5 2 4 29 +full 4 5 2 5 27 +mysql 1 5 5 1 0 +mysql 1 5 5 1 31 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +search 4 5 2 4 39 +search 4 5 2 5 37 +show 3 3 1 3 42 +stands 1 1 1 1 20 +text 4 5 2 4 34 +text 4 5 2 5 32 +through 2 2 1 2 37 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 3 2 1 6 +tutorial 1 3 2 3 25 +use 2 5 3 2 7 +use 2 5 3 4 25 +use 2 5 3 5 23 +well 2 2 1 2 17 +went 2 2 1 2 32 +you 2 2 1 2 28 +SET @save_dbug=@@debug_dbug; +SET debug_dbug='+d,fts_instrument_result_cache_limit'; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +after 2 2 1 2 22 +database 1 1 1 1 37 +dbms 1 1 1 1 15 +engine 4 5 2 4 46 +engine 4 5 2 5 44 +full 4 5 2 4 29 +full 4 5 2 5 27 +mysql 1 5 5 1 0 +mysql 1 5 5 1 31 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +search 4 5 2 4 39 +search 4 5 2 5 37 +show 3 3 1 3 42 +stands 1 1 1 1 20 +text 4 5 2 4 34 +text 4 5 2 5 32 +through 2 2 1 2 37 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 3 2 1 6 +tutorial 1 3 2 3 25 +use 2 5 3 2 7 +use 2 5 3 4 25 +use 2 5 3 5 23 +well 2 2 1 2 17 +went 2 2 1 2 32 +you 2 2 1 2 28 +SET debug_dbug=@save_dbug; +DROP TABLE articles; +SET GLOBAL innodb_ft_result_cache_limit=default; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +content TEXT +) ENGINE= InnoDB; +CREATE FULLTEXT INDEX idx_t ON articles (title); +CREATE FULLTEXT INDEX idx_c ON articles (content); +INSERT INTO articles (title, content) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','How to use full-text search engine'), +('Go MySQL Tricks','How to use full text search engine'); +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SET GLOBAL innodb_ft_aux_table='test/articles'; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +mysql 1 5 5 1 0 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 1 1 1 6 +use 2 2 1 2 7 +well 2 2 1 2 17 +after 2 2 1 2 0 +database 1 1 1 1 22 +dbms 1 1 1 1 0 +engine 4 5 2 4 28 +engine 4 5 2 5 28 +full 4 5 2 4 11 +full 4 5 2 5 11 +mysql 1 1 1 1 16 +search 4 5 2 4 21 +search 4 5 2 5 21 +show 3 3 1 3 25 +stands 1 1 1 1 5 +text 4 5 2 4 16 +text 4 5 2 5 16 +through 2 2 1 2 15 +tutorial 3 3 1 3 8 +use 4 5 2 4 7 +use 4 5 2 5 7 +went 2 2 1 2 10 +you 2 2 1 2 6 +OPTIMIZE TABLE articles; +Table Op Msg_type Msg_text +test.articles optimize status OK +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +mysql 1 5 5 1 0 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 1 1 1 6 +use 2 2 1 2 7 +well 2 2 1 2 17 +after 2 2 1 2 0 +database 1 1 1 1 22 +dbms 1 1 1 1 0 +engine 4 5 2 4 28 +engine 4 5 2 5 28 +full 4 5 2 4 11 +full 4 5 2 5 11 +mysql 1 1 1 1 16 +search 4 5 2 4 21 +search 4 5 2 5 21 +show 3 3 1 3 25 +stands 1 1 1 1 5 +text 4 5 2 4 16 +text 4 5 2 5 16 +through 2 2 1 2 15 +tutorial 3 3 1 3 8 +use 4 5 2 4 7 +use 4 5 2 5 7 +went 2 2 1 2 10 +you 2 2 1 2 6 +DROP TABLE articles; +SET NAMES utf8; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200) +) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; +CREATE FULLTEXT INDEX idx ON articles (title); +INSERT INTO articles (title) VALUES +('相亲相爱'),('怜香惜爱'),('充满å¯çˆ±'),('爱æ¨äº¤ç»‡'); +SET GLOBAL innodb_ft_aux_table="test/articles"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +充满å¯çˆ± 3 3 1 3 0 +怜香惜爱 2 2 1 2 0 +爱æ¨äº¤ç»‡ 4 4 1 4 0 +相亲相爱 1 1 1 1 0 +OPTIMIZE TABLE articles; +Table Op Msg_type Msg_text +test.articles optimize status OK +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +充满å¯çˆ± 3 3 1 3 0 +怜香惜爱 2 2 1 2 0 +爱æ¨äº¤ç»‡ 4 4 1 4 0 +相亲相爱 1 1 1 1 0 +DROP TABLE articles; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200) +) ENGINE=InnoDB DEFAULT CHARACTER SET gb2312 COLLATE gb2312_chinese_ci; +CREATE FULLTEXT INDEX idx ON articles (title); +INSERT INTO articles (title) VALUES +('相亲相爱'),('怜香惜爱'),('充满å¯çˆ±'),('爱æ¨äº¤ç»‡'); +SET GLOBAL innodb_ft_aux_table="test/articles"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +爱æ¨äº¤ç»‡ 4 4 1 4 0 +充满å¯çˆ± 3 3 1 3 0 +怜香惜爱 2 2 1 2 0 +相亲相爱 1 1 1 1 0 +OPTIMIZE TABLE articles; +Table Op Msg_type Msg_text +test.articles optimize status OK +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +怜香惜爱 2 2 1 2 0 +充满å¯çˆ± 3 3 1 3 0 +相亲相爱 1 1 1 1 0 +爱æ¨äº¤ç»‡ 4 4 1 4 0 +DROP TABLE articles; +SET GLOBAL innodb_ft_aux_table=@aux; +SET GLOBAL INNODB_OPTIMIZE_FULLTEXT_ONLY=@optimize; diff --git a/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result b/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result index d67981e0851..a53fca51c6c 100644 --- a/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result +++ b/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result @@ -134,6 +134,7 @@ count(*) 2 DROP TABLE t1; set global innodb_file_per_table=1; +set names utf8; CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, a TEXT, @@ -160,7 +161,7 @@ SELECT count(*) FROM t1 WHERE MATCH (a,b,c) AGAINST ('"very blob"@4' IN BOOLEAN MODE); count(*) -4 +5 SELECT count(*) FROM t1 WHERE MATCH (a,b,c) AGAINST ('"interesting blob"@9' IN BOOLEAN MODE); @@ -175,7 +176,7 @@ SELECT COUNT(*) FROM t1 WHERE MATCH (a,b,c) AGAINST ('"very blob"@4 - "interesting blob"@9' IN BOOLEAN MODE); COUNT(*) -3 +4 DROP TABLE t1; CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, diff --git a/mysql-test/suite/innodb_fts/r/limit_union.result b/mysql-test/suite/innodb_fts/r/limit_union.result new file mode 100644 index 00000000000..843d55d23e4 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/limit_union.result @@ -0,0 +1,157 @@ +# Bug #22709692 FTS QUERY EXCEEDS RESULT CACHE LIMIT +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body), +FULLTEXT (body))ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SET @default_cache_size = @@GLOBAL.query_cache_size; +SET GLOBAL query_cache_size=0; +# Query involves Ranking +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN NATURAL LANGUAGE MODE) LIMIT 1; +id title body +6 MySQL Security When configured properly, MySQL ... +# Without optimization +SET @save_dbug = @@debug_dbug; +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN NATURAL LANGUAGE MODE) LIMIT 1; +id title body +6 MySQL Security When configured properly, MySQL ... +SET debug_dbug = @save_dbug; +# Query involves No Ranking and fts_union operations +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN BOOLEAN MODE) limit 1; +id title body +6 MySQL Security When configured properly, MySQL ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN BOOLEAN MODE) limit 1; +id title body +6 MySQL Security When configured properly, MySQL ... +SET debug_dbug = @save_dbug; +# Query involves No ranking and fts_union, fts_ignore +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL -YourSQL' IN BOOLEAN MODE) limit 1; +id title body +6 MySQL Security When configured properly, MySQL ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL -YourSQL' IN BOOLEAN MODE) limit 1; +id title body +6 MySQL Security When configured properly, MySQL ... +SET debug_dbug = @save_dbug; +# Query with fts_intersect +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL +YourSQL' IN BOOLEAN MODE) limit 1; +id title body +5 MySQL vs. YourSQL In the following database comparison ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL +YourSQL' IN BOOLEAN MODE) limit 1; +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SET debug_dbug = @save_dbug; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','request doc@oraclehelp.com ...'), +('MySQL Tutorial','request support@oraclehelp.com ...'), +('Trial version','query performace @1255 minute on 2.1Hz + Memory 2GB...'), +('when To Use MySQL Well','for free faq mail@xyz.com ...'); +# Query with @distance +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"MySQL request"@3' IN BOOLEAN MODE) limit 1; +id title body +7 MySQL Tutorial request doc@oraclehelp.com ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"MySQL request"@3' IN BOOLEAN MODE) limit 1; +id title body +7 MySQL Tutorial request doc@oraclehelp.com ... +SET debug_dbug = @save_dbug; +# Query with subexpression +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('+MySQL +(-support +doc)' IN BOOLEAN MODE) limit 1; +id title body +7 MySQL Tutorial request doc@oraclehelp.com ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('+MySQL +(-support +doc)' IN BOOLEAN MODE) limit 1; +id title body +7 MySQL Tutorial request doc@oraclehelp.com ... +SET debug_dbug = @save_dbug; +# limit num1 OFFSET num2 +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' in boolean mode) limit 4 offset 2; +id title body +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' in boolean mode) limit 4 offset 2; +id title body +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +SET debug_dbug = @save_dbug; +# wild card search +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('ru*' IN BOOLEAN MODE) limit 1; +id title body +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('ru*' IN BOOLEAN MODE) limit 1; +id title body +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SET debug_dbug = @save_dbug; +# phrase search +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"request support"' IN BOOLEAN MODE) limit 1; +id title body +8 MySQL Tutorial request support@oraclehelp.com ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"request support"' IN BOOLEAN MODE) limit 1; +id title body +8 MySQL Tutorial request support@oraclehelp.com ... +SET debug_dbug = @save_dbug; +DROP TABLE articles; +SET GLOBAL query_cache_size = @default_cache_size; diff --git a/mysql-test/suite/innodb_fts/r/misc.result b/mysql-test/suite/innodb_fts/r/misc.result new file mode 100644 index 00000000000..684996fb748 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/misc.result @@ -0,0 +1,1878 @@ +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `a` varchar(200) DEFAULT NULL, + `b` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`a`,`b`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST ("collections" WITH QUERY EXPANSION); +id +select id from t1 where MATCH(a,b) AGAINST ("indexes" WITH QUERY EXPANSION); +id +select id from t1 where MATCH(a,b) AGAINST ("indexes collections" WITH QUERY EXPANSION); +id +ALTER TABLE t1 DROP INDEX idx; +CREATE FULLTEXT INDEX idx on t1 (a,b); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST ("collections" WITH QUERY EXPANSION); +id +select id from t1 where MATCH(a,b) AGAINST ("indexes" WITH QUERY EXPANSION); +id +select id from t1 where MATCH(a,b) AGAINST ("indexes collections" WITH QUERY EXPANSION); +id +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +INSERT INTO t1 (a,b) VALUES +('test proximity search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test proximity fts search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test more proximity fts search, test, more proximity and phrase', +'search, with proximity innodb'); +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@2' IN BOOLEAN MODE); +id +8 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@1' IN BOOLEAN MODE); +id +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@3' IN BOOLEAN MODE); +id +8 +9 +10 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"test proximity"@3' IN BOOLEAN MODE); +id +8 +9 +10 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); +id +10 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more test proximity"@2' IN BOOLEAN MODE); +id +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more fts proximity"@02' IN BOOLEAN MODE); +id +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +CREATE FULLTEXT INDEX idx on t1 (a,b); +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +SELECT id FROM t1 WHERE id = (SELECT MAX(id) FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)); +id +3 +SELECT id FROM t1 WHERE id = (SELECT MIN(id) FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)); +id +1 +SELECT id FROM t1 WHERE id = (SELECT MIN(id) FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) OR id = 3 ; +id +1 +3 +SELECT id FROM t1 WHERE CONCAT(t1.a,t1.b) IN ( +SELECT CONCAT(a,b) FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +) OR t1.id = 3 ; +id +1 +3 +SELECT id FROM t1 WHERE CONCAT(t1.a,t1.b) IN ( +SELECT CONCAT(a,b) FROM t1 AS t2 +WHERE MATCH (t2.a,t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +AND t2.id != 3) ; +id +1 +SELECT id FROM t1 WHERE id IN (SELECT MIN(id) FROM t1 WHERE +MATCH (a,b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) OR id = 3 ; +id +1 +3 +SELECT id FROM t1 WHERE id NOT IN (SELECT MIN(id) FROM t1 +WHERE MATCH (a,b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) ; +id +2 +3 +4 +5 +6 +SELECT id FROM t1 WHERE EXISTS (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +AND t1.id = t2.id) ; +id +1 +3 +SELECT id FROM t1 WHERE NOT EXISTS (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +AND t1.id = t2.id) ; +id +2 +4 +5 +6 +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT , +FULLTEXT (a,b) +) ENGINE = InnoDB; +INSERT INTO t1(a,b) VALUES('MySQL has now support', 'for full-text search'), +('Full-text indexes', 'are called collections'), +('Only MyISAM tables','support collections'), +('Function MATCH ... AGAINST()','is used to do a search'), +('Full-text search in MySQL', 'implements vector space model'); +SELECT id FROM t1 WHERE t1.id = (SELECT MAX(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST("+support +collections" IN BOOLEAN MODE)); +id +3 +SELECT id FROM t1 WHERE t1.id != (SELECT MIN(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST("+search" IN BOOLEAN MODE)); +id +2 +3 +4 +5 +SELECT id FROM t1 WHERE t1.id IN (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ("+call* +coll*" IN BOOLEAN MODE)); +id +2 +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE) AND t2.id=t1.id); +id +1 +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +INSERT INTO t1 (a,b) VALUES +('test proximity search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test proximity fts search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test more proximity fts search, test, more proximity and phrase', +'search, with proximity innodb'); +SELECT id FROM t1 WHERE t1.id = (SELECT MAX(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); +id +7 +SELECT id FROM t1 WHERE t1.id > (SELECT MIN(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); +id +8 +9 +SELECT id FROM t1 WHERE t1.id IN (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); +id +7 +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"proximity search"@2' IN BOOLEAN MODE) +AND t2.id=t1.id); +id +7 +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"more test proximity"@3' IN BOOLEAN MODE) +AND t2.id=t1.id); +id +9 +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"more test proximity"@2' IN BOOLEAN MODE) +AND t2.id=t1.id); +id +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST ('support') ; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(10) unsigned NOT NULL DEFAULT 0 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT id FROM t2; +id +1 +3 +DROP TABLE t2; +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST("+support +collections" IN BOOLEAN MODE); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(10) unsigned NOT NULL DEFAULT 0 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT id FROM t2; +id +3 +DROP TABLE t2; +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST ('"proximity search"@10' IN BOOLEAN MODE); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(10) unsigned NOT NULL DEFAULT 0 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT id FROM t2; +id +7 +8 +9 +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +CREATE FULLTEXT INDEX idx on t1 (a,b); +INSERT INTO t1 (a,b) VALUES +('MySQL from Tutorial','DBMS stands for DataBase ...'); +INSERT INTO t1 (a,b) VALUES +('when To Use MySQL Well','After that you went through a ...'); +INSERT INTO t1 (a,b) VALUES +('where will Optimizing MySQL','what In this tutorial we will show ...'); +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL null...'); +SELECT COUNT(*) FROM t1; +COUNT(*) +106 +SELECT COUNT(*) FROM t1 WHERE a IS NULL; +COUNT(*) +100 +SELECT COUNT(*) FROM t1 WHERE b IS NOT NULL; +COUNT(*) +6 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +103 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST (NULL IN NATURAL LANGUAGE MODE); +id +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST (NULL WITH QUERY EXPANSION); +id +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('null' IN NATURAL LANGUAGE MODE); +id +106 +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); +id +106 +1 +52 +103 +104 +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) AND (a IS NOT NULL OR b IS NOT NULL); +id +106 +1 +52 +103 +104 +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) AND (a IS NULL AND b IS NOT NULL); +id +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('DBMS Security' IN BOOLEAN MODE); +id +1 +106 +SELECT COUNT(*) FROM t1 +WHERE MATCH (a,b) +AGAINST ('database' WITH QUERY EXPANSION); +COUNT(*) +6 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"following database"@10' IN BOOLEAN MODE); +id +105 +DROP TABLE t1; +drop table if exists t50; +set names utf8; +"----------Test1---------" +create table t50 (s1 varchar(60) character set utf8 collate utf8_bin) engine = innodb; +create fulltext index i on t50 (s1); +insert into t50 values ('ABCDE'),('FGHIJ'),('KLMNO'),('VÃÆ·Wİ'); +select * from t50 where match(s1) against ('VÃÆ·Wİ'); +s1 +VÃÆ·Wİ +drop table t50; +"----------Test2---------" +create table t50 (s1 int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÃÆ·Wİ'),('ABCDE'); +select * from t50 order by s2; +s1 s2 +4 ABCDE +1 FGHIJ +2 KLMNO +3 VÃÆ·Wİ +drop table t50; +"----------Test3---------" +create table t50 (id int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÃÆ·Wİ'),('ABCDE'); +set @@autocommit=0; +update t50 set s2 = lower(s2); +update t50 set s2 = upper(s2); +commit; +select * from t50 where match(s2) against ('VÃÆ·Wİ FGHIJ KLMNO ABCDE' in boolean mode); +id s2 +1 FGHIJ +2 KLMNO +3 VÃÆ·WI +4 ABCDE +select * from t50; +id s2 +1 FGHIJ +2 KLMNO +3 VÃÆ·WI +4 ABCDE +drop table t50; +set @@autocommit=1; +"----------Test4---------" +create table t50 (id int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÃÆ·Wİ'),('ABCD*'); +select * from t50 where match(s2) against ('abcd*' in natural language +mode); +id s2 +4 ABCD* +select * from t50 where match(s2) against ('abcd*' in boolean mode); +id s2 +4 ABCD* +drop table t50; +"----------Test5---------" +create table t50 (s1 int, s2 varchar(200), fulltext key(s2)) engine = innodb; +set @@autocommit=0; +insert into t50 values (1,'Sunshine'),(2,'Lollipops'); +select * from t50 where match(s2) against('Rainbows'); +s1 s2 +rollback; +select * from t50; +s1 s2 +drop table t50; +set @@autocommit=1; +"----------Test6---------" +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('aab` MySQL Tutorial','DBMS stands for DataBase ...') , +('aas How To Use MySQL Well','After you went through a ...'), +('aac Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t1 (a,b) VALUES +('aac 1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('aab MySQL vs. YourSQL','In the following database comparison ...'), +('aaa MySQL Security','When configured properly, MySQL ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SELECT * FROM t1 ORDER BY MATCH(a,b) AGAINST ('aac') DESC; +id a b +3 aac Optimizing MySQL In this tutorial we will show ... +4 aac 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +1 aab` MySQL Tutorial DBMS stands for DataBase ... +2 aas How To Use MySQL Well After you went through a ... +5 aab MySQL vs. YourSQL In the following database comparison ... +6 aaa MySQL Security When configured properly, MySQL ... +SELECT * FROM t1 ORDER BY MATCH(a,b) AGAINST ('aab') DESC; +id a b +1 aab` MySQL Tutorial DBMS stands for DataBase ... +5 aab MySQL vs. YourSQL In the following database comparison ... +2 aas How To Use MySQL Well After you went through a ... +3 aac Optimizing MySQL In this tutorial we will show ... +4 aac 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +6 aaa MySQL Security When configured properly, MySQL ... +"----------Test7---------" +select * from t1 where match(a,b) against ('aaa') +union select * from t1 where match(a,b) against ('aab') +union select * from t1 where match(a,b) against ('aac'); +id a b +6 aaa MySQL Security When configured properly, MySQL ... +1 aab` MySQL Tutorial DBMS stands for DataBase ... +5 aab MySQL vs. YourSQL In the following database comparison ... +3 aac Optimizing MySQL In this tutorial we will show ... +4 aac 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +select * from t1 where match(a,b) against ('aaa') +or match(a,b) against ('aab') +or match(a,b) against ('aac'); +id a b +1 aab` MySQL Tutorial DBMS stands for DataBase ... +3 aac Optimizing MySQL In this tutorial we will show ... +4 aac 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 aab MySQL vs. YourSQL In the following database comparison ... +6 aaa MySQL Security When configured properly, MySQL ... +DROP TABLE t1; +"----------Test8---------" +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ... abcd') , +('How To Use MySQL Well','After you went through a q ...abdd'), +('Optimizing MySQL','In this tutorial we will show ...abed'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `a` varchar(200) DEFAULT NULL, + `b` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`a`,`b`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. q ...'), +('MySQL vs. YourSQL use','In the following database comparison ...'), +('MySQL Security','When run configured properly, MySQL ...'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run'); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. q ... +6 MySQL Security When run configured properly, MySQL ... +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('use'); +id a b +2 How To Use MySQL Well After you went through a q ...abdd +5 MySQL vs. YourSQL use In the following database comparison ... +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('went'); +id a b +2 How To Use MySQL Well After you went through a q ...abdd +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run') AND NOT MATCH(a,b) AGAINST ('q'); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. q ... +6 MySQL Security When run configured properly, MySQL ... +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('use') AND NOT MATCH(a,b) AGAINST ('q'); +id a b +2 How To Use MySQL Well After you went through a q ...abdd +5 MySQL vs. YourSQL use In the following database comparison ... +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('went') AND NOT MATCH(a,b) AGAINST ('q'); +id a b +2 How To Use MySQL Well After you went through a q ...abdd +"----------Test9---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE=MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +SET @x = (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('run')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('use')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('went')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('run')); +SET @x2 = (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('run')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('use')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('went')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('run')); +SELECT @x, @x2; +@x @x2 +7 0 +DROP TABLE t2; +"----------Test10---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE=MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +COUNT(*) +1 +SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +COUNT(*) +1 +DROP TABLE t2; +"----------Test11---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE = MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +ALTER TABLE t2 ENGINE=InnoDB; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run'); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. q ... +6 MySQL Security When run configured properly, MySQL ... +SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +COUNT(*) +1 +DROP TABLE t2,t1; +"----------Test13---------" +set names utf8; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200) CHARACTER SET UTF8 COLLATE UTF8_SPANISH_CI) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1 (s2); +INSERT INTO t1 VALUES (1,'aaCen'),(2,'aaCha'),(3,'aaCio'),(4,'aaçen'),(5,'aaçha'),(6,'aaçio'); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('aach*' IN BOOLEAN MODE); +s1 s2 +2 aaCha +5 aaçha +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('aaC*' IN BOOLEAN MODE); +s1 s2 +1 aaCen +2 aaCha +3 aaCio +4 aaçen +5 aaçha +6 aaçio +DROP TABLE t1; +"----------Test14---------" +CREATE TABLE t1(s1 INT , s2 VARCHAR(100) CHARACTER SET sjis) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1 (s2); +INSERT INTO t1 VALUES (1,'ペペペ'),(2,'テテテ'),(3,'ルルル'),(4,'ã‚°ã‚°ã‚°'); +DROP TABLE t1; +"----------Test15---------" +CREATE TABLE t1 (s1 VARCHAR (60) CHARACTER SET UTF8 COLLATE UTF8_UNICODE_520_CI) ENGINE = MyISAM; +CREATE FULLTEXT INDEX i ON t1 (s1); +INSERT INTO t1 VALUES +('a'),('b'),('c'),('d'),('ÅÅÅÅ'),('LLLL'),(NULL),('ÅÅÅÅ ÅÅÅÅ'),('LLLLLLLL'); +SELECT * FROM t1 WHERE MATCH(s1) AGAINST ('LLLL' COLLATE UTF8_UNICODE_520_CI); +s1 +ÅÅÅÅ +LLLL +ÅÅÅÅ ÅÅÅÅ +DROP TABLE if EXISTS t2; +Warnings: +Note 1051 Unknown table 'test.t2' +CREATE TABLE t2 (s1 VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_POLISH_CI) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t2 ( s1); +INSERT INTO t2 VALUES +('a'),('b'),('c'),('d'),('ÅÅÅÅ'),('LLLL'),(NULL),('ÅÅÅÅ ÅÅÅÅ'),('LLLLLLLL'); +SELECT * FROM t2 WHERE MATCH(s1) AGAINST ('LLLL' COLLATE UTF8_UNICODE_520_CI); +s1 +LLLL +DROP TABLE t1,t2; +"----------Test16---------" +CREATE TABLE t1 (s1 INT, s2 VARCHAR(50) CHARACTER SET UTF8) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1(s2); +INSERT INTO t1 VALUES (2, 'ÄŸÄ— DaÅ›i p '); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('+p +"ÄŸÄ— DaÅ›i*"' IN BOOLEAN MODE); +s1 s2 +DROP TABLE t1; +"----------Test19---------" +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,'İóëɠ'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +SELECT * FROM t1 WHERE MATCH(char_column) AGAINST ('"İóëɠ"' IN BOOLEAN MODE); +id char_column +1 İóëɠ +DROP TABLE t1; +"----------Test20---------" +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF32, char_column2 VARCHAR(60) character set utf8) ENGINE = InnoDB; +INSERT INTO t1 (char_column) VALUES ('abcde'),('fghij'),('klmno'),('qrstu'); +UPDATE t1 SET char_column2 = char_column; +CREATE FULLTEXT INDEX i ON t1 (char_column2); +SELECT * FROM t1 WHERE MATCH(char_column) AGAINST ('abc*' IN BOOLEAN MODE); +ERROR HY000: Can't find FULLTEXT index matching the column list +DROP TABLE t1; +"----------Test22---------" +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,'aaa'),(2,'bbb'),(3,'ccc'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +HANDLER t1 OPEN; +HANDLER t1 READ i = ('aaa'); +ERROR HY000: FULLTEXT index `i` does not support this operation +DROP TABLE t1; +"----------Test25---------" +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_CROATIAN_CI) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,'LJin'),(2,'ljin'),(3,'lmin'),(4,'LJLJLJLJLJ'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +SELECT count(*) FROM t1 WHERE MATCH (char_column) AGAINST ('lj*' IN BOOLEAN MODE); +count(*) +3 +DROP TABLE t1; +"----------Test27---------" +CREATE TABLE t1 (id INT,char_column VARCHAR(60)) ENGINE=InnoDB; +SET @@autocommit=0; +CREATE FULLTEXT INDEX i ON t1 (char_column); +INSERT INTO t1 values (1,'aaa'); +"restart server..." +# Restart the server +--source include/restart_mysqld.inc +DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb') +SET @@autocommit=1; +DROP TABLE t1; +"----------Test28---------" +drop table if exists `fts_test`; +Warnings: +Note 1051 Unknown table 'test.fts_test' +create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb; +set session autocommit=0; +insert into `fts_test` values (''); +savepoint `b`; +savepoint `b`; +set session autocommit=1; +DROP TABLE fts_test; +"----------Test29---------" +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...'); +start transaction; +INSERT INTO articles (title,body) VALUES +('How To Use MySQL Well','After you went through a ...'); +savepoint `a1`; +INSERT INTO articles (title,body) VALUES +('Optimizing MySQL','In this tutorial we will show ...'); +savepoint `a2`; +INSERT INTO articles (title,body) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'); +savepoint `a3`; +INSERT INTO articles (title,body) VALUES +('MySQL vs. YourSQL','In the following database comparison ...'); +savepoint `a4`; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +rollback to savepoint a3; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +INSERT INTO articles (title,body) VALUES +('MySQL Security','When configured properly, MySQL ...'); +savepoint `a5`; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +MySQL Security When configured properly, MySQL ... +rollback to savepoint a2; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +commit; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +DROP TABLE articles; +"----------Test30---------" +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...'); +start transaction; +INSERT INTO articles (title,body) VALUES +('How To Use MySQL Well','After you went through a ...'); +savepoint `a1`; +INSERT INTO articles (title,body) VALUES +('Optimizing MySQL','In this tutorial we will show ...'); +savepoint `a2`; +INSERT INTO articles (title,body) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'); +savepoint `a3`; +INSERT INTO articles (title,body) VALUES +('MySQL vs. YourSQL','In the following database comparison ...'); +savepoint `a4`; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +rollback to savepoint a3; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +INSERT INTO articles (title,body) VALUES +('MySQL Security','When configured properly, MySQL ...'); +savepoint `a5`; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +MySQL Security When configured properly, MySQL ... +rollback to savepoint a2; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +rollback; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +DROP TABLE articles; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +ANALYZE TABLE articles; +SELECT *, MATCH(title, body) AGAINST ('-database +MySQL' IN BOOLEAN MODE) AS score from articles; +id title body score +1 MySQL Tutorial DBMS stands for DataBase ... 0 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.000000001885928302414186 +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... 0.000000001885928302414186 +5 MySQL vs. YourSQL In the following database comparison ... 0 +6 MySQL Security When configured properly, MySQL ... 0.000000003771856604828372 +SELECT *, MATCH(title, body) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score FROM articles; +id title body score +1 MySQL Tutorial DBMS stands for DataBase ... 0 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.000000001885928302414186 +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... 0.000000001885928302414186 +5 MySQL vs. YourSQL In the following database comparison ... 0 +6 MySQL Security When configured properly, MySQL ... 0.000000003771856604828372 +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (database - tutorial)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (- tutorial database)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (- tutorial database) -Tricks' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM articles where MATCH(title, body) AGAINST ('-Tricks MySQL - (- tutorial database)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +DROP TABLE articles; +drop table if exists t1; +Warnings: +Note 1051 Unknown table 'test.t1' +create table t1 (FTS_DOC_ID bigint unsigned auto_increment not null primary key, +title varchar(200),body text,fulltext(title,body)) engine=innodb; +insert into t1 set body='test'; +select * from t1 where match(title,body) against('%test'); +FTS_DOC_ID title body +1 NULL test +select * from t1 where match(title,body) against('%'); +FTS_DOC_ID title body +select * from t1 where match(title,body) against('%%%%'); +FTS_DOC_ID title body +drop table t1; +CREATE DATABASE `benu database`; +USE `benu database`; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `a` varchar(200) DEFAULT NULL, + `b` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`a`,`b`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE); +id +DROP DATABASE `benu database`; +USE test; +CREATE TABLE `t21` (`a` text, `b` int not null, +fulltext key (`a`), fulltext key (`a`) +) ENGINE=INNODB DEFAULT CHARSET=LATIN1; +Warnings: +Note 1831 Duplicate index `a_2`. This is deprecated and will be disallowed in a future release +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`), ALGORITHM=INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`); +DROP TABLE t21; +CREATE TABLE `t21` (`a` text, `b` int not null, +fulltext key (`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1; +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`); +DROP TABLE t21; +CREATE TABLE t1 ( +id INT NOT NULL, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +(1, 'MySQL Tutorial','DBMS stands for DataBase ...') , +(2, 'How To Use MySQL Well','After you went through a ...'), +(3, 'Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +ALTER TABLE t1 ADD UNIQUE INDEX (`id`); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +DROP TABLE t1; +CREATE TABLE t1 ( +id INT NOT NULL, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +(1, 'MySQL Tutorial','DBMS stands for DataBase ...') , +(2, 'How To Use MySQL Well','After you went through a ...'), +(3, 'Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD UNIQUE INDEX (`id`), ADD FULLTEXT INDEX idx (a,b); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +DROP TABLE t1; +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED NOT NULL, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +(1, 'MySQL Tutorial','DBMS stands for DataBase ...') , +(2, 'How To Use MySQL Well','After you went through a ...'), +(3, 'Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +ALTER TABLE t1 ADD UNIQUE INDEX (`FTS_DOC_ID`); +SELECT FTS_DOC_ID FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +FTS_DOC_ID +1 +3 +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +FTS_DOC_ID x +1 0 +2 0 +3 0 +DROP TABLE t1; +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED NOT NULL, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +(1, 'MySQL Tutorial','DBMS stands for DataBase ...') , +(2, 'How To Use MySQL Well','After you went through a ...'), +(3, 'Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b), ADD UNIQUE INDEX FTS_DOC_ID_INDEX (FTS_DOC_ID); +SELECT FTS_DOC_ID FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +FTS_DOC_ID +1 +3 +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +FTS_DOC_ID x +1 0 +2 0 +3 0 +DROP TABLE t1; +CREATE TABLE t2 (`b` char(2),fulltext(`b`)) ENGINE=INNODB +DEFAULT CHARSET=LATIN1; +CREATE TABLE t3 LIKE t2; +INSERT INTO `t2` VALUES(); +COMMIT WORK AND CHAIN; +INSERT INTO `t3` VALUES (); +UPDATE `t2` SET `b` = 'a'; +SAVEPOINT BATCH1; +DROP TABLE t2; +DROP TABLE t3; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +COMMIT WORK AND CHAIN; +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SAVEPOINT BATCH1; +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); +id +1 +2 +3 +INSERT INTO t1 (a,b) VALUES +('1002 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +ROLLBACK TO SAVEPOINT BATCH1; +COMMIT; +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); +id +6 +1 +2 +3 +4 +5 +DROP TABLE t1; +CREATE TABLE `t` (`a` char(20) character set utf8 default null, +fulltext key (`a`)) ENGINE=INNODB; +INSERT INTO `t` VALUES ('a'); +INSERT INTO `t` VALUES ('aaa'); +SELECT MATCH(`a`) AGAINST (0x22dd22) FROM `t`; +MATCH(`a`) AGAINST (0x22dd22) +0 +0 +SELECT MATCH(`a`) AGAINST (0x2222) FROM `t`; +MATCH(`a`) AGAINST (0x2222) +0 +0 +SELECT MATCH(`a`) AGAINST (0x22) FROM `t`; +MATCH(`a`) AGAINST (0x22) +0 +0 +SELECT MATCH(`a`) AGAINST (0x2261616122) FROM `t`; +MATCH(`a`) AGAINST (0x2261616122) +0 +0.0906190574169159 +SELECT MATCH(`a`) AGAINST (0x2261dd6122) FROM `t`; +MATCH(`a`) AGAINST (0x2261dd6122) +0 +0 +SELECT MATCH(`a`) AGAINST (0x2261dd612222226122) FROM `t`; +MATCH(`a`) AGAINST (0x2261dd612222226122) +0 +0 +DROP TABLE t; +CREATE TABLE t(a CHAR(1),FULLTEXT KEY(a)) ENGINE=INNODB; +HANDLER t OPEN; +HANDLER t READ a NEXT; +a +HANDLER t READ a PREV; +a +DROP TABLE t; +CREATE TABLE `%`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; +CREATE TABLE `A B`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; +DROP TABLE `%`; +DROP TABLE `A B`; +CREATE TABLE `t-26`(a VARCHAR(10),FULLTEXT KEY(a)) ENGINE=INNODB; +INSERT INTO `t-26` VALUES('117'); +DROP TABLE `t-26`; +CREATE TABLE `t1` ( +`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, +`content` TEXT NOT NULL, +PRIMARY KEY (`id`), +FULLTEXT INDEX `IDX_CONTEXT_FULLTEXT`(`content`) +) +ENGINE = InnoDB; +insert into t1 (content) +values +('This is a story which has has a complicated phrase structure here in the +middle'), +('This is a story which doesn''t have that text'), +('This is a story that has complicated the phrase structure'); +select * from t1 +where match(content) against('"complicated phrase structure"' in boolean +mode); +id content +1 This is a story which has has a complicated phrase structure here in the +middle +select * from t1 +where match(content) against('+"complicated phrase structure"' in boolean +mode); +id content +1 This is a story which has has a complicated phrase structure here in the +middle +select * from t1 +where match(content) against('"complicated the phrase structure"' in boolean +mode); +id content +3 This is a story that has complicated the phrase structure +select * from t1 where match(content) against('+"this is a story which" +"complicated the phrase structure"' in boolean mode); +id content +select * from t1 where match(content) against('"the complicated the phrase structure"' in boolean mode); +id content +3 This is a story that has complicated the phrase structure +select * from t1 where match(content) against('"complicated a phrase structure"' in boolean mode); +id content +DROP TABLE t1; +CREATE TABLE my (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, +c VARCHAR(32), FULLTEXT(c)) ENGINE = INNODB; +INSERT INTO my (c) VALUES ('green-iguana'); +SELECT * FROM my WHERE MATCH(c) AGAINST ('green-iguana'); +id c +1 green-iguana +DROP TABLE my; +CREATE TABLE ift ( +`a` int(11) NOT NULL, +`b` text, +PRIMARY KEY (`a`), +FULLTEXT KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO ift values (1, "skip"); +INSERT INTO ift values (2, "skip and networking"); +INSERT INTO ift values (3, "--skip-networking"); +INSERT INTO ift values (4, "-donot--skip-networking"); +SELECT * FROM ift WHERE MATCH (b) AGAINST ('--skip-networking'); +a b +2 skip and networking +3 --skip-networking +4 -donot--skip-networking +1 skip +SELECT * FROM ift WHERE MATCH (b) AGAINST ('skip-networking'); +a b +2 skip and networking +3 --skip-networking +4 -donot--skip-networking +1 skip +SELECT * FROM ift WHERE MATCH (b) AGAINST ('----'); +a b +SELECT * FROM ift WHERE MATCH (b) AGAINST ('-donot--skip-networking'); +a b +4 -donot--skip-networking +2 skip and networking +3 --skip-networking +1 skip +DROP TABLE ift; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('( that''s me )','When configured properly, MySQL ...'); +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('( yours''s* )' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('s*' IN BOOLEAN MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('stands\'] | * | show[@database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +5 MySQL vs. YourSQL In the following database comparison ... +DROP TABLE articles; +CREATE TABLE t1(a TEXT CHARACTER SET LATIN1, FULLTEXT INDEX(a)) ENGINE=INNODB; +SELECT * FROM t1 WHERE MATCH(a) AGAINST("*"); +ERROR 42000: syntax error, unexpected $end, expecting FTS_TERM or FTS_NUMB or '*' +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +FULLTEXT (a) +) ENGINE= InnoDB; +INSERT INTO t1 (a) VALUES +('Do you know MySQL is a good database'), +('How to build a good database'), +('Do you know'), +('Do you know MySQL'), +('How to use MySQL'), +('Do you feel good'), +('MySQL is good'), +('MySQL is good to know'), +('What is database'); +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know mysql"' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql")' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('("know mysql" good)' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +2 How to build a good database +6 Do you feel good +7 MySQL is good +8 MySQL is good to know +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql" good)' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +2 How to build a good database +6 Do you feel good +7 MySQL is good +8 MySQL is good to know +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('(good "know mysql")' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +2 How to build a good database +6 Do you feel good +7 MySQL is good +8 MySQL is good to know +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+(good "know mysql")' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +2 How to build a good database +6 Do you feel good +7 MySQL is good +8 MySQL is good to know +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql" "good database")' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +2 How to build a good database +4 Do you know MySQL +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know mysql" +"good database"' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know database"@4' IN BOOLEAN MODE); +id a +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know database"@8' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +FULLTEXT (a) +) ENGINE= InnoDB; +INSERT INTO t1 (a) VALUES +('know mysql good database'); +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"good database"' IN BOOLEAN MODE); +id a +1 know mysql good database +DROP TABLE t1; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES ('Test Article','blah blah +blah'),("Matt's Noise",'this is noisy'),('February Weather','It was terrible +this year.'),('Peter Pan','Tis a kids story.'),('Test1','nada'),('Database +database database','foo database database database'),('Database article +title','body with lots of words.'),('myfulltext database', 'my test fulltext +database'); +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +id title body +6 Database +database database foo database database database +8 myfulltext database my test fulltext +database +7 Database article +title body with lots of words. +1 Test Article blah blah +blah +2 Matt's Noise this is noisy +3 February Weather It was terrible +this year. +4 Peter Pan Tis a kids story. +5 Test1 nada +DELETE from articles WHERE title like "myfulltext database"; +INSERT INTO articles (title,body) VALUES ('myfulltext database', 'my test fulltext database'); +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +id title body +6 Database +database database foo database database database +9 myfulltext database my test fulltext database +7 Database article +title body with lots of words. +1 Test Article blah blah +blah +2 Matt's Noise this is noisy +3 February Weather It was terrible +this year. +4 Peter Pan Tis a kids story. +5 Test1 nada +DELETE from articles WHERE title like "myfulltext database"; +INSERT INTO articles (title,body) VALUES ('myfulltext database', 'my test fulltext database'); +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +id title body +6 Database +database database foo database database database +10 myfulltext database my test fulltext database +7 Database article +title body with lots of words. +1 Test Article blah blah +blah +2 Matt's Noise this is noisy +3 February Weather It was terrible +this year. +4 Peter Pan Tis a kids story. +5 Test1 nada +DROP TABLE articles; +CREATE TABLE t1( +a TEXT CHARSET ujis COLLATE ujis_japanese_ci, +b TEXT CHARSET utf8mb4 COLLATE utf8mb4_turkish_ci, +c TEXT CHARSET eucjpms COLLATE eucjpms_bin, +d TEXT CHARSET utf8mb4, +FULLTEXT INDEX(a), +FULLTEXT INDEX(b), +FULLTEXT INDEX(c), +FULLTEXT INDEX(d) +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +('myisam', 'myisam', 'myisam', 'myisam'), +('innodb', 'innodb', 'innodb', 'innodb'), +('innodb myisam', 'innodb myisam', 'innodb myisam', 'innodb myisam'), +('memory', 'memory', 'memory', 'memory'), +('archive', 'archive', 'archive', 'archive'), +('federated', 'federated', 'federated', 'federated'), +('storage engine innodb', 'storage engine innodb', 'storage engine innodb', 'storage engine innodb'), +('storage engine myisam', 'storage engine myisam', 'storage engine myisam', 'storage engine myisam'), +('innobase', 'innobase', 'innobase', 'innobase'), +('myisam innodb', 'myisam innodb', 'myisam innodb', 'myisam innodb'), +('innodb myisam engines', 'innodb myisam engines', 'innodb myisam engines', 'innodb myisam engines'); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00)); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', ' ', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '&', 0x00, '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '&', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '%', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +a +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +a +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +a +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +a +innodb myisam +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +a +innodb myisam +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +a +innodb myisam +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +a +innodb myisam +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected FTS_TERM, expecting FTS_NUMB +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00)); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', ' ', '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '&', 0x00, '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, '&', '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '%', '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +b +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +b +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +b +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +b +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +b +innodb myisam +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +b +innodb myisam +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected FTS_TERM, expecting FTS_NUMB +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00)); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', ' ', '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '&', 0x00, '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, '&', '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '%', '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +c +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +c +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +c +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +c +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +c +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +c +innodb myisam +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +c +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +c +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +c +innodb myisam +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +c +innodb myisam +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +c +innodb myisam +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected FTS_TERM, expecting FTS_NUMB +ALTER TABLE t1 ENGINE = MyISAM; +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00)); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', ' ', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '&', 0x00, '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '&', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '%', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +a +innodb +innodb myisam +myisam innodb +storage engine innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +a +innodb +innodb myisam +myisam innodb +storage engine innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +a +innodb +innodb myisam +myisam innodb +storage engine innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +a +innodb myisam +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +a +innodb myisam +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); +a +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +FULLTEXT (a) +) ENGINE= InnoDB; +INSERT INTO t1 (a) VALUES +('know database'),('good database'), ('gmail email'), ('ghome windows'); +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g *' IN NATURAL LANGUAGE MODE); +id a +2 good database +3 gmail email +4 ghome windows +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +3 gmail email +4 ghome windows +2 good database +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * k *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +1 know database +3 gmail email +4 ghome windows +2 good database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * k * d *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +1 know database +3 gmail email +4 ghome windows +2 good database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * go *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +2 good database +3 gmail email +4 ghome windows +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * good' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +2 good database +3 gmail email +4 ghome windows +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('gm * go *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +3 gmail email +2 good database +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('good *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +2 good database +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g* database' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +1 know database +2 good database +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/misc_1.result b/mysql-test/suite/innodb_fts/r/misc_1.result new file mode 100644 index 00000000000..69a234fb0be --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/misc_1.result @@ -0,0 +1,922 @@ +set names utf8; +call mtr.add_suppression("\\[Warning\\] InnoDB: A new Doc ID must be supplied while updating FTS indexed columns."); +call mtr.add_suppression("\\[Warning\\] InnoDB: FTS Doc ID must be larger than [0-9]+ for table `test`.`t1`"); +CREATE TABLE t1 ( +id1 INT , +a1 VARCHAR(200) , +b1 TEXT , +FULLTEXT KEY (a1,b1), PRIMARY KEY (a1, id1) +) CHARACTER SET = utf8 , ENGINE = InnoDB; +CREATE TABLE t2 ( +id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a2 VARCHAR(200), +b2 TEXT , +FOREIGN KEY (a2) REFERENCES t1(a1) ON UPDATE CASCADE, +FULLTEXT KEY (b2,a2) +) CHARACTER SET = utf8 ,ENGINE = InnoDB; +INSERT INTO t1 (id1,a1,b1) VALUES +(1,'MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , +(2,'How To Use MySQL Well','After you went through a ...'), +(3,'Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t1 (id1,a1,b1) VALUES +(4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +(5,'MySQL vs. YourSQL','In the following database comparison ...'), +(6,'MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t2 (a2,b2) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tricks','1. Never run mysqld as root. 2. ...'); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a2`) REFERENCES `t1` (`a1`) ON UPDATE CASCADE) +DELETE FROM t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a2`) REFERENCES `t1` (`a1`) ON UPDATE CASCADE) +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 'b1' +test.t1 analyze status OK +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze Warning Engine-independent statistics are not collected for column 'b2' +test.t2 analyze status OK +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial') ORDER BY id1; +id1 +1 +3 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial') ORDER BY id2; +id2 +1 +3 +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ORDER BY id1; +id1 +1 +2 +3 +4 +5 +6 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ORDER BY id2; +id2 +1 +2 +3 +4 +5 +6 +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id1; +id1 +1 +2 +3 +4 +5 +6 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id2; +id2 +1 +2 +3 +4 +5 +6 +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +id1 +1 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +id2 +1 +set global innodb_optimize_fulltext_only=1; +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +set global innodb_optimize_fulltext_only=0; +UPDATE t1 SET a1 = "changing column - on update cascade" , b1 = "to check foreign constraint" WHERE +MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +id1 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +id2 +3 +6 +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('+update +cascade' IN BOOLEAN MODE) ORDER BY id1; +id1 +1 +2 +3 +4 +5 +6 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('+update +cascade' IN BOOLEAN MODE) ORDER BY id2; +id2 +1 +2 +3 +4 +5 +6 +SELECT id2 FROM t2 WHERE a2 LIKE '%UPDATE CASCADE%' ORDER BY id2; +id2 +1 +2 +3 +4 +5 +6 +DROP TABLE t2 , t1; +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), +fulltext key(s2), +foreign key (s1,s2) references t1 (s1,s2) on update cascade) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s2 = 'Rainbows' where s2 <> 'Sunshine'; +commit; +select * from t2 where match(s2) against ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), +fulltext key(s2), +foreign key (s1,s2) references t1 (s1,s2) on delete cascade) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +delete from t1 where s2 <> 'Sunshine'; +select * from t2 where match(s2) against ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), +fulltext key(s2), +foreign key (s1,s2) references t1 (s1,s2) on delete set null) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +delete from t1 where s2 <> 'Sunshine'; +select * from t2 where match(s2) against ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), +fulltext key(s2), +foreign key (s1,s2) references t1 (s1,s2) on update set null) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s2 = 'Rainbows' where s2 <> 'Sunshine'; +commit; +select * from t2 where match(s2) against ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +create table t1 (s1 bigint unsigned not null, s2 varchar(200), +primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL, s2 varchar(200), +foreign key (FTS_DOC_ID) references t1 (s1) +on update cascade) ENGINE = InnoDB; +create fulltext index idx on t2(s2); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `FTS_DOC_ID` bigint(20) unsigned NOT NULL, + `s2` varchar(200) DEFAULT NULL, + KEY `FTS_DOC_ID` (`FTS_DOC_ID`), + FULLTEXT KEY `idx` (`s2`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`FTS_DOC_ID`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s1 = 3 where s1=1; +select * from t2 where match(s2) against ('sunshine'); +FTS_DOC_ID s2 +3 Sunshine +update t1 set s1 = 1 where s1=3; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`FTS_DOC_ID`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE) +DROP TABLE t2 , t1; +CREATE TABLE t1 ( +id1 INT , +a1 VARCHAR(200) PRIMARY KEY, +b1 TEXT character set utf8 , +FULLTEXT KEY (a1,b1) +) CHARACTER SET = utf8 ,ENGINE = InnoDB; +CREATE TABLE t2 ( +id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a2 VARCHAR(200), +b2 TEXT character set utf8 , +FOREIGN KEY (a2) REFERENCES t1(a1) ON DELETE CASCADE, +FULLTEXT KEY (b2,a2) +) CHARACTER SET = utf8 ,ENGINE = InnoDB; +INSERT INTO t1 (id1,a1,b1) VALUES +(1,'MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , +(2,'How To Use MySQL Well','After you went through a ...'), +(3,'Optimizing MySQL','In this tutorial we will show ...'), +(4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +(5,'MySQL vs. YourSQL','In the following database comparison ...'), +(6,'MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +DELETE FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +id2 a2 b2 +SELECT * FROM t1 WHERE a1 LIKE '%tutorial%'; +id1 a1 b1 +SELECT * FROM t2 WHERE a2 LIKE '%tutorial%'; +id2 a2 b2 +DROP TABLE t2 , t1; +call mtr.add_suppression("\\[ERROR\\] InnoDB: FTS Doc ID must be larger than 3 for table `test`.`t2`"); +CREATE TABLE t1 ( +id1 INT , +a1 VARCHAR(200) , +b1 TEXT , +FULLTEXT KEY (a1,b1), PRIMARY KEY(a1, id1) +) CHARACTER SET = utf8 , ENGINE = InnoDB; +CREATE TABLE t2 ( +id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a2 VARCHAR(200), +b2 TEXT , +FOREIGN KEY (a2) REFERENCES t1(a1) ON UPDATE CASCADE, +FULLTEXT KEY (b2,a2) +) CHARACTER SET = utf8 ,ENGINE = InnoDB; +INSERT INTO t1 (id1,a1,b1) VALUES +(1,'MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , +(2,'How To Use MySQL Well','After you went through a ...'), +(3,'Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +START TRANSACTION; +INSERT INTO t1 (id1,a1,b1) VALUES +(4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +(5,'MySQL vs. YourSQL','In the following database comparison ...'), +(6,'MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tricks','1. Never run mysqld as root. 2. ...'); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a2`) REFERENCES `t1` (`a1`) ON UPDATE CASCADE) +DELETE FROM t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a2`) REFERENCES `t1` (`a1`) ON UPDATE CASCADE) +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial') ORDER BY id1; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial') ORDER BY id2; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ORDER BY id1; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ORDER BY id2; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id1; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id2; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('root') ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('root') ; +id2 a2 b2 +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('mysqld (+root)' IN BOOLEAN MODE) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('mysqld (-root)' IN BOOLEAN MODE) ; +id2 a2 b2 +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('root' WITH QUERY EXPANSION) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('root' WITH QUERY EXPANSION) ; +id2 a2 b2 +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('"database comparison"@02' IN BOOLEAN MODE) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('"database comparison"@02' IN BOOLEAN MODE) ; +id2 a2 b2 +SELECT * FROM t1 ORDER BY id1; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +SELECT * FROM t2 ORDER BY id2; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +COMMIT; +START TRANSACTION; +UPDATE t1 SET a1 = "changing column - on UPDATE cascade" , b1 = "to check foreign constraint" WHERE +MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +COMMIT; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +id2 a2 b2 +3 changing column - on UPDATE cascade In this tutorial we will show ... +6 changing column - on UPDATE cascade When configured properly, MySQL ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('+UPDATE +cascade' IN BOOLEAN MODE) ORDER BY id1; +id1 a1 b1 +1 changing column - on UPDATE cascade to check foreign constraint +2 changing column - on UPDATE cascade to check foreign constraint +3 changing column - on UPDATE cascade to check foreign constraint +4 changing column - on UPDATE cascade to check foreign constraint +5 changing column - on UPDATE cascade to check foreign constraint +6 changing column - on UPDATE cascade to check foreign constraint +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('+UPDATE +cascade' IN BOOLEAN MODE) ORDER BY id2; +id2 a2 b2 +1 changing column - on UPDATE cascade DBMS stands for DataBase VÃÆ·Wİ... +2 changing column - on UPDATE cascade After you went through a ... +3 changing column - on UPDATE cascade In this tutorial we will show ... +4 changing column - on UPDATE cascade 1. Never run mysqld as root. 2. ... +5 changing column - on UPDATE cascade In the following database comparison ... +6 changing column - on UPDATE cascade When configured properly, MySQL ... +SELECT * FROM t2 WHERE a2 LIKE '%UPDATE CASCADE%' ORDER BY id2; +id2 a2 b2 +1 changing column - on UPDATE cascade DBMS stands for DataBase VÃÆ·Wİ... +2 changing column - on UPDATE cascade After you went through a ... +3 changing column - on UPDATE cascade In this tutorial we will show ... +4 changing column - on UPDATE cascade 1. Never run mysqld as root. 2. ... +5 changing column - on UPDATE cascade In the following database comparison ... +6 changing column - on UPDATE cascade When configured properly, MySQL ... +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +set global innodb_file_per_table=1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) CHARACTER SET = utf8, ROW_FORMAT=COMPRESSED, ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `a` varchar(200) DEFAULT NULL, + `b` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`a`,`b`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci ROW_FORMAT=COMPRESSED +SELECT count(*) FROM information_schema.innodb_sys_tables WHERE name LIKE "%FTS_%" AND space !=0; +count(*) +11 +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +ANALYZE TABLE t1; +SELECT * FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +3 Optimizing MySQL In this tutorial we will show ... +select * from t1 where MATCH(a,b) AGAINST("+tutorial +VÃÆ·Wİ" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +select * from t1 where MATCH(a,b) AGAINST("+-VÃÆ·Wİ" IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected '-' +select * from t1 where MATCH(a,b) AGAINST("+Mysql +(tricks never)" IN BOOLEAN MODE); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +select * from t1 where MATCH(a,b) AGAINST("+mysql -(tricks never)" IN BOOLEAN MODE) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +select *, MATCH(a,b) AGAINST("mysql stands" IN BOOLEAN MODE) as x from t1 ORDER BY id; +id a b x +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... 0.6055193543434143 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.000000001885928302414186 +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... 0.000000001885928302414186 +5 MySQL vs. YourSQL In the following database comparison ... 0.000000001885928302414186 +6 MySQL Security When configured properly, MySQL ... 0.000000003771856604828372 +select * from t1 where MATCH a,b AGAINST ("+database* +VÃÆ·W*" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +select * from t1 where MATCH a,b AGAINST ('"security mysql"' IN BOOLEAN MODE); +id a b +select * from t1 where MATCH(a,b) AGAINST ("VÃÆ·Wİ" WITH QUERY EXPANSION) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +ALTER TABLE t1 DROP INDEX idx; +CREATE FULLTEXT INDEX idx on t1 (a,b); +SELECT * FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +3 Optimizing MySQL In this tutorial we will show ... +select * from t1 where MATCH(a,b) AGAINST("+tutorial +VÃÆ·Wİ" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +select * from t1 where MATCH(a,b) AGAINST("+dbms" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +select * from t1 where MATCH(a,b) AGAINST("+Mysql +(tricks never)" IN BOOLEAN MODE); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +select * from t1 where MATCH(a,b) AGAINST("+mysql -(tricks never)" IN BOOLEAN MODE) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +select *, MATCH(a,b) AGAINST("mysql VÃÆ·Wİ" IN BOOLEAN MODE) as x from t1 ORDER BY id; +id a b x +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... 0.6055193543434143 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.000000001885928302414186 +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... 0.000000001885928302414186 +5 MySQL vs. YourSQL In the following database comparison ... 0.000000001885928302414186 +6 MySQL Security When configured properly, MySQL ... 0.000000003771856604828372 +select * from t1 where MATCH a,b AGAINST ('"security mysql"' IN BOOLEAN MODE); +id a b +select * from t1 where MATCH(a,b) AGAINST ("VÃÆ·Wİ" WITH QUERY EXPANSION) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÃÆ·Wİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +INSERT INTO t1 (a,b) VALUES +('test proximity search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test proximity fts search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test more proximity fts search, test, more proximity and phrase', +'search, with proximity innodb'); +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@2' IN BOOLEAN MODE); +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@1' IN BOOLEAN MODE); +id a b +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@3' IN BOOLEAN MODE) ORDER BY id; +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +10 test more proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"test proximity"@5' IN BOOLEAN MODE) ORDER BY id; +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +10 test more proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more test proximity"@2' IN BOOLEAN MODE); +id a b +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); +id a b +10 test more proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more fts proximity"@03' IN BOOLEAN MODE); +id a b +10 test more proximity fts search, test, more proximity and phrase search, with proximity innodb +UPDATE t1 SET a = UPPER(a) , b = UPPER(b) ; +UPDATE t1 SET a = UPPER(a) , b = LOWER(b) ; +select * from t1 where MATCH(a,b) AGAINST("+tutorial +dbms" IN BOOLEAN MODE); +id a b +1 MYSQL TUTORIAL dbms stands for database vðʒwi... +select * from t1 where MATCH(a,b) AGAINST("+VÃÆ·Wİ" IN BOOLEAN MODE); +id a b +1 MYSQL TUTORIAL dbms stands for database vðʒwi... +SELECT * FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; +id a b +1 MYSQL TUTORIAL dbms stands for database vðʒwi... +3 OPTIMIZING MYSQL in this tutorial we will show ... +DELETE FROM t1 WHERE MATCH (a,b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +DELETE FROM t1 WHERE MATCH (a,b) AGAINST ('"proximity search"@14' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id a b +SELECT * FROM t1 ORDER BY id; +id a b +2 HOW TO USE MYSQL WELL after you went through a ... +4 1001 MYSQL TRICKS 1. never run mysqld as root. 2. ... +5 MYSQL VS. YOURSQL in the following database comparison ... +6 MYSQL SECURITY when configured properly, mysql ... +7 TEST QUERY EXPANSION for database ... +DROP TABLE t1; +SET GLOBAL innodb_file_per_table=1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) CHARACTER SET = utf8, ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES +('Я могу еÑть Ñтекло', 'оно мне не вредит'), +('Мога да Ñм Ñтъкло', 'то не ми вреди'), +('ΜποÏá¿¶ νὰ φάω σπασμένα' ,'γυαλιὰ χωÏá½¶Ï‚ νὰ πάθω τίποτα'), +('PříliÅ¡ žluÅ¥ouÄký kůň', 'úpÄ›l Äábelské kódy'), +('Sævör grét', 'áðan því úlpan var ónýt'), +('ã†ã‚ã®ãŠãã‚„ã¾','ã‘ãµã“ãˆã¦'), +('ã„ã‚ã¯ã«ã»ã¸ã©ã€€ã¡ã‚Šã¬ã‚‹','ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš'); +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','request docteam@oraclehelp.com ...') , +('Trial version','query performace @1255 minute on 2.1Hz Memory 2GB...') , +('when To Use MySQL Well','for free faq mail@xyz.com ...'); +CREATE FULLTEXT INDEX idx on t1 (a,b); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("вредит χωÏá½¶Ï‚") ORDER BY id; +id a b +1 Я могу еÑть Ñтекло оно мне не вредит +3 ΜποÏá¿¶ νὰ φάω σπασμένα γυαλιὰ χωÏá½¶Ï‚ νὰ πάθω τίποτα +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("оно" WITH QUERY EXPANSION); +id a b +1 Я могу еÑть Ñтекло оно мне не вредит +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("вред*" IN BOOLEAN MODE) ORDER BY id; +id a b +1 Я могу еÑть Ñтекло оно мне не вредит +2 Мога да Ñм Ñтъкло то не ми вреди +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+γυαλιὰ +tutorial" IN BOOLEAN MODE); +id a b +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+tutorial +(Мога τίποτα)" IN BOOLEAN MODE); +id a b +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš"); +id a b +7 ã„ã‚ã¯ã«ã»ã¸ã©ã€€ã¡ã‚Šã¬ã‚‹ ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ã¡ã‚Šã¬ã‚‹" WITH QUERY EXPANSION); +id a b +7 ã„ã‚ã¯ã«ã»ã¸ã©ã€€ã¡ã‚Šã¬ã‚‹ ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("+ã‚ã•ãゆã‚ã¿ã˜ã€€+ã‚‘ã²ã‚‚ã›ãš" IN BOOLEAN MODE); +id a b +7 ã„ã‚ã¯ã«ã»ã¸ã©ã€€ã¡ã‚Šã¬ã‚‹ ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("ã†ã‚ã®ãŠã*" IN BOOLEAN MODE); +id a b +6 ã†ã‚ã®ãŠãã‚„ã¾ ã‘ãµã“ãˆã¦ +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); +id a b +5 Sævör grét áðan því úlpan var ónýt +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"γυαλιὰ χωÏá½¶Ï‚"@2' IN BOOLEAN MODE); +id a b +3 ΜποÏá¿¶ νὰ φάω σπασμένα γυαλιὰ χωÏá½¶Ï‚ νὰ πάθω τίποτα +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"query performace"@02' IN BOOLEAN MODE); +id a b +9 Trial version query performace @1255 minute on 2.1Hz Memory 2GB... +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"πάθω τίποτα"@2' IN BOOLEAN MODE); +id a b +3 ΜποÏá¿¶ νὰ φάω σπασμένα γυαλιὰ χωÏá½¶Ï‚ νὰ πάθω τίποτα +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"ã‚ã•ãゆã‚ã¿ã˜ ã‚‘ã²ã‚‚ã›ãš"@1' IN BOOLEAN MODE); +id a b +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"ã‚ã•ãゆã‚ã¿ã˜ ã‚‘ã²ã‚‚ã›ãš"@2' IN BOOLEAN MODE); +id a b +7 ã„ã‚ã¯ã«ã»ã¸ã©ã€€ã¡ã‚Šã¬ã‚‹ ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš +ALTER TABLE t1 DROP INDEX idx; +CREATE FULLTEXT INDEX idx on t1 (a,b); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ã‚ã•ãゆã‚ã¿ã˜ ã‚‘ã²ã‚‚ã›ãš"); +id a b +7 ã„ã‚ã¯ã«ã»ã¸ã©ã€€ã¡ã‚Šã¬ã‚‹ ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš +UPDATE t1 SET a = "Pchnąć w tÄ™ łódź jeża" , b = "lub osiem skrzyÅ„ fig" WHERE MATCH(a,b) AGAINST ("ã‚ã•ãゆã‚ã¿ã˜ ã‚‘ã²ã‚‚ã›ãš"); +UPDATE t1 SET a = "Ð’ чащах юга жил-был цитруÑ? Да", b = "но фальшивый ÑкземплÑÑ€! ёъ" WHERE MATCH(a,b) AGAINST ("вред*" IN BOOLEAN MODE); +DELETE FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš"); +id a b +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("łódź osiem"); +id a b +7 Pchnąć w tÄ™ łódź jeża lub osiem skrzyÅ„ fig +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("вред*" IN BOOLEAN MODE); +id a b +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("фальшив*" IN BOOLEAN MODE) ORDER BY id; +id a b +1 Ð’ чащах юга жил-был цитруÑ? Да но фальшивый ÑкземплÑÑ€! ёъ +2 Ð’ чащах юга жил-был цитруÑ? Да но фальшивый ÑкземплÑÑ€! ёъ +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); +id a b +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"łódź jeża"@2' IN BOOLEAN MODE); +id a b +7 Pchnąć w tÄ™ łódź jeża lub osiem skrzyÅ„ fig +SELECT * FROM t1 ORDER BY id; +id a b +1 Ð’ чащах юга жил-был цитруÑ? Да но фальшивый ÑкземплÑÑ€! ёъ +2 Ð’ чащах юга жил-был цитруÑ? Да но фальшивый ÑкземплÑÑ€! ёъ +3 ΜποÏá¿¶ νὰ φάω σπασμένα γυαλιὰ χωÏá½¶Ï‚ νὰ πάθω τίποτα +4 PříliÅ¡ žluÅ¥ouÄký kůň úpÄ›l Äábelské kódy +6 ã†ã‚ã®ãŠãã‚„ã¾ ã‘ãµã“ãˆã¦ +7 Pchnąć w tÄ™ łódź jeża lub osiem skrzyÅ„ fig +8 MySQL Tutorial request docteam@oraclehelp.com ... +9 Trial version query performace @1255 minute on 2.1Hz Memory 2GB... +10 when To Use MySQL Well for free faq mail@xyz.com ... +DROP TABLE t1; +CREATE TABLE t1(ID INT PRIMARY KEY, +no_fts_field VARCHAR(10), +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +ID no_fts_field fts_field +1 AAA BBB +UPDATE t1 SET fts_field='anychange' where id = 1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); +ID no_fts_field fts_field +1 AAA anychange +UPDATE t1 SET no_fts_field='anychange' where id = 1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); +ID no_fts_field fts_field +1 anychange anychange +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where id = 1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); +ID no_fts_field fts_field +1 anychange other +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +ID no_fts_field fts_field +DROP INDEX f on t1; +UPDATE t1 SET fts_field='anychange' where id = 1; +UPDATE t1 SET no_fts_field='anychange' where id = 1; +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where id = 1; +CREATE FULLTEXT INDEX f ON t1(FTS_FIELD); +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); +ID no_fts_field fts_field +1 anychange other +DROP TABLE t1; +CREATE TABLE t1(`FTS_DOC_ID` serial, +no_fts_field VARCHAR(10), +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); +UPDATE t1 SET fts_field='anychange' where FTS_DOC_ID = 1; +ERROR HY000: Invalid InnoDB FTS Doc ID +UPDATE t1 SET fts_field='anychange', FTS_DOC_ID = 2 where FTS_DOC_ID = 1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); +FTS_DOC_ID no_fts_field fts_field +2 AAA anychange +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +FTS_DOC_ID no_fts_field fts_field +UPDATE t1 SET no_fts_field='anychange' where FTS_DOC_ID = 2; +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); +FTS_DOC_ID no_fts_field fts_field +2 anychange anychange +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where FTS_DOC_ID = 2; +ERROR HY000: Invalid InnoDB FTS Doc ID +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); +FTS_DOC_ID no_fts_field fts_field +UPDATE t1 SET FTS_DOC_ID = 1 where FTS_DOC_ID = 2; +ERROR HY000: Invalid InnoDB FTS Doc ID +DROP INDEX f ON t1; +UPDATE t1 SET fts_field='newchange' where FTS_DOC_ID = 2; +UPDATE t1 SET no_fts_field='anychange' where FTS_DOC_ID = 2; +SELECT * FROM t1; +FTS_DOC_ID no_fts_field fts_field +2 anychange newchange +DROP TABLE t1; +CREATE TABLE t1(ID INT PRIMARY KEY, +no_fts_field VARCHAR(10), +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field), index k(fts_field)) ENGINE=INNODB; +CREATE TABLE t2(ID INT PRIMARY KEY, +no_fts_field VARCHAR(10), +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field), +INDEX k2(fts_field), +FOREIGN KEY(fts_field) REFERENCES +t1(fts_field) ON UPDATE CASCADE) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); +INSERT INTO t2 VALUES (1, 'AAA', 'BBB'); +update t1 set fts_field='newchange' where id =1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +ID no_fts_field fts_field +SELECT * FROM t2 WHERE MATCH(fts_field) against("BBB"); +ID no_fts_field fts_field +SELECT * FROM t1 WHERE MATCH(fts_field) against("newchange"); +ID no_fts_field fts_field +1 AAA newchange +SELECT * FROM t2 WHERE MATCH(fts_field) against("newchange"); +ID no_fts_field fts_field +1 AAA newchange +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1(id INT PRIMARY KEY, +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; +CREATE TABLE t2(id INT PRIMARY KEY, +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; +INSERT INTO t1 values (1,'100'),(2,'200'),(3,'300'),(4,'400'),(5,'500'),(6,'600'), (7,'700'),(8,'800'),(9,'900'),(10,'1000'),(11,'1100'),(12,'1200'); +INSERT INTO t2 values (1,'100'),(2,'200'),(3,'300'),(4,'400'),(5,'500'),(6,'600'), (7,'700'),(8,'800'); +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'foo'); +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'foo') WHERE t1.fts_field = "100foo"; +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'xoo'), t2.fts_field = CONCAT(t1.fts_field, 'xoo') where t1.fts_field=CONCAT(t2.fts_field, 'foo'); +SELECT * FROM t1 WHERE MATCH(fts_field) against("100foofoo"); +id fts_field +1 100foofoo +SELECT * FROM t1 WHERE MATCH(fts_field) against("100foo"); +id fts_field +SELECT * FROM t1 WHERE MATCH(fts_field) against("100"); +id fts_field +SELECT * FROM t2 WHERE MATCH(fts_field) against("400fooxoo"); +id fts_field +4 400fooxoo +SELECT * FROM t2 WHERE MATCH(fts_field) against("100"); +id fts_field +1 100 +SELECT * FROM t2 WHERE MATCH(fts_field) against("200"); +id fts_field +SELECT * FROM t2 WHERE MATCH(fts_field) against("400"); +id fts_field +DROP TABLE t1; +DROP TABLE t2; + +BUG#13701973/64274: MYSQL THREAD WAS SUSPENDED WHEN EXECUTE UPDATE QUERY + +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +CREATE TABLE t1 ( +t1_id INT(10) UNSIGNED NOT NULL, +t2_id INT(10) UNSIGNED DEFAULT NULL, +PRIMARY KEY (t1_id), +FOREIGN KEY (t2_id) REFERENCES t2 (t2_id) +ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; +CREATE TABLE t2 ( +t1_id INT(10) UNSIGNED NOT NULL, +t2_id INT(10) UNSIGNED NOT NULL, +t3_id INT(10) UNSIGNED NOT NULL, +t4_id INT(10) UNSIGNED NOT NULL, +PRIMARY KEY (t2_id), +FOREIGN KEY (t1_id) REFERENCES t1 (t1_id), +FOREIGN KEY (t3_id) REFERENCES t3 (t3_id) +ON DELETE CASCADE ON UPDATE CASCADE, +FOREIGN KEY (t4_id) REFERENCES t4 (t4_id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( +t3_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +payload char(3), +PRIMARY KEY (t3_id) +) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1, '100'); +CREATE TABLE t4 ( +t2_id INT(10) UNSIGNED DEFAULT NULL, +t4_id INT(10) UNSIGNED NOT NULL, +PRIMARY KEY (t4_id), +FOREIGN KEY (t2_id) REFERENCES t2 (t2_id) +ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; +SET FOREIGN_KEY_CHECKS=1; +UPDATE t3 SET payload='101' WHERE t3_id=1; +SET FOREIGN_KEY_CHECKS=0; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; diff --git a/mysql-test/suite/innodb_fts/r/opt.result b/mysql-test/suite/innodb_fts/r/opt.result new file mode 100644 index 00000000000..6385ea2a778 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/opt.result @@ -0,0 +1,1650 @@ +CREATE TABLE wp( +FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, +title VARCHAR(255) NOT NULL DEFAULT '', +text MEDIUMTEXT NOT NULL, +dummy INTEGER, +PRIMARY KEY (FTS_DOC_ID), +UNIQUE KEY FTS_DOC_ID_INDEX (FTS_DOC_ID), +FULLTEXT KEY idx (title,text) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO wp (title, text) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database to database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 SELECT FTS_DOC_ID FROM wp; +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE wp; +Table Op Msg_type Msg_text +test.wp analyze status OK +SELECT FTS_DOC_ID, title, MATCH(title, text) AGAINST ('database') AS score1, +MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp; +FTS_DOC_ID title score1 score2 +1 MySQL Tutorial 0.22764469683170319 0.000000003771856604828372 +2 How To Use MySQL Well 0 0.000000001885928302414186 +3 Optimizing MySQL 0 0.000000001885928302414186 +4 1001 MySQL Tricks 0 0.000000001885928302414186 +5 MySQL vs. YourSQL 0.45528939366340637 0.000000001885928302414186 +6 MySQL Security 0 0.000000003771856604828372 +No sorting for this query +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +No sorting for this query even if MATCH is part of an expression +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') > 0.1 +ORDER BY score DESC; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +No sorting even if there are several MATCH expressions as long as the +right one is used in ORDER BY +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score1, +MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score1 DESC; +title score1 score2 +MySQL vs. YourSQL 0.45528939366340637 0.000000001885928302414186 +MySQL Tutorial 0.22764469683170319 0.000000003771856604828372 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +No Sorting since FT table is first table in query +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID = t1.i +ORDER BY score DESC; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting since there is no WHERE clause +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('database'), title AS score +FROM wp +ORDER BY score DESC; +MATCH(title, text) AGAINST ('database') score +0 1001 MySQL Tricks +0 How To Use MySQL Well +0 MySQL Security +0 Optimizing MySQL +0.22764469683170319 MySQL Tutorial +0.45528939366340637 MySQL vs. YourSQL +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 6 +Sorting since ordering on multiple columns +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC, FTS_DOC_ID; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting since ordering is not descending +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score ASC; +title score +MySQL Tutorial 0.22764469683170319 +MySQL vs. YourSQL 0.45528939366340637 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting because one is ordering on a different MATCH expression +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('mysql') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; +title score +MySQL Tutorial 0.000000003771856604828372 +MySQL vs. YourSQL 0.000000001885928302414186 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +No sorting for this query +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +Revert to table scan and sorting for this query since not +enough matching rows to satisfy LIMIT clause +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting since no LIMIT clause +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('database') AS score, title +FROM wp +ORDER BY score DESC; +score title +0 1001 MySQL Tricks +0 How To Use MySQL Well +0 MySQL Security +0 Optimizing MySQL +0.22764469683170319 MySQL Tutorial +0.45528939366340637 MySQL vs. YourSQL +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 6 +Sorting since there is a WHERE clause +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE dummy IS NULL +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting since ordering is not on a simple MATCH expressions +FLUSH STATUS; +SELECT title, (MATCH(title, text) AGAINST ('database')) * 100 AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 45.52893936634064 +MySQL Tutorial 22.76446968317032 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +No ordinary handler accesses when only accessing FTS_DOC_ID and MATCH +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +docid score +5 0.45528939366340637 +1 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Still no handler accesses when adding FTS_DOC_ID to WHERE clause +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID > 2; +docid score +5 0.45528939366340637 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Still no handler accesses when ordering by MATCH expression +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score; +docid score +1 0.22764469683170319 +5 0.45528939366340637 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 3 +Optimization is disabled when ordering on FTS_DOC_ID +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY 1 DESC; +docid score +5 0.45528939366340637 +1 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Optimization also work with several MATCH expressions +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, +MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +docid score1 score2 +5 0.45528939366340637 0.000000001885928302414186 +1 0.22764469683170319 0.000000003771856604828372 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Optimization does not apply if sorting on a different MATCH expressions +from the one used to access the +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, +MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score2 DESC; +docid score1 score2 +1 0.22764469683170319 0.000000003771856604828372 +5 0.45528939366340637 0.000000001885928302414186 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 3 +FLUSH STATUS; +Optimization does not apply for GROUP BY +SET @save_mode = @@sql_mode; +SET sql_mode = (select replace(@@sql_mode,'ONLY_FULL_GROUP_BY','')); +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +GROUP BY score; +FTS_DOC_ID score +1 0.22764469683170319 +5 0.45528939366340637 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 3 +SET sql_mode = @save_mode; +No sorting and no table access with LIMIT clause and only information +from FTS result +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +docid score +5 0.45528939366340637 +1 0.22764469683170319 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +If count optimization applies, EXPLAIN shows +"Select tables optimized away." +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(*) +2 +Verify that there was no table access +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Optimization applies also to COUNT(expr) as long as expr is not nullable +EXPLAIN SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(title) +2 +Optimization does not apply if not a single table query. +EXPLAIN SELECT count(*) +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 +SELECT count(*) +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database'); +count(*) +12 +Optimization does not apply if MATCH is part of an expression +EXPLAIN SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; +COUNT(title) +2 +Optimization does not apply if MATCH is part of an expression +EXPLAIN SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; +COUNT(title) +2 +Optimization does not apply if COUNT expression is nullable +EXPLAIN SELECT COUNT(dummy) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +SELECT COUNT(dummy) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(dummy) +0 +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score, +title +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC; +score title +0.000000001885928302414186 1001 MySQL Tricks +0.000000001885928302414186 How To Use MySQL Well +0.000000003771856604828372 MySQL Security +0.22764469683170319 Optimizing MySQL +1.6663280725479126 MySQL Tutorial +2.2718474864959717 MySQL vs. YourSQL +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 6 +Sort_scan 1 +FLUSH STATUS; +SELECT title, +MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 2.2718474864959717 +MySQL Tutorial 1.6663280725479126 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +docid score +5 2.2718474864959717 +1 1.6663280725479126 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +docid score +5 2.2718474864959717 +1 1.6663280725479126 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' WITH QUERY EXPANSION); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' WITH QUERY EXPANSION); +COUNT(*) +6 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) score, +title +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) +ORDER BY score DESC; +score title +0.000000001885928302414186 1001 MySQL Tricks +0.000000001885928302414186 How To Use MySQL Well +0.000000001885928302414186 Optimizing MySQL +0.000000003771856604828372 MySQL Security +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 4 +Sort_scan 1 +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) score, +title +FROM wp +ORDER BY score DESC; +score title +0 MySQL Tutorial +0 MySQL vs. YourSQL +0.000000001885928302414186 1001 MySQL Tricks +0.000000001885928302414186 How To Use MySQL Well +0.000000001885928302414186 Optimizing MySQL +0.000000003771856604828372 MySQL Security +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 6 +Sort_scan 1 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database'); +docid score +5 0 +1 0 +6 0.000000003771856604828372 +2 0.000000001885928302414186 +3 0.000000001885928302414186 +4 0.000000001885928302414186 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +docid score +6 0.000000003771856604828372 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 1 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 1 +Sort_scan 1 +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('+MySQL -database' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('+MySQL -database' IN BOOLEAN MODE); +COUNT(*) +4 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT title, +MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC; +title score +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 1 +Sort_scan 1 +FLUSH STATUS; +SELECT title, +MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +title score +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 1 +Sort_scan 1 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5'); +docid score +1 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +docid score +1 0.22764469683170319 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 1 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 1 +Sort_scan 1 +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE); +COUNT(*) +1 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +SELECT title, +MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC, title ASC; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +1001 MySQL Tricks 0 +How To Use MySQL Well 0 +MySQL Security 0 +Optimizing MySQL 0 +SELECT title, +MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('MySQL database' WITH QUERY EXPANSION) +ORDER BY score DESC, title ASC; +title score +MySQL Security 0.000000003771856604828372 +1001 MySQL Tricks 0.000000001885928302414186 +How To Use MySQL Well 0.000000001885928302414186 +Optimizing MySQL 0.000000001885928302414186 +MySQL Tutorial 0 +MySQL vs. YourSQL 0 +SELECT title, +MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC, title ASC; +title score +MySQL Tutorial 0 +ALTER TABLE wp ENGINE=myisam; +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; +title score +MySQL vs. YourSQL 0.9562782645225525 +MySQL Tutorial 0.5756555199623108 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 0.9562782645225525 +MySQL Tutorial 0.5756555199623108 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +docid score +5 0.9562782645225525 +1 0.5756555199623108 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 3 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +docid score +5 0.9562782645225525 +1 0.5756555199623108 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(*) +2 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 3 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +DROP TABLE wp, t1; +CREATE TABLE t1 +( +FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, +title VARCHAR(255) DEFAULT '', +text MEDIUMTEXT , +PRIMARY KEY (FTS_DOC_ID), +UNIQUE KEY FTS_DOC_ID_INDEX (FTS_DOC_ID), +FULLTEXT KEY ft_idx (title,text) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t1 (title, text) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL database','In the following database to database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'), +('InnoDB', 'InnoDB is a transaction-safe (ACID compliant) storage engine'), +('MySQL is a database management system', 'A database is a structured collection of data...'), +('MySQL databases are relational', 'A relational database stores data in separate tables rather than putting all the data in one big storeroom...'), +('MySQL software is Open Source', 'Open Source means that it is possible for anyone to use and modify the software...'), +('The MySQL Database Server is very fast, reliable, scalable, and easy to use', 'MySQL Server can run comfortably on a desktop or laptop...'), +('MySQL Server works in client/server or embedded systems', 'The MySQL Database Software is a client/server system...'), +('MyISAM', 'MyISAM is based on the older (and no longer available) ISAM storage engine but has many useful extensions'), +('A large amount of contributed MySQL software is available', 'MySQL Server has a practical set of features developed in close cooperation with our users'), +(NULL,NULL); +ANALYZE TABLE t1; +# No ranking +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE); +count(*) +6 +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('data*' IN BOOLEAN MODE) ORDER BY title LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('data*' IN BOOLEAN MODE) ORDER BY title LIMIT 3; +count(*) +6 +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +FTS_DOC_ID title +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION); +FTS_DOC_ID title +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +12 MySQL Server works in client/server or embedded systems +10 MySQL software is Open Source +4 1001 MySQL Tricks +14 A large amount of contributed MySQL software is available +2 How To Use MySQL Well +13 MyISAM +5 MySQL vs. YourSQL database +8 MySQL is a database management system +1 MySQL Tutorial +9 MySQL databases are relational +6 MySQL Security +3 Optimizing MySQL +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE); +FTS_DOC_ID title +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+for' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+for' IN BOOLEAN MODE); +FTS_DOC_ID +# No sorting by rank +EXPLAIN SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY title; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY title; +FTS_DOC_ID TITLE +9 MySQL databases are relational +8 MySQL is a database management system +12 MySQL Server works in client/server or embedded systems +1 MySQL Tutorial +5 MySQL vs. YourSQL database +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +FTS_DOC_ID +11 +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title; +FTS_DOC_ID title +4 1001 MySQL Tricks +14 A large amount of contributed MySQL software is available +2 How To Use MySQL Well +13 MyISAM +9 MySQL databases are relational +8 MySQL is a database management system +6 MySQL Security +12 MySQL Server works in client/server or embedded systems +10 MySQL software is Open Source +1 MySQL Tutorial +5 MySQL vs. YourSQL database +3 Optimizing MySQL +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title; +FTS_DOC_ID title +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +# LIMIT optimization +EXPLAIN SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +LIMIT 3; +FTS_DOC_ID TITLE +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +5 MySQL vs. YourSQL database +8 MySQL is a database management system +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +LIMIT 3; +FTS_DOC_ID +11 +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +ORDER BY title +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +ORDER BY title +LIMIT 3; +FTS_DOC_ID +11 +EXPLAIN +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title LIMIT 1; +FTS_DOC_ID +4 +EXPLAIN +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title LIMIT 1; +FTS_DOC_ID +11 +EXPLAIN +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank, FTS_DOC_ID +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank, FTS_DOC_ID +LIMIT 3; +FTS_DOC_ID rank +1 0.15835624933242798 +9 0.15835624933242798 +12 0.15835624933242798 +EXPLAIN +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank DESC, FTS_DOC_ID ASC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank DESC, FTS_DOC_ID ASC +LIMIT 3; +FTS_DOC_ID rank +11 1.5415468215942383 +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +FTS_DOC_ID rank +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 3; +FTS_DOC_ID rank +11 1.5415468215942383 +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC, +FTS_DOC_ID ASC; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC, +FTS_DOC_ID ASC; +FTS_DOC_ID rank +5 0.47506874799728394 +8 0.31671249866485596 +1 0.15835624933242798 +9 0.15835624933242798 +11 0.15835624933242798 +12 0.15835624933242798 +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) and FTS_DOC_ID > 1 +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC +LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext PRIMARY,FTS_DOC_ID_INDEX,ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) and FTS_DOC_ID > 1 +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC +LIMIT 2; +FTS_DOC_ID rank +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank +LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank +LIMIT 1; +FTS_DOC_ID rank +3 0.009391550906002522 +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank DESC +LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank DESC +LIMIT 1; +FTS_DOC_ID rank +11 15.345823287963867 +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) DESC +LIMIT 1; +FTS_DOC_ID rank +11 15.345823287963867 +# WHERE optimization on MATCH > 'some_rank' +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) > 0.1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) > 0.1; +FTS_DOC_ID +11 +5 +8 +1 +9 +12 +# additional test for correct behaviour +EXPLAIN SELECT * FROM t1 ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC LIMIT 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using temporary; Using filesort +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) AND +MATCH (title, text) AGAINST ('mysql' IN NATURAL LANGUAGE MODE) +LIMIT 6; +FTS_DOC_ID +11 +5 +8 +1 +9 +12 +# test OR condition +SELECT FTS_DOC_ID +FROM t1 +WHERE MATCH(title, text) AGAINST ('database') +OR MATCH(title, text) AGAINST ('mysql') +ORDER BY MATCH(title, text) AGAINST ('database') DESC, FTS_DOC_ID ASC; +FTS_DOC_ID +5 +8 +1 +9 +11 +12 +2 +3 +4 +6 +10 +14 +EXPLAIN SELECT FTS_DOC_ID +FROM t1 +WHERE MATCH(title, text) AGAINST ('database') +OR MATCH(title, text) AGAINST ('mysql') +ORDER BY MATCH(title, text) AGAINST ('database') DESC, FTS_DOC_ID ASC; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using where; Using temporary; Using filesort +# MATCH and GROUP BY, DISTINCT +SET sql_mode = (select replace(@@sql_mode,'ONLY_FULL_GROUP_BY','')); +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY FTS_DOC_ID +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY FTS_DOC_ID +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +FTS_DOC_ID +11 +5 +8 +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY title +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY title +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +FTS_DOC_ID +11 +5 +8 +EXPLAIN SELECT MAX(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT MAX(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +MAX(FTS_DOC_ID) +12 +EXPLAIN SELECT DISTINCT(title) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT DISTINCT(title) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +title +The MySQL Database Server is very fast, reliable, scalable, and easy to use +MySQL vs. YourSQL database +MySQL is a database management system +EXPLAIN SELECT DISTINCT(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT DISTINCT(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +FTS_DOC_ID +11 +5 +8 +SET sql_mode = @save_mode; +# FTS index access +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +FTS_DOC_ID rank +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using temporary; Using filesort +SELECT a.FTS_DOC_ID, b.FTS_DOC_ID +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and +MATCH(b.title, b.text) AGAINST ('+mysql' IN BOOLEAN MODE) and +a.FTS_DOC_ID = b.FTS_DOC_ID; +FTS_DOC_ID FTS_DOC_ID +5 5 +8 8 +1 1 +9 9 +11 11 +12 12 +EXPLAIN SELECT a.FTS_DOC_ID, b.FTS_DOC_ID +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and +MATCH(b.title, b.text) AGAINST ('+mysql' IN BOOLEAN MODE) and +a.FTS_DOC_ID = b.FTS_DOC_ID; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE a fulltext PRIMARY,FTS_DOC_ID_INDEX,ft_idx ft_idx 0 1 Using where +1 SIMPLE b eq_ref PRIMARY,FTS_DOC_ID_INDEX,ft_idx PRIMARY 8 test.a.FTS_DOC_ID 1 Using where +SELECT a.FTS_DOC_ID, MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE), +b.FTS_DOC_ID, MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and +MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE); +FTS_DOC_ID MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) FTS_DOC_ID MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +5 0.47506874799728394 5 0.47506874799728394 +5 0.47506874799728394 8 0.31671249866485596 +5 0.47506874799728394 1 0.15835624933242798 +5 0.47506874799728394 9 0.15835624933242798 +5 0.47506874799728394 11 0.15835624933242798 +5 0.47506874799728394 12 0.15835624933242798 +8 0.31671249866485596 5 0.47506874799728394 +8 0.31671249866485596 8 0.31671249866485596 +8 0.31671249866485596 1 0.15835624933242798 +8 0.31671249866485596 9 0.15835624933242798 +8 0.31671249866485596 11 0.15835624933242798 +8 0.31671249866485596 12 0.15835624933242798 +1 0.15835624933242798 5 0.47506874799728394 +1 0.15835624933242798 8 0.31671249866485596 +1 0.15835624933242798 1 0.15835624933242798 +1 0.15835624933242798 9 0.15835624933242798 +1 0.15835624933242798 11 0.15835624933242798 +1 0.15835624933242798 12 0.15835624933242798 +9 0.15835624933242798 5 0.47506874799728394 +9 0.15835624933242798 8 0.31671249866485596 +9 0.15835624933242798 1 0.15835624933242798 +9 0.15835624933242798 9 0.15835624933242798 +9 0.15835624933242798 11 0.15835624933242798 +9 0.15835624933242798 12 0.15835624933242798 +11 0.15835624933242798 5 0.47506874799728394 +11 0.15835624933242798 8 0.31671249866485596 +11 0.15835624933242798 1 0.15835624933242798 +11 0.15835624933242798 9 0.15835624933242798 +11 0.15835624933242798 11 0.15835624933242798 +11 0.15835624933242798 12 0.15835624933242798 +12 0.15835624933242798 5 0.47506874799728394 +12 0.15835624933242798 8 0.31671249866485596 +12 0.15835624933242798 1 0.15835624933242798 +12 0.15835624933242798 9 0.15835624933242798 +12 0.15835624933242798 11 0.15835624933242798 +12 0.15835624933242798 12 0.15835624933242798 +EXPLAIN SELECT a.FTS_DOC_ID, MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE), +b.FTS_DOC_ID, MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and +MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE a fulltext ft_idx ft_idx 0 1 Using where +1 SIMPLE b fulltext ft_idx ft_idx 0 1 Using where +EXPLAIN SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using where +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100 +FROM t1 WHERE MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100; +FTS_DOC_ID MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100 +1 4.92168664932251 +5 14.76505994796753 +8 9.84337329864502 +9 4.92168664932251 +11 4.92168664932251 +12 4.92168664932251 +SELECT * FROM t1 WHERE title IS NULL AND text IS NULL; +FTS_DOC_ID title text +15 NULL NULL +CREATE TABLE t2 SELECT FTS_DOC_ID as doc_id, title, text FROM t1; +ALTER TABLE t2 ADD PRIMARY KEY (doc_id); +ALTER TABLE t2 ADD FULLTEXT KEY ft_idx (title,text); +ANALYZE TABLE t2; +EXPLAIN SELECT DOC_ID FROM t2 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 15 Using where +SELECT DOC_ID FROM t2 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +DOC_ID +1 +5 +8 +9 +11 +12 +EXPLAIN SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using where +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +FTS_DOC_ID +1 +5 +8 +9 +11 +12 +DROP TABLE t1, t2; +"Check hints with uft8 charset for 2 cases" +set names utf8; +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +text TEXT +) CHARACTER SET = utf8, ENGINE=InnoDB; +INSERT INTO t1 (title, text) VALUES +('Я могу еÑть Ñтекло', 'оно мне не вредит'), +('Мога да Ñм Ñтъкло', 'то не ми вреди'), +('ΜποÏá¿¶ νὰ φάω σπασμένα' ,'γυαλιὰ χωÏá½¶Ï‚ νὰ πάθω τίποτα'), +('PříliÅ¡ žluÅ¥ouÄký kůň', 'úpÄ›l Äábelské kódy'), +('Sævör grét', 'áðan því úlpan var ónýt'), +('ã†ã‚ã®ãŠãã‚„ã¾','ã‘ãµã“ãˆã¦'), +('ã„ã‚ã¯ã«ã»ã¸ã©ã€€ã¡ã‚Šã¬ã‚‹','ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš'); +CREATE FULLTEXT INDEX idx on t1 (title, text); +# No ranking +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('вредит' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext idx idx 0 1 Using where +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('вредит' IN NATURAL LANGUAGE MODE); +count(*) +1 +EXPLAIN +SELECT * FROM t1 WHERE MATCH(title, text) AGAINST ("оно" WITH QUERY EXPANSION); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext idx idx 0 1 Using where +SELECT * FROM t1 WHERE MATCH(title, text) AGAINST ("оно" WITH QUERY EXPANSION); +FTS_DOC_ID title text +1 Я могу еÑть Ñтекло оно мне не вредит +# No sorting by rank +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+(Мога τίποτα)' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext idx idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+(Мога τίποτα)' IN BOOLEAN MODE); +FTS_DOC_ID +2 +3 +DROP TABLE t1; +# +# Bug #18924341 CRASH IN TEST_IF_SKIP_SORT_ORDER, GROUP BY MATCH AGAINST DESC +# +CREATE TABLE t1 (f1 CHAR(1), FULLTEXT KEY (f1)); +SELECT 1 FROM t1 NATURAL JOIN t1 a GROUP BY MATCH(t1.f1) AGAINST ("1") DESC; +1 +DROP TABLE t1; +# +# Bug#20261601 ASSERTION FAILED: !FIRST_QEP_TAB->TABLE()->NO_KEYREAD +# +CREATE TABLE t1(a INT PRIMARY KEY); +INSERT INTO t1 VALUES(1),(2); +SELECT (SELECT MATCH(`a`)AGAINST('1') FROM t1) FROM t1; +ERROR HY000: Can't find FULLTEXT index matching the column list +SELECT 1, a IN (SELECT a FROM t1) FROM t1; +1 a IN (SELECT a FROM t1) +1 1 +1 1 +DROP TABLE t1; +# +# Bug#20442572 ASSERTION `!FIRST_QEP_TAB->TABLE()->NO_KEYREAD' FAILED. +# Bug#75688 Assertion `!first_qep_tab->table()->no_keyread' failed. +# +CREATE TABLE t1(a INT,b POINT NOT NULL,KEY(a)); +HANDLER t1 OPEN; +select * from t1 where MATCH a,b AGAINST('"Now sUPPort"' IN BOOLEAN MODE); +a b +prepare stmt1 from "truncate t1"; +SELECT a IN(SELECT a FROM t1)FROM t1; +a IN(SELECT a FROM t1) +deallocate prepare stmt1; +DROP TABLE t1; +# +# Bug #20685427 INVALID WRITE OF FREED MEMORY IN ITEM_FUNC_MATCH::CLEANUP +# +CREATE TABLE t1(a TEXT CHARSET LATIN1, FULLTEXT KEY(a)) ENGINE=INNODB; +SELECT MATCH(a) AGAINST ('') FROM (SELECT a FROM t1 LIMIT 1) q; +ERROR HY000: Can't find FULLTEXT index matching the column list +DROP TABLE t1; +# +# Bug#21140067 EXPLAIN .. MATCH AGAINST: ASSERTION FAILED: TO <= END +# +CREATE TABLE t1(f1 CHAR(1) CHARSET latin1, FULLTEXT(f1)) ENGINE=INNODB; +EXPLAIN SELECT 1 FROM t1 WHERE 1.238585e+308 <= MATCH(f1) AGAINST ('1' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext f1 f1 0 1 Using where +EXPLAIN FORMAT = JSON SELECT 1 FROM t1 WHERE 1.238585e+308 <= MATCH(f1) AGAINST ('1' IN BOOLEAN MODE); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t1", + "access_type": "fulltext", + "possible_keys": ["f1"], + "key": "f1", + "key_length": "0", + "used_key_parts": ["f1"], + "rows": 1, + "filtered": 100, + "attached_condition": "1.238585e+308 <= (match t1.f1 against ('1' in boolean mode))" + } + } +} +DROP TABLE t1; +# +# Bug#21140088 MATCH AGAINST: ASSERTION FAILED: !TABLE || (!TABLE->READ_SET || BITMAP_IS_SET +# +SET sql_mode=''; +CREATE TABLE t1(a INT) ENGINE=INNODB; +CREATE TABLE t2(b TEXT CHARSET LATIN1, FULLTEXT(b), PRIMARY KEY(b(10))) ENGINE=INNODB; +INSERT INTO t2 VALUES ('a'),('b'); +SELECT NOT EXISTS (SELECT MATCH(b) AGAINST ('1') FROM t1) FROM t2 GROUP BY "a"; +ERROR HY000: Incorrect arguments to MATCH +DROP TABLE t1, t2; +CREATE TABLE t1(a INT) ENGINE=MyISAM; +CREATE TABLE t2(b TEXT CHARSET LATIN1, FULLTEXT(b), PRIMARY KEY(b(10))) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('a'),('b'); +SELECT NOT EXISTS (SELECT MATCH(b) AGAINST ('1' in BOOLEAN MODE) FROM t1) FROM t2 GROUP BY "a"; +NOT EXISTS (SELECT MATCH(b) AGAINST ('1' in BOOLEAN MODE) FROM t1) +1 +DROP TABLE t1, t2; +SET sql_mode=default; +# +# Bug#21140039 ASSERTION FAILED: !FIRST_QEP_TAB->TABLE()->NO_KEYREAD MATCH AGAINST..... +# +CREATE TABLE t1 +( +a INT, +b INT, +c CHAR(1) CHARSET latin1, +PRIMARY KEY (b,a), +FULLTEXT KEY (c) +) ENGINE=INNODB; +SELECT "a" NOT IN(SELECT b FROM t1 WHERE MATCH(c) AGAINST ('a' IN BOOLEAN MODE)); +"a" NOT IN(SELECT b FROM t1 WHERE MATCH(c) AGAINST ('a' IN BOOLEAN MODE)) +1 +DROP TABLE t1; +# +# Bug#21300774 ASSERT `!INIT_FTFUNCS(THD, SELECT_LEX)` IN JOIN::RESET AT SQL/SQL_SELECT.CC:874 +# +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +CREATE TABLE t2 (ft TEXT, FULLTEXT KEY ft(ft)); +INSERT INTO t2 VALUES ('abc'); +INSERT INTO t2 VALUES ('def'); +UPDATE t1 SET f1 = +(SELECT t1.f1 FROM t2 WHERE NOT TRUE AND +MATCH (ft) AGAINST ((SELECT 'xyz' FROM t2))); +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1, t2; +# +# Bug#22679209: FULL-TEXT QUERIES WITH ADDITIONAL SECONDARY INDEX +# GIVES NULL OR ZERO ROWS +# +CREATE TABLE t1 ( +f1 INTEGER, +title varchar(255), +body mediumtext, +KEY f1 (f1), +FULLTEXT KEY title (title), +FULLTEXT KEY body (body) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1, 'Insert into table', 'insert into table select from'), +(1, 'Delete from table', 'insert into table select from'), +(1, 'Update', 'perform update'), +(2, 'Insert into table', 'insert into table select from'), +( 2, 'Delete from table', 'some body text here'), +( 2, 'Update', 'perform update'), +( 3, 'Insert into table', 'insert into table select from'), +( 3, 'Delete from table', 'some body text here'); +SELECT f1 FROM t1 WHERE f1=1 AND +(MATCH (title) AGAINST ('table' IN BOOLEAN MODE) OR +MATCH (body) AGAINST ('table' IN BOOLEAN MODE)); +f1 +1 +1 +DROP TABLE t1; +# End of test for Bug#22679209 diff --git a/mysql-test/suite/innodb_fts/r/phrase.result b/mysql-test/suite/innodb_fts/r/phrase.result new file mode 100644 index 00000000000..efcbaeac66c --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/phrase.result @@ -0,0 +1,84 @@ +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +(NULL, 'mysql good database'), +(NULL, ' mysql good database'), +('', 'mysql good database'), +('', ' mysql good database'), +(' ', 'mysql good database'), +('mysql', 'good database'), +('mysql ', 'good database'), +('mysql', ' good database'), +('mysql good database', ''), +('mysql good database', NULL); +SET GLOBAL innodb_ft_aux_table="test/articles"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +database 1 10 10 1 11 +database 1 10 10 2 12 +database 1 10 10 3 11 +database 1 10 10 4 12 +database 1 10 10 5 13 +database 1 10 10 6 11 +database 1 10 10 7 12 +database 1 10 10 8 12 +database 1 10 10 9 11 +database 1 10 10 10 11 +good 1 10 10 1 6 +good 1 10 10 2 7 +good 1 10 10 3 6 +good 1 10 10 4 7 +good 1 10 10 5 8 +good 1 10 10 6 6 +good 1 10 10 7 7 +good 1 10 10 8 7 +good 1 10 10 9 6 +good 1 10 10 10 6 +mysql 1 10 10 1 0 +mysql 1 10 10 2 1 +mysql 1 10 10 3 0 +mysql 1 10 10 4 1 +mysql 1 10 10 5 2 +mysql 1 10 10 6 0 +mysql 1 10 10 7 0 +mysql 1 10 10 8 0 +mysql 1 10 10 9 0 +mysql 1 10 10 10 0 +SET GLOBAL innodb_ft_aux_table=default; +SELECT * FROM articles; +id title body +1 NULL mysql good database +2 NULL mysql good database +3 mysql good database +4 mysql good database +5 mysql good database +6 mysql good database +7 mysql good database +8 mysql good database +9 mysql good database +10 mysql good database NULL +SELECT * FROM articles WHERE MATCH(title, body) +AGAINST('"mysql good database"' IN BOOLEAN MODE); +id title body +1 NULL mysql good database +2 NULL mysql good database +3 mysql good database +4 mysql good database +5 mysql good database +9 mysql good database +10 mysql good database NULL +SELECT * FROM articles WHERE MATCH(title, body) +AGAINST('("mysql good database")' IN BOOLEAN MODE); +id title body +1 NULL mysql good database +2 NULL mysql good database +3 mysql good database +4 mysql good database +5 mysql good database +9 mysql good database +10 mysql good database NULL +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/r/result_cache_limit.result b/mysql-test/suite/innodb_fts/r/result_cache_limit.result new file mode 100644 index 00000000000..4f13f4e702e --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/result_cache_limit.result @@ -0,0 +1,31 @@ +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE= InnoDB; +CREATE FULLTEXT INDEX idx on t1 (a,b); +INSERT INTO t1 (a,b) VALUES +('MySQL from Tutorial','DBMS stands for DataBase ...') , +('when To Use MySQL Well','After that you went through a ...'), +('where will Optimizing MySQL','what In this tutorial we will show ...'), +('MySQL from Tutorial','DBMS stands for DataBase ...') , +('when To Use MySQL Well','After that you went through a ...'), +('where will Optimizing MySQL','what In this tutorial we will show ...'), +('MySQL from Tutorial','DBMS stands for DataBase ...') , +('when To Use MySQL Well','After that you went through a ...'), +('where will Optimizing MySQL','what In this tutorial we will show ...'); +SET @save_limit=@@GLOBAL.innodb_ft_result_cache_limit; +SET @save_dbug=@@debug_dbug; +SET debug_dbug="+d,fts_instrument_result_cache_limit"; +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('mysql' IN BOOLEAN MODE); +COUNT(*) +9 +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('mysql' WITH QUERY EXPANSION); +ERROR HY000: Table handler out of memory +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('"mysql database"' IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('"mysql database" @ 5' IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +SET debug_dbug=@save_dbug; +DROP TABLE t1; +SET GLOBAL innodb_ft_result_cache_limit=@save_limit; diff --git a/mysql-test/suite/innodb_fts/r/savepoint.result b/mysql-test/suite/innodb_fts/r/savepoint.result new file mode 100644 index 00000000000..1abfc961d0a --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/savepoint.result @@ -0,0 +1,318 @@ +CREATE TABLE articles ( +id INT UNSIGNED NOT NULL PRIMARY KEY, +title VARCHAR(200), +FULLTEXT (title) +) ENGINE= InnoDB; +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +4 mysql +5 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +4 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +5 mysql +6 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +5 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +5 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +5 mysql +6 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +RELEASE SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +5 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +4 mysql +5 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +RELEASE SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +5 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +3 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +4 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +5 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +5 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +7 mysql +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/r/subexpr.result b/mysql-test/suite/innodb_fts/r/subexpr.result new file mode 100644 index 00000000000..cf476abb893 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/subexpr.result @@ -0,0 +1,105 @@ +# +# Bug #20028323 INNODB FULLTEXT BOOLEAN SEARCH INCORRECTLY HANDLES +# PARENTHESES +# +CREATE TABLE t1 ( +f1 INT NOT NULL AUTO_INCREMENT, +f2 TEXT NOT NULL, +PRIMARY KEY (f1), +FULLTEXT (f2) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO t1 (f2) VALUES +('Pumpkin soup with cheese bread'), +('Yellow chicken curry'), +('Fresh green vegetables with garlic'); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+pumpkin' IN BOOLEAN MODE); +f1 f2 +1 Pumpkin soup with cheese bread +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+cheese' IN BOOLEAN MODE); +f1 f2 +1 Pumpkin soup with cheese bread +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+(pumpkin cheese)' IN BOOLEAN MODE); +f1 f2 +1 Pumpkin soup with cheese bread +SELECT * FROM t1 WHERE MATCH(f2) +AGAINST('+pumpkin +(souffle)' IN BOOLEAN MODE); +f1 f2 +SELECT * FROM t1 WHERE MATCH(f2) +AGAINST('+pumpkin +(souffle tart)' IN BOOLEAN MODE); +f1 f2 +SELECT * FROM t1 WHERE MATCH(f2) +AGAINST('+pumpkin +(>souffle souffle = 1 +#AND t1.id <=3 ; + +# proximity search +# insert for proximity search +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +# Insert into table with similar word of different distances +INSERT INTO t1 (a,b) VALUES + ('test proximity search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO t1 (a,b) VALUES + ('test proximity fts search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO t1 (a,b) VALUES + ('test more proximity fts search, test, more proximity and phrase', + 'search, with proximity innodb'); + + +SELECT id FROM t1 WHERE t1.id = (SELECT MAX(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); +SELECT id FROM t1 WHERE t1.id > (SELECT MIN(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); + +SELECT id FROM t1 WHERE t1.id IN (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); + +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"proximity search"@2' IN BOOLEAN MODE) +AND t2.id=t1.id); + +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"more test proximity"@3' IN BOOLEAN MODE) +AND t2.id=t1.id); + +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"more test proximity"@2' IN BOOLEAN MODE) +AND t2.id=t1.id); + + +#------------------------------------------------------------------------------ +# create table AS SELECT from fts indexed table +#------------------------------------------------------------------------------ +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST ('support') ; +SHOW CREATE TABLE t2; +SELECT id FROM t2; +DROP TABLE t2; + +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST("+support +collections" IN BOOLEAN MODE); +SHOW CREATE TABLE t2; +SELECT id FROM t2; +DROP TABLE t2; + +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST ('"proximity search"@10' IN BOOLEAN MODE); +SHOW CREATE TABLE t2; +SELECT id FROM t2; +DROP TABLE t2; + +DROP TABLE t1; + + +#------------------------------------------------------------------------------ +# Verift FTS with NULL records +#------------------------------------------------------------------------------ +# Create FTS table +EVAL CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + + +# Insert rows +INSERT INTO t1 (a,b) VALUES +('MySQL from Tutorial','DBMS stands for DataBase ...'); + +let $counter = 50; +--disable_query_log +WHILE ($counter > 0) { + INSERT INTO t1 (a,b) VALUES (NULL,NULL); + dec $counter; +} +--enable_query_log +INSERT INTO t1 (a,b) VALUES +('when To Use MySQL Well','After that you went through a ...'); + +let $counter = 50; +--disable_query_log +WHILE ($counter > 0) { + INSERT INTO t1 (a,b) VALUES (NULL,NULL); + dec $counter; +} +--enable_query_log +INSERT INTO t1 (a,b) VALUES +('where will Optimizing MySQL','what In this tutorial we will show ...'); + +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL null...'); + +SELECT COUNT(*) FROM t1; +SELECT COUNT(*) FROM t1 WHERE a IS NULL; +SELECT COUNT(*) FROM t1 WHERE b IS NOT NULL; + +SELECT id FROM t1 + WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +SELECT id FROM t1 + WHERE MATCH (a,b) + AGAINST (NULL IN NATURAL LANGUAGE MODE); +SELECT id FROM t1 + WHERE MATCH (a,b) + AGAINST (NULL WITH QUERY EXPANSION); +SELECT id FROM t1 + WHERE MATCH (a,b) + AGAINST ('null' IN NATURAL LANGUAGE MODE); +# Boolean search +# Select rows contain "MySQL" but not "YourSQL" +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) AND (a IS NOT NULL OR b IS NOT NULL); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) AND (a IS NULL AND b IS NOT NULL); + +# Select rows contain at least one of the two words +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('DBMS Security' IN BOOLEAN MODE); + +# Test query expansion +SELECT COUNT(*) FROM t1 +WHERE MATCH (a,b) +AGAINST ('database' WITH QUERY EXPANSION); + +# proximity +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"following database"@10' IN BOOLEAN MODE); + + +DROP TABLE t1; + + + +#------------------------------------------------------------------------------ +# More FTS test from peter's testing +#------------------------------------------------------------------------------ +--disable_warnings +drop table if exists t50; +--enable_warnings + +set names utf8; + + +--echo "----------Test1---------" +# Create FTS table +create table t50 (s1 varchar(60) character set utf8 collate utf8_bin) engine = innodb; +create fulltext index i on t50 (s1); +# INNODB_FTS: Assert - fixed +# Assert : InnoDB: Failing assertion: rbt_validate(result_doc->tokens) +insert into t50 values ('ABCDE'),('FGHIJ'),('KLMNO'),('VÃÆ·Wİ'); +# it was giving empty result set instead of one record +select * from t50 where match(s1) against ('VÃÆ·Wİ'); +drop table t50; + + +--echo "----------Test2---------" +create table t50 (s1 int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÃÆ·Wİ'),('ABCDE'); +# INNODB_FTS: RESULT DIFF +# Order by does not sort result. +# Optimizer's Evgeny is investigate a similar issue. InnoDB FTS is used only +# for FT search, and should not be used as regular index for such order by query. +# Correct the result file when fixed. +select * from t50 order by s2; +drop table t50; + + +--echo "----------Test3---------" +create table t50 (id int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÃÆ·Wİ'),('ABCDE'); +set @@autocommit=0; +update t50 set s2 = lower(s2); +update t50 set s2 = upper(s2); +commit; +select * from t50 where match(s2) against ('VÃÆ·Wİ FGHIJ KLMNO ABCDE' in boolean mode); +select * from t50; +drop table t50; +set @@autocommit=1; + +--echo "----------Test4---------" +create table t50 (id int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÃÆ·Wİ'),('ABCD*'); +select * from t50 where match(s2) against ('abcd*' in natural language +mode); +# INNODB_FTS: RESULT DIFF(Expected). InnoDB do not index "*", so +# word "ABCD" indexed, instead of "ABCD*" +select * from t50 where match(s2) against ('abcd*' in boolean mode); +drop table t50; + + +--echo "----------Test5---------" +create table t50 (s1 int, s2 varchar(200), fulltext key(s2)) engine = innodb; +set @@autocommit=0; +insert into t50 values (1,'Sunshine'),(2,'Lollipops'); +select * from t50 where match(s2) against('Rainbows'); +rollback; +select * from t50; +drop table t50; +set @@autocommit=1; + +--echo "----------Test6---------" +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('aab` MySQL Tutorial','DBMS stands for DataBase ...') , + ('aas How To Use MySQL Well','After you went through a ...'), + ('aac Optimizing MySQL','In this tutorial we will show ...'); +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('aac 1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('aab MySQL vs. YourSQL','In the following database comparison ...'), + ('aaa MySQL Security','When configured properly, MySQL ...'); +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); + +-- disable_query_log +-- disable_result_log +ANALYZE TABLE t1; +-- enable_result_log +-- enable_query_log + +SELECT * FROM t1 ORDER BY MATCH(a,b) AGAINST ('aac') DESC; +SELECT * FROM t1 ORDER BY MATCH(a,b) AGAINST ('aab') DESC; + +--echo "----------Test7---------" +select * from t1 where match(a,b) against ('aaa') +union select * from t1 where match(a,b) against ('aab') +union select * from t1 where match(a,b) against ('aac'); + +select * from t1 where match(a,b) against ('aaa') + or match(a,b) against ('aab') + or match(a,b) against ('aac'); + +DROP TABLE t1; + +--echo "----------Test8---------" +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ... abcd') , + ('How To Use MySQL Well','After you went through a q ...abdd'), + ('Optimizing MySQL','In this tutorial we will show ...abed'); + +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +EVAL SHOW CREATE TABLE t1; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. q ...'), + ('MySQL vs. YourSQL use','In the following database comparison ...'), + ('MySQL Security','When run configured properly, MySQL ...'); + +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('use'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('went'); +# rows should be matched as 'q' is single char its not indexed +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run') AND NOT MATCH(a,b) AGAINST ('q'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('use') AND NOT MATCH(a,b) AGAINST ('q'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('went') AND NOT MATCH(a,b) AGAINST ('q'); + +--echo "----------Test9---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE=MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +SET @x = (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('run')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('use')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('went')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('run')); +SET @x2 = (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('run')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('use')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('went')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('run')); +# Innodb returns value for x which is correct +SELECT @x, @x2; + + +DROP TABLE t2; + +--echo "----------Test10---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE=MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); + +DROP TABLE t2; + + +--echo "----------Test11---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE = MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +ALTER TABLE t2 ENGINE=InnoDB; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run'); +SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +DROP TABLE t2,t1; + + +--echo "----------Test13---------" +set names utf8; + +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200) CHARACTER SET UTF8 COLLATE UTF8_SPANISH_CI) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1 (s2); +INSERT INTO t1 VALUES (1,'aaCen'),(2,'aaCha'),(3,'aaCio'),(4,'aaçen'),(5,'aaçha'),(6,'aaçio'); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('aach*' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('aaC*' IN BOOLEAN MODE); +DROP TABLE t1; + +--echo "----------Test14---------" +CREATE TABLE t1(s1 INT , s2 VARCHAR(100) CHARACTER SET sjis) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1 (s2); +INSERT INTO t1 VALUES (1,'ペペペ'),(2,'テテテ'),(3,'ルルル'),(4,'ã‚°ã‚°ã‚°'); +# Innodb Asset : file ha_innodb.cc line 4557 +#SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('テテ*' IN BOOLEAN MODE); +DROP TABLE t1; + + +--echo "----------Test15---------" +CREATE TABLE t1 (s1 VARCHAR (60) CHARACTER SET UTF8 COLLATE UTF8_UNICODE_520_CI) ENGINE = MyISAM; +CREATE FULLTEXT INDEX i ON t1 (s1); +INSERT INTO t1 VALUES +('a'),('b'),('c'),('d'),('ÅÅÅÅ'),('LLLL'),(NULL),('ÅÅÅÅ ÅÅÅÅ'),('LLLLLLLL'); +SELECT * FROM t1 WHERE MATCH(s1) AGAINST ('LLLL' COLLATE UTF8_UNICODE_520_CI); +DROP TABLE if EXISTS t2; +CREATE TABLE t2 (s1 VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_POLISH_CI) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t2 ( s1); +INSERT INTO t2 VALUES +('a'),('b'),('c'),('d'),('ÅÅÅÅ'),('LLLL'),(NULL),('ÅÅÅÅ ÅÅÅÅ'),('LLLLLLLL'); +SELECT * FROM t2 WHERE MATCH(s1) AGAINST ('LLLL' COLLATE UTF8_UNICODE_520_CI); +--disable_warnings +DROP TABLE t1,t2; +--enable_warnings + +--echo "----------Test16---------" +CREATE TABLE t1 (s1 INT, s2 VARCHAR(50) CHARACTER SET UTF8) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1(s2); +INSERT INTO t1 VALUES (2, 'ÄŸÄ— DaÅ›i p '); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('+p +"ÄŸÄ— DaÅ›i*"' IN BOOLEAN MODE); +DROP TABLE t1; + + +--echo "----------Test19---------" +#19 Failure with Boolean quoted search +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,'İóëɠ'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +SELECT * FROM t1 WHERE MATCH(char_column) AGAINST ('"İóëɠ"' IN BOOLEAN MODE); +DROP TABLE t1; + +--echo "----------Test20---------" +#20 Crash with utf32 and boolean mode. +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF32, char_column2 VARCHAR(60) character set utf8) ENGINE = InnoDB; +INSERT INTO t1 (char_column) VALUES ('abcde'),('fghij'),('klmno'),('qrstu'); +UPDATE t1 SET char_column2 = char_column; +CREATE FULLTEXT INDEX i ON t1 (char_column2); +--error ER_FT_MATCHING_KEY_NOT_FOUND +SELECT * FROM t1 WHERE MATCH(char_column) AGAINST ('abc*' IN BOOLEAN MODE); +DROP TABLE t1; + +--echo "----------Test22---------" +# case 22 +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,'aaa'),(2,'bbb'),(3,'ccc'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +HANDLER t1 OPEN; +--error ER_KEY_DOESNT_SUPPORT +HANDLER t1 READ i = ('aaa'); +DROP TABLE t1; +#23. Duplicate key error when there are no unique indexes (procedure test) +#24 Failure after cascading update - already have tests + +--echo "----------Test25---------" +#25 Failure with Croatian boolean truncated search. +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_CROATIAN_CI) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,'LJin'),(2,'ljin'),(3,'lmin'),(4,'LJLJLJLJLJ'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +#inndob:error incorrect result correct it after fix +SELECT count(*) FROM t1 WHERE MATCH (char_column) AGAINST ('lj*' IN BOOLEAN MODE); +DROP TABLE t1; + +#26. Index error when run procedure call from multiple clients + +--echo "----------Test27---------" +#27 Crash after server restart +CREATE TABLE t1 (id INT,char_column VARCHAR(60)) ENGINE=InnoDB; +SET @@autocommit=0; +CREATE FULLTEXT INDEX i ON t1 (char_column); +INSERT INTO t1 values (1,'aaa'); +echo "restart server..." +# Restart the server +--source include/restart_mysqld.inc +DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb'); +SET @@autocommit=1; +DROP TABLE t1; + +--echo "----------Test28---------" +drop table if exists `fts_test`; +create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb; +set session autocommit=0; +insert into `fts_test` values (''); +savepoint `b`; +savepoint `b`; +set session autocommit=1; +DROP TABLE fts_test; + +# Continue test savepoint related operations. With a commit after +# multiple rollback to savepoints +--echo "----------Test29---------" +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...'); + + +start transaction; + +INSERT INTO articles (title,body) VALUES +('How To Use MySQL Well','After you went through a ...'); + +savepoint `a1`; + +INSERT INTO articles (title,body) VALUES +('Optimizing MySQL','In this tutorial we will show ...'); + +savepoint `a2`; + +INSERT INTO articles (title,body) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'); + +savepoint `a3`; + +INSERT INTO articles (title,body) VALUES +('MySQL vs. YourSQL','In the following database comparison ...'); + +savepoint `a4`; + +# FTS do not parse those uncommitted rows, only one row should show up +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +rollback to savepoint a3; + +# The last inserted row should not be there +select title, body from articles; + +INSERT INTO articles (title,body) VALUES +('MySQL Security','When configured properly, MySQL ...'); + +savepoint `a5`; + +select title, body from articles; + +rollback to savepoint a2; + +select title, body from articles; + +commit; + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +DROP TABLE articles; + +# Continue test savepoint related operations. With a rollback after +# multiple rollback to savepoints +--echo "----------Test30---------" +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...'); + +start transaction; + +INSERT INTO articles (title,body) VALUES +('How To Use MySQL Well','After you went through a ...'); + +savepoint `a1`; + +INSERT INTO articles (title,body) VALUES +('Optimizing MySQL','In this tutorial we will show ...'); + +savepoint `a2`; + +INSERT INTO articles (title,body) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'); + +savepoint `a3`; + +INSERT INTO articles (title,body) VALUES +('MySQL vs. YourSQL','In the following database comparison ...'); + +savepoint `a4`; + +# FTS do not parse those uncommitted rows, only one row should show up +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +rollback to savepoint a3; + +# The last inserted row should not be there +select title, body from articles; + +INSERT INTO articles (title,body) VALUES +('MySQL Security','When configured properly, MySQL ...'); + +savepoint `a5`; + +select title, body from articles; + +rollback to savepoint a2; + +select title, body from articles; + +rollback; + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +DROP TABLE articles; + +# Test for Bug #13907075 - DIFFERENT RESULTS FOR DIFFERENT TERM ORDER +# WITH INNODB BOOLEAN FULLTEXT SEARCH. The FTS_IGNORE ("-") operation +# is orderless +# Create FTS table +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +# Insert six rows +INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +-- disable_result_log +ANALYZE TABLE articles; +-- enable_result_log + +SELECT *, MATCH(title, body) AGAINST ('-database +MySQL' IN BOOLEAN MODE) AS score from articles; + +SELECT *, MATCH(title, body) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score FROM articles; + +# With subquery +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (database - tutorial)' IN BOOLEAN MODE); + +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (- tutorial database)' IN BOOLEAN MODE); + +# More complex query +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (- tutorial database) -Tricks' IN BOOLEAN MODE); + +SELECT * FROM articles where MATCH(title, body) AGAINST ('-Tricks MySQL - (- tutorial database)' IN BOOLEAN MODE); + +DROP TABLE articles; + +# Test for Bug 13940669 - 64901: INNODB: ASSERTION FAILURE IN +# THREAD 34387022112 IN FILE REM0CMP.CC LINE 5 + +drop table if exists t1; + +create table t1 (FTS_DOC_ID bigint unsigned auto_increment not null primary key, +title varchar(200),body text,fulltext(title,body)) engine=innodb; + +insert into t1 set body='test'; + +select * from t1 where match(title,body) against('%test'); + +select * from t1 where match(title,body) against('%'); + +select * from t1 where match(title,body) against('%%%%'); + +drop table t1; + +# Test for Bug 13881758 - 64745: CREATE FULLTEXT INDEX CAUSES CRASH +# Create a database with empty space in its name +CREATE DATABASE `benu database`; + +USE `benu database`; + +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +EVAL SHOW CREATE TABLE t1; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +# Select word "tutorial" in the table +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +select id, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +select id from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE); +select id from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE); +select id from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE); + +DROP DATABASE `benu database`; + +USE test; + +# Test for Bug #14101706 - CRASH WITH DDL IN ROW_MERGE_BUILD_INDEXES +# WHEN FULLTEXT INDEXES EXIST + +CREATE TABLE `t21` (`a` text, `b` int not null, +fulltext key (`a`), fulltext key (`a`) +) ENGINE=INNODB DEFAULT CHARSET=LATIN1; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`), ALGORITHM=INPLACE; +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`); + +DROP TABLE t21; + +CREATE TABLE `t21` (`a` text, `b` int not null, +fulltext key (`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1; + +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`); + +DROP TABLE t21; + +# Test primary index rebuild +CREATE TABLE t1 ( + id INT NOT NULL, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 VALUES + (1, 'MySQL Tutorial','DBMS stands for DataBase ...') , + (2, 'How To Use MySQL Well','After you went through a ...'), + (3, 'Optimizing MySQL','In this tutorial we will show ...'); + +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); + +ALTER TABLE t1 ADD UNIQUE INDEX (`id`); + +# Select word "tutorial" in the table +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; + +DROP TABLE t1; + +# Test create the FTS and primary index in the same clause +CREATE TABLE t1 ( + id INT NOT NULL, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 VALUES + (1, 'MySQL Tutorial','DBMS stands for DataBase ...') , + (2, 'How To Use MySQL Well','After you went through a ...'), + (3, 'Optimizing MySQL','In this tutorial we will show ...'); + +ALTER TABLE t1 ADD UNIQUE INDEX (`id`), ADD FULLTEXT INDEX idx (a,b); + +# Select word "tutorial" in the table +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); + +DROP TABLE t1; + +# Create FTS table with FTS_DOC_ID already existed +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED NOT NULL, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 VALUES + (1, 'MySQL Tutorial','DBMS stands for DataBase ...') , + (2, 'How To Use MySQL Well','After you went through a ...'), + (3, 'Optimizing MySQL','In this tutorial we will show ...'); + +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); + +ALTER TABLE t1 ADD UNIQUE INDEX (`FTS_DOC_ID`); + +# Select word "tutorial" in the table +SELECT FTS_DOC_ID FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +select FTS_DOC_ID, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; + +DROP TABLE t1; + +# Create FTS table with FTS_DOC_ID and FTS_DOC_ID_INDEX +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED NOT NULL, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 VALUES + (1, 'MySQL Tutorial','DBMS stands for DataBase ...') , + (2, 'How To Use MySQL Well','After you went through a ...'), + (3, 'Optimizing MySQL','In this tutorial we will show ...'); + +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b), ADD UNIQUE INDEX FTS_DOC_ID_INDEX (FTS_DOC_ID); + +# Select word "tutorial" in the table +SELECT FTS_DOC_ID FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +select FTS_DOC_ID, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; + +DROP TABLE t1; + +# Test for bug #14079609 - FTS: CRASH IN FTS_TRX_TABLE_CMP WITH SAVEPOINTS, XA + +CREATE TABLE t2 (`b` char(2),fulltext(`b`)) ENGINE=INNODB +DEFAULT CHARSET=LATIN1; + +CREATE TABLE t3 LIKE t2; + +INSERT INTO `t2` VALUES(); + +COMMIT WORK AND CHAIN; + +INSERT INTO `t3` VALUES (); +UPDATE `t2` SET `b` = 'a'; + +SAVEPOINT BATCH1; + +DROP TABLE t2; +DROP TABLE t3; + +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); + +COMMIT WORK AND CHAIN; + +INSERT INTO t1 (a,b) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +SAVEPOINT BATCH1; + +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); + +INSERT INTO t1 (a,b) VALUES + ('1002 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + + +ROLLBACK TO SAVEPOINT BATCH1; + +COMMIT; + +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); + +DROP TABLE t1; + +# Test for Bug 14588091 - FTS: BUFFER OVERFLOW IN FTS_AST_CREATE_NODE_TEXT +CREATE TABLE `t` (`a` char(20) character set utf8 default null, +fulltext key (`a`)) ENGINE=INNODB; +INSERT INTO `t` VALUES ('a'); +INSERT INTO `t` VALUES ('aaa'); + +# 0x22 is the '"', 0xdd is not encoded in utf8 +SELECT MATCH(`a`) AGAINST (0x22dd22) FROM `t`; +SELECT MATCH(`a`) AGAINST (0x2222) FROM `t`; +SELECT MATCH(`a`) AGAINST (0x22) FROM `t`; + +# this should show one match +SELECT MATCH(`a`) AGAINST (0x2261616122) FROM `t`; + +# again 0xdd should be ignored +SELECT MATCH(`a`) AGAINST (0x2261dd6122) FROM `t`; + +SELECT MATCH(`a`) AGAINST (0x2261dd612222226122) FROM `t`; + +DROP TABLE t; + +# InnoDB FTS does not support index scan from handler +CREATE TABLE t(a CHAR(1),FULLTEXT KEY(a)) ENGINE=INNODB; +HANDLER t OPEN; +HANDLER t READ a NEXT; +HANDLER t READ a PREV; +DROP TABLE t; + +CREATE TABLE `%`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; +CREATE TABLE `A B`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; +DROP TABLE `%`; +DROP TABLE `A B`; + +CREATE TABLE `t-26`(a VARCHAR(10),FULLTEXT KEY(a)) ENGINE=INNODB; +INSERT INTO `t-26` VALUES('117'); +DROP TABLE `t-26`; + +# Test on phrase search with stopwords contained in the search string +CREATE TABLE `t1` ( + `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + `content` TEXT NOT NULL, + PRIMARY KEY (`id`), + FULLTEXT INDEX `IDX_CONTEXT_FULLTEXT`(`content`) +) +ENGINE = InnoDB; + +insert into t1 (content) +values +('This is a story which has has a complicated phrase structure here in the +middle'), +('This is a story which doesn''t have that text'), +('This is a story that has complicated the phrase structure'); + +select * from t1 +where match(content) against('"complicated phrase structure"' in boolean +mode); + +# Test single phrase search with "+" symbol, one row should be returned +select * from t1 +where match(content) against('+"complicated phrase structure"' in boolean +mode); + +# Test phrase search with stopwords in between, one row should be returned +select * from t1 +where match(content) against('"complicated the phrase structure"' in boolean +mode); + +# Test phrase search with multiple "+" symbols +select * from t1 where match(content) against('+"this is a story which" +"complicated the phrase structure"' in boolean mode); + +# Test phrase search with leading word is a stopword, such stopword would be +# ignored +select * from t1 where match(content) against('"the complicated the phrase structure"' in boolean mode); + +# Test phrase search with non-matching stopword in between, no row should be +# returned +select * from t1 where match(content) against('"complicated a phrase structure"' in boolean mode); + +DROP TABLE t1; + +CREATE TABLE my (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, +c VARCHAR(32), FULLTEXT(c)) ENGINE = INNODB; + +INSERT INTO my (c) VALUES ('green-iguana'); + +SELECT * FROM my WHERE MATCH(c) AGAINST ('green-iguana'); + +DROP TABLE my; + +CREATE TABLE ift ( + `a` int(11) NOT NULL, + `b` text, + PRIMARY KEY (`a`), + FULLTEXT KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO ift values (1, "skip"); +INSERT INTO ift values (2, "skip and networking"); +INSERT INTO ift values (3, "--skip-networking"); +INSERT INTO ift values (4, "-donot--skip-networking"); + +SELECT * FROM ift WHERE MATCH (b) AGAINST ('--skip-networking'); +SELECT * FROM ift WHERE MATCH (b) AGAINST ('skip-networking'); +SELECT * FROM ift WHERE MATCH (b) AGAINST ('----'); +SELECT * FROM ift WHERE MATCH (b) AGAINST ('-donot--skip-networking'); + +DROP TABLE ift; + +# Test special cases of wildword. +# Create FTS table +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +# Insert six rows +INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('( that''s me )','When configured properly, MySQL ...'); + +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('( yours''s* )' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('s*' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('stands\'] | * | show[@database' IN NATURAL LANGUAGE MODE); + +DROP TABLE articles; + +# Test for BUG#16429688 - FTS: SYNTAX ERROR, UNEXPECTED '*', EXPECTING $END +CREATE TABLE t1(a TEXT CHARACTER SET LATIN1, FULLTEXT INDEX(a)) ENGINE=INNODB; + +--error ER_PARSE_ERROR +SELECT * FROM t1 WHERE MATCH(a) AGAINST("*"); + +DROP TABLE t1; + +# Test for BUG#16516193 - LITERAL PHRASES CANNOT BE COMBINED WITH + OR - OPERATOR +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + FULLTEXT (a) + ) ENGINE= InnoDB; + +# Insert rows +INSERT INTO t1 (a) VALUES + ('Do you know MySQL is a good database'), + ('How to build a good database'), + ('Do you know'), + ('Do you know MySQL'), + ('How to use MySQL'), + ('Do you feel good'), + ('MySQL is good'), + ('MySQL is good to know'), + ('What is database'); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know mysql"' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql")' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('("know mysql" good)' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql" good)' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('(good "know mysql")' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+(good "know mysql")' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql" "good database")' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know mysql" +"good database"' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know database"@4' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know database"@8' IN BOOLEAN MODE); + +# Drop table +DROP TABLE t1; + +# Test for BUG#16885178 - INNODB FULLTEXT PHRASE SEARCH VALGRIND ERROR +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + FULLTEXT (a) + ) ENGINE= InnoDB; + +# Insert a special row +INSERT INTO t1 (a) VALUES + ('know mysql good database'); + +# This phrase search fails in valgrind test before the fix. +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"good database"' IN BOOLEAN MODE); + +DROP TABLE t1; + +# Test single term ranking +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +# Repeatedly insert/delete records, the ranking should be the same for +# each of them +INSERT INTO articles (title,body) VALUES ('Test Article','blah blah +blah'),("Matt's Noise",'this is noisy'),('February Weather','It was terrible +this year.'),('Peter Pan','Tis a kids story.'),('Test1','nada'),('Database +database database','foo database database database'),('Database article +title','body with lots of words.'),('myfulltext database', 'my test fulltext +database'); + +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +DELETE from articles WHERE title like "myfulltext database"; + +INSERT INTO articles (title,body) VALUES ('myfulltext database', 'my test fulltext database'); + +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +DELETE from articles WHERE title like "myfulltext database"; + +INSERT INTO articles (title,body) VALUES ('myfulltext database', 'my test fulltext database'); + +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; + +DROP TABLE articles; + +# Test for BUG 18277305 - FTS: FAILING ASSERTION: PTR[1] == '\"' +# IN FTS_AST_CREATE_NODE_TEXT +CREATE TABLE t1( + a TEXT CHARSET ujis COLLATE ujis_japanese_ci, + b TEXT CHARSET utf8mb4 COLLATE utf8mb4_turkish_ci, + c TEXT CHARSET eucjpms COLLATE eucjpms_bin, + d TEXT CHARSET utf8mb4, + FULLTEXT INDEX(a), + FULLTEXT INDEX(b), + FULLTEXT INDEX(c), + FULLTEXT INDEX(d) +) ENGINE = InnoDB; + +INSERT INTO t1 VALUES + ('myisam', 'myisam', 'myisam', 'myisam'), + ('innodb', 'innodb', 'innodb', 'innodb'), + ('innodb myisam', 'innodb myisam', 'innodb myisam', 'innodb myisam'), + ('memory', 'memory', 'memory', 'memory'), + ('archive', 'archive', 'archive', 'archive'), + ('federated', 'federated', 'federated', 'federated'), + ('storage engine innodb', 'storage engine innodb', 'storage engine innodb', 'storage engine innodb'), + ('storage engine myisam', 'storage engine myisam', 'storage engine myisam', 'storage engine myisam'), + ('innobase', 'innobase', 'innobase', 'innobase'), + ('myisam innodb', 'myisam innodb', 'myisam innodb', 'myisam innodb'), + ('innodb myisam engines', 'innodb myisam engines', 'innodb myisam engines', 'innodb myisam engines'); + +# Test the ujis_japanese_ci +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', ' ', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '&', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '&', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '%', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +--error ER_PARSE_ERROR +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); + + +# Test the utf8mb4_turkish_ci +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00)); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', ' ', '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '&', 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, '&', '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '%', '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +--error ER_PARSE_ERROR +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); + +# Test the eucjpms_bin +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00)); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', ' ', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '&', 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, '&', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '%', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +--error ER_PARSE_ERROR +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); + +ALTER TABLE t1 ENGINE = MyISAM; + +# Test the query against myisam to verify +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', ' ', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '&', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '&', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '%', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); + +DROP TABLE t1; + +# Test for BUG#18229097 - FTS: DID NOT FIND WORD 0 IN DOC 39161 FOR QUERY EXPANSION SEARCH. +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + FULLTEXT (a) +) ENGINE= InnoDB; + +INSERT INTO t1 (a) VALUES + ('know database'),('good database'), ('gmail email'), ('ghome windows'); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g *' IN NATURAL LANGUAGE MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * k *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * k * d *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * go *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * good' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('gm * go *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('good *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g* database' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/misc_1.test b/mysql-test/suite/innodb_fts/t/misc_1.test new file mode 100644 index 00000000000..45eaf447978 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/misc_1.test @@ -0,0 +1,894 @@ +--source include/have_innodb.inc +--source include/innodb_page_size_small.inc +--source include/no_valgrind_without_big.inc + +#------------------------------------------------------------------------------ +# FTS with FK and update cascade +#------------------------------------------------------------------------------- +set names utf8; + +call mtr.add_suppression("\\[Warning\\] InnoDB: A new Doc ID must be supplied while updating FTS indexed columns."); +call mtr.add_suppression("\\[Warning\\] InnoDB: FTS Doc ID must be larger than [0-9]+ for table `test`.`t1`"); + +# Create FTS table +CREATE TABLE t1 ( + id1 INT , + a1 VARCHAR(200) , + b1 TEXT , + FULLTEXT KEY (a1,b1), PRIMARY KEY (a1, id1) + ) CHARACTER SET = utf8 , ENGINE = InnoDB; + +CREATE TABLE t2 ( + id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a2 VARCHAR(200), + b2 TEXT , + FOREIGN KEY (a2) REFERENCES t1(a1) ON UPDATE CASCADE, + FULLTEXT KEY (b2,a2) + ) CHARACTER SET = utf8 ,ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (1,'MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , + (2,'How To Use MySQL Well','After you went through a ...'), + (3,'Optimizing MySQL','In this tutorial we will show ...'); + +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + (5,'MySQL vs. YourSQL','In the following database comparison ...'), + (6,'MySQL Security','When configured properly, MySQL ...'); + +# Insert rows in t2 fk table +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +# Insert rows t2 fk table +INSERT INTO t2 (a2,b2) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +# error on violating fk constraint +--error 1452 +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tricks','1. Never run mysqld as root. 2. ...'); + +# error on delete from parent table +--error 1451 +DELETE FROM t1; + +ANALYZE TABLE t1; +ANALYZE TABLE t2; + +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial') ORDER BY id1; +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial') ORDER BY id2; + +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ORDER BY id1; +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ORDER BY id2; + +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id1; +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id2; + + +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; + +set global innodb_optimize_fulltext_only=1; +optimize table t1; +set global innodb_optimize_fulltext_only=0; +# Updating parent table hence child table should get updated due to 'update cascade' clause +UPDATE t1 SET a1 = "changing column - on update cascade" , b1 = "to check foreign constraint" WHERE +MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; + +# no records expected +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +# InnoDB:Error child table shows records which is incorrect - UPADTE on Fix +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; + +# it shows updated record +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('+update +cascade' IN BOOLEAN MODE) ORDER BY id1; +# InnoDB:Error child table does not show the expected record +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('+update +cascade' IN BOOLEAN MODE) ORDER BY id2; +SELECT id2 FROM t2 WHERE a2 LIKE '%UPDATE CASCADE%' ORDER BY id2; + +DROP TABLE t2 , t1; + +# on update cascade +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), + fulltext key(s2), + foreign key (s1,s2) references t1 (s1,s2) on update cascade) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s2 = 'Rainbows' where s2 <> 'Sunshine'; +commit; +select * from t2 where match(s2) against ('Lollipops'); +DROP TABLE t2 , t1; + +# on delete cascade +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), + fulltext key(s2), + foreign key (s1,s2) references t1 (s1,s2) on delete cascade) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +delete from t1 where s2 <> 'Sunshine'; +select * from t2 where match(s2) against ('Lollipops'); +DROP TABLE t2 , t1; + +# on delete set NULL +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), + fulltext key(s2), + foreign key (s1,s2) references t1 (s1,s2) on delete set null) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +delete from t1 where s2 <> 'Sunshine'; +select * from t2 where match(s2) against ('Lollipops'); +DROP TABLE t2 , t1; + + +# on update set NULL +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), + fulltext key(s2), + foreign key (s1,s2) references t1 (s1,s2) on update set null) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s2 = 'Rainbows' where s2 <> 'Sunshine'; +commit; +select * from t2 where match(s2) against ('Lollipops'); +DROP TABLE t2 , t1; + +# When Doc ID is involved +create table t1 (s1 bigint unsigned not null, s2 varchar(200), + primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL, s2 varchar(200), + foreign key (FTS_DOC_ID) references t1 (s1) + on update cascade) ENGINE = InnoDB; + +create fulltext index idx on t2(s2); + +show create table t2; + +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); + +update t1 set s1 = 3 where s1=1; + +select * from t2 where match(s2) against ('sunshine'); + +# FTS Doc ID cannot be reused +--error 1451 +update t1 set s1 = 1 where s1=3; + +DROP TABLE t2 , t1; + +#------------------------------------------------------------------------------ +# FTS with FK and delete casecade +#------------------------------------------------------------------------------ + +# Create FTS table +CREATE TABLE t1 ( + id1 INT , + a1 VARCHAR(200) PRIMARY KEY, + b1 TEXT character set utf8 , + FULLTEXT KEY (a1,b1) + ) CHARACTER SET = utf8 ,ENGINE = InnoDB; + +CREATE TABLE t2 ( + id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a2 VARCHAR(200), + b2 TEXT character set utf8 , + FOREIGN KEY (a2) REFERENCES t1(a1) ON DELETE CASCADE, + FULLTEXT KEY (b2,a2) + ) CHARACTER SET = utf8 ,ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (1,'MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , + (2,'How To Use MySQL Well','After you went through a ...'), + (3,'Optimizing MySQL','In this tutorial we will show ...'), + (4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + (5,'MySQL vs. YourSQL','In the following database comparison ...'), + (6,'MySQL Security','When configured properly, MySQL ...'); + +# Insert rows in t2 +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +# delete records from parent +DELETE FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; + +# no records expected +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; + +SELECT * FROM t1 WHERE a1 LIKE '%tutorial%'; +SELECT * FROM t2 WHERE a2 LIKE '%tutorial%'; + +DROP TABLE t2 , t1; + +#------------------------------------------------------------------------------ +# FTS with FK+transactions and UPDATE casecade with transaction +#------------------------------------------------------------------------------- + +call mtr.add_suppression("\\[ERROR\\] InnoDB: FTS Doc ID must be larger than 3 for table `test`.`t2`"); + +# Create FTS table +CREATE TABLE t1 ( + id1 INT , + a1 VARCHAR(200) , + b1 TEXT , + FULLTEXT KEY (a1,b1), PRIMARY KEY(a1, id1) + ) CHARACTER SET = utf8 , ENGINE = InnoDB; + +CREATE TABLE t2 ( + id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a2 VARCHAR(200), + b2 TEXT , + FOREIGN KEY (a2) REFERENCES t1(a1) ON UPDATE CASCADE, + FULLTEXT KEY (b2,a2) + ) CHARACTER SET = utf8 ,ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (1,'MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , + (2,'How To Use MySQL Well','After you went through a ...'), + (3,'Optimizing MySQL','In this tutorial we will show ...'); + +# Insert rows in t2 fk table +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +START TRANSACTION; +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + (5,'MySQL vs. YourSQL','In the following database comparison ...'), + (6,'MySQL Security','When configured properly, MySQL ...'); + +# Insert rows t2 fk table +INSERT INTO t2 (a2,b2) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +# error on violating fk constraint +--error 1452 +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tricks','1. Never run mysqld as root. 2. ...'); + +# error on DELETE FROM parent table +--error 1451 +DELETE FROM t1; + +# records expected +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial') ORDER BY id1; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial') ORDER BY id2; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ORDER BY id1; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ORDER BY id2; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id1; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id2; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; + +# no records as data not COMMITted. +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('root') ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('root') ; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('mysqld (+root)' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('mysqld (-root)' IN BOOLEAN MODE) ; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('root' WITH QUERY EXPANSION) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('root' WITH QUERY EXPANSION) ; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('"database comparison"@02' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('"database comparison"@02' IN BOOLEAN MODE) ; + +SELECT * FROM t1 ORDER BY id1; +SELECT * FROM t2 ORDER BY id2; + +COMMIT; + +START TRANSACTION; +# Updating parent table hence child table should get updated due to 'UPDATE cascade' clause +UPDATE t1 SET a1 = "changing column - on UPDATE cascade" , b1 = "to check foreign constraint" WHERE +MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +COMMIT; + +# no records expected +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÃÆ·Wİ)' IN BOOLEAN MODE) ; + +# it shows updated record +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('+UPDATE +cascade' IN BOOLEAN MODE) ORDER BY id1; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('+UPDATE +cascade' IN BOOLEAN MODE) ORDER BY id2; +SELECT * FROM t2 WHERE a2 LIKE '%UPDATE CASCADE%' ORDER BY id2; + +DROP TABLE t2 , t1; + + +# FTS with FK+transactions - UPDATE cascade +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + +# FTS with FK+transactions - on DELETE cascade +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + +# FTS with FK+transactions - DELETE SET NULL +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + + +# FTS with FK+transactions - UPDATE SET NULL +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + + +#----------------------------------------------------------------------------- + +# FTS with FK+transactions - UPDATE cascade +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + +# FTS with FK+transactions - DELETE cascade +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + +# FTS with FK+transactions - DELETE SET NULL +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + + +# FTS with FK+transactions - UPDATE SET NULL +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + + +#------------------------------------------------------------------------------ +# FTS index with compressed row format +#------------------------------------------------------------------------------ + +# Save innodb variables +let $innodb_file_per_table_orig=`select @@innodb_file_per_table`; + +set global innodb_file_per_table=1; + +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) CHARACTER SET = utf8, ROW_FORMAT=COMPRESSED, ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','DBMS stands for DataBase VÃÆ·Wİ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +EVAL SHOW CREATE TABLE t1; + +# Check whether individual space id created for AUX tables +SELECT count(*) FROM information_schema.innodb_sys_tables WHERE name LIKE "%FTS_%" AND space !=0; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +-- disable_result_log +ANALYZE TABLE t1; +-- enable_result_log + +# Select word "tutorial" in the table +SELECT * FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; + +# boolean mode +select * from t1 where MATCH(a,b) AGAINST("+tutorial +VÃÆ·Wİ" IN BOOLEAN MODE); +--error ER_PARSE_ERROR +select * from t1 where MATCH(a,b) AGAINST("+-VÃÆ·Wİ" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+Mysql +(tricks never)" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+mysql -(tricks never)" IN BOOLEAN MODE) ORDER BY id; +select *, MATCH(a,b) AGAINST("mysql stands" IN BOOLEAN MODE) as x from t1 ORDER BY id; +select * from t1 where MATCH a,b AGAINST ("+database* +VÃÆ·W*" IN BOOLEAN MODE); +select * from t1 where MATCH a,b AGAINST ('"security mysql"' IN BOOLEAN MODE); + +# query expansion +select * from t1 where MATCH(a,b) AGAINST ("VÃÆ·Wİ" WITH QUERY EXPANSION) ORDER BY id; + +# Drop index +ALTER TABLE t1 DROP INDEX idx; + +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + +-- disable_query_log +-- disable_result_log +ANALYZE TABLE t1; +-- enable_result_log +-- enable_query_log + +# Select word "tutorial" in the table +SELECT * FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; + +# boolean mode +select * from t1 where MATCH(a,b) AGAINST("+tutorial +VÃÆ·Wİ" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+dbms" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+Mysql +(tricks never)" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+mysql -(tricks never)" IN BOOLEAN MODE) ORDER BY id; +select *, MATCH(a,b) AGAINST("mysql VÃÆ·Wİ" IN BOOLEAN MODE) as x from t1 ORDER BY id; +# Innodb:Assert eval0eval.c line 148 +#select * from t1 where MATCH a,b AGAINST ("+database* +VÃÆ·Wİ*" IN BOOLEAN MODE); +select * from t1 where MATCH a,b AGAINST ('"security mysql"' IN BOOLEAN MODE); + +# query expansion +select * from t1 where MATCH(a,b) AGAINST ("VÃÆ·Wİ" WITH QUERY EXPANSION) ORDER BY id; + + +# insert for proximity search +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +# Insert into table with similar word of different distances +INSERT INTO t1 (a,b) VALUES + ('test proximity search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO t1 (a,b) VALUES + ('test proximity fts search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO t1 (a,b) VALUES + ('test more proximity fts search, test, more proximity and phrase', + 'search, with proximity innodb'); + +# This should only return the first document +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"proximity search"@2' IN BOOLEAN MODE); + +# This would return no document +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"proximity search"@1' IN BOOLEAN MODE); + +# This give you all three documents +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"proximity search"@3' IN BOOLEAN MODE) ORDER BY id; + +# Similar boundary testing for the words +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"test proximity"@5' IN BOOLEAN MODE) ORDER BY id; + +# Test with more word The last document will return, please notice there +# is no ordering requirement for proximity search. +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"more test proximity"@2' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); + +# The phrase search will not require exact word ordering +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"more fts proximity"@03' IN BOOLEAN MODE); + + +UPDATE t1 SET a = UPPER(a) , b = UPPER(b) ; +UPDATE t1 SET a = UPPER(a) , b = LOWER(b) ; + +select * from t1 where MATCH(a,b) AGAINST("+tutorial +dbms" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+VÃÆ·Wİ" IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; + +DELETE FROM t1 WHERE MATCH (a,b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +DELETE FROM t1 WHERE MATCH (a,b) AGAINST ('"proximity search"@14' IN BOOLEAN MODE); + + +SELECT * FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +SELECT * FROM t1 ORDER BY id; + +DROP TABLE t1; +eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; + +#------------------------------------------------------------------------------ +# FTS index with utf8 character testcase +#------------------------------------------------------------------------------ + +# Create FTS table +EVAL CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) CHARACTER SET = utf8, ENGINE=InnoDB; + + +# Insert rows from different languages +INSERT INTO t1 (a,b) VALUES +('Я могу еÑть Ñтекло', 'оно мне не вредит'), +('Мога да Ñм Ñтъкло', 'то не ми вреди'), +('ΜποÏá¿¶ νὰ φάω σπασμένα' ,'γυαλιὰ χωÏá½¶Ï‚ νὰ πάθω τίποτα'), +('PříliÅ¡ žluÅ¥ouÄký kůň', 'úpÄ›l Äábelské kódy'), +('Sævör grét', 'áðan því úlpan var ónýt'), +('ã†ã‚ã®ãŠãã‚„ã¾','ã‘ãµã“ãˆã¦'), +('ã„ã‚ã¯ã«ã»ã¸ã©ã€€ã¡ã‚Šã¬ã‚‹','ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš'); + +# insert english text +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','request docteam@oraclehelp.com ...') , + ('Trial version','query performace @1255 minute on 2.1Hz Memory 2GB...') , + ('when To Use MySQL Well','for free faq mail@xyz.com ...'); + +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + +# FTS Queries +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("вредит χωÏá½¶Ï‚") ORDER BY id; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("оно" WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("вред*" IN BOOLEAN MODE) ORDER BY id; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+γυαλιὰ +tutorial" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+tutorial +(Мога τίποτα)" IN BOOLEAN MODE); + +# Innodb:error - no result returned (update result of query once fixed) (innodb limit , does not understand character boundry for japanses like charcter set) +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš"); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ã¡ã‚Šã¬ã‚‹" WITH QUERY EXPANSION); + +# Innodb:error - no result returned (update result of query once fixed) (innodb limit , does not understand character boundry for japanses like charcter set) +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("+ã‚ã•ãゆã‚ã¿ã˜ã€€+ã‚‘ã²ã‚‚ã›ãš" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("ã†ã‚ã®ãŠã*" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"γυαλιὰ χωÏá½¶Ï‚"@2' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"query performace"@02' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"πάθω τίποτα"@2' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"ã‚ã•ãゆã‚ã¿ã˜ ã‚‘ã²ã‚‚ã›ãš"@1' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"ã‚ã•ãゆã‚ã¿ã˜ ã‚‘ã²ã‚‚ã›ãš"@2' IN BOOLEAN MODE); + +ALTER TABLE t1 DROP INDEX idx; +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + +# Innodb:error - no result returned (update result of query once fixed) (innodb limit , does not understand character boundry for japanses like charcter set) +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ã‚ã•ãゆã‚ã¿ã˜ ã‚‘ã²ã‚‚ã›ãš"); +# Update fails because where condition do not succeed which is incorrect (update result of query once fixed) +UPDATE t1 SET a = "Pchnąć w tÄ™ łódź jeża" , b = "lub osiem skrzyÅ„ fig" WHERE MATCH(a,b) AGAINST ("ã‚ã•ãゆã‚ã¿ã˜ ã‚‘ã²ã‚‚ã›ãš"); +UPDATE t1 SET a = "Ð’ чащах юга жил-был цитруÑ? Да", b = "но фальшивый ÑкземплÑÑ€! ёъ" WHERE MATCH(a,b) AGAINST ("вред*" IN BOOLEAN MODE); +DELETE FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); + +# Innodb error - no result returned +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš"); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("łódź osiem"); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("вред*" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("фальшив*" IN BOOLEAN MODE) ORDER BY id; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"łódź jeża"@2' IN BOOLEAN MODE); + +SELECT * FROM t1 ORDER BY id; +DROP TABLE t1; + +# This is to test the update operation on FTS indexed and non-indexed +# column +CREATE TABLE t1(ID INT PRIMARY KEY, + no_fts_field VARCHAR(10), + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); + +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); + +# Update FULLTEXT indexed column, Doc ID will be updated +UPDATE t1 SET fts_field='anychange' where id = 1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); + +# Update non-FULLTEXT indexed column, Doc ID stay to be the same +UPDATE t1 SET no_fts_field='anychange' where id = 1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); + +# Update both FULLTEXT indexed and non-indexed column, Doc ID will be updated +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where id = 1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); + +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); + +# FTS index dropped, the DOC_ID column is kept, however, the ID will not +# change +DROP INDEX f on t1; + +UPDATE t1 SET fts_field='anychange' where id = 1; + +UPDATE t1 SET no_fts_field='anychange' where id = 1; + +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where id = 1; + +CREATE FULLTEXT INDEX f ON t1(FTS_FIELD); + +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); + +DROP TABLE t1; + +# Test on user supplied 'FTS_DOC_ID' +CREATE TABLE t1(`FTS_DOC_ID` serial, + no_fts_field VARCHAR(10), + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); + +# Doc ID must be updated as well (HA_FTS_INVALID_DOCID). +--error 182 +UPDATE t1 SET fts_field='anychange' where FTS_DOC_ID = 1; + +UPDATE t1 SET fts_field='anychange', FTS_DOC_ID = 2 where FTS_DOC_ID = 1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); + +# "BBB" should be marked as deleted. +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); + +UPDATE t1 SET no_fts_field='anychange' where FTS_DOC_ID = 2; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); + +# "HA_FTS_INVALID_DOCID" +--error 182 +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where FTS_DOC_ID = 2; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); + +# Doc ID must be monotonically increase (HA_FTS_INVALID_DOCID) +--error 182 +UPDATE t1 SET FTS_DOC_ID = 1 where FTS_DOC_ID = 2; + +DROP INDEX f ON t1; + +# After FULLTEXT index dropped, we can update the fields freely +UPDATE t1 SET fts_field='newchange' where FTS_DOC_ID = 2; + +UPDATE t1 SET no_fts_field='anychange' where FTS_DOC_ID = 2; + +SELECT * FROM t1; + +DROP TABLE t1; + +CREATE TABLE t1(ID INT PRIMARY KEY, + no_fts_field VARCHAR(10), + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field), index k(fts_field)) ENGINE=INNODB; + +CREATE TABLE t2(ID INT PRIMARY KEY, + no_fts_field VARCHAR(10), + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field), + INDEX k2(fts_field), + FOREIGN KEY(fts_field) REFERENCES + t1(fts_field) ON UPDATE CASCADE) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); + +INSERT INTO t2 VALUES (1, 'AAA', 'BBB'); + +update t1 set fts_field='newchange' where id =1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +SELECT * FROM t2 WHERE MATCH(fts_field) against("BBB"); +SELECT * FROM t1 WHERE MATCH(fts_field) against("newchange"); +SELECT * FROM t2 WHERE MATCH(fts_field) against("newchange"); + +DROP TABLE t2; + +DROP TABLE t1; + +# Testcases adopted from innodb_multi_update.test + +CREATE TABLE t1(id INT PRIMARY KEY, + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; + + +CREATE TABLE t2(id INT PRIMARY KEY, + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; + +INSERT INTO t1 values (1,'100'),(2,'200'),(3,'300'),(4,'400'),(5,'500'),(6,'600'), (7,'700'),(8,'800'),(9,'900'),(10,'1000'),(11,'1100'),(12,'1200'); +INSERT INTO t2 values (1,'100'),(2,'200'),(3,'300'),(4,'400'),(5,'500'),(6,'600'), (7,'700'),(8,'800'); + +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'foo'); + +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'foo') WHERE t1.fts_field = "100foo"; + +# Update two tables in the same statement +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'xoo'), t2.fts_field = CONCAT(t1.fts_field, 'xoo') where t1.fts_field=CONCAT(t2.fts_field, 'foo'); + +# Following selects shows whether the correct Doc ID are updated + +# This row should present in table t1 +SELECT * FROM t1 WHERE MATCH(fts_field) against("100foofoo"); + +# Following rows should be dropped +SELECT * FROM t1 WHERE MATCH(fts_field) against("100foo"); +SELECT * FROM t1 WHERE MATCH(fts_field) against("100"); + +# This row should present in table t2 +SELECT * FROM t2 WHERE MATCH(fts_field) against("400fooxoo"); +SELECT * FROM t2 WHERE MATCH(fts_field) against("100"); + +# Follow rows should be marked as dropped +SELECT * FROM t2 WHERE MATCH(fts_field) against("200"); +SELECT * FROM t2 WHERE MATCH(fts_field) against("400"); + + +DROP TABLE t1; + +DROP TABLE t2; + + +--echo +--echo BUG#13701973/64274: MYSQL THREAD WAS SUSPENDED WHEN EXECUTE UPDATE QUERY +--echo +# FTS setup did not track which tables it had already looked at to see whether +# they need initialization. Hilarity ensued when hitting circular dependencies. + +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; + +CREATE TABLE t1 ( + t1_id INT(10) UNSIGNED NOT NULL, + t2_id INT(10) UNSIGNED DEFAULT NULL, + PRIMARY KEY (t1_id), + FOREIGN KEY (t2_id) REFERENCES t2 (t2_id) + ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +CREATE TABLE t2 ( + t1_id INT(10) UNSIGNED NOT NULL, + t2_id INT(10) UNSIGNED NOT NULL, + t3_id INT(10) UNSIGNED NOT NULL, + t4_id INT(10) UNSIGNED NOT NULL, + PRIMARY KEY (t2_id), + FOREIGN KEY (t1_id) REFERENCES t1 (t1_id), + FOREIGN KEY (t3_id) REFERENCES t3 (t3_id) + ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (t4_id) REFERENCES t4 (t4_id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( + t3_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + payload char(3), + PRIMARY KEY (t3_id) +) ENGINE=InnoDB; + +INSERT INTO t3 VALUES (1, '100'); + +CREATE TABLE t4 ( + t2_id INT(10) UNSIGNED DEFAULT NULL, + t4_id INT(10) UNSIGNED NOT NULL, + PRIMARY KEY (t4_id), + FOREIGN KEY (t2_id) REFERENCES t2 (t2_id) + ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +SET FOREIGN_KEY_CHECKS=1; + +UPDATE t3 SET payload='101' WHERE t3_id=1; + +SET FOREIGN_KEY_CHECKS=0; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; + +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; diff --git a/mysql-test/suite/innodb_fts/t/opt.opt b/mysql-test/suite/innodb_fts/t/opt.opt new file mode 100644 index 00000000000..d7d47164883 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/opt.opt @@ -0,0 +1 @@ +--query_cache_type=0 diff --git a/mysql-test/suite/innodb_fts/t/opt.test b/mysql-test/suite/innodb_fts/t/opt.test new file mode 100644 index 00000000000..19dfdcad8fd --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/opt.test @@ -0,0 +1,1086 @@ +--source include/have_innodb.inc + +# +# Tests for optimizations for InnoDB fulltext search (WL#6043) +# + +CREATE TABLE wp( + FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + title VARCHAR(255) NOT NULL DEFAULT '', + text MEDIUMTEXT NOT NULL, + dummy INTEGER, + PRIMARY KEY (FTS_DOC_ID), + UNIQUE KEY FTS_DOC_ID_INDEX (FTS_DOC_ID), + FULLTEXT KEY idx (title,text) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO wp (title, text) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database to database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 SELECT FTS_DOC_ID FROM wp; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE wp; + +--disable_ps2_protocol + +# +# Show results of MATCH expressions for reference +# +SELECT FTS_DOC_ID, title, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp; + +# +# Test that filesort is not used if ordering on same match expression +# as where clause +# +--echo No sorting for this query +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo No sorting for this query even if MATCH is part of an expression +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') > 0.1 +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo No sorting even if there are several MATCH expressions as long as the +--echo right one is used in ORDER BY +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score1 DESC; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo No Sorting since FT table is first table in query +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID = t1.i +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since there is no WHERE clause +FLUSH STATUS; + +--sorted_result +SELECT MATCH(title, text) AGAINST ('database'), title AS score +FROM wp +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since ordering on multiple columns +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC, FTS_DOC_ID; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since ordering is not descending +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score ASC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting because one is ordering on a different MATCH expression +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('mysql') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +# +# Tests for ORDER BY/LIMIT optimzation +# +--echo No sorting for this query +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo Revert to table scan and sorting for this query since not +--echo enough matching rows to satisfy LIMIT clause +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since no LIMIT clause +FLUSH STATUS; + +--sorted_result +SELECT MATCH(title, text) AGAINST ('database') AS score, title +FROM wp +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since there is a WHERE clause +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE dummy IS NULL +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since ordering is not on a simple MATCH expressions +FLUSH STATUS; + +SELECT title, (MATCH(title, text) AGAINST ('database')) * 100 AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +# +# Test that there is no row accesses if all necessary information is +# available in FTS result +# +--echo No ordinary handler accesses when only accessing FTS_DOC_ID and MATCH +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Still no handler accesses when adding FTS_DOC_ID to WHERE clause +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID > 2; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Still no handler accesses when ordering by MATCH expression +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Optimization is disabled when ordering on FTS_DOC_ID +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY 1 DESC; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Optimization also work with several MATCH expressions +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Optimization does not apply if sorting on a different MATCH expressions +--echo from the one used to access the +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score2 DESC; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +FLUSH STATUS; + +--echo Optimization does not apply for GROUP BY +SET @save_mode = @@sql_mode; +SET sql_mode = (select replace(@@sql_mode,'ONLY_FULL_GROUP_BY','')); +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +GROUP BY score; + +SHOW SESSION STATUS LIKE 'Handler_read%'; +SET sql_mode = @save_mode; + +# +# Putting all three optimizations together +# +--echo No sorting and no table access with LIMIT clause and only information +--echo from FTS result +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# +# Count optimization +# +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); + +--echo If count optimization applies, EXPLAIN shows +--echo "Select tables optimized away." +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +--echo Verify that there was no table access +SHOW STATUS LIKE 'Handler_read%'; + +let $query = +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); + +--echo Optimization applies also to COUNT(expr) as long as expr is not nullable +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT count(*) +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database'); + +--echo Optimization does not apply if not a single table query. +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; + +--echo Optimization does not apply if MATCH is part of an expression +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; + +--echo Optimization does not apply if MATCH is part of an expression +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT COUNT(dummy) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); + +--echo Optimization does not apply if COUNT expression is nullable +eval EXPLAIN $query; +eval $query; + +# +# Verify that the queries optimized for InnoDB works with QUERY EXPANSION +# + +# Query will also avoid sorting when query expansion is used +FLUSH STATUS; +--sorted_result +SELECT MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score, +title +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' WITH QUERY EXPANSION); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + +# +# Verify that the queries optimized for InnoDB works with BOOLEAN MODE +# + +# Query will also avoid sorting when Boolean mode is used +FLUSH STATUS; +--sorted_result +SELECT MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) score, +title +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +--sorted_result +SELECT MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) score, +title +FROM wp +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('+MySQL -database' IN BOOLEAN MODE); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + + +# +# Verify that the queries optimized for InnoDB works with +# BOOLEAN proximity search +# + +# Query will also avoid sorting when Boolean mode is used +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + +# +# Check that nothing goes wrong when combining different modes +# +SELECT title, + MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC, title ASC; + +SELECT title, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('MySQL database' WITH QUERY EXPANSION) +ORDER BY score DESC, title ASC; + +SELECT title, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC, title ASC; + + +# +# Verify that the queries optimized for InnoDB still works with MyISAM +# +ALTER TABLE wp ENGINE=myisam; + +# Check avoid sorting query +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + + +DROP TABLE wp, t1; + +--enable_ps2_protocol + +# Tests for FT hints. + +CREATE TABLE t1 +( + FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + title VARCHAR(255) DEFAULT '', + text MEDIUMTEXT , + PRIMARY KEY (FTS_DOC_ID), + UNIQUE KEY FTS_DOC_ID_INDEX (FTS_DOC_ID), + FULLTEXT KEY ft_idx (title,text) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + + +INSERT INTO t1 (title, text) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL database','In the following database to database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'), + ('InnoDB', 'InnoDB is a transaction-safe (ACID compliant) storage engine'), + ('MySQL is a database management system', 'A database is a structured collection of data...'), + ('MySQL databases are relational', 'A relational database stores data in separate tables rather than putting all the data in one big storeroom...'), + ('MySQL software is Open Source', 'Open Source means that it is possible for anyone to use and modify the software...'), + ('The MySQL Database Server is very fast, reliable, scalable, and easy to use', 'MySQL Server can run comfortably on a desktop or laptop...'), + ('MySQL Server works in client/server or embedded systems', 'The MySQL Database Software is a client/server system...'), + ('MyISAM', 'MyISAM is based on the older (and no longer available) ISAM storage engine but has many useful extensions'), + ('A large amount of contributed MySQL software is available', 'MySQL Server has a practical set of features developed in close cooperation with our users'), + (NULL,NULL); + +-- disable_result_log +ANALYZE TABLE t1; +-- enable_result_log + +--echo # No ranking + +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE); +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE); + +# Atm opt_sum_query does not support COUNT optimization if +# ORDER BY is present. TODO: fix it. +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('data*' IN BOOLEAN MODE) ORDER BY title LIMIT 3; +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('data*' IN BOOLEAN MODE) ORDER BY title LIMIT 3; + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION); +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION); + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE); +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE); + +# check case with 'for' stopword +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+for' IN BOOLEAN MODE); +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+for' IN BOOLEAN MODE); + + +--echo # No sorting by rank + +EXPLAIN SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY title; +SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY title; + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title; +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title; + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title; +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title; + +--echo # LIMIT optimization + +EXPLAIN SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +LIMIT 3; +SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +LIMIT 3; +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +ORDER BY title +LIMIT 3; +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +ORDER BY title +LIMIT 3; + + +EXPLAIN +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title LIMIT 1; +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title LIMIT 1; + +EXPLAIN +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title LIMIT 1; +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title LIMIT 1; + +EXPLAIN +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank, FTS_DOC_ID +LIMIT 3; +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank, FTS_DOC_ID +LIMIT 3; + +EXPLAIN +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank DESC, FTS_DOC_ID ASC +LIMIT 3; +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank DESC, FTS_DOC_ID ASC +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; + +EXPLAIN SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 3; +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC, +FTS_DOC_ID ASC; +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC, +FTS_DOC_ID ASC; + +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) and FTS_DOC_ID > 1 +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC +LIMIT 2; +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) and FTS_DOC_ID > 1 +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC +LIMIT 2; + + +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank +LIMIT 1; +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank +LIMIT 1; + +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank DESC +LIMIT 1; +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank DESC +LIMIT 1; + + +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +LIMIT 1; +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) DESC +LIMIT 1; + +--echo # WHERE optimization on MATCH > 'some_rank' + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) > 0.1; + +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) > 0.1; + + +--echo # additional test for correct behaviour + +EXPLAIN SELECT * FROM t1 ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC LIMIT 10; + +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) AND +MATCH (title, text) AGAINST ('mysql' IN NATURAL LANGUAGE MODE) +LIMIT 6; + +--echo # test OR condition + +SELECT FTS_DOC_ID +FROM t1 +WHERE MATCH(title, text) AGAINST ('database') + OR MATCH(title, text) AGAINST ('mysql') +ORDER BY MATCH(title, text) AGAINST ('database') DESC, FTS_DOC_ID ASC; + +EXPLAIN SELECT FTS_DOC_ID +FROM t1 +WHERE MATCH(title, text) AGAINST ('database') + OR MATCH(title, text) AGAINST ('mysql') +ORDER BY MATCH(title, text) AGAINST ('database') DESC, FTS_DOC_ID ASC; + +--echo # MATCH and GROUP BY, DISTINCT + +SET sql_mode = (select replace(@@sql_mode,'ONLY_FULL_GROUP_BY','')); + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY FTS_DOC_ID +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY FTS_DOC_ID +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY title +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY title +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +EXPLAIN SELECT MAX(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +SELECT MAX(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +EXPLAIN SELECT DISTINCT(title) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +SELECT DISTINCT(title) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +EXPLAIN SELECT DISTINCT(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +SELECT DISTINCT(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +SET sql_mode = @save_mode; + +--echo # FTS index access + +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; + +SELECT a.FTS_DOC_ID, b.FTS_DOC_ID +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and + MATCH(b.title, b.text) AGAINST ('+mysql' IN BOOLEAN MODE) and + a.FTS_DOC_ID = b.FTS_DOC_ID; +EXPLAIN SELECT a.FTS_DOC_ID, b.FTS_DOC_ID +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and + MATCH(b.title, b.text) AGAINST ('+mysql' IN BOOLEAN MODE) and + a.FTS_DOC_ID = b.FTS_DOC_ID; + +SELECT a.FTS_DOC_ID, MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE), + b.FTS_DOC_ID, MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and + MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE); + +EXPLAIN SELECT a.FTS_DOC_ID, MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE), + b.FTS_DOC_ID, MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and + MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE); + +# Index only access by non-FTS index + +EXPLAIN SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100; +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100 +FROM t1 WHERE MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100; +# Run query returning null record +SELECT * FROM t1 WHERE title IS NULL AND text IS NULL; + +# More testing of index only access by non-FTS index + +CREATE TABLE t2 SELECT FTS_DOC_ID as doc_id, title, text FROM t1; +ALTER TABLE t2 ADD PRIMARY KEY (doc_id); +ALTER TABLE t2 ADD FULLTEXT KEY ft_idx (title,text); + +-- disable_result_log +ANALYZE TABLE t2; +-- enable_result_log + +# No index access +EXPLAIN SELECT DOC_ID FROM t2 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +SELECT DOC_ID FROM t2 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +# Index access +EXPLAIN SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; + +DROP TABLE t1, t2; + +--echo "Check hints with uft8 charset for 2 cases" +set names utf8; +EVAL CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + text TEXT + ) CHARACTER SET = utf8, ENGINE=InnoDB; + +INSERT INTO t1 (title, text) VALUES +('Я могу еÑть Ñтекло', 'оно мне не вредит'), +('Мога да Ñм Ñтъкло', 'то не ми вреди'), +('ΜποÏá¿¶ νὰ φάω σπασμένα' ,'γυαλιὰ χωÏá½¶Ï‚ νὰ πάθω τίποτα'), +('PříliÅ¡ žluÅ¥ouÄký kůň', 'úpÄ›l Äábelské kódy'), +('Sævör grét', 'áðan því úlpan var ónýt'), +('ã†ã‚ã®ãŠãã‚„ã¾','ã‘ãµã“ãˆã¦'), +('ã„ã‚ã¯ã«ã»ã¸ã©ã€€ã¡ã‚Šã¬ã‚‹','ã‚ã•ãゆã‚ã¿ã˜ã€€ã‚‘ã²ã‚‚ã›ãš'); +CREATE FULLTEXT INDEX idx on t1 (title, text); + +--echo # No ranking + +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('вредит' IN NATURAL LANGUAGE MODE); +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('вредит' IN NATURAL LANGUAGE MODE); + +EXPLAIN +SELECT * FROM t1 WHERE MATCH(title, text) AGAINST ("оно" WITH QUERY EXPANSION); +SELECT * FROM t1 WHERE MATCH(title, text) AGAINST ("оно" WITH QUERY EXPANSION); +--echo # No sorting by rank +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+(Мога τίποτα)' IN BOOLEAN MODE); +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+(Мога τίποτα)' IN BOOLEAN MODE); +DROP TABLE t1; + + +--echo # +--echo # Bug #18924341 CRASH IN TEST_IF_SKIP_SORT_ORDER, GROUP BY MATCH AGAINST DESC +--echo # + +CREATE TABLE t1 (f1 CHAR(1), FULLTEXT KEY (f1)); +SELECT 1 FROM t1 NATURAL JOIN t1 a GROUP BY MATCH(t1.f1) AGAINST ("1") DESC; +DROP TABLE t1; + + +--echo # +--echo # Bug#20261601 ASSERTION FAILED: !FIRST_QEP_TAB->TABLE()->NO_KEYREAD +--echo # + +CREATE TABLE t1(a INT PRIMARY KEY); +INSERT INTO t1 VALUES(1),(2); +--error ER_FT_MATCHING_KEY_NOT_FOUND +SELECT (SELECT MATCH(`a`)AGAINST('1') FROM t1) FROM t1; +SELECT 1, a IN (SELECT a FROM t1) FROM t1; +DROP TABLE t1; + +--echo # +--echo # Bug#20442572 ASSERTION `!FIRST_QEP_TAB->TABLE()->NO_KEYREAD' FAILED. +--echo # Bug#75688 Assertion `!first_qep_tab->table()->no_keyread' failed. +--echo # + +CREATE TABLE t1(a INT,b POINT NOT NULL,KEY(a)); + +HANDLER t1 OPEN; +#--error ER_FT_MATCHING_KEY_NOT_FOUND +select * from t1 where MATCH a,b AGAINST('"Now sUPPort"' IN BOOLEAN MODE); +prepare stmt1 from "truncate t1"; +SELECT a IN(SELECT a FROM t1)FROM t1; + +deallocate prepare stmt1; +DROP TABLE t1; + +--echo # +--echo # Bug #20685427 INVALID WRITE OF FREED MEMORY IN ITEM_FUNC_MATCH::CLEANUP +--echo # + +CREATE TABLE t1(a TEXT CHARSET LATIN1, FULLTEXT KEY(a)) ENGINE=INNODB; +--error ER_FT_MATCHING_KEY_NOT_FOUND +SELECT MATCH(a) AGAINST ('') FROM (SELECT a FROM t1 LIMIT 1) q; +DROP TABLE t1; + +--echo # +--echo # Bug#21140067 EXPLAIN .. MATCH AGAINST: ASSERTION FAILED: TO <= END +--echo # + +CREATE TABLE t1(f1 CHAR(1) CHARSET latin1, FULLTEXT(f1)) ENGINE=INNODB; +EXPLAIN SELECT 1 FROM t1 WHERE 1.238585e+308 <= MATCH(f1) AGAINST ('1' IN BOOLEAN MODE); + +EXPLAIN FORMAT = JSON SELECT 1 FROM t1 WHERE 1.238585e+308 <= MATCH(f1) AGAINST ('1' IN BOOLEAN MODE); + +DROP TABLE t1; + +--echo # +--echo # Bug#21140088 MATCH AGAINST: ASSERTION FAILED: !TABLE || (!TABLE->READ_SET || BITMAP_IS_SET +--echo # + +SET sql_mode=''; +CREATE TABLE t1(a INT) ENGINE=INNODB; +CREATE TABLE t2(b TEXT CHARSET LATIN1, FULLTEXT(b), PRIMARY KEY(b(10))) ENGINE=INNODB; +INSERT INTO t2 VALUES ('a'),('b'); +--error ER_WRONG_ARGUMENTS +SELECT NOT EXISTS (SELECT MATCH(b) AGAINST ('1') FROM t1) FROM t2 GROUP BY "a"; +DROP TABLE t1, t2; + +CREATE TABLE t1(a INT) ENGINE=MyISAM; +CREATE TABLE t2(b TEXT CHARSET LATIN1, FULLTEXT(b), PRIMARY KEY(b(10))) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('a'),('b'); +#--error ER_WRONG_ARGUMENTS +SELECT NOT EXISTS (SELECT MATCH(b) AGAINST ('1' in BOOLEAN MODE) FROM t1) FROM t2 GROUP BY "a"; +DROP TABLE t1, t2; + +SET sql_mode=default; + +--echo # +--echo # Bug#21140039 ASSERTION FAILED: !FIRST_QEP_TAB->TABLE()->NO_KEYREAD MATCH AGAINST..... +--echo # + +CREATE TABLE t1 +( + a INT, + b INT, + c CHAR(1) CHARSET latin1, + PRIMARY KEY (b,a), + FULLTEXT KEY (c) +) ENGINE=INNODB; +SELECT "a" NOT IN(SELECT b FROM t1 WHERE MATCH(c) AGAINST ('a' IN BOOLEAN MODE)); +DROP TABLE t1; + +--echo # +--echo # Bug#21300774 ASSERT `!INIT_FTFUNCS(THD, SELECT_LEX)` IN JOIN::RESET AT SQL/SQL_SELECT.CC:874 +--echo # + +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +CREATE TABLE t2 (ft TEXT, FULLTEXT KEY ft(ft)); +INSERT INTO t2 VALUES ('abc'); +INSERT INTO t2 VALUES ('def'); + +--error ER_SUBQUERY_NO_1_ROW +UPDATE t1 SET f1 = +(SELECT t1.f1 FROM t2 WHERE NOT TRUE AND + MATCH (ft) AGAINST ((SELECT 'xyz' FROM t2))); + +DROP TABLE t1, t2; + +--echo # +--echo # Bug#22679209: FULL-TEXT QUERIES WITH ADDITIONAL SECONDARY INDEX +--echo # GIVES NULL OR ZERO ROWS +--echo # + +CREATE TABLE t1 ( +f1 INTEGER, +title varchar(255), +body mediumtext, +KEY f1 (f1), +FULLTEXT KEY title (title), +FULLTEXT KEY body (body) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES +(1, 'Insert into table', 'insert into table select from'), +(1, 'Delete from table', 'insert into table select from'), +(1, 'Update', 'perform update'), +(2, 'Insert into table', 'insert into table select from'), +( 2, 'Delete from table', 'some body text here'), +( 2, 'Update', 'perform update'), +( 3, 'Insert into table', 'insert into table select from'), +( 3, 'Delete from table', 'some body text here'); + +SELECT f1 FROM t1 WHERE f1=1 AND +(MATCH (title) AGAINST ('table' IN BOOLEAN MODE) OR +MATCH (body) AGAINST ('table' IN BOOLEAN MODE)); + +DROP TABLE t1; + +--echo # End of test for Bug#22679209 diff --git a/mysql-test/suite/innodb_fts/t/phrase.opt b/mysql-test/suite/innodb_fts/t/phrase.opt new file mode 100644 index 00000000000..7724f97647f --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/phrase.opt @@ -0,0 +1,2 @@ +--innodb-ft-index-cache +--innodb-ft-index-table diff --git a/mysql-test/suite/innodb_fts/t/phrase.test b/mysql-test/suite/innodb_fts/t/phrase.test new file mode 100644 index 00000000000..fb0d29f369a --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/phrase.test @@ -0,0 +1,39 @@ +-- source include/have_innodb.inc + +# +# BUG#20465273 - FULLTEXT SEARCH BEHAVIOUR WITH MYISAM VS. INNODB (WRONG RESULT WITH INNODB) +# + +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) +) ENGINE=InnoDB; + +INSERT INTO articles (title,body) VALUES + (NULL, 'mysql good database'), + (NULL, ' mysql good database'), + ('', 'mysql good database'), + ('', ' mysql good database'), + (' ', 'mysql good database'), + ('mysql', 'good database'), + ('mysql ', 'good database'), + ('mysql', ' good database'), + ('mysql good database', ''), + ('mysql good database', NULL); + + +SET GLOBAL innodb_ft_aux_table="test/articles"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM articles; + +SELECT * FROM articles WHERE MATCH(title, body) + AGAINST('"mysql good database"' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE MATCH(title, body) + AGAINST('("mysql good database")' IN BOOLEAN MODE); + +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/t/result_cache_limit.test b/mysql-test/suite/innodb_fts/t/result_cache_limit.test new file mode 100644 index 00000000000..b19907a5052 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/result_cache_limit.test @@ -0,0 +1,52 @@ +# This is a basic test for innodb fts result cache limit. + +-- source include/have_innodb.inc + +# Must have debug code to use SET SESSION debug +--source include/have_debug.inc + +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE= InnoDB; + +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), + ('where will Optimizing MySQL','what In this tutorial we will show ...'), + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), + ('where will Optimizing MySQL','what In this tutorial we will show ...'), + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), + ('where will Optimizing MySQL','what In this tutorial we will show ...'); + +SET @save_limit=@@GLOBAL.innodb_ft_result_cache_limit; +SET @save_dbug=@@debug_dbug; +SET debug_dbug="+d,fts_instrument_result_cache_limit"; + +# Simple term search +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('mysql' IN BOOLEAN MODE); + +# Query expansion +--error 128 +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('mysql' WITH QUERY EXPANSION); + +# Simple phrase search +--error 128 +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('"mysql database"' IN BOOLEAN MODE); + +# Simple proximity search +--error 128 +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('"mysql database" @ 5' IN BOOLEAN MODE); + +SET debug_dbug=@save_dbug; + +DROP TABLE t1; +SET GLOBAL innodb_ft_result_cache_limit=@save_limit; diff --git a/mysql-test/suite/innodb_fts/t/savepoint.test b/mysql-test/suite/innodb_fts/t/savepoint.test new file mode 100644 index 00000000000..09ccb383bb9 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/savepoint.test @@ -0,0 +1,475 @@ +# This is the basic function tests for innodb FTS savepoint + +-- source include/have_innodb.inc + + +CREATE TABLE articles ( + id INT UNSIGNED NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT (title) + ) ENGINE= InnoDB; + +# Test Part 1: ROLLBACK TO SAVEPOINT +# Test rollback to savepoint 1(S1,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback to savepoint 2(S1,RB1,S2,RB2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback to savepoint 3(S1,S2,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback to savepoint 4(S1,S2,RB2,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test Part 2: RELEASE SAVEPOINT +# Test release savepoint 1(S1,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release savepoint 2(S1,RL1,S2,RL2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release savepoint 3(S1,S2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release savepoint 4(S1,S2,RL2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test Part 3: RELEASE & ROLLBACK TO SAVEPOINT +# Test release & rollback to savepoint 1(S1,RB1,S2,RL2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release & rollback to savepoint 2(S1,RL1,S2,RB2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release & rollback to savepoint 3(S1,S2,RL2,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release & rollback to savepoint 4(S1,S2,RB2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test Part 4: ROLLBACK & SAVEPOINT +# Test rollback 1 +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 2(S1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 3(S1,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 4(S1,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 5(S1,S2,RB2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/t/subexpr.test b/mysql-test/suite/innodb_fts/t/subexpr.test new file mode 100644 index 00000000000..632940661b5 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/subexpr.test @@ -0,0 +1,58 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #20028323 INNODB FULLTEXT BOOLEAN SEARCH INCORRECTLY HANDLES +--echo # PARENTHESES +--echo # + +CREATE TABLE t1 ( + f1 INT NOT NULL AUTO_INCREMENT, + f2 TEXT NOT NULL, + PRIMARY KEY (f1), + FULLTEXT (f2) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO t1 (f2) VALUES +('Pumpkin soup with cheese bread'), +('Yellow chicken curry'), +('Fresh green vegetables with garlic'); + +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+pumpkin' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+cheese' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+(pumpkin cheese)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle tart)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(>souffle souffle 30 limit 10; -rollback; -select count(*) from t1; -select * from t1 where keyc > 30 limit 10; -# -update t1 set keyc = keyc + 2000; -select * from t1 limit 10; -rollback; -begin; -update t1 set keyc = keyc + 2000; -select * from t1 limit 10; -rollback; -select * from t1 limit 10; -commit; -select * from t1 limit 10; -# -insert into t2 select * from t1 where keyc < 2101; -select count(*) from t2; -# -drop procedure populate_t1; -drop procedure populate_t1_small; -drop procedure populate_t1_small2; diff --git a/mysql-test/suite/mariabackup/backup_grants.result b/mysql-test/suite/mariabackup/backup_grants.result index 56899f8d9c0..6bd6c9f42cd 100644 --- a/mysql-test/suite/mariabackup/backup_grants.result +++ b/mysql-test/suite/mariabackup/backup_grants.result @@ -3,12 +3,13 @@ FOUND 1 /missing required privilege RELOAD/ in backup.log FOUND 1 /missing required privilege PROCESS/ in backup.log FOUND 1 /GRANT USAGE ON/ in backup.log GRANT RELOAD, PROCESS on *.* to backup@localhost; -NOT FOUND /missing required privilege REPLICA MONITOR/ in backup.log +FOUND 1 /missing required privilege REPLICA MONITOR/ in backup.log GRANT REPLICA MONITOR ON *.* TO backup@localhost; REVOKE REPLICA MONITOR ON *.* FROM backup@localhost; +FOUND 1 /missing required privilege CONNECTION ADMIN/ in backup.log GRANT CONNECTION ADMIN ON *.* TO backup@localhost; FOUND 1 /missing required privilege REPLICATION SLAVE ADMIN/ in backup.log -NOT FOUND /missing required privilege REPLICA MONITOR/ in backup.log +FOUND 1 /missing required privilege REPLICA MONITOR/ in backup.log GRANT REPLICATION SLAVE ADMIN ON *.* TO backup@localhost; GRANT REPLICA MONITOR ON *.* TO backup@localhost; DROP USER backup@localhost; diff --git a/mysql-test/suite/mariabackup/backup_grants.test b/mysql-test/suite/mariabackup/backup_grants.test index 894ae73aeb9..18db3489a94 100644 --- a/mysql-test/suite/mariabackup/backup_grants.test +++ b/mysql-test/suite/mariabackup/backup_grants.test @@ -10,7 +10,7 @@ rmdir $targetdir; # backup fails without --no-lock, because of FTWRL --disable_result_log error 1; -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/backup.log; @@ -31,7 +31,7 @@ rmdir $targetdir; # --slave-info and galera info require REPLICA MONITOR --disable_result_log error 1; -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --slave-info --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --slave-info --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log rmdir $targetdir; @@ -47,16 +47,15 @@ REVOKE REPLICA MONITOR ON *.* FROM backup@localhost; # TODO need a query that would delay a BACKUP STAGE START/ BACKUP STAGE BLOCK_COMMIT longer than the kill-long-queries-timeout #--send SELECT SLEEP(9) kill_me -## kill-long-query-type=(not empty) requires CONNECTION ADMIN -#--disable_result_log -#error 1; -#--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --kill-long-query-type=all --kill-long-queries-timeout=4 --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log; -#--reap -#--enable_result_log -#rmdir $targetdir; -# -#--let SEARCH_PATTERN= missing required privilege CONNECTION ADMIN -#--source include/search_pattern_in_file.inc + +# kill-long-query-type=(not empty) requires CONNECTION ADMIN +--disable_result_log +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --kill-long-query-type=ALL --kill-long-queries-timeout=4 --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; +--enable_result_log +rmdir $targetdir; + +--let SEARCH_PATTERN= missing required privilege CONNECTION ADMIN +--source include/search_pattern_in_file.inc GRANT CONNECTION ADMIN ON *.* TO backup@localhost; --disable_result_log diff --git a/mysql-test/suite/mariabackup/slave_provision_nolock.cnf b/mysql-test/suite/mariabackup/slave_provision_nolock.cnf new file mode 100644 index 00000000000..0e0bbd63f39 --- /dev/null +++ b/mysql-test/suite/mariabackup/slave_provision_nolock.cnf @@ -0,0 +1,13 @@ +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb + +[ENV] +SERVER_MYPORT_1= @mysqld.1.port +SERVER_MYSOCK_1= @mysqld.1.socket +SERVER_MYPORT_2= @mysqld.2.port +SERVER_MYSOCK_2= @mysqld.2.socket diff --git a/mysql-test/suite/mariabackup/slave_provision_nolock.result b/mysql-test/suite/mariabackup/slave_provision_nolock.result new file mode 100644 index 00000000000..de63a5db84b --- /dev/null +++ b/mysql-test/suite/mariabackup/slave_provision_nolock.result @@ -0,0 +1,44 @@ +call mtr.add_suppression("Can't init tc log"); +call mtr.add_suppression("Aborting"); +# restart +RESET MASTER; +CREATE TABLE t1(a varchar(60) PRIMARY KEY, b VARCHAR(60)) ENGINE INNODB; +INSERT INTO t1 VALUES(1, NULL); +CREATE TABLE t2 (val INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (0); +connect con1,localhost,root,,; +*** Start a background load... +CALL gen_load(); +connection default; +*** Doing backup... +*** Doing prepare... +*** Stop the background load... +UPDATE t2 SET val=1; +connection con1; +connection default; +disconnect con1; +*** Provision a new slave from the backup +connect server2,127.0.0.1,root,,,$SERVER_MYPORT_2; +*** Stopping provisioned server +*** Removing old datadir for provisioned server +*** Provision new server from backup +# restart +*** Configure slave position from xtrabackup_binlog_pos_innodb +CREATE TABLE t3 (file VARCHAR(255), pos INT) ENGINE=InnoDB; +LOAD DATA LOCAL INFILE "BASEDIR/xtrabackup_binlog_pos_innodb" + INTO TABLE t3 FIELDS ESCAPED BY '' (file, pos); +CHANGE MASTER TO +master_port=PORT, master_host='127.0.0.1', master_user='root', +master_log_file= "MASTER_FILE", +master_log_pos= MASTER_POS; +START SLAVE; +connection default; +connection server2; +connection server2; +STOP SLAVE; +RESET SLAVE ALL; +DROP PROCEDURE gen_load; +DROP TABLE t1, t2, t3; +connection default; +DROP PROCEDURE gen_load; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/mariabackup/slave_provision_nolock.test b/mysql-test/suite/mariabackup/slave_provision_nolock.test new file mode 100644 index 00000000000..618f313290c --- /dev/null +++ b/mysql-test/suite/mariabackup/slave_provision_nolock.test @@ -0,0 +1,170 @@ +--source include/have_innodb.inc +--source include/have_log_bin.inc + +call mtr.add_suppression("Can't init tc log"); +call mtr.add_suppression("Aborting"); + +# Test provisioning a slave from an existing server, using mariabackup --no-lock +# and the binlog position recovered from InnoDB redo log. + +# Update the InnoDB system tablespace to simulate a pre-10.3.5 +# position in TRX_SYS. There was a bug that the wrong position could +# be recovered if the old filename in TRX_SYS compares newer than the +# newer filenames stored in rseg headers. +let MYSQLD_DATADIR=`select @@datadir`; +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; + +--source include/shutdown_mysqld.inc + +--perl +use strict; +use warnings; +use Fcntl qw(:DEFAULT :seek); +do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; + +my $ps = $ENV{INNODB_PAGE_SIZE}; + +sysopen IBD_FILE, "$ENV{MYSQLD_DATADIR}/ibdata1", O_RDWR + or die "Cannot open ibdata1: $!\n"; + +# Read the TRX_SYS page. +my $page; +sysseek(IBD_FILE, $ps * 5, SEEK_SET) + or die "Cannot seek ibdata1: $!\n"; +sysread(IBD_FILE, $page, $ps) + or die "Cannot read ibdata1: $!\n"; + +# Put in an old binlog position that will compare larger than master-bin.000001 +my $old_name= '~~~-bin.999999' . chr(0); +my $old_off= 0xffff0000; +my $old_magic= 873422344; +my $binlog_offset= $ps - 1000 + 38; +substr($page, $binlog_offset, 4)= pack('N', $old_magic); +substr($page, $binlog_offset + 4, 4)= pack('N', ($old_off >> 32)); +substr($page, $binlog_offset + 8, 4)= pack('N', ($old_off & 0xffffffff)); +substr($page, $binlog_offset + 12, length($old_name))= $old_name; + +# Write back the modified page. +my $full_crc32= get_full_crc32(\*IBD_FILE); +$page= fix_page_crc($page, $full_crc32); +sysseek(IBD_FILE, $ps * 5, SEEK_SET) + or die "Cannot seek ibdata1: $!\n"; +syswrite(IBD_FILE, $page, $ps) == $ps + or die "Cannot write ibdata1: $!\n"; +close IBD_FILE; +EOF + +--source include/start_mysqld.inc + + +let $basedir=$MYSQLTEST_VARDIR/tmp/backup; + +RESET MASTER; +CREATE TABLE t1(a varchar(60) PRIMARY KEY, b VARCHAR(60)) ENGINE INNODB; +INSERT INTO t1 VALUES(1, NULL); +CREATE TABLE t2 (val INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (0); + +--disable_query_log +--delimiter // +CREATE PROCEDURE gen_load() + MODIFIES SQL DATA + BEGIN + DECLARE i INT; + DECLARE flag TYPE OF t2.val; + SET i = 0; + load_loop: LOOP + SELECT val INTO flag FROM t2; + IF NOT (flag=0) THEN + LEAVE load_loop; + END IF; + START TRANSACTION; + INSERT INTO t1 VALUES (CONCAT("AbAdCaFe", LPAD(i, 6, "0")), @@SESSION.last_gtid); + COMMIT; + SET i = i + 1; + END LOOP; + END +// +--delimiter ; +--enable_query_log + +connect (con1,localhost,root,,); +--echo *** Start a background load... +send CALL gen_load(); + +--connection default +--echo *** Doing backup... +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir --no-lock +--echo *** Doing prepare... +--exec $XTRABACKUP --prepare --binlog-info=1 --target-dir=$basedir + +--echo *** Stop the background load... +UPDATE t2 SET val=1; +--connection con1 +reap; +--connection default +disconnect con1; +--let $count_master= `SELECT COUNT(*) FROM t1` + +--echo *** Provision a new slave from the backup +--connect (server2,127.0.0.1,root,,,$SERVER_MYPORT_2) +--let $datadir_2= `SELECT @@datadir` + +--echo *** Stopping provisioned server +--source include/shutdown_mysqld.inc + +--echo *** Removing old datadir for provisioned server +--rmdir $datadir_2 + +--echo *** Provision new server from backup +--exec $XTRABACKUP --copy-back --datadir=$datadir_2 --target-dir=$basedir + +# --no-lock backup might leave prepared xa transactions. rollback them. +--error 1 +--exec $MYSQLD_LAST_CMD --tc-heuristic-recover=ROLLBACK +--source include/start_mysqld.inc + +--echo *** Configure slave position from xtrabackup_binlog_pos_innodb +CREATE TABLE t3 (file VARCHAR(255), pos INT) ENGINE=InnoDB; +--replace_result $basedir BASEDIR +--disable_warnings +eval LOAD DATA LOCAL INFILE "$basedir/xtrabackup_binlog_pos_innodb" + INTO TABLE t3 FIELDS ESCAPED BY '' (file, pos); +--enable_warnings + +# Remove leading ./ from filename (leading .\ on windows). +--let provision_master_file= `SELECT REGEXP_REPLACE(file, "^[.].", "") FROM t3` +--let provision_master_pos= `SELECT pos FROM t3` + +--replace_result $SERVER_MYPORT_1 PORT $provision_master_file MASTER_FILE $provision_master_pos MASTER_POS +eval CHANGE MASTER TO + master_port=$SERVER_MYPORT_1, master_host='127.0.0.1', master_user='root', + master_log_file= "$provision_master_file", + master_log_pos= $provision_master_pos; +START SLAVE; + +--connection default +--save_master_pos + +--connection server2 +--sync_with_master +--let $count_slave= `SELECT COUNT(*) FROM t1` +if ($count_master != $count_slave) { + --echo *** ERROR: Table on master has $count_master rows, but table on provisioned slave has $count_slave rows + --die Row difference on provisioned slave. +} + +# Cleanup + +--connection server2 +STOP SLAVE; +RESET SLAVE ALL; +DROP PROCEDURE gen_load; +DROP TABLE t1, t2, t3; + +--connection default +DROP PROCEDURE gen_load; +DROP TABLE t1, t2; + +rmdir $basedir; diff --git a/mysql-test/suite/multi_source/gtid_slave_pos.result b/mysql-test/suite/multi_source/gtid_slave_pos.result index d57cfc17959..44eb482327d 100644 --- a/mysql-test/suite/multi_source/gtid_slave_pos.result +++ b/mysql-test/suite/multi_source/gtid_slave_pos.result @@ -97,8 +97,9 @@ set default_master_connection = 'slave1'; STOP SLAVE; include/wait_for_slave_to_stop.inc set default_master_connection = 'slave2'; +include/wait_for_slave_sql_error.inc [errno=1942] STOP SLAVE; -include/wait_for_slave_to_stop.inc +include/wait_for_slave_io_to_stop.inc set default_master_connection = 'slave1'; START SLAVE; include/wait_for_slave_to_start.inc diff --git a/mysql-test/suite/multi_source/gtid_slave_pos.test b/mysql-test/suite/multi_source/gtid_slave_pos.test index c01130f8cd5..cc418d76870 100644 --- a/mysql-test/suite/multi_source/gtid_slave_pos.test +++ b/mysql-test/suite/multi_source/gtid_slave_pos.test @@ -118,8 +118,10 @@ set default_master_connection = 'slave1'; STOP SLAVE; --source include/wait_for_slave_to_stop.inc set default_master_connection = 'slave2'; +--let $slave_sql_errno= 1942 +--source include/wait_for_slave_sql_error.inc STOP SLAVE; ---source include/wait_for_slave_to_stop.inc +--source include/wait_for_slave_io_to_stop.inc set default_master_connection = 'slave1'; START SLAVE; --source include/wait_for_slave_to_start.inc diff --git a/mysql-test/suite/perfschema/include/pfs_running_event_scheduler.inc b/mysql-test/suite/perfschema/include/pfs_running_event_scheduler.inc index 219a41051fb..313c0ed8ca9 100644 --- a/mysql-test/suite/perfschema/include/pfs_running_event_scheduler.inc +++ b/mysql-test/suite/perfschema/include/pfs_running_event_scheduler.inc @@ -1,10 +1,10 @@ -# threads are removed from: +# threads are added to: # - information_schema.processlist # - performance_schema.threads # at different times, so we may have to wait a little more -# for the event_scheduler to shutdown +# for the event_scheduler to start # let $wait_condition= SELECT COUNT(*) = 1 FROM performance_schema.threads - WHERE name like 'thread/sql/event%'; + WHERE name LIKE 'thread/sql/event%' AND processlist_command IS NOT NULL; --source include/wait_condition.inc diff --git a/mysql-test/suite/plugins/r/test_sql_service.result b/mysql-test/suite/plugins/r/test_sql_service.result index af414d6c6e7..c8467a42f15 100644 --- a/mysql-test/suite/plugins/r/test_sql_service.result +++ b/mysql-test/suite/plugins/r/test_sql_service.result @@ -1,8 +1,100 @@ install plugin test_sql_service soname 'test_sql_service'; -set global test_sql_service_run_test= 1; -show status like 'test_sql_service%'; +show status like 'test_sql_service_passed'; Variable_name Value -Test_sql_service_passed 0 +Test_sql_service_passed 1 +reset master; +set global test_sql_service_execute_sql_global= 'create table test.t1 select 1 as a, @@SQL_LOG_BIN'; +set global test_sql_service_execute_sql_local= 'insert into test.t1 select 2 as a, @@SQL_LOG_BIN'; +set global test_sql_service_execute_sql_global= 'SET SQL_LOG_BIN=1'; +set global test_sql_service_execute_sql_global= 'insert into test.t1 select 3 as a, @@SQL_LOG_BIN'; +set global test_sql_service_execute_sql_global= 'SET SQL_LOG_BIN=0'; +set global test_sql_service_execute_sql_global= 'insert into test.t1 select 4 as a, @@SQL_LOG_BIN'; +set global test_sql_service_execute_sql_global= 'SET sql_auto_is_null=1'; +set global test_sql_service_execute_sql_global= 'insert into test.t1 select 5 as a, @@sql_auto_is_null'; +set global test_sql_service_execute_sql_global= 'SET sql_auto_is_null=0'; +set global test_sql_service_execute_sql_global= 'insert into test.t1 select 6 as a, @@sql_auto_is_null'; +select * from t1 order by a; +a @@SQL_LOG_BIN +1 0 +2 0 +3 1 +4 0 +5 1 +6 0 +drop table t1; +SET SQL_LOG_BIN=0; +set global test_sql_service_run_test= 1; +show status like 'test_sql_service_passed'; +Variable_name Value +Test_sql_service_passed 1 +set global test_sql_service_execute_sql_local= 'create table test.t1(id int)'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query affected 0 rows. +set global test_sql_service_execute_sql_local= 'insert into test.t1 values (1), (2)'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query affected 2 rows. +set global test_sql_service_execute_sql_local= 'select * from test.t1'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query returned 2 rows. +set global test_sql_service_execute_sql_local= 'drop table test.t1'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query affected 0 rows. +set global test_sql_service_execute_sql_local= 'drop table test.t1'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Error 1051 returned. Unknown table 'test.t1' +set global test_sql_service_execute_sql_global= 'create table test.t1(id int)'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query affected 0 rows. +set global test_sql_service_execute_sql_global= 'insert into test.t1 values (1), (2)'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query affected 2 rows. +set global test_sql_service_execute_sql_global= 'select * from test.t1'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query returned 2 rows. +set global test_sql_service_execute_sql_global= 'drop table test.t1'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query affected 0 rows. +set global test_sql_service_execute_sql_global= 'drop table test.t1'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Error 1051 returned. Unknown table 'test.t1' +create table t1 (id int, time timestamp); +insert into t1 values (1, NULL), (2, NULL), (3, NULL), (4, NULL), (5, NULL); +set global test_sql_service_execute_sql_global= 'select * FROM test.t1 WHERE time < DATE_SUB(NOW(), interval 5 minute)'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query returned 0 rows. +set global test_sql_service_execute_sql_global= 'select * FROM test.t1 WHERE time <= NOW()'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query returned 5 rows. +set global test_sql_service_execute_sql_local= 'select * FROM test.t1 WHERE time < DATE_SUB(NOW(), interval 5 minute)'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query returned 0 rows. +set global test_sql_service_execute_sql_local= 'select * FROM test.t1 WHERE time <= NOW()'; +show status like 'test_sql_query_result'; +Variable_name Value +Test_sql_query_result Query returned 5 rows. +drop table t1; uninstall plugin test_sql_service; Warnings: Warning 1620 Plugin is busy and will be uninstalled on shutdown +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # insert into test.t1 select 3 as a, @@SQL_LOG_BIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ diff --git a/mysql-test/suite/plugins/t/test_sql_service.test b/mysql-test/suite/plugins/t/test_sql_service.test index 9b9e29c6913..393fb431e23 100644 --- a/mysql-test/suite/plugins/t/test_sql_service.test +++ b/mysql-test/suite/plugins/t/test_sql_service.test @@ -1,4 +1,5 @@ --source include/not_embedded.inc +--source include/have_log_bin.inc if (!$TEST_SQL_SERVICE_SO) { skip No TEST_SQL_SERVICE plugin; @@ -9,9 +10,73 @@ let count_sessions= 1; source include/wait_until_count_sessions.inc; install plugin test_sql_service soname 'test_sql_service'; +show status like 'test_sql_service_passed'; +reset master; + +set global test_sql_service_execute_sql_global= 'create table test.t1 select 1 as a, @@SQL_LOG_BIN'; +set global test_sql_service_execute_sql_local= 'insert into test.t1 select 2 as a, @@SQL_LOG_BIN'; +set global test_sql_service_execute_sql_global= 'SET SQL_LOG_BIN=1'; +set global test_sql_service_execute_sql_global= 'insert into test.t1 select 3 as a, @@SQL_LOG_BIN'; +set global test_sql_service_execute_sql_global= 'SET SQL_LOG_BIN=0'; +set global test_sql_service_execute_sql_global= 'insert into test.t1 select 4 as a, @@SQL_LOG_BIN'; +set global test_sql_service_execute_sql_global= 'SET sql_auto_is_null=1'; +set global test_sql_service_execute_sql_global= 'insert into test.t1 select 5 as a, @@sql_auto_is_null'; +set global test_sql_service_execute_sql_global= 'SET sql_auto_is_null=0'; +set global test_sql_service_execute_sql_global= 'insert into test.t1 select 6 as a, @@sql_auto_is_null'; +select * from t1 order by a; +drop table t1; +SET SQL_LOG_BIN=0; set global test_sql_service_run_test= 1; -show status like 'test_sql_service%'; +show status like 'test_sql_service_passed'; + +set global test_sql_service_execute_sql_local= 'create table test.t1(id int)'; +show status like 'test_sql_query_result'; + +set global test_sql_service_execute_sql_local= 'insert into test.t1 values (1), (2)'; +show status like 'test_sql_query_result'; + +set global test_sql_service_execute_sql_local= 'select * from test.t1'; +show status like 'test_sql_query_result'; + +set global test_sql_service_execute_sql_local= 'drop table test.t1'; +show status like 'test_sql_query_result'; + +set global test_sql_service_execute_sql_local= 'drop table test.t1'; +show status like 'test_sql_query_result'; + +set global test_sql_service_execute_sql_global= 'create table test.t1(id int)'; +show status like 'test_sql_query_result'; + +set global test_sql_service_execute_sql_global= 'insert into test.t1 values (1), (2)'; +show status like 'test_sql_query_result'; + +set global test_sql_service_execute_sql_global= 'select * from test.t1'; +show status like 'test_sql_query_result'; + +set global test_sql_service_execute_sql_global= 'drop table test.t1'; +show status like 'test_sql_query_result'; + +set global test_sql_service_execute_sql_global= 'drop table test.t1'; +show status like 'test_sql_query_result'; + +create table t1 (id int, time timestamp); +insert into t1 values (1, NULL), (2, NULL), (3, NULL), (4, NULL), (5, NULL); +set global test_sql_service_execute_sql_global= 'select * FROM test.t1 WHERE time < DATE_SUB(NOW(), interval 5 minute)'; +show status like 'test_sql_query_result'; +set global test_sql_service_execute_sql_global= 'select * FROM test.t1 WHERE time <= NOW()'; +show status like 'test_sql_query_result'; +set global test_sql_service_execute_sql_local= 'select * FROM test.t1 WHERE time < DATE_SUB(NOW(), interval 5 minute)'; +show status like 'test_sql_query_result'; +set global test_sql_service_execute_sql_local= 'select * FROM test.t1 WHERE time <= NOW()'; +show status like 'test_sql_query_result'; +drop table t1; uninstall plugin test_sql_service; +# Check that statements were executed/binlogged in correct order. +--source include/show_binlog_events.inc +# --replace_column 2 # 5 # +# --replace_regex /xid=[0-9]+/xid=XX/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ +# SHOW BINLOG EVENTS LIMIT 3,5; + diff --git a/mysql-test/suite/rpl/include/mdev-31448_conservative.inc b/mysql-test/suite/rpl/include/mdev-31448_conservative.inc index 3db5a000af0..e479901f9ed 100644 --- a/mysql-test/suite/rpl/include/mdev-31448_conservative.inc +++ b/mysql-test/suite/rpl/include/mdev-31448_conservative.inc @@ -36,7 +36,8 @@ insert into t1 values (3); --connection slave --source include/start_slave.inc ---let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Update_rows_log_event::find_row(-1)%' and command LIKE 'Slave_worker'; +# Wildcard for `state` as it depends on whether WSREP is compiled in or not. +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Update_rows_log_event::find_row(%' and command LIKE 'Slave_worker'; --source include/wait_condition.inc --let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to commit%' and command LIKE 'Slave_worker'; --source include/wait_condition.inc @@ -50,8 +51,8 @@ insert into t1 values (3); commit; --connection slave ---let $slave_timeout=1032 ---source include/wait_for_slave_sql_to_stop.inc +--let $slave_sql_errno=1032 +--source include/wait_for_slave_sql_error.inc update t1 set a=1 where a=2; set @@global.slave_parallel_threads = @save.slave_parallel_threads; diff --git a/mysql-test/suite/rpl/include/mdev-31448_optimistic.inc b/mysql-test/suite/rpl/include/mdev-31448_optimistic.inc index 22cee6b3195..c561e29800e 100644 --- a/mysql-test/suite/rpl/include/mdev-31448_optimistic.inc +++ b/mysql-test/suite/rpl/include/mdev-31448_optimistic.inc @@ -55,7 +55,8 @@ drop table t2; --source include/start_slave.inc --echo # wait for T1 ---let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Update_rows_log_event::find_row(-1)%' and command LIKE 'Slave_worker'; +# Wildcard for `state` as it depends on whether WSREP is compiled in or not. +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Update_rows_log_event::find_row(%' and command LIKE 'Slave_worker'; --source include/wait_condition.inc --echo # wait for T2 @@ -75,8 +76,8 @@ drop table t2; commit; --connection slave ---let $slave_timeout=1032 ---source include/wait_for_slave_sql_to_stop.inc +--let $slave_sql_errno=1032 +--source include/wait_for_slave_sql_error.inc update t1 set a=1 where a=2; set @@global.slave_parallel_threads = @save.slave_parallel_threads; diff --git a/mysql-test/suite/rpl/include/rpl_binlog_max_cache_size.test b/mysql-test/suite/rpl/include/rpl_binlog_max_cache_size.test index d750554b4ec..59bc4d056ab 100644 --- a/mysql-test/suite/rpl/include/rpl_binlog_max_cache_size.test +++ b/mysql-test/suite/rpl/include/rpl_binlog_max_cache_size.test @@ -411,6 +411,8 @@ while ($n) COMMIT; --connection slave +# Multi-statement transaction raised ER_TRANS_CACHE_FULL (4096=128x32) +# that will stop SQL slave thread --let $slave_sql_errno= 1197 if (`SELECT @@binlog_format = 'ROW'`) { @@ -430,7 +432,8 @@ source include/show_binlog_events.inc; --replace_result $old_binlog_stmt_cache_size ORIGINAL_VALUE --eval SET GLOBAL binlog_stmt_cache_size= $old_binlog_stmt_cache_size -source include/stop_slave.inc; +# SQL slave is stopped, stop only IO thread +source include/stop_slave_io.inc; source include/start_slave.inc; connection master; diff --git a/mysql-test/suite/rpl/include/rpl_parallel_29322.inc b/mysql-test/suite/rpl/include/rpl_parallel_29322.inc index 54eb13d7f09..b32d463294a 100644 --- a/mysql-test/suite/rpl/include/rpl_parallel_29322.inc +++ b/mysql-test/suite/rpl/include/rpl_parallel_29322.inc @@ -66,6 +66,17 @@ if ($same_version_binlogs) if (!$same_version_binlogs) { + # Make sure the dump thread is gone before moving around binlog files. Else + # it might see an empty file and give error (MDEV-29816). + --let $dump_thrid= `Select id FROM information_schema.processlist WHERE Command='Binlog Dump'` + if ($dump_thrid) { + --disable_query_log + --error 0,ER_NO_SUCH_THREAD + eval KILL CONNECTION $dump_thrid; + --enable_query_log + --let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.processlist WHERE Command='Binlog Dump' + --source include/wait_condition.inc + } --move_file $datadir/master-bin.000002 $datadir/master-bin.000002.sav --copy_file $MYSQL_TEST_DIR/std_data/mdev29078-mysql-bin.000001 $datadir/master-bin.000002 --exec $MYSQL_BINLOG --short-form $datadir/master-bin.000002 diff --git a/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc b/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc index 4726bbe1889..f9c007b44ab 100644 --- a/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc +++ b/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc @@ -75,17 +75,22 @@ EOF --connection server_1 DROP TABLE t1; +# Slaves IO thread will receive the disconnect error when master was shutdown +# so we are allowing error on start. --connection server_2 --disable_warnings +--let rpl_allow_error=1 --source include/start_slave.inc --enable_warnings --connection server_3 --disable_warnings +--let rpl_allow_error=1 --source include/start_slave.inc --enable_warnings --connection server_4 --disable_warnings +--let rpl_allow_error=1 --source include/start_slave.inc --enable_warnings diff --git a/mysql-test/suite/rpl/include/rpl_start_stop_slave.test b/mysql-test/suite/rpl/include/rpl_start_stop_slave.test index 32f33b2a31d..72f481e00fb 100644 --- a/mysql-test/suite/rpl/include/rpl_start_stop_slave.test +++ b/mysql-test/suite/rpl/include/rpl_start_stop_slave.test @@ -207,7 +207,7 @@ START SLAVE; --let $status_items= Last_IO_Errno, Last_IO_Error --source include/show_slave_status.inc ---source include/stop_slave.inc +--source include/stop_slave_sql.inc RESET SLAVE; --connection master diff --git a/mysql-test/suite/rpl/include/rpl_stop_middle_group.test b/mysql-test/suite/rpl/include/rpl_stop_middle_group.test index ac01fb04d16..6bc872cabe5 100644 --- a/mysql-test/suite/rpl/include/rpl_stop_middle_group.test +++ b/mysql-test/suite/rpl/include/rpl_stop_middle_group.test @@ -82,7 +82,9 @@ connection slave; # slave will catch the killed status, won't shut down immediately # but does it eventually having the whole group unfinished (not committed) -source include/wait_for_slave_sql_to_stop.inc; +# ER_SLAVE_FATAL_ERROR +--let slave_sql_errno= 1593 +source include/wait_for_slave_sql_error.inc; # checking: the error and group unfinished @@ -120,7 +122,8 @@ connection slave; # but does it eventually having the whole group unfinished (not committed) # -source include/wait_for_slave_sql_to_stop.inc; +--let slave_sql_errno= 1593 +source include/wait_for_slave_sql_error.inc; # checking: the error and group unfinished diff --git a/mysql-test/suite/rpl/r/mdev-31448_kill_ooo_finish_optimistic.result b/mysql-test/suite/rpl/r/mdev-31448_kill_ooo_finish_optimistic.result index 23a16e01b96..7fa1a831025 100644 --- a/mysql-test/suite/rpl/r/mdev-31448_kill_ooo_finish_optimistic.result +++ b/mysql-test/suite/rpl/r/mdev-31448_kill_ooo_finish_optimistic.result @@ -42,7 +42,8 @@ include/save_master_gtid.inc connection slave; # # Cleanup -include/stop_slave.inc +include/wait_for_slave_sql_to_stop.inc +include/stop_slave_io.inc set @@global.slave_parallel_threads= 0; set @@global.slave_parallel_mode= optimistic; set @@global.innodb_lock_wait_timeout= 50; diff --git a/mysql-test/suite/rpl/r/parallel_backup.result b/mysql-test/suite/rpl/r/parallel_backup.result index 7cf72ed15e4..83c7a916c13 100644 --- a/mysql-test/suite/rpl/r/parallel_backup.result +++ b/mysql-test/suite/rpl/r/parallel_backup.result @@ -73,8 +73,6 @@ include/stop_slave.inc # Normal XA ROLLBACK connection slave; include/stop_slave.inc -Warnings: -Note 1255 Slave already has been stopped connection master; connection aux_slave; BEGIN; @@ -110,8 +108,6 @@ include/stop_slave.inc # Errored out XA COMMIT connection slave; include/stop_slave.inc -Warnings: -Note 1255 Slave already has been stopped connection master; connection aux_slave; BEGIN; diff --git a/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result b/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result index b89cb154f24..e1fd7701fcc 100644 --- a/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result +++ b/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result @@ -76,8 +76,6 @@ include/stop_slave.inc # Normal XA ROLLBACK connection slave; include/stop_slave.inc -Warnings: -Note 1255 Slave already has been stopped connection master; connection aux_slave; BEGIN; @@ -113,8 +111,6 @@ include/stop_slave.inc # Errored out XA COMMIT connection slave; include/stop_slave.inc -Warnings: -Note 1255 Slave already has been stopped connection master; connection aux_slave; BEGIN; diff --git a/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result b/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result index 111bc7fb76f..9e29e5a3875 100644 --- a/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result +++ b/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result @@ -76,8 +76,6 @@ include/stop_slave.inc # Normal XA ROLLBACK connection slave; include/stop_slave.inc -Warnings: -Note 1255 Slave already has been stopped connection master; connection aux_slave; BEGIN; @@ -113,8 +111,6 @@ include/stop_slave.inc # Errored out XA COMMIT connection slave; include/stop_slave.inc -Warnings: -Note 1255 Slave already has been stopped connection master; connection aux_slave; BEGIN; diff --git a/mysql-test/suite/rpl/r/rpl_binlog_cache_disk_full_loaddata.result b/mysql-test/suite/rpl/r/rpl_binlog_cache_disk_full_loaddata.result new file mode 100644 index 00000000000..a876a597aea --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_binlog_cache_disk_full_loaddata.result @@ -0,0 +1,38 @@ +include/master-slave.inc +[connection master] +connection master; +SET @save_binlog_stmt_cache_size= @@GLOBAL.binlog_stmt_cache_size; +SET GLOBAL binlog_stmt_cache_size= 4096; +CALL mtr.add_suppression('"No space left on device".*An incident event is written to binary log'); +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=MyISAM; +FLUSH STATUS; +SHOW STATUS LIKE "binlog_stmt_cache%"; +Variable_name Value +Binlog_stmt_cache_disk_use 0 +Binlog_stmt_cache_use 0 +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,load_data_binlog_cache_error"; +LOAD DATA CONCURRENT LOCAL INFILE 'std_data/bug30435_5k.txt' + REPLACE INTO TABLE t1 (a); +ERROR HY000: Error writing file '' (Errcode: 28 "No space left on device") +SET SESSION debug_dbug= @old_dbug; +SHOW STATUS LIKE "binlog_stmt_cache%"; +Variable_name Value +Binlog_stmt_cache_disk_use 1 +Binlog_stmt_cache_use 1 +SELECT IF(COUNT(*) > 0 AND COUNT(*) < 5000, +"ok", +CONCAT("ERROR! Row count ", COUNT(*), " not as expected for partially executed query")) +AS check_result +FROM t1; +check_result +ok +connection slave; +include/wait_for_slave_sql_error_and_skip.inc [errno=1590] +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +connection master; +SET GLOBAL binlog_stmt_cache_size= @save_binlog_stmt_cache_size; +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_binlog_cache_disk_full_row.result b/mysql-test/suite/rpl/r/rpl_binlog_cache_disk_full_row.result new file mode 100644 index 00000000000..753fdaa4e6b --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_binlog_cache_disk_full_row.result @@ -0,0 +1,51 @@ +include/master-slave.inc +[connection master] +connection master; +SET @save_binlog_stmt_cache_size= @@GLOBAL.binlog_stmt_cache_size; +SET GLOBAL binlog_stmt_cache_size= 4096; +CALL mtr.add_suppression('"No space left on device".*An incident event is written to binary log'); +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(255)) ENGINE=MyISAM; +FLUSH STATUS; +SHOW STATUS LIKE "binlog_stmt_cache%"; +Variable_name Value +Binlog_stmt_cache_disk_use 0 +Binlog_stmt_cache_use 0 +INSERT INTO t1 VALUES (0, CONCAT("?", "-", REPEAT("x", 200))); +INSERT INTO t1 SELECT a+1, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+2, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+4, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+8, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+16, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+32, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+64, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+128, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +SHOW STATUS LIKE "binlog_stmt_cache%"; +Variable_name Value +Binlog_stmt_cache_disk_use 2 +Binlog_stmt_cache_use 9 +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,simulate_disk_full_at_flush_pending"; +INSERT INTO t1 SELECT a+256, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +ERROR HY000: Error writing file '' (Errcode: 28 "No space left on device") +SET SESSION debug_dbug= @old_dbug; +SHOW STATUS LIKE "binlog_stmt_cache%"; +Variable_name Value +Binlog_stmt_cache_disk_use 3 +Binlog_stmt_cache_use 10 +SELECT IF(COUNT(*) > 256 AND COUNT(*) < 512, +"ok", +CONCAT("ERROR! Row count ", COUNT(*), " not as expected for partially executed query")) +AS check_result +FROM t1; +check_result +ok +ALTER TABLE t1 COMMENT ''; +connection slave; +include/wait_for_slave_sql_error_and_skip.inc [errno=1590] +SELECT COUNT(*) FROM t1; +COUNT(*) +256 +connection master; +SET GLOBAL binlog_stmt_cache_size= @save_binlog_stmt_cache_size; +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_connection.result b/mysql-test/suite/rpl/r/rpl_connection.result index b5ce7f4ed71..9fb17b5f174 100644 --- a/mysql-test/suite/rpl/r/rpl_connection.result +++ b/mysql-test/suite/rpl/r/rpl_connection.result @@ -6,7 +6,7 @@ include/stop_slave.inc CHANGE MASTER TO MASTER_USER= '', MASTER_PASSWORD= ''; START SLAVE; include/wait_for_slave_io_error.inc [errno=1045, 1593] -include/stop_slave.inc +include/stop_slave_sql.inc CHANGE MASTER TO MASTER_USER= 'root', MASTER_PASSWORD= ''; START SLAVE; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_domain_id_filter_io_crash.result b/mysql-test/suite/rpl/r/rpl_domain_id_filter_io_crash.result index feef82a57fc..5250c4bb36a 100644 --- a/mysql-test/suite/rpl/r/rpl_domain_id_filter_io_crash.result +++ b/mysql-test/suite/rpl/r/rpl_domain_id_filter_io_crash.result @@ -135,7 +135,7 @@ i 2 3 SET @@global.debug_dbug=@saved_dbug; -include/stop_slave.inc +include/stop_slave_sql.inc DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; @@ -204,7 +204,7 @@ i 10 11 SET @@global.debug_dbug=@saved_dbug; -include/stop_slave.inc +include/stop_slave_sql.inc DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : 1 CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; @@ -287,7 +287,7 @@ i 16 17 SET @@global.debug_dbug=@saved_dbug; -include/stop_slave.inc +include/stop_slave_sql.inc DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : 1 CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; @@ -384,7 +384,7 @@ i 22 23 SET @@global.debug_dbug=@saved_dbug; -include/stop_slave.inc +include/stop_slave_sql.inc DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; diff --git a/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result b/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result index 0a414cb3b1f..4169a2ddc26 100644 --- a/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result +++ b/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result @@ -38,8 +38,8 @@ connection master; include/rpl_start_server.inc [server_number=1] # Master has restarted successfully connection slave; -include/stop_slave.inc -include/start_slave.inc +include/wait_for_slave_io_to_start.inc +include/wait_for_slave_sql_to_start.inc select * from ti; a 1 diff --git a/mysql-test/suite/rpl/r/rpl_fail_register.result b/mysql-test/suite/rpl/r/rpl_fail_register.result index 2cddc796314..0398220c4d0 100644 --- a/mysql-test/suite/rpl/r/rpl_fail_register.result +++ b/mysql-test/suite/rpl/r/rpl_fail_register.result @@ -1,14 +1,15 @@ include/master-slave.inc [connection master] connection slave; +CALL mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: Debug Induced Error"); set @old_dbug=@@global.debug_dbug; set global debug_dbug='d,fail_com_register_slave'; stop slave; reset slave; include/wait_for_slave_to_stop.inc start slave; -stop slave; -include/wait_for_slave_to_stop.inc +include/wait_for_slave_io_error.inc [errno=1597] +include/stop_slave_sql.inc set global debug_dbug=@old_dbug; connection master; kill DUMP_THREAD; diff --git a/mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result b/mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result index 9c36973427a..9e788e8f965 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result @@ -52,7 +52,7 @@ Waiting until 'Slave_IO_Running' = 'Yes' [$slave_error_param='Last_IO_Errno'] .. con='slave' warn='1' qlog='1' rlog='1' aborterr='1' ...==== BEGIN include/wait_for_slave_param.inc [Slave_SQL_Running] ==== ... con='slave' warn='1' qlog='1' rlog='1' aborterr='1' -Waiting until 'Slave_SQL_Running' = 'Yes' [$slave_error_param='1'] +Waiting until 'Slave_SQL_Running' = 'Yes' [$slave_error_param=''] [connection slave] ...==== END include/wait_for_slave_param.inc [Slave_SQL_Running] ==== ... con='slave' warn='1' qlog='1' rlog='1' aborterr='1' diff --git a/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result b/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result index 593f83a7946..229ac02b1d1 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result @@ -23,7 +23,8 @@ INSERT INTO t1 VALUES (2); SET sql_log_bin=1; START SLAVE; include/wait_for_slave_sql_error.inc [errno=1062] -include/stop_slave.inc +include/wait_for_slave_io_to_start.inc +include/stop_slave_io.inc SET GLOBAL gtid_slave_pos= "0-1-100"; include/start_slave.inc SELECT * FROM t1 ORDER BY a; @@ -39,7 +40,7 @@ REPLACE INTO t1 VALUES (5); SET debug_dbug= @dbug_save; connection slave; include/wait_for_slave_sql_error.inc [errno=1590] -include/stop_slave.inc +include/stop_slave_io.inc SET sql_slave_skip_counter=1; include/start_slave.inc SELECT * FROM t1 ORDER BY a; diff --git a/mysql-test/suite/rpl/r/rpl_gtid_startpos.result b/mysql-test/suite/rpl/r/rpl_gtid_startpos.result index 3c363004170..2ee51245c90 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_startpos.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_startpos.result @@ -36,7 +36,7 @@ CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, MASTER_USE_GTID=CURRENT_POS; START SLAVE; include/wait_for_slave_io_error.inc [errno=1236] -include/stop_slave.inc +include/stop_slave_sql.inc CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, MASTER_LOG_FILE="master-bin.000003", MASTER_LOG_POS=4; include/start_slave.inc diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result index 1db69ea4b83..683b5fb569a 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result @@ -226,7 +226,7 @@ connection slave; call mtr.add_suppression("Slave SQL.*Duplicate entry .1. for key .PRIMARY.. on query.* error.* 1062"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); Heartbeat events are received while sql thread stopped (1 means 'yes'): 1 -include/stop_slave.inc +include/stop_slave_io.inc DROP TABLE t1; *** Master send to slave *** diff --git a/mysql-test/suite/rpl/r/rpl_invoked_features.result b/mysql-test/suite/rpl/r/rpl_invoked_features.result index 43a8e8625de..3cfd40d5a0e 100644 --- a/mysql-test/suite/rpl/r/rpl_invoked_features.result +++ b/mysql-test/suite/rpl/r/rpl_invoked_features.result @@ -45,14 +45,14 @@ BEGIN UPDATE t12 SET c = ''; UPDATE t13 SET c = ''; END| -CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DISABLE DO +CREATE EVENT e1 ON SCHEDULE EVERY 10 SECOND DISABLE DO BEGIN ALTER EVENT e1 DISABLE; CALL p1(10, ''); END| Warnings: Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. -CREATE EVENT e11 ON SCHEDULE EVERY 1 SECOND DISABLE DO +CREATE EVENT e11 ON SCHEDULE EVERY 10 SECOND DISABLE DO BEGIN ALTER EVENT e11 DISABLE; CALL p11(10, ''); diff --git a/mysql-test/suite/rpl/r/rpl_mdev_17614.result b/mysql-test/suite/rpl/r/rpl_mdev_17614.result index ba077111522..125f90c0485 100644 --- a/mysql-test/suite/rpl/r/rpl_mdev_17614.result +++ b/mysql-test/suite/rpl/r/rpl_mdev_17614.result @@ -29,8 +29,7 @@ SELECT * FROM t1; a b c 1 1 1 2 2 3 -stop slave; -include/wait_for_slave_to_stop.inc +include/stop_slave_io.inc reset slave; connection master; reset master; @@ -189,8 +188,7 @@ SELECT * FROM t1; a b c 1 1 1 2 2 3 -stop slave; -include/wait_for_slave_to_stop.inc +include/stop_slave_io.inc reset slave; connection master; reset master; diff --git a/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result index 944ad9331ad..7ce98cbcc10 100644 --- a/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result @@ -192,7 +192,7 @@ SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; -include/stop_slave.inc +include/stop_slave_io.inc include/start_slave.inc connection master; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_parallel_ignored_errors.result b/mysql-test/suite/rpl/r/rpl_parallel_ignored_errors.result index ce11b814d44..57654d1596b 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_ignored_errors.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_ignored_errors.result @@ -36,7 +36,8 @@ connection server_2; connection con_temp2; COMMIT; connection server_2; -include/stop_slave.inc +include/wait_for_slave_sql_error.inc [errno=1062] +include/stop_slave_io.inc include/assert.inc [table t1 should have zero rows where a>32] SELECT * FROM t1 WHERE a>32; a diff --git a/mysql-test/suite/rpl/r/rpl_parallel_kill.result b/mysql-test/suite/rpl/r/rpl_parallel_kill.result index 7e6b065725b..8772ac9955d 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_kill.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_kill.result @@ -30,7 +30,7 @@ kill $t3_tid; connection slave1; commit; connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1032] update t1 set a=1 where a=2; set @@global.slave_parallel_threads = @save.slave_parallel_threads; set @@global.slave_parallel_mode = @save.slave_parallel_mode; @@ -78,7 +78,7 @@ include/wait_for_slave_param.inc [Last_Errno] connection slave1; commit; connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1032] update t1 set a=1 where a=2; set @@global.slave_parallel_threads = @save.slave_parallel_threads; set @@global.slave_parallel_mode = @save.slave_parallel_mode; @@ -127,7 +127,7 @@ include/wait_for_slave_param.inc [Last_Errno] connection slave1; commit; connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1032] update t1 set a=1 where a=2; set @@global.slave_parallel_threads = @save.slave_parallel_threads; set @@global.slave_parallel_mode = @save.slave_parallel_mode; diff --git a/mysql-test/suite/rpl/r/rpl_parallel_missed_error_handling.result b/mysql-test/suite/rpl/r/rpl_parallel_missed_error_handling.result index e9d04c02d7a..c9094c8b8cc 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_missed_error_handling.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_missed_error_handling.result @@ -38,7 +38,6 @@ connection con2; SET debug_sync='RESET'; connection server_2; include/wait_for_slave_sql_error.inc [errno=1062] -include/wait_for_slave_sql_to_stop.inc SELECT * FROM t3 WHERE a >= 110 ORDER BY a; a b 110 1 diff --git a/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result index a8e569aad61..e10008352a9 100644 --- a/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result @@ -191,7 +191,7 @@ SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; -include/stop_slave.inc +include/stop_slave_io.inc include/start_slave.inc connection master; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_row_corruption.result b/mysql-test/suite/rpl/r/rpl_row_corruption.result index 24535460418..1950617af83 100644 --- a/mysql-test/suite/rpl/r/rpl_row_corruption.result +++ b/mysql-test/suite/rpl/r/rpl_row_corruption.result @@ -14,7 +14,7 @@ connection master; UPDATE t1_11753004, t2_11753004 SET t1_11753004.c1=3, t2_11753004.c1=4 WHERE t1_11753004.c1=1 OR t2_11753004.c1=2; connection slave; include/wait_for_slave_sql_error.inc [errno=1593 ] -include/stop_slave.inc +include/stop_slave_io.inc SET @@global.debug_dbug=@saved_debug; include/start_slave.inc connection master; diff --git a/mysql-test/suite/rpl/r/rpl_row_idempotency.result b/mysql-test/suite/rpl/r/rpl_row_idempotency.result index c655ae67185..061cc8363bf 100644 --- a/mysql-test/suite/rpl/r/rpl_row_idempotency.result +++ b/mysql-test/suite/rpl/r/rpl_row_idempotency.result @@ -89,7 +89,7 @@ b 3 *** slave must stop (Trying to delete a referenced foreing key) connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1451] Last_SQL_Error 1451 select * from ti1 order by b /* must be (1),(2),(3) - not deleted */; @@ -114,7 +114,7 @@ connection master; insert into ti2 set a=3, b=3 /* offending write event */; *** slave must stop (Trying to insert an invalid foreign key) connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1452] Last_SQL_Error 1452 select * from ti2 order by b /* must be (2,2) */; @@ -139,9 +139,9 @@ a b insert into ti1 set b=1; connection master; insert into ti1 set b=1 /* offending write event */; -*** slave must stop (Trying to insert a dupliacte key) +*** slave must stop (Trying to insert a duplicate key) connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1062] Last_SQL_Error 1062 set foreign_key_checks= 0; @@ -164,7 +164,7 @@ connection master; DELETE FROM t1 WHERE a = -2; *** slave must stop (Key was not found) connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1032] Last_SQL_Error 1032 set global slave_exec_mode='IDEMPOTENT'; @@ -176,7 +176,7 @@ connection master; DELETE FROM t2 WHERE a = -2; *** slave must stop (Key was not found) connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1032] Last_SQL_Error 1032 set global slave_exec_mode='IDEMPOTENT'; @@ -190,7 +190,7 @@ connection master; UPDATE t1 SET a = 1 WHERE a = -1; *** slave must stop (Key was not found) connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1032] Last_SQL_Error 1032 set global slave_exec_mode='IDEMPOTENT'; @@ -202,7 +202,7 @@ connection master; UPDATE t2 SET a = 1 WHERE a = -1; *** slave must stop (Key was not found) connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1032] Last_SQL_Error 1032 set global slave_exec_mode='IDEMPOTENT'; diff --git a/mysql-test/suite/rpl/r/rpl_row_until.result b/mysql-test/suite/rpl/r/rpl_row_until.result index 82268ce72eb..d5085a4feaf 100644 --- a/mysql-test/suite/rpl/r/rpl_row_until.result +++ b/mysql-test/suite/rpl/r/rpl_row_until.result @@ -51,7 +51,9 @@ ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UN START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', MASTER_LOG_POS=MASTER_LOG_POS; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=MASTER_LOG_POS; -include/stop_slave.inc +include/wait_for_slave_io_to_start.inc +include/wait_for_slave_sql_to_stop.inc +include/stop_slave_io.inc RESET SLAVE; include/start_slave.inc include/rpl_reset.inc diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_master_shutdown.result b/mysql-test/suite/rpl/r/rpl_semi_sync_master_shutdown.result index 786e1682bb0..6124ba01679 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_master_shutdown.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_master_shutdown.result @@ -14,14 +14,12 @@ connection master; # Shutdown master include/rpl_stop_server.inc [server_number=1] connection slave; -include/stop_slave.inc +include/wait_for_slave_io_error.inc [errno=2003] # Restart master include/rpl_start_server.inc [server_number=1] connection slave; -include/stop_slave.inc -Warnings: -Note 1255 Slave already has been stopped -include/start_slave.inc +include/wait_for_slave_sql_to_start.inc +include/wait_for_slave_io_to_start.inc connection master; SET @@GLOBAL.debug_dbug=""; SET @@GLOBAL. rpl_semi_sync_master_enabled = 0; diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result index f026a1c9db4..e482da7d0fc 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result @@ -32,7 +32,7 @@ connection slave; include/diff_tables.inc [master:t1, slave:t1] connection master; set statement sql_log_bin=0 for call mtr.add_suppression("Read semi-sync reply magic number error"); -SET @save_debug_master= @@global.debug; +SET @save_debug_master= @@global.debug_dbug; SET GLOBAL debug_dbug="+d,semisync_corrupt_magic"; insert into t1 values (11); connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_set_statement_default_master.result b/mysql-test/suite/rpl/r/rpl_set_statement_default_master.result index 828e171548d..46f5a7c927e 100644 --- a/mysql-test/suite/rpl/r/rpl_set_statement_default_master.result +++ b/mysql-test/suite/rpl/r/rpl_set_statement_default_master.result @@ -14,6 +14,7 @@ RESET SLAVE ALL; CHANGE MASTER 'm1' TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_MYPORT, MASTER_USER='root'; SET STATEMENT default_master_connection = 'm1' FOR START SLAVE; set default_master_connection = 'm1'; +include/wait_for_slave_to_start.inc stop slave; include/wait_for_slave_to_stop.inc reset slave all; diff --git a/mysql-test/suite/rpl/r/rpl_slave_load_tmpdir_not_exist.result b/mysql-test/suite/rpl/r/rpl_slave_load_tmpdir_not_exist.result index 249f3514c8a..e9a96fc41e1 100644 --- a/mysql-test/suite/rpl/r/rpl_slave_load_tmpdir_not_exist.result +++ b/mysql-test/suite/rpl/r/rpl_slave_load_tmpdir_not_exist.result @@ -4,6 +4,7 @@ connection slave; START SLAVE; call mtr.add_suppression("Slave SQL.*Unable to use slave.s temporary directory"); include/wait_for_slave_sql_error.inc [errno=12] +include/wait_for_slave_io_to_start.inc include/stop_slave_io.inc RESET SLAVE; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_slave_status.result b/mysql-test/suite/rpl/r/rpl_slave_status.result index 1c81cec2577..ef122b9ca92 100644 --- a/mysql-test/suite/rpl/r/rpl_slave_status.result +++ b/mysql-test/suite/rpl/r/rpl_slave_status.result @@ -36,7 +36,6 @@ connection slave; include/stop_slave.inc START SLAVE; include/wait_for_slave_sql_to_start.inc -include/wait_for_slave_io_to_stop.inc ==== Verify that Slave IO thread stopped with error ==== include/wait_for_slave_io_error.inc [errno=1045] ==== Cleanup (Note that slave IO thread is not running) ==== diff --git a/mysql-test/suite/rpl/r/rpl_sql_thd_start_errno_cleared.result b/mysql-test/suite/rpl/r/rpl_sql_thd_start_errno_cleared.result index b14f7b01541..a3e98afa775 100644 --- a/mysql-test/suite/rpl/r/rpl_sql_thd_start_errno_cleared.result +++ b/mysql-test/suite/rpl/r/rpl_sql_thd_start_errno_cleared.result @@ -34,6 +34,7 @@ set debug_sync= "now wait_for sql_thread_run_lock_released"; # Validating that Last_SQL_Errno is cleared.. # ..success set debug_sync= "now signal sql_thread_continue"; +# Wait for debug_sync signal to have been received before issuing RESET set @@global.debug_dbug= @saved_dbug; set debug_sync= "RESET"; # Cleanup diff --git a/mysql-test/suite/rpl/r/rpl_ssl1.result b/mysql-test/suite/rpl/r/rpl_ssl1.result index 1d55fe1259e..0cb21716e75 100644 --- a/mysql-test/suite/rpl/r/rpl_ssl1.result +++ b/mysql-test/suite/rpl/r/rpl_ssl1.result @@ -14,8 +14,8 @@ insert into t1 values (1); connection slave; select * from t1; t -stop slave; -include/wait_for_slave_to_stop.inc +include/wait_for_slave_io_error.inc [errno=1045] +include/stop_slave_sql.inc change master to master_ssl=1 , master_ssl_ca ='MYSQL_TEST_DIR/std_data/cacert.pem', master_ssl_cert='MYSQL_TEST_DIR/std_data/client-cert.pem', master_ssl_key='MYSQL_TEST_DIR/std_data/client-key.pem'; start slave; include/wait_for_slave_to_start.inc diff --git a/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result index 944ad9331ad..7ce98cbcc10 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result @@ -192,7 +192,7 @@ SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; -include/stop_slave.inc +include/stop_slave_io.inc include/start_slave.inc connection master; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result index 992e6c2181b..391ef95104f 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result +++ b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result @@ -109,7 +109,7 @@ START SLAVE; include/wait_for_slave_param.inc [Last_IO_Errno] Last_IO_Errno = '1236' Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position; the first event 'master-bin.000001' at XXX, the last event read from 'master-bin.000001' at XXX, the last byte read from 'master-bin.000001' at XXX.'' -include/stop_slave.inc +include/stop_slave_sql.inc RESET SLAVE; connection master; RESET MASTER; diff --git a/mysql-test/suite/rpl/r/rpl_stm_stop_middle_group.result b/mysql-test/suite/rpl/r/rpl_stm_stop_middle_group.result index 0afe1992fb9..86c90ff33dd 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_stop_middle_group.result +++ b/mysql-test/suite/rpl/r/rpl_stm_stop_middle_group.result @@ -43,7 +43,7 @@ Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction commit; connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1593] SELECT "Fatal error: ... Slave SQL Thread stopped with incomplete event group having non-transactional changes. If the group consists solely of row-based events, you can try to restart the slave with --slave-exec-mode=IDEMPOTENT, which ignores duplicate key, key not found, and similar errors (see documentation for details)." AS Last_SQL_Error, @check as `true`; Last_SQL_Error true Fatal error: ... Slave SQL Thread stopped with incomplete event group having non-transactional changes. If the group consists solely of row-based events, you can try to restart the slave with --slave-exec-mode=IDEMPOTENT, which ignores duplicate key, key not found, and similar errors (see documentation for details). 1 @@ -63,7 +63,7 @@ set @@global.debug_dbug="d,stop_slave_middle_group,incomplete_group_in_relay_log connection master; update tm as t1, ti as t2 set t1.a=t1.a * 2, t2.a=t2.a * 2; connection slave; -include/wait_for_slave_sql_to_stop.inc +include/wait_for_slave_sql_error.inc [errno=1593] SELECT "Fatal error: ... Slave SQL Thread stopped with incomplete event group having non-transactional changes. If the group consists solely of row-based events, you can try to restart the slave with --slave-exec-mode=IDEMPOTENT, which ignores duplicate key, key not found, and similar errors (see documentation for details)." AS Last_SQL_Error, @check as `true`; Last_SQL_Error true Fatal error: ... Slave SQL Thread stopped with incomplete event group having non-transactional changes. If the group consists solely of row-based events, you can try to restart the slave with --slave-exec-mode=IDEMPOTENT, which ignores duplicate key, key not found, and similar errors (see documentation for details). 1 diff --git a/mysql-test/suite/rpl/r/semisync_future-7591.result b/mysql-test/suite/rpl/r/semisync_future-7591.result index 9dc0ee51e53..fe355f34cfa 100644 --- a/mysql-test/suite/rpl/r/semisync_future-7591.result +++ b/mysql-test/suite/rpl/r/semisync_future-7591.result @@ -13,7 +13,7 @@ connection master; insert into t1 values (1); reset master; connection slave; -include/stop_slave.inc +include/stop_slave_sql.inc reset slave; include/start_slave.inc set global rpl_semi_sync_slave_enabled = OFF; diff --git a/mysql-test/suite/rpl/t/create_or_replace.inc b/mysql-test/suite/rpl/t/create_or_replace.inc index df46cc36e97..e8fa95cb94a 100644 --- a/mysql-test/suite/rpl/t/create_or_replace.inc +++ b/mysql-test/suite/rpl/t/create_or_replace.inc @@ -213,12 +213,19 @@ set @@session.binlog_format=default; drop temporary table if exists t9; --connect(con1,localhost,root,,) +--let $conid = `SELECT CONNECTION_ID()` set session binlog_format=default; create temporary table t9 (i int); --echo *** Must be no DROP logged for t9 when there was no CREATE, at disconnect too *** --disconnect con1 --connection server_1 +# The disconnect runs asynchroneously. Wait for it to complete, otherwise the +# DROP TEMPORARY TABLE may not have been binlogged yet when SHOW BINLOG EVENTS +# is run. +--let $wait_condition= SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID=$conid +--source include/wait_condition.inc + --source include/show_binlog_events.inc # Clean up diff --git a/mysql-test/suite/rpl/t/mdev-31448_kill_ooo_finish_optimistic.test b/mysql-test/suite/rpl/t/mdev-31448_kill_ooo_finish_optimistic.test index 1297fcda7f7..aa777d40523 100644 --- a/mysql-test/suite/rpl/t/mdev-31448_kill_ooo_finish_optimistic.test +++ b/mysql-test/suite/rpl/t/mdev-31448_kill_ooo_finish_optimistic.test @@ -54,7 +54,8 @@ drop table t2; --source include/start_slave.inc --echo # wait for T1 ---let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Update_rows_log_event::find_row(-1)%' and command LIKE 'Slave_worker'; +# Wildcard for `state` as it depends on whether WSREP is compiled in or not. +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Update_rows_log_event::find_row(%' and command LIKE 'Slave_worker'; --source include/wait_condition.inc --echo # wait for T2 @@ -81,7 +82,9 @@ DROP TABLE t1; --connection slave --echo # --echo # Cleanup ---source include/stop_slave.inc +--let $rpl_allow_error= 1 +--source include/wait_for_slave_sql_to_stop.inc +--source include/stop_slave_io.inc eval set @@global.slave_parallel_threads= $save_slave_parallel_threads; eval set @@global.slave_parallel_mode= $save_slave_parallel_mode; eval set @@global.innodb_lock_wait_timeout= $save_innodb_lock_wait_timeout; diff --git a/mysql-test/suite/rpl/t/parallel_backup_xa.inc b/mysql-test/suite/rpl/t/parallel_backup_xa.inc index 2d831199aa8..83a6fb79345 100644 --- a/mysql-test/suite/rpl/t/parallel_backup_xa.inc +++ b/mysql-test/suite/rpl/t/parallel_backup_xa.inc @@ -59,6 +59,7 @@ XA RECOVER; { --let $wait_condition= SELECT COUNT(*) = 0 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" --source include/wait_condition.inc + --let $rpl_allow_error=1 } ROLLBACK; --let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = "Waiting for backup lock" @@ -71,6 +72,7 @@ if (!$slave_ooo_error) { --source include/sync_with_master_gtid.inc } +--let $rpl_only_running_threads= 1 --source include/stop_slave.inc if ($slave_ooo_error) { diff --git a/mysql-test/suite/rpl/t/rpl_binlog_cache_disk_full_loaddata.test b/mysql-test/suite/rpl/t/rpl_binlog_cache_disk_full_loaddata.test new file mode 100644 index 00000000000..50a67532501 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_cache_disk_full_loaddata.test @@ -0,0 +1,47 @@ +--source include/have_binlog_format_statement.inc +--source include/have_debug.inc +--source include/master-slave.inc + +--connection master +# Set minimal cache size so smaller transaction can trigger spill to disk. +SET @save_binlog_stmt_cache_size= @@GLOBAL.binlog_stmt_cache_size; +SET GLOBAL binlog_stmt_cache_size= 4096; + +CALL mtr.add_suppression('"No space left on device".*An incident event is written to binary log'); +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=MyISAM; + +FLUSH STATUS; +SHOW STATUS LIKE "binlog_stmt_cache%"; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,load_data_binlog_cache_error"; +--replace_regex /Error writing file '[^']+'/Error writing file ''/ +--error 3 +LOAD DATA CONCURRENT LOCAL INFILE 'std_data/bug30435_5k.txt' + REPLACE INTO TABLE t1 (a); +SET SESSION debug_dbug= @old_dbug; +SHOW STATUS LIKE "binlog_stmt_cache%"; +# The actual number of rows left after the disk full error may change as +# binlog event sizes are modified. So here we just test that we get partial +# update from the last INSERT..SELECT that gets disk full error. +SELECT IF(COUNT(*) > 0 AND COUNT(*) < 5000, + "ok", + CONCAT("ERROR! Row count ", COUNT(*), " not as expected for partially executed query")) + AS check_result + FROM t1; + +--save_master_pos + +--connection slave +--let $slave_sql_errno= 1590 +--source include/wait_for_slave_sql_error_and_skip.inc + +--sync_with_master +SELECT COUNT(*) FROM t1; + +# Cleanup + +--connection master +SET GLOBAL binlog_stmt_cache_size= @save_binlog_stmt_cache_size; +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_cache_disk_full_row.test b/mysql-test/suite/rpl/t/rpl_binlog_cache_disk_full_row.test new file mode 100644 index 00000000000..2c5813bb53e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_cache_disk_full_row.test @@ -0,0 +1,61 @@ +--source include/have_binlog_format_row.inc +--source include/have_debug.inc +--source include/master-slave.inc + +--connection master +# Set minimal cache size so smaller transaction can trigger spill to disk. +SET @save_binlog_stmt_cache_size= @@GLOBAL.binlog_stmt_cache_size; +SET GLOBAL binlog_stmt_cache_size= 4096; + +CALL mtr.add_suppression('"No space left on device".*An incident event is written to binary log'); +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(255)) ENGINE=MyISAM; + +FLUSH STATUS; +SHOW STATUS LIKE "binlog_stmt_cache%"; +INSERT INTO t1 VALUES (0, CONCAT("?", "-", REPEAT("x", 200))); +INSERT INTO t1 SELECT a+1, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+2, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+4, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+8, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+16, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+32, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+64, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +INSERT INTO t1 SELECT a+128, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +SHOW STATUS LIKE "binlog_stmt_cache%"; + +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,simulate_disk_full_at_flush_pending"; +--replace_regex /Error writing file '[^']+'/Error writing file ''/ +--error 3 +INSERT INTO t1 SELECT a+256, CONCAT(a, "-", REPEAT("x", 200)) FROM t1; +SET SESSION debug_dbug= @old_dbug; +SHOW STATUS LIKE "binlog_stmt_cache%"; +# The actual number of rows left after the disk full error may change as +# binlog event sizes are modified. So here we just test that we get partial +# update from the last INSERT..SELECT that gets disk full error. +SELECT IF(COUNT(*) > 256 AND COUNT(*) < 512, + "ok", + CONCAT("ERROR! Row count ", COUNT(*), " not as expected for partially executed query")) + AS check_result + FROM t1; + +# A random extra event that helped show the bug that a partial event +# group was binlogged. +ALTER TABLE t1 COMMENT ''; + +--save_master_pos + +--connection slave +--let $slave_sql_errno= 1590 +--source include/wait_for_slave_sql_error_and_skip.inc + +--sync_with_master +SELECT COUNT(*) FROM t1; + +# Cleanup + +--connection master +SET GLOBAL binlog_stmt_cache_size= @save_binlog_stmt_cache_size; +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_checksum.test b/mysql-test/suite/rpl/t/rpl_checksum.test index 17a986dc308..36cd382eaad 100644 --- a/mysql-test/suite/rpl/t/rpl_checksum.test +++ b/mysql-test/suite/rpl/t/rpl_checksum.test @@ -89,6 +89,9 @@ flush logs; flush logs; -- source include/wait_for_binlog_checkpoint.inc flush logs; +# The binlog position here is output in the error message from +# wait_for_slave_io_error below, so make sure it's deterministic. +-- source include/wait_for_binlog_checkpoint.inc sync_slave_with_master; #connection slave; diff --git a/mysql-test/suite/rpl/t/rpl_connection.test b/mysql-test/suite/rpl/t/rpl_connection.test index 310240061d1..24ada7c85c6 100644 --- a/mysql-test/suite/rpl/t/rpl_connection.test +++ b/mysql-test/suite/rpl/t/rpl_connection.test @@ -16,7 +16,7 @@ CHANGE MASTER TO MASTER_USER= '', MASTER_PASSWORD= ''; START SLAVE; --let $slave_io_errno= 1045, 1593 --source include/wait_for_slave_io_error.inc ---source include/stop_slave.inc +--source include/stop_slave_sql.inc CHANGE MASTER TO MASTER_USER= 'root', MASTER_PASSWORD= ''; START SLAVE; diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test index a949da0cc25..95fac6c2edb 100644 --- a/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test @@ -149,8 +149,7 @@ connection slave; SELECT * FROM t1; SET @@global.debug_dbug=@saved_dbug; - ---source include/stop_slave.inc +--source include/stop_slave_sql.inc let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); --echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before @@ -218,7 +217,7 @@ SELECT * FROM t1; SET @@global.debug_dbug=@saved_dbug; ---source include/stop_slave.inc +--source include/stop_slave_sql.inc let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); --echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before @@ -286,7 +285,7 @@ SELECT * FROM t1; SET @@global.debug_dbug=@saved_dbug; ---source include/stop_slave.inc +--source include/stop_slave_sql.inc let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); --echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before @@ -354,7 +353,7 @@ SELECT * FROM t1; SET @@global.debug_dbug=@saved_dbug; ---source include/stop_slave.inc +--source include/stop_slave_sql.inc let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); --echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test index 6dafab192a0..b1fa9af33a4 100644 --- a/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test @@ -67,8 +67,10 @@ connection master; save_master_pos; --connection slave ---source include/stop_slave.inc ---source include/start_slave.inc +--let rpl_allow_error=1 +--source include/wait_for_slave_io_to_start.inc +--let rpl_allow_error= +--source include/wait_for_slave_sql_to_start.inc sync_with_master; select * from ti; select * from tm; diff --git a/mysql-test/suite/rpl/t/rpl_fail_register.test b/mysql-test/suite/rpl/t/rpl_fail_register.test index d95a5c5f1c3..5f86a33c9aa 100644 --- a/mysql-test/suite/rpl/t/rpl_fail_register.test +++ b/mysql-test/suite/rpl/t/rpl_fail_register.test @@ -3,7 +3,7 @@ source include/have_binlog_format_mixed.inc; source include/master-slave.inc; connection slave; - +CALL mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: Debug Induced Error"); set @old_dbug=@@global.debug_dbug; set global debug_dbug='d,fail_com_register_slave'; @@ -11,8 +11,11 @@ stop slave; reset slave; source include/wait_for_slave_to_stop.inc; start slave; -stop slave; -source include/wait_for_slave_to_stop.inc; +# Debug point will raise IO thread error ER_SLAVE_MASTER_COM_FAILURE +# so we will wait for that and manually stop the SQL thread +--let $slave_io_errno= 1597 +--source include/wait_for_slave_io_error.inc +--source include/stop_slave_sql.inc set global debug_dbug=@old_dbug; connection master; diff --git a/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test index c02e2670c92..eec7a275e03 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test @@ -19,7 +19,7 @@ INSERT INTO t1 VALUES (1); CALL mtr.add_suppression("Slave: Failed to open mysql.gtid_slave_pos"); --let $slave_sql_errno=1944 --source include/wait_for_slave_sql_error.inc - +--let $rpl_only_running_threads= 1 --source include/stop_slave.inc ALTER TABLE mysql.gtid_slave_pos CHANGE seq_no seq_no BIGINT UNSIGNED NOT NULL; ALTER TABLE mysql.gtid_slave_pos DROP PRIMARY KEY; diff --git a/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test b/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test index ea321062100..0ee54cd1183 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test @@ -31,8 +31,8 @@ SET sql_log_bin=1; START SLAVE; --let $slave_sql_errno=1062 --source include/wait_for_slave_sql_error.inc - ---source include/stop_slave.inc +--source include/wait_for_slave_io_to_start.inc +--source include/stop_slave_io.inc # Skip the problem event from the master. SET GLOBAL gtid_slave_pos= "0-1-100"; --source include/start_slave.inc @@ -51,7 +51,7 @@ SET debug_dbug= @dbug_save; --connection slave --let $slave_sql_errno=1590 --source include/wait_for_slave_sql_error.inc ---source include/stop_slave.inc +--source include/stop_slave_io.inc SET sql_slave_skip_counter=1; --source include/start_slave.inc --sync_with_master diff --git a/mysql-test/suite/rpl/t/rpl_gtid_startpos.test b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test index 100d75a8cdc..6795c008311 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_startpos.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test @@ -50,7 +50,7 @@ eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, START SLAVE; --let $slave_io_errno= 1236 --source include/wait_for_slave_io_error.inc ---source include/stop_slave.inc +--source include/stop_slave_sql.inc --replace_result $MASTER_MYPORT MASTER_PORT eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, diff --git a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test index 38537810906..0d232f3c60c 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test @@ -211,7 +211,7 @@ SET sql_log_bin=0; call mtr.add_suppression("Failed to load slave replication state from table"); call mtr.add_suppression("Unable to load replication GTID slave state"); SET sql_log_bin=1; - +--let rpl_allow_error= 1 --source include/start_slave.inc --connection server_1 INSERT INTO t1 VALUES (9); diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test index 45b5d48c13b..c3a767be118 100644 --- a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test @@ -329,7 +329,7 @@ sleep 4; let $rcvd_heartbeats_after= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_before) > 0 AS Result, Result, 1); --echo Heartbeat events are received while sql thread stopped (1 means 'yes'): $result ---source include/stop_slave.inc +--source include/stop_slave_io.inc DROP TABLE t1; --echo diff --git a/mysql-test/suite/rpl/t/rpl_invoked_features.test b/mysql-test/suite/rpl/t/rpl_invoked_features.test index 91391cf8372..cd2b770c419 100644 --- a/mysql-test/suite/rpl/t/rpl_invoked_features.test +++ b/mysql-test/suite/rpl/t/rpl_invoked_features.test @@ -102,14 +102,17 @@ BEGIN UPDATE t13 SET c = ''; END| -# Create events which will run every 1 sec -CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DISABLE DO +# Create events which will run every 10 sec +# It cannot be much shorter as we have to ensure that a new +# event is not scheduled before the DISABLE has been +# executed. +CREATE EVENT e1 ON SCHEDULE EVERY 10 SECOND DISABLE DO BEGIN ALTER EVENT e1 DISABLE; CALL p1(10, ''); END| -CREATE EVENT e11 ON SCHEDULE EVERY 1 SECOND DISABLE DO +CREATE EVENT e11 ON SCHEDULE EVERY 10 SECOND DISABLE DO BEGIN ALTER EVENT e11 DISABLE; CALL p11(10, ''); diff --git a/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test index 19f2db32cb7..18228e75e2e 100644 --- a/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test +++ b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test @@ -20,6 +20,7 @@ SET @@global.debug_dbug='+d,simulate_slave_capability_none'; connection master; FLUSH LOGS; +--source include/wait_for_binlog_checkpoint.inc CREATE TABLE t1 (a INT PRIMARY KEY); INSERT INTO t1 VALUES (0); sync_slave_with_master; diff --git a/mysql-test/suite/rpl/t/rpl_mdev_17614.test b/mysql-test/suite/rpl/t/rpl_mdev_17614.test index c11aad3305e..92fddc79e84 100644 --- a/mysql-test/suite/rpl/t/rpl_mdev_17614.test +++ b/mysql-test/suite/rpl/t/rpl_mdev_17614.test @@ -40,8 +40,7 @@ SELECT * FROM t1; SELECT * FROM t1; # restart replication for the next testcase -stop slave; ---source include/wait_for_slave_to_stop.inc +--source include/stop_slave_io.inc reset slave; connection master; reset master; @@ -159,8 +158,7 @@ SELECT * FROM t1; SELECT * FROM t1; # restart replication for the next testcase -stop slave; ---source include/wait_for_slave_to_stop.inc +--source include/stop_slave_io.inc reset slave; connection master; reset master; diff --git a/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test b/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test index 493385f1ae3..83b89a69f05 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test @@ -96,7 +96,9 @@ COMMIT; # Clean up. --connection server_2 ---source include/stop_slave.inc +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc +--source include/stop_slave_io.inc --let $assert_cond= COUNT(*) = 0 FROM t1 WHERE a>32 --let $assert_text= table t1 should have zero rows where a>32 --source include/assert.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test b/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test index 33b1bcb11d9..6ed9638db7e 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test @@ -60,7 +60,6 @@ SET debug_sync='RESET'; --connection server_2 --let $slave_sql_errno= 1062 --source include/wait_for_slave_sql_error.inc ---source include/wait_for_slave_sql_to_stop.inc # We should not see the row (112,3) here, it should be rolled back due to # error signal from the prior transaction. SELECT * FROM t3 WHERE a >= 110 ORDER BY a; diff --git a/mysql-test/suite/rpl/t/rpl_parallel_retry.test b/mysql-test/suite/rpl/t/rpl_parallel_retry.test index 8b2affed571..fe6f40d2c85 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_retry.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_retry.test @@ -497,6 +497,7 @@ if (`SELECT count(*) = 1 FROM t1 WHERE a = 2`) # Clean up # --connection server_2 +--let $rpl_only_running_threads= 1 --source include/stop_slave.inc SET @@GLOBAL.slave_parallel_threads=@old_parallel_threads; SET @@GLOBAL.slave_parallel_mode=@old_parallel_mode; diff --git a/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_coordinator.test b/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_coordinator.test index d4f185812e0..1fbd60bb94d 100644 --- a/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_coordinator.test +++ b/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_coordinator.test @@ -209,6 +209,7 @@ drop table t; reset master; --connection slave +--let $rpl_only_running_threads= 1 --source include/stop_slave.inc reset slave; reset master; diff --git a/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_worker.test b/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_worker.test index 857979d00c4..5ef28a62006 100644 --- a/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_worker.test +++ b/mysql-test/suite/rpl/t/rpl_perfschema_applier_status_by_worker.test @@ -227,6 +227,7 @@ select Last_Error_Message from performance_schema.replication_applier_status_by_ #let $assert_cond= "$sss_value" = "$ps_value_in_sss_format"; #source include/assert.inc; +--let $rpl_only_running_threads= 1 --source include/stop_slave.inc RESET SLAVE; --connection master diff --git a/mysql-test/suite/rpl/t/rpl_row_corruption.test b/mysql-test/suite/rpl/t/rpl_row_corruption.test index d78df905ccb..6f4f9c882e2 100644 --- a/mysql-test/suite/rpl/t/rpl_row_corruption.test +++ b/mysql-test/suite/rpl/t/rpl_row_corruption.test @@ -39,7 +39,7 @@ SET @@global.debug_dbug="d,inject_tblmap_same_id_maps_diff_table"; # wait for error 1593 (ER_SLAVE_FATAL_ERROR) --let $slave_sql_errno=1593 --source include/wait_for_slave_sql_error.inc ---source include/stop_slave.inc +--source include/stop_slave_io.inc # clean up SET @@global.debug_dbug=@saved_debug; diff --git a/mysql-test/suite/rpl/t/rpl_row_idempotency.test b/mysql-test/suite/rpl/t/rpl_row_idempotency.test index 85775832b2b..326f94ecbc3 100644 --- a/mysql-test/suite/rpl/t/rpl_row_idempotency.test +++ b/mysql-test/suite/rpl/t/rpl_row_idempotency.test @@ -139,7 +139,9 @@ select * from ti1 order by b /* must be (2),(3) */; --echo *** slave must stop (Trying to delete a referenced foreing key) connection slave; -source include/wait_for_slave_sql_to_stop.inc; +# ER_ROW_IS_REFERENCED_2 # Cannot add or update a child row: a foreign key constraint fails +--let slave_sql_errno= 1451 +source include/wait_for_slave_sql_error.inc; let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); disable_query_log; @@ -173,7 +175,9 @@ insert into ti2 set a=3, b=3 /* offending write event */; --echo *** slave must stop (Trying to insert an invalid foreign key) connection slave; -source include/wait_for_slave_sql_to_stop.inc; +# ER_NO_REFERENCED_ROW_2 # Cannot add or update a parent row: a foreign key constraint fails +--let slave_sql_errno= 1452 +source include/wait_for_slave_sql_error.inc; let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); disable_query_log; @@ -210,9 +214,11 @@ insert into ti1 set b=1; connection master; insert into ti1 set b=1 /* offending write event */; ---echo *** slave must stop (Trying to insert a dupliacte key) +--echo *** slave must stop (Trying to insert a duplicate key) connection slave; -source include/wait_for_slave_sql_to_stop.inc; +# ER_DUP_ENTRY # Duplicate entry for key +--let slave_sql_errno= 1062 +source include/wait_for_slave_sql_error.inc; let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); disable_query_log; @@ -247,7 +253,10 @@ DELETE FROM t1 WHERE a = -2; --echo *** slave must stop (Key was not found) connection slave; -source include/wait_for_slave_sql_to_stop.inc; +# ER_KEY_NOT_FOUND # Can't find record +--let slave_sql_errno= 1032 +source include/wait_for_slave_sql_error.inc; + let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); disable_query_log; @@ -265,7 +274,9 @@ connection master; DELETE FROM t2 WHERE a = -2; --echo *** slave must stop (Key was not found) connection slave; -source include/wait_for_slave_sql_to_stop.inc; +# ER_KEY_NOT_FOUND # Can't find record +--let slave_sql_errno= 1032 +source include/wait_for_slave_sql_error.inc; let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); disable_query_log; @@ -287,7 +298,9 @@ UPDATE t1 SET a = 1 WHERE a = -1; --echo *** slave must stop (Key was not found) connection slave; -source include/wait_for_slave_sql_to_stop.inc; +# ER_KEY_NOT_FOUND # Can't find record +--let slave_sql_errno= 1032 +source include/wait_for_slave_sql_error.inc; let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); disable_query_log; @@ -307,7 +320,9 @@ UPDATE t2 SET a = 1 WHERE a = -1; --echo *** slave must stop (Key was not found) connection slave; -source include/wait_for_slave_sql_to_stop.inc; +# ER_KEY_NOT_FOUND # Can't find record +--let slave_sql_errno= 1032 +source include/wait_for_slave_sql_error.inc; let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); disable_query_log; diff --git a/mysql-test/suite/rpl/t/rpl_row_until.test b/mysql-test/suite/rpl/t/rpl_row_until.test index 478c2206a5a..5825d56f487 100644 --- a/mysql-test/suite/rpl/t/rpl_row_until.test +++ b/mysql-test/suite/rpl/t/rpl_row_until.test @@ -101,7 +101,12 @@ START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', MASTER_LOG_POS=561; --replace_result 740 MASTER_LOG_POS START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=740; ---source include/stop_slave.inc +# Explicit wait for slave thread start and then stop. Otherwise the STOP SLAVE +# command can abort the slave connecting to the master, and an error state +# left which makes stop_slave.inc throw an error. +--source include/wait_for_slave_io_to_start.inc +--source include/wait_for_slave_sql_to_stop.inc +--source include/stop_slave_io.inc RESET SLAVE; --source include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_master_shutdown.test b/mysql-test/suite/rpl/t/rpl_semi_sync_master_shutdown.test index 2224f78d6d0..05e6fcca143 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_master_shutdown.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_master_shutdown.test @@ -30,8 +30,12 @@ connection master; --let $rpl_server_number=1 source include/rpl_stop_server.inc; +# After stoping the master, slave receives the disconnect error (2003) --connection slave ---source include/stop_slave.inc +--let $slave_io_errno=2003 +--let $slave_io_error_is_nonfatal=1 +--source include/wait_for_slave_io_error.inc +--let $slave_io_error_is_nonfatal=0 #connection master; --echo # Restart master @@ -42,8 +46,10 @@ source include/rpl_start_server.inc; # Clean up # --connection slave ---source include/stop_slave.inc ---source include/start_slave.inc +--source include/wait_for_slave_sql_to_start.inc +--let rpl_allow_error=1 +--source include/wait_for_slave_io_to_start.inc +#--source include/start_slave.inc --connection master SET @@GLOBAL.debug_dbug=""; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.inc b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.inc index a232f68540d..252541ae13b 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.inc +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.inc @@ -116,11 +116,13 @@ show status like 'Rpl_semi_sync_master_no_tx'; --connection server_2 --eval SET @@GLOBAL.debug_dbug= "$sav_server_2_dbug" --eval SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0 +--let $rpl_only_running_threads= 1 source include/stop_slave.inc; --connection server_3 --eval SET @@GLOBAL.debug_dbug= "$sav_server_3_dbug" --eval SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0 +--let $rpl_only_running_threads= 1 source include/stop_slave.inc; --echo #-- Bring the master back up diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_compressed_protocol.test b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_compressed_protocol.test index bc05bec2a96..644e6517131 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_compressed_protocol.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_compressed_protocol.test @@ -40,7 +40,7 @@ DROP TABLE t1; --let $assert_select=Read semi-sync reply magic number error --let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err --let $assert_count= 0 ---let $assert_only_after = CURRENT_TEST:rpl.rpl_semi_sync_slave_compressed_protocol.test +--let $assert_only_after = CURRENT_TEST: rpl.rpl_semi_sync_slave_compressed_protocol --source include/assert_grep.inc --connection master diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test index 948537997dd..2ebc092e33d 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test @@ -78,7 +78,7 @@ insert into t1 values (10); --connection master set statement sql_log_bin=0 for call mtr.add_suppression("Read semi-sync reply magic number error"); -SET @save_debug_master= @@global.debug; +SET @save_debug_master= @@global.debug_dbug; SET GLOBAL debug_dbug="+d,semisync_corrupt_magic"; insert into t1 values (11); diff --git a/mysql-test/suite/rpl/t/rpl_set_statement_default_master.test b/mysql-test/suite/rpl/t/rpl_set_statement_default_master.test index 106cb4547f4..d30da61bee6 100644 --- a/mysql-test/suite/rpl/t/rpl_set_statement_default_master.test +++ b/mysql-test/suite/rpl/t/rpl_set_statement_default_master.test @@ -26,6 +26,7 @@ eval CHANGE MASTER 'm1' TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, SET STATEMENT default_master_connection = 'm1' FOR START SLAVE; set default_master_connection = 'm1'; +--source include/wait_for_slave_to_start.inc stop slave; --source include/wait_for_slave_to_stop.inc reset slave all; diff --git a/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist.test b/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist.test index 16dcd8ecbd3..89b7c7f1744 100644 --- a/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist.test +++ b/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist.test @@ -15,6 +15,7 @@ call mtr.add_suppression("Slave SQL.*Unable to use slave.s temporary directory") --let $slave_sql_errno= 12 source include/wait_for_slave_sql_error.inc; +--source include/wait_for_slave_io_to_start.inc --source include/stop_slave_io.inc RESET SLAVE; diff --git a/mysql-test/suite/rpl/t/rpl_slave_status.test b/mysql-test/suite/rpl/t/rpl_slave_status.test index 63e37216926..fb552d6477d 100644 --- a/mysql-test/suite/rpl/t/rpl_slave_status.test +++ b/mysql-test/suite/rpl/t/rpl_slave_status.test @@ -59,7 +59,6 @@ sync_slave_with_master; source include/stop_slave.inc; START SLAVE; source include/wait_for_slave_sql_to_start.inc; -source include/wait_for_slave_io_to_stop.inc; --echo ==== Verify that Slave IO thread stopped with error ==== # 1045 = ER_ACCESS_DENIED_ERROR @@ -68,7 +67,7 @@ source include/wait_for_slave_io_to_stop.inc; --echo ==== Cleanup (Note that slave IO thread is not running) ==== -# cleanup: slave io thread has is stopped so we reset replication +# cleanup: slave io thread is stopped so we reset replication --source include/stop_slave_sql.inc CHANGE MASTER TO MASTER_USER = 'root', MASTER_PASSWORD = ''; # clear Slave_IO_Errno diff --git a/mysql-test/suite/rpl/t/rpl_sql_thd_start_errno_cleared.test b/mysql-test/suite/rpl/t/rpl_sql_thd_start_errno_cleared.test index f6dcfd91409..8b096902143 100644 --- a/mysql-test/suite/rpl/t/rpl_sql_thd_start_errno_cleared.test +++ b/mysql-test/suite/rpl/t/rpl_sql_thd_start_errno_cleared.test @@ -76,6 +76,10 @@ if ($last_error) set debug_sync= "now signal sql_thread_continue"; +--echo # Wait for debug_sync signal to have been received before issuing RESET +let $wait_condition= select count(*)=0 from information_schema.processlist where state like "debug sync point%"; +source include/wait_condition.inc; + set @@global.debug_dbug= @saved_dbug; set debug_sync= "RESET"; diff --git a/mysql-test/suite/rpl/t/rpl_ssl1.test b/mysql-test/suite/rpl/t/rpl_ssl1.test index d994dd21c1d..04f6cfffa6c 100644 --- a/mysql-test/suite/rpl/t/rpl_ssl1.test +++ b/mysql-test/suite/rpl/t/rpl_ssl1.test @@ -29,8 +29,10 @@ connection slave; select * from t1; #showing that replication could work with ssl params -stop slave; ---source include/wait_for_slave_to_stop.inc +--let $slave_io_errno=1045 +--source include/wait_for_slave_io_error.inc +--source include/stop_slave_sql.inc + --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR eval change master to master_ssl=1 , master_ssl_ca ='$MYSQL_TEST_DIR/std_data/cacert.pem', master_ssl_cert='$MYSQL_TEST_DIR/std_data/client-cert.pem', master_ssl_key='$MYSQL_TEST_DIR/std_data/client-key.pem'; start slave; diff --git a/mysql-test/suite/rpl/t/rpl_temporary_errors.test b/mysql-test/suite/rpl/t/rpl_temporary_errors.test index 85e16afa270..4d179cd51ab 100644 --- a/mysql-test/suite/rpl/t/rpl_temporary_errors.test +++ b/mysql-test/suite/rpl/t/rpl_temporary_errors.test @@ -71,13 +71,15 @@ connection slave; set @@global.innodb_lock_wait_timeout=1; set @@global.slave_transaction_retries=100; +--let $rpl_allow_error=1 --source include/restart_slave_sql.inc +--let $rpl_allow_error=0 --let $last_retries= query_get_value(SHOW GLOBAL STATUS LIKE 'Slave_retried_transactions', Value, 1) --let $status_type=GLOBAL --let $status_var=Slave_retried_transactions --let $status_var_value=`SELECT 1 + $last_retries` ---let $$status_var_comparsion= > +--let $status_var_comparsion= > --source include/wait_for_status_var.inc # Release the record after just one retry diff --git a/mysql-test/suite/rpl/t/semisync_future-7591.test b/mysql-test/suite/rpl/t/semisync_future-7591.test index 866041d2579..53d87182870 100644 --- a/mysql-test/suite/rpl/t/semisync_future-7591.test +++ b/mysql-test/suite/rpl/t/semisync_future-7591.test @@ -19,7 +19,7 @@ insert into t1 values (1); reset master; --connection slave ---source include/stop_slave.inc +--source include/stop_slave_sql.inc reset slave; --source include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test b/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test index 12794dbd898..cd0f8aad106 100644 --- a/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test +++ b/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test @@ -15,6 +15,9 @@ call mtr.add_suppression("Master is configured to log replication events"); # All done. --connection slave +# The parallel START SLAVE can leave an error condition if the last START was +# aborted by the master due to conflicting server_id from multiple connections. +--let $rpl_allow_error= 1 --source include/wait_for_slave_to_stop.inc start slave; diff --git a/mysql-test/suite/sys_vars/r/pseudo_slave_mode_notembedded.result b/mysql-test/suite/sys_vars/r/pseudo_slave_mode_notembedded.result new file mode 100644 index 00000000000..3246a309638 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/pseudo_slave_mode_notembedded.result @@ -0,0 +1,14 @@ +'### MDEV-32844: THD::rli_fake/rgi_fake not cleared on new connection' +connect con1,localhost,root,,; +BINLOG ' +6ENbZQ8BAAAA/AAAAAABAAAAAAQAMTAuMTEuNi1NYXJpYURCLWRlYnVnLWxvZwAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAADoQ1tlEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAEEwQADQgICAoKCgGbvv33 +'; +disconnect con1; +connect con1,localhost,root,,; +SET SESSION pseudo_slave_mode= 1; +disconnect con1; +connection default; diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff index c83cc9ce944..4ebd48ad6bd 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_server_embedded.result -+++ suite/sys_vars/r/sysvars_server_embedded,32bit.reject +--- sysvars_server_embedded.result ++++ sysvars_server_embedded.result @@ -34,7 +34,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE @@ -290,7 +290,16 @@ VARIABLE_COMMENT Precision of the result of '/' operator will be increased on that value NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 38 -@@ -954,7 +954,7 @@ +@@ -914,7 +914,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME EXPIRE_LOGS_DAYS + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT If non-zero, binary logs will be purged after expire_logs_days days; possible purges happen at startup and at binary log rotation + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 99 +@@ -944,7 +944,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME EXTRA_MAX_CONNECTIONS VARIABLE_SCOPE GLOBAL @@ -422,7 +431,7 @@ VARIABLE_SCOPE SESSION -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT Log some not critical warnings to the general log file.Value can be between 0 and 11. Higher values mean more verbosity + VARIABLE_COMMENT Log some non critical warnings to the error log.Value can be between 0 and 11. Higher values mean more verbosity NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 @@ -1784,7 +1784,7 @@ 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 a6ed72520e5..8e50d8e7268 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -1735,7 +1735,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME LOG_WARNINGS VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED -VARIABLE_COMMENT Log some not critical warnings to the general log file.Value can be between 0 and 11. Higher values mean more verbosity +VARIABLE_COMMENT Log some non critical warnings to the error log.Value can be between 0 and 11. Higher values mean more verbosity NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 NUMERIC_BLOCK_SIZE 1 diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff index bb7972900e9..dfe7e0d829d 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_server_notembedded.result -+++ suite/sys_vars/r/sysvars_server_notembedded,32bit.reject +--- sysvars_server_notembedded.result ++++ sysvars_server_notembedded.result @@ -34,7 +34,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE @@ -422,7 +422,7 @@ VARIABLE_SCOPE SESSION -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT Log some not critical warnings to the general log file.Value can be between 0 and 11. Higher values mean more verbosity + VARIABLE_COMMENT Log some non critical warnings to the error log.Value can be between 0 and 11. Higher values mean more verbosity NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 @@ -1934,7 +1934,7 @@ 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 2ade2a9649a..319b86583fc 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -1875,7 +1875,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME LOG_WARNINGS VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED -VARIABLE_COMMENT Log some not critical warnings to the general log file.Value can be between 0 and 11. Higher values mean more verbosity +VARIABLE_COMMENT Log some non critical warnings to the error log.Value can be between 0 and 11. Higher values mean more verbosity NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 NUMERIC_BLOCK_SIZE 1 diff --git a/mysql-test/suite/sys_vars/t/pseudo_slave_mode_notembedded.test b/mysql-test/suite/sys_vars/t/pseudo_slave_mode_notembedded.test new file mode 100644 index 00000000000..c18872dba0e --- /dev/null +++ b/mysql-test/suite/sys_vars/t/pseudo_slave_mode_notembedded.test @@ -0,0 +1,20 @@ +--source include/not_embedded.inc +--source include/load_sysvars.inc + +--echo '### MDEV-32844: THD::rli_fake/rgi_fake not cleared on new connection' +--connect(con1,localhost,root,,) +BINLOG ' +6ENbZQ8BAAAA/AAAAAABAAAAAAQAMTAuMTEuNi1NYXJpYURCLWRlYnVnLWxvZwAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAADoQ1tlEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAEEwQADQgICAoKCgGbvv33 +'; +--disconnect con1 +--connect(con1,localhost,root,,) +# The bug was that the THD::rli_fake was not cleared when the THD is re-used +# for the new connection, and we would get a warning from the following +# statement. +SET SESSION pseudo_slave_mode= 1; +--disconnect con1 +--connection default diff --git a/mysql-test/suite/sysschema/disabled.def b/mysql-test/suite/sysschema/disabled.def index 62df96a4663..ffb897b553a 100644 --- a/mysql-test/suite/sysschema/disabled.def +++ b/mysql-test/suite/sysschema/disabled.def @@ -9,4 +9,5 @@ # Do not use any TAB characters for whitespace. # ############################################################################## +import_update_stats: MDEV-32725 fails in MSAN, uninit access pr_statement_performance_analyzer : MDEV-29822 perfschema specific and Windows specific problems. diff --git a/mysql-test/suite/vcol/r/partition.result b/mysql-test/suite/vcol/r/partition.result index d7c5052b72a..74c1e3bfee0 100644 --- a/mysql-test/suite/vcol/r/partition.result +++ b/mysql-test/suite/vcol/r/partition.result @@ -101,3 +101,25 @@ partition pn values less than (maxvalue)); insert into t1 (x, b) values (1, ''), (2, ''), (3, 'a'), (4, 'b'); update t1 set b= 'bar' where x > 0 order by v limit 2; drop table t1; +# +# MDEV-28127 EXCHANGE PARTITION with non-matching vcol expression segfault +# +set @old_mode= @@sql_mode; +set sql_mode=''; +create table t1 (a int, key(a)) partition by range (a) (partition p values less than (1)); +create table t (a int generated always as (1) virtual, key(a)); +alter table t1 exchange partition p with table t; +ERROR HY000: Tables have different definitions +create or replace table t (a int, key(a)); +alter table t1 exchange partition p with table t; +create or replace table t1 (a int generated always as (1) virtual, key(a)) partition by range (a) (partition p values less than (1)); +create or replace table t (a int generated always as (1) virtual, key(a)); +alter table t1 exchange partition p with table t; +create or replace table t (a int generated always as (1) stored, key(a)); +alter table t1 exchange partition p with table t; +ERROR HY000: Tables have different definitions +insert into t values (1); +Warnings: +Warning 1906 The value specified for generated column 'a' in table 't' has been ignored +drop tables t1, t; +set sql_mode= @old_mode; diff --git a/mysql-test/suite/vcol/r/vcol_keys_myisam.result b/mysql-test/suite/vcol/r/vcol_keys_myisam.result index 2e15c50263b..6b86d40e6b1 100644 --- a/mysql-test/suite/vcol/r/vcol_keys_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_keys_myisam.result @@ -418,3 +418,40 @@ create or replace table t2 (pk int, b int, c int as (b) virtual, primary key (pk insert into t2 (pk) select a from t1; ERROR 23000: Duplicate entry '1' for key 'PRIMARY' drop tables t1, t2; +# +# MDEV-23294 Segfault or assertion upon MyISAM repair +# +set @old_mode= @@sql_mode; +set @old_myisam_repair_threads= @@myisam_repair_threads; +set sql_mode='', myisam_repair_threads=2; +create table t (a binary,b blob,c blob as (concat (a,b)),h char,index (c)) engine=innodb; +Warnings: +Warning 1286 Unknown storage engine 'innodb' +Warning 1266 Using storage engine MyISAM for table 't' +Note 1071 Specified key was too long; max key length is 1000 bytes +insert into t values (0,0,default,0); +create table ti like t; +alter table ti engine=myisam; +insert into ti select * from t; +Warnings: +Warning 1906 The value specified for generated column 'c' in table 'ti' has been ignored +drop tables ti, t; +create table t (id int,a varchar(1),b varchar(1),c varchar(1) generated always as (concat (a,b)),key(c)) engine=myisam; +insert into t values (0,0,9687,0); +Warnings: +Warning 1265 Data truncated for column 'b' at row 1 +Warning 1906 The value specified for generated column 'c' in table 't' has been ignored +Warning 1265 Data truncated for column 'c' at row 1 +repair table t quick; +Table Op Msg_type Msg_text +test.t repair status OK +drop table t; +create table t1 (b varchar(1024), c char(3), unique(b,c)) engine=myisam; +insert into t1 values ('foo','baz'); +alter table t1 disable keys; +set session myisam_repair_threads= 2; +insert into t1 select 'qux'; +ERROR 21S01: Column count doesn't match value count at row 1 +drop table t1; +set sql_mode= @old_mode; +set myisam_repair_threads= @old_myisam_repair_threads; diff --git a/mysql-test/suite/vcol/r/vcol_syntax.result b/mysql-test/suite/vcol/r/vcol_syntax.result index 7725d59f59c..1c3a7566f48 100644 --- a/mysql-test/suite/vcol/r/vcol_syntax.result +++ b/mysql-test/suite/vcol/r/vcol_syntax.result @@ -238,3 +238,13 @@ Warning 1292 Incorrect datetime value: '1' for column `test`.`t`.`c2` at row 1 Warning 1292 Incorrect datetime value: '0' for column `test`.`t`.`c2` at row 1 drop trigger tr; drop table t; +# +# MDEV-29932 Invalid expr in cleanup_session_expr() upon INSERT DELAYED +# +create table t (f timestamp default from_unixtime(1), g timestamp as (from_unixtime(2))); +insert delayed into t values (); +flush table t; +select unix_timestamp(f), unix_timestamp(g) from t; +unix_timestamp(f) unix_timestamp(g) +1 2 +drop table t; diff --git a/mysql-test/suite/vcol/t/partition.test b/mysql-test/suite/vcol/t/partition.test index 408990b20a6..019618b00b1 100644 --- a/mysql-test/suite/vcol/t/partition.test +++ b/mysql-test/suite/vcol/t/partition.test @@ -78,3 +78,24 @@ partition by range columns (x) ( insert into t1 (x, b) values (1, ''), (2, ''), (3, 'a'), (4, 'b'); update t1 set b= 'bar' where x > 0 order by v limit 2; drop table t1; + +--echo # +--echo # MDEV-28127 EXCHANGE PARTITION with non-matching vcol expression segfault +--echo # +set @old_mode= @@sql_mode; +set sql_mode=''; +create table t1 (a int, key(a)) partition by range (a) (partition p values less than (1)); +create table t (a int generated always as (1) virtual, key(a)); +--error ER_TABLES_DIFFERENT_METADATA +alter table t1 exchange partition p with table t; +create or replace table t (a int, key(a)); +alter table t1 exchange partition p with table t; +create or replace table t1 (a int generated always as (1) virtual, key(a)) partition by range (a) (partition p values less than (1)); +create or replace table t (a int generated always as (1) virtual, key(a)); +alter table t1 exchange partition p with table t; +create or replace table t (a int generated always as (1) stored, key(a)); +--error ER_TABLES_DIFFERENT_METADATA +alter table t1 exchange partition p with table t; +insert into t values (1); +drop tables t1, t; +set sql_mode= @old_mode; diff --git a/mysql-test/suite/vcol/t/vcol_keys_myisam.test b/mysql-test/suite/vcol/t/vcol_keys_myisam.test index ab75703f2a9..bc8fcbd29c0 100644 --- a/mysql-test/suite/vcol/t/vcol_keys_myisam.test +++ b/mysql-test/suite/vcol/t/vcol_keys_myisam.test @@ -313,3 +313,32 @@ create or replace table t2 (pk int, b int, c int as (b) virtual, primary key (pk --error ER_DUP_ENTRY insert into t2 (pk) select a from t1; drop tables t1, t2; + +--echo # +--echo # MDEV-23294 Segfault or assertion upon MyISAM repair +--echo # +set @old_mode= @@sql_mode; +set @old_myisam_repair_threads= @@myisam_repair_threads; +set sql_mode='', myisam_repair_threads=2; +create table t (a binary,b blob,c blob as (concat (a,b)),h char,index (c)) engine=innodb; +insert into t values (0,0,default,0); +create table ti like t; +alter table ti engine=myisam; +insert into ti select * from t; +drop tables ti, t; + +create table t (id int,a varchar(1),b varchar(1),c varchar(1) generated always as (concat (a,b)),key(c)) engine=myisam; +insert into t values (0,0,9687,0); +repair table t quick; +drop table t; + +create table t1 (b varchar(1024), c char(3), unique(b,c)) engine=myisam; +insert into t1 values ('foo','baz'); +alter table t1 disable keys; +set session myisam_repair_threads= 2; +--error ER_WRONG_VALUE_COUNT_ON_ROW +insert into t1 select 'qux'; +# cleanup +drop table t1; +set sql_mode= @old_mode; +set myisam_repair_threads= @old_myisam_repair_threads; diff --git a/mysql-test/suite/vcol/t/vcol_syntax.test b/mysql-test/suite/vcol/t/vcol_syntax.test index c26c4897833..4f6130a973f 100644 --- a/mysql-test/suite/vcol/t/vcol_syntax.test +++ b/mysql-test/suite/vcol/t/vcol_syntax.test @@ -187,3 +187,13 @@ insert into t values (1, 1, 1); drop trigger tr; drop table t; + +--echo # +--echo # MDEV-29932 Invalid expr in cleanup_session_expr() upon INSERT DELAYED +--echo # +create table t (f timestamp default from_unixtime(1), g timestamp as (from_unixtime(2))); +insert delayed into t values (); +flush table t; +select unix_timestamp(f), unix_timestamp(g) from t; +# Cleanup +drop table t; diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index 9751f7c718d..b3c342fd591 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -787,6 +787,68 @@ modify row_start varchar(8); ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `row_start` and `row_end` drop table t1; # +# MDEV-20545 Assertion (col.vers_sys_end()) upon inplace ALTER with virtual columns +# +create table t1 ( +a int, +va int as (a) virtual, +b int, +vb int as (b) virtual, +c int, +vc int as (c) virtual, +d int, +e int, +index(va) +) engine=innodb with system versioning; +replace into t1 () values (),(); +set statement system_versioning_alter_history=keep for alter table t1 drop e; +alter table t1 algorithm=inplace, drop system versioning; +drop table t1; +# +# MDEV-20765 Assertion (type.vers_sys_end()) upon inplace ALTER with virtual columns +# +create table t1 ( +a int, +b int as (a) virtual, +c int, +d int as (c) virtual, +e int, +f int as (e) virtual, +g int, +h int, +i int, +index(d), +key(h), +foreign key (g) references t1 (h) +) engine=innodb with system versioning; +set system_versioning_alter_history= keep; +alter table t1 drop column i; +insert into t1 (g,h) values (1,1); +drop table t1; +# +# MDEV-29034 Assertion (o->ind == vers_start) upon inplace ALTER with virtual columns +# +create table b ( +pk integer auto_increment, +col_int_key integer, +col_varchar_key varchar(1), +o bit, n bit, +h float as ( n + 2 ) virtual, +v bit, +primary key (pk), +key (col_varchar_key, col_int_key) +) engine = innodb; +set `system_versioning_alter_history`= keep; +alter table `b` add system versioning; +alter table `b` add column if not exists ( w bit, v serial ); +Warnings: +Note 1060 Duplicate column name 'v' +alter table `b` add column if not exists ( p bit ); +drop table `b`; +# +# End of 10.4 tests +# +# # MDEV-21941 RENAME doesn't work for system time or period fields # create or replace table t1 (a int) with system versioning; @@ -809,4 +871,6 @@ t1 CREATE TABLE `t1` ( PERIOD FOR SYSTEM_TIME (`x`, `y`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING drop table t1; +# # End of 10.5 tests +# diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 90c99d1bf0e..714455b6304 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -443,7 +443,7 @@ create or replace table t1 (x int) with system versioning; select * from t1 for system_time as of current_timestamp; x select * from t1 for system_time as of now; -ERROR 42S22: Unknown column 'now' in 'FOR SYSTEM_TIME' +ERROR HY000: Illegal parameter data type now for operation 'FOR SYSTEM_TIME' ### Issue #405, NATURAL JOIN failure create or replace table t1 (a int) with system versioning; create or replace table t2 (b int); @@ -708,3 +708,12 @@ No A B C D 33 1 1 1 1 34 1 1 1 1 SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; +# +# MDEV-32082 Server crash in find_field_in_table +# +create table t0 (c0 int) with system versioning; +select x0 from ( +select c0 x0 from t0 +) for system_time as of nowasdf deriv; +ERROR HY000: Illegal parameter data type nowasdf for operation 'FOR SYSTEM_TIME' +drop table t0; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 607aa8d603a..432f708a805 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -680,6 +680,71 @@ alter table t1 # cleanup drop table t1; +--echo # +--echo # MDEV-20545 Assertion (col.vers_sys_end()) upon inplace ALTER with virtual columns +--echo # +create table t1 ( + a int, + va int as (a) virtual, + b int, + vb int as (b) virtual, + c int, + vc int as (c) virtual, + d int, + e int, + index(va) +) engine=innodb with system versioning; +replace into t1 () values (),(); +set statement system_versioning_alter_history=keep for alter table t1 drop e; +alter table t1 algorithm=inplace, drop system versioning; +# cleanup +drop table t1; + +--echo # +--echo # MDEV-20765 Assertion (type.vers_sys_end()) upon inplace ALTER with virtual columns +--echo # +create table t1 ( + a int, + b int as (a) virtual, + c int, + d int as (c) virtual, + e int, + f int as (e) virtual, + g int, + h int, + i int, + index(d), + key(h), + foreign key (g) references t1 (h) +) engine=innodb with system versioning; +set system_versioning_alter_history= keep; +alter table t1 drop column i; +insert into t1 (g,h) values (1,1); +# cleanup +drop table t1; + +--echo # +--echo # MDEV-29034 Assertion (o->ind == vers_start) upon inplace ALTER with virtual columns +--echo # +create table b ( + pk integer auto_increment, + col_int_key integer, + col_varchar_key varchar(1), + o bit, n bit, + h float as ( n + 2 ) virtual, + v bit, + primary key (pk), + key (col_varchar_key, col_int_key) +) engine = innodb; +set `system_versioning_alter_history`= keep; +alter table `b` add system versioning; +alter table `b` add column if not exists ( w bit, v serial ); +alter table `b` add column if not exists ( p bit ); +drop table `b`; + +--echo # +--echo # End of 10.4 tests +--echo # --echo # --echo # MDEV-21941 RENAME doesn't work for system time or period fields @@ -702,4 +767,6 @@ show create table t1; # cleanup drop table t1; +--echo # --echo # End of 10.5 tests +--echo # diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test index 9142a8fae8a..5603d1a3a12 100644 --- a/mysql-test/suite/versioning/t/select.test +++ b/mysql-test/suite/versioning/t/select.test @@ -314,7 +314,7 @@ select * from t1 where (a, 2) in ((1, 1), (2, 2)) and b = 1; --echo ### Issue #398, NOW is now non-magic create or replace table t1 (x int) with system versioning; select * from t1 for system_time as of current_timestamp; ---error ER_BAD_FIELD_ERROR +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION select * from t1 for system_time as of now; --echo ### Issue #405, NATURAL JOIN failure @@ -487,4 +487,14 @@ call verify_trt_dummy(34); SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; +--echo # +--echo # MDEV-32082 Server crash in find_field_in_table +--echo # +create table t0 (c0 int) with system versioning; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +select x0 from ( + select c0 x0 from t0 +) for system_time as of nowasdf deriv; +drop table t0; + -- source suite/versioning/common_finish.inc diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 9127bb1f962..54a8b60f73d 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -684,6 +684,16 @@ fun:_ZN7ODBConn10GetDriversEP7_qryres } +{ + ConnectSE: unixODBC SQLAllocEnv leaves some "still reachable" pointers + Memcheck:Leak + fun:malloc + fun:strdup + ... + obj:*/libodbc.so* + fun:_ZN7ODBConn12AllocConnectEj +} + { ConnectSE: unixODBC SQLAllocEnv leaves some "still reachable" pointers Memcheck:Leak @@ -693,6 +703,15 @@ fun:_ZN7ODBConn10GetDriversEP7_qryres } +{ + ConnectSE: unixODBC SQLAllocEnv leaves some "still reachable" pointers + Memcheck:Leak + fun:calloc + ... + obj:*/libodbc.so* + fun:_ZN7ODBConn12AllocConnectEj +} + { ConnectSE: unixODBC SQLAllocEnv leavs some "still reachable" pointers Memcheck:Leak diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index e0efd53040e..e81509c9efc 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -23,14 +23,12 @@ #undef EXTRA_DEBUG #define EXTRA_DEBUG -#ifndef DBUG_OFF -/* Put a protected barrier after every element when using multi_alloc_root() */ -#define ALLOC_BARRIER -#endif +#define ROOT_FLAG_THREAD_SPECIFIC 1 +#define ROOT_FLAG_READ_ONLY 4 /* data packed in MEM_ROOT -> min_malloc */ -#define MALLOC_FLAG(A) ((A & 1) ? MY_THREAD_SPECIFIC : 0) +#define MALLOC_FLAG(root) (((root)->flags & ROOT_FLAG_THREAD_SPECIFIC) ? MY_THREAD_SPECIFIC : 0) #define TRASH_MEM(X) TRASH_FREE(((char*)(X) + ((X)->size-(X)->left)), (X)->left) @@ -55,9 +53,6 @@ Although error can happen during execution of this function if pre_alloc_size is non-0 it won't be reported. Instead it will be reported as error in first alloc_root() on this memory root. - - We don't want to change the structure size for MEM_ROOT. - Because of this, we store in MY_THREAD_SPECIFIC as bit 1 in block_size */ void init_alloc_root(PSI_memory_key key, MEM_ROOT *mem_root, size_t block_size, @@ -69,17 +64,15 @@ void init_alloc_root(PSI_memory_key key, MEM_ROOT *mem_root, size_t block_size, mem_root->free= mem_root->used= mem_root->pre_alloc= 0; mem_root->min_malloc= 32; - mem_root->block_size= (block_size - ALLOC_ROOT_MIN_BLOCK_SIZE) & ~1; + mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; + mem_root->flags= 0; if (my_flags & MY_THREAD_SPECIFIC) - mem_root->block_size|= 1; + mem_root->flags|= ROOT_FLAG_THREAD_SPECIFIC; mem_root->error_handler= 0; mem_root->block_num= 4; /* We shift this with >>2 */ mem_root->first_block_usage= 0; mem_root->m_psi_key= key; -#ifdef PROTECT_STATEMENT_MEMROOT - mem_root->read_only= 0; -#endif #if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) if (pre_alloc_size) @@ -88,7 +81,7 @@ void init_alloc_root(PSI_memory_key key, MEM_ROOT *mem_root, size_t block_size, if ((mem_root->free= mem_root->pre_alloc= (USED_MEM*) my_malloc(key, size, MYF(my_flags)))) { - mem_root->free->size= size; + mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM)); mem_root->free->left= pre_alloc_size; mem_root->free->next= 0; TRASH_MEM(mem_root->free); @@ -121,8 +114,7 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, DBUG_ENTER("reset_root_defaults"); DBUG_ASSERT(alloc_root_inited(mem_root)); - mem_root->block_size= (((block_size - ALLOC_ROOT_MIN_BLOCK_SIZE) & ~1) | - (mem_root->block_size & 1)); + mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; #if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) if (pre_alloc_size) { @@ -154,8 +146,7 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, } /* Allocate new prealloc block and add it to the end of free list */ if ((mem= (USED_MEM *) my_malloc(mem_root->m_psi_key, size, - MYF(MALLOC_FLAG(mem_root-> - block_size))))) + MYF(MALLOC_FLAG(mem_root))))) { mem->size= size; mem->left= pre_alloc_size; @@ -197,7 +188,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) length+=ALIGN_SIZE(sizeof(USED_MEM)); if (!(next = (USED_MEM*) my_malloc(mem_root->m_psi_key, length, MYF(MY_WME | ME_FATAL | - MALLOC_FLAG(mem_root->block_size))))) + MALLOC_FLAG(mem_root))))) { if (mem_root->error_handler) (*mem_root->error_handler)(); @@ -218,10 +209,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) DBUG_ENTER("alloc_root"); DBUG_PRINT("enter",("root: %p", mem_root)); DBUG_ASSERT(alloc_root_inited(mem_root)); - -#ifdef PROTECT_STATEMENT_MEMROOT - DBUG_ASSERT(mem_root->read_only == 0); -#endif + DBUG_ASSERT((mem_root->flags & ROOT_FLAG_READ_ONLY) == 0); DBUG_EXECUTE_IF("simulate_out_of_memory", { @@ -249,14 +237,13 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) } if (! next) { /* Time to alloc new block */ - block_size= (mem_root->block_size & ~1) * (mem_root->block_num >> 2); + block_size= mem_root->block_size * (mem_root->block_num >> 2); get_size= length+ALIGN_SIZE(sizeof(USED_MEM)); get_size= MY_MAX(get_size, block_size); if (!(next = (USED_MEM*) my_malloc(mem_root->m_psi_key, get_size, MYF(MY_WME | ME_FATAL | - MALLOC_FLAG(mem_root-> - block_size))))) + MALLOC_FLAG(mem_root))))) { if (mem_root->error_handler) (*mem_root->error_handler)(); @@ -323,7 +310,7 @@ void *multi_alloc_root(MEM_ROOT *root, ...) { length= va_arg(args, uint); tot_length+= ALIGN_SIZE(length); -#ifdef ALLOC_BARRIER +#ifndef DBUG_OFF tot_length+= ALIGN_SIZE(1); #endif } @@ -339,7 +326,7 @@ void *multi_alloc_root(MEM_ROOT *root, ...) *ptr= res; length= va_arg(args, uint); res+= ALIGN_SIZE(length); -#ifdef ALLOC_BARRIER +#ifndef DBUG_OFF TRASH_FREE(res, ALIGN_SIZE(1)); res+= ALIGN_SIZE(1); #endif @@ -472,6 +459,28 @@ void set_prealloc_root(MEM_ROOT *root, char *ptr) } } +/* + Move allocated objects from one root to another. + + Notes: + We do not increase 'to->block_num' here as the variable isused to + increase block sizes in case of many allocations. This is special + case where this is not needed to take into account +*/ + +void move_root(MEM_ROOT *to, MEM_ROOT *from) +{ + USED_MEM *block, *next; + for (block= from->used; block ; block= next) + { + next= block->next; + block->next= to->used; + to->used= block; + } + from->used= 0; +} + + char *strdup_root(MEM_ROOT *root, const char *str) { diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index edfe3b18479..2fc34a9231b 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -70,7 +70,7 @@ struct st_irem uint32 marker; /* Underrun marker value */ }; -static int sf_malloc_count= 0; /* Number of allocated chunks */ +static uint sf_malloc_count= 0; /* Number of allocated chunks */ static void *sf_min_adress= (void*) (intptr)~0ULL, *sf_max_adress= 0; @@ -362,7 +362,7 @@ int sf_sanity() { struct st_irem *irem; int flag= 0; - int count= 0; + uint count= 0; pthread_mutex_lock(&sf_mutex); count= sf_malloc_count; @@ -387,6 +387,7 @@ void sf_report_leaked_memory(my_thread_id id) { size_t total= 0; struct st_irem *irem; + uint first= 0, chunks= 0; sf_sanity(); @@ -398,15 +399,18 @@ void sf_report_leaked_memory(my_thread_id id) { my_thread_id tid = irem->thread_id && irem->flags & MY_THREAD_SPECIFIC ? irem->thread_id : 0; + if (!first++) + fprintf(stderr, "Memory report from safemalloc\n"); fprintf(stderr, "Warning: %4lu bytes lost at %p, allocated by T@%llu at ", (ulong) irem->datasize, (char*) (irem + 1), tid); print_stack(irem->frame); total+= irem->datasize; + chunks++; } } if (total) - fprintf(stderr, "Memory lost: %lu bytes in %d chunks\n", - (ulong) total, sf_malloc_count); + fprintf(stderr, "Memory lost: %lu bytes in %u chunks of %u total chunks\n", + (ulong) total, chunks, sf_malloc_count); return; } diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index d232b3b5c65..cce5042443c 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -21,9 +21,9 @@ #include #include #include +#include #include #include "auth_pam_tool.h" -#include #ifndef DBUG_OFF static char pam_debug = 0; diff --git a/plugin/disks/CMakeLists.txt b/plugin/disks/CMakeLists.txt index 4e40842cad0..e4cf0dc1de3 100644 --- a/plugin/disks/CMakeLists.txt +++ b/plugin/disks/CMakeLists.txt @@ -4,7 +4,6 @@ CHECK_SYMBOL_EXISTS (getmntent "mntent.h" HAVE_GETMNTENT) CHECK_SYMBOL_EXISTS (getmntent "sys/mnttab.h" HAVE_GETMNTENT_IN_SYS_MNTAB) CHECK_SYMBOL_EXISTS (setmntent "mntent.h" HAVE_SETMNTENT) CHECK_SYMBOL_EXISTS (getmntinfo "sys/types.h;sys/mount.h" HAVE_GETMNTINFO) -CHECK_SYMBOL_EXISTS (getmntinfo64 "sys/types.h;sys/mount.h" HAVE_GETMNTINFO64) IF (HAVE_GETMNTINFO) CHECK_CXX_SOURCE_COMPILES(" @@ -18,7 +17,7 @@ int main() " HAVE_GETMNTINFO_TAKES_statvfs) ENDIF() IF (HAVE_GETMNTENT OR HAVE_GETMNTENT_IN_SYS_MNTAB OR - HAVE_GETMNTINFO OR HAVE_GETMNTINFO64) + HAVE_GETMNTINFO) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) MYSQL_ADD_PLUGIN(DISKS information_schema_disks.cc MODULE_ONLY RECOMPILE_FOR_EMBEDDED) ENDIF() diff --git a/plugin/disks/information_schema_disks.cc b/plugin/disks/information_schema_disks.cc index 15e26dad12a..18195b91044 100644 --- a/plugin/disks/information_schema_disks.cc +++ b/plugin/disks/information_schema_disks.cc @@ -37,8 +37,7 @@ This intends to support *BSD's, macOS, Solaris, AIX, HP-UX, and Linux. specificly: - FreeBSD/OpenBSD/DragonFly (statfs) NetBSD (statvfs) uses getmntinfo(). - macOS uses getmntinfo64(). + FreeBSD/OpenBSD/DragonFly/macOS (statfs) NetBSD (statvfs) uses getmntinfo(). Linux can use getmntent_r(), but we've just used getmntent for simplification. Linux/Solaris/AIX/HP-UX uses setmntent()/getmntent(). Solaris uses getmntent() with a diffent prototype, return structure, and @@ -46,8 +45,6 @@ */ #if defined(HAVE_GETMNTINFO_TAKES_statvfs) || defined(HAVE_GETMNTENT) typedef struct statvfs st_info; -#elif defined(HAVE_GETMNTINFO64) -typedef struct statfs64 st_info; #else // GETMNTINFO typedef struct statfs st_info; #endif @@ -150,8 +147,6 @@ static int disks_fill_table(THD* pThd, TABLE_LIST* pTables, Item* pCond) #if defined(HAVE_GETMNTINFO_TAKES_statvfs) count= getmntinfo(&s, ST_WAIT); -#elif defined(HAVE_GETMNTINFO64) - count= getmntinfo64(&s, MNT_WAIT); #else count= getmntinfo(&s, MNT_WAIT); #endif diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index 1aac71b132a..6c6aeb318c6 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -96,8 +96,8 @@ static int prepare_for_fill(TABLE_LIST *tables) thd->mysys_var->current_cond= &sleep_condition; thd->mysys_var->current_mutex= &sleep_mutex; + thd->mark_connection_idle(); thd->proc_info="feedback"; - thd->set_command(COM_SLEEP); thd->system_thread= SYSTEM_THREAD_EVENT_WORKER; // whatever thd->set_time(); thd->init_for_queries(); diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 52af6206cb2..3c94df243d0 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -1153,7 +1153,6 @@ static void setup_connection_simple(struct connection_info *ci) #define MAX_HOSTNAME (HOSTNAME_LENGTH + 1) /* len+1 in mysql.user */ -#define USERNAME_LENGTH 384 static void setup_connection_connect(MYSQL_THD thd,struct connection_info *cn, const struct mysql_event_connection *event) diff --git a/plugin/test_sql_service/CMakeLists.txt b/plugin/test_sql_service/CMakeLists.txt index aa9ecfe685e..b40e2575db5 100644 --- a/plugin/test_sql_service/CMakeLists.txt +++ b/plugin/test_sql_service/CMakeLists.txt @@ -15,4 +15,4 @@ SET(SOURCES test_sql_service.c) -MYSQL_ADD_PLUGIN(test_sql_service ${SOURCES} MODULE_ONLY RECOMPILE_FOR_EMBEDDED) +MYSQL_ADD_PLUGIN(test_sql_service ${SOURCES} MODULE_ONLY COMPONENT Test) diff --git a/plugin/test_sql_service/test_sql_service.c b/plugin/test_sql_service/test_sql_service.c index 062f10fce58..4ea6533af84 100644 --- a/plugin/test_sql_service/test_sql_service.c +++ b/plugin/test_sql_service/test_sql_service.c @@ -14,71 +14,108 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ -#define PLUGIN_VERSION 0x100 -#define PLUGIN_STR_VERSION "1.0.0" +#define PLUGIN_VERSION 0x200 -#define _my_thread_var loc_thread_var - -#include -#include -#include -#include -#include -//#include /* for enum enum_server_command */ -#include #include -//#include - - -LEX_STRING * thd_query_string (MYSQL_THD thd); -unsigned long long thd_query_id(const MYSQL_THD thd); -size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen); -const char *thd_user_name(MYSQL_THD thd); -const char *thd_client_host(MYSQL_THD thd); -const char *thd_client_ip(MYSQL_THD thd); -LEX_CSTRING *thd_current_db(MYSQL_THD thd); -int thd_current_status(MYSQL_THD thd); -enum enum_server_command thd_current_command(MYSQL_THD thd); - -int maria_compare_hostname(const char *wild_host, long wild_ip, long ip_mask, - const char *host, const char *ip); -void maria_update_hostname(const char **wild_host, long *wild_ip, long *ip_mask, - const char *host); +#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1)) /* Status variables for SHOW STATUS */ static long test_passed= 0; +static char *sql_text_local, *sql_text_global; +static char qwe_res[1024]= ""; + static struct st_mysql_show_var test_sql_status[]= { {"test_sql_service_passed", (char *)&test_passed, SHOW_LONG}, + {"test_sql_query_result", qwe_res, SHOW_CHAR}, {0,0,0} }; -static my_bool do_test= TRUE; -static void run_test(MYSQL_THD thd, struct st_mysql_sys_var *var, - void *var_ptr, const void *save); -static MYSQL_SYSVAR_BOOL(run_test, do_test, PLUGIN_VAR_OPCMDARG, - "Perform the test now.", NULL, run_test, FALSE); +static my_bool do_test= 1; +static int run_test(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save, + struct st_mysql_value *value); +static int run_sql_local(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save, + struct st_mysql_value *value); +static int run_sql_global(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save, + struct st_mysql_value *value); + +static void noop_update(MYSQL_THD thd, struct st_mysql_sys_var *var, + void *var_ptr, const void *save); + +static MYSQL_SYSVAR_BOOL(run_test, do_test, + PLUGIN_VAR_OPCMDARG, + "Perform the test now.", + run_test, NULL, 0); + +static MYSQL_SYSVAR_STR(execute_sql_local, sql_text_local, + PLUGIN_VAR_OPCMDARG, + "Create the new local connection, execute SQL statement with it.", + run_sql_local, noop_update, 0); + +static MYSQL_SYSVAR_STR(execute_sql_global, sql_text_global, + PLUGIN_VAR_OPCMDARG, + "Execute SQL statement using the global connection.", + run_sql_global, noop_update, 0); + static struct st_mysql_sys_var* test_sql_vars[]= { MYSQL_SYSVAR(run_test), + MYSQL_SYSVAR(execute_sql_local), + MYSQL_SYSVAR(execute_sql_global), NULL }; +static MYSQL *global_mysql; -extern int execute_sql_command(const char *command, - char *hosts, char *names, char *filters); +static int run_queries(MYSQL *mysql) +{ + MYSQL_RES *res; + + if (mysql_real_query(mysql, + STRING_WITH_LEN("CREATE TABLE test.ts_table" + " ( hash varbinary(512)," + " time timestamp default current_time," + " primary key (hash), index tm (time) )"))) + return 1; + + if (mysql_real_query(mysql, + STRING_WITH_LEN("INSERT INTO test.ts_table VALUES('1234567890', NULL)"))) + return 1; + + if (mysql_real_query(mysql, STRING_WITH_LEN("select * from test.ts_table"))) + return 1; + + if (!(res= mysql_store_result(mysql))) + return 1; + + mysql_free_result(res); + + if (mysql_real_query(mysql, STRING_WITH_LEN("DROP TABLE test.ts_table"))) + return 1; + + return 0; +} static int do_tests() { - char plugins[1024]; - char names[1024]; - char dl[2048]; - int result; + MYSQL *mysql; + int result= 1; - result= execute_sql_command("select 'plugin', name, dl from mysql.plugin", - plugins, names, dl); + mysql= mysql_init(NULL); + if (mysql_real_connect_local(mysql) == NULL) + return 1; + + if (run_queries(mysql)) + goto exit; + + if (run_queries(global_mysql)) + goto exit; + + result= 0; +exit: + mysql_close(mysql); return result; } @@ -89,29 +126,117 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) } -static void run_test(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), - const void *save __attribute__((unused))) +static int run_test(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save, + struct st_mysql_value *value) { - test_passed= do_tests(); + return (test_passed= (do_tests() == 0)) == 0; +} + + +static int run_sql(MYSQL *mysql, void *save, struct st_mysql_value *value) +{ + const char *str; + int len= 0; + MYSQL_RES *res; + + str= value->val_str(value, NULL, &len); + + if (mysql_real_query(mysql, str, len)) + { + if (mysql_error(mysql)[0]) + { + my_snprintf(qwe_res, sizeof(qwe_res), "Error %d returned. %s", + mysql_errno(mysql), mysql_error(mysql)); + return 0; + } + + return 1; + } + + if ((res= mysql_store_result(mysql))) + { + my_snprintf(qwe_res, sizeof(qwe_res), "Query returned %lld rows.", + mysql_num_rows(res)); + mysql_free_result(res); + } + else + { + if (mysql_error(mysql)[0]) + { + my_snprintf(qwe_res, sizeof(qwe_res), "Error %d returned. %s", + mysql_errno(mysql), mysql_error(mysql)); + } + else + my_snprintf(qwe_res, sizeof(qwe_res), "Query affected %lld rows.", + mysql_affected_rows(mysql)); + } + + return 0; +} + + +static void noop_update(MYSQL_THD thd, struct st_mysql_sys_var *var, + void *var_ptr, const void *save) +{ + sql_text_local= sql_text_global= qwe_res; +} + +static int run_sql_local(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save, + struct st_mysql_value *value) +{ + MYSQL *mysql; + int result= 1; + + mysql= mysql_init(NULL); + if (mysql_real_connect_local(mysql) == NULL) + return 1; + + if (run_sql(mysql, save, value)) + goto exit; + + result= 0; + +exit: + mysql_close(mysql); + + return result; +} + + +static int run_sql_global(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save, + struct st_mysql_value *value) +{ + return run_sql(global_mysql, save, value); } static int init_done= 0; -static int test_sql_service_plugin_init(void *p __attribute__((unused))) +static int test_sql_service_plugin_init(void *p) { + (void) p; + global_mysql= mysql_init(NULL); + + if (!global_mysql || + mysql_real_connect_local(global_mysql) == NULL) + return 1; + init_done= 1; + + test_passed= (do_tests() == 0); + return 0; } -static int test_sql_service_plugin_deinit(void *p __attribute__((unused))) +static int test_sql_service_plugin_deinit(void *p) { + (void) p; if (!init_done) return 0; + mysql_close(global_mysql); + return 0; } @@ -138,7 +263,7 @@ maria_declare_plugin(test_sql_service) PLUGIN_VERSION, test_sql_status, test_sql_vars, - PLUGIN_STR_VERSION, + NULL, MariaDB_PLUGIN_MATURITY_STABLE } maria_declare_plugin_end; diff --git a/plugin/type_mysql_json/type.cc b/plugin/type_mysql_json/type.cc index 9cb69c8aa28..57f252564c3 100644 --- a/plugin/type_mysql_json/type.cc +++ b/plugin/type_mysql_json/type.cc @@ -14,8 +14,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ -#include #include +#include #include #include #include diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 93f9270e790..3dc7c0e3b69 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -102,6 +102,7 @@ if [ -z "$BACKUP_BIN" ]; then fi DATA="$WSREP_SST_OPT_DATA" + INFO_FILE='xtrabackup_galera_info' IST_FILE='xtrabackup_ist' MAGIC_FILE="$DATA/$INFO_FILE" @@ -1042,6 +1043,23 @@ setup_commands() INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF --backup$disver${iopts:+ }$iopts$tmpopts$INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA'$mysqld_args $INNOBACKUP" } +send_magic() +{ + # Store donor's wsrep GTID (state ID) and wsrep_gtid_domain_id + # (separated by a space). + echo "$WSREP_SST_OPT_GTID $WSREP_SST_OPT_GTID_DOMAIN_ID" > "$MAGIC_FILE" + + if [ -n "$WSREP_SST_OPT_REMOTE_PSWD" ]; then + # Let joiner know that we know its secret + echo "$SECRET_TAG $WSREP_SST_OPT_REMOTE_PSWD" >> "$MAGIC_FILE" + fi + + if [ $WSREP_SST_OPT_BYPASS -eq 0 -a $WSREP_SST_OPT_PROGRESS -eq 1 ]; then + # Tell joiner what to expect: + echo "$TOTAL_TAG $payload" >> "$MAGIC_FILE" + fi +} + get_stream get_transfer @@ -1099,20 +1117,7 @@ if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]; then fi wsrep_log_info "Streaming GTID file before SST" - - # Store donor's wsrep GTID (state ID) and wsrep_gtid_domain_id - # (separated by a space). - echo "$WSREP_SST_OPT_GTID $WSREP_SST_OPT_GTID_DOMAIN_ID" > "$MAGIC_FILE" - - if [ -n "$WSREP_SST_OPT_REMOTE_PSWD" ]; then - # Let joiner know that we know its secret - echo "$SECRET_TAG $WSREP_SST_OPT_REMOTE_PSWD" >> "$MAGIC_FILE" - fi - - if [ $WSREP_SST_OPT_PROGRESS -eq 1 ]; then - # Tell joiner what to expect: - echo "$TOTAL_TAG $payload" >> "$MAGIC_FILE" - fi + send_magic ttcmd="$tcmd" @@ -1202,9 +1207,8 @@ if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]; then wsrep_log_info "Bypassing the SST for IST" echo "continue" # now server can resume updating data - # Store donor's wsrep GTID (state ID) and wsrep_gtid_domain_id - # (separated by a space). - echo "$WSREP_SST_OPT_GTID $WSREP_SST_OPT_GTID_DOMAIN_ID" > "$MAGIC_FILE" + send_magic + echo "1" > "$DATA/$IST_FILE" if [ -n "$scomp" ]; then @@ -1310,7 +1314,7 @@ else # joiner impts="--parallel=$backup_threads${impts:+ }$impts" fi - SST_PID="$WSREP_SST_OPT_DATA/wsrep_sst.pid" + SST_PID="$DATA/wsrep_sst.pid" # give some time for previous SST to complete: check_round=0 @@ -1451,8 +1455,8 @@ else # joiner TDATA="$DATA" DATA="$DATA/.sst" - MAGIC_FILE="$DATA/$INFO_FILE" + wsrep_log_info "Waiting for SST streaming to complete!" monitor_process $jpid diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 3e63596bcbe..ade9bb491e5 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -149,10 +149,12 @@ check_pid_and_port() check_pid "$pid_file" && [ $CHECK_PID -eq $pid ] } -STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf" -STUNNEL_PID="$WSREP_SST_OPT_DATA/stunnel.pid" +DATA="$WSREP_SST_OPT_DATA" -MAGIC_FILE="$WSREP_SST_OPT_DATA/rsync_sst_complete" +STUNNEL_CONF="$DATA/stunnel.conf" +STUNNEL_PID="$DATA/stunnel.pid" + +MAGIC_FILE="$DATA/rsync_sst_complete" get_binlog @@ -163,7 +165,6 @@ fi OLD_PWD="$(pwd)" -DATA="$WSREP_SST_OPT_DATA" if [ -n "$DATA" -a "$DATA" != '.' ]; then [ ! -d "$DATA" ] && mkdir -p "$DATA" cd "$DATA" @@ -347,7 +348,7 @@ fi readonly SECRET_TAG='secret' readonly BYPASS_TAG='bypass' -SST_PID="$WSREP_SST_OPT_DATA/wsrep_sst.pid" +SST_PID="$DATA/wsrep_sst.pid" # give some time for previous SST to complete: check_round=0 @@ -379,8 +380,8 @@ done MODULE="${WSREP_SST_OPT_MODULE:-rsync_sst}" -RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid" -RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf" +RSYNC_PID="$DATA/$MODULE.pid" +RSYNC_CONF="$DATA/$MODULE.conf" # give some time for rsync from the previous SST to complete: check_round=0 @@ -422,8 +423,8 @@ EOF if [ $WSREP_SST_OPT_BYPASS -eq 0 ]; then - FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed" - ERROR="$WSREP_SST_OPT_DATA/sst_error" + FLUSHED="$DATA/tables_flushed" + ERROR="$DATA/sst_error" [ -f "$FLUSHED" ] && rm -f "$FLUSHED" [ -f "$ERROR" ] && rm -f "$ERROR" @@ -580,7 +581,7 @@ FILTER="-f '- /lost+found' eval rsync ${STUNNEL:+"--rsh='$STUNNEL'"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ - $WHOLE_FILE_OPT $FILTER "'$WSREP_SST_OPT_DATA/'" \ + $WHOLE_FILE_OPT $FILTER "'$DATA/'" \ "'rsync://$WSREP_SST_OPT_ADDR'" >&2 || RC=$? if [ $RC -ne 0 ]; then @@ -688,7 +689,7 @@ FILTER="-f '- /lost+found' -f '- $ib_log_dir/ib_logfile[0-9]*' \ -f '- $ar_log_dir/aria_log_control' \ -f '- $ar_log_dir/aria_log.*' \ - "$WSREP_SST_OPT_DATA/{}/" \ + "$DATA/{}/" \ "rsync://$WSREP_SST_OPT_ADDR/{}" >&2 || RC=$? cd "$OLD_PWD" @@ -770,7 +771,7 @@ read only = no timeout = 300 $SILENT [$MODULE] - path = $WSREP_SST_OPT_DATA + path = $DATA exclude = .zfs [$MODULE-log_dir] path = $ib_log_dir diff --git a/sql-common/client.c b/sql-common/client.c index 5bf751c22ec..0adaa00a0c4 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1712,14 +1712,14 @@ static MYSQL_METHODS client_methods= cli_use_result, /* use_result */ cli_fetch_lengths, /* fetch_lengths */ cli_flush_use_result, /* flush_use_result */ - cli_read_change_user_result /* read_change_user_result */ + cli_read_change_user_result, /* read_change_user_result */ + NULL /* on_close_free */ #ifndef MYSQL_SERVER ,cli_list_fields, /* list_fields */ cli_read_prepare_result, /* read_prepare_result */ cli_stmt_execute, /* stmt_execute */ cli_read_binary_rows, /* read_binary_rows */ cli_unbuffered_fetch, /* unbuffered_fetch */ - NULL, /* free_embedded_thd */ cli_read_statistics, /* read_statistics */ cli_read_query_result, /* next_result */ cli_read_binary_rows /* read_rows_from_cursor */ @@ -3321,10 +3321,8 @@ static void mysql_close_free(MYSQL *mysql) my_free(mysql->user); my_free(mysql->passwd); my_free(mysql->db); -#if defined(EMBEDDED_LIBRARY) || MYSQL_VERSION_ID >= 50100 - my_free(mysql->info_buffer); - mysql->info_buffer= 0; -#endif + if (mysql->methods && mysql->methods->on_close_free) + (*mysql->methods->on_close_free)(mysql); /* Clear pointers for better safety */ mysql->host_info= mysql->user= mysql->passwd= mysql->db= 0; } @@ -3443,13 +3441,6 @@ void STDCALL mysql_close(MYSQL *mysql) mysql_close_free_options(mysql); mysql_close_free(mysql); mysql_detach_stmt_list(&mysql->stmts, "mysql_close"); -#ifndef MYSQL_SERVER - if (mysql->thd) - { - (*mysql->methods->free_embedded_thd)(mysql); - mysql->thd= 0; - } -#endif if (mysql->free_me) my_free(mysql); } diff --git a/sql/event_queue.cc b/sql/event_queue.cc index ebd2dfeefd6..7ed4d8c61a1 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -656,7 +656,6 @@ Event_queue::get_top_for_execution_if_time(THD *thd, top->status= Event_parse_data::DISABLED; DBUG_PRINT("info", ("event %s status is %d", top->name.str, top->status)); - top->execution_count++; (*event_name)->dropped= top->dropped; /* Save new values of last_executed timestamp and event status on stack diff --git a/sql/field.h b/sql/field.h index 51fdc8124e6..d5170290c6b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1822,6 +1822,16 @@ public: return flags & (VERS_ROW_START | VERS_ROW_END); } + bool vers_sys_start() const + { + return flags & VERS_ROW_START; + } + + bool vers_sys_end() const + { + return flags & VERS_ROW_END; + } + bool vers_update_unversioned() const { return flags & VERS_UPDATE_UNVERSIONED_FLAG; diff --git a/sql/filesort.h b/sql/filesort.h index ebb521e2adc..8c7931e75e9 100644 --- a/sql/filesort.h +++ b/sql/filesort.h @@ -56,8 +56,11 @@ public: bool using_pq; /* TRUE means sort operation must produce table rowids. - FALSE means that it halso has an option of producing {sort_key, - addon_fields} pairs. + FALSE means that it also has an option of producing {sort_key, addon_fields} + pairs. + + Usually initialized with value of join_tab->keep_current_rowid to allow for + a call to table->file->position() using these table rowids. */ bool sort_positions; /* diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 25bbcfdd75c..e174ef8d219 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4308,6 +4308,7 @@ int ha_partition::external_lock(THD *thd, int lock_type) m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0); if ((error= m_part_info->vers_set_hist_part(thd))) goto err_handler; + need_info_for_auto_inc(); } DBUG_RETURN(0); @@ -4623,33 +4624,8 @@ int ha_partition::write_row(const uchar * buf) */ if (have_auto_increment) { - if (!table_share->next_number_keypart) - if (unlikely(error= update_next_auto_inc_val())) - goto exit; - - /* - If we have failed to set the auto-increment value for this row, - it is highly likely that we will not be able to insert it into - the correct partition. We must check and fail if necessary. - */ if (unlikely(error= update_auto_increment())) goto exit; - - /* - Don't allow generation of auto_increment value the partitions handler. - If a partitions handler would change the value, then it might not - match the partition any longer. - This can occur if 'SET INSERT_ID = 0; INSERT (NULL)', - So allow this by adding 'MODE_NO_AUTO_VALUE_ON_ZERO' to sql_mode. - The partitions handler::next_insert_id must always be 0. Otherwise - we need to forward release_auto_increment, or reset it for all - partitions. - */ - if (table->next_number_field->val_int() == 0) - { - table->auto_increment_field_not_null= TRUE; - thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO; - } } old_map= dbug_tmp_use_all_columns(table, &table->read_set); error= m_part_info->get_partition_id(m_part_info, &part_id, &func_value); @@ -11012,10 +10988,7 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment, else { THD *thd= ha_thd(); - /* - This is initialized in the beginning of the first write_row call. - */ - DBUG_ASSERT(part_share->auto_inc_initialized); + update_next_auto_inc_val(); /* Get a lock for handling the auto_increment in part_share for avoiding two concurrent statements getting the same number. diff --git a/sql/ha_partition.h b/sql/ha_partition.h index d75e38ec272..0ac8f696fcf 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1408,9 +1408,8 @@ private: { ulonglong nr= (((Field_num*) field)->unsigned_flag || field->val_int() > 0) ? field->val_int() : 0; + update_next_auto_inc_val(); lock_auto_increment(); - DBUG_ASSERT(part_share->auto_inc_initialized || - !can_use_for_auto_inc_init()); /* must check when the mutex is taken */ if (nr >= part_share->next_auto_inc_val) part_share->next_auto_inc_val= nr + 1; diff --git a/sql/handler.cc b/sql/handler.cc index 0a167c74aa1..a0bc758c00c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7639,7 +7639,12 @@ int handler::ha_write_row(const uchar *buf) { DBUG_ASSERT(inited == NONE || lookup_handler != this); if ((error= check_duplicate_long_entries(buf))) + { + if (table->next_number_field && buf == table->record[0]) + if (int err= update_auto_increment()) + error= err; DBUG_RETURN(error); + } } MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str); diff --git a/sql/item.cc b/sql/item.cc index 5c3985e6a68..a055e9cea7d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2674,7 +2674,8 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, if (conv->fix_fields_if_needed(thd, arg)) return TRUE; - if (!thd->stmt_arena->is_conventional()) + if (!thd->stmt_arena->is_conventional() && + thd->lex->current_select->first_cond_optimization) { Query_arena *arena, backup; arena= thd->activate_stmt_arena_if_needed(&backup); diff --git a/sql/item.h b/sql/item.h index 2469bbcbfc8..9897a964e9c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -28,6 +28,7 @@ #include "field.h" /* Derivation */ #include "sql_type.h" #include "sql_time.h" +#include "sql_schema.h" #include "mem_root_array.h" #include "cset_narrowing.h" @@ -1957,7 +1958,8 @@ public: QT_ITEM_IDENT_SKIP_DB_NAMES | QT_ITEM_IDENT_SKIP_TABLE_NAMES | QT_NO_DATA_EXPANSION | - QT_TO_SYSTEM_CHARSET), + QT_TO_SYSTEM_CHARSET | + QT_FOR_FRM), LOWEST_PRECEDENCE); } virtual void print(String *str, enum_query_type query_type); @@ -5478,6 +5480,14 @@ public: return true; return (this->*processor)(arg); } + /* + Built-in schema, e.g. mariadb_schema, oracle_schema, maxdb_schema + */ + virtual const Schema *schema() const + { + // A function does not belong to a built-in schema by default + return NULL; + } /* This method is used for debug purposes to print the name of an item to the debug log. The second use of this method is as diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 48215c60768..71043df46af 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -3466,7 +3466,13 @@ void Item_func_case_simple::print(String *str, enum_query_type query_type) void Item_func_decode_oracle::print(String *str, enum_query_type query_type) { - str->append(func_name_cstring()); + if (query_type & QT_FOR_FRM) + { + // 10.3 downgrade compatibility for FRM + str->append(STRING_WITH_LEN("decode_oracle")); + } + else + print_sql_mode_qualified_name(str, query_type); str->append('('); args[0]->print(str, query_type); for (uint i= 1, count= when_count() ; i <= count; i++) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 2e8a28cdd17..bea9fbdbdd2 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -2471,9 +2471,10 @@ public: Item_func_decode_oracle(THD *thd, List &list) :Item_func_case_simple(thd, list) { } + const Schema *schema() const override { return &oracle_schema_ref; } LEX_CSTRING func_name_cstring() const override { - static LEX_CSTRING name= {STRING_WITH_LEN("decode_oracle") }; + static LEX_CSTRING name= {STRING_WITH_LEN("decode") }; return name; } void print(String *str, enum_query_type query_type) override; diff --git a/sql/item_create.cc b/sql/item_create.cc index 73d356cf6e8..794e65a31a6 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -427,9 +427,6 @@ public: virtual Item *create_native(THD *thd, const LEX_CSTRING *name, List *item_list) { - if (thd->variables.sql_mode & MODE_ORACLE) - return Create_func_decode_oracle::s_singleton.create_native(thd, name, - item_list); if (unlikely(!item_list || item_list->elements != 2)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); @@ -1500,9 +1497,7 @@ public: virtual Item *create_native(THD *thd, const LEX_CSTRING *name, List *item_list) { - return thd->variables.sql_mode & MODE_ORACLE ? - create_native_oracle(thd, name, item_list) : - create_native_std(thd, name, item_list); + return create_native_std(thd, name, item_list); } static Create_func_lpad s_singleton; @@ -1899,9 +1894,7 @@ public: virtual Item *create_native(THD *thd, const LEX_CSTRING *name, List *item_list) { - return thd->variables.sql_mode & MODE_ORACLE ? - create_native_oracle(thd, name, item_list) : - create_native_std(thd, name, item_list); + return create_native_std(thd, name, item_list); } static Create_func_rpad s_singleton; @@ -3041,9 +3034,7 @@ Create_func_concat::create_native(THD *thd, const LEX_CSTRING *name, return NULL; } - return thd->variables.sql_mode & MODE_ORACLE ? - new (thd->mem_root) Item_func_concat_operator_oracle(thd, *item_list) : - new (thd->mem_root) Item_func_concat(thd, *item_list); + return new (thd->mem_root) Item_func_concat(thd, *item_list); } Create_func_concat_operator_oracle @@ -4295,10 +4286,7 @@ Create_func_length Create_func_length::s_singleton; Item* Create_func_length::create_1_arg(THD *thd, Item *arg1) { - if (thd->variables.sql_mode & MODE_ORACLE) - return new (thd->mem_root) Item_func_char_length(thd, arg1); - else - return new (thd->mem_root) Item_func_octet_length(thd, arg1); + return new (thd->mem_root) Item_func_octet_length(thd, arg1); } Create_func_octet_length Create_func_octet_length::s_singleton; @@ -4516,7 +4504,7 @@ Create_func_ltrim Create_func_ltrim::s_singleton; Item* Create_func_ltrim::create_1_arg(THD *thd, Item *arg1) { - return Lex_trim(TRIM_LEADING, arg1).make_item_func_trim(thd); + return Lex_trim(TRIM_LEADING, arg1).make_item_func_trim_std(thd); } @@ -5015,7 +5003,7 @@ Create_func_rtrim Create_func_rtrim::s_singleton; Item* Create_func_rtrim::create_1_arg(THD *thd, Item *arg1) { - return Lex_trim(TRIM_TRAILING, arg1).make_item_func_trim(thd); + return Lex_trim(TRIM_TRAILING, arg1).make_item_func_trim_std(thd); } @@ -5750,9 +5738,25 @@ const Native_func_registry func_array[] = Native_func_registry_array native_func_registry_array(func_array, array_elements(func_array)); -const size_t func_array_length= sizeof(func_array) / sizeof(Native_func_registry) - 1; +const Native_func_registry func_array_oracle_overrides[] = +{ + { { STRING_WITH_LEN("CONCAT") }, BUILDER(Create_func_concat_operator_oracle)}, + { { STRING_WITH_LEN("DECODE") }, BUILDER(Create_func_decode_oracle)}, + { { STRING_WITH_LEN("LENGTH") }, BUILDER(Create_func_char_length)}, + { { STRING_WITH_LEN("LPAD") }, BUILDER(Create_func_lpad_oracle)}, + { { STRING_WITH_LEN("LTRIM") }, BUILDER(Create_func_ltrim_oracle)}, + { { STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad_oracle)}, + { { STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim_oracle)}, + { {0, 0}, NULL} +}; + +Native_func_registry_array + oracle_func_registry_array(func_array_oracle_overrides, + array_elements(func_array_oracle_overrides)); Native_functions_hash native_functions_hash; +Native_functions_hash native_functions_hash_oracle; + /* Load the hash table for native functions. @@ -5881,13 +5885,30 @@ int item_create_init() native_func_registry_array_geom.count())) return true; #endif - return false; + + count+= oracle_func_registry_array.count(); + + if (native_functions_hash_oracle.init(count) || + native_functions_hash_oracle.append(native_func_registry_array.elements(), + native_func_registry_array.count())) + return true; + +#ifdef HAVE_SPATIAL + if (native_functions_hash_oracle.append(native_func_registry_array_geom.elements(), + native_func_registry_array_geom.count())) + return true; +#endif + + return + native_functions_hash_oracle.replace(oracle_func_registry_array.elements(), + oracle_func_registry_array.count()); } void item_create_cleanup() { native_functions_hash.cleanup(); + native_functions_hash_oracle.cleanup(); } diff --git a/sql/item_create.h b/sql/item_create.h index 74a052c79fd..25a75a22163 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -324,6 +324,12 @@ public: bool init(size_t count); bool append(const Native_func_registry array[], size_t count); bool remove(const Native_func_registry array[], size_t count); + bool replace(const Native_func_registry array[], size_t count) + { + DBUG_ENTER("Native_functions_hash::replace"); + remove(array, count); + DBUG_RETURN(append(array, count)); + } void cleanup(); /** Find the native function builder associated with a given function name. @@ -335,6 +341,7 @@ public: }; extern MYSQL_PLUGIN_IMPORT Native_functions_hash native_functions_hash; +extern MYSQL_PLUGIN_IMPORT Native_functions_hash native_functions_hash_oracle; extern const Native_func_registry func_array[]; extern const size_t func_array_length; @@ -377,4 +384,3 @@ public: #endif - diff --git a/sql/item_func.cc b/sql/item_func.cc index 6193dc38046..707fac4291e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -131,6 +131,16 @@ Item_args::Item_args(THD *thd, const Item_args *other) } +void Item_func::wrong_param_count_error(const LEX_CSTRING &schema_name, + const LEX_CSTRING &func_name) +{ + DBUG_ASSERT(schema_name.length); + Database_qualified_name qname(schema_name, func_name); + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), + ErrConvDQName(&qname).ptr()); +} + + void Item_func::sync_with_sum_func_and_with_field(List &list) { List_iterator_fast li(list); @@ -618,13 +628,12 @@ table_map Item_func::not_null_tables() const void Item_func::print(String *str, enum_query_type query_type) { str->append(func_name_cstring()); - str->append('('); - print_args(str, 0, query_type); - str->append(')'); + print_args_parenthesized(str, query_type); } -void Item_func::print_args(String *str, uint from, enum_query_type query_type) +void Item_func::print_args(String *str, uint from, + enum_query_type query_type) const { for (uint i=from ; i < arg_count ; i++) { @@ -1808,7 +1817,7 @@ void Item_func_neg::fix_length_and_dec_int() Use val() to get value as arg_type doesn't mean that item is Item_int or Item_float due to existence of Item_param. */ - if (args[0]->const_item()) + if (args[0]->const_item() && !args[0]->is_expensive()) { longlong val= args[0]->val_int(); if ((ulonglong) val >= (ulonglong) LONGLONG_MIN && @@ -2787,8 +2796,17 @@ bool Item_func_rand::fix_fields(THD *thd,Item **ref) No need to send a Rand log event if seed was given eg: RAND(seed), as it will be replicated in the query as such. */ + DBUG_ASSERT((!rand && + (thd->active_stmt_arena_to_use()-> + is_stmt_prepare_or_first_stmt_execute() || + thd->active_stmt_arena_to_use()-> + is_conventional() || + thd->active_stmt_arena_to_use()->state == + Query_arena::STMT_SP_QUERY_ARGUMENTS + ) + ) || rand); if (!rand && !(rand= (struct my_rnd_struct*) - thd->stmt_arena->alloc(sizeof(*rand)))) + thd->active_stmt_arena_to_use()->alloc(sizeof(*rand)))) return TRUE; } else diff --git a/sql/item_func.h b/sql/item_func.h index aa5bbd4bb96..fc921f8d91b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -55,8 +55,40 @@ protected: bool check_argument_types_can_return_date(uint start, uint end) const; bool check_argument_types_can_return_time(uint start, uint end) const; void print_cast_temporal(String *str, enum_query_type query_type); + + void print_schema_qualified_name(String *to, + const LEX_CSTRING &schema_name, + const LEX_CSTRING &function_name) const + { + // e.g. oracle_schema.func() + to->append(schema_name); + to->append('.'); + to->append(function_name); + } + + void print_sql_mode_qualified_name(String *to, + enum_query_type query_type, + const LEX_CSTRING &function_name) const + { + const Schema *func_schema= schema(); + if (!func_schema || func_schema == Schema::find_implied(current_thd)) + to->append(function_name); + else + print_schema_qualified_name(to, func_schema->name(), function_name); + } + + void print_sql_mode_qualified_name(String *to, enum_query_type query_type) + const + { + return print_sql_mode_qualified_name(to, query_type, func_name_cstring()); + } + public: + // Print an error message for a builtin-schema qualified function call + static void wrong_param_count_error(const LEX_CSTRING &schema_name, + const LEX_CSTRING &func_name); + table_map not_null_tables_cache; enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC, @@ -202,9 +234,15 @@ public: List &fields, uint flags) override; void print(String *str, enum_query_type query_type) override; void print_op(String *str, enum_query_type query_type); - void print_args(String *str, uint from, enum_query_type query_type); + void print_args(String *str, uint from, enum_query_type query_type) const; + void print_args_parenthesized(String *str, enum_query_type query_type) const + { + str->append('('); + print_args(str, 0, query_type); + str->append(')'); + } bool is_null() override - { + { update_null_value(); return null_value; } diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 78ac38e95d2..c4157cbf61d 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -825,7 +825,7 @@ static int alloc_tmp_paths(THD *thd, uint n_paths, { if (*tmp_paths == 0) { - MEM_ROOT *root= thd->stmt_arena->mem_root; + MEM_ROOT *root= thd->active_stmt_arena_to_use()->mem_root; *paths= (json_path_with_flags *) alloc_root(root, sizeof(json_path_with_flags) * n_paths); @@ -857,21 +857,47 @@ static void mark_constant_paths(json_path_with_flags *p, } -bool Item_json_str_multipath::fix_fields(THD *thd, Item **ref) -{ - return alloc_tmp_paths(thd, get_n_paths(), &paths, &tmp_paths) || - Item_str_func::fix_fields(thd, ref); -} - - -void Item_json_str_multipath::cleanup() +Item_json_str_multipath::~Item_json_str_multipath() { if (tmp_paths) { - for (uint i= get_n_paths(); i>0; i--) + for (uint i= n_paths; i>0; i--) tmp_paths[i-1].free(); } - Item_str_func::cleanup(); +} + + +bool Item_json_str_multipath::fix_fields(THD *thd, Item **ref) +{ + if (!tmp_paths) + { + /* + Remember the number of paths and allocate required memory on first time + the method fix_fields() is invoked. For prepared statements the method + fix_fields can be called several times for the same item because its + clean up is performed every item a prepared statement finishing its + execution. In result, the data member fixed is reset and the method + fix_field() is invoked on next time the same prepared statement be + executed. On the other side, any memory allocations on behalf of + the prepared statement must be performed only once on its first execution. + The data member tmp_path is kind a guard to do these activities only once + on first time the method fix_field() is called. + */ + n_paths= get_n_paths(); + + if (alloc_tmp_paths(thd, n_paths, &paths, &tmp_paths)) + return true; + } + +#ifdef PROTECT_STATEMENT_MEMROOT + /* + Check that the number of paths remembered on first run of a statement + never changed later. + */ + DBUG_ASSERT(n_paths == get_n_paths()); +#endif + + return Item_str_func::fix_fields(thd, ref); } @@ -1398,10 +1424,19 @@ return_null: bool Item_func_json_contains_path::fix_fields(THD *thd, Item **ref) { - return alloc_tmp_paths(thd, arg_count-2, &paths, &tmp_paths) || - (p_found= (bool *) alloc_root(thd->mem_root, - (arg_count-2)*sizeof(bool))) == NULL || - Item_int_func::fix_fields(thd, ref); + /* + See comments on Item_json_str_multipath::fix_fields regarding + the aim of the condition 'if (!tmp_paths)'. + */ + if (!tmp_paths) + { + if (alloc_tmp_paths(thd, arg_count-2, &paths, &tmp_paths) || + (p_found= (bool *) alloc_root(thd->active_stmt_arena_to_use()->mem_root, + (arg_count-2)*sizeof(bool))) == NULL) + return true; + } + + return Item_int_func::fix_fields(thd, ref); } @@ -1414,8 +1449,7 @@ bool Item_func_json_contains_path::fix_length_and_dec() return Item_bool_func::fix_length_and_dec(); } - -void Item_func_json_contains_path::cleanup() +Item_func_json_contains_path::~Item_func_json_contains_path() { if (tmp_paths) { @@ -1423,7 +1457,6 @@ void Item_func_json_contains_path::cleanup() tmp_paths[i-1].free(); tmp_paths= 0; } - Item_int_func::cleanup(); } diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index 86895a7c247..0611c6f15e5 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -246,11 +246,26 @@ class Item_json_str_multipath: public Item_json_func protected: json_path_with_flags *paths; String *tmp_paths; +private: + /** + Number of paths returned by calling virtual method get_n_paths() and + remembered inside fix_fields(). It is used by the virtual destructor + ~Item_json_str_multipath() to iterate along allocated memory chunks stored + in the array tmp_paths and free every of them. The virtual method + get_n_paths() can't be used for this goal from within virtual destructor. + We could get rid of the virtual method get_n_paths() and store the number + of paths directly in the constructor of classes derived from the class + Item_json_str_multipath but presence of the method get_n_paths() allows + to check invariant that the number of arguments not changed between + sequential runs of the same prepared statement that seems to be useful. + */ + uint n_paths; public: Item_json_str_multipath(THD *thd, List &list): - Item_json_func(thd, list), tmp_paths(0) {} + Item_json_func(thd, list), paths(NULL), tmp_paths(0), n_paths(0) {} + virtual ~Item_json_str_multipath(); + bool fix_fields(THD *thd, Item **ref); - void cleanup(); virtual uint get_n_paths() const = 0; }; @@ -317,6 +332,7 @@ protected: public: Item_func_json_contains_path(THD *thd, List &list): Item_bool_func(thd, list), tmp_paths(0) {} + virtual ~Item_func_json_contains_path(); LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("json_contains_path") }; @@ -324,7 +340,6 @@ public: } bool fix_fields(THD *thd, Item **ref) override; bool fix_length_and_dec() override; - void cleanup() override; longlong val_int() override; Item *get_copy(THD *thd) override { return get_item_copy(thd, this); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 64fa144c413..86c69bd7e8c 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2154,13 +2154,31 @@ bool Item_func_trim::fix_length_and_dec() void Item_func_trim::print(String *str, enum_query_type query_type) { + LEX_CSTRING suffix= {STRING_WITH_LEN("_oracle")}; if (arg_count == 1) { - Item_func::print(str, query_type); + if (query_type & QT_FOR_FRM) + { + // 10.3 downgrade compatibility for FRM + str->append(func_name_cstring()); + if (schema() == &oracle_schema_ref) + str->append(suffix); + } + else + print_sql_mode_qualified_name(str, query_type, func_name_cstring()); + print_args_parenthesized(str, query_type); return; } - str->append(Item_func_trim::func_name_cstring()); - str->append(func_name_ext()); + + if (query_type & QT_FOR_FRM) + { + // 10.3 downgrade compatibility for FRM + str->append(Item_func_trim::func_name_cstring()); + if (schema() == &oracle_schema_ref) + str->append(suffix); + } + else + print_sql_mode_qualified_name(str, query_type, Item_func_trim::func_name_cstring()); str->append('('); str->append(mode_name()); str->append(' '); diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 258c0e26bad..1997670841d 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -288,6 +288,12 @@ protected: public: Item_func_concat(THD *thd, List &list): Item_str_func(thd, list) {} Item_func_concat(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} + const Schema *schema() const override { return &mariadb_schema; } + void print(String *str, enum_query_type query_type) override + { + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); + } String *val_str(String *) override; bool fix_length_and_dec() override; LEX_CSTRING func_name_cstring() const override @@ -314,10 +320,17 @@ public: :Item_func_concat(thd, a, b) { } String *val_str(String *) override; - LEX_CSTRING func_name_cstring() const override + const Schema *schema() const override { return &oracle_schema_ref; } + void print(String *str, enum_query_type query_type) override { - static LEX_CSTRING name= {STRING_WITH_LEN("concat_operator_oracle") }; - return name; + if (query_type & QT_FOR_FRM) + { + // 10.3 downgrade compatibility for FRM + str->append(STRING_WITH_LEN("concat_operator_oracle")); + } + else + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); } Item *get_copy(THD *thd) override { @@ -391,6 +404,12 @@ public: String *val_str(String *to) override { return val_str_internal(to, NULL); }; bool fix_length_and_dec() override; String *val_str_internal(String *str, String *empty_string_for_null); + const Schema *schema() const override { return &mariadb_schema; } + void print(String *str, enum_query_type query_type) override + { + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); + } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("replace") }; @@ -409,10 +428,17 @@ public: Item_func_replace(thd, org, find, replace) {} String *val_str(String *to) override { return val_str_internal(to, &tmp_emtpystr); }; - LEX_CSTRING func_name_cstring() const override + const Schema *schema() const override { return &oracle_schema_ref; } + void print(String *str, enum_query_type query_type) override { - static LEX_CSTRING name= {STRING_WITH_LEN("replace_oracle") }; - return name; + if (query_type & QT_FOR_FRM) + { + // 10.3 downgrade compatibility for FRM + str->append(STRING_WITH_LEN("replace_oracle")); + } + else + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); } Item *get_copy(THD *thd) override { return get_item_copy(thd, this); } @@ -576,8 +602,16 @@ public: Item_func_substr(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} Item_func_substr(THD *thd, Item *a, Item *b, Item *c): Item_str_func(thd, a, b, c) {} + Item_func_substr(THD *thd, List &list) + :Item_str_func(thd, list) {} String *val_str(String *) override; bool fix_length_and_dec() override; + const Schema *schema() const override { return &mariadb_schema; } + void print(String *str, enum_query_type query_type) override + { + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); + } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("substr") }; @@ -599,16 +633,25 @@ public: Item_func_substr(thd, a, b) {} Item_func_substr_oracle(THD *thd, Item *a, Item *b, Item *c): Item_func_substr(thd, a, b, c) {} + Item_func_substr_oracle(THD *thd, List &list) + :Item_func_substr(thd, list) {} bool fix_length_and_dec() override { bool res= Item_func_substr::fix_length_and_dec(); set_maybe_null(); return res; } - LEX_CSTRING func_name_cstring() const override + const Schema *schema() const override { return &oracle_schema_ref; } + void print(String *str, enum_query_type query_type) override { - static LEX_CSTRING name= {STRING_WITH_LEN("substr_oracle") }; - return name; + if (query_type & QT_FOR_FRM) + { + // 10.3 downgrade compatibility for FRM + str->append(STRING_WITH_LEN("substr_oracle")); + } + else + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); } Item *get_copy(THD *thd) override { return get_item_copy(thd, this); } @@ -656,17 +699,13 @@ protected: { return trimmed_value(res, 0, res->length()); } - virtual LEX_CSTRING func_name_ext() const - { - static LEX_CSTRING name_ext= {STRING_WITH_LEN("") }; - return name_ext; - } public: Item_func_trim(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} Item_func_trim(THD *thd, Item *a): Item_str_func(thd, a) {} Sql_mode_dependency value_depends_on_sql_mode() const override; String *val_str(String *) override; bool fix_length_and_dec() override; + const Schema *schema() const override { return &mariadb_schema; } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("trim") }; @@ -684,20 +723,11 @@ class Item_func_trim_oracle :public Item_func_trim protected: String *make_empty_result(String *str) override { null_value= 1; return NULL; } - LEX_CSTRING func_name_ext() const override - { - static LEX_CSTRING name_ext= {STRING_WITH_LEN("_oracle") }; - return name_ext; - } public: Item_func_trim_oracle(THD *thd, Item *a, Item *b): Item_func_trim(thd, a, b) {} Item_func_trim_oracle(THD *thd, Item *a): Item_func_trim(thd, a) {} - LEX_CSTRING func_name_cstring() const override - { - static LEX_CSTRING name= {STRING_WITH_LEN("trim_oracle") }; - return name; - } + const Schema *schema() const override { return &oracle_schema_ref; } bool fix_length_and_dec() override { bool res= Item_func_trim::fix_length_and_dec(); @@ -719,6 +749,7 @@ public: return Item_func::value_depends_on_sql_mode(); } String *val_str(String *) override; + const Schema *schema() const override { return &mariadb_schema; } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("ltrim") }; @@ -736,20 +767,11 @@ class Item_func_ltrim_oracle :public Item_func_ltrim protected: String *make_empty_result(String *str) override { null_value= 1; return NULL; } - LEX_CSTRING func_name_ext() const override - { - static LEX_CSTRING name_ext= {STRING_WITH_LEN("_oracle") }; - return name_ext; - } public: Item_func_ltrim_oracle(THD *thd, Item *a, Item *b): Item_func_ltrim(thd, a, b) {} Item_func_ltrim_oracle(THD *thd, Item *a): Item_func_ltrim(thd, a) {} - LEX_CSTRING func_name_cstring() const override - { - static LEX_CSTRING name= {STRING_WITH_LEN("ltrim_oracle") }; - return name; - } + const Schema *schema() const override { return &oracle_schema_ref; } bool fix_length_and_dec() override { bool res= Item_func_ltrim::fix_length_and_dec(); @@ -767,6 +789,7 @@ public: Item_func_rtrim(THD *thd, Item *a, Item *b): Item_func_trim(thd, a, b) {} Item_func_rtrim(THD *thd, Item *a): Item_func_trim(thd, a) {} String *val_str(String *) override; + const Schema *schema() const override { return &mariadb_schema; } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("rtrim") }; @@ -784,20 +807,11 @@ class Item_func_rtrim_oracle :public Item_func_rtrim protected: String *make_empty_result(String *str) override { null_value= 1; return NULL; } - LEX_CSTRING func_name_ext() const override - { - static LEX_CSTRING name_ext= {STRING_WITH_LEN("_oracle") }; - return name_ext; - } public: Item_func_rtrim_oracle(THD *thd, Item *a, Item *b): Item_func_rtrim(thd, a, b) {} Item_func_rtrim_oracle(THD *thd, Item *a): Item_func_rtrim(thd, a) {} - LEX_CSTRING func_name_cstring() const override - { - static LEX_CSTRING name= {STRING_WITH_LEN("rtrim_oracle") }; - return name; - } + const Schema *schema() const override { return &oracle_schema_ref; } bool fix_length_and_dec() override { bool res= Item_func_rtrim::fix_length_and_dec(); @@ -984,6 +998,12 @@ class Item_func_decode :public Item_func_encode { public: Item_func_decode(THD *thd, Item *a, Item *seed_arg): Item_func_encode(thd, a, seed_arg) {} + const Schema *schema() const override { return &mariadb_schema; } + void print(String *str, enum_query_type query_type) override + { + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); + } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("decode") }; @@ -1354,6 +1374,8 @@ public: Item_str_func(thd, arg1, arg2, arg3) {} Item_func_pad(THD *thd, Item *arg1, Item *arg2): Item_str_func(thd, arg1, arg2) {} + Item_func_pad(THD *thd, List &list): + Item_str_func(thd,list) {} bool fix_length_and_dec() override; }; @@ -1365,7 +1387,15 @@ public: Item_func_pad(thd, arg1, arg2, arg3) {} Item_func_rpad(THD *thd, Item *arg1, Item *arg2): Item_func_pad(thd, arg1, arg2) {} + Item_func_rpad(THD *thd, List &list): + Item_func_pad(thd,list) {} String *val_str(String *) override; + const Schema *schema() const override { return &mariadb_schema; } + void print(String *str, enum_query_type query_type) override + { + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); + } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("rpad") }; @@ -1386,16 +1416,25 @@ public: Item_func_rpad(thd, arg1, arg2, arg3) {} Item_func_rpad_oracle(THD *thd, Item *arg1, Item *arg2): Item_func_rpad(thd, arg1, arg2) {} + Item_func_rpad_oracle(THD *thd, List &list): + Item_func_rpad(thd,list) {} bool fix_length_and_dec() override { bool res= Item_func_rpad::fix_length_and_dec(); set_maybe_null(); return res; } - LEX_CSTRING func_name_cstring() const override + const Schema *schema() const override { return &oracle_schema_ref; } + void print(String *str, enum_query_type query_type) override { - static LEX_CSTRING name= {STRING_WITH_LEN("rpad_oracle") }; - return name; + if (query_type & QT_FOR_FRM) + { + // 10.3 downgrade compatibility for FRM + str->append(STRING_WITH_LEN("rpad_oracle")); + } + else + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); } Item *get_copy(THD *thd) override { return get_item_copy(thd, this); } @@ -1409,7 +1448,15 @@ public: Item_func_pad(thd, arg1, arg2, arg3) {} Item_func_lpad(THD *thd, Item *arg1, Item *arg2): Item_func_pad(thd, arg1, arg2) {} + Item_func_lpad(THD *thd, List &list): + Item_func_pad(thd,list) {} String *val_str(String *) override; + const Schema *schema() const override { return &mariadb_schema; } + void print(String *str, enum_query_type query_type) override + { + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); + } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("lpad") }; @@ -1429,16 +1476,25 @@ public: Item_func_lpad(thd, arg1, arg2, arg3) {} Item_func_lpad_oracle(THD *thd, Item *arg1, Item *arg2): Item_func_lpad(thd, arg1, arg2) {} + Item_func_lpad_oracle(THD *thd, List &list): + Item_func_lpad(thd,list) {} bool fix_length_and_dec() override { bool res= Item_func_lpad::fix_length_and_dec(); set_maybe_null(); return res; } - LEX_CSTRING func_name_cstring() const override + const Schema *schema() const override { return &oracle_schema_ref; } + void print(String *str, enum_query_type query_type) override { - static LEX_CSTRING name= {STRING_WITH_LEN("lpad_oracle") }; - return name; + if (query_type & QT_FOR_FRM) + { + // 10.3 downgrade compatibility for FRM + str->append(STRING_WITH_LEN("lpad_oracle")); + } + else + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); } Item *get_copy(THD *thd) override { return get_item_copy(thd, this); } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 0e351f21b28..cc49d6a3d5d 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -3273,8 +3273,12 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg) if (eqs.at(i).outer_exp-> walk(&Item::find_item_processor, TRUE, upper->item)) break; + DBUG_ASSERT(thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute() || + thd->stmt_arena->is_conventional()); + DBUG_ASSERT(thd->stmt_arena->mem_root == thd->mem_root); if (i == (uint)eqs.elements() && - (in_subs->upper_refs.push_back(upper, thd->stmt_arena->mem_root))) + (in_subs->upper_refs.push_back( + upper, thd->mem_root))) goto out; } } @@ -3981,14 +3985,14 @@ bool subselect_union_engine::fix_length_and_dec(Item_cache **row) if (unit->first_select()->item_list.elements == 1) { - if (set_row(unit->types, row)) + if (set_row(unit->item_list, row)) return TRUE; item->collation.set(row[0]->collation); } else { bool maybe_null_saved= maybe_null; - if (set_row(unit->types, row)) + if (set_row(unit->item_list, row)) return TRUE; maybe_null= maybe_null_saved; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index b3e600824de..e4aeaa5254a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -4284,8 +4284,14 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) char *buf; String *new_separator; - if (!(buf= (char*) thd->stmt_arena->alloc(buflen)) || - !(new_separator= new(thd->stmt_arena->mem_root) + DBUG_ASSERT(thd->active_stmt_arena_to_use()-> + is_stmt_prepare_or_first_sp_execute() || + thd->active_stmt_arena_to_use()-> + is_conventional() || + thd->active_stmt_arena_to_use()->state == + Query_arena::STMT_SP_QUERY_ARGUMENTS); + if (!(buf= (char*) thd->active_stmt_arena_to_use()->alloc(buflen)) || + !(new_separator= new(thd->active_stmt_arena_to_use()->mem_root) String(buf, buflen, collation.collation))) return TRUE; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 6915700f4b0..87c144a89dd 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -3084,6 +3084,13 @@ void Item_char_typecast::print(String *str, enum_query_type query_type) { str->append(STRING_WITH_LEN(" charset ")); str->append(cast_cs->cs_name); + /* + Print the "binary" keyword in cases like: + CAST('str' AS CHAR CHARACTER SET latin1 BINARY) + */ + if ((cast_cs->state & MY_CS_BINSORT) && + Charset(cast_cs).can_have_collate_clause()) + str->append(STRING_WITH_LEN(" binary")); } str->append(')'); } diff --git a/sql/log.cc b/sql/log.cc index e54d4087d46..ae1ac360f9a 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2419,6 +2419,23 @@ bool MYSQL_BIN_LOG::check_write_error(THD *thd) } +/* + Check if there was an error while writing the statement cache. + If the cache content is corrupt due to an error, we should write an incident + event to the binlog rather than write corrupt data to it. +*/ +bool +MYSQL_BIN_LOG::check_cache_error(THD *thd, binlog_cache_data *cache_data) +{ + if (!cache_data) + return false; + if (check_write_error(thd)) + return true; + if (!cache_data->empty() && cache_data->cache_log.error) + return true; + return false; +} + /** @note How do we handle this (unlikely but legal) case: @@ -6163,7 +6180,7 @@ write_err: engines, data is written to table but writing to binary log failed. In these scenarios rollback is not possible. Hence report an incident. */ - if (mysql_bin_log.check_write_error(this) && cache_data && + if (mysql_bin_log.check_cache_error(this, cache_data) && lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) && table->current_lock == F_WRLCK) cache_data->set_incident(); @@ -6295,20 +6312,37 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, /* Write pending event to the cache. */ +#ifndef DBUG_OFF + bool clear_dbug= false; +#endif DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending", - {DBUG_SET("+d,simulate_file_write_error");}); + { + if (my_b_tell(&cache_data->cache_log) > 10000) + { + DBUG_SET("+d,simulate_file_write_error"); + clear_dbug= true; + } + }); if (writer.write(pending)) { set_write_error(thd, is_transactional); - if (check_write_error(thd) && cache_data && + if (check_cache_error(thd, cache_data) && stmt_has_updated_non_trans_table(thd)) cache_data->set_incident(); delete pending; cache_data->set_pending(NULL); DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending", - {DBUG_SET("-d,simulate_file_write_error");}); + { + if (clear_dbug) + DBUG_SET("-d,simulate_file_write_error"); + }); DBUG_RETURN(1); } + DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending", + { + if (clear_dbug) + DBUG_SET("-d,simulate_file_write_error"); + }); delete pending; } @@ -6903,7 +6937,7 @@ err: if (unlikely(error)) { set_write_error(thd, is_trans_cache); - if (check_write_error(thd) && cache_data && + if (check_cache_error(thd, cache_data) && stmt_has_updated_non_trans_table(thd)) cache_data->set_incident(); } @@ -8638,6 +8672,20 @@ MYSQL_BIN_LOG::write_transaction_or_stmt(group_commit_entry *entry, DBUG_ENTER("MYSQL_BIN_LOG::write_transaction_or_stmt"); + /* + An error in the trx_cache will truncate the cache to the last good + statement, it won't leave a lingering error. Assert that this holds. + */ + DBUG_ASSERT(!(entry->using_trx_cache && !mngr->trx_cache.empty() && + mngr->get_binlog_cache_log(TRUE)->error)); + /* + An error in the stmt_cache would be caught on the higher level and result + in an incident event being written over a (possibly corrupt) cache content. + Assert that this holds. + */ + DBUG_ASSERT(!(entry->using_stmt_cache && !mngr->stmt_cache.empty() && + mngr->get_binlog_cache_log(FALSE)->error)); + if (write_gtid_event(entry->thd, is_prepared_xa(entry->thd), entry->using_trx_cache, commit_id, has_xid, entry->ro_1pc)) diff --git a/sql/log.h b/sql/log.h index 7b62a1a5477..e636d1a3027 100644 --- a/sql/log.h +++ b/sql/log.h @@ -824,6 +824,7 @@ public: int write_cache(THD *thd, IO_CACHE *cache); void set_write_error(THD *thd, bool is_transactional); bool check_write_error(THD *thd); + bool check_cache_error(THD *thd, binlog_cache_data *cache_data); void start_union_events(THD *thd, query_id_t query_id_param); void stop_union_events(THD *thd); diff --git a/sql/log_event.cc b/sql/log_event.cc index 15f06861928..5c1ff3d2e68 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -915,7 +915,8 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet, Log_event* Log_event::read_log_event(IO_CACHE* file, const Format_description_log_event *fdle, - my_bool crc_check) + my_bool crc_check, + my_bool print_errors) { DBUG_ENTER("Log_event::read_log_event(IO_CACHE*,Format_description_log_event*...)"); DBUG_ASSERT(fdle != 0); @@ -954,8 +955,12 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, goto err; } + /* + print_errors is false to prevent redundant error messages cluttering up the + log, as it will be printed below (if _our_ print_errors is true) + */ if ((res= read_log_event((uchar*) event.ptr(), event.length(), - &error, fdle, crc_check))) + &error, fdle, crc_check, false))) res->register_temp_buf((uchar*) event.release(), true); err: @@ -966,13 +971,7 @@ err: if (force_opt) DBUG_RETURN(new Unknown_log_event()); #endif - if (event.length() >= OLD_HEADER_LEN) - sql_print_error("Error in Log_event::read_log_event(): '%s'," - " data_len: %lu, event_type: %u", error, - (ulong) uint4korr(&event[EVENT_LEN_OFFSET]), - (uint) (uchar)event[EVENT_TYPE_OFFSET]); - else - sql_print_error("Error in Log_event::read_log_event(): '%s'", error); + /* The SQL slave thread will check if file->error<0 to know if there was an I/O error. Even if there is no "low-level" I/O errors @@ -982,6 +981,19 @@ err: only corrupt the slave's databases. So stop. */ file->error= -1; + +#ifndef MYSQL_CLIENT + if (!print_errors) + DBUG_RETURN(res); +#endif + + if (event.length() >= OLD_HEADER_LEN) + sql_print_error("Error in Log_event::read_log_event(): '%s'," + " data_len: %lu, event_type: %u", error, + (ulong) uint4korr(&event[EVENT_LEN_OFFSET]), + (uint) (uchar)event[EVENT_TYPE_OFFSET]); + else + sql_print_error("Error in Log_event::read_log_event(): '%s'", error); } DBUG_RETURN(res); } @@ -995,7 +1007,8 @@ err: Log_event* Log_event::read_log_event(const uchar *buf, uint event_len, const char **error, const Format_description_log_event *fdle, - my_bool crc_check) + my_bool crc_check, + my_bool print_errors) { Log_event* ev; enum enum_binlog_checksum_alg alg; @@ -1063,7 +1076,8 @@ Log_event* Log_event::read_log_event(const uchar *buf, uint event_len, DBUG_RETURN(NULL); #else *error= ER_THD_OR_DEFAULT(current_thd, ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE); - sql_print_error("%s", *error); + if (print_errors) + sql_print_error("%s", *error); DBUG_RETURN(NULL); #endif } diff --git a/sql/log_event.h b/sql/log_event.h index 5c7229838ed..a3b48f03184 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1328,7 +1328,8 @@ public: static Log_event* read_log_event(IO_CACHE* file, const Format_description_log_event *description_event, - my_bool crc_check); + my_bool crc_check, + my_bool print_errors= 1); /** Reads an event from a binlog or relay log. Used by the dump thread @@ -1472,7 +1473,8 @@ public: static Log_event* read_log_event(const uchar *buf, uint event_len, const char **error, const Format_description_log_event - *description_event, my_bool crc_check); + *description_event, my_bool crc_check, + my_bool print_errors= 1); /** Returns the human readable name of the given event type. */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9e2575511be..bca1e6556e3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1511,6 +1511,16 @@ static void end_ssl(); #ifndef EMBEDDED_LIBRARY +extern Atomic_counter local_connection_thread_count; + +uint THD_count::connection_thd_count() +{ + return value() - + binlog_dump_thread_count - + local_connection_thread_count; +} + + /**************************************************************************** ** Code to end mysqld ****************************************************************************/ @@ -1778,9 +1788,8 @@ static void close_connections(void) */ DBUG_PRINT("info", ("THD_count: %u", THD_count::value())); - for (int i= 0; (THD_count::value() - binlog_dump_thread_count - - n_threads_awaiting_ack) && - i < 1000 && + for (int i= 0; THD_count::connection_thd_count() - n_threads_awaiting_ack + && i < 1000 && DBUG_EVALUATE_IF("only_kill_system_threads_no_loop", 0, 1); i++) my_sleep(20000); @@ -1800,8 +1809,7 @@ static void close_connections(void) THD_count::value() - binlog_dump_thread_count - n_threads_awaiting_ack)); - while ((THD_count::value() - binlog_dump_thread_count - - n_threads_awaiting_ack) && + while (THD_count::connection_thd_count() - n_threads_awaiting_ack && DBUG_EVALUATE_IF("only_kill_system_threads_no_loop", 0, 1)) { my_sleep(1000); @@ -1809,7 +1817,7 @@ static void close_connections(void) /* Kill phase 2 */ server_threads.iterate(kill_thread_phase_2); - for (uint64 i= 0; THD_count::value(); i++) + for (uint64 i= 0; THD_count::value() > local_connection_thread_count; i++) { /* This time the warnings are emitted within the loop to provide a @@ -5102,6 +5110,7 @@ static int init_server_components() init_global_table_stats(); init_global_index_stats(); + init_update_queries(); /* Allow storage engine to give real error messages */ if (unlikely(ha_init_errors())) @@ -5438,7 +5447,6 @@ static int init_server_components() ft_init_stopwords(); init_max_user_conn(); - init_update_queries(); init_global_user_stats(); init_global_client_stats(); if (!opt_bootstrap) diff --git a/sql/mysqld.h b/sql/mysqld.h index 25b99e873e6..638323754d6 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -869,6 +869,11 @@ enum enum_query_type /// good for parsing QT_PARSABLE= (1 << 8), + // If an expression is constant, print the expression, not the value + // it evaluates to. Should be used for error messages, so that they + // don't reveal values. + QT_NO_DATA_EXPANSION= (1 << 9), + /// This value means focus on readability, not on ability to parse back, etc. QT_EXPLAIN= QT_TO_SYSTEM_CHARSET | QT_ITEM_IDENT_SKIP_DB_NAMES | @@ -889,12 +894,12 @@ enum enum_query_type QT_EXPLAIN_EXTENDED= QT_TO_SYSTEM_CHARSET| QT_SHOW_SELECT_NUMBER, - // If an expression is constant, print the expression, not the value - // it evaluates to. Should be used for error messages, so that they - // don't reveal values. - QT_NO_DATA_EXPANSION= (1 << 9), // Remove wrappers added for TVC when creating or showing view QT_NO_WRAPPERS_FOR_TVC_IN_VIEW= (1 << 12), + + /// Print for FRM file. Focus on parse-back. + /// e.g. VIEW expressions and virtual column expressions + QT_FOR_FRM= (1 << 13) }; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 72703a018ad..86eaec3a699 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -15107,13 +15107,6 @@ int QUICK_GROUP_MIN_MAX_SELECT::init() { if (group_prefix) /* Already initialized. */ return 0; - - /* - We allocate one byte more to serve the case when the last field in - the buffer is compared using uint3korr (e.g. a Field_newdate field) - */ - if (!(last_prefix= (uchar*) alloc_root(&alloc, group_prefix_len+1))) - return 1; /* We may use group_prefix to store keys with all select fields, so allocate enough space for it. @@ -15370,8 +15363,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat() QUICK_GROUP_MIN_MAX_SELECT::reset() DESCRIPTION - Initialize the index chosen for access and find and store the prefix - of the last group. The method is expensive since it performs disk access. + Initialize the index chosen for access. RETURN 0 OK @@ -15393,12 +15385,6 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void) } if (quick_prefix_select && quick_prefix_select->reset()) DBUG_RETURN(1); - result= file->ha_index_last(record); - if (result == HA_ERR_END_OF_FILE) - DBUG_RETURN(0); - /* Save the prefix of the last group. */ - key_copy(last_prefix, record, index_info, group_prefix_len); - DBUG_RETURN(0); } @@ -15444,34 +15430,20 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next() #else int result; #endif - int is_last_prefix= 0; - DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::get_next"); /* - Loop until a group is found that satisfies all query conditions or the last - group is reached. + Loop until a group is found that satisfies all query conditions or + there are no satisfying groups left */ do { result= next_prefix(); - /* - Check if this is the last group prefix. Notice that at this point - this->record contains the current prefix in record format. - */ - if (!result) - { - is_last_prefix= key_cmp(index_info->key_part, last_prefix, - group_prefix_len); - DBUG_ASSERT(is_last_prefix <= 0); - } - else - { - if (result == HA_ERR_KEY_NOT_FOUND) - continue; + if (result != 0) break; - } - + /* + At this point this->record contains the current prefix in record format. + */ if (have_min) { min_res= next_min(); @@ -15500,8 +15472,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next() HA_READ_KEY_EXACT); result= have_min ? min_res : have_max ? max_res : result; - } while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) && - is_last_prefix != 0); + } while (result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE); if (result == HA_ERR_KEY_NOT_FOUND) result= HA_ERR_END_OF_FILE; diff --git a/sql/opt_range.h b/sql/opt_range.h index 18b3c33cafa..f6ffde5a6b7 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -1595,7 +1595,6 @@ private: uchar *group_prefix; /* Key prefix consisting of the GROUP fields. */ const uint group_prefix_len; /* Length of the group prefix. */ uint group_key_parts; /* A number of keyparts in the group prefix */ - uchar *last_prefix; /* Prefix of the last group for detecting EOF. */ bool have_min; /* Specify whether we are computing */ bool have_max; /* a MIN, a MAX, or both. */ bool have_agg_distinct;/* aggregate_function(DISTINCT ...). */ diff --git a/sql/protocol.cc b/sql/protocol.cc index a8e451137c8..0131a22b8fb 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -414,7 +414,6 @@ static bool write_eof_packet(THD *thd, NET *net, bool Protocol::net_send_error_packet(THD *thd, uint sql_errno, const char *err, const char* sqlstate) - { NET *net= &thd->net; uint length; diff --git a/sql/protocol.h b/sql/protocol.h index 683bbd69583..17b458dcccf 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -228,9 +228,9 @@ public: #ifdef EMBEDDED_LIBRARY void remove_last_row() override; #endif - virtual bool store_field_metadata(const THD *thd, const Send_field &field, - CHARSET_INFO *charset_for_protocol, - uint pos); + bool store_field_metadata(const THD *thd, const Send_field &field, + CHARSET_INFO *charset_for_protocol, + uint pos); bool store_item_metadata(THD *thd, Item *item, uint pos); bool store_field_metadata_for_list_fields(const THD *thd, Field *field, const TABLE_LIST *table_list, diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 1377a816d48..92938ac2f94 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -210,6 +210,16 @@ class Master_info : public Slave_reporting_capability void lock_slave_threads(); void unlock_slave_threads(); + ulonglong get_slave_skip_counter() + { + return rli.slave_skip_counter; + } + + ulonglong get_max_relay_log_size() + { + return rli.max_relay_log_size; + } + /* the variables below are needed because we can change masters on the fly */ char master_log_name[FN_REFLEN+6]; /* Room for multi-*/ char host[HOSTNAME_LENGTH*SYSTEM_CHARSET_MBMAXLEN+1]; diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index e1a4a25b27a..4e587b28f28 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -395,19 +395,6 @@ extern "C" void wsrep_thd_set_PA_unsafe(THD *thd) } } -extern "C" int wsrep_thd_append_table_key(MYSQL_THD thd, - const char* db, - const char* table, - enum Wsrep_service_key_type key_type) -{ - wsrep_key_arr_t key_arr = {0, 0}; - int ret = wsrep_prepare_keys_for_isolation(thd, db, table, NULL, &key_arr); - ret = ret || wsrep_thd_append_key(thd, key_arr.keys, - (int)key_arr.keys_len, key_type); - wsrep_keys_free(&key_arr); - return ret; -} - extern "C" my_bool wsrep_thd_is_local_transaction(const THD *thd) { return (wsrep_thd_is_local(thd) && diff --git a/sql/slave.cc b/sql/slave.cc index e991f7374e2..f17b6d46f2c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -46,7 +46,7 @@ #include #include #include - +#include "debug_sync.h" // debug_sync_set_action #include "sql_base.h" // close_thread_tables #include "tztime.h" // struct Time_zone #include "log_event.h" // Rotate_log_event, @@ -63,7 +63,6 @@ Master_info_index *master_info_index; #ifdef HAVE_REPLICATION #include "rpl_tblmap.h" -#include "debug_sync.h" #include "rpl_parallel.h" #include "sql_show.h" #include "semisync_slave.h" @@ -4863,7 +4862,13 @@ connected: goto err; goto connected; } - DBUG_EXECUTE_IF("fail_com_register_slave", goto err;); + DBUG_EXECUTE_IF("fail_com_register_slave", + { + mi->report(ERROR_LEVEL, ER_SLAVE_MASTER_COM_FAILURE, NULL, + ER(ER_SLAVE_MASTER_COM_FAILURE), "COM_REGISTER_SLAVE", + "Debug Induced Error"); + goto err; + }); } DBUG_PRINT("info",("Starting reading binary log from master")); diff --git a/sql/sp.cc b/sql/sp.cc index 73408481082..4907bf521f0 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -2733,7 +2733,13 @@ sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx, for (uint i=0 ; i < src->records ; i++) { Sroutine_hash_entry *rt= (Sroutine_hash_entry *)my_hash_element(src, i); - (void)sp_add_used_routine(prelocking_ctx, thd->stmt_arena, + DBUG_ASSERT(thd->active_stmt_arena_to_use()-> + is_stmt_prepare_or_first_stmt_execute() || + thd->active_stmt_arena_to_use()-> + is_conventional() || + thd->active_stmt_arena_to_use()->state == + Query_arena::STMT_SP_QUERY_ARGUMENTS); + (void)sp_add_used_routine(prelocking_ctx, thd->active_stmt_arena_to_use(), &rt->mdl_request.key, rt->m_handler, belong_to_view); } @@ -2759,7 +2765,7 @@ void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx, TABLE_LIST *belong_to_view) { for (Sroutine_hash_entry *rt= src->first; rt; rt= rt->next) - (void)sp_add_used_routine(prelocking_ctx, thd->stmt_arena, + (void)sp_add_used_routine(prelocking_ctx, thd->active_stmt_arena_to_use(), &rt->mdl_request.key, rt->m_handler, belong_to_view); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index d8e801d167b..c95761309a7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1554,7 +1554,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) { // Don't count a call ended with an error as normal run executed_counter= 0; - main_mem_root.read_only= 0; + main_mem_root.flags &= ~ROOT_FLAG_READ_ONLY; reset_instrs_executed_counter(); } #endif @@ -1675,10 +1675,10 @@ sp_head::execute(THD *thd, bool merge_da_on_success) #ifdef PROTECT_STATEMENT_MEMROOT if (!err_status) { - if (!main_mem_root.read_only && + if (!(main_mem_root.flags & ROOT_FLAG_READ_ONLY) && has_all_instrs_executed()) { - main_mem_root.read_only= 1; + main_mem_root.flags |= ROOT_FLAG_READ_ONLY; } ++executed_counter; DBUG_PRINT("info", ("execute counter: %lu", executed_counter)); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 797f69f4bec..800a21a7749 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -944,6 +944,7 @@ class User_table_tabular: public User_table int get_auth(THD *thd, MEM_ROOT *root, ACL_USER *u) const { + mysql_mutex_assert_owner(&acl_cache->lock); u->alloc_auth(root, 1); if (have_password()) { @@ -2272,6 +2273,9 @@ static bool validate_password(THD *thd, const LEX_CSTRING &user, static int set_user_salt(ACL_USER::AUTH *auth, plugin_ref plugin) { st_mysql_auth *info= (st_mysql_auth *) plugin_decl(plugin)->info; + + mysql_mutex_assert_owner(&acl_cache->lock); + if (info->interface_version >= 0x0202 && info->preprocess_hash && auth->auth_string.length) { @@ -2306,6 +2310,8 @@ static int set_user_auth(THD *thd, const LEX_CSTRING &user, plugin_ref plugin= get_auth_plugin(thd, auth->plugin, &unlock_plugin); int res= 1; + mysql_mutex_assert_owner(&acl_cache->lock); + if (!plugin) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -2382,10 +2388,13 @@ static bool set_user_salt_if_needed(ACL_USER *user_copy, int curr_auth, if (auth_copy->salt.str) return 0; // already done - if (set_user_salt(auth_copy, plugin)) - return 1; - mysql_mutex_lock(&acl_cache->lock); + if (set_user_salt(auth_copy, plugin)) + { + mysql_mutex_unlock(&acl_cache->lock); + return 1; + } + ACL_USER *user= find_user_exact(user_copy->host.hostname, user_copy->user.str); // make sure the user wasn't altered or dropped meanwhile if (user) @@ -3420,6 +3429,7 @@ ACL_USER::ACL_USER(THD *thd, const LEX_USER &combo, const Account_options &options, const privilege_t privileges) { + mysql_mutex_assert_owner(&acl_cache->lock); user= safe_lexcstrdup_root(&acl_memroot, combo.user); update_hostname(&host, safe_strdup_root(&acl_memroot, combo.host.str)); hostname_length= combo.host.length; @@ -3436,6 +3446,8 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth, const privilege_t privileges) { ACL_USER_PARAM::AUTH *work_copy= NULL; + mysql_mutex_assert_owner(&acl_cache->lock); + if (nauth) { if (!(work_copy= (ACL_USER_PARAM::AUTH*) @@ -5114,6 +5126,7 @@ update_role_mapping(LEX_CSTRING *user, LEX_CSTRING *host, LEX_CSTRING *role, return 0; } + mysql_mutex_assert_owner(&acl_cache->lock); /* allocate a new entry that will go in the hash */ ROLE_GRANT_PAIR *hash_entry= new (&acl_memroot) ROLE_GRANT_PAIR; if (hash_entry->init(&acl_memroot, user->str, host->str, @@ -5178,6 +5191,7 @@ replace_proxies_priv_table(THD *thd, TABLE *table, const LEX_USER *user, DBUG_ENTER("replace_proxies_priv_table"); + mysql_mutex_assert_owner(&acl_cache->lock); if (!table) { my_error(ER_NO_SUCH_TABLE, MYF(0), MYSQL_SCHEMA_NAME.str, diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 7ed906210c5..eeff246794f 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -628,19 +628,19 @@ bool Sql_cmd_alter_table::execute(THD *thd) } wsrep::key_array keys; - wsrep_append_fk_parent_table(thd, first_table, &keys); - - WSREP_TO_ISOLATION_BEGIN_ALTER(lex->name.str ? select_lex->db.str - : first_table->db.str, - lex->name.str ? lex->name.str - : first_table->table_name.str, - first_table, &alter_info, &keys, - used_engine ? &create_info : nullptr) + if (!wsrep_append_fk_parent_table(thd, first_table, &keys)) { - WSREP_WARN("ALTER TABLE isolation failure"); - DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN_ALTER(lex->name.str ? select_lex->db.str + : first_table->db.str, + lex->name.str ? lex->name.str + : first_table->table_name.str, + first_table, &alter_info, &keys, + used_engine ? &create_info : nullptr) + { + WSREP_WARN("ALTER TABLE isolation failure"); + DBUG_RETURN(TRUE); + } } - DEBUG_SYNC(thd, "wsrep_alter_table_after_toi"); } #endif diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 2bb9aaec322..d85d33f7b06 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2128,6 +2128,7 @@ retry_share: if (thd->has_read_only_protection()) { MYSQL_UNBIND_TABLE(table->file); + table->vcol_cleanup_expr(thd); tc_release_table(table); DBUG_RETURN(TRUE); } @@ -2147,6 +2148,7 @@ retry_share: if (result) { MYSQL_UNBIND_TABLE(table->file); + table->vcol_cleanup_expr(thd); tc_release_table(table); DBUG_RETURN(TRUE); } @@ -7749,7 +7751,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array, while ((item= it++)) { if (make_pre_fix) - pre_fix->push_back(item, thd->stmt_arena->mem_root); + pre_fix->push_back(item, thd->active_stmt_arena_to_use()->mem_root); if (item->fix_fields_if_needed_for_scalar(thd, it.ref())) { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 60e5c66e3cf..8b778b68fc6 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1264,7 +1264,9 @@ void THD::init() user_time.val= start_time= start_time_sec_part= 0; - server_status= SERVER_STATUS_AUTOCOMMIT; + server_status= 0; + if (variables.option_bits & OPTION_AUTOCOMMIT) + server_status|= SERVER_STATUS_AUTOCOMMIT; if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES; if (variables.sql_mode & MODE_ANSI_QUOTES) @@ -1323,10 +1325,7 @@ void THD::init() wsrep_desynced_backup_stage= false; #endif /* WITH_WSREP */ - if (variables.sql_log_bin) - variables.option_bits|= OPTION_BIN_LOG; - else - variables.option_bits&= ~OPTION_BIN_LOG; + set_binlog_bit(); select_commands= update_commands= other_commands= 0; /* Set to handle counting of aborted connections */ @@ -1624,6 +1623,10 @@ void THD::free_connection() vio_delete(net.vio); net.vio= nullptr; net_end(&net); + delete(rgi_fake); + rgi_fake= NULL; + delete(rli_fake); + rli_fake= NULL; #endif if (!cleanup_done) cleanup(); @@ -1662,6 +1665,7 @@ void THD::reset_for_reuse() abort_on_warning= 0; free_connection_done= 0; m_command= COM_CONNECT; + proc_info= "login"; // Same as in THD::THD() transaction->on= 1; #if defined(ENABLED_PROFILING) profiling.reset(); @@ -1674,6 +1678,7 @@ void THD::reset_for_reuse() wsrep_cs().reset_error(); wsrep_aborter= 0; wsrep_abort_by_kill= NOT_KILLED; + my_free(wsrep_abort_by_kill_err); wsrep_abort_by_kill_err= 0; #ifndef DBUG_OFF wsrep_killed_state= 0; @@ -1716,6 +1721,8 @@ THD::~THD() #ifdef WITH_WSREP mysql_cond_destroy(&COND_wsrep_thd); + my_free(wsrep_abort_by_kill_err); + wsrep_abort_by_kill_err= 0; #endif mdl_context.destroy(); @@ -1728,17 +1735,6 @@ THD::~THD() dbug_sentry= THD_SENTRY_GONE; #endif #ifndef EMBEDDED_LIBRARY - if (rgi_fake) - { - delete rgi_fake; - rgi_fake= NULL; - } - if (rli_fake) - { - delete rli_fake; - rli_fake= NULL; - } - if (rgi_slave) rgi_slave->cleanup_after_session(); my_free(semisync_info); @@ -1746,6 +1742,7 @@ THD::~THD() main_lex.free_set_stmt_mem_root(); free_root(&main_mem_root, MYF(0)); my_free(m_token_array); + my_free(killed_err); main_da.free_memory(); if (tdc_hash_pins) lf_hash_put_pins(tdc_hash_pins); @@ -2161,7 +2158,11 @@ void THD::reset_killed() mysql_mutex_assert_not_owner(&LOCK_thd_kill); mysql_mutex_lock(&LOCK_thd_kill); killed= NOT_KILLED; - killed_err= 0; + if (unlikely(killed_err)) + { + my_free(killed_err); + killed_err= 0; + } mysql_mutex_unlock(&LOCK_thd_kill); } #ifdef WITH_WSREP @@ -2172,6 +2173,7 @@ void THD::reset_killed() mysql_mutex_assert_not_owner(&LOCK_thd_kill); mysql_mutex_lock(&LOCK_thd_kill); wsrep_abort_by_kill= NOT_KILLED; + my_free(wsrep_abort_by_kill_err); wsrep_abort_by_kill_err= 0; mysql_mutex_unlock(&LOCK_thd_kill); } @@ -5942,8 +5944,6 @@ void THD::set_examined_row_count(ha_rows count) void THD::inc_sent_row_count(ha_rows count) { m_sent_row_count+= count; - DBUG_EXECUTE_IF("debug_huge_number_of_examined_rows", - m_examined_row_count= (ULONGLONG_MAX - 1000000);); MYSQL_SET_STATEMENT_ROWS_SENT(m_statement_psi, m_sent_row_count); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 90b0ed87a27..99a6348ea84 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1165,6 +1165,7 @@ struct THD_count { static Atomic_counter count; static uint value() { return static_cast(count); } + static uint connection_thd_count(); THD_count() { count++; } ~THD_count() { count--; } }; @@ -3200,6 +3201,17 @@ public: */ Query_arena *stmt_arena; + /** + Get either call or statement arena. In case some function is called from + within a query the call arena has to be used for a memory allocation, + else use the statement arena. + */ + Query_arena *active_stmt_arena_to_use() + { + return (state == Query_arena::STMT_SP_QUERY_ARGUMENTS) ? this : + stmt_arena; + } + void *bulk_param; /* @@ -3344,6 +3356,13 @@ public: auto_inc_intervals_forced.empty(); // in case of multiple SET INSERT_ID auto_inc_intervals_forced.append(next_id, ULONGLONG_MAX, 0); } + inline void set_binlog_bit() + { + if (variables.sql_log_bin) + variables.option_bits |= OPTION_BIN_LOG; + else + variables.option_bits &= ~OPTION_BIN_LOG; + } ulonglong limit_found_rows; @@ -3424,7 +3443,11 @@ public: { return m_sent_row_count; } ha_rows get_examined_row_count() const - { return m_examined_row_count; } + { + DBUG_EXECUTE_IF("debug_huge_number_of_examined_rows", + return (ULONGLONG_MAX - 1000000);); + return m_examined_row_count; + } ulonglong get_affected_rows() const { return affected_rows; } @@ -4040,6 +4063,11 @@ public: user_time= t; set_time(); } + inline void force_set_time(my_time_t t, ulong sec_part) + { + start_time= system_time.sec= t; + start_time_sec_part= system_time.sec_part= sec_part; + } /* this is only used by replication and BINLOG command. usecs > TIME_MAX_SECOND_PART means "was not in binlog" @@ -4051,15 +4079,9 @@ public: else { if (sec_part <= TIME_MAX_SECOND_PART) - { - start_time= system_time.sec= t; - start_time_sec_part= system_time.sec_part= sec_part; - } + force_set_time(t, sec_part); else if (t != system_time.sec) - { - start_time= system_time.sec= t; - start_time_sec_part= system_time.sec_part= 0; - } + force_set_time(t, 0); else { start_time= t; @@ -4600,7 +4622,8 @@ public: The worst things that can happen is that we get a suboptimal error message. */ - killed_err= (err_info*) alloc_root(&main_mem_root, sizeof(*killed_err)); + if (!killed_err) + killed_err= (err_info*) my_malloc(PSI_INSTRUMENT_ME, sizeof(*killed_err), MYF(MY_WME)); if (likely(killed_err)) { killed_err->no= killed_errno_arg; @@ -5059,13 +5082,24 @@ public: public: /** Overloaded to guard query/query_length fields */ virtual void set_statement(Statement *stmt); - void set_command(enum enum_server_command command) + inline void set_command(enum enum_server_command command) { + DBUG_ASSERT(command != COM_SLEEP); m_command= command; #ifdef HAVE_PSI_THREAD_INTERFACE PSI_STATEMENT_CALL(set_thread_command)(m_command); #endif } + /* As sleep needs a bit of special handling, we have a special case for it */ + inline void mark_connection_idle() + { + proc_info= 0; + m_command= COM_SLEEP; +#ifdef HAVE_PSI_THREAD_INTERFACE + PSI_STATEMENT_CALL(set_thread_command)(m_command); +#endif + } + inline enum enum_server_command get_command() const { return m_command; } diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 6b195ac9fe7..8878c722557 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1240,8 +1240,7 @@ void prepare_new_connection_state(THD* thd) embedded server library. TODO: refactor this to avoid code duplication there */ - thd->proc_info= 0; - thd->set_command(COM_SLEEP); + thd->mark_connection_idle(); thd->init_for_queries(); if (opt_init_connect.length && diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 6d8c402f6e4..1dbb265452a 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -643,6 +643,8 @@ void With_element::check_dependencies_in_unit(st_select_lex_unit *unit, { check_dependencies_in_select(sl, &unit_ctxt_elem, in_subq, dep_map); } + if ((sl= unit->fake_select_lex)) + check_dependencies_in_select(sl, &unit_ctxt_elem, in_subq, dep_map); } @@ -1279,14 +1281,14 @@ bool With_element::prepare_unreferenced(THD *thd) sl= sl->next_select()) sl->context.outer_context= 0; + uint8 save_context_analysys_only= thd->lex->context_analysis_only; thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED; if (!spec->prepared && (spec->prepare(spec->derived, 0, 0) || process_columns_of_derived_unit(thd, spec) || check_duplicate_names(thd, first_sl->item_list, 1))) rc= true; - - thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED; + thd->lex->context_analysis_only= save_context_analysys_only; return rc; } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 5de19084b0f..bd89c984706 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1256,6 +1256,13 @@ multi_delete::initialize_tables(JOIN *join) { TABLE_LIST *tbl= walk->correspondent_table->find_table_for_update(); tables_to_delete_from|= tbl->table->map; + + /* + Ensure that filesort re-reads the row from the engine before + delete is called. + */ + join->map2table[tbl->table->tablenr]->keep_current_rowid= true; + if (delete_while_scanning && unique_table(thd, tbl, join->tables_list, 0)) { diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index b26bbc48008..69e0f7c5102 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1350,13 +1350,10 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived) (derived->alias.str ? derived->alias.str : ""), derived->get_unit())); st_select_lex_unit *unit= derived->get_unit(); - st_select_lex *sl= unit->first_select(); // reset item names to that saved after wildcard expansion in JOIN::prepare - do - { + for(st_select_lex *sl= unit->first_select(); sl; sl= sl->next_select()) sl->restore_item_list_names(); - } while ((sl= sl->next_select())); derived->merged_for_insert= FALSE; unit->unclean(); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 90eff7e0d7b..c3006ecde9c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -83,6 +83,7 @@ #include "rpl_rli.h" #ifdef WITH_WSREP +#include "wsrep_mysqld.h" /* wsrep_append_table_keys() */ #include "wsrep_trans_observer.h" /* wsrep_start_transction() */ #endif /* WITH_WSREP */ @@ -580,7 +581,8 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list) Open tables used for sub-selects or in stored functions, will also cache these functions. */ - if (open_and_lock_tables(thd, table_list->next_global, TRUE, + if (table_list->next_global && + open_and_lock_tables(thd, table_list->next_global, TRUE, MYSQL_OPEN_IGNORE_ENGINE_STATS)) { end_delayed_insert(thd); @@ -2674,7 +2676,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) } THD_STAGE_INFO(client_thd, stage_got_handler_lock); if (client_thd->killed) - goto error; + goto error2; if (thd.killed) { /* @@ -2699,7 +2701,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) my_message(thd.get_stmt_da()->sql_errno(), thd.get_stmt_da()->message(), MYF(0)); } - goto error; + goto error2; } } share= table->s; @@ -2728,11 +2730,14 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) &record, (uint) share->reclength, &bitmap, (uint) share->column_bitmap_size*4, NullS)) - goto error; + goto error2; /* Copy the TABLE object. */ copy= new (copy_tmp) TABLE; *copy= *table; + copy->vcol_refix_list.empty(); + init_sql_alloc(key_memory_TABLE, ©->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, + MYF(MY_THREAD_SPECIFIC)); /* We don't need to change the file handler here */ /* Assign the pointers for the field pointers array and the record. */ @@ -2816,11 +2821,15 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) bzero((char*) bitmap, share->column_bitmap_size * bitmaps_used); copy->read_set= ©->def_read_set; copy->write_set= ©->def_write_set; + move_root(client_thd->mem_root, ©->mem_root); + free_root(©->mem_root, 0); DBUG_RETURN(copy); /* Got fatal error */ error: + free_root(©->mem_root, 0); +error2: tables_in_use--; mysql_cond_signal(&cond); // Inform thread about abort DBUG_RETURN(0); @@ -5067,17 +5076,13 @@ bool select_create::send_eof() thd->wsrep_trx_id(), thd->thread_id, thd->query_id); /* - append table level exclusive key for CTAS + For CTAS, append table level exclusive key for created table + and table level shared key for selected table. */ - wsrep_key_arr_t key_arr= {0, 0}; - wsrep_prepare_keys_for_isolation(thd, - create_table->db.str, - create_table->table_name.str, - table_list, - &key_arr); - int rcode= wsrep_thd_append_key(thd, key_arr.keys, key_arr.keys_len, - WSREP_SERVICE_KEY_EXCLUSIVE); - wsrep_keys_free(&key_arr); + int rcode= wsrep_append_table_keys(thd, create_table, table_list, + WSREP_SERVICE_KEY_EXCLUSIVE); + rcode= rcode || wsrep_append_table_keys(thd, nullptr, select_tables, + WSREP_SERVICE_KEY_SHARED); if (rcode) { DBUG_PRINT("wsrep", ("row key failed: %d", rcode)); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 24baf144fec..68475984635 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1485,7 +1485,7 @@ bool is_lex_native_function(const LEX_CSTRING *name) bool is_native_function(THD *thd, const LEX_CSTRING *name) { - if (native_functions_hash.find(thd, *name)) + if (mariadb_schema.find_native_function_builder(thd, *name)) return true; if (is_lex_native_function(name)) @@ -2164,7 +2164,18 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) if (lex->parsing_options.lookup_keywords_after_qualifier) next_state= MY_LEX_IDENT_OR_KEYWORD; else - next_state= MY_LEX_IDENT_START; // Next is ident (not keyword) + { + /* + Next is: + - A qualified func with a special syntax: + mariadb_schema.REPLACE('a','b','c') + mariadb_schema.SUSTRING('a',1,2) + mariadb_schema.TRIM('a') + - Or an identifier otherwise. No keyword lookup is done, + all keywords are treated as identifiers. + */ + next_state= MY_LEX_IDENT_OR_QUALIFIED_SPECIAL_FUNC; + } if (!ident_map[(uchar) yyPeek()]) // Probably ` or " next_state= MY_LEX_START; return((int) c); @@ -2608,7 +2619,12 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) We should now be able to handle: [(global | local | session) .]variable_name */ - return scan_ident_sysvar(thd, &yylval->ident_cli); + return scan_ident_common(thd, &yylval->ident_cli, + GENERAL_KEYWORD_OR_FUNC_LPAREN); + + case MY_LEX_IDENT_OR_QUALIFIED_SPECIAL_FUNC: + return scan_ident_common(thd, &yylval->ident_cli, + QUALIFIED_SPECIAL_FUNC_LPAREN); } } } @@ -2630,7 +2646,64 @@ bool Lex_input_stream::get_7bit_or_8bit_ident(THD *thd, uchar *last_char) } -int Lex_input_stream::scan_ident_sysvar(THD *thd, Lex_ident_cli_st *str) +/* + Resolve special SQL functions that have a qualified syntax in sql_yacc.yy. + These functions are not listed in the native function registry + because of a special syntax, or a reserved keyword: + + mariadb_schema.SUBSTRING('a' FROM 1 FOR 2) -- Special syntax + mariadb_schema.TRIM(BOTH ' ' FROM 'a') -- Special syntax + mariadb_schema.REPLACE('a','b','c') -- Verb keyword +*/ + +int Lex_input_stream::find_keyword_qualified_special_func(Lex_ident_cli_st *str, + uint length) const +{ + /* + There are many other special functions, see the following grammar rules: + function_call_keyword + function_call_nonkeyword + Here we resolve only those that have a qualified syntax to handle + different behavior in different @@sql_mode settings. + + Other special functions do not work in qualified context: + SELECT mariadb_schema.year(now()); -- Function year is not defined + SELECT mariadb_schema.now(); -- Function now is not defined + + We don't resolve TRIM_ORACLE here, because it does not have + a qualified syntax yet. Search for "trim_operands" in sql_yacc.yy + to find more comments. + */ + static LEX_CSTRING funcs[]= + { + {STRING_WITH_LEN("SUBSTRING")}, + {STRING_WITH_LEN("SUBSTR")}, + {STRING_WITH_LEN("TRIM")}, + {STRING_WITH_LEN("REPLACE")} + }; + + int tokval= find_keyword(str, length, true); + if (!tokval) + return 0; + for (size_t i= 0; i < array_elements(funcs); i++) + { + CHARSET_INFO *cs= system_charset_info; + /* + Check length equality to avoid non-ASCII variants + compared as equal to ASCII variants. + */ + if (length == funcs[i].length && + !cs->coll->strnncollsp(cs, + (const uchar *) m_tok_start, length, + (const uchar *) funcs[i].str, funcs[i].length)) + return tokval; + } + return 0; +} + + +int Lex_input_stream::scan_ident_common(THD *thd, Lex_ident_cli_st *str, + Ident_mode mode) { uchar last_char; uint length; @@ -2644,10 +2717,41 @@ int Lex_input_stream::scan_ident_sysvar(THD *thd, Lex_ident_cli_st *str) next_state= MY_LEX_IDENT_SEP; if (!(length= yyLength())) return ABORT_SYM; // Names must be nonempty. - if ((tokval= find_keyword(str, length, 0))) - { - yyUnget(); // Put back 'c' - return tokval; // Was keyword + + switch (mode) { + case GENERAL_KEYWORD_OR_FUNC_LPAREN: + /* + We can come here inside a system variable after "@@", + e.g. @@global.character_set_client. + We resolve all general purpose keywords here. + + We can come here when LEX::parsing_options.lookup_keywords_after_qualifier + is true, i.e. within the "field_spec" Bison rule. + We need to resolve functions that have special rules inside sql_yacc.yy, + such as SUBSTR, REPLACE, TRIM, to make this work: + c2 varchar(4) GENERATED ALWAYS AS (mariadb_schema.substr(c1,1,4)) + */ + if ((tokval= find_keyword(str, length, last_char == '('))) + { + yyUnget(); // Put back 'c' + return tokval; // Was keyword + } + break; + case QUALIFIED_SPECIAL_FUNC_LPAREN: + /* + We come here after '.' in various contexts: + SELECT @@global.character_set_client; + SELECT t1.a FROM t1; + SELECT test.f1() FROM t1; + SELECT mariadb_schema.trim('a'); + */ + if (last_char == '(' && + (tokval= find_keyword_qualified_special_func(str, length))) + { + yyUnget(); // Put back 'c' + return tokval; // Was keyword + } + break; } yyUnget(); // ptr points now after last token char @@ -3554,8 +3658,9 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) uint n_elems= get_cardinality_of_ref_ptrs_slice(order_group_num) * 5; if (!ref_pointer_array.is_null()) return false; - Item **array= static_cast(thd->stmt_arena->alloc(sizeof(Item*) * - n_elems)); + + Item **array= static_cast( + thd->active_stmt_arena_to_use()->alloc(sizeof(Item*) * n_elems)); if (likely(array != NULL)) ref_pointer_array= Ref_ptr_array(array, n_elems); return array == NULL; @@ -4699,18 +4804,24 @@ static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl) void st_select_lex::fix_prepare_information(THD *thd, Item **conds, Item **having_conds) { + Query_arena *active_arena= thd->active_stmt_arena_to_use(); + DBUG_ENTER("st_select_lex::fix_prepare_information"); - if (!thd->stmt_arena->is_conventional() && + + if (!active_arena->is_conventional() && !(changed_elements & TOUCHED_SEL_COND)) { Query_arena_stmt on_stmt_arena(thd); changed_elements|= TOUCHED_SEL_COND; + DBUG_ASSERT( + active_arena->is_stmt_prepare_or_first_stmt_execute() || + active_arena->state == Query_arena::STMT_SP_QUERY_ARGUMENTS); if (group_list.first) { if (!group_list_ptrs) { - void *mem= thd->stmt_arena->alloc(sizeof(Group_list_ptrs)); - group_list_ptrs= new (mem) Group_list_ptrs(thd->stmt_arena->mem_root); + void *mem= active_arena->alloc(sizeof(Group_list_ptrs)); + group_list_ptrs= new (mem) Group_list_ptrs(active_arena->mem_root); } group_list_ptrs->reserve(group_list.elements); for (ORDER *order= group_list.first; order; order= order->next) @@ -9370,6 +9481,136 @@ Item *LEX::make_item_func_sysdate(THD *thd, uint fsp) } +const Schema * +LEX::find_func_schema_by_name_or_error(const Lex_ident_sys &schema, + const Lex_ident_sys &func) +{ + Schema *res= Schema::find_by_name(schema); + if (res) + return res; + Database_qualified_name qname(schema, func); + my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), ErrConvDQName(&qname).ptr()); + return NULL; +} + + +Item *LEX::make_item_func_substr(THD *thd, + const Lex_ident_cli_st &schema_name_cli, + const Lex_ident_cli_st &func_name_cli, + const Lex_substring_spec_st &spec) +{ + Lex_ident_sys schema_name(thd, &schema_name_cli); + Lex_ident_sys func_name(thd, &func_name_cli); + if (schema_name.is_null() || func_name.is_null()) + return NULL; // EOM + const Schema *schema= find_func_schema_by_name_or_error(schema_name, + func_name); + return schema ? schema->make_item_func_substr(thd, spec) : NULL; +} + + +Item *LEX::make_item_func_substr(THD *thd, + const Lex_ident_cli_st &schema_name_cli, + const Lex_ident_cli_st &func_name_cli, + List *item_list) +{ + Lex_ident_sys schema_name(thd, &schema_name_cli); + Lex_ident_sys func_name(thd, &func_name_cli); + if (schema_name.is_null() || func_name.is_null()) + return NULL; // EOM + Schema *schema; + if (item_list && + (item_list->elements == 2 || item_list->elements == 3) && + (schema= Schema::find_by_name(schema_name))) + { + Item_args args(thd, *item_list); + Lex_substring_spec_st spec= + Lex_substring_spec_st::init(args.arguments()[0], + args.arguments()[1], + item_list->elements == 3 ? + args.arguments()[2] : NULL); + return schema->make_item_func_substr(thd, spec); + } + return make_item_func_call_generic(thd, schema_name, func_name, item_list); +} + + +Item *LEX::make_item_func_replace(THD *thd, + const Lex_ident_cli_st &schema_name_cli, + const Lex_ident_cli_st &func_name_cli, + Item *org, + Item *find, + Item *replace) +{ + Lex_ident_sys schema_name(thd, &schema_name_cli); + Lex_ident_sys func_name(thd, &func_name_cli); + if (schema_name.is_null() || func_name.is_null()) + return NULL; // EOM + const Schema *schema= find_func_schema_by_name_or_error(schema_name, + func_name); + return schema ? schema->make_item_func_replace(thd, org, find, replace) : + NULL; +} + + +Item *LEX::make_item_func_replace(THD *thd, + const Lex_ident_cli_st &schema_name_cli, + const Lex_ident_cli_st &func_name_cli, + List *item_list) +{ + Lex_ident_sys schema_name(thd, &schema_name_cli); + Lex_ident_sys func_name(thd, &func_name_cli); + if (schema_name.is_null() || func_name.is_null()) + return NULL; // EOM + const Schema *schema; + if (item_list && item_list->elements == 3 && + (schema= Schema::find_by_name(schema_name))) + { + Item_args args(thd, *item_list); + return schema->make_item_func_replace(thd, args.arguments()[0], + args.arguments()[1], + args.arguments()[2]); + } + return make_item_func_call_generic(thd, schema_name, func_name, item_list); +} + + +Item *LEX::make_item_func_trim(THD *thd, + const Lex_ident_cli_st &schema_name_cli, + const Lex_ident_cli_st &func_name_cli, + const Lex_trim_st &spec) +{ + Lex_ident_sys schema_name(thd, &schema_name_cli); + Lex_ident_sys func_name(thd, &func_name_cli); + if (schema_name.is_null() || func_name.is_null()) + return NULL; // EOM + const Schema *schema= find_func_schema_by_name_or_error(schema_name, + func_name); + return schema ? schema->make_item_func_trim(thd, spec) : NULL; +} + + +Item *LEX::make_item_func_trim(THD *thd, + const Lex_ident_cli_st &schema_name_cli, + const Lex_ident_cli_st &func_name_cli, + List *item_list) +{ + Lex_ident_sys schema_name(thd, &schema_name_cli); + Lex_ident_sys func_name(thd, &func_name_cli); + if (schema_name.is_null() || func_name.is_null()) + return NULL; // EOM + const Schema *schema; + if (item_list && item_list->elements == 1 && + (schema= Schema::find_by_name(schema_name))) + { + Item_args args(thd, *item_list); + Lex_trim spec(TRIM_BOTH, args.arguments()[0]); + return schema->make_item_func_trim(thd, spec); + } + return make_item_func_call_generic(thd, schema_name, func_name, item_list); +} + + bool SELECT_LEX::vers_push_field(THD *thd, TABLE_LIST *table, const LEX_CSTRING field_name) { @@ -9448,16 +9689,10 @@ Item *Lex_trim_st::make_item_func_trim_oracle(THD *thd) const } -Item *Lex_trim_st::make_item_func_trim(THD *thd) const -{ - return (thd->variables.sql_mode & MODE_ORACLE) ? - make_item_func_trim_oracle(thd) : - make_item_func_trim_std(thd); -} - - -Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cdb, - Lex_ident_cli_st *cname, List *args) +Item *LEX::make_item_func_call_generic(THD *thd, + const Lex_ident_cli_st *cdb, + const Lex_ident_cli_st *cname, + List *args) { Lex_ident_sys db(thd, cdb), name(thd, cname); if (db.is_null() || name.is_null()) @@ -9484,6 +9719,19 @@ Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cdb, if (check_routine_name(&name)) return NULL; + return make_item_func_call_generic(thd, db, name, args); +} + + +Item *LEX::make_item_func_call_generic(THD *thd, + const Lex_ident_sys &db, + const Lex_ident_sys &name, + List *args) +{ + const Schema *schema= Schema::find_by_name(db); + if (schema) + return schema->make_item_func_call_native(thd, name, args); + Create_qfunc *builder= find_qualified_function_builder(thd); DBUG_ASSERT(builder); return builder->create_with_db(thd, &db, &name, true, args); @@ -9924,8 +10172,17 @@ bool Lex_order_limit_lock::set_to(SELECT_LEX *sel) "CUBE/ROLLUP", "ORDER BY"); return TRUE; } + for (ORDER *order= order_list->first; order; order= order->next) + (*order->item)->walk(&Item::change_context_processor, FALSE, + &sel->context); sel->order_list= *(order_list); } + if (limit.select_limit) + limit.select_limit->walk(&Item::change_context_processor, FALSE, + &sel->context); + if (limit.offset_limit) + limit.offset_limit->walk(&Item::change_context_processor, FALSE, + &sel->context); sel->is_set_query_expr_tail= true; return FALSE; } @@ -11208,8 +11465,9 @@ bool st_select_lex::save_item_list_names(THD *thd) while ((item= li++)) { - if (unlikely(orig_names_of_item_list_elems->push_back( - new Lex_ident_sys(item->name.str, item->name.length)))) + Lex_ident_sys *name= new (thd->mem_root) Lex_ident_sys(thd, &item->name); + if (unlikely(!name || + orig_names_of_item_list_elems->push_back(name, thd->mem_root))) { if (arena) thd->restore_active_arena(arena, &backup); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index b05d09a77ca..ba0fc1d7205 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -146,6 +146,11 @@ public: struct Lex_ident_sys_st: public LEX_CSTRING { public: + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () + { return alloc_root(mem_root, size); } + static void operator delete(void *ptr,size_t size) { TRASH_FREE(ptr, size); } + static void operator delete(void *ptr, MEM_ROOT *mem_root) {} + bool copy_ident_cli(THD *thd, const Lex_ident_cli_st *str); bool copy_keyword(THD *thd, const Lex_ident_cli_st *str); bool copy_sys(THD *thd, const LEX_CSTRING *str); @@ -179,6 +184,10 @@ public: LEX_CSTRING tmp= {name, length}; set_valid_utf8(&tmp); } + Lex_ident_sys(THD *thd, const LEX_CSTRING *str) + { + set_valid_utf8(str); + } Lex_ident_sys & operator=(const Lex_ident_sys_st &name) { Lex_ident_sys_st::operator=(name); @@ -2465,6 +2474,15 @@ public: void reduce_digest_token(uint token_left, uint token_right); private: + + enum Ident_mode + { + GENERAL_KEYWORD_OR_FUNC_LPAREN, + QUALIFIED_SPECIAL_FUNC_LPAREN + }; + + int scan_ident_common(THD *thd, Lex_ident_cli_st *str, Ident_mode mode); + /** Set the echo mode. @@ -2785,8 +2803,8 @@ private: bool consume_comment(int remaining_recursions_permitted); int lex_one_token(union YYSTYPE *yylval, THD *thd); int find_keyword(Lex_ident_cli_st *str, uint len, bool function) const; + int find_keyword_qualified_special_func(Lex_ident_cli_st *str, uint len) const; LEX_CSTRING get_token(uint skip, uint length); - int scan_ident_sysvar(THD *thd, Lex_ident_cli_st *str); int scan_ident_start(THD *thd, Lex_ident_cli_st *str); int scan_ident_middle(THD *thd, Lex_ident_cli_st *str, CHARSET_INFO **cs, my_lex_states *); @@ -4136,8 +4154,42 @@ public: Item *create_item_query_expression(THD *thd, st_select_lex_unit *unit); Item *make_item_func_sysdate(THD *thd, uint fsp); - Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db, - Lex_ident_cli_st *name, List *args); + + static const Schema * + find_func_schema_by_name_or_error(const Lex_ident_sys &schema_name, + const Lex_ident_sys &func_name); + Item *make_item_func_replace(THD *thd, + const Lex_ident_cli_st &schema_name, + const Lex_ident_cli_st &func_name, + Item *org, Item *find, Item *replace); + Item *make_item_func_replace(THD *thd, + const Lex_ident_cli_st &schema_name, + const Lex_ident_cli_st &func_name, + List *args); + Item *make_item_func_substr(THD *thd, + const Lex_ident_cli_st &schema_name, + const Lex_ident_cli_st &func_name, + const Lex_substring_spec_st &spec); + Item *make_item_func_substr(THD *thd, + const Lex_ident_cli_st &schema_name, + const Lex_ident_cli_st &func_name, + List *args); + Item *make_item_func_trim(THD *thd, + const Lex_ident_cli_st &schema_name, + const Lex_ident_cli_st &func_name, + const Lex_trim_st &spec); + Item *make_item_func_trim(THD *thd, + const Lex_ident_cli_st &schema_name, + const Lex_ident_cli_st &func_name, + List *args); + Item *make_item_func_call_generic(THD *thd, + const Lex_ident_cli_st *db, + const Lex_ident_cli_st *name, + List *args); + Item *make_item_func_call_generic(THD *thd, + const Lex_ident_sys &db, + const Lex_ident_sys &name, + List *args); Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db, Lex_ident_cli_st *pkg, diff --git a/sql/sql_load.cc b/sql/sql_load.cc index f8572dce66f..2a0fb4cb20f 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -255,6 +255,10 @@ public: */ void skip_data_till_eof() { +#ifndef EMBEDDED_LIBRARY + if (mysql_bin_log.is_open()) + cache.read_function= cache.real_read_function; +#endif while (GET != my_b_EOF) ; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index af96a744087..c09a59b3adc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2437,7 +2437,7 @@ resume: /* Performance Schema Interface instrumentation, end */ MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); thd->set_examined_row_count(0); // For processlist - thd->set_command(COM_SLEEP); + thd->mark_connection_idle(); thd->m_statement_psi= NULL; thd->m_digest= NULL; @@ -2451,6 +2451,8 @@ resume: */ thd->lex->m_sql_cmd= NULL; free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); + DBUG_EXECUTE_IF("print_allocated_thread_memory", + SAFEMALLOC_REPORT_MEMORY(sf_malloc_dbug_id());); #if defined(ENABLED_PROFILING) thd->profiling.finish_current_query(); @@ -5174,9 +5176,55 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) my_ok(thd); break; case SQLCOM_BACKUP_LOCK: - if (check_global_access(thd, RELOAD_ACL)) - goto error; - /* first table is set for lock. For unlock the list is empty */ + if (check_global_access(thd, RELOAD_ACL, true)) + { +#ifndef NO_EMBEDDED_ACCESS_CHECKS + /* + In case there is no global privilege, check DB privilege for LOCK TABLES. + */ + if (first_table) // BACKUP LOCK + { + if (check_single_table_access(thd, LOCK_TABLES_ACL, first_table, true)) + { + char command[30]; + get_privilege_desc(command, sizeof(command), RELOAD_ACL|LOCK_TABLES_ACL); + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); + goto error; + } + } + else // BACKUP UNLOCK + { + /* + We test mdl_backup_lock here because, if a user could obtain a lock + it would be silly to error and say `you can't BACKUP UNLOCK` + (because its obvious you did a `BACKUP LOCK`). + As `BACKUP UNLOCK` doesn't have a database reference, + there's no way we can check if the `BACKUP LOCK` privilege is missing. + Testing `thd->db` would involve faking a `TABLE_LIST` structure, + which because of the depth of inspection + in `check_single_table_access` makes the faking likely to cause crashes, + or unintended effects. The outcome of this is, + if a user does an `BACKUP UNLOCK` without a `BACKUP LOCKED` table, + there may be a` ER_SPECIFIC_ACCESS_DENIED` error even though + user has the privilege. + Its a bit different to what happens if the user has RELOAD_ACL, + where the error is silently ignored. + */ + if (!thd->mdl_backup_lock) + { + + char command[30]; + get_privilege_desc(command, sizeof(command), RELOAD_ACL|LOCK_TABLES_ACL); + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); + goto error; + } + } +#endif + } + /* + There is reload privilege, first table is set for lock. + For unlock the list is empty + */ if (first_table) res= backup_lock(thd, first_table); else @@ -7951,6 +7999,7 @@ static bool wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, thd->wsrep_retry_query = NULL; thd->wsrep_retry_query_len = 0; thd->wsrep_retry_command = COM_CONNECT; + thd->proc_info= 0; } return false; } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 40fc94fe978..7fb9801e7a3 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1689,7 +1689,6 @@ int plugin_init(int *argc, char **argv, int flags) } } - free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE)); tmp.state= PLUGIN_IS_UNINITIALIZED; if (register_builtin(plugin, &tmp, &plugin_ptr)) goto err_unlock; diff --git a/sql/sql_plugin_services.inl b/sql/sql_plugin_services.inl index 7bd38368f3d..0471003923f 100644 --- a/sql/sql_plugin_services.inl +++ b/sql/sql_plugin_services.inl @@ -228,6 +228,28 @@ struct json_service_st json_handler= json_unescape_json }; +struct sql_service_st sql_service_handler= +{ + mysql_init, + mysql_real_connect_local, + mysql_real_connect, + mysql_errno, + mysql_error, + mysql_real_query, + mysql_affected_rows, + mysql_num_rows, + mysql_store_result, + mysql_free_result, + mysql_fetch_row, + mysql_close, + mysql_options, + mysql_fetch_lengths, + mysql_set_character_set, + mysql_num_fields, + mysql_select_db, + mysql_ssl_set +}; + static struct thd_mdl_service_st thd_mdl_handler= { thd_mdl_context @@ -257,5 +279,6 @@ static struct st_service_ref list_of_services[]= { "thd_wait_service", VERSION_thd_wait, &thd_wait_handler }, { "wsrep_service", VERSION_wsrep, &wsrep_handler }, { "json_service", VERSION_json, &json_handler }, + { "sql_service", VERSION_sql_service, &sql_service_handler }, { "thd_mdl_service", VERSION_thd_mdl, &thd_mdl_handler } }; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 7fb944795e6..821ef29a0c2 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -132,6 +132,7 @@ static const uint PARAMETER_FLAG_UNSIGNED= 128U << 8; #include "wsrep_mysqld.h" #include "wsrep_trans_observer.h" #endif /* WITH_WSREP */ +#include "sql_audit.h" // mysql_audit_release #include "xa.h" // xa_recover_get_fields /** @@ -180,7 +181,7 @@ public: /* The following data member is wholly for debugging purpose. It can be used for possible crash analysis to determine how many times - the stored routine was executed before the mem_root marked read_only + the stored routine was executed before the mem_root marked ROOT_FLAG_READ_ONLY was requested for a memory chunk. Additionally, a value of this data member is output to the log with DBUG_PRINT. */ @@ -264,7 +265,6 @@ private: class Ed_connection; - /****************************************************************************** Implementation ******************************************************************************/ @@ -4060,19 +4060,23 @@ Execute_sql_statement(LEX_STRING sql_text) executions without having to cleanup/reset THD in between. */ -bool -Execute_sql_statement::execute_server_code(THD *thd) +static bool execute_server_code(THD *thd, + const char *sql_text, size_t sql_len) { PSI_statement_locker *parent_locker; + Reprepare_observer *reprepare_observer; bool error; + query_id_t save_query_id= thd->query_id; + query_id_t next_id= next_query_id(); - if (alloc_query(thd, m_sql_text.str, m_sql_text.length)) + if (alloc_query(thd, sql_text, sql_len)) return TRUE; Parser_state parser_state; if (parser_state.init(thd, thd->query(), thd->query_length())) return TRUE; + thd->query_id= next_id; parser_state.m_lip.multi_statements= FALSE; lex_start(thd); @@ -4085,22 +4089,33 @@ Execute_sql_statement::execute_server_code(THD *thd) parent_locker= thd->m_statement_psi; thd->m_statement_psi= NULL; + reprepare_observer= thd->m_reprepare_observer; + thd->m_reprepare_observer= NULL; error= mysql_execute_command(thd); thd->m_statement_psi= parent_locker; + thd->m_reprepare_observer= reprepare_observer; /* report error issued during command execution */ if (likely(error == 0) && thd->spcont == NULL) - general_log_write(thd, COM_STMT_EXECUTE, - thd->query(), thd->query_length()); + general_log_write(thd, COM_QUERY, thd->query(), thd->query_length()); end: thd->lex->restore_set_statement_var(); + thd->query_id= save_query_id; delete_explain_query(thd->lex); + lex_end(thd->lex); return error; } + +bool Execute_sql_statement::execute_server_code(THD *thd) +{ + return ::execute_server_code(thd, m_sql_text.str, m_sql_text.length); +} + + /*************************************************************************** Prepared_statement ****************************************************************************/ @@ -4672,7 +4687,7 @@ reexecute: #ifdef PROTECT_STATEMENT_MEMROOT // There was reprepare so the counter of runs should be reset executed_counter= 0; - mem_root->read_only= 0; + mem_root->flags &= ~ROOT_FLAG_READ_ONLY; #endif goto reexecute; } @@ -4681,7 +4696,7 @@ reexecute: #ifdef PROTECT_STATEMENT_MEMROOT if (!error) { - mem_root->read_only= 1; + mem_root->flags |= ROOT_FLAG_READ_ONLY; ++executed_counter; DBUG_PRINT("info", ("execute counter: %lu", executed_counter)); @@ -4690,7 +4705,7 @@ reexecute: { // Error on call shouldn't be counted as a normal run executed_counter= 0; - mem_root->read_only= 0; + mem_root->flags &= ~ROOT_FLAG_READ_ONLY; } #endif @@ -5637,15 +5652,6 @@ Ed_connection::store_result_set() return ed_result_set; } -/* - MENT-56 - Protocol_local and service_sql for plugins to enable 'local' SQL query execution. -*/ - -#ifndef EMBEDDED_LIBRARY -// This part is mostly copied from libmysqld/lib_sql.cc -// TODO: get rid of code duplications - #include #include "../libmysqld/embedded_priv.h" @@ -5660,12 +5666,30 @@ public: char **next_field; MYSQL_FIELD *next_mysql_field; MEM_ROOT *alloc; + THD *new_thd; + Security_context empty_ctx; + ulonglong client_capabilities; - Protocol_local(THD *thd_arg, ulong prealloc= 0) : + my_bool do_log_bin; + + Protocol_local(THD *thd_arg, THD *new_thd_arg, ulong prealloc) : Protocol_text(thd_arg, prealloc), - cur_data(0), first_data(0), data_tail(&first_data), alloc(0) - {} + cur_data(0), first_data(0), data_tail(&first_data), alloc(0), + new_thd(new_thd_arg), do_log_bin(FALSE) + {} + void set_binlog_vars(my_bool *sav_log_bin) + { + *sav_log_bin= thd->variables.sql_log_bin; + thd->variables.sql_log_bin= do_log_bin; + thd->set_binlog_bit(); + } + void restore_binlog_vars(my_bool sav_log_bin) + { + do_log_bin= thd->variables.sql_log_bin; + thd->variables.sql_log_bin= sav_log_bin; + thd->set_binlog_bit(); + } protected: bool net_store_data(const uchar *from, size_t length); bool net_store_data_cs(const uchar *from, size_t length, @@ -5736,6 +5760,20 @@ MYSQL_DATA *Protocol_local::alloc_new_dataset() } +void Protocol_local::clear_data_list() +{ + while (first_data) + { + MYSQL_DATA *data= first_data; + first_data= data->embedded_info->next; + free_rows(data); + } + data_tail= &first_data; + free_rows(cur_data); + cur_data= 0; +} + + static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length, CHARSET_INFO *fromcs, CHARSET_INFO *tocs) { @@ -6029,7 +6067,6 @@ bool Protocol_local::send_result_set_metadata(List *list, uint flags) { List_iterator_fast it(*list); Item *item; -// Protocol_local prot(thd); DBUG_ENTER("send_result_set_metadata"); // if (!thd->mysql) // bootstrap file handling @@ -6040,7 +6077,8 @@ bool Protocol_local::send_result_set_metadata(List *list, uint flags) for (uint pos= 0 ; (item= it++); pos++) { - if (/*prot.*/store_item_metadata(thd, item, pos)) + Send_field sf(thd, item); + if (store_field_metadata(thd, sf, item->charset_for_protocol(), pos)) goto err; } @@ -6054,6 +6092,7 @@ bool Protocol_local::send_result_set_metadata(List *list, uint flags) DBUG_RETURN(1); /* purecov: inspected */ } + static void list_fields_send_default(THD *thd, Protocol_local *p, Field *fld, uint pos) { @@ -6141,19 +6180,6 @@ bool Protocol_local::store_null() #include #include -struct local_results -{ - struct st_mysql_data *cur_data; - struct st_mysql_data *first_data; - struct st_mysql_data **data_tail; - void clear_data_list(); - struct st_mysql_data *alloc_new_dataset(); - char **next_field; - MYSQL_FIELD *next_mysql_field; - MEM_ROOT *alloc; -}; - - static void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data) { NET *net= &mysql->net; @@ -6168,11 +6194,11 @@ static void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data) static my_bool loc_read_query_result(MYSQL *mysql) { - local_results *thd= (local_results *) mysql->thd; + Protocol_local *p= (Protocol_local *) mysql->thd; - MYSQL_DATA *res= thd->first_data; - DBUG_ASSERT(!thd->cur_data); - thd->first_data= res->embedded_info->next; + MYSQL_DATA *res= p->first_data; + DBUG_ASSERT(!p->cur_data); + p->first_data= res->embedded_info->next; if (res->embedded_info->last_errno && !res->embedded_info->fields_list) { @@ -6200,7 +6226,7 @@ static my_bool loc_read_query_result(MYSQL *mysql) if (res->embedded_info->fields_list) { mysql->status=MYSQL_STATUS_GET_RESULT; - thd->cur_data= res; + p->cur_data= res; } else my_free(res); @@ -6209,23 +6235,206 @@ static my_bool loc_read_query_result(MYSQL *mysql) } +static my_bool +loc_advanced_command(MYSQL *mysql, enum enum_server_command command, + const uchar *header, ulong header_length, + const uchar *arg, ulong arg_length, my_bool skip_check, + MYSQL_STMT *stmt) +{ + my_bool result= 1; + Protocol_local *p= (Protocol_local *) mysql->thd; + NET *net= &mysql->net; + + if (p->thd && p->thd->killed != NOT_KILLED) + { + if (p->thd->killed < KILL_CONNECTION) + p->thd->killed= NOT_KILLED; + else + return 1; + } + + p->clear_data_list(); + /* Check that we are calling the client functions in right order */ + if (mysql->status != MYSQL_STATUS_READY) + { + set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); + goto end; + } + + /* Clear result variables */ + p->thd->clear_error(1); + mysql->affected_rows= ~(my_ulonglong) 0; + mysql->field_count= 0; + net_clear_error(net); + + /* + We have to call free_old_query before we start to fill mysql->fields + for new query. In the case of embedded server we collect field data + during query execution (not during data retrieval as it is in remote + client). So we have to call free_old_query here + */ + free_old_query(mysql); + + if (header) + { + arg= header; + arg_length= header_length; + } + + if (p->new_thd) + { + THD *thd_orig= current_thd; + set_current_thd(p->thd); + p->thd->thread_stack= (char*) &result; + p->thd->set_time(); + result= execute_server_code(p->thd, (const char *)arg, arg_length); + p->thd->cleanup_after_query(); + mysql_audit_release(p->thd); + p->end_statement(); + set_current_thd(thd_orig); + } + else + { + Ed_connection con(p->thd); + Security_context *ctx_orig= p->thd->security_ctx; + ulonglong cap_orig= p->thd->client_capabilities; + MYSQL_LEX_STRING sql_text; + my_bool log_bin_orig; + p->set_binlog_vars(&log_bin_orig); + + DBUG_ASSERT(current_thd == p->thd); + sql_text.str= (char *) arg; + sql_text.length= arg_length; + p->thd->security_ctx= &p->empty_ctx; + p->thd->client_capabilities= p->client_capabilities; + result= con.execute_direct(p, sql_text); + p->thd->client_capabilities= cap_orig; + p->thd->security_ctx= ctx_orig; + p->restore_binlog_vars(log_bin_orig); + } + if (skip_check) + result= 0; + p->cur_data= 0; + +end: + return result; +} + + +/* + reads dataset from the next query result + + SYNOPSIS + loc_read_rows() + mysql connection handle + other parameters are not used + + NOTES + It just gets next MYSQL_DATA from the result's queue + + RETURN + pointer to MYSQL_DATA with the coming recordset +*/ + +static MYSQL_DATA * +loc_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)), + unsigned int fields __attribute__((unused))) +{ + MYSQL_DATA *result= ((Protocol_local *)mysql->thd)->cur_data; + ((Protocol_local *)mysql->thd)->cur_data= 0; + if (result->embedded_info->last_errno) + { + embedded_get_error(mysql, result); + return NULL; + } + *result->embedded_info->prev_ptr= NULL; + return result; +} + + +/************************************************************************** + Get column lengths of the current row + If one uses mysql_use_result, res->lengths contains the length information, + else the lengths are calculated from the offset between pointers. +**************************************************************************/ + +static void loc_fetch_lengths(ulong *to, MYSQL_ROW column, + unsigned int field_count) +{ + MYSQL_ROW end; + + for (end=column + field_count; column != end ; column++,to++) + *to= *column ? *(uint *)((*column) - sizeof(uint)) : 0; +} + + +static void loc_flush_use_result(MYSQL *mysql, my_bool) +{ + Protocol_local *p= (Protocol_local *) mysql->thd; + if (p->cur_data) + { + free_rows(p->cur_data); + p->cur_data= 0; + } + else if (p->first_data) + { + MYSQL_DATA *data= p->first_data; + p->first_data= data->embedded_info->next; + free_rows(data); + } +} + + +static void loc_on_close_free(MYSQL *mysql) +{ + Protocol_local *p= (Protocol_local *) mysql->thd; + THD *thd= p->new_thd; + delete p; + if (thd) + { + delete thd; + local_connection_thread_count--; + } + my_free(mysql->info_buffer); + mysql->info_buffer= 0; +} + +static MYSQL_RES *loc_use_result(MYSQL *mysql) +{ + return mysql_store_result(mysql); +} + static MYSQL_METHODS local_methods= { loc_read_query_result, /* read_query_result */ - NULL/*loc_advanced_command*/, /* advanced_command */ - NULL/*loc_read_rows*/, /* read_rows */ - NULL/*loc_use_result*/, /* use_result */ - NULL/*loc_fetch_lengths*/, /* fetch_lengths */ - NULL/*loc_flush_use_result*/, /* flush_use_result */ - NULL/*loc_read_change_user_result*/ /* read_change_user_result */ + loc_advanced_command, /* advanced_command */ + loc_read_rows, /* read_rows */ + loc_use_result, /* use_result */ + loc_fetch_lengths, /* fetch_lengths */ + loc_flush_use_result, /* flush_use_result */ + NULL, /* read_change_user_result */ + loc_on_close_free /* on_close_free */ +#ifdef EMBEDDED_LIBRARY + ,NULL, /* list_fields */ + NULL, /* read_prepare_result */ + NULL, /* stmt_execute */ + NULL, /* read_binary_rows */ + NULL, /* unbuffered_fetch */ + NULL, /* read_statistics */ + NULL, /* next_result */ + NULL /* read_rows_from_cursor */ +#endif }; -extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql, - const char *host, const char *user, const char *passwd, const char *db) -{ - //char name_buff[USERNAME_LENGTH]; +Atomic_counter local_connection_thread_count; +extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql) +{ + THD *thd_orig= current_thd; + THD *new_thd; + Protocol_local *p; + ulonglong client_flag; DBUG_ENTER("mysql_real_connect_local"); /* Test whether we're already connected */ @@ -6235,148 +6444,62 @@ extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql, DBUG_RETURN(0); } - if (!host || !host[0]) - host= mysql->options.host; - mysql->methods= &local_methods; - - if (!db || !db[0]) - db=mysql->options.db; - - if (!user || !user[0]) - user=mysql->options.user; - - mysql->user= my_strdup(PSI_INSTRUMENT_ME, user, MYF(0)); - + mysql->user= NULL; + client_flag= mysql->options.client_flag; + client_flag|= CLIENT_MULTI_RESULTS;; + client_flag&= ~(CLIENT_COMPRESS | CLIENT_PLUGIN_AUTH); mysql->info_buffer= (char *) my_malloc(PSI_INSTRUMENT_ME, MYSQL_ERRMSG_SIZE, MYF(0)); - //mysql->thd= create_embedded_thd(client_flag); - - //init_embedded_mysql(mysql, client_flag); - - //if (mysql_init_character_set(mysql)) - // goto error; - - //if (check_embedded_connection(mysql, db)) - // goto error; - - mysql->server_status= SERVER_STATUS_AUTOCOMMIT; - - //if (mysql->options.init_commands) - //{ - // DYNAMIC_ARRAY *init_commands= mysql->options.init_commands; - // char **ptr= (char**)init_commands->buffer; - // char **end= ptr + init_commands->elements; -// - // for (; ptrfields) - // { - // if (!(res= (*mysql->methods->use_result)(mysql))) - // goto error; - // mysql_free_result(res); - // } - // } - //} - - DBUG_PRINT("exit",("Mysql handler: %p", mysql)); - DBUG_RETURN(mysql); - -//error: - DBUG_PRINT("error",("message: %u (%s)", - mysql->net.last_errno, - mysql->net.last_error)); + if (!thd_orig || thd_orig->lock) { - /* Free alloced memory */ - my_bool free_me=mysql->free_me; - free_old_query(mysql); - mysql->free_me=0; - mysql_close(mysql); - mysql->free_me=free_me; - } - DBUG_RETURN(0); -} + /* + When we start with the empty current_thd (that happens when plugins + are loaded during the server start) or when some tables are locked + with the current_thd already (that happens when INSTALL PLUGIN + calls the plugin_init or with queries), we create the new THD for + the local connection. So queries with this MYSQL will be run with + it rather than the current THD. + */ - -extern "C" int execute_sql_command(const char *command, - char *hosts, char *names, char *filters) -{ - MYSQL_LEX_STRING sql_text; - THD *thd= current_thd; - THD *new_thd= 0; - int result; - my_bool qc_save= 0; - Reprepare_observer *save_reprepare_observer= nullptr; - - if (!thd) - { new_thd= new THD(0); - new_thd->thread_stack= (char*) &sql_text; + local_connection_thread_count++; + new_thd->thread_stack= (char*) &thd_orig; new_thd->store_globals(); new_thd->security_ctx->skip_grants(); new_thd->query_cache_is_applicable= 0; new_thd->variables.wsrep_on= 0; + new_thd->client_capabilities= client_flag; + new_thd->variables.sql_log_bin= 0; + new_thd->set_binlog_bit(); + /* + TOSO: decide if we should turn the auditing off + for such threads. + We can do it like this: + new_thd->audit_class_mask[0]= ~0; + */ bzero((char*) &new_thd->net, sizeof(new_thd->net)); - thd= new_thd; + set_current_thd(thd_orig); + thd_orig= new_thd; } else - { - if (thd->lock) - /* Doesn't work if the thread opened/locked tables already. */ - return 2; - - 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); - { - Protocol_local p(thd); - Ed_connection con(thd); - result= con.execute_direct(&p, sql_text); - if (!result && p.first_data) - { - int nr= (int) p.first_data->rows; - MYSQL_ROWS *rows= p.first_data->data; - - while (nr--) - { - strcpy(hosts, rows->data[0]); - hosts+= strlen(hosts) + 1; - strcpy(names, rows->data[1]); - names+= strlen(names) + 1; - if (filters) - { - strcpy(filters, rows->data[2]); - filters+= strlen(filters) + 1; - } - rows= rows->next; - } - } - if (p.first_data) - { - if (p.alloc) - free_root(p.alloc, MYF(0)); - my_free(p.first_data); - } - } + new_thd= NULL; + p= new Protocol_local(thd_orig, new_thd, 0); if (new_thd) - delete new_thd; + new_thd->protocol= p; else { - thd->query_cache_is_applicable= qc_save; - thd->m_reprepare_observer= save_reprepare_observer; + p->empty_ctx.init(); + p->empty_ctx.skip_grants(); + p->client_capabilities= client_flag; } - *hosts= 0; - return result; -} + mysql->thd= p; + mysql->server_status= SERVER_STATUS_AUTOCOMMIT; -#endif /*!EMBEDDED_LIBRARY*/ + + DBUG_PRINT("exit",("Mysql handler: %p", mysql)); + DBUG_RETURN(mysql); +} diff --git a/sql/sql_prepare.h b/sql/sql_prepare.h index 1ea773a7ca8..ff6e986ec87 100644 --- a/sql/sql_prepare.h +++ b/sql/sql_prepare.h @@ -353,4 +353,6 @@ private: size_t m_column_count; /* TODO: change to point to metadata */ }; +extern Atomic_counter local_connection_thread_count; + #endif // SQL_PREPARE_H diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index f576e693a0e..863f03698a4 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -202,7 +202,8 @@ void PROF_MEASUREMENT::set_label(const char *status_arg, allocated_status_memory= (char *) my_malloc(key_memory_PROFILE, sizes[0] + sizes[1] + sizes[2], MYF(0)); - DBUG_ASSERT(allocated_status_memory != NULL); + if (!allocated_status_memory) + return; cursor= allocated_status_memory; @@ -266,6 +267,8 @@ QUERY_PROFILE::QUERY_PROFILE(PROFILING *profiling_arg, const char *status_arg) { m_seq_counter= 1; PROF_MEASUREMENT *prof= new PROF_MEASUREMENT(this, status_arg); + if (!prof) + return; prof->m_seq= m_seq_counter++; m_start_time_usecs= prof->time_usecs; m_end_time_usecs= m_start_time_usecs; @@ -307,6 +310,8 @@ void QUERY_PROFILE::new_status(const char *status_arg, prof= new PROF_MEASUREMENT(this, status_arg, function_arg, base_name(file_arg), line_arg); else prof= new PROF_MEASUREMENT(this, status_arg); + if (!prof) + DBUG_VOID_RETURN; prof->m_seq= m_seq_counter++; m_end_time_usecs= prof->time_usecs; diff --git a/sql/sql_profile.h b/sql/sql_profile.h index 881365596ed..c225f61773a 100644 --- a/sql/sql_profile.h +++ b/sql/sql_profile.h @@ -103,6 +103,8 @@ public: new_item= (struct queue_item *) my_malloc(key_memory_queue_item, sizeof(struct queue_item), MYF(0)); + if (!new_item) + return; new_item->payload= payload; @@ -296,7 +298,11 @@ public: { DBUG_ASSERT(!current); if (unlikely(enabled)) - current= new QUERY_PROFILE(this, initial_state); + { + QUERY_PROFILE *new_profile= new QUERY_PROFILE(this, initial_state); + if (new_profile) + current= new_profile; + } } void discard_current_query(); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 336e1eeb38e..c880ff98f71 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -4219,11 +4219,17 @@ bool mysql_show_binlog_events(THD* thd) } } + /* + Omit error messages from server log in Log_event::read_log_event. That + is, we only need to notify the client to correct their 'from' offset; + writing about this in the server log would be confusing as it isn't + related to server operational status. + */ for (event_count = 0; (ev = Log_event::read_log_event(&log, description_event, (opt_master_verify_checksum || - verify_checksum_once))); ) + verify_checksum_once), false)); ) { if (!unit->lim.check_offset(event_count) && ev->net_send(protocol, linfo.log_file_name, pos)) @@ -4511,6 +4517,10 @@ int log_loaded_block(IO_CACHE* file, uchar *Buffer, size_t Count) /* buffer contains position where we started last read */ uchar* buffer= (uchar*) my_b_get_buffer_start(file); uint max_event_size= lf_info->thd->variables.max_allowed_packet; + int res; +#ifndef DBUG_OFF + bool did_dbug_inject= false; +#endif if (lf_info->thd->is_current_stmt_binlog_format_row()) goto ret; @@ -4518,6 +4528,19 @@ int log_loaded_block(IO_CACHE* file, uchar *Buffer, size_t Count) lf_info->last_pos_in_file >= my_b_get_pos_in_file(file)) goto ret; + DBUG_EXECUTE_IF("load_data_binlog_cache_error", + { + /* + Simulate "disk full" error in the middle of writing to + the binlog cache. + */ + if (lf_info->last_pos_in_file >= 2*4096) + { + DBUG_SET("+d,simulate_file_write_error"); + did_dbug_inject= true; + } + };); + for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0; buffer += MY_MIN(block_len, max_event_size), block_len -= MY_MIN(block_len, max_event_size)) @@ -4529,7 +4552,10 @@ int log_loaded_block(IO_CACHE* file, uchar *Buffer, size_t Count) MY_MIN(block_len, max_event_size), lf_info->log_delayed); if (mysql_bin_log.write(&a)) - DBUG_RETURN(1); + { + res= 1; + goto err; + } } else { @@ -4538,12 +4564,20 @@ int log_loaded_block(IO_CACHE* file, uchar *Buffer, size_t Count) MY_MIN(block_len, max_event_size), lf_info->log_delayed); if (mysql_bin_log.write(&b)) - DBUG_RETURN(1); + { + res= 1; + goto err; + } lf_info->wrote_create_file= 1; } } ret: - int res= Buffer ? lf_info->real_read_function(file, Buffer, Count) : 0; + res= Buffer ? lf_info->real_read_function(file, Buffer, Count) : 0; +err: +#ifndef DBUG_OFF + if (did_dbug_inject) + DBUG_SET("-d,simulate_file_write_error"); +#endif DBUG_RETURN(res); } diff --git a/sql/sql_schema.cc b/sql/sql_schema.cc index f08204d272d..7a6c0c99398 100644 --- a/sql/sql_schema.cc +++ b/sql/sql_schema.cc @@ -33,6 +33,12 @@ public: return src; } + Create_func *find_native_function_builder(THD *thd, const LEX_CSTRING &name) + const + { + return native_functions_hash_oracle.find(thd, name); + } + Item *make_item_func_replace(THD *thd, Item *subj, Item *find, @@ -64,6 +70,7 @@ Schema mariadb_schema(Lex_cstring(STRING_WITH_LEN("mariadb_schema"))); Schema_oracle oracle_schema(Lex_cstring(STRING_WITH_LEN("oracle_schema"))); Schema_maxdb maxdb_schema(Lex_cstring(STRING_WITH_LEN("maxdb_schema"))); +const Schema &oracle_schema_ref= oracle_schema; Schema *Schema::find_by_name(const LEX_CSTRING &name) { @@ -88,6 +95,26 @@ Schema *Schema::find_implied(THD *thd) } +Create_func * +Schema::find_native_function_builder(THD *thd, const LEX_CSTRING &name) const +{ + return native_functions_hash.find(thd, name); +} + + +Item *Schema::make_item_func_call_native(THD *thd, + const Lex_ident_sys &name, + List *args) const +{ + Create_func *builder= find_native_function_builder(thd, name); + if (builder) + return builder->create_func(thd, &name, args); + my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), name.str); + return NULL; +} + + + Item *Schema::make_item_func_replace(THD *thd, Item *subj, Item *find, diff --git a/sql/sql_schema.h b/sql/sql_schema.h index 0258ff2dc97..af83c5e9599 100644 --- a/sql/sql_schema.h +++ b/sql/sql_schema.h @@ -19,6 +19,9 @@ #include "mysqld.h" #include "lex_string.h" +class Lex_ident_sys; +class Create_func; + class Schema { LEX_CSTRING m_name; @@ -34,6 +37,24 @@ public: return src; } + /** + Find a native function builder, return an error if not found, + build an Item otherwise. + */ + Item *make_item_func_call_native(THD *thd, + const Lex_ident_sys &name, + List *args) const; + + /** + Find the native function builder associated with a given function name. + @param thd The current thread + @param name The native function name + @return The native function builder associated with the name, or NULL + */ + virtual Create_func *find_native_function_builder(THD *thd, + const LEX_CSTRING &name) + const; + // Builders for native SQL function with a special syntax in sql_yacc.yy virtual Item *make_item_func_replace(THD *thd, Item *subj, @@ -67,5 +88,6 @@ public: extern Schema mariadb_schema; +extern const Schema &oracle_schema_ref; #endif // SQL_SCHEMA_H_INCLUDED diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f6293c8999a..40e8a800b26 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2774,7 +2774,7 @@ static const char *thread_state_info(THD *tmp) if (cond) return "Waiting on cond"; } - return NULL; + return ""; } @@ -8653,9 +8653,9 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list) } List_iterator_fast it(sel->item_list); if (!(transl= - (Field_translator*)(thd->stmt_arena-> + (Field_translator*)(thd->active_stmt_arena_to_use()-> alloc(sel->item_list.elements * - sizeof(Field_translator))))) + sizeof(Field_translator))))) // ??? { DBUG_RETURN(1); } @@ -9611,7 +9611,7 @@ ST_FIELD_INFO partitions_fields_info[]= ST_FIELD_INFO variables_fields_info[]= { Column("VARIABLE_NAME", Varchar(64), NOT_NULL, "Variable_name"), - Column("VARIABLE_VALUE", Varchar(2048), NOT_NULL, "Value"), + Column("VARIABLE_VALUE", Varchar(4096), NOT_NULL, "Value"), CEnd() }; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 772119fc8bd..40965468e7e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7005,6 +7005,14 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, (uint) (field->flags & NOT_NULL_FLAG)) DBUG_RETURN(false); + if (field->vcol_info) + { + if (!tmp_new_field->field->vcol_info) + DBUG_RETURN(false); + if (!field->vcol_info->is_equal(tmp_new_field->field->vcol_info)) + DBUG_RETURN(false); + } + /* mysql_prepare_alter_table() clears HA_OPTION_PACK_RECORD bit when preparing description of existing table. In ALTER TABLE it is later @@ -8755,6 +8763,30 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, goto err; case Alter_drop::FOREIGN_KEY: // Leave the DROP FOREIGN KEY names in the alter_info->drop_list. + /* If this is DROP FOREIGN KEY without IF EXIST, + we can now check does it exists and if not report a error. */ + if (!drop->drop_if_exists) + { + List fk_child_key_list; + table->file->get_foreign_key_list(thd, &fk_child_key_list); + if (fk_child_key_list.is_empty()) + { + fk_not_found: + my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop->type_name(), + drop->name); + goto err; + } + List_iterator fk_key_it(fk_child_key_list); + while (FOREIGN_KEY_INFO *f_key= fk_key_it++) + { + if (my_strcasecmp(system_charset_info, f_key->foreign_id->str, + drop->name) == 0) + goto fk_found; + } + goto fk_not_found; + fk_found: + break; + } break; } } @@ -11734,13 +11766,18 @@ bool check_engine(THD *thd, const char *db_name, if (!*new_engine) DBUG_RETURN(true); - /* Enforced storage engine should not be used in - ALTER TABLE that does not use explicit ENGINE = x to - avoid unwanted unrelated changes.*/ - if (!(thd->lex->sql_command == SQLCOM_ALTER_TABLE && - !(create_info->used_fields & HA_CREATE_USED_ENGINE))) - enf_engine= thd->variables.enforced_table_plugin ? - plugin_hton(thd->variables.enforced_table_plugin) : NULL; + /* + Enforced storage engine should not be used in ALTER TABLE that does not + use explicit ENGINE = x to avoid unwanted unrelated changes. It should not + be used in CREATE INDEX too. + */ + if (!((thd->lex->sql_command == SQLCOM_ALTER_TABLE && + !(create_info->used_fields & HA_CREATE_USED_ENGINE)) || + thd->lex->sql_command == SQLCOM_CREATE_INDEX)) + { + plugin_ref enf_plugin= thd->variables.enforced_table_plugin; + enf_engine= enf_plugin ? plugin_hton(enf_plugin) : NULL; + } if (enf_engine && enf_engine != *new_engine) { @@ -11837,8 +11874,18 @@ bool Sql_cmd_create_table_like::execute(THD *thd) Alter_info alter_info(lex->alter_info, thd->mem_root); #ifdef WITH_WSREP + bool wsrep_ctas= false; // If CREATE TABLE AS SELECT and wsrep_on - const bool wsrep_ctas= (select_lex->item_list.elements && WSREP(thd)); + if (WSREP(thd) && (select_lex->item_list.elements || + // Only CTAS may be applied not using TOI. + (wsrep_thd_is_applying(thd) && !wsrep_thd_is_toi(thd)))) + { + wsrep_ctas= true; + + // MDEV-22232: Disable CTAS retry by setting the retry counter to the + // threshold value. + thd->wsrep_retry_counter= thd->variables.wsrep_retry_autocommit; + } // This will be used in THD::decide_logging_format if CTAS Enable_wsrep_ctas_guard wsrep_ctas_guard(thd, wsrep_ctas); diff --git a/sql/sql_test.cc b/sql/sql_test.cc index bca6c21f668..aabc03ffa69 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -29,13 +29,15 @@ #include #include "sql_connect.h" #include "thread_cache.h" -#if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_H) +#if defined(HAVE_MALLINFO) || defined(HAVE_MALLINFO2) +#if defined(HAVE_MALLOC_H) #include -#elif defined(HAVE_MALLINFO) && defined(HAVE_SYS_MALLOC_H) +#elif defined(HAVE_SYS_MALLOC_H) #include #elif defined(HAVE_MALLOC_ZONE) #include #endif +#endif #ifdef HAVE_EVENT_SCHEDULER #include "events.h" diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index d29ef532382..656642e1f20 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -2537,7 +2537,8 @@ add_tables_and_routines_for_triggers(THD *thd, MDL_key key(MDL_key::TRIGGER, trigger->m_db.str, trigger->m_name.str); - if (sp_add_used_routine(prelocking_ctx, thd->stmt_arena, + if (sp_add_used_routine(prelocking_ctx, + thd->active_stmt_arena_to_use(), &key, &sp_handler_trigger, table_list->belong_to_view)) { diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 70657291271..3d3dd2135f2 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -271,7 +271,10 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl, if (!holders) { - holders= type_holders= new (thd->stmt_arena->mem_root) Type_holder[cnt]; + DBUG_ASSERT(thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute() || + thd->stmt_arena->is_conventional()); + holders= type_holders= + new (thd->active_stmt_arena_to_use()->mem_root) Type_holder[cnt]; if (!holders || join_type_handlers_for_tvc(thd, li, holders, cnt) || get_type_attributes_for_tvc(thd, li, holders, diff --git a/sql/sql_type.cc b/sql/sql_type.cc index fec7f0edb9f..b62909cbb53 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -1446,22 +1446,6 @@ Type_handler_string_result::charset_for_protocol(const Item *item) const } -const Type_handler * -Type_handler::get_handler_by_cmp_type(Item_result type) -{ - switch (type) { - case REAL_RESULT: return &type_handler_double; - case INT_RESULT: return &type_handler_slonglong; - case DECIMAL_RESULT: return &type_handler_newdecimal; - case STRING_RESULT: return &type_handler_long_blob; - case TIME_RESULT: return &type_handler_datetime; - case ROW_RESULT: return &type_handler_row; - } - DBUG_ASSERT(0); - return &type_handler_string; -} - - /* If we have a mixture of: - a MariaDB standard (built-in permanent) data type, and diff --git a/sql/sql_type.h b/sql/sql_type.h index 6c277e5ad9c..732d5250b33 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -3702,7 +3702,6 @@ public: static const Type_handler *blob_type_handler(const Item *item); static const Type_handler *get_handler_by_field_type(enum_field_types type); static const Type_handler *get_handler_by_real_type(enum_field_types type); - static const Type_handler *get_handler_by_cmp_type(Item_result type); static const Type_collection * type_collection_for_aggregation(const Type_handler *h1, const Type_handler *h2); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 3e416cc8a05..0e1ce008b7f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1005,7 +1005,8 @@ static int mysql_register_view(THD *thd, DDL_LOG_STATE *ddl_log_state, { Sql_mode_save_for_frm_handling sql_mode_save(thd); - lex->unit.print(&view_query, enum_query_type(QT_VIEW_INTERNAL | + lex->unit.print(&view_query, enum_query_type(QT_FOR_FRM | + QT_VIEW_INTERNAL | QT_ITEM_ORIGINAL_FUNC_NULLIF | QT_NO_WRAPPERS_FOR_TVC_IN_VIEW)); lex->unit.print(&is_query, enum_query_type(QT_TO_SYSTEM_CHARSET | @@ -1725,7 +1726,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, objects of the view. */ if (!(table->view_sctx= (Security_context *) - thd->stmt_arena->calloc(sizeof(Security_context)))) + thd->active_stmt_arena_to_use()->calloc(sizeof(Security_context)))) goto err; security_ctx= table->view_sctx; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8f790abf572..63d06867f04 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1822,8 +1822,17 @@ rule: %type sp_param_name_and_type_anchored %type sp_for_loop_index_and_bounds %type sp_for_loop_bounds -%type trim_operands -%type substring_operands + +%type + trim_operands + trim_operands_regular + trim_operands_special + +%type + substring_operands + substring_operands_regular + substring_operands_special + %type opt_sp_for_loop_direction %type sp_parameter_type %type index_hint_type @@ -9946,8 +9955,16 @@ explicit_cursor_attr: trim_operands: + trim_operands_regular + | trim_operands_special + ; + +trim_operands_regular: expr { $$.set(TRIM_BOTH, $1); } - | LEADING expr FROM expr { $$.set(TRIM_LEADING, $2, $4); } + ; + +trim_operands_special: + LEADING expr FROM expr { $$.set(TRIM_LEADING, $2, $4); } | TRAILING expr FROM expr { $$.set(TRIM_TRAILING, $2, $4); } | BOTH expr FROM expr { $$.set(TRIM_BOTH, $2, $4); } | LEADING FROM expr { $$.set(TRIM_LEADING, $3); } @@ -10358,6 +10375,11 @@ function_call_keyword: ; substring_operands: + substring_operands_regular + | substring_operands_special + ; + +substring_operands_regular: expr ',' expr ',' expr { $$= Lex_substring_spec_st::init($1, $3, $5); @@ -10366,7 +10388,10 @@ substring_operands: { $$= Lex_substring_spec_st::init($1, $3); } - | expr FROM expr FOR_SYM expr + ; + +substring_operands_special: + expr FROM expr FOR_SYM expr { $$= Lex_substring_spec_st::init($1, $3, $5); } @@ -10834,7 +10859,9 @@ function_call_generic: This will be revised with WL#2128 (SQL PATH) */ - if ((builder= native_functions_hash.find(thd, $1))) + builder= Schema::find_implied(thd)-> + find_native_function_builder(thd, $1); + if (builder) { item= builder->create_func(thd, &$1, $4); } @@ -10898,6 +10925,43 @@ function_call_generic: if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, &$5, $7)))) MYSQL_YYABORT; } + | ident_cli '.' REPLACE '(' opt_expr_list ')' + { + if (unlikely(!($$= Lex->make_item_func_replace(thd, $1, $3, $5)))) + MYSQL_YYABORT; + } + | ident_cli '.' SUBSTRING '(' opt_expr_list ')' + { + if (unlikely(!($$= Lex->make_item_func_substr(thd, $1, $3, $5)))) + MYSQL_YYABORT; + } + | ident_cli '.' SUBSTRING '(' substring_operands_special ')' + { + if (unlikely(!($$= Lex->make_item_func_substr(thd, $1, $3, $5)))) + MYSQL_YYABORT; + } + | ident_cli '.' TRIM '(' opt_expr_list ')' + { + if (unlikely(!($$= Lex->make_item_func_trim(thd, $1, $3, $5)))) + MYSQL_YYABORT; + } + | ident_cli '.' TRIM '(' trim_operands_special ')' + { + if (unlikely(!($$= Lex->make_item_func_trim(thd, $1, $3, $5)))) + MYSQL_YYABORT; + } + /* + We don't add a qualified syntax for TRIM_ORACLE here, + as this syntax is not absolutely required: + SELECT mariadb_schema.TRIM_ORACLE(..); + What absolutely required is only: + SELECT mariadb_schema.TRIM(..); + Adding a qualified syntax for TRIM_ORACLE would be tricky because + it is a non-reserved keyword. To avoid new shift/reduce conflicts + it would require grammar changes, like introducing a new rule + ident_step2_cli (which would include everything that ident_cli + includes but TRIM_ORACLE). + */ ; fulltext_options: @@ -15392,10 +15456,7 @@ with_column_list: ident_sys_alloc: ident_cli { - void *buf= thd->alloc(sizeof(Lex_ident_sys)); - if (!buf) - MYSQL_YYABORT; - $$= new (buf) Lex_ident_sys(thd, &$1); + $$= new (thd->mem_root) Lex_ident_sys(thd, &$1); } ; diff --git a/sql/structs.h b/sql/structs.h index 967dadb91bc..1641b8b3cbd 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -33,6 +33,7 @@ struct TABLE; class Type_handler; class Field; class Index_statistics; +struct Lex_ident_cli_st; class THD; @@ -790,12 +791,6 @@ public: } Item *make_item_func_trim_std(THD *thd) const; Item *make_item_func_trim_oracle(THD *thd) const; - /* - This method is still used to handle LTRIM and RTRIM, - while the special syntax TRIM(... BOTH|LEADING|TRAILING) - is now handled by Schema::make_item_func_trim(). - */ - Item *make_item_func_trim(THD *thd) const; }; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 34a8d7e3fe0..be8a66ff7f2 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1503,7 +1503,7 @@ static Sys_var_bit Sys_log_slow_slave_statements( static Sys_var_ulong Sys_log_warnings( "log_warnings", - "Log some not critical warnings to the general log file." + "Log some non critical warnings to the error log." "Value can be between 0 and 11. Higher values mean more verbosity", SESSION_VAR(log_warnings), CMD_LINE(OPT_ARG, 'W'), @@ -4481,10 +4481,7 @@ static bool fix_sql_log_bin_after_update(sys_var *self, THD *thd, { DBUG_ASSERT(type == OPT_SESSION); - if (thd->variables.sql_log_bin) - thd->variables.option_bits |= OPTION_BIN_LOG; - else - thd->variables.option_bits &= ~OPTION_BIN_LOG; + thd->set_binlog_bit(); return FALSE; } @@ -5489,7 +5486,7 @@ Sys_slave_net_timeout( */ ulonglong Sys_var_multi_source_ulonglong:: -get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const +get_master_info_ulonglong_value(THD *thd) const { Master_info *mi; ulonglong res= 0; // Default value @@ -5497,7 +5494,7 @@ get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const if ((mi= get_master_info(&thd->variables.default_master_connection, Sql_condition::WARN_LEVEL_WARN))) { - res= *((ulonglong*) (((uchar*) mi) + master_info_offset)); + res= (mi->*mi_accessor_func)(); mi->release(); } mysql_mutex_lock(&LOCK_global_system_variables); @@ -5567,7 +5564,7 @@ static bool update_slave_skip_counter(sys_var *self, THD *thd, Master_info *mi) static Sys_var_multi_source_ulonglong Sys_slave_skip_counter( "sql_slave_skip_counter", "Skip the next N events from the master log", SESSION_VAR(slave_skip_counter), NO_CMD_LINE, - MASTER_INFO_VAR(rli.slave_skip_counter), + &Master_info::get_slave_skip_counter, VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1), ON_UPDATE(update_slave_skip_counter)); @@ -5583,7 +5580,7 @@ static Sys_var_multi_source_ulonglong Sys_max_relay_log_size( "relay log will be rotated automatically when the size exceeds this " "value. If 0 at startup, it's set to max_binlog_size", SESSION_VAR(max_relay_log_size), CMD_LINE(REQUIRED_ARG), - MASTER_INFO_VAR(rli.max_relay_log_size), + &Master_info::get_max_relay_log_size, VALID_RANGE(0, 1024L*1024*1024), DEFAULT(0), BLOCK_SIZE(IO_SIZE), ON_UPDATE(update_max_relay_log_size)); diff --git a/sql/sys_vars.inl b/sql/sys_vars.inl index 09191a7236d..ac4fbf33446 100644 --- a/sql/sys_vars.inl +++ b/sql/sys_vars.inl @@ -2378,10 +2378,10 @@ public: like sql_slave_skip_counter are GLOBAL. */ -#define MASTER_INFO_VAR(X) my_offsetof(Master_info, X), sizeof(((Master_info *)0x10)->X) class Sys_var_multi_source_ulonglong; class Master_info; +typedef ulonglong (Master_info::*mi_ulonglong_accessor_function)(void); typedef bool (*on_multi_source_update_function)(sys_var *self, THD *thd, Master_info *mi); bool update_multi_source_variable(sys_var *self, @@ -2390,26 +2390,23 @@ bool update_multi_source_variable(sys_var *self, class Sys_var_multi_source_ulonglong :public Sys_var_ulonglong { - ptrdiff_t master_info_offset; + mi_ulonglong_accessor_function mi_accessor_func; on_multi_source_update_function update_multi_source_variable_func; public: Sys_var_multi_source_ulonglong(const char *name_arg, const char *comment, int flag_args, ptrdiff_t off, size_t size, CMD_LINE getopt, - ptrdiff_t master_info_offset_arg, - size_t master_info_arg_size, + mi_ulonglong_accessor_function mi_accessor_arg, ulonglong min_val, ulonglong max_val, ulonglong def_val, uint block_size, on_multi_source_update_function on_update_func) :Sys_var_ulonglong(name_arg, comment, flag_args, off, size, getopt, min_val, max_val, def_val, block_size, 0, VARIABLE_NOT_IN_BINLOG, 0, update_multi_source_variable), - master_info_offset(master_info_offset_arg), + mi_accessor_func(mi_accessor_arg), update_multi_source_variable_func(on_update_func) - { - SYSVAR_ASSERT(master_info_arg_size == size); - } + { } bool global_update(THD *thd, set_var *var) { return session_update(thd, var); @@ -2423,7 +2420,7 @@ public: { ulonglong *tmp, res; tmp= (ulonglong*) (((uchar*)&(thd->variables)) + offset); - res= get_master_info_ulonglong_value(thd, master_info_offset); + res= get_master_info_ulonglong_value(thd); *tmp= res; return (uchar*) tmp; } @@ -2431,7 +2428,7 @@ public: { return session_value_ptr(thd, base); } - ulonglong get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const; + ulonglong get_master_info_ulonglong_value(THD *thd) const; bool update_variable(THD *thd, Master_info *mi) { return update_multi_source_variable_func(this, thd, mi); diff --git a/sql/table.cc b/sql/table.cc index 83203890846..58599396d9b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5940,7 +5940,7 @@ allocate: /* Create view fields translation table */ if (!(transl= - (Field_translator*)(thd->stmt_arena-> + (Field_translator*)(thd-> alloc(select->item_list.elements * sizeof(Field_translator))))) { @@ -10393,6 +10393,12 @@ bool Vers_history_point::check_unit(THD *thd) { if (!item) return false; + if (item->real_type() == Item::FIELD_ITEM) + { + my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0), + item->full_name(), "FOR SYSTEM_TIME"); + return true; + } if (item->fix_fields_if_needed(thd, &item)) return true; const Type_handler *t= item->this_item()->real_type_handler(); diff --git a/sql/table.h b/sql/table.h index 56412abd6e8..e7ff7e21c6f 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2043,7 +2043,6 @@ public: void empty() { unit= VERS_TIMESTAMP; item= NULL; } void print(String *str, enum_query_type, const char *prefix, size_t plen) const; bool check_unit(THD *thd); - void bad_expression_data_type_error(const char *type) const; bool eq(const vers_history_point_t &point) const; }; diff --git a/sql/thread_pool_info.cc b/sql/thread_pool_info.cc index 90ac6871784..e3ffd160a11 100644 --- a/sql/thread_pool_info.cc +++ b/sql/thread_pool_info.cc @@ -14,9 +14,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/ #include -#include #include +#include #include #include #include diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc index d3b4a18195b..e26cac50697 100644 --- a/sql/wsrep_client_service.cc +++ b/sql/wsrep_client_service.cc @@ -281,11 +281,18 @@ enum wsrep::provider::status Wsrep_client_service::replay() original THD state during replication event applying. */ THD *replayer_thd= new THD(true, true); + // Replace the security context of the replayer with the security context + // of the original THD. Since security context class doesn't have proper + // copy constructors, we need to store the original one and set it back + // before destruction so that THD desctruction doesn't cause double-free + // on the replaced security context. + Security_context old_ctx = replayer_thd->main_security_ctx; + replayer_thd->main_security_ctx = m_thd->main_security_ctx; replayer_thd->thread_stack= m_thd->thread_stack; replayer_thd->real_id= pthread_self(); replayer_thd->prior_thr_create_utime= replayer_thd->start_utime= microsecond_interval_timer(); - replayer_thd->set_command(COM_SLEEP); + replayer_thd->mark_connection_idle(); replayer_thd->reset_for_next_command(true); enum wsrep::provider::status ret; @@ -297,6 +304,7 @@ enum wsrep::provider::status Wsrep_client_service::replay() replayer_service.replay_status(ret); } + replayer_thd->main_security_ctx = old_ctx; delete replayer_thd; DBUG_RETURN(ret); } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 76afbd303ff..d48ad74d6fe 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1692,7 +1692,13 @@ bool wsrep_sync_wait(THD* thd, enum enum_sql_command command) return res; } -void wsrep_keys_free(wsrep_key_arr_t* key_arr) +typedef struct wsrep_key_arr +{ + wsrep_key_t* keys; + size_t keys_len; +} wsrep_key_arr_t; + +static void wsrep_keys_free(wsrep_key_arr_t* key_arr) { for (size_t i= 0; i < key_arr->keys_len; ++i) { @@ -1708,7 +1714,7 @@ void wsrep_keys_free(wsrep_key_arr_t* key_arr) * @param tables list of tables * @param keys prepared keys - * @return true if parent table append was successfull, otherwise false. + * @return 0 if parent table append was successful, non-zero otherwise. */ bool wsrep_append_fk_parent_table(THD* thd, TABLE_LIST* tables, wsrep::key_array* keys) @@ -1757,6 +1763,8 @@ wsrep_append_fk_parent_table(THD* thd, TABLE_LIST* tables, wsrep::key_array* key } exit: + DEBUG_SYNC(thd, "wsrep_append_fk_toi_keys_before_close_tables"); + /* close the table and release MDL locks */ close_thread_tables(thd); thd->mdl_context.rollback_to_savepoint(mdl_savepoint); @@ -1767,6 +1775,24 @@ exit: table->mdl_request.ticket= NULL; } + /* + MDEV-32938: Check if DDL operation has been killed before. + + It may be that during collecting foreign keys this operation gets BF-aborted + by another already-running TOI operation because it got MDL locks on the same + table for checking foreign keys. + After `close_thread_tables()` has been called it's safe to assume that no-one + can BF-abort this operation as it's not holding any MDL locks any more. + */ + if (!fail) + { + mysql_mutex_lock(&thd->LOCK_thd_kill); + if (thd->killed) + { + fail= true; + } + mysql_mutex_unlock(&thd->LOCK_thd_kill); + } return fail; } @@ -1942,18 +1968,43 @@ err: } /* - * Prepare key list from db/table and table_list + * Prepare key list from db/table and table_list and append it to Wsrep + * with the given key type. * * Return zero in case of success, 1 in case of failure. */ - -bool wsrep_prepare_keys_for_isolation(THD* thd, - const char* db, - const char* table, - const TABLE_LIST* table_list, - wsrep_key_arr_t* ka) +int wsrep_append_table_keys(THD* thd, + TABLE_LIST* first_table, + TABLE_LIST* table_list, + Wsrep_service_key_type key_type) { - return wsrep_prepare_keys_for_isolation(thd, db, table, table_list, NULL, ka); + wsrep_key_arr_t key_arr= {0, 0}; + const char* db_name= first_table ? first_table->db.str : NULL; + const char* table_name= first_table ? first_table->table_name.str : NULL; + int rcode= wsrep_prepare_keys_for_isolation(thd, db_name, table_name, + table_list, NULL, &key_arr); + + if (!rcode && key_arr.keys_len) + { + rcode= wsrep_thd_append_key(thd, key_arr.keys, + key_arr.keys_len, key_type); + } + + wsrep_keys_free(&key_arr); + return rcode; +} + +extern "C" int wsrep_thd_append_table_key(MYSQL_THD thd, + const char* db, + const char* table, + enum Wsrep_service_key_type key_type) +{ + wsrep_key_arr_t key_arr = {0, 0}; + int ret = wsrep_prepare_keys_for_isolation(thd, db, table, NULL, NULL, &key_arr); + ret = ret || wsrep_thd_append_key(thd, key_arr.keys, + (int)key_arr.keys_len, key_type); + wsrep_keys_free(&key_arr); + return ret; } bool wsrep_prepare_key(const uchar* cache_key, size_t cache_key_len, @@ -2873,6 +2924,15 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_, const wsrep::key_array *fk_tables, const HA_CREATE_INFO *create_info) { + mysql_mutex_lock(&thd->LOCK_thd_kill); + const killed_state killed = thd->killed; + mysql_mutex_unlock(&thd->LOCK_thd_kill); + if (killed) + { + DBUG_ASSERT(FALSE); + return -1; + } + /* No isolation for applier or replaying threads. */ @@ -3606,8 +3666,7 @@ void* start_wsrep_THD(void *arg) thd->security_ctx->skip_grants(); /* handle_one_connection() again... */ - thd->proc_info= 0; - thd->set_command(COM_SLEEP); + thd->mark_connection_idle(); thd->init_for_queries(); mysql_mutex_lock(&LOCK_wsrep_slave_threads); diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 67183167519..308da46b411 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -502,17 +502,10 @@ void wsrep_init_gtid(); bool wsrep_check_gtid_seqno(const uint32&, const uint32&, uint64&); bool wsrep_get_binlog_gtid_seqno(wsrep_server_gtid_t&); -typedef struct wsrep_key_arr -{ - wsrep_key_t* keys; - size_t keys_len; -} wsrep_key_arr_t; -bool wsrep_prepare_keys_for_isolation(THD* thd, - const char* db, - const char* table, - const TABLE_LIST* table_list, - wsrep_key_arr_t* ka); -void wsrep_keys_free(wsrep_key_arr_t* key_arr); +int wsrep_append_table_keys(THD* thd, + TABLE_LIST* first_table, + TABLE_LIST* table_list, + Wsrep_service_key_type key_type); extern void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, diff --git a/sql/wsrep_server_service.cc b/sql/wsrep_server_service.cc index 6f902130e6a..c3df6e9f73c 100644 --- a/sql/wsrep_server_service.cc +++ b/sql/wsrep_server_service.cc @@ -39,7 +39,7 @@ static void init_service_thd(THD* thd, char* thread_stack) thd->thread_stack= thread_stack; thd->real_id= pthread_self(); thd->prior_thr_create_utime= thd->start_utime= microsecond_interval_timer(); - thd->set_command(COM_SLEEP); + thd->mark_connection_idle(); thd->reset_for_next_command(true); server_threads.insert(thd); // as wsrep_innobase_kill_one_trx() uses find_thread_by_id() } diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 682e64859b4..f2b8821e34c 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -487,6 +487,7 @@ void wsrep_backup_kill_for_commit(THD *thd) thd->wsrep_trx().state() != wsrep::transaction::s_must_replay) { thd->wsrep_abort_by_kill= thd->killed; + my_free(thd->wsrep_abort_by_kill_err); thd->wsrep_abort_by_kill_err= thd->killed_err; thd->killed= NOT_KILLED; thd->killed_err= 0; @@ -499,6 +500,7 @@ void wsrep_restore_kill_after_commit(THD *thd) DBUG_ASSERT(WSREP(thd)); mysql_mutex_assert_owner(&thd->LOCK_thd_kill); thd->killed= thd->wsrep_abort_by_kill; + my_free(thd->killed_err); thd->killed_err= thd->wsrep_abort_by_kill_err; thd->wsrep_abort_by_kill= NOT_KILLED; thd->wsrep_abort_by_kill_err= 0; diff --git a/storage/columnstore/CMakeLists.txt b/storage/columnstore/CMakeLists.txt index 6669862f038..899cb592257 100644 --- a/storage/columnstore/CMakeLists.txt +++ b/storage/columnstore/CMakeLists.txt @@ -5,6 +5,10 @@ if("NO" STREQUAL "${PLUGIN_COLUMNSTORE}") endif() add_definitions(-DBOOST_BIND_GLOBAL_PLACEHOLDERS) +IF(NOT PLUGIN_PERFSCHEMA STREQUAL NO) + add_definitions(-DHAVE_PSI_INTERFACE=) +ENDIF() + # this does everything, gets the var from the correct scope, appends new # values, sets in the correct scope diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 8f2015070be..c66c33a7818 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -98,7 +98,7 @@ #pragma implementation // gcc: Class implementation #endif -#include +#include #include #include "ha_example.h" #include "sql_class.h" diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 8e2b80b9512..1ac8fd15a57 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -2442,10 +2442,11 @@ static void buf_flush_page_cleaner() else { maybe_unemployed: - const bool below{dirty_pct < pct_lwm}; - pct_lwm= 0.0; - if (below) + if (dirty_pct < pct_lwm) + { + pct_lwm= 0.0; goto possibly_unemployed; + } } } else if (dirty_pct < srv_max_buf_pool_modified_pct) diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 614048b7ba0..8e5081ded8c 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -353,9 +353,6 @@ dict_build_table_def_step( /* Always set this bit for all new created tables */ DICT_TF2_FLAG_SET(table, DICT_TF2_FTS_AUX_HEX_NAME); - DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name", - DICT_TF2_FLAG_UNSET(table, - DICT_TF2_FTS_AUX_HEX_NAME);); if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_USE_FILE_PER_TABLE)) { /* This table will need a new tablespace. */ diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 25f72a974c3..d51ced003e8 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2810,8 +2810,7 @@ dict_foreign_find_index( for (dict_index_t* index = dict_table_get_first_index(table); index; index = dict_table_get_next_index(index)) { - if (types_idx != index - && !index->to_be_dropped + if (!index->to_be_dropped && !dict_index_is_online_ddl(index) && dict_foreign_qualify_index( table, col_names, columns, n_cols, @@ -3531,6 +3530,7 @@ dict_foreign_parse_drop_constraints( const char* ptr1; const char* id; CHARSET_INFO* cs; + bool if_exists = false; ut_a(trx->mysql_thd); @@ -3584,6 +3584,7 @@ loop: ptr1 = dict_accept(cs, ptr1, "EXISTS", &success); if (success) { ptr = ptr1; + if_exists = true; } } @@ -3594,14 +3595,14 @@ loop: goto syntax_error; } - ut_a(*n < 1000); - (*constraints_to_drop)[*n] = id; - (*n)++; - if (std::find_if(table->foreign_set.begin(), - table->foreign_set.end(), - dict_foreign_matches_id(id)) - == table->foreign_set.end()) { + table->foreign_set.end(), + dict_foreign_matches_id(id)) + == table->foreign_set.end()) { + + if (if_exists) { + goto loop; + } if (!srv_read_only_mode) { FILE* ef = dict_foreign_err_file; @@ -3623,6 +3624,9 @@ loop: return(DB_CANNOT_DROP_CONSTRAINT); } + ut_a(*n < 1000); + (*constraints_to_drop)[*n] = id; + (*n)++; goto loop; syntax_error: diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 17e512bf34e..ece04aaa3a0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7887,20 +7887,6 @@ ha_innobase::write_row( #endif if ((error_result = update_auto_increment())) { - /* We don't want to mask autoinc overflow errors. */ - - /* Handle the case where the AUTOINC sub-system - failed during initialization. */ - if (m_prebuilt->autoinc_error == DB_UNSUPPORTED) { - error_result = ER_AUTOINC_READ_FAILED; - /* Set the error message to report too. */ - my_error(ER_AUTOINC_READ_FAILED, MYF(0)); - goto func_exit; - } else if (m_prebuilt->autoinc_error != DB_SUCCESS) { - error = m_prebuilt->autoinc_error; - goto report_error; - } - /* MySQL errors are passed straight back. */ goto func_exit; } @@ -8038,7 +8024,6 @@ set_max_autoinc: } } -report_error: /* Cleanup and exit. */ if (error == DB_TABLESPACE_DELETED) { ib_senderrf( @@ -11889,8 +11874,6 @@ index_bad: /* Set the flags2 when create table or alter tables */ m_flags2 |= DICT_TF2_FTS_AUX_HEX_NAME; - DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name", - m_flags2 &= ~DICT_TF2_FTS_AUX_HEX_NAME;); DBUG_RETURN(true); } @@ -18331,11 +18314,15 @@ static void buf_flush_list_now_set(THD*, st_mysql_sys_var*, void*, const void* save) { - if (*(my_bool*) save) { - mysql_mutex_unlock(&LOCK_global_system_variables); - buf_flush_sync(); - mysql_mutex_lock(&LOCK_global_system_variables); - } + if (!*(my_bool*) save) + return; + const uint s= srv_fil_make_page_dirty_debug; + mysql_mutex_unlock(&LOCK_global_system_variables); + if (s) + buf_flush_sync(); + else + while (buf_flush_list_space(fil_system.sys_space, nullptr)); + mysql_mutex_lock(&LOCK_global_system_variables); } /** Override current MERGE_THRESHOLD setting for all indexes at dictionary diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index b8a9a7e5d96..810a4a26363 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4672,11 +4672,13 @@ innobase_build_col_map( col_map[old_i - num_old_v] = i; if (!old_table->versioned() || !altered_table->versioned()) { - } else if (old_i == old_table->vers_start) { - new_table->vers_start = (i + num_v) + } else if (old_i - num_old_v == old_table->vers_start) { + ut_ad(field->vers_sys_start()); + new_table->vers_start = i & dict_index_t::MAX_N_FIELDS; - } else if (old_i == old_table->vers_end) { - new_table->vers_end = (i + num_v) + } else if (old_i - num_old_v == old_table->vers_end) { + ut_ad(field->vers_sys_end()); + new_table->vers_end = i & dict_index_t::MAX_N_FIELDS; } goto found_col; @@ -7755,6 +7757,7 @@ bool check_col_is_in_fk_indexes( for (const auto &a : add_fk) { + if (!a->foreign_index) continue; for (ulint i= 0; i < a->n_fields; i++) { if (a->foreign_index->fields[i].col == col) diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index a8e110889e3..0e520a174da 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -4745,6 +4745,15 @@ i_s_dict_fill_sys_tables( DBUG_RETURN(0); } +/** Handle the error for information schema query +@param err error value +@param thd thread +@return 0 if query is interrupted or error */ +static int i_s_sys_error_handling(int err, THD *thd) +{ + return thd_kill_level(thd) ? 0 : err; +} + /** Convert one SYS_TABLES record to dict_table_t. @param pcur persistent cursor position on SYS_TABLES record @param mtr mini-transaction (nullptr=use the dict_sys cache) @@ -4793,6 +4802,7 @@ i_s_sys_tables_fill_table( { btr_pcur_t pcur; mtr_t mtr; + int err = 0; DBUG_ENTER("i_s_sys_tables_fill_table"); RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); @@ -4822,8 +4832,15 @@ i_s_sys_tables_fill_table( dict_sys.unlock(); if (!err_msg) { - i_s_dict_fill_sys_tables(thd, table_rec, - tables->table); + err = i_s_dict_fill_sys_tables( + thd, table_rec, tables->table); + if (err) { + err = i_s_sys_error_handling(err, thd); + if (table_rec) { + dict_mem_table_free(table_rec); + } + goto func_exit; + } } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_CANT_FIND_SYSTEM_REC, "%s", @@ -4841,8 +4858,10 @@ i_s_sys_tables_fill_table( mtr.commit(); dict_sys.unlock(); +func_exit: + ut_free(pcur.old_rec_buf); - DBUG_RETURN(0); + DBUG_RETURN(err); } /*******************************************************************//** @@ -5024,6 +5043,7 @@ i_s_sys_tables_fill_table_stats( btr_pcur_t pcur; const rec_t* rec; mtr_t mtr; + int err = 0; DBUG_ENTER("i_s_sys_tables_fill_table_stats"); RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); @@ -5049,8 +5069,12 @@ i_s_sys_tables_fill_table_stats( &table_rec); if (UNIV_LIKELY(!err_msg)) { - i_s_dict_fill_sys_tablestats(thd, table_rec, + err = i_s_dict_fill_sys_tablestats(thd, table_rec, tables->table); + if (err) { + err = i_s_sys_error_handling(err, thd); + goto func_exit; + } } else { ut_ad(!table_rec); dict_sys.unlock(); @@ -5068,8 +5092,9 @@ i_s_sys_tables_fill_table_stats( mtr.commit(); dict_sys.unlock(); - - DBUG_RETURN(0); +func_exit: + ut_free(pcur.old_rec_buf); + DBUG_RETURN(err); } /*******************************************************************//** @@ -5252,6 +5277,7 @@ i_s_sys_indexes_fill_table( const rec_t* rec; mem_heap_t* heap; mtr_t mtr; + int err = 0; DBUG_ENTER("i_s_sys_indexes_fill_table"); RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); @@ -5287,11 +5313,13 @@ i_s_sys_indexes_fill_table( dict_sys.unlock(); if (!err_msg) { - if (int err = i_s_dict_fill_sys_indexes( - thd, table_id, space_id, &index_rec, - tables->table)) { - mem_heap_free(heap); - DBUG_RETURN(err); + err = i_s_dict_fill_sys_indexes( + thd, table_id, space_id, + &index_rec, + tables->table); + if (err) { + err = i_s_sys_error_handling(err, thd); + goto func_exit; } } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -5309,9 +5337,11 @@ i_s_sys_indexes_fill_table( mtr.commit(); dict_sys.unlock(); +func_exit: mem_heap_free(heap); + ut_free(pcur.old_rec_buf); - DBUG_RETURN(0); + DBUG_RETURN(err); } /*******************************************************************//** Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_indexes @@ -5471,6 +5501,7 @@ i_s_sys_columns_fill_table( const char* col_name; mem_heap_t* heap; mtr_t mtr; + int err = 0; DBUG_ENTER("i_s_sys_columns_fill_table"); RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); @@ -5502,9 +5533,14 @@ i_s_sys_columns_fill_table( dict_sys.unlock(); if (!err_msg) { - i_s_dict_fill_sys_columns(thd, table_id, col_name, - &column_rec, nth_v_col, - tables->table); + err = i_s_dict_fill_sys_columns( + thd, table_id, col_name, + &column_rec, nth_v_col, + tables->table); + if (err) { + err = i_s_sys_error_handling(err, thd); + goto func_exit; + } } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_CANT_FIND_SYSTEM_REC, "%s", @@ -5521,9 +5557,11 @@ i_s_sys_columns_fill_table( mtr.commit(); dict_sys.unlock(); +func_exit: mem_heap_free(heap); + ut_free(pcur.old_rec_buf); - DBUG_RETURN(0); + DBUG_RETURN(err); } /*******************************************************************//** @@ -5666,6 +5704,7 @@ i_s_sys_virtual_fill_table( ulint pos; ulint base_pos; mtr_t mtr; + int err = 0; DBUG_ENTER("i_s_sys_virtual_fill_table"); RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); @@ -5694,8 +5733,13 @@ i_s_sys_virtual_fill_table( dict_sys.unlock(); if (!err_msg) { - i_s_dict_fill_sys_virtual(thd, table_id, pos, base_pos, - tables->table); + err = i_s_dict_fill_sys_virtual( + thd, table_id, pos, base_pos, + tables->table); + if (err) { + err = i_s_sys_error_handling(err, thd); + goto func_exit; + } } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_CANT_FIND_SYSTEM_REC, "%s", @@ -5712,6 +5756,9 @@ i_s_sys_virtual_fill_table( dict_sys.unlock(); DBUG_RETURN(0); +func_exit: + ut_free(pcur.old_rec_buf); + DBUG_RETURN(err); } /** Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_virtual @@ -5850,6 +5897,7 @@ i_s_sys_fields_fill_table( mem_heap_t* heap; index_id_t last_id; mtr_t mtr; + int err = 0; DBUG_ENTER("i_s_sys_fields_fill_table"); RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); @@ -5885,8 +5933,13 @@ i_s_sys_fields_fill_table( dict_sys.unlock(); if (!err_msg) { - i_s_dict_fill_sys_fields(thd, index_id, &field_rec, - pos, tables->table); + err = i_s_dict_fill_sys_fields( + thd, index_id, &field_rec, + pos, tables->table); + if (err) { + err = i_s_sys_error_handling(err, thd); + goto func_exit; + } last_id = index_id; } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -5904,9 +5957,11 @@ i_s_sys_fields_fill_table( mtr.commit(); dict_sys.unlock(); +func_exit: mem_heap_free(heap); + ut_free(pcur.old_rec_buf); - DBUG_RETURN(0); + DBUG_RETURN(err); } /*******************************************************************//** Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_fields @@ -6054,6 +6109,7 @@ i_s_sys_foreign_fill_table( const rec_t* rec; mem_heap_t* heap; mtr_t mtr; + int err = 0; DBUG_ENTER("i_s_sys_foreign_fill_table"); RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); @@ -6081,8 +6137,12 @@ i_s_sys_foreign_fill_table( dict_sys.unlock(); if (!err_msg) { - i_s_dict_fill_sys_foreign(thd, &foreign_rec, - tables->table); + err = i_s_dict_fill_sys_foreign( + thd, &foreign_rec, tables->table); + if (err) { + err = i_s_sys_error_handling(err, thd); + goto func_exit; + } } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_CANT_FIND_SYSTEM_REC, "%s", @@ -6099,9 +6159,11 @@ i_s_sys_foreign_fill_table( mtr.commit(); dict_sys.unlock(); +func_exit: mem_heap_free(heap); + ut_free(pcur.old_rec_buf); - DBUG_RETURN(0); + DBUG_RETURN(err); } /*******************************************************************//** @@ -6246,6 +6308,7 @@ i_s_sys_foreign_cols_fill_table( const rec_t* rec; mem_heap_t* heap; mtr_t mtr; + int err = 0; DBUG_ENTER("i_s_sys_foreign_cols_fill_table"); RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); @@ -6277,9 +6340,13 @@ i_s_sys_foreign_cols_fill_table( dict_sys.unlock(); if (!err_msg) { - i_s_dict_fill_sys_foreign_cols( - thd, name, for_col_name, ref_col_name, pos, - tables->table); + err = i_s_dict_fill_sys_foreign_cols( + thd, name, for_col_name, + ref_col_name, pos, tables->table); + if (err) { + err = i_s_sys_error_handling(err, thd); + goto func_exit; + } } else { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_CANT_FIND_SYSTEM_REC, "%s", @@ -6296,9 +6363,11 @@ i_s_sys_foreign_cols_fill_table( mtr.commit(); dict_sys.unlock(); +func_exit: mem_heap_free(heap); + ut_free(pcur.old_rec_buf); - DBUG_RETURN(0); + DBUG_RETURN(err); } /*******************************************************************//** Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols @@ -6512,6 +6581,8 @@ static int i_s_sys_tablespaces_fill_table(THD *thd, TABLE_LIST *tables, Item*) mysql_mutex_unlock(&fil_system.mutex); if (err == DB_SUCCESS) err= i_s_sys_tablespaces_fill(thd, *fil_system.temp_space, tables->table); + else + err = i_s_sys_error_handling(err, thd); DBUG_RETURN(err); } diff --git a/storage/innobase/include/fts0priv.inl b/storage/innobase/include/fts0priv.inl index da14cfcb013..3cb09c924db 100644 --- a/storage/innobase/include/fts0priv.inl +++ b/storage/innobase/include/fts0priv.inl @@ -34,29 +34,6 @@ fts_write_object_id( ib_id_t id, /* in: a table/index id */ char* str) /* in: buffer to write the id to */ { - -#ifdef _WIN32 - - DBUG_EXECUTE_IF("innodb_test_wrong_non_windows_fts_aux_table_name", - return(sprintf(str, UINT64PFx, id));); - - /* Use this to construct old(5.6.14 and 5.7.3) windows - ambiguous aux table names */ - DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name", - return(sprintf(str, "%016llu", (ulonglong) id));); - -#else /* _WIN32 */ - - /* Use this to construct old(5.6.14 and 5.7.3) windows - ambiguous aux table names */ - DBUG_EXECUTE_IF("innodb_test_wrong_windows_fts_aux_table_name", - return(sprintf(str, "%016llu", (ulonglong) id));); - - DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name", - return(sprintf(str, "%016llx", (ulonglong) id));); - -#endif /* _WIN32 */ - return(sprintf(str, "%016llx", (ulonglong) id)); } diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index 0398e8da791..c5f8ab012c4 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -900,8 +900,8 @@ public: uint64_t recovered_binlog_offset; /** Latest recovered binlog file name */ char recovered_binlog_filename[TRX_SYS_MYSQL_LOG_NAME_LEN]; - /** FIL_PAGE_LSN of the page with the latest recovered binlog metadata */ - lsn_t recovered_binlog_lsn; + /** Set when latest position is from pre-version 10.3.5 TRX_SYS. */ + bool recovered_binlog_is_legacy_pos; /** diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index e610edfb1c7..d5638778079 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -1062,6 +1062,7 @@ public: { ut_ad(state == TRX_STATE_NOT_STARTED); ut_ad(!id); + ut_ad(!*detailed_error); ut_ad(!mutex_is_owner()); ut_ad(!has_logged()); ut_ad(!is_referenced()); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 56374f2442a..390fec8f4fb 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -4500,7 +4500,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) recv_group_scan_log_recs(checkpoint_lsn, &contiguous_lsn, false); /* The first scan should not have stored or applied any records. */ ut_ad(recv_sys.pages.empty()); - ut_ad(!recv_sys.is_corrupt_fs()); + ut_ad(!recv_sys.is_corrupt_fs() || !srv_force_recovery); if (srv_read_only_mode && recv_needed_recovery) { mysql_mutex_unlock(&log_sys.mutex); diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index 61614007bd4..51bcc9540fc 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -1778,9 +1778,6 @@ pars_create_table( ulint flags = 0; ulint flags2 = DICT_TF2_FTS_AUX_HEX_NAME; - DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name", - flags2 &= ~DICT_TF2_FTS_AUX_HEX_NAME;); - n_cols = que_node_list_get_len(column_defs); table = dict_table_t::create( diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 136fa51f3e1..c94ceb728fb 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -1627,9 +1627,6 @@ row_fts_merge_insert( /* We should set the flags2 with aux_table_name here, in order to get the correct aux table names. */ index->table->flags2 |= DICT_TF2_FTS_AUX_HEX_NAME; - DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name", - index->table->flags2 &= ~DICT_TF2_FTS_AUX_HEX_NAME - & ((1U << DICT_TF2_BITS) - 1);); fts_table.type = FTS_INDEX_TABLE; fts_table.index_id = index->id; fts_table.table_id = table->id; diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 7642326f8b7..178c2836c7c 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -3359,17 +3359,6 @@ row_merge_sort( of file marker). Thus, it must be at least one block. */ ut_ad(file->offset > 0); - /* These thd_progress* calls will crash on sol10-64 when innodb_plugin - is used. MDEV-9356: innodb.innodb_bug53290 fails (crashes) on - sol10-64 in buildbot. - */ -#ifndef __sun__ - /* Progress report only for "normal" indexes. */ - if (!(dup->index->type & DICT_FTS)) { - thd_progress_init(trx->mysql_thd, 1); - } -#endif /* __sun__ */ - if (global_system_variables.log_warnings > 2) { sql_print_information("InnoDB: Online DDL : merge-sorting" " has estimated " ULINTPF " runs", @@ -3378,15 +3367,6 @@ row_merge_sort( /* Merge the runs until we have one big run */ do { - /* Report progress of merge sort to MySQL for - show processlist progress field */ - /* Progress report only for "normal" indexes. */ -#ifndef __sun__ - if (!(dup->index->type & DICT_FTS)) { - thd_progress_report(trx->mysql_thd, file->offset - num_runs, file->offset); - } -#endif /* __sun__ */ - error = row_merge(trx, dup, file, block, tmpfd, &num_runs, run_offset, stage, crypt_block, space); @@ -3410,13 +3390,6 @@ row_merge_sort( ut_free(run_offset); - /* Progress report only for "normal" indexes. */ -#ifndef __sun__ - if (!(dup->index->type & DICT_FTS)) { - thd_progress_end(trx->mysql_thd); - } -#endif /* __sun__ */ - DBUG_RETURN(error); } diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index bec5384144d..a39574d2f64 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -2158,6 +2158,25 @@ row_upd_clust_rec_by_insert_inherit_func( return(inherit); } +/** Mark 'disowned' BLOBs as 'owned' and 'inherited' again, +after resuming from a lock wait. +@param entry clustered index entry */ +static ATTRIBUTE_COLD void row_upd_reown_inherited_fields(dtuple_t *entry) +{ + for (ulint i= 0; i < entry->n_fields; i++) + { + const dfield_t *dfield= dtuple_get_nth_field(entry, i); + if (dfield_is_ext(dfield)) + { + byte *blob_len= static_cast(dfield->data) + + dfield->len - (BTR_EXTERN_FIELD_REF_SIZE - BTR_EXTERN_LEN); + ut_ad(*blob_len & BTR_EXTERN_OWNER_FLAG); + *blob_len= byte((*blob_len & ~BTR_EXTERN_OWNER_FLAG) | + BTR_EXTERN_INHERITED_FLAG); + } + } +} + /***********************************************************//** Marks the clustered index record deleted and inserts the updated version of the record to the index. This function should be used when the ordering @@ -2236,12 +2255,16 @@ row_upd_clust_rec_by_insert( /* If the clustered index record is already delete marked, then we are here after a DB_LOCK_WAIT. Skip delete marking clustered index and disowning - its blobs. */ + its blobs. Mark the BLOBs in the index entry + (which we copied from the already "disowned" rec) + as "owned", like it was on the previous call of + row_upd_clust_rec_by_insert(). */ ut_ad(row_get_rec_trx_id(rec, index, offsets) == trx->id); ut_ad(!trx_undo_roll_ptr_is_insert( row_get_rec_roll_ptr(rec, index, offsets))); + row_upd_reown_inherited_fields(entry); goto check_fk; } diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 136294ae48b..b9ea545f93c 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -462,20 +462,31 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, mtr_t *mtr) TRX_RSEG + TRX_RSEG_BINLOG_NAME + rseg_hdr->page.frame; if (*binlog_name) { - lsn_t lsn= mach_read_from_8(my_assume_aligned<8> - (FIL_PAGE_LSN + rseg_hdr->page.frame)); static_assert(TRX_RSEG_BINLOG_NAME_LEN == sizeof trx_sys.recovered_binlog_filename, "compatibility"); - if (lsn > trx_sys.recovered_binlog_lsn) - { - trx_sys.recovered_binlog_lsn= lsn; - trx_sys.recovered_binlog_offset= - mach_read_from_8(TRX_RSEG + TRX_RSEG_BINLOG_OFFSET + - rseg_hdr->page.frame); - memcpy(trx_sys.recovered_binlog_filename, binlog_name, - TRX_RSEG_BINLOG_NAME_LEN); - } + /* Always prefer a position from rollback segment over + a legacy position from before version 10.3.5. */ + int cmp = *trx_sys.recovered_binlog_filename && + !trx_sys.recovered_binlog_is_legacy_pos + ? strncmp((const char*)(binlog_name), + trx_sys.recovered_binlog_filename, + TRX_RSEG_BINLOG_NAME_LEN) + : 1; + + if (cmp >= 0) { + uint64_t binlog_offset = + mach_read_from_8(TRX_RSEG + TRX_RSEG_BINLOG_OFFSET + + rseg_hdr->page.frame); + if (cmp) { + memcpy(trx_sys.recovered_binlog_filename, binlog_name, + TRX_RSEG_BINLOG_NAME_LEN); + trx_sys.recovered_binlog_offset = binlog_offset; + } else if (binlog_offset > trx_sys.recovered_binlog_offset) { + trx_sys.recovered_binlog_offset = binlog_offset; + } + trx_sys.recovered_binlog_is_legacy_pos= false; + } #ifdef WITH_WSREP trx_rseg_read_wsrep_checkpoint(rseg_hdr, trx_sys.recovered_wsrep_xid); #endif @@ -547,6 +558,7 @@ static void trx_rseg_init_binlog_info(const page_t* page) trx_sys.recovered_binlog_offset = mach_read_from_8( TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_OFFSET + TRX_SYS + page); + trx_sys.recovered_binlog_is_legacy_pos= true; } #ifdef WITH_WSREP @@ -561,6 +573,7 @@ dberr_t trx_rseg_array_init() *trx_sys.recovered_binlog_filename = '\0'; trx_sys.recovered_binlog_offset = 0; + trx_sys.recovered_binlog_is_legacy_pos= false; #ifdef WITH_WSREP trx_sys.recovered_wsrep_xid.null(); XID wsrep_sys_xid; diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index c99dd2110d4..58e36726bbc 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1502,6 +1502,7 @@ void trx_t::commit_cleanup() mutex.wr_lock(); state= TRX_STATE_NOT_STARTED; + *detailed_error= '\0'; mod_tables.clear(); check_foreigns= true; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 209fd0938b7..736c137eb8d 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -709,6 +709,16 @@ my_bool mi_killed_in_mariadb(MI_INFO *info) return (((TABLE*) (info->external_ref))->in_use->killed != 0); } +static void init_compute_vcols(void *table) +{ + /* + To evaluate vcols we must have current_thd set. + This will set current_thd in all threads to the same THD, but it's + safe, because vcols are always evaluated under info->s->intern_lock. + */ + set_current_thd(static_cast(table)->in_use); +} + static int compute_vcols(MI_INFO *info, uchar *record, int keynum) { /* This mutex is needed for parallel repair */ @@ -1010,6 +1020,7 @@ void ha_myisam::setup_vcols_for_repair(HA_CHECK *param) } DBUG_ASSERT(file->s->base.reclength < file->s->vreclength || !table->s->stored_fields); + param->init_fix_record= init_compute_vcols; param->fix_record= compute_vcols; table->use_all_columns(); } diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index 8ec1330c72d..e97a9260f57 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -528,6 +528,11 @@ pthread_handler_t thr_find_all_keys(void *arg) { MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg; my_bool error= FALSE; + + MI_SORT_INFO *si= sort_param->sort_info; + if (si->param->init_fix_record) + si->param->init_fix_record(si->info->external_ref); + /* If my_thread_init fails */ if (my_thread_init() || thr_find_all_keys_exec(sort_param)) error= TRUE; diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 2ff333d5d54..5c265a7d5bf 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -73,7 +73,7 @@ ha_spider::ha_spider( { DBUG_ENTER("ha_spider::ha_spider"); DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 139); + spider_alloc_calc_mem_init(mem_calc, SPD_MID_HA_SPIDER_HA_SPIDER_1); spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); share = NULL; conns = NULL; @@ -176,7 +176,7 @@ ha_spider::ha_spider( { DBUG_ENTER("ha_spider::ha_spider"); DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 0); + spider_alloc_calc_mem_init(mem_calc, SPD_MID_HA_SPIDER_HA_SPIDER_2); spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); share = NULL; conns = NULL; @@ -491,10 +491,10 @@ int ha_spider::open( } for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) { - result_list.sqls[roop_count].init_calc_mem(80); - result_list.insert_sqls[roop_count].init_calc_mem(81); - result_list.update_sqls[roop_count].init_calc_mem(82); - result_list.tmp_sqls[roop_count].init_calc_mem(83); + result_list.sqls[roop_count].init_calc_mem(SPD_MID_HA_SPIDER_OPEN_3); + result_list.insert_sqls[roop_count].init_calc_mem(SPD_MID_HA_SPIDER_OPEN_4); + result_list.update_sqls[roop_count].init_calc_mem(SPD_MID_HA_SPIDER_OPEN_5); + result_list.tmp_sqls[roop_count].init_calc_mem(SPD_MID_HA_SPIDER_OPEN_6); uint all_link_idx = conn_link_idx[roop_count]; uint dbton_id = share->sql_dbton_ids[all_link_idx]; if (share->dbton_share[dbton_id]->need_change_db_table_name()) @@ -525,7 +525,7 @@ int ha_spider::open( } for (roop_count = 0; roop_count < (int) table_share->fields; roop_count++) { - blob_buff[roop_count].init_calc_mem(84); + blob_buff[roop_count].init_calc_mem(SPD_MID_HA_SPIDER_OPEN_7); blob_buff[roop_count].set_charset(table->field[roop_count]->charset()); } } @@ -1206,6 +1206,14 @@ int ha_spider::external_lock( wide_handler->trx= trx; /* End of wide_handler setup */ + if (lock_type == F_UNLCK) + { + if (!trx->locked_connections) + { + DBUG_RETURN(0); /* No remote table actually locked by Spider */ + } + } + if (store_error_num) { DBUG_RETURN(store_error_num); @@ -1234,10 +1242,7 @@ int ha_spider::external_lock( if (lock_type == F_UNLCK) { - if (sql_command != SQLCOM_UNLOCK_TABLES) - { - DBUG_RETURN(0); /* Unlock remote tables only by UNLOCK TABLES. */ - } + wide_handler->sql_command = SQLCOM_UNLOCK_TABLES; if (!trx->locked_connections) { DBUG_RETURN(0); /* No remote table actually locked by Spider */ @@ -4728,13 +4733,13 @@ int ha_spider::read_multi_range_first_internal( } #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 if (!(multi_range_keys = (range_id_t *) - spider_malloc(spider_current_trx, 1, sizeof(range_id_t) * + spider_malloc(spider_current_trx, SPD_MID_HA_SPIDER_MULTI_RANGE_READ_NEXT_FIRST_1, sizeof(range_id_t) * (multi_range_num < result_list.multi_split_read ? multi_range_num : result_list.multi_split_read), MYF(MY_WME))) ) #else if (!(multi_range_keys = (char **) - spider_malloc(spider_current_trx, 1, sizeof(char *) * + spider_malloc(spider_current_trx, SPD_MID_HA_SPIDER_MULTI_RANGE_READ_NEXT_FIRST_2, sizeof(char *) * (multi_range_num < result_list.multi_split_read ? multi_range_num : result_list.multi_split_read), MYF(MY_WME))) ) @@ -4748,7 +4753,7 @@ int ha_spider::read_multi_range_first_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); } for (roop_count = 0; roop_count < 2; roop_count++) - mrr_key_buff[roop_count].init_calc_mem(235); + mrr_key_buff[roop_count].init_calc_mem(SPD_MID_HA_SPIDER_MULTI_RANGE_READ_NEXT_FIRST_3); } #else multi_range_ranges = ranges; @@ -7876,7 +7881,7 @@ FT_INFO *ha_spider::ft_init_ext( if (!ft_current) { if (!(ft_current = (st_spider_ft_info *) - spider_malloc(spider_current_trx, 2, sizeof(st_spider_ft_info), + spider_malloc(spider_current_trx, SPD_MID_HA_SPIDER_FT_INIT_EXT_1, sizeof(st_spider_ft_info), MYF(MY_WME | MY_ZEROFILL)))) { my_error(HA_ERR_OUT_OF_MEM, MYF(0)); @@ -11327,7 +11332,7 @@ int ha_spider::create( if (form->s->keys > 0) { if (!(tmp_share.static_key_cardinality = (longlong *) - spider_bulk_malloc(spider_current_trx, 246, MYF(MY_WME), + spider_bulk_malloc(spider_current_trx, SPD_MID_HA_SPIDER_CREATE_1, MYF(MY_WME), &tmp_share.static_key_cardinality, (uint) (sizeof(*tmp_share.static_key_cardinality) * form->s->keys), NullS)) @@ -11342,7 +11347,7 @@ int ha_spider::create( } } for (roop_count = 0; roop_count < form->s->keys; roop_count++) - tmp_share.key_hint[roop_count].init_calc_mem(85); + tmp_share.key_hint[roop_count].init_calc_mem(SPD_MID_HA_SPIDER_CREATE_2); DBUG_PRINT("info",("spider tmp_share.key_hint=%p", tmp_share.key_hint)); if ((error_num = spider_parse_connect_info(&tmp_share, form->s, #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -11826,12 +11831,6 @@ int ha_spider::delete_table( ) need_lock = TRUE; - if ((error_num = spider_sys_delete_table_sts( - current_thd, name, name_len, need_lock))) - goto error; - if ((error_num = spider_sys_delete_table_crd( - current_thd, name, name_len, need_lock))) - goto error; if ( !(table_tables = spider_open_sys_table( current_thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, @@ -12048,7 +12047,7 @@ const COND *ha_spider::cond_push( { SPIDER_CONDITION *tmp_cond; if (!(tmp_cond = (SPIDER_CONDITION *) - spider_malloc(spider_current_trx, 3, sizeof(*tmp_cond), MYF(MY_WME))) + spider_malloc(spider_current_trx, SPD_MID_HA_SPIDER_COND_PUSH_1, sizeof(*tmp_cond), MYF(MY_WME))) ) DBUG_RETURN(cond); tmp_cond->cond = (COND *) cond; @@ -12144,7 +12143,7 @@ int ha_spider::info_push( spider_free(spider_current_trx, wide_handler->hs_pushed_ret_fields, MYF(0)); if (!(wide_handler->hs_pushed_ret_fields = (uint32 *) - spider_bulk_malloc(spider_current_trx, 17, MYF(MY_WME), + spider_bulk_malloc(spider_current_trx, SPD_MID_HA_SPIDER_INFO_PUSH_1, MYF(MY_WME), &wide_handler->hs_pushed_ret_fields, sizeof(uint32) * wide_handler->hs_pushed_ret_fields_num, NullS)) @@ -13685,7 +13684,7 @@ SPIDER_BULK_ACCESS_LINK *ha_spider::create_bulk_access_link() } */ if (!(bulk_access_link = (SPIDER_BULK_ACCESS_LINK *) - spider_bulk_malloc(spider_current_trx, 168, MYF(MY_WME), + spider_bulk_malloc(spider_current_trx, SPD_MID_HA_SPIDER_CREATE_BULK_ACCESS_LINK_1, MYF(MY_WME), &bulk_access_link, (uint) (sizeof(SPIDER_BULK_ACCESS_LINK)), &ref, (uint) (ALIGN_SIZE(ref_length) * 2), NullS)) diff --git a/storage/spider/mysql-test/spider/bugfix/include/spider_table_sts_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/spider_table_sts_deinit.inc deleted file mode 100644 index 01645e85f32..00000000000 --- a/storage/spider/mysql-test/spider/bugfix/include/spider_table_sts_deinit.inc +++ /dev/null @@ -1,12 +0,0 @@ ---connection master_1 -alter table mysql.spider_table_sts add column checksum bigint unsigned default null after update_time; -DROP DATABASE IF EXISTS auto_test_local; - ---let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_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/spider_table_sts_init.inc b/storage/spider/mysql-test/spider/bugfix/include/spider_table_sts_init.inc deleted file mode 100644 index 1e438812af7..00000000000 --- a/storage/spider/mysql-test/spider/bugfix/include/spider_table_sts_init.inc +++ /dev/null @@ -1,13 +0,0 @@ ---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_2_1_BACKUP= $MASTER_1_COMMENT_2_1 -let $MASTER_1_COMMENT_2_1= - COMMENT='table "tbl_a", host "127.0.0.1", port "$MASTER_1_MYPORT", user "root"'; ---connection master_1 -alter table mysql.spider_table_sts drop column checksum; -insert into mysql.spider_table_sts values ('auto_test_local', 'tbl_a', 0, 0, 0, 0, 0, '2019-01-01 00:00:00', '2019-01-01 00:00:00', '2019-01-01 00:00:00'); diff --git a/storage/spider/mysql-test/spider/bugfix/r/gbh_outer_fields_in_join.result b/storage/spider/mysql-test/spider/bugfix/r/gbh_outer_fields_in_join.result new file mode 100644 index 00000000000..75c2f2c2751 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/gbh_outer_fields_in_join.result @@ -0,0 +1,50 @@ +# +# MDEV-26247 Spider: Valid LEFT JOIN results in ERROR 1064 +# +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; +CREATE TABLE t1 (a int) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 (a int) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t3 (a int) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1), (2); +INSERT INTO t3 VALUES (1), (2), (3); +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE t1 (a int) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='srv "s_2_1", table "t1"'; +CREATE TABLE t2 (a int) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='srv "s_2_1", table "t2"'; +CREATE TABLE t3 (a int) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='srv "s_2_1", table "t3"'; +select * from t3 left join t1 on t3.a = t1.a left join t2 on t3.a = t2.a; +a a a +1 1 1 +2 NULL 2 +3 NULL NULL +select * from t1 left join t2 on t1.a = t2.a right join t3 on t3.a = t1.a; +a a a +1 1 1 +NULL NULL 2 +NULL NULL 3 +select * from t3 left join (t1 left join t2 on t1.a = t2.a) on t3.a = t1.a; +a a a +1 1 1 +2 NULL NULL +3 NULL NULL +drop table t1, t2, t3; +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 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_19866.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_19866.result index dbf0f54c804..4386b4cbd4d 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_19866.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_19866.result @@ -72,6 +72,7 @@ SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argum argument select `pkey`,`val` from `auto_test_remote`.`tbl_a` select `pkey`,`val` from `auto_test_remote`.`tbl_a` where `pkey` = 1 +select 1 from (select 1) t0 select `pkey`,`val` from `auto_test_remote`.`tbl_a` select `pkey`,`val` from `auto_test_remote`.`tbl_a` SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' @@ -85,6 +86,7 @@ argument select `pkey`,`val` from `auto_test_remote2`.`tbl_a` select `pkey`,`val` from `auto_test_remote2`.`tbl_a` select `pkey`,`val` from `auto_test_remote2`.`tbl_a` where `pkey` = 2 +select 1 from (select 1) t0 select `pkey`,`val` from `auto_test_remote2`.`tbl_a` SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT pkey, val FROM tbl_a ORDER BY pkey; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_22979.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_22979.result new file mode 100644 index 00000000000..b3049af3e67 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_22979.result @@ -0,0 +1,5 @@ +MDEV-22979 "mysqld --bootstrap" / mysql_install_db hangs when Spider is installed +# Kill the server +# restart +Warnings: +Note 1305 SONAME ha_spider.so does not exist diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26247.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26247.result new file mode 100644 index 00000000000..6eddf9a733e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26247.result @@ -0,0 +1,90 @@ +# +# MDEV-26247 Spider: Valid LEFT JOIN results in ERROR 1064 +# +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; +CREATE TABLE t1 ( +a11 int, +primary key (a11) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( +a21 int, +a22 int, +primary key (a21, a22) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t3 ( +a31 int, +a32 int, +primary key (a31, a32) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (1, 11), (2, 22), (3, 33); +INSERT INTO t3 VALUES (1, 111), (2, 222), (3, 333); +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE t1 ( +a11 int, +primary key (a11) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='srv "s_2_1", table "t1"'; +CREATE TABLE t2 ( +a21 int, +a22 int, +primary key (a21, a22) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='srv "s_2_1", table "t2"'; +CREATE TABLE t3 ( +a31 int, +a32 int, +primary key (a31, a32) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='srv "s_2_1", table "t3"'; +SELECT a22 FROM t1 LEFT JOIN t2 ON a11 = a21 WHERE a11 IN (1); +a22 +11 +SELECT a22 FROM t1 LEFT JOIN t2 ON a11 = a21 - a21 WHERE a11 IN (1); +a22 +NULL +SELECT a22 FROM t2 RIGHT JOIN t1 ON a21 = a11 WHERE a11 IN (1); +a22 +11 +SELECT a22 FROM t2 RIGHT JOIN t1 ON a21 = a11 WHERE a11 IN (1,2); +a22 +11 +22 +SELECT a22, a32 FROM t1 LEFT JOIN t2 ON a11 = a21 RIGHT JOIN t3 on a21 = a31 WHERE a11 IN (1); +a22 a32 +11 111 +SELECT a22, a32 FROM t1 LEFT JOIN t2 ON a11 = a21 - a21 RIGHT JOIN t3 on a21 = a31 - a31 WHERE a11 IN (1); +a22 a32 +SELECT a22, a32 FROM t1 LEFT JOIN t2 ON a11 = a21 RIGHT JOIN t3 on a21 = a31 WHERE a11 IN (1,2); +a22 a32 +11 111 +22 222 +SELECT a22 FROM t2 LEFT JOIN t1 ON a11 = a21 WHERE a11 IN (1); +a22 +11 +SELECT a22 FROM t2 LEFT JOIN t1 ON a11 = a21 - a21 WHERE a11 IN (1); +a22 +SELECT a22 FROM t1 RIGHT JOIN t2 ON a21 = a11 WHERE a11 IN (1); +a22 +11 +SELECT a22 FROM t1 RIGHT JOIN t2 ON a21 = a11 WHERE a11 IN (1,2); +a22 +11 +22 +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 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result index 72921d2e695..34d561f46d1 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result @@ -7,7 +7,7 @@ DROP FUNCTION spider_copy_tables; DROP FUNCTION spider_ping_table; DROP FUNCTION spider_bg_direct_sql; DROP FUNCTION spider_direct_sql; -UNINSTALL SONAME IF EXISTS "ha_spider"; +UNINSTALL SONAME IF EXISTS 'ha_spider'; DROP TABLE IF EXISTS mysql.spider_xa; DROP TABLE IF EXISTS mysql.spider_xa_member; DROP TABLE IF EXISTS mysql.spider_xa_failed_log; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result new file mode 100644 index 00000000000..17f3316b625 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result @@ -0,0 +1,11 @@ +# +# MDEV-27233 Server hangs when using --init-file which loads Spider and creates a Spider table +# +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `c` int(11) DEFAULT NULL +) ENGINE=SPIDER DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +Warnings: +Error 1429 Unable to connect to foreign data source: localhost +Error 1429 Unable to connect to foreign data source: localhost diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result new file mode 100644 index 00000000000..4899f191ada --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result @@ -0,0 +1,18 @@ +# +# MDEV-27575 Spider: UBSAN member access within null pointer of type 'struct st_plugin_int and SIGSEGV in intern_plugin_lock on SHUTDOWN when setting Spider as default storage engine (temporary or global) +# +for master_1 +for child2 +for child3 +call mtr.add_suppression("\\[ERROR\\] Table 'mysql.spider_table_sts' doesn't exist"); +call mtr.add_suppression("\\[ERROR\\] Server shutdown in progress"); +SET GLOBAL default_tmp_storage_engine=spider; +# restart +SET GLOBAL default_storage_engine=Spider; +# restart +for master_1 +for child2 +for child3 +# +# end of test mdev_27575 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28218.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28218.result new file mode 100644 index 00000000000..394d3b271b5 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28218.result @@ -0,0 +1,9 @@ +# +# MDEV-28218 Spider: thread hang/deadlock as result of INSTALL PLUGIN and DROP TABLE +# +INSTALL SONAME 'ha_spider.so'; +DROP TABLE IF EXISTS mysql.spider_tables; +show create table mysql.spider_tables; +ERROR 42S02: Table 'mysql.spider_tables' doesn't exist +Warnings: +Note 1051 Unknown table 'mysql.spider_tables' diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28218_init_file.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28218_init_file.result new file mode 100644 index 00000000000..05c396acb99 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28218_init_file.result @@ -0,0 +1,5 @@ +# +# MDEV-28218 Spider: thread hang/deadlock as result of INSTALL PLUGIN and DROP TABLE +# +show create table mysql.spider_tables; +ERROR 42S02: Table 'mysql.spider_tables' doesn't exist diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28218_mixed.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28218_mixed.result new file mode 100644 index 00000000000..05c396acb99 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28218_mixed.result @@ -0,0 +1,5 @@ +# +# MDEV-28218 Spider: thread hang/deadlock as result of INSTALL PLUGIN and DROP TABLE +# +show create table mysql.spider_tables; +ERROR 42S02: Table 'mysql.spider_tables' doesn't exist diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28739.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28739.result new file mode 100644 index 00000000000..ee497bb3e1e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28739.result @@ -0,0 +1,34 @@ +# +# MDEV-28739 Trying to lock uninitialized mutex or hang upon shutdown after using Spider with query_cache +# +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; +CREATE TABLE tbl_a (id INT); +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +set global query_cache_type= on; +set spider_same_server_link = on; +CREATE TABLE tbl_a ( +id INT +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +SELECT * FROM tbl_a; +id +# restart +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 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result new file mode 100644 index 00000000000..af4bef1efa9 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result @@ -0,0 +1,23 @@ +# +# MDEV-29163 Server crash with SIGSEGV or dynamic-stack-buffer-overflow in spider_db_mbase_util::append_table +# +for master_1 +for child2 +for child3 +CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); +CREATE TABLE t3 (c INT, PRIMARY KEY(c)); +CREATE TABLE t1_spider (a INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't1'"; +CREATE TABLE t2_spider (b INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't2'"; +CREATE TABLE t3_spider (c INT, PRIMARY KEY(c)) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't3'"; +SELECT t1_spider.* FROM t1_spider LEFT JOIN t2_spider LEFT JOIN t3_spider ON b = c ON a = b; +a +DROP TABLE t1_spider, t2_spider, t3_spider, t1, t2, t3; +drop server s; +for master_1 +for child2 +for child3 +# +# end of test mdev_29163 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29421.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29421.result new file mode 100644 index 00000000000..bcbf050d142 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29421.result @@ -0,0 +1,19 @@ +for master_1 +for child2 +for child3 +set @old_table_open_cache=@@global.table_open_cache; +set global table_open_cache=10; +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t (c INT) ENGINE=InnoDB; +CREATE TABLE t_s (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv", TABLE "t"'; +CREATE TABLE t1 (a INT) ENGINE=Spider; +SELECT * FROM t1; +ERROR HY000: Unable to connect to foreign data source: localhost +SELECT * FROM information_schema.tables; +DROP TABLE t, t_s, t1; +drop server srv; +set global table_open_cache=@old_table_open_cache; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29456.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29456.result new file mode 100644 index 00000000000..4d9095830d1 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29456.result @@ -0,0 +1,41 @@ +# +# MDEV-29456 Spider hangs in 'Waiting for table metadata lock' state on CREATE TABLE after LOCK TABLES +# +for master_1 +for child2 +for child3 +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t1 (c int); +create table t2 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +CREATE TABLE t3 (c INT KEY) ENGINE=Spider; +LOCK TABLE t2 WRITE; +LOCK TABLE t3 WRITE; +ERROR HY000: Unable to connect to foreign data source: localhost +UNLOCK TABLES; +drop table t1, t2, t3; +CREATE TABLE t (c INT) ENGINE=InnoDB; +CREATE TABLE t1 (c INT) ENGINE=Spider; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +LOCK TABLES t2 WRITE; +LOCK TABLES t1 READ; +ERROR HY000: Unable to connect to foreign data source: localhost +CREATE TABLE t (c INT) ENGINE=Spider; +ERROR 42S01: Table 't' already exists +drop table t, t1, t2; +CREATE TABLE t (c INT) ENGINE=InnoDB; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +CREATE TABLE t3 (c INT) ENGINE=InnoDB; +LOCK TABLES t2 WRITE; +LOCK TABLES mysql.proc WRITE,mysql.user WRITE; +ERROR HY000: You can't combine write-locking of system tables with other tables or lock types +INSERT INTO t3 SELECT * FROM t; +drop table t, t2, t3; +drop server srv; +for master_1 +for child2 +for child3 +# +# end of test mdev_29456 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29667.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29667.result new file mode 100644 index 00000000000..f2e90760ed4 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29667.result @@ -0,0 +1,40 @@ +# +# MDEV-29667 Server hangs on DROP DATABASE after failing LOCK TABLES on Spider 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; +CREATE TABLE tbl_a ( +a INT +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +a INT +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +CREATE TABLE tbl_b ( +a INT +) ENGINE=Spider DEFAULT CHARSET=utf8; +LOCK TABLES tbl_a WRITE; +LOCK TABLES tbl_b READ, tbl_a READ; +ERROR HY000: Unable to connect to foreign data source: localhost +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 mdev_29667 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29963.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29963.result new file mode 100644 index 00000000000..17390346a99 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29963.result @@ -0,0 +1,43 @@ +# +# MDEV-29963 SIGSEGV in spider_db_mbase::append_lock_tables on LOCK TABLES +# +for master_1 +for child2 +for child3 +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t (a INT) ENGINE=Spider; +CREATE TABLE t2 (b INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +LOCK TABLES t AS a READ,t2 AS b LOW_PRIORITY WRITE,t2 AS c WRITE; +ERROR HY000: Unable to connect to foreign data source: localhost +DROP TABLE t2; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +LOCK TABLES t2 WRITE; +ERROR HY000: Unable to connect to foreign data source: localhost +DROP TABLE t2,t; +CREATE TABLE t (a INT); +CREATE TABLE t1 (a INT) ENGINE=Spider; +CREATE TABLE t2 (b INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +LOCK TABLES t1 READ, t2 WRITE; +ERROR HY000: Unable to connect to foreign data source: localhost +DROP TABLE t2; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +LOCK TABLES t2 WRITE; +UNLOCK TABLES; +DROP TABLE t, t1, t2; +CREATE TABLE t1 (c INT) ENGINE=Spider; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT="WRAPPER 'mysql',srv 'srv',TABLE 't1'"; +LOCK TABLES t1 WRITE,t2 WRITE; +ERROR HY000: Unable to connect to foreign data source: localhost +TRUNCATE t2; +ERROR HY000: Unable to connect to foreign data source: localhost +LOCK TABLES t2 AS o WRITE; +ERROR HY000: Unable to connect to foreign data source: localhost +drop table t1, t2; +drop server srv; +for master_1 +for child2 +for child3 +# +# end of test mdev_29963 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30014.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30014.result new file mode 100644 index 00000000000..e1dca495047 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30014.result @@ -0,0 +1,38 @@ +# +# MDEV-30014 heap-use-after-free in ha_spider::lock_tables(), highly sporadic SIGSEGV in intern_close_table +# +for master_1 +for child2 +for child3 +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t1 (c int); +create table t2 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +CREATE TABLE t3 (c INT KEY) ENGINE=Spider; +LOCK TABLE t2 WRITE,t3 WRITE; +ERROR HY000: Unable to connect to foreign data source: localhost +CREATE TABLE t4 (c INT) ENGINE=Spider; +FLUSH NO_WRITE_TO_BINLOG TABLES t4 WITH READ LOCK; +Warnings: +Error 1429 Unable to connect to foreign data source: localhost +Error 1429 Unable to connect to foreign data source: localhost +Error 1429 Unable to connect to foreign data source: localhost +Error 1429 Unable to connect to foreign data source: localhost +UNLOCK TABLES; +drop table t1, t2, t3, t4; +create table t1 (c int); +create table t2 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +CREATE TABLE t3 (c INT KEY) ENGINE=Spider; +LOCK TABLE t2 WRITE, t3 WRITE; +ERROR HY000: Unable to connect to foreign data source: localhost +UNLOCK TABLES; +drop table t1, t2, t3; +drop server srv; +for master_1 +for child2 +for child3 +# +# end of test mdev_30014 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result index df0f6949280..7a0b6a2094a 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result @@ -1,3 +1,8 @@ # # MDEV-30370 mariadbd hangs when running with --wsrep-recover and --plugin-load-add=ha_spider.so # +call mtr.add_suppression(".*\\[Warning\\] InnoDB: Skipping buffer pool dump/restore during wsrep recovery"); +# Kill the server +# restart +Warnings: +Note 1305 SONAME ha_spider.so does not exist diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result new file mode 100644 index 00000000000..58873d2c6e5 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result @@ -0,0 +1,22 @@ +# +# MDEV-30392 Syntax error upon query with subquery from Spider table +# +for master_1 +for child2 +for child3 +CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (a INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 'srv', table 't1'"; +SELECT a FROM t2 WHERE a IN ( SELECT a FROM t2 ); +a +1 +2 +DROP TABLE t1, t2; +DROP SERVER srv; +for master_1 +for child2 +for child3 +# +# end of test mdev_30392 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result new file mode 100644 index 00000000000..94b76de7df4 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result @@ -0,0 +1,22 @@ +# +# MDEV-31645 Spider doesn't recognize semi JOIN +# +for master_1 +for child2 +for child3 +CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t1 ( a bigint(20) NOT NULL, b bigint(20) DEFAULT 0, PRIMARY KEY (a)); +CREATE TABLE t2 ( a bigint(20) NOT NULL, b bigint(20) DEFAULT 0, PRIMARY KEY (a)) ENGINE=SPIDER COMMENT='srv "srv", WRAPPER "mysql", TABLE "t1"'; +SELECT * FROM t2 WHERE b IN (SELECT b FROM t2 WHERE a > 10); +a b +SELECT * FROM t2 +WHERE A BETWEEN 0 AND 10 AND B IN(SELECT B FROM t2 WHERE A BETWEEN 11 AND 20); +a b +drop table t1, t2; +drop server srv; +for master_1 +for child2 +for child3 +# +# end of test mdev_31645 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_32683.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_32683.result new file mode 100644 index 00000000000..350a723f6b1 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_32683.result @@ -0,0 +1,16 @@ +# +# MDEV-32683 Spider engine does not load with non-default alter-algorithm +# +set global alter_algorithm=INSTANT; +install plugin spider soname 'ha_spider'; +select plugin_name, plugin_status, plugin_type, plugin_license, load_option from information_schema.plugins where plugin_name like 'spider'; +plugin_name plugin_status plugin_type plugin_license load_option +SPIDER ACTIVE STORAGE ENGINE GPL ON +uninstall plugin spider; +drop table mysql.spider_link_failed_log, mysql.spider_link_mon_servers, mysql.spider_tables, mysql.spider_table_crd, mysql.spider_table_position_for_recovery, mysql.spider_table_sts, mysql.spider_xa, mysql.spider_xa_failed_log, mysql.spider_xa_member; +drop function spider_direct_sql; +drop function spider_bg_direct_sql; +drop function spider_ping_table; +drop function spider_copy_tables; +drop function spider_flush_table_mon_cache; +set global alter_algorithm=DEFAULT; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_32753.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_32753.result new file mode 100644 index 00000000000..4260d80f0cf --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_32753.result @@ -0,0 +1,10 @@ +# +# MDEV-32753 Spider engine does not load in ORACLE mode +# +select * from mysql.plugin; +name dl +create table t (c int) Engine=SPIDER; +drop table t; +# +# end of test mdev_32753 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_32753_after_start.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_32753_after_start.result new file mode 100644 index 00000000000..4e046d16708 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_32753_after_start.result @@ -0,0 +1,14 @@ +# +# MDEV-32753 Spider engine does not load in ORACLE mode +# +install soname 'ha_spider'; +select * from mysql.plugin; +name dl +SPIDER ha_spider.so +SPIDER_ALLOC_MEM ha_spider.so +SPIDER_WRAPPER_PROTOCOLS ha_spider.so +create table t (c int) Engine=SPIDER; +drop table t; +# +# end of test mdev_32753_after_start +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_32753_after_start_session.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_32753_after_start_session.result new file mode 100644 index 00000000000..b9d025633e2 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_32753_after_start_session.result @@ -0,0 +1,17 @@ +# +# MDEV-32753 Spider engine does not load in ORACLE mode +# +set @old_sql_mode=@@sql_mode; +SET @@sql_mode = CONCAT(@@sql_mode, ',ORACLE'); +install soname 'ha_spider'; +select * from mysql.plugin; +name dl +SPIDER ha_spider.so +SPIDER_ALLOC_MEM ha_spider.so +SPIDER_WRAPPER_PROTOCOLS ha_spider.so +create table t (c int) Engine=SPIDER; +drop table t; +set sql_mode=@old_sql_mode; +# +# end of test mdev_32753_after_start +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result new file mode 100644 index 00000000000..04e5ed6da68 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result @@ -0,0 +1,7 @@ +# +# plugin-load-add=ha_spider +# +select * from mysql.plugin; +name dl +create table t (c int) Engine=SPIDER; +drop table t; diff --git a/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_spider.result b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_spider.result new file mode 100644 index 00000000000..04e5ed6da68 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_spider.result @@ -0,0 +1,7 @@ +# +# plugin-load-add=ha_spider +# +select * from mysql.plugin; +name dl +create table t (c int) Engine=SPIDER; +drop table t; diff --git a/storage/spider/mysql-test/spider/bugfix/r/spider_join_with_non_spider.result b/storage/spider/mysql-test/spider/bugfix/r/spider_join_with_non_spider.result new file mode 100644 index 00000000000..b9c1c5c9de5 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/spider_join_with_non_spider.result @@ -0,0 +1,23 @@ +# +# Test joining a spider table with a non-spider table +# +for master_1 +for child2 +for child3 +CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t1 (c int); +create table t2 (d int); +insert into t2 values (1), (2); +create table t3 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +insert into t3 values (2), (3); +select c from t3 join t2 on c = d; +c +2 +drop table t1, t2, t3; +drop server srv; +for master_1 +for child2 +for child3 +# +# end of test spider_join_with_non_spider +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/spider_table_sts.result b/storage/spider/mysql-test/spider/bugfix/r/spider_table_sts.result deleted file mode 100644 index f915cc951b1..00000000000 --- a/storage/spider/mysql-test/spider/bugfix/r/spider_table_sts.result +++ /dev/null @@ -1,38 +0,0 @@ -for master_1 -for child2 -for child3 -connection master_1; -alter table mysql.spider_table_sts drop column checksum; -insert into mysql.spider_table_sts values ('auto_test_local', 'tbl_a', 0, 0, 0, 0, 0, '2019-01-01 00:00:00', '2019-01-01 00:00:00', '2019-01-01 00:00:00'); - -this test is for MDEV-19842 - -drop and create databases -connection master_1; -CREATE DATABASE auto_test_local; -USE auto_test_local; - -create table -connection master_1; -CREATE TABLE tbl_a ( -pkey int NOT NULL, -PRIMARY KEY (pkey) -) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1 - -select test 1 -connection master_1; -SELECT pkey FROM tbl_a; -ERROR HY000: System table spider_table_sts is different version - -deinit -connection master_1; -DROP DATABASE IF EXISTS auto_test_local; -ERROR HY000: System table spider_table_sts is different version -connection master_1; -alter table mysql.spider_table_sts add column checksum bigint unsigned default null after update_time; -DROP DATABASE IF EXISTS auto_test_local; -for master_1 -for child2 -for child3 - -end of test diff --git a/storage/spider/mysql-test/spider/bugfix/r/subquery.result b/storage/spider/mysql-test/spider/bugfix/r/subquery.result new file mode 100644 index 00000000000..c6ea45e2dc0 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/subquery.result @@ -0,0 +1,24 @@ +# +# Test spider select with subqueries +# +for master_1 +for child2 +for child3 +CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t1 (c1 int); +create table t2 (c2 int); +insert into t1 values (1), (2); +insert into t2 values (0), (1), (2); +create table t1s (c1 int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +create table t2s (c2 int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +select c1 from t1s, (select c2 from t2s where c2 > 0) t where c1 + 1 = c2; +c1 +1 +drop table t1, t2, t1s, t2s; +drop server srv; +for master_1 +for child2 +for child3 +# +# end of test subquery +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early.result b/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early.result new file mode 100644 index 00000000000..b84f60a67fb --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early.result @@ -0,0 +1,43 @@ +# +# Test that udf created by inserting into mysql_func works as expected +# +CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( +HOST 'localhost', +DATABASE 'auto_test_local', +USER 'root', +PASSWORD '', +SOCKET '$MASTER_1_MYSOCK' + ); +CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS ( +HOST 'localhost', +DATABASE 'auto_test_remote', +USER 'root', +PASSWORD '', +SOCKET '$CHILD2_1_MYSOCK' + ); +connect master_1, localhost, root, , , $MASTER_1_MYPORT, $MASTER_1_MYSOCK; +connect child2_1, localhost, root, , , $CHILD2_1_MYPORT, $CHILD2_1_MYSOCK; +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +a INT +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +insert into tbl_a values (42); +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +a INT +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +create temporary table results (a int); +SELECT SPIDER_DIRECT_SQL('select * from tbl_a', 'results', 'srv "s_2_1", database "auto_test_remote"'); +SPIDER_DIRECT_SQL('select * from tbl_a', 'results', 'srv "s_2_1", database "auto_test_remote"') +1 +select * from results; +a +42 +connection master_1; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; diff --git a/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early_init_file.result b/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early_init_file.result new file mode 120000 index 00000000000..045ddc4372c --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early_init_file.result @@ -0,0 +1 @@ +udf_mysql_func_early.result \ No newline at end of file diff --git a/storage/spider/mysql-test/spider/bugfix/t/spider_table_sts.cnf b/storage/spider/mysql-test/spider/bugfix/t/gbh_outer_fields_in_join.cnf similarity index 71% rename from storage/spider/mysql-test/spider/bugfix/t/spider_table_sts.cnf rename to storage/spider/mysql-test/spider/bugfix/t/gbh_outer_fields_in_join.cnf index b0853e32654..05dfd8a0bce 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/spider_table_sts.cnf +++ b/storage/spider/mysql-test/spider/bugfix/t/gbh_outer_fields_in_join.cnf @@ -1,2 +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/gbh_outer_fields_in_join.test b/storage/spider/mysql-test/spider/bugfix/t/gbh_outer_fields_in_join.test new file mode 100644 index 00000000000..f60abc3049d --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/gbh_outer_fields_in_join.test @@ -0,0 +1,46 @@ +--echo # +--echo # MDEV-26247 Spider: Valid LEFT JOIN results in ERROR 1064 +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +eval CREATE TABLE t1 (a int) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; +eval CREATE TABLE t2 (a int) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; +eval CREATE TABLE t3 (a int) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1), (2); +INSERT INTO t3 VALUES (1), (2), (3); + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; + +eval CREATE TABLE t1 (a int) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='srv "s_2_1", table "t1"'; +eval CREATE TABLE t2 (a int) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='srv "s_2_1", table "t2"'; +eval CREATE TABLE t3 (a int) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='srv "s_2_1", table "t3"'; + +select * from t3 left join t1 on t3.a = t1.a left join t2 on t3.a = t2.a; +select * from t1 left join t2 on t1.a = t2.a right join t3 on t3.a = t1.a; +select * from t3 left join (t1 left join t2 on t1.a = t2.a) on t3.a = t1.a; + +drop table t1, t2, t3; + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; +--connection child2_1 +DROP DATABASE IF EXISTS 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_22979.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_22979.test new file mode 100644 index 00000000000..7f42bd734c6 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_22979.test @@ -0,0 +1,18 @@ +--echo MDEV-22979 "mysqld --bootstrap" / mysql_install_db hangs when Spider is installed + +# This test is not the most faithful, as it does not have any +# dependency problems on the existence of the `mysql` database. To +# test MDEV-22979 faithfully, a mysql_install_db invocation with +# --plugin-load-add=ha_spider should be run. We cannot run it in mtr +# because we do not have access to --srcdir. + +let $MYSQLD_DATADIR= `select @@datadir`; +let $PLUGIN_DIR=`select @@plugin_dir`; +--source include/kill_mysqld.inc +--write_file $MYSQLTEST_VARDIR/tmp/mdev_22979.sql +drop table if exists foo.bar; +EOF +--exec $MYSQLD_CMD --datadir=$MYSQLD_DATADIR --bootstrap --plugin-dir=$PLUGIN_DIR --plugin-load-add=ha_spider < $MYSQLTEST_VARDIR/tmp/mdev_22979.sql +--source include/start_mysqld.inc +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26247.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_26247.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26247.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_26247.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26247.test new file mode 100644 index 00000000000..80328e05fd6 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26247.test @@ -0,0 +1,78 @@ +--echo # +--echo # MDEV-26247 Spider: Valid LEFT JOIN results in ERROR 1064 +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +eval CREATE TABLE t1 ( + a11 int, + primary key (a11) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +eval CREATE TABLE t2 ( + a21 int, + a22 int, + primary key (a21, a22) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +eval CREATE TABLE t3 ( + a31 int, + a32 int, + primary key (a31, a32) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +INSERT INTO t1 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (1, 11), (2, 22), (3, 33); +INSERT INTO t3 VALUES (1, 111), (2, 222), (3, 333); + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; + +eval CREATE TABLE t1 ( + a11 int, + primary key (a11) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='srv "s_2_1", table "t1"'; + +eval CREATE TABLE t2 ( + a21 int, + a22 int, + primary key (a21, a22) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='srv "s_2_1", table "t2"'; + +eval CREATE TABLE t3 ( + a31 int, + a32 int, + primary key (a31, a32) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='srv "s_2_1", table "t3"'; + +SELECT a22 FROM t1 LEFT JOIN t2 ON a11 = a21 WHERE a11 IN (1); +SELECT a22 FROM t1 LEFT JOIN t2 ON a11 = a21 - a21 WHERE a11 IN (1); +SELECT a22 FROM t2 RIGHT JOIN t1 ON a21 = a11 WHERE a11 IN (1); +SELECT a22 FROM t2 RIGHT JOIN t1 ON a21 = a11 WHERE a11 IN (1,2); +SELECT a22, a32 FROM t1 LEFT JOIN t2 ON a11 = a21 RIGHT JOIN t3 on a21 = a31 WHERE a11 IN (1); +SELECT a22, a32 FROM t1 LEFT JOIN t2 ON a11 = a21 - a21 RIGHT JOIN t3 on a21 = a31 - a31 WHERE a11 IN (1); +SELECT a22, a32 FROM t1 LEFT JOIN t2 ON a11 = a21 RIGHT JOIN t3 on a21 = a31 WHERE a11 IN (1,2); +SELECT a22 FROM t2 LEFT JOIN t1 ON a11 = a21 WHERE a11 IN (1); +SELECT a22 FROM t2 LEFT JOIN t1 ON a11 = a21 - a21 WHERE a11 IN (1); +SELECT a22 FROM t1 RIGHT JOIN t2 ON a21 = a11 WHERE a11 IN (1); +SELECT a22 FROM t1 RIGHT JOIN t2 ON a21 = a11 WHERE a11 IN (1,2); + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; +--connection child2_1 +DROP DATABASE IF EXISTS 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_27233.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt new file mode 100644 index 00000000000..b046607108b --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt @@ -0,0 +1 @@ +--init-file=$MTR_SUITE_DIR/t/mdev_27233.sql diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql new file mode 100644 index 00000000000..2be9ec1fad6 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql @@ -0,0 +1,3 @@ +INSTALL SONAME 'ha_spider.so'; +USE test; +CREATE TABLE t (c INT) ENGINE=SPIDER; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test new file mode 100644 index 00000000000..88e70f4b689 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test @@ -0,0 +1,7 @@ +--echo # +--echo # MDEV-27233 Server hangs when using --init-file which loads Spider and creates a Spider table +--echo # +# ps protocol eats warnings +--disable_ps_protocol +show create table t; +--enable_ps_protocol diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27575.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27575.test new file mode 100644 index 00000000000..6f291c6f690 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27575.test @@ -0,0 +1,27 @@ +--echo # +--echo # MDEV-27575 Spider: UBSAN member access within null pointer of type 'struct st_plugin_int and SIGSEGV in intern_plugin_lock on SHUTDOWN when setting Spider as default storage engine (temporary or global) +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +# These suppressions are a workaround and should not be needed once +# MDEV-29870 is done. +call mtr.add_suppression("\\[ERROR\\] Table 'mysql.spider_table_sts' doesn't exist"); +call mtr.add_suppression("\\[ERROR\\] Server shutdown in progress"); +SET GLOBAL default_tmp_storage_engine=spider; +--source include/restart_mysqld.inc + +SET GLOBAL default_storage_engine=Spider; +--source include/restart_mysqld.inc + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test mdev_27575 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28218.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218.test new file mode 100644 index 00000000000..91fdf168f53 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218.test @@ -0,0 +1,10 @@ +--echo # +--echo # MDEV-28218 Spider: thread hang/deadlock as result of INSTALL PLUGIN and DROP TABLE +--echo # +INSTALL SONAME 'ha_spider.so'; +DROP TABLE IF EXISTS mysql.spider_tables; +--error ER_NO_SUCH_TABLE +show create table mysql.spider_tables; + +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.opt new file mode 100644 index 00000000000..556df9cdc10 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.opt @@ -0,0 +1 @@ +--init-file=$MTR_SUITE_DIR/t/mdev_28218_init_file.sql diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.sql b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.sql new file mode 100644 index 00000000000..ef3e1e91ce1 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.sql @@ -0,0 +1,2 @@ +INSTALL PLUGIN spider SONAME 'ha_spider.so'; +DROP TABLE IF EXISTS mysql.spider_tables; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.test new file mode 100644 index 00000000000..9152df4f684 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.test @@ -0,0 +1,7 @@ +--echo # +--echo # MDEV-28218 Spider: thread hang/deadlock as result of INSTALL PLUGIN and DROP TABLE +--echo # +# This is a variant of the testcase in MDEV-28218, where we put the +# queries are in an init file +--error ER_NO_SUCH_TABLE +show create table mysql.spider_tables; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.opt new file mode 100644 index 00000000000..5561f625c8e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.opt @@ -0,0 +1,2 @@ +--plugin-load-add=ha_spider +--init-file=$MTR_SUITE_DIR/t/mdev_28218_mixed.sql diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.sql b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.sql new file mode 100644 index 00000000000..e408ae0c04a --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS mysql.spider_tables; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.test new file mode 100644 index 00000000000..184a5399312 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.test @@ -0,0 +1,8 @@ +--echo # +--echo # MDEV-28218 Spider: thread hang/deadlock as result of INSTALL PLUGIN and DROP TABLE +--echo # +# this is a variant of the testcase in MDEV-28218, where we load +# spider early with --plugin_load_add, and execute the drop table +# query in an init file +--error ER_NO_SUCH_TABLE +show create table mysql.spider_tables; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28683.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28683.test new file mode 100644 index 00000000000..0508a9993c5 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28683.test @@ -0,0 +1,29 @@ +--echo # +--echo # MDEV-28683 Spider: SIGSEGV in spider_db_direct_delete, SIGSEGV in spider_db_connect, ASAN: heap-use-after-free in spider_db_direct_delete +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +CREATE TABLE t (c INT) ENGINE=Spider; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +SELECT * FROM t; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +INSERT INTO t (SELECT 1 FROM t); +LOCK TABLES t WRITE CONCURRENT; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +DELETE FROM t; + +UNLOCK TABLES; +DROP TABLE t; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test mdev_28683 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28739.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_28739.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28739.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_28739.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28739.test new file mode 100644 index 00000000000..d4ac8e42d86 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28739.test @@ -0,0 +1,41 @@ +--echo # +--echo # MDEV-28739 Trying to lock uninitialized mutex or hang upon shutdown after using Spider with query_cache +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +CREATE TABLE tbl_a (id INT); + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; + +set global query_cache_type= on; +set spider_same_server_link = on; + +eval CREATE TABLE tbl_a ( + id INT +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; + +SELECT * FROM tbl_a; + +--source include/restart_mysqld.inc + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; +--connection child2_1 +DROP DATABASE IF EXISTS 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_28739_simple.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28739_simple.test new file mode 100644 index 00000000000..7a011520bb6 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28739_simple.test @@ -0,0 +1,30 @@ +--echo # +--echo # MDEV-28739 Trying to lock uninitialized mutex or hang upon shutdown after using Spider with query_cache +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +# set @@global.debug_dbug="+d,xid_thd_trace,enter,exit,info,error:o,/tmp/trace2.out:i:F:L"; +#set @@global.debug_dbug="d:t:i:o,mysqld.trace"; + +set global query_cache_type= on; +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +SELECT * FROM t1; +#shutdown; +--source include/restart_mysqld.inc +drop table t1, t2; +drop server srv; + +--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_29163.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29163.test new file mode 100644 index 00000000000..ac116fd0e4f --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29163.test @@ -0,0 +1,31 @@ +--echo # +--echo # MDEV-29163 Server crash with SIGSEGV or dynamic-stack-buffer-overflow in spider_db_mbase_util::append_table +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +evalp CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); +CREATE TABLE t3 (c INT, PRIMARY KEY(c)); + +CREATE TABLE t1_spider (a INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't1'"; +CREATE TABLE t2_spider (b INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't2'"; +CREATE TABLE t3_spider (c INT, PRIMARY KEY(c)) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't3'"; + +SELECT t1_spider.* FROM t1_spider LEFT JOIN t2_spider LEFT JOIN t3_spider ON b = c ON a = b; + +# Cleanup +DROP TABLE t1_spider, t2_spider, t3_spider, t1, t2, t3; +drop server s; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test mdev_29163 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29421.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29421.test new file mode 100644 index 00000000000..47ad42d3d92 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29421.test @@ -0,0 +1,26 @@ +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +set @old_table_open_cache=@@global.table_open_cache; +set global table_open_cache=10; +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t (c INT) ENGINE=InnoDB; +CREATE TABLE t_s (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv", TABLE "t"'; +CREATE TABLE t1 (a INT) ENGINE=Spider; +--error 1429 +SELECT * FROM t1; +--disable_result_log +SELECT * FROM information_schema.tables; +--enable_result_log +DROP TABLE t, t_s, t1; +drop server srv; +set global table_open_cache=@old_table_open_cache; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29456.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29456.test new file mode 100644 index 00000000000..16291f82075 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29456.test @@ -0,0 +1,52 @@ +--echo # +--echo # MDEV-29456 Spider hangs in 'Waiting for table metadata lock' state on CREATE TABLE after LOCK TABLES +--echo # +--source include/have_innodb.inc +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +create table t1 (c int); +create table t2 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +CREATE TABLE t3 (c INT KEY) ENGINE=Spider; +LOCK TABLE t2 WRITE; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLE t3 WRITE; +UNLOCK TABLES; +drop table t1, t2, t3; + +CREATE TABLE t (c INT) ENGINE=InnoDB; +CREATE TABLE t1 (c INT) ENGINE=Spider; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +LOCK TABLES t2 WRITE; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLES t1 READ; +--error ER_TABLE_EXISTS_ERROR +CREATE TABLE t (c INT) ENGINE=Spider; +drop table t, t1, t2; + +# MDEV-30049 +CREATE TABLE t (c INT) ENGINE=InnoDB; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +CREATE TABLE t3 (c INT) ENGINE=InnoDB; +LOCK TABLES t2 WRITE; +--error 1428 +LOCK TABLES mysql.proc WRITE,mysql.user WRITE; # ERROR 1428 (HY000): You can't combine write-locking of system tables with other tables or lock types +INSERT INTO t3 SELECT * FROM t; +drop table t, t2, t3; + +drop server srv; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test mdev_29456 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29667.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_29667.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29667.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_29667.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29667.test new file mode 100644 index 00000000000..c96eb60efc5 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29667.test @@ -0,0 +1,44 @@ +--echo # +--echo # MDEV-29667 Server hangs on DROP DATABASE after failing LOCK TABLES on Spider table +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +eval CREATE TABLE tbl_a ( + a INT +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; +eval CREATE TABLE tbl_a ( + a INT +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; +eval CREATE TABLE tbl_b ( + a INT +) $MASTER_1_ENGINE $MASTER_1_CHARSET; + +LOCK TABLES tbl_a WRITE; +--error 1429 +LOCK TABLES tbl_b READ, tbl_a READ; + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_query_log +--enable_result_log +--echo # +--echo # end of test mdev_29667 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29963.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29963.test new file mode 100644 index 00000000000..ab7a4ded07c --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29963.test @@ -0,0 +1,55 @@ +--echo # +--echo # MDEV-29963 SIGSEGV in spider_db_mbase::append_lock_tables on LOCK TABLES +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +CREATE TABLE t (a INT) ENGINE=Spider; +CREATE TABLE t2 (b INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLES t AS a READ,t2 AS b LOW_PRIORITY WRITE,t2 AS c WRITE; +DROP TABLE t2; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLES t2 WRITE; +DROP TABLE t2,t; + +# A less complex scenario +CREATE TABLE t (a INT); +CREATE TABLE t1 (a INT) ENGINE=Spider; +CREATE TABLE t2 (b INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLES t1 READ, t2 WRITE; +DROP TABLE t2; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; +LOCK TABLES t2 WRITE; +UNLOCK TABLES; +DROP TABLE t, t1, t2; + +# MDEV-31357 +CREATE TABLE t1 (c INT) ENGINE=Spider; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT="WRAPPER 'mysql',srv 'srv',TABLE 't1'"; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLES t1 WRITE,t2 WRITE; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +TRUNCATE t2; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLES t2 AS o WRITE; +drop table t1, t2; + +drop server srv; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test mdev_29963 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30014.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30014.test new file mode 100644 index 00000000000..4dc3dafab24 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30014.test @@ -0,0 +1,45 @@ +--echo # +--echo # MDEV-30014 heap-use-after-free in ha_spider::lock_tables(), highly sporadic SIGSEGV in intern_close_table +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +create table t1 (c int); +create table t2 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +CREATE TABLE t3 (c INT KEY) ENGINE=Spider; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLE t2 WRITE,t3 WRITE; +CREATE TABLE t4 (c INT) ENGINE=Spider; +FLUSH NO_WRITE_TO_BINLOG TABLES t4 WITH READ LOCK; +UNLOCK TABLES; + +drop table t1, t2, t3, t4; + +# This is a test case in MDEV-29456 but it is more like the above +# case. +create table t1 (c int); +create table t2 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +CREATE TABLE t3 (c INT KEY) ENGINE=Spider; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLE t2 WRITE, t3 WRITE; +UNLOCK TABLES; +drop table t1, t2, t3; + +drop server srv; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test mdev_30014 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test index 0e982d90ba6..73376d27b81 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test @@ -3,7 +3,9 @@ --echo # MDEV-30370 mariadbd hangs when running with --wsrep-recover and --plugin-load-add=ha_spider.so --echo # -let $MYSQLD_DATADIR=$MYSQLTEST_VARDIR/mdev_30370; ---mkdir $MYSQLD_DATADIR ---exec $MYSQLD_BOOTSTRAP_CMD --wsrep-recover --plugin-load-add=ha_spider.so --datadir=$MYSQLD_DATADIR ---rmdir $MYSQLD_DATADIR +call mtr.add_suppression(".*\\[Warning\\] InnoDB: Skipping buffer pool dump/restore during wsrep recovery"); +--source include/kill_mysqld.inc +--exec $MYSQLD_LAST_CMD --wsrep-recover --plugin-load-add=ha_spider +--source include/start_mysqld.inc +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test new file mode 100644 index 00000000000..03417013b07 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test @@ -0,0 +1,28 @@ +--echo # +--echo # MDEV-30392 Syntax error upon query with subquery from Spider table +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (a INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 'srv', table 't1'"; + +SELECT a FROM t2 WHERE a IN ( SELECT a FROM t2 ); + +# Cleanup + +DROP TABLE t1, t2; +DROP SERVER srv; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test mdev_30392 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test new file mode 100644 index 00000000000..bec9dd6c316 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test @@ -0,0 +1,26 @@ +--echo # +--echo # MDEV-31645 Spider doesn't recognize semi JOIN +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +CREATE TABLE t1 ( a bigint(20) NOT NULL, b bigint(20) DEFAULT 0, PRIMARY KEY (a)); +CREATE TABLE t2 ( a bigint(20) NOT NULL, b bigint(20) DEFAULT 0, PRIMARY KEY (a)) ENGINE=SPIDER COMMENT='srv "srv", WRAPPER "mysql", TABLE "t1"'; + +SELECT * FROM t2 WHERE b IN (SELECT b FROM t2 WHERE a > 10); +SELECT * FROM t2 +WHERE A BETWEEN 0 AND 10 AND B IN(SELECT B FROM t2 WHERE A BETWEEN 11 AND 20); +drop table t1, t2; +drop server srv; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test mdev_31645 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_32683.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_32683.test new file mode 100644 index 00000000000..d208957f048 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_32683.test @@ -0,0 +1,14 @@ +--echo # +--echo # MDEV-32683 Spider engine does not load with non-default alter-algorithm +--echo # +set global alter_algorithm=INSTANT; +install plugin spider soname 'ha_spider'; +select plugin_name, plugin_status, plugin_type, plugin_license, load_option from information_schema.plugins where plugin_name like 'spider'; +uninstall plugin spider; +drop table mysql.spider_link_failed_log, mysql.spider_link_mon_servers, mysql.spider_tables, mysql.spider_table_crd, mysql.spider_table_position_for_recovery, mysql.spider_table_sts, mysql.spider_xa, mysql.spider_xa_failed_log, mysql.spider_xa_member; +drop function spider_direct_sql; +drop function spider_bg_direct_sql; +drop function spider_ping_table; +drop function spider_copy_tables; +drop function spider_flush_table_mon_cache; +set global alter_algorithm=DEFAULT; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_32753.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753.opt new file mode 100644 index 00000000000..c3151b0e44a --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753.opt @@ -0,0 +1,2 @@ +--sql-mode=oracle +--plugin-load-add=ha_spider diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_32753.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753.test new file mode 100644 index 00000000000..2be7289fd74 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753.test @@ -0,0 +1,12 @@ +--echo # +--echo # MDEV-32753 Spider engine does not load in ORACLE mode +--echo # + +# This test tests spider init during server startup under global +# ORACLE mode +select * from mysql.plugin; +create table t (c int) Engine=SPIDER; +drop table t; +--echo # +--echo # end of test mdev_32753 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.opt new file mode 100644 index 00000000000..a918abb90b9 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.opt @@ -0,0 +1 @@ +--sql-mode=oracle diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.test new file mode 100644 index 00000000000..281d2adce64 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.test @@ -0,0 +1,19 @@ +--echo # +--echo # MDEV-32753 Spider engine does not load in ORACLE mode +--echo # + +# This test tests spider init after startup under global ORACLE mode +install soname 'ha_spider'; +select * from mysql.plugin; +create table t (c int) Engine=SPIDER; +drop table t; + +--disable_query_log +--disable_result_log +--source ../../include/clean_up_spider.inc +--enable_result_log +--enable_query_log + +--echo # +--echo # end of test mdev_32753_after_start +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start_session.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start_session.test new file mode 100644 index 00000000000..bf7bdb4f884 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start_session.test @@ -0,0 +1,22 @@ +--echo # +--echo # MDEV-32753 Spider engine does not load in ORACLE mode +--echo # + +# This test tests spider init after startup under session ORACLE mode +set @old_sql_mode=@@sql_mode; +SET @@sql_mode = CONCAT(@@sql_mode, ',ORACLE'); +install soname 'ha_spider'; +select * from mysql.plugin; +create table t (c int) Engine=SPIDER; +drop table t; +set sql_mode=@old_sql_mode; + +--disable_query_log +--disable_result_log +--source ../../include/clean_up_spider.inc +--enable_result_log +--enable_query_log + +--echo # +--echo # end of test mdev_32753_after_start +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.opt b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.opt new file mode 100644 index 00000000000..924ea4e31ef --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.opt @@ -0,0 +1 @@ +--plugin-load-add=ha_spider diff --git a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test new file mode 100644 index 00000000000..396145fba2e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test @@ -0,0 +1,7 @@ +--echo # +--echo # plugin-load-add=ha_spider +--echo # +# A simple test that tests plugin-load-add=ha_spider +select * from mysql.plugin; +create table t (c int) Engine=SPIDER; +drop table t; diff --git a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.opt b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.opt new file mode 100644 index 00000000000..bf4180ca67a --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.opt @@ -0,0 +1 @@ +--plugin-load-add=SPIDER=ha_spider diff --git a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.test b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.test new file mode 100644 index 00000000000..49db6c38a28 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.test @@ -0,0 +1,7 @@ +--echo # +--echo # plugin-load-add=ha_spider +--echo # +# A simple test that tests plugin-load-add=SPIDER=ha_spider +select * from mysql.plugin; +create table t (c int) Engine=SPIDER; +drop table t; diff --git a/storage/spider/mysql-test/spider/bugfix/t/spider_join_with_non_spider.test b/storage/spider/mysql-test/spider/bugfix/t/spider_join_with_non_spider.test new file mode 100644 index 00000000000..7b5d38014ed --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/spider_join_with_non_spider.test @@ -0,0 +1,28 @@ +--echo # +--echo # Test joining a spider table with a non-spider table +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t1 (c int); +create table t2 (d int); +insert into t2 values (1), (2); +create table t3 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +insert into t3 values (2), (3); +select c from t3 join t2 on c = d; +drop table t1, t2, t3; +drop server srv; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test spider_join_with_non_spider +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/spider_table_sts.test b/storage/spider/mysql-test/spider/bugfix/t/spider_table_sts.test deleted file mode 100644 index 7213017505b..00000000000 --- a/storage/spider/mysql-test/spider/bugfix/t/spider_table_sts.test +++ /dev/null @@ -1,46 +0,0 @@ ---source ../include/spider_table_sts_init.inc ---echo ---echo this test is for MDEV-19842 ---echo ---echo drop and create databases - ---connection master_1 ---disable_warnings -CREATE DATABASE auto_test_local; -USE auto_test_local; ---enable_warnings - ---echo ---echo create table - ---connection master_1 ---disable_query_log -echo CREATE TABLE tbl_a ( - pkey int NOT NULL, - PRIMARY KEY (pkey) -) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1; -eval CREATE TABLE tbl_a ( - pkey int NOT NULL, - PRIMARY KEY (pkey) -) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1; ---enable_query_log - ---echo ---echo select test 1 - ---connection master_1 ---error 12609 -SELECT pkey FROM tbl_a; - ---echo ---echo deinit ---disable_warnings - ---connection master_1 ---error 12609 -DROP DATABASE IF EXISTS auto_test_local; - ---enable_warnings ---source ../include/spider_table_sts_deinit.inc ---echo ---echo end of test diff --git a/storage/spider/mysql-test/spider/bugfix/t/subquery.test b/storage/spider/mysql-test/spider/bugfix/t/subquery.test new file mode 100644 index 00000000000..7a50719603d --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/subquery.test @@ -0,0 +1,30 @@ +--echo # +--echo # Test spider select with subqueries +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t1 (c1 int); +create table t2 (c2 int); + +insert into t1 values (1), (2); +insert into t2 values (0), (1), (2); + +create table t1s (c1 int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +create table t2s (c2 int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; + +select c1 from t1s, (select c2 from t2s where c2 > 0) t where c1 + 1 = c2; + +drop table t1, t2, t1s, t2s; +drop server srv; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test subquery +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early.cnf b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early.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/udf_mysql_func_early.opt b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early.opt new file mode 100644 index 00000000000..52144383000 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early.opt @@ -0,0 +1 @@ +--plugin-load-add=ha_spider \ No newline at end of file diff --git a/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early.test b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early.test new file mode 100644 index 00000000000..4edff9ca784 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early.test @@ -0,0 +1,48 @@ +--echo # +--echo # Test that udf created by inserting into mysql_func works as expected +--echo # + +evalp CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( +HOST 'localhost', +DATABASE 'auto_test_local', +USER 'root', +PASSWORD '', +SOCKET '$MASTER_1_MYSOCK' + ); +evalp CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS ( +HOST 'localhost', +DATABASE 'auto_test_remote', +USER 'root', +PASSWORD '', +SOCKET '$CHILD2_1_MYSOCK' + ); + +--connect (master_1, localhost, root, , , $MASTER_1_MYPORT, $MASTER_1_MYSOCK) +--connect (child2_1, localhost, root, , , $CHILD2_1_MYPORT, $CHILD2_1_MYSOCK) + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +eval CREATE TABLE tbl_a ( + a INT +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; +insert into tbl_a values (42); + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; +eval CREATE TABLE tbl_a ( + a INT +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; + +create temporary table results (a int); +--disable_ps_protocol +SELECT SPIDER_DIRECT_SQL('select * from tbl_a', 'results', 'srv "s_2_1", database "auto_test_remote"'); +--enable_ps_protocol +select * from results; + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; diff --git a/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.cnf b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.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/udf_mysql_func_early_init_file.opt b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.opt new file mode 100644 index 00000000000..d0f5777db87 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.opt @@ -0,0 +1 @@ +--init-file=$MTR_SUITE_DIR/t/udf_mysql_func_early_init_file.sql diff --git a/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.sql b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.sql new file mode 100644 index 00000000000..9b767554185 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.sql @@ -0,0 +1 @@ +install soname "ha_spider.so"; diff --git a/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.test b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.test new file mode 100644 index 00000000000..57b4ee15220 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.test @@ -0,0 +1,4 @@ +# Same as udf_mysql_func_early.test, except that we load spider in +# init_file, which is after udf_init() and before +# mysqld_server_started is on. +--source udf_mysql_func_early.test diff --git a/storage/spider/mysql-test/spider/include/clean_up_spider.inc b/storage/spider/mysql-test/spider/include/clean_up_spider.inc index 1f0659dc98a..249606ec774 100644 --- a/storage/spider/mysql-test/spider/include/clean_up_spider.inc +++ b/storage/spider/mysql-test/spider/include/clean_up_spider.inc @@ -3,7 +3,7 @@ DROP FUNCTION spider_copy_tables; DROP FUNCTION spider_ping_table; DROP FUNCTION spider_bg_direct_sql; DROP FUNCTION spider_direct_sql; -UNINSTALL SONAME IF EXISTS "ha_spider"; +UNINSTALL SONAME IF EXISTS 'ha_spider'; DROP TABLE IF EXISTS mysql.spider_xa; DROP TABLE IF EXISTS mysql.spider_xa_member; DROP TABLE IF EXISTS mysql.spider_xa_failed_log; diff --git a/storage/spider/mysql-test/spider/include/init_spider.inc b/storage/spider/mysql-test/spider/include/init_spider.inc index 6a22ffcc1fd..9ec26b9eeee 100644 --- a/storage/spider/mysql-test/spider/include/init_spider.inc +++ b/storage/spider/mysql-test/spider/include/init_spider.inc @@ -2,7 +2,7 @@ let $VERSION_COMPILE_OS_WIN= `SELECT IF(@@version_compile_os like 'Win%', 1, 0)`; if ($VERSION_COMPILE_OS_WIN) { - INSTALL PLUGIN spider SONAME 'ha_spider.dll'; + INSTALL SONAME 'ha_spider'; if ($MASTER_1_MYPORT) { eval CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( @@ -76,7 +76,7 @@ if ($VERSION_COMPILE_OS_WIN) } if (!$VERSION_COMPILE_OS_WIN) { - INSTALL PLUGIN spider SONAME 'ha_spider.so'; + INSTALL SONAME 'ha_spider'; if ($MASTER_1_MYSOCK) { eval CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( @@ -164,27 +164,6 @@ let $PLUGIN_VERSION= `SELECT SUBSTRING_INDEX(plugin_version, '.', 1) FROM information_schema.plugins WHERE plugin_name = 'SPIDER'`; -if (`SELECT IF($PLUGIN_VERSION = 3, 1, 0)`) -{ - let $HAS_REWRITE= - `SELECT IF (STRCMP('$SERVER_NAME', 'MariaDB') = 0, - IF ($SERVER_MAJOR_VERSION = 10, - IF ($SERVER_MINOR_VERSION < 4, 0, 1), - IF ($SERVER_MAJOR_VERSION < 10, 0, 1)), - 0)`; - let $HAS_REWRITE= 0; - if ($HAS_REWRITE) - { - let $PLUGIN_NAME= spider_flush_rewrite_cache; - let $PLUGIN_EXIST= - `SELECT COUNT(*) FROM mysql.func WHERE name = '$PLUGIN_NAME'`; - while (!$PLUGIN_EXIST) - { - let $PLUGIN_EXIST= - `SELECT COUNT(*) FROM mysql.func WHERE name = '$PLUGIN_NAME'`; - } - } -} let $PLUGIN_NAME= spider_flush_table_mon_cache; let $PLUGIN_EXIST= `SELECT COUNT(*) FROM mysql.func WHERE name = '$PLUGIN_NAME'`; diff --git a/storage/spider/mysql-test/spider/r/direct_join.result b/storage/spider/mysql-test/spider/r/direct_join.result index 398985ac02b..96f18a542ab 100644 --- a/storage/spider/mysql-test/spider/r/direct_join.result +++ b/storage/spider/mysql-test/spider/r/direct_join.result @@ -167,7 +167,7 @@ connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument select `id`,`hr_status`,`region_code`,`region` from `auto_test_remote`.`tbl_person` where `id` = '24FC3F0A5119432BAE13DD65AABAA39C' and `region` = 510411 -select count(0) `count(0)` from `auto_test_remote`.`tbl_ncd_cm_person` t0 where ((t0.`person_id` = '24FC3F0A5119432BAE13DD65AABAA39C') and (t0.`diseaseKind_id` = '52A0328740914BCE86ED10A4D2521816')) +select count(0) `count(0)` from (select 1) t0 join `auto_test_remote`.`tbl_ncd_cm_person` t1 where ((t1.`person_id` = '24FC3F0A5119432BAE13DD65AABAA39C') and (t1.`diseaseKind_id` = '52A0328740914BCE86ED10A4D2521816')) SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT * FROM tbl_person; id hr_status region_code region diff --git a/storage/spider/mysql-test/spider/r/direct_left_right_join_nullable.result b/storage/spider/mysql-test/spider/r/direct_left_right_join_nullable.result index a6bd3a7c1a1..96b00c61c2d 100644 --- a/storage/spider/mysql-test/spider/r/direct_left_right_join_nullable.result +++ b/storage/spider/mysql-test/spider/r/direct_left_right_join_nullable.result @@ -87,7 +87,7 @@ NULL NULL NULL 3 connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join (`auto_test_remote`.`ta_r_auto_inc` t2 join `auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r` t0) on ((t2.`b` = t3.`b`) and (t2.`c` = t1.`c`) and (t0.`a` = t1.`a`) and (t1.`a` is not null)) where 1 order by t3.`a` desc +select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join (`auto_test_remote`.`ta_r` t0 join `auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r_auto_inc` t2) on ((t2.`b` = t3.`b`) and (t2.`c` = t1.`c`) and (t0.`a` = t1.`a`) and (t1.`a` is not null)) where 1 order by t3.`a` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/direct_left_right_left_join_nullable.result b/storage/spider/mysql-test/spider/r/direct_left_right_left_join_nullable.result index 8fab6d24b9a..7ba1084a17e 100644 --- a/storage/spider/mysql-test/spider/r/direct_left_right_left_join_nullable.result +++ b/storage/spider/mysql-test/spider/r/direct_left_right_left_join_nullable.result @@ -86,7 +86,7 @@ NULL c 2000-01-03 00:00:00 3 connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_auto_inc` t2 left join (`auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r` t0) on ((t1.`c` = t2.`c`) and (t0.`a` = t1.`a`) and (t1.`a` is not null)) left join `auto_test_remote`.`ta_r_no_idx` t3 on (t3.`b` = t2.`b`) where 1 order by t3.`a` desc +select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_auto_inc` t2 left join (`auto_test_remote`.`ta_r` t0 join `auto_test_remote`.`ta_r_3` t1) on ((t1.`c` = t2.`c`) and (t0.`a` = t1.`a`) and (t1.`a` is not null)) left join `auto_test_remote`.`ta_r_no_idx` t3 on (t3.`b` = t2.`b`) where 1 order by t3.`a` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/direct_right_join.result b/storage/spider/mysql-test/spider/r/direct_right_join.result index d7780b94284..ee0940a4f73 100644 --- a/storage/spider/mysql-test/spider/r/direct_right_join.result +++ b/storage/spider/mysql-test/spider/r/direct_right_join.result @@ -79,7 +79,7 @@ a b c connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`b` `b`,t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r_int` t2 left join (`auto_test_remote`.`ta_r` t0 join `auto_test_remote`.`ta_r_3` t1) on ((t0.`a` = t2.`a`) and (t1.`a` = t2.`a`)) where 1 order by t0.`b` desc +select t0.`b` `b`,t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r_int` t2 left join (`auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r` t0) on ((t0.`a` = t2.`a`) and (t1.`a` = t2.`a`)) where 1 order by t0.`b` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/direct_right_join_nullable.result b/storage/spider/mysql-test/spider/r/direct_right_join_nullable.result index 5101ea5036a..fefb67fa562 100644 --- a/storage/spider/mysql-test/spider/r/direct_right_join_nullable.result +++ b/storage/spider/mysql-test/spider/r/direct_right_join_nullable.result @@ -87,7 +87,7 @@ NULL c 2000-01-03 00:00:00 3 connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join `auto_test_remote`.`ta_r_auto_inc` t2 on (t2.`b` = t3.`b`) left join `auto_test_remote`.`ta_r_3` t1 on (t1.`c` = t2.`c`) left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null)) where 1 order by t3.`a` desc +select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join (`auto_test_remote`.`ta_r_auto_inc` t2 left join (`auto_test_remote`.`ta_r_3` t1 left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null))) on (t1.`c` = t2.`c`)) on (t2.`b` = t3.`b`) where 1 order by t3.`a` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/direct_right_left_join_nullable.result b/storage/spider/mysql-test/spider/r/direct_right_left_join_nullable.result index c90fe3abf97..64c3b57c8a1 100644 --- a/storage/spider/mysql-test/spider/r/direct_right_left_join_nullable.result +++ b/storage/spider/mysql-test/spider/r/direct_right_left_join_nullable.result @@ -86,7 +86,7 @@ NULL c 2000-01-03 00:00:00 3 connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_auto_inc` t2 left join `auto_test_remote`.`ta_r_3` t1 on (t1.`c` = t2.`c`) left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null)) left join `auto_test_remote`.`ta_r_no_idx` t3 on (t3.`b` = t2.`b`) where 1 order by t3.`a` desc +select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_auto_inc` t2 left join (`auto_test_remote`.`ta_r_3` t1 left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null))) on (t1.`c` = t2.`c`) left join `auto_test_remote`.`ta_r_no_idx` t3 on (t3.`b` = t2.`b`) where 1 order by t3.`a` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/direct_right_left_right_join_nullable.result b/storage/spider/mysql-test/spider/r/direct_right_left_right_join_nullable.result index f6c808be973..68d11934216 100644 --- a/storage/spider/mysql-test/spider/r/direct_right_left_right_join_nullable.result +++ b/storage/spider/mysql-test/spider/r/direct_right_left_right_join_nullable.result @@ -87,7 +87,7 @@ NULL c 2000-01-03 00:00:00 3 connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join (`auto_test_remote`.`ta_r_auto_inc` t2 join `auto_test_remote`.`ta_r_3` t1 left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null))) on ((t2.`b` = t3.`b`) and (t2.`c` = t1.`c`)) where 1 order by t3.`a` desc +select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join (`auto_test_remote`.`ta_r_3` t1 left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null)) join `auto_test_remote`.`ta_r_auto_inc` t2) on ((t2.`b` = t3.`b`) and (t2.`c` = t1.`c`)) where 1 order by t3.`a` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result b/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result index 3eed8df28bf..850546fa1e9 100644 --- a/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result +++ b/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result @@ -86,8 +86,10 @@ SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argum argument select `value` from `auto_test_remote2`.`tbl_a` where `value` = 5 select `value2` from `auto_test_remote2`.`tbl_b` where `value2` = 5 +select sum('5') `sum(a.value)`,count('5') `count(b.value2)` from (select 1) t0 join (select 1) t1 select `value` from `auto_test_remote2`.`tbl_a` where `value` = 5 select `value2` from `auto_test_remote2`.`tbl_b` where `value2` = 5 +select sum('5') `sum(a.value)`,count('5') `count(b.value2)` from (select 1) t0 join (select 1) t1 SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT value FROM tbl_a ORDER BY value; value diff --git a/storage/spider/mysql-test/spider/regression/e1121/r/direct_join_by_pkey_key.result b/storage/spider/mysql-test/spider/regression/e1121/r/direct_join_by_pkey_key.result index a5553304ae0..72645f4f472 100644 --- a/storage/spider/mysql-test/spider/regression/e1121/r/direct_join_by_pkey_key.result +++ b/storage/spider/mysql-test/spider/regression/e1121/r/direct_join_by_pkey_key.result @@ -46,7 +46,7 @@ connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%`tbl_a`%' ; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%`tbl_b`%'; argument -select t0.`val` `val`,t0.`akey` `akey` from `auto_test_remote`.`tbl_a` t0 where (t0.`akey` = '4') +select t0.`val` `val`,t0.`akey` `akey` from `auto_test_remote`.`tbl_a` t0 join (select 1) t1 where (t0.`akey` = '4') SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%`tbl_a`%' ; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%`tbl_b`%' argument diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index db0a874005d..5378f196d66 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -591,7 +591,7 @@ SPIDER_CONN *spider_create_conn( tables_on_different_db_are_joinable = TRUE; } if (!(conn = (SPIDER_CONN *) - spider_bulk_malloc(spider_current_trx, 18, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_CONN_1, MYF(MY_WME | MY_ZEROFILL), &conn, (uint) (sizeof(*conn)), &tmp_name, (uint) (share->conn_keys_lengths[link_idx] + 1), &tmp_host, (uint) (share->tgt_hosts_lengths[link_idx] + 1), @@ -630,7 +630,7 @@ SPIDER_CONN *spider_create_conn( goto error_alloc_conn; } - conn->default_database.init_calc_mem(75); + conn->default_database.init_calc_mem(SPD_MID_CREATE_CONN_2); conn->conn_key_length = share->conn_keys_lengths[link_idx]; conn->conn_key = tmp_name; memcpy(conn->conn_key, share->conn_keys[link_idx], @@ -762,7 +762,7 @@ SPIDER_CONN *spider_create_conn( #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) } else if (conn_kind == SPIDER_CONN_KIND_HS_READ) { if (!(conn = (SPIDER_CONN *) - spider_bulk_malloc(spider_current_trx, 19, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_CONN_3, MYF(MY_WME | MY_ZEROFILL), &conn, (uint) (sizeof(*conn)), &tmp_name, (uint) (share->hs_read_conn_keys_lengths[link_idx] + 1), &tmp_host, (uint) (share->tgt_hosts_lengths[link_idx] + 1), @@ -776,7 +776,7 @@ SPIDER_CONN *spider_create_conn( goto error_alloc_conn; } - conn->default_database.init_calc_mem(76); + conn->default_database.init_calc_mem(SPD_MID_CREATE_CONN_4); conn->conn_key_length = share->hs_read_conn_keys_lengths[link_idx]; conn->conn_key = tmp_name; memcpy(conn->conn_key, share->hs_read_conn_keys[link_idx], @@ -804,7 +804,7 @@ SPIDER_CONN *spider_create_conn( conn->dbton_id = share->hs_dbton_ids[link_idx]; } else { if (!(conn = (SPIDER_CONN *) - spider_bulk_malloc(spider_current_trx, 20, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_CONN_5, MYF(MY_WME | MY_ZEROFILL), &conn, (uint) (sizeof(*conn)), &tmp_name, (uint) (share->hs_write_conn_keys_lengths[link_idx] + 1), &tmp_host, (uint) (share->tgt_hosts_lengths[link_idx] + 1), @@ -818,7 +818,7 @@ SPIDER_CONN *spider_create_conn( goto error_alloc_conn; } - conn->default_database.init_calc_mem(77); + conn->default_database.init_calc_mem(SPD_MID_CREATE_CONN_6); conn->conn_key_length = share->hs_write_conn_keys_lengths[link_idx]; conn->conn_key = tmp_name; memcpy(conn->conn_key, share->hs_write_conn_keys[link_idx], @@ -2525,7 +2525,7 @@ int spider_create_conn_thread( error_num = HA_ERR_OUT_OF_MEM; goto error_job_stack_init; } - spider_alloc_calc_mem_init(conn->bg_job_stack, 163); + spider_alloc_calc_mem_init(conn->bg_job_stack, SPD_MID_CREATE_CONN_THREAD_1); spider_alloc_calc_mem(spider_current_trx, conn->bg_job_stack, conn->bg_job_stack.max_element * @@ -4320,7 +4320,7 @@ int spider_create_mon_threads( char *buf = (char *) my_alloca(share->table_name_length + SPIDER_SQL_INT_LEN + 1); spider_string conv_name_str(buf, share->table_name_length + SPIDER_SQL_INT_LEN + 1, system_charset_info); - conv_name_str.init_calc_mem(105); + conv_name_str.init_calc_mem(SPD_MID_CREATE_MON_THREADS_1); conv_name_str.length(0); conv_name_str.q_append(share->table_name, share->table_name_length); for (roop_count = 0; roop_count < (int) share->all_link_count; @@ -4353,7 +4353,7 @@ int spider_create_mon_threads( } } if (!(share->bg_mon_thds = (THD **) - spider_bulk_malloc(spider_current_trx, 23, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_MON_THREADS_2, MYF(MY_WME | MY_ZEROFILL), &share->bg_mon_thds, (uint) (sizeof(THD *) * share->all_link_count), &share->bg_mon_threads, diff --git a/storage/spider/spd_copy_tables.cc b/storage/spider/spd_copy_tables.cc index 4ceaaae9230..520c1f63c05 100644 --- a/storage/spider/spd_copy_tables.cc +++ b/storage/spider/spd_copy_tables.cc @@ -283,7 +283,7 @@ int spider_udf_get_copy_tgt_tables( } do { if (!(table_conn = (SPIDER_COPY_TABLE_CONN *) - spider_bulk_malloc(spider_current_trx, 25, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_UDF_GET_COPY_TGT_TABLES_1, MYF(MY_WME | MY_ZEROFILL), &table_conn, (uint) (sizeof(SPIDER_COPY_TABLE_CONN)), &tmp_share, (uint) (sizeof(SPIDER_SHARE)), &tmp_connect_info, @@ -601,7 +601,7 @@ int spider_udf_copy_tables_create_table_list( } if (!(copy_tables->link_idxs[0] = (int *) - spider_bulk_malloc(spider_current_trx, 26, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_UDF_COPY_TABLES_CREATE_TABLE_LIST_1, MYF(MY_WME | MY_ZEROFILL), ©_tables->link_idxs[0], (uint) (sizeof(int) * copy_tables->link_idx_count[0]), ©_tables->link_idxs[1], @@ -803,7 +803,7 @@ long long spider_copy_tables_body( } if (!(copy_tables = (SPIDER_COPY_TABLES *) - spider_bulk_malloc(spider_current_trx, 27, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_COPY_TABLES_BODY_1, MYF(MY_WME | MY_ZEROFILL), ©_tables, (uint) (sizeof(SPIDER_COPY_TABLES)), NullS)) ) { @@ -1019,7 +1019,7 @@ long long spider_copy_tables_body( { tmp_spider = &spider[roop_count]; if (!(tmp_spider->dbton_handler = (spider_db_handler **) - spider_bulk_alloc_mem(spider_current_trx, 205, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_COPY_TABLES_BODY_2, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &tmp_spider->dbton_handler, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE, @@ -1040,7 +1040,7 @@ long long spider_copy_tables_body( } */ tmp_spider->conns = &table_conn->conn; - tmp_sql[roop_count].init_calc_mem(122); + tmp_sql[roop_count].init_calc_mem(SPD_MID_COPY_TABLES_BODY_3); tmp_sql[roop_count].set_charset(copy_tables->access_charset); tmp_spider->result_list.sqls = &tmp_sql[roop_count]; tmp_spider->need_mons = &table_conn->need_mon; @@ -1065,7 +1065,7 @@ long long spider_copy_tables_body( { tmp_spider = &spider[roop_count]; if (!(tmp_spider->dbton_handler = (spider_db_handler **) - spider_bulk_alloc_mem(spider_current_trx, 206, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_COPY_TABLES_BODY_4, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &tmp_spider->dbton_handler, sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE, @@ -1086,7 +1086,7 @@ long long spider_copy_tables_body( } */ tmp_spider->conns = &table_conn->conn; - tmp_sql[roop_count].init_calc_mem(201); + tmp_sql[roop_count].init_calc_mem(SPD_MID_COPY_TABLES_BODY_5); tmp_sql[roop_count].set_charset(copy_tables->access_charset); tmp_spider->result_list.sqls = &tmp_sql[roop_count]; tmp_spider->need_mons = &table_conn->need_mon; diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 04cb8bad669..95878357de4 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -280,7 +280,7 @@ int spider_db_conn_queue_action( spider_string sql_str(sql_buf, sizeof(sql_buf), system_charset_info); DBUG_ENTER("spider_db_conn_queue_action"); DBUG_PRINT("info", ("spider conn=%p", conn)); - sql_str.init_calc_mem(106); + sql_str.init_calc_mem(SPD_MID_DB_CONN_QUEUE_ACTION_1); sql_str.length(0); if (conn->queued_connect) { @@ -698,7 +698,7 @@ int spider_db_query( DBUG_RETURN(error_num); #ifndef DBUG_OFF spider_string tmp_query_str(sizeof(char) * (length + 1)); - tmp_query_str.init_calc_mem(107); + tmp_query_str.init_calc_mem(SPD_MID_DB_QUERY_1); char *tmp_query = (char *) tmp_query_str.c_ptr_safe(); memcpy(tmp_query, query, length); tmp_query[length] = '\0'; @@ -2860,7 +2860,7 @@ int spider_db_fetch_for_item_sum_func( { if (!spider->direct_aggregate_item_first) { - if (!spider_bulk_malloc(spider_current_trx, 240, MYF(MY_WME), + if (!spider_bulk_malloc(spider_current_trx, SPD_MID_DB_FETCH_FOR_ITEM_SUM_FUNC_1, MYF(MY_WME), &spider->direct_aggregate_item_first, (uint) (sizeof(SPIDER_ITEM_HLD)), NullS) @@ -2879,7 +2879,7 @@ int spider_db_fetch_for_item_sum_func( } else { if (!spider->direct_aggregate_item_current->next) { - if (!spider_bulk_malloc(spider_current_trx, 241, MYF(MY_WME), + if (!spider_bulk_malloc(spider_current_trx, SPD_MID_DB_FETCH_FOR_ITEM_SUM_FUNC_2, MYF(MY_WME), &spider->direct_aggregate_item_current->next, (uint) (sizeof(SPIDER_ITEM_HLD)), NullS) ) { @@ -2939,7 +2939,7 @@ int spider_db_fetch_for_item_sum_func( } else { char buf[MAX_FIELD_WIDTH]; spider_string tmp_str(buf, MAX_FIELD_WIDTH, share->access_charset); - tmp_str.init_calc_mem(242); + tmp_str.init_calc_mem(SPD_MID_DB_FETCH_FOR_ITEM_SUM_FUNC_3); tmp_str.length(0); if ((error_num = row->append_to_str(&tmp_str))) DBUG_RETURN(error_num); @@ -3987,7 +3987,7 @@ int spider_db_store_result( if (!result_list->first) { if (!(result_list->first = (SPIDER_RESULT *) - spider_malloc(spider_current_trx, 4, sizeof(*result_list->first), + spider_malloc(spider_current_trx, SPD_MID_DB_STORE_RESULT_1, sizeof(*result_list->first), MYF(MY_WME | MY_ZEROFILL))) ) { if (!conn->mta_conn_mutex_unlock_later) @@ -4019,7 +4019,7 @@ int spider_db_store_result( if (result_list->bgs_current == result_list->last) { if (!(result_list->last = (SPIDER_RESULT *) - spider_malloc(spider_current_trx, 5, sizeof(*result_list->last), + spider_malloc(spider_current_trx, SPD_MID_DB_STORE_RESULT_2, sizeof(*result_list->last), MYF(MY_WME | MY_ZEROFILL))) ) { if (!conn->mta_conn_mutex_unlock_later) @@ -4064,7 +4064,7 @@ int spider_db_store_result( if (result_list->current == result_list->last) { if (!(result_list->last = (SPIDER_RESULT *) - spider_malloc(spider_current_trx, 6, sizeof(*result_list->last), + spider_malloc(spider_current_trx, SPD_MID_DB_STORE_RESULT_3, sizeof(*result_list->last), MYF(MY_WME | MY_ZEROFILL))) ) { if (!conn->mta_conn_mutex_unlock_later) @@ -4285,7 +4285,7 @@ int spider_db_store_result( } current->field_count = field_count; if (!(position = (SPIDER_POSITION *) - spider_bulk_malloc(spider_current_trx, 7, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_DB_STORE_RESULT_4, MYF(MY_WME | MY_ZEROFILL), &position, (uint) (sizeof(SPIDER_POSITION) * page_size), &tmp_row, (uint) (sizeof(SPIDER_DB_ROW) * field_count), NullS)) @@ -4348,7 +4348,7 @@ int spider_db_store_result( THD *thd = current_thd; char buf[MAX_FIELD_WIDTH]; spider_string tmp_str(buf, MAX_FIELD_WIDTH, &my_charset_bin); - tmp_str.init_calc_mem(120); + tmp_str.init_calc_mem(SPD_MID_DB_STORE_RESULT_5); DBUG_PRINT("info",("spider store result to temporary table")); DBUG_ASSERT(!current->result_tmp_tbl); @@ -4786,7 +4786,7 @@ int spider_db_store_result_for_reuse_cursor( THD *thd = current_thd; char buf[MAX_FIELD_WIDTH]; spider_string tmp_str(buf, MAX_FIELD_WIDTH, &my_charset_bin); - tmp_str.init_calc_mem(120); + tmp_str.init_calc_mem(SPD_MID_DB_STORE_RESULT_FOR_REUSE_CURSOR_1); DBUG_PRINT("info",("spider store result to temporary table")); DBUG_ASSERT(!current->result_tmp_tbl); @@ -9691,19 +9691,20 @@ int spider_db_open_item_ident( } else { if (str) { - SPIDER_FIELD_CHAIN *field_chain = fields->get_next_field_chain(); - SPIDER_FIELD_HOLDER *field_holder = field_chain->field_holder; - spider = field_holder->spider; + SPIDER_TABLE_HOLDER *table= fields->find_table(field); + /* If table or table->spider is NULL the GBH creation + would have been skipped the first pass (see below). */ + spider = table->spider; share = spider->share; if ((error_num = share->dbton_share[dbton_id]-> append_column_name_with_alias(str, field->field_index, - field_holder->alias->ptr(), field_holder->alias->length()))) + table->alias->ptr(), table->alias->length()))) DBUG_RETURN(error_num); - } else { - if ((error_num = fields->add_field(field))) - { - DBUG_RETURN(error_num); - } + } else + { + SPIDER_TABLE_HOLDER *table= fields->find_table(field); + if (!table || !table->spider) + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); } } } @@ -9822,21 +9823,20 @@ int spider_db_open_item_field( } else { if (str) { - SPIDER_FIELD_CHAIN *field_chain = fields->get_next_field_chain(); - SPIDER_FIELD_HOLDER *field_holder = field_chain->field_holder; - spider = field_holder->spider; + SPIDER_TABLE_HOLDER *table= fields->find_table(field); + /* If table or table->spider is NULL the GBH creation + would have been skipped the first pass (see below). */ + spider = table->spider; share = spider->share; - field = spider->field_exchange(field); - DBUG_ASSERT(field); if ((error_num = share->dbton_share[dbton_id]-> append_column_name_with_alias(str, field->field_index, - field_holder->alias->ptr(), field_holder->alias->length()))) + table->alias->ptr(), table->alias->length()))) DBUG_RETURN(error_num); - } else { - if ((error_num = fields->add_field(field))) - { - DBUG_RETURN(error_num); - } + } else + { + SPIDER_TABLE_HOLDER *table= fields->find_table(field); + if (!table || !table->spider) + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); } DBUG_RETURN(0); } @@ -9998,7 +9998,7 @@ int spider_db_open_item_string( char tmp_buf[MAX_FIELD_WIDTH]; spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); String *tmp_str2; - tmp_str.init_calc_mem(126); + tmp_str.init_calc_mem(SPD_MID_DB_OPEN_ITEM_STRING_1); if (!(tmp_str2 = item->val_str(tmp_str.get_str()))) { @@ -10117,7 +10117,7 @@ int spider_db_open_item_int( char tmp_buf[MAX_FIELD_WIDTH]; spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); String *tmp_str2; - tmp_str.init_calc_mem(127); + tmp_str.init_calc_mem(SPD_MID_DB_OPEN_ITEM_INT_1); if (!(tmp_str2 = item->val_str(tmp_str.get_str()))) { @@ -11270,8 +11270,8 @@ int spider_db_udf_ping_table( system_charset_info); spider_string where_str(where_buf, sizeof(where_buf), system_charset_info); - sql_str.init_calc_mem(128); - where_str.init_calc_mem(129); + sql_str.init_calc_mem(SPD_MID_DB_UDF_PING_TABLE_1); + where_str.init_calc_mem(SPD_MID_DB_UDF_PING_TABLE_2); sql_str.length(0); where_str.length(0); if ( @@ -11381,8 +11381,8 @@ int spider_db_udf_ping_table_append_mon_next( spider_string where_clause_str(where_clause ? where_clause : "", where_clause_length + 1, str->charset()); DBUG_ENTER("spider_db_udf_ping_table_append_mon_next"); - child_table_name_str.init_calc_mem(130); - where_clause_str.init_calc_mem(131); + child_table_name_str.init_calc_mem(SPD_MID_DB_UDF_PING_TABLE_APPEND_MON_NEXT_1); + where_clause_str.init_calc_mem(SPD_MID_DB_UDF_PING_TABLE_APPEND_MON_NEXT_2); child_table_name_str.length(child_table_name_length); where_clause_str.length(where_clause_length); limit_str_length = my_sprintf(limit_str, (limit_str, "%lld", limit)); @@ -11535,7 +11535,7 @@ int spider_db_udf_ping_table_mon_next( } spider_string sql_str(sql_buf, sizeof(sql_buf), thd->variables.character_set_client); - sql_str.init_calc_mem(132); + sql_str.init_calc_mem(SPD_MID_DB_UDF_PING_TABLE_MON_NEXT_1); sql_str.length(0); trx.thd = thd; spider.share = share; @@ -11695,7 +11695,7 @@ int spider_db_udf_copy_tables( int bulk_insert_interval; DBUG_ENTER("spider_db_udf_copy_tables"); if (!(last_row_pos = (ulong *) - spider_bulk_malloc(spider_current_trx, 30, MYF(MY_WME), + spider_bulk_malloc(spider_current_trx, SPD_MID_DB_UDF_COPY_TABLES_1, MYF(MY_WME), &last_row_pos, (uint) (sizeof(ulong) * table->s->fields), &last_lengths, (uint) (sizeof(ulong) * table->s->fields), NullS)) diff --git a/storage/spider/spd_db_handlersocket.cc b/storage/spider/spd_db_handlersocket.cc index 030201e61ae..656ea991619 100644 --- a/storage/spider/spd_db_handlersocket.cc +++ b/storage/spider/spd_db_handlersocket.cc @@ -214,7 +214,7 @@ int spider_db_hs_string_ref_buffer::init() { SPD_INIT_DYNAMIC_ARRAY2(&hs_conds, sizeof(SPIDER_HS_STRING_REF), NULL, 16, 16, MYF(MY_WME)); - spider_alloc_calc_mem_init(hs_conds, 159); + spider_alloc_calc_mem_init(hs_conds, SPD_MID_DB_HS_STRING_REF_BUFFER_INIT_1); spider_alloc_calc_mem(spider_current_trx, hs_conds, hs_conds.max_element * hs_conds.size_of_element); hs_da_init = TRUE; @@ -290,7 +290,7 @@ int spider_db_hs_str_buffer::init() { SPD_INIT_DYNAMIC_ARRAY2(&hs_conds, sizeof(spider_string *), NULL, 16, 16, MYF(MY_WME)); - spider_alloc_calc_mem_init(hs_conds, 160); + spider_alloc_calc_mem_init(hs_conds, SPD_MID_DB_HS_STR_BUFFER_INIT_1); spider_alloc_calc_mem(spider_current_trx, hs_conds, hs_conds.max_element * hs_conds.size_of_element); hs_da_init = TRUE; @@ -324,10 +324,10 @@ spider_string *spider_db_hs_str_buffer::add( DBUG_PRINT("info",("spider this=%p", this)); if (hs_conds.elements <= *strs_pos + 1) { - if (!(element = (spider_string *) spider_malloc(spider_current_trx, 8, + if (!(element = (spider_string *) spider_malloc(spider_current_trx, SPD_MID_DB_HS_STR_BUFFER_ADD_1, sizeof(spider_string), MYF(MY_WME | MY_ZEROFILL)))) DBUG_RETURN(NULL); - element->init_calc_mem(98); + element->init_calc_mem(SPD_MID_DB_HS_STR_BUFFER_ADD_2); element->set_charset(&my_charset_bin); if ((element->reserve(str_len + 1))) { @@ -395,7 +395,7 @@ int spider_db_handlersocket_row::store_to_field( #ifndef DBUG_OFF char buf[MAX_FIELD_WIDTH]; spider_string tmp_str(buf, MAX_FIELD_WIDTH, field->charset()); - tmp_str.init_calc_mem(119); + tmp_str.init_calc_mem(SPD_MID_DB_HANDLERSOCKET_ROW_STORE_TO_FIELD_1); tmp_str.length(0); tmp_str.append(hs_row->begin(), hs_row->size(), &my_charset_bin); DBUG_PRINT("info", ("spider val=%s", tmp_str.c_ptr_safe())); @@ -430,7 +430,7 @@ int spider_db_handlersocket_row::append_escaped_to_str( DBUG_ENTER("spider_db_handlersocket_row::append_escaped_to_str"); DBUG_PRINT("info",("spider this=%p", this)); spider_string tmp_str(hs_row->begin(), hs_row->size() + 1, &my_charset_bin); - tmp_str.init_calc_mem(172); + tmp_str.init_calc_mem(SPD_MID_DB_HANDLERSOCKET_ROW_APPEND_ESCAPED_TO_STR_1); tmp_str.length(hs_row->size()); if (str->reserve(hs_row->size() * 2 + 2)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -507,7 +507,7 @@ SPIDER_DB_ROW *spider_db_handlersocket_row::clone() { DBUG_RETURN(NULL); } - if (!spider_bulk_malloc(spider_current_trx, 169, MYF(MY_WME), + if (!spider_bulk_malloc(spider_current_trx, SPD_MID_DB_HANDLERSOCKET_ROW_CLONE_1, MYF(MY_WME), &clone_row->hs_row, (uint) (sizeof(SPIDER_HS_STRING_REF) * field_count), &tmp_char, (uint) (row_size), NullS) @@ -715,8 +715,8 @@ SPIDER_DB_ROW *spider_db_handlersocket_result::fetch_row_from_tmp_table( uint field_count; DBUG_ENTER("spider_db_handlersocket_result::fetch_row_from_tmp_table"); DBUG_PRINT("info",("spider this=%p", this)); - tmp_str1.init_calc_mem(171); - tmp_str2.init_calc_mem(173); + tmp_str1.init_calc_mem(SPD_MID_DB_HANDLERSOCKET_RESULT_FETCH_ROW_FROM_TMP_TABLE_1); + tmp_str2.init_calc_mem(SPD_MID_DB_HANDLERSOCKET_RESULT_FETCH_ROW_FROM_TMP_TABLE_2); tmp_table->field[0]->val_str(tmp_str1.get_str()); tmp_table->field[1]->val_str(tmp_str2.get_str()); tmp_str1.mem_calc(); @@ -909,7 +909,7 @@ int spider_db_handlersocket::init() ) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - spider_alloc_calc_mem_init(handler_open_array, 79); + spider_alloc_calc_mem_init(handler_open_array, SPD_MID_DB_HANDLERSOCKET_INIT_1); spider_alloc_calc_mem(spider_current_trx, handler_open_array, handler_open_array.max_element * @@ -1113,7 +1113,7 @@ int spider_db_handlersocket::exec_query( spider_string tmp_query_str((*hs_conn_p)->get_writebuf_size() + conn->tgt_wrapper_length + tgt_len + (SPIDER_SQL_SPACE_LEN * 2)); - tmp_query_str.init_calc_mem(231); + tmp_query_str.init_calc_mem(SPD_MID_DB_HANDLERSOCKET_EXEC_QUERY_1); tmp_query_str.length(0); tmp_query_str.q_append(conn->tgt_wrapper, conn->tgt_wrapper_length); tmp_query_str.q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); @@ -2313,7 +2313,7 @@ int spider_db_handlersocket::append_request_key( request_key_reuse_last = NULL; } else { if (!(tmp_request_key = (st_spider_db_request_key *) - spider_malloc(spider_current_trx, 1, sizeof(st_spider_db_request_key), + spider_malloc(spider_current_trx, SPD_MID_DB_HANDLERSOCKET_APPEND_REQUEST_KEY_1, sizeof(st_spider_db_request_key), MYF(MY_WME))) ) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -2605,7 +2605,7 @@ int spider_db_handlersocket_util::append_column_value( String *ptr; uint length; DBUG_ENTER("spider_db_handlersocket_util::append_column_value"); - tmp_str.init_calc_mem(180); + tmp_str.init_calc_mem(SPD_MID_DB_HANDLERSOCKET_UTIL_APPEND_COLUMN_VALUE_1); if (new_ptr) { @@ -3304,7 +3304,7 @@ int spider_db_handlersocket_util::open_item_func( { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); - tmp_str.init_calc_mem(123); + tmp_str.init_calc_mem(SPD_MID_DB_HANDLERSOCKET_UTIL_OPEN_ITEM_FUNC_1); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) @@ -3444,7 +3444,7 @@ int spider_db_handlersocket_util::open_item_func( { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); - tmp_str.init_calc_mem(124); + tmp_str.init_calc_mem(SPD_MID_DB_HANDLERSOCKET_UTIL_OPEN_ITEM_FUNC_2); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) @@ -3602,7 +3602,7 @@ int spider_db_handlersocket_util::open_item_func( { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); - tmp_str.init_calc_mem(125); + tmp_str.init_calc_mem(SPD_MID_DB_HANDLERSOCKET_UTIL_OPEN_ITEM_FUNC_3); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) @@ -4113,7 +4113,7 @@ spider_handlersocket_share::spider_handlersocket_share( { DBUG_ENTER("spider_handlersocket_share::spider_handlersocket_share"); DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 186); + spider_alloc_calc_mem_init(mem_calc, SPD_MID_HANDLERSOCKET_SHARE_SPIDER_HANDLERSOCKET_SHARE_1); spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); DBUG_VOID_RETURN; } @@ -4141,7 +4141,7 @@ int spider_handlersocket_share::init() DBUG_PRINT("info",("spider this=%p", this)); #ifdef SPIDER_HAS_HASH_VALUE_TYPE if (!(db_table_str_hash_value = (my_hash_value_type *) - spider_bulk_alloc_mem(spider_current_trx, 203, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_HANDLERSOCKET_SHARE_INIT_1, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &db_table_str_hash_value, sizeof(my_hash_value_type) * spider_share->all_link_count, @@ -4215,9 +4215,9 @@ int spider_handlersocket_share::create_table_names_str() for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { - table_names_str[roop_count].init_calc_mem(86); - db_names_str[roop_count].init_calc_mem(87); - db_table_str[roop_count].init_calc_mem(88); + table_names_str[roop_count].init_calc_mem(SPD_MID_HANDLERSOCKET_SHARE_CREATE_TABLE_NAMES_STR_1); + db_names_str[roop_count].init_calc_mem(SPD_MID_HANDLERSOCKET_SHARE_CREATE_TABLE_NAMES_STR_2); + db_table_str[roop_count].init_calc_mem(SPD_MID_HANDLERSOCKET_SHARE_CREATE_TABLE_NAMES_STR_3); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; if (first_all_link_idx == -1) @@ -4359,7 +4359,7 @@ int spider_handlersocket_share::create_column_name_str() for (field = table_share->field, str = column_name_str; *field; field++, str++) { - str->init_calc_mem(202); + str->init_calc_mem(SPD_MID_HANDLERSOCKET_SHARE_CREATE_COLUMN_NAME_STR_1); str->set_charset(spider_share->access_charset); if ((error_num = spider_db_append_name_with_quote_str(str, (*field)->field_name, dbton_id))) @@ -4455,7 +4455,7 @@ spider_handlersocket_handler::spider_handlersocket_handler( { DBUG_ENTER("spider_handlersocket_handler::spider_handlersocket_handler"); DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 187); + spider_alloc_calc_mem_init(mem_calc, SPD_MID_HANDLERSOCKET_HANDLER_SPIDER_HANDLERSOCKET_HANDLER_1); spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); DBUG_VOID_RETURN; } @@ -4479,7 +4479,7 @@ int spider_handlersocket_handler::init() DBUG_ENTER("spider_handlersocket_handler::init"); DBUG_PRINT("info",("spider this=%p", this)); if (!(link_for_hash = (SPIDER_LINK_FOR_HASH *) - spider_bulk_alloc_mem(spider_current_trx, 204, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_HANDLERSOCKET_HANDLER_INIT_1, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &link_for_hash, sizeof(SPIDER_LINK_FOR_HASH) * share->link_count, @@ -4501,7 +4501,7 @@ int spider_handlersocket_handler::init() handlersocket_share->db_table_str_hash_value[roop_count]; #endif } - hs_sql.init_calc_mem(63); + hs_sql.init_calc_mem(SPD_MID_HANDLERSOCKET_HANDLER_INIT_2); hs_sql.set_charset(share->access_charset); hs_keys.init(); hs_upds.init(); diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index 53c59891cf4..dc40091abba 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -613,34 +613,26 @@ typedef struct spider_conn_holder spider_conn_holder *next; } SPIDER_CONN_HOLDER; +/* Record information of a local (spider) table, for use of the spider +group by handler. */ typedef struct spider_table_holder { TABLE *table; ha_spider *spider; + /* alias of the table, in the form of tk, where k is the index of + the table from `query->from' indexed by next_local. */ spider_string *alias; } SPIDER_TABLE_HOLDER; -typedef struct spider_field_holder -{ - Field *field; - ha_spider *spider; - spider_string *alias; - spider_field_holder *next; -} SPIDER_FIELD_HOLDER; - -typedef struct spider_field_chain -{ - spider_field_holder *field_holder; - spider_field_chain *next; -} SPIDER_FIELD_CHAIN; - +/* For use of the spider group by handler. */ class spider_fields { uint dbton_count; uint current_dbton_num; uint dbton_ids[SPIDER_DBTON_SIZE]; + /* Number of tables in `query->from'. */ uint table_count; - uint current_table_num; + /* All tables in `query->from', in the same order by next_local. */ SPIDER_TABLE_HOLDER *table_holder; SPIDER_LINK_IDX_CHAIN *first_link_idx_chain; SPIDER_LINK_IDX_CHAIN *last_link_idx_chain; @@ -649,13 +641,6 @@ class spider_fields SPIDER_CONN_HOLDER *first_conn_holder; SPIDER_CONN_HOLDER *last_conn_holder; SPIDER_CONN_HOLDER *current_conn_holder; - SPIDER_FIELD_HOLDER *first_field_holder; - SPIDER_FIELD_HOLDER *last_field_holder; - SPIDER_FIELD_HOLDER *current_field_holder; - SPIDER_FIELD_CHAIN *first_field_chain; - SPIDER_FIELD_CHAIN *last_field_chain; - SPIDER_FIELD_CHAIN *current_field_chain; - Field **first_field_ptr; Field **current_field_ptr; public: spider_fields(); @@ -698,8 +683,6 @@ public: long access_balance ); SPIDER_CONN_HOLDER *create_conn_holder(); - void set_pos_to_first_conn_holder(); - SPIDER_CONN_HOLDER *get_next_conn_holder(); bool has_conn_holder(); void clear_conn_holder_from_conn(); bool check_conn_same_conn( @@ -713,24 +696,14 @@ public: void free_conn_holder( SPIDER_CONN_HOLDER *conn_holder_arg ); - SPIDER_TABLE_HOLDER *add_table( - ha_spider *spider_arg - ); - bool all_query_fields_are_query_table_members(); - int create_table_holder( + SPIDER_TABLE_HOLDER *find_table(Field *field); + void set_table_holder( + SPIDER_TABLE_HOLDER *table_holder_arg, uint table_count_arg ); - void set_pos_to_first_table_holder(); - SPIDER_TABLE_HOLDER *get_next_table_holder(); + SPIDER_TABLE_HOLDER *get_first_table_holder(); SPIDER_TABLE_HOLDER *get_table_holder(TABLE *table); uint get_table_count(); - int add_field(Field *field_arg); - SPIDER_FIELD_HOLDER *create_field_holder(); - void set_pos_to_first_field_holder(); - SPIDER_FIELD_HOLDER *get_next_field_holder(); - SPIDER_FIELD_CHAIN *create_field_chain(); - void set_pos_to_first_field_chain(); - SPIDER_FIELD_CHAIN *get_next_field_chain(); void set_field_ptr(Field **field_arg); Field **get_next_field_ptr(); int ping_table_mon_from_table( @@ -936,11 +909,6 @@ public: TABLE_LIST *table_list, uint table_count ) = 0; - virtual int reappend_tables( - spider_fields *fields, - SPIDER_LINK_IDX_CHAIN *link_idx_chain, - spider_string *str - ) = 0; virtual int append_where( spider_string *str ) = 0; @@ -1784,10 +1752,6 @@ public: spider_fields *fields, ulong sql_type ) = 0; - virtual int reappend_tables_part( - spider_fields *fields, - ulong sql_type - ) = 0; virtual int append_where_part( ulong sql_type ) = 0; diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 23e110b2af2..22399dc0ab4 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -462,7 +462,7 @@ int spider_db_mbase_row::append_escaped_to_str( DBUG_ENTER("spider_db_mbase_row::append_escaped_to_str"); DBUG_PRINT("info",("spider this=%p", this)); spider_string tmp_str(*row, *lengths + 1, str->charset()); - tmp_str.init_calc_mem(133); + tmp_str.init_calc_mem(SPD_MID_DB_MBASE_ROW_APPEND_ESCAPED_TO_STR_1); tmp_str.length(*lengths); if (str->reserve(*lengths * 2 + 2)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -555,7 +555,7 @@ SPIDER_DB_ROW *spider_db_mbase_row::clone() row_size = record_size + field_count; } if (!spider_bulk_malloc( - spider_current_trx, 29, MYF(MY_WME), + spider_current_trx, SPD_MID_DB_MBASE_ROW_CLONE_1, MYF(MY_WME), &clone_row->row, (uint) (sizeof(char*) * (field_count + 1)), &tmp_char, (uint) (row_size), &clone_row->lengths, (uint) (sizeof(ulong) * field_count), @@ -785,9 +785,9 @@ SPIDER_DB_ROW *spider_db_mbase_result::fetch_row_from_tmp_table( uint field_count; DBUG_ENTER("spider_db_mbase_result::fetch_row_from_tmp_table"); DBUG_PRINT("info",("spider this=%p", this)); - tmp_str1.init_calc_mem(117); - tmp_str2.init_calc_mem(118); - tmp_str3.init_calc_mem(170); + tmp_str1.init_calc_mem(SPD_MID_DB_MBASE_RESULT_FETCH_ROW_FROM_TMP_TABLE_1); + tmp_str2.init_calc_mem(SPD_MID_DB_MBASE_RESULT_FETCH_ROW_FROM_TMP_TABLE_2); + tmp_str3.init_calc_mem(SPD_MID_DB_MBASE_RESULT_FETCH_ROW_FROM_TMP_TABLE_3); tmp_table->field[0]->val_str(tmp_str1.get_str()); tmp_table->field[1]->val_str(tmp_str2.get_str()); tmp_table->field[2]->val_str(tmp_str3.get_str()); @@ -1886,7 +1886,7 @@ int spider_db_mbase::init() ) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - spider_alloc_calc_mem_init(lock_table_hash, 140); + spider_alloc_calc_mem_init(lock_table_hash, SPD_MID_DB_MBASE_INIT_1); spider_alloc_calc_mem(spider_current_trx, lock_table_hash, lock_table_hash.array.max_element * @@ -1899,7 +1899,7 @@ int spider_db_mbase::init() ) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - spider_alloc_calc_mem_init(handler_open_array, 162); + spider_alloc_calc_mem_init(handler_open_array, SPD_MID_DB_MBASE_INIT_2); spider_alloc_calc_mem(spider_current_trx, handler_open_array, handler_open_array.max_element * @@ -2135,7 +2135,7 @@ int spider_db_mbase::exec_query( const char *tgt_str = conn->tgt_host; uint32 tgt_len = conn->tgt_host_length; spider_string tmp_query_str; - tmp_query_str.init_calc_mem(230); + tmp_query_str.init_calc_mem(SPD_MID_DB_MBASE_EXEC_QUERY_1); if (tmp_query_str.reserve( length + conn->tgt_wrapper_length + tgt_len + (SPIDER_SQL_SPACE_LEN * 2))) @@ -2165,7 +2165,7 @@ int spider_db_mbase::exec_query( struct tm lt; struct tm *l_time = localtime_r(&cur_time, <); spider_string tmp_query_str; - tmp_query_str.init_calc_mem(243); + tmp_query_str.init_calc_mem(SPD_MID_DB_MBASE_EXEC_QUERY_2); uint query_length = thd->query_length(); if ((log_result_error_with_sql & 2) && query_length) { @@ -2729,7 +2729,7 @@ int spider_db_mbase::xa_end( spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin); DBUG_ENTER("spider_db_mbase::xa_end"); DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(108); + sql_str.init_calc_mem(SPD_MID_DB_MBASE_XA_END_1); sql_str.length(0); sql_str.q_append(SPIDER_SQL_XA_END_STR, SPIDER_SQL_XA_END_LEN); @@ -2772,7 +2772,7 @@ int spider_db_mbase::xa_prepare( spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin); DBUG_ENTER("spider_db_mbase::xa_prepare"); DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(109); + sql_str.init_calc_mem(SPD_MID_DB_MBASE_XA_PREPARE_1); sql_str.length(0); sql_str.q_append(SPIDER_SQL_XA_PREPARE_STR, SPIDER_SQL_XA_PREPARE_LEN); @@ -2815,7 +2815,7 @@ int spider_db_mbase::xa_commit( spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin); DBUG_ENTER("spider_db_mbase::xa_commit"); DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(110); + sql_str.init_calc_mem(SPD_MID_DB_MBASE_XA_COMMIT_1); sql_str.length(0); sql_str.q_append(SPIDER_SQL_XA_COMMIT_STR, SPIDER_SQL_XA_COMMIT_LEN); @@ -2858,7 +2858,7 @@ int spider_db_mbase::xa_rollback( spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin); DBUG_ENTER("spider_db_mbase::xa_rollback"); DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(111); + sql_str.init_calc_mem(SPD_MID_DB_MBASE_XA_ROLLBACK_1); sql_str.length(0); sql_str.q_append(SPIDER_SQL_XA_ROLLBACK_STR, SPIDER_SQL_XA_ROLLBACK_LEN); @@ -3195,7 +3195,7 @@ int spider_db_mbase::set_wait_timeout( spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin); DBUG_ENTER("spider_db_mbase::set_wait_timeout"); DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(264); + sql_str.init_calc_mem(SPD_MID_DB_MBASE_SET_WAIT_TIMEOUT_1); sql_str.length(0); timeout_str_length = my_sprintf(timeout_str, (timeout_str, "%d", wait_timeout)); @@ -3249,7 +3249,7 @@ int spider_db_mbase::set_sql_mode( spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin); DBUG_ENTER("spider_db_mbase::set_sql_mode"); DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(265); + sql_str.init_calc_mem(SPD_MID_DB_MBASE_SET_SQL_MODE_1); sql_str.length(0); if (sql_str.reserve(SPIDER_SQL_SQL_MODE_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -3314,7 +3314,7 @@ int spider_db_mbase::set_time_zone( spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin); DBUG_ENTER("spider_db_mbase::set_time_zone"); DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(214); + sql_str.init_calc_mem(SPD_MID_DB_MBASE_SET_TIME_ZONE_1); sql_str.length(0); if (sql_str.reserve(SPIDER_SQL_TIME_ZONE_LEN + tz_str->length() + SPIDER_SQL_VALUE_QUOTE_LEN)) @@ -3367,7 +3367,7 @@ int spider_db_mbase::set_loop_check( spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin); DBUG_ENTER("spider_db_mbase::set_loop_check"); DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(270); + sql_str.init_calc_mem(SPD_MID_DB_MBASE_SET_LOOP_CHECK_1); while ((lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_element( &conn->loop_check_queue, 0))) { @@ -4179,7 +4179,7 @@ int spider_db_mariadb_util::append_column_value(ha_spider *spider, THD *thd = field->table->in_use; Time_zone *saved_time_zone = thd->variables.time_zone; DBUG_ENTER("spider_db_mariadb_util::append_column_value"); - tmp_str.init_calc_mem(113); + tmp_str.init_calc_mem(SPD_MID_DB_MARIADB_UTIL_APPEND_COLUMN_VALUE_1); thd->variables.time_zone = UTC; @@ -4255,7 +4255,7 @@ int spider_db_mariadb_util::append_column_value(ha_spider *spider, DBUG_PRINT("info", ("spider append_escaped")); char buf2[MAX_FIELD_WIDTH]; spider_string tmp_str2(buf2, MAX_FIELD_WIDTH, field->charset()); - tmp_str2.init_calc_mem(114); + tmp_str2.init_calc_mem(SPD_MID_DB_MARIADB_UTIL_APPEND_COLUMN_VALUE_2); tmp_str2.length(0); if ( tmp_str2.append(ptr->ptr(), ptr->length(), field->charset()) || @@ -4323,7 +4323,7 @@ int spider_db_mysql_util::append_column_value( THD *thd = field->table->in_use; Time_zone *saved_time_zone = thd->variables.time_zone; DBUG_ENTER("spider_db_mysql_util::append_column_value"); - tmp_str.init_calc_mem(266); + tmp_str.init_calc_mem(SPD_MID_DB_MYSQL_UTIL_APPEND_COLUMN_VALUE_1); thd->variables.time_zone = UTC; @@ -4474,7 +4474,7 @@ int spider_db_mysql_util::append_column_value( DBUG_PRINT("info", ("spider append_escaped")); char buf2[MAX_FIELD_WIDTH]; spider_string tmp_str2(buf2, MAX_FIELD_WIDTH, field->charset()); - tmp_str2.init_calc_mem(267); + tmp_str2.init_calc_mem(SPD_MID_DB_MYSQL_UTIL_APPEND_COLUMN_VALUE_2); tmp_str2.length(0); if ( tmp_str2.append(ptr->ptr(), ptr->length(), field->charset()) || @@ -6312,7 +6312,7 @@ int spider_db_mbase_util::print_item_func( char *tmp_ptr, *tmp_ptr2; DBUG_ASSERT(tmp_str.length() == 0); tmp_str.set_charset(str->charset()); - tmp_str.init_calc_mem(123); + tmp_str.init_calc_mem(SPD_MID_DB_MBASE_UTIL_PRINT_ITEM_FUNC_1); tmp_str.reserve(MAX_FIELD_WIDTH); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) @@ -6437,7 +6437,7 @@ int spider_db_mbase_util::print_item_func( char *tmp_ptr, *tmp_ptr2; DBUG_ASSERT(tmp_str.length() == 0); tmp_str.set_charset(str->charset()); - tmp_str.init_calc_mem(124); + tmp_str.init_calc_mem(SPD_MID_DB_MBASE_UTIL_PRINT_ITEM_FUNC_2); tmp_str.reserve(MAX_FIELD_WIDTH); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) @@ -6574,7 +6574,7 @@ int spider_db_mbase_util::print_item_func( char *tmp_ptr, *tmp_ptr2; DBUG_ASSERT(tmp_str.length() == 0); tmp_str.set_charset(str->charset()); - tmp_str.init_calc_mem(125); + tmp_str.init_calc_mem(SPD_MID_DB_MBASE_UTIL_PRINT_ITEM_FUNC_3); tmp_str.reserve(MAX_FIELD_WIDTH); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) @@ -7024,558 +7024,268 @@ int spider_db_mbase_util::append_escaped_util( } #ifdef SPIDER_HAS_GROUP_BY_HANDLER -int spider_db_mbase_util::append_table( - ha_spider *spider, - spider_fields *fields, - spider_string *str, - TABLE_LIST *table_list, - TABLE_LIST **used_table_list, - uint *current_pos, - TABLE_LIST **cond_table_list_ptr, - bool top_down, - bool first -) { - int error_num; - bool use_cond_table_list = FALSE; - spider_mbase_share *db_share; - spider_mbase_handler *dbton_hdl; - SPIDER_TABLE_HOLDER *table_holder; - TABLE_LIST *cond_table_list = *cond_table_list_ptr; - ha_spider *spd; - DBUG_ENTER("spider_db_mbase_util::append_table"); - DBUG_PRINT("info",("spider table_list=%p", table_list)); - DBUG_PRINT("info",("spider table_list->outer_join=%u", - table_list->outer_join)); - DBUG_PRINT("info",("spider table_list->on_expr=%p", - table_list->on_expr)); - DBUG_PRINT("info",("spider table_list->join_using_fields=%p", - table_list->join_using_fields)); - DBUG_PRINT("info",("spider table_list->table=%p", - table_list->table)); - if (!top_down && table_list->embedding) +/* + Walk a TABLE_LIST, or format it to a string and append it. + + If str is NULL, walk the nested join (if any) to determine whether + to create a group by handler. Otherwise, format the TABLE_LIST to a + string and append it to str. + + Adapted from TABLE_LIST::print(). +*/ +int spider_db_mbase_util::append_table_list(spider_fields *fields, + spider_string *str, + TABLE_LIST *table, + table_map *upper_usable_tables, + table_map eliminated_tables) +{ + DBUG_ENTER("spider_db_mbase_util::append_table_list"); + /* Eliminated tables were removed from append_join(). */ + DBUG_ASSERT(!is_eliminated_table(eliminated_tables, table)); + if (!str) /* First pass (GBH creation) */ { - if ((error_num = append_embedding_tables(spider, fields, str, - table_list->embedding, used_table_list, current_pos, - cond_table_list_ptr))) - DBUG_RETURN(error_num); - } else if (!table_list->table) - { - if ((error_num = append_tables_top_down(spider, fields, str, table_list, - used_table_list, current_pos, cond_table_list_ptr))) - DBUG_RETURN(error_num); - } else { - if ( - table_list->outer_join || - table_list->on_expr || - table_list->join_using_fields - ) { - DBUG_PRINT("info",("spider use table_list")); - if (table_list->outer_join & JOIN_TYPE_LEFT) - { - if (str) - { - if (str->reserve(SPIDER_SQL_LEFT_JOIN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_LEFT_JOIN_STR, SPIDER_SQL_LEFT_JOIN_LEN); - } - } else { - if (str) - { - if (str->reserve(SPIDER_SQL_JOIN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_JOIN_STR, SPIDER_SQL_JOIN_LEN); - } - } - } else if ( - cond_table_list && - ( - cond_table_list->outer_join || - cond_table_list->on_expr || - cond_table_list->join_using_fields - ) - ) { - DBUG_PRINT("info",("spider use cond_table_list")); - if (cond_table_list->outer_join & (JOIN_TYPE_LEFT | JOIN_TYPE_RIGHT)) - { - if (str) - { - if (str->reserve(SPIDER_SQL_LEFT_JOIN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_LEFT_JOIN_STR, SPIDER_SQL_LEFT_JOIN_LEN); - } - } else { - if (str) - { - if (str->reserve(SPIDER_SQL_JOIN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_JOIN_STR, SPIDER_SQL_JOIN_LEN); - } - } - use_cond_table_list = TRUE; - } else if (*current_pos > 0 && !first) - { - DBUG_PRINT("info",("spider no condition")); - if (str) - { - if (str->reserve(SPIDER_SQL_JOIN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_JOIN_STR, SPIDER_SQL_JOIN_LEN); - } - } - - if (str) - { - table_holder = fields->get_table_holder(table_list->table); - spd = table_holder->spider; - db_share = (spider_mbase_share *) - spd->share->dbton_share[dbton_id]; - dbton_hdl = (spider_mbase_handler *) - spd->dbton_handler[dbton_id]; - - dbton_hdl->table_name_pos = str->length(); - - if (str->reserve( - db_share->db_nm_max_length + - SPIDER_SQL_DOT_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 4 + - db_share->table_nm_max_length + SPIDER_SQL_SPACE_LEN + - table_holder->alias->length() - SPIDER_SQL_DOT_LEN - )) { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - - if ((error_num = db_share->append_table_name_with_adjusting(str, - spd->conn_link_idx[dbton_hdl->first_link_idx]))) - { - DBUG_RETURN(error_num); - } - str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); - str->q_append(table_holder->alias->ptr(), - table_holder->alias->length() - SPIDER_SQL_DOT_LEN); - } - used_table_list[(*current_pos)++] = table_list; - - if (str) - { - List *join_using_fields = table_list->join_using_fields; - if (!join_using_fields && cond_table_list) - { - join_using_fields = cond_table_list->join_using_fields; - } - - if (join_using_fields) - { - if (str->reserve(SPIDER_SQL_USING_LEN + SPIDER_SQL_OPEN_PAREN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_USING_STR, SPIDER_SQL_USING_LEN); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, - SPIDER_SQL_OPEN_PAREN_LEN); - List_iterator_fast it2(*join_using_fields); - String *ptr; - while ((ptr = it2++)) - { - if (str->reserve(ptr->length() + SPIDER_SQL_COMMA_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(ptr->ptr(), ptr->length()); - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - } - str->length(str->length() - SPIDER_SQL_COMMA_LEN); - 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); - } - } - - Item *on_expr = table_list->on_expr; - if (!on_expr && cond_table_list) - { - on_expr = cond_table_list->on_expr; - } - - if (on_expr) - { - if (str) - { - if (str->reserve(SPIDER_SQL_ON_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_ON_STR, SPIDER_SQL_ON_LEN); - } - if ((error_num = spider_db_print_item_type(on_expr, NULL, - spider, str, NULL, 0, dbton_id, TRUE, fields))) - { - DBUG_RETURN(error_num); - } - } - - if (use_cond_table_list) - { - (*cond_table_list_ptr) = NULL; - DBUG_PRINT("info",("spider cond_table_list=%p", (*cond_table_list_ptr))); - } + DBUG_ASSERT(upper_usable_tables); + if (table->nested_join) + DBUG_RETURN(append_join(fields, str, + &table->nested_join->join_list, + upper_usable_tables, eliminated_tables)); + /* jtbm is a kind of semi join, and TABLE_LIST::print() adds an + extra " " annotation. */ + if (table->jtbm_subselect) + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + /* TODO: These conditions are printed in a different way in + TABLE_LIST::print(), but they do not seem to occur very often. + Let's not worry about them now. */ + if (table->view_name.str || table->derived) + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + *upper_usable_tables |= table->table->map; + DBUG_RETURN(0); } + /* Second pass (query execution) */ + DBUG_ASSERT(!upper_usable_tables); + if (table->nested_join) + { + if (str->append("(")) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + if (int error_num= append_join( + fields, str, &table->nested_join->join_list, + upper_usable_tables, eliminated_tables)) + DBUG_RETURN(error_num); + if (str->append(")")) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + DBUG_RETURN(0); + } + /* These have been ruled out during the creation of the group by + handler, see above. */ + DBUG_ASSERT(!table->jtbm_subselect); + DBUG_ASSERT(!table->view_name.str); + DBUG_ASSERT(!table->derived); + /* We have a "normal" table. Print it and append to str. */ + SPIDER_TABLE_HOLDER *table_holder = fields->get_table_holder(table->table); + ha_spider *spd = table_holder->spider; + spider_mbase_share *db_share = + (spider_mbase_share *) spd->share->dbton_share[dbton_id]; + spider_mbase_handler *dbton_hdl = + (spider_mbase_handler *) spd->dbton_handler[dbton_id]; + if (table->table->const_table) + { + if (str->append(STRING_WITH_LEN("(select 1)"))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + else + if (int error_num= db_share->append_table_name( + str, spd->conn_link_idx[dbton_hdl->first_link_idx])) + DBUG_RETURN(error_num); + if (str->append(" ") || + str->append(table_holder->alias->ptr(), + /* Don't append the trailing dot */ + table_holder->alias->length() - 1)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); DBUG_RETURN(0); } -int spider_db_mbase_util::append_tables_top_down( - ha_spider *spider, - spider_fields *fields, - spider_string *str, - TABLE_LIST *table_list, - TABLE_LIST **used_table_list, - uint *current_pos, - TABLE_LIST **cond_table_list_ptr -) { - int error_num; - uint outer_join_backup; - TABLE_LIST *cur_table_list, *prev_table_list = NULL, *cond_table_list = NULL; - bool first = TRUE; - DBUG_ENTER("spider_db_mbase_util::append_tables_top_down"); - DBUG_PRINT("info",("spider this=%p", this)); - if ( - table_list->outer_join || - table_list->on_expr || - table_list->join_using_fields - ) { - DBUG_ASSERT(!(*cond_table_list_ptr)); - (*cond_table_list_ptr) = table_list; - DBUG_PRINT("info",("spider cond_table_list=%p", table_list)); - } - List_iterator_fast it1(table_list->nested_join->join_list); - cur_table_list = it1++; - if (cur_table_list->outer_join & JOIN_TYPE_RIGHT) - { - first = FALSE; - prev_table_list = cur_table_list; - cur_table_list = it1++; - } else if (*cond_table_list_ptr) - { - first = TRUE; - cond_table_list = (*cond_table_list_ptr); - (*cond_table_list_ptr) = NULL; - if (cond_table_list->outer_join & JOIN_TYPE_LEFT) - { - if (str) - { - if (str->reserve(SPIDER_SQL_LEFT_JOIN_LEN + SPIDER_SQL_OPEN_PAREN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_LEFT_JOIN_STR, SPIDER_SQL_LEFT_JOIN_LEN); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); - } - } else { - if (str) - { - if (str->reserve(SPIDER_SQL_JOIN_LEN + SPIDER_SQL_OPEN_PAREN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_JOIN_STR, SPIDER_SQL_JOIN_LEN); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); - } - } - } +/* + Walk an array of TABLE_LIST's, or format it to a string and append it. - do { - if (cur_table_list->outer_join & JOIN_TYPE_RIGHT) + If str is NULL, walk each TABLE_LIST to determine whether to create + a group by handler. Otherwise, format the TABLE_LISTs to a string + and append it to str. + + Adapted from print_table_array(). +*/ +int spider_db_mbase_util::append_table_array(spider_fields *fields, + spider_string *str, + TABLE_LIST **table, + TABLE_LIST **end, + table_map *upper_usable_tables, + table_map eliminated_tables) +{ + DBUG_ENTER("spider_db_mbase_util::append_table_array"); + if (str) + { + DBUG_ASSERT(!upper_usable_tables); + if (int error_num= append_table_list(fields, str, *table, NULL, + eliminated_tables)) + DBUG_RETURN(error_num); + + for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++) { - prev_table_list = cur_table_list; - } else { - if ((error_num = append_table(spider, fields, str, cur_table_list, - used_table_list, current_pos, cond_table_list_ptr, TRUE, first))) - DBUG_RETURN(error_num); - first = FALSE; - if (prev_table_list) + TABLE_LIST *curr= *tbl; + + /* JOIN_TYPE_OUTER is just a marker unrelated to real join */ + if (curr->outer_join & (JOIN_TYPE_LEFT|JOIN_TYPE_RIGHT)) { - outer_join_backup = prev_table_list->outer_join; - prev_table_list->outer_join = JOIN_TYPE_LEFT; - if ((error_num = append_table(spider, fields, str, prev_table_list, - used_table_list, current_pos, cond_table_list_ptr, TRUE, FALSE))) - { - prev_table_list->outer_join = outer_join_backup; + /* MySQL converts right to left joins */ + if (str->append(STRING_WITH_LEN(" left join "))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + else if (curr->straight) + { + if (str->append(STRING_WITH_LEN(" straight_join "))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + /* semi join should already have been ruled out during the + creation of the group by handler. */ + else if (curr->sj_inner_tables) + DBUG_ASSERT(0); + else + if (str->append(STRING_WITH_LEN(" join "))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + + if (int error_num= append_table_list(fields, str, curr, NULL, + eliminated_tables)) + DBUG_RETURN(error_num); + + if (curr->on_expr) + { + if (str->append(STRING_WITH_LEN(" on "))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + if (int error_num= + spider_db_print_item_type(curr->on_expr, NULL, + fields->get_first_table_holder()->spider, + str, NULL, 0, dbton_id, TRUE, fields)) DBUG_RETURN(error_num); - } - prev_table_list->outer_join = outer_join_backup; - prev_table_list = NULL; - } - } - } while ((cur_table_list = it1++)); - - if (cond_table_list) - { - if (str) - { - 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); - - List *join_using_fields = cond_table_list->join_using_fields; - if (join_using_fields) - { - if (str->reserve(SPIDER_SQL_USING_LEN + SPIDER_SQL_OPEN_PAREN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_USING_STR, SPIDER_SQL_USING_LEN); - str->q_append(SPIDER_SQL_OPEN_PAREN_STR, - SPIDER_SQL_OPEN_PAREN_LEN); - List_iterator_fast it2(*join_using_fields); - String *ptr; - while ((ptr = it2++)) - { - if (str->reserve(ptr->length() + SPIDER_SQL_COMMA_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(ptr->ptr(), ptr->length()); - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); - } - str->length(str->length() - SPIDER_SQL_COMMA_LEN); - 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); - } - } - - Item *on_expr = cond_table_list->on_expr; - if (on_expr) - { - if (str) - { - if (str->reserve(SPIDER_SQL_ON_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_ON_STR, SPIDER_SQL_ON_LEN); - } - if ((error_num = spider_db_print_item_type(on_expr, NULL, - spider, str, NULL, 0, dbton_id, TRUE, fields))) - { - DBUG_RETURN(error_num); } } } - DBUG_RETURN(0); -} - -int spider_db_mbase_util::append_tables_top_down_check( - TABLE_LIST *table_list, - TABLE_LIST **used_table_list, - uint *current_pos -) { - int error_num; - TABLE_LIST *cur_table_list; - DBUG_ENTER("spider_db_mbase_util::append_tables_top_down_check"); - DBUG_PRINT("info",("spider this=%p", this)); - List_iterator_fast it1(table_list->nested_join->join_list); - while ((cur_table_list = it1++)) + else /* str == NULL */ { - if (!cur_table_list->table) - { - if ((error_num = append_tables_top_down_check( - cur_table_list, used_table_list, current_pos))) - DBUG_RETURN(error_num); - } else { - used_table_list[(*current_pos)++] = cur_table_list; - } - } - DBUG_RETURN(0); -} - -int spider_db_mbase_util::append_embedding_tables( - ha_spider *spider, - spider_fields *fields, - spider_string *str, - TABLE_LIST *table_list, - TABLE_LIST **used_table_list, - uint *current_pos, - TABLE_LIST **cond_table_list_ptr -) { - int error_num; - TABLE_LIST *embedding = table_list->embedding; - DBUG_ENTER("spider_db_mbase_util::append_embedding_tables"); - DBUG_PRINT("info",("spider this=%p", this)); - if (embedding) - { - DBUG_PRINT("info",("spider embedding=%p", embedding)); - DBUG_PRINT("info",("spider embedding->outer_join=%u", - embedding->outer_join)); - DBUG_PRINT("info",("spider embedding->on_expr=%p", - embedding->on_expr)); - DBUG_PRINT("info",("spider embedding->join_using_fields=%p", - embedding->join_using_fields)); - DBUG_PRINT("info",("spider embedding->table=%p", - embedding->table)); - if ((error_num = append_embedding_tables(spider, fields, str, embedding, - used_table_list, current_pos, cond_table_list_ptr))) + table_map usable_tables= 0; + if (int error_num= append_table_list(fields, str, *table, + &usable_tables, eliminated_tables)) DBUG_RETURN(error_num); - } else { - DBUG_PRINT("info",("spider table_list=%p", table_list)); - DBUG_PRINT("info",("spider table_list->outer_join=%u", - table_list->outer_join)); - DBUG_PRINT("info",("spider table_list->on_expr=%p", - table_list->on_expr)); - DBUG_PRINT("info",("spider table_list->join_using_fields=%p", - table_list->join_using_fields)); - DBUG_PRINT("info",("spider table_list->table=%p", - table_list->table)); - if (table_list->outer_join & JOIN_TYPE_RIGHT) + for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++) { - if ((error_num = append_tables_top_down_check(table_list, - used_table_list, current_pos))) - DBUG_RETURN(error_num); - DBUG_ASSERT(!(*cond_table_list_ptr)); - (*cond_table_list_ptr) = table_list; - DBUG_PRINT("info",("spider cond_table_list=%p", table_list)); - } else { - if ((error_num = append_tables_top_down(spider, fields, str, table_list, - used_table_list, current_pos, cond_table_list_ptr))) + TABLE_LIST *curr= *tbl; + /* semi join is an "internal" join and is unsupported. */ + if (curr->sj_inner_tables) + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + if (int error_num= append_table_list(fields, str, curr, + &usable_tables, eliminated_tables)) DBUG_RETURN(error_num); + if (curr->on_expr) + { + /* The join refers to fields outside of the current context, + and cannot be handled by a group by handler. */ + if ((curr->on_expr->used_tables() & usable_tables) != + curr->on_expr->used_tables()) + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + if (int error_num= + spider_db_print_item_type(curr->on_expr, NULL, + fields->get_first_table_holder()->spider, + str, NULL, 0, dbton_id, TRUE, fields)) + DBUG_RETURN(error_num); + } } + /* Update usable tables in the outer context. */ + if (upper_usable_tables) + *upper_usable_tables |= usable_tables; } DBUG_RETURN(0); } +/* + Walk a join, or format it to a string and append the string. + + Skip all eliminated tables. + + If str is NULL, walk the tables to determine whether to create a + group by handler. Otherwise, format the join to a string and append + it to str. + + Adapted from print_join(). +*/ +int spider_db_mbase_util::append_join(spider_fields *fields, + spider_string *str, + List *tables, + table_map *upper_usable_tables, + table_map eliminated_tables) +{ + /* List is reversed => we should reverse it before using */ + List_iterator_fast ti(*tables); + TABLE_LIST **table; + THD *thd= fields->get_first_table_holder()->spider->wide_handler->trx->thd; + DBUG_ENTER("spider_db_mbase_util::append_join"); + + size_t tables_to_print= 0; + + for (TABLE_LIST *t= ti++; t ; t= ti++) + { + /* optimized_away implies const_table */ + DBUG_ASSERT(!t->optimized_away || t->table->const_table); + if (!is_eliminated_table(eliminated_tables, t)) + tables_to_print++; + } + if (tables_to_print == 0) + { + if (str && str->append(STRING_WITH_LEN("dual"))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + DBUG_RETURN(0); + } + ti.rewind(); + + if (!(table= static_cast(thd->alloc(sizeof(TABLE_LIST*) * + tables_to_print)))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + + TABLE_LIST *tmp, **t= table + (tables_to_print - 1); + while ((tmp= ti++)) + if (!is_eliminated_table(eliminated_tables, tmp)) + *t--= tmp; + + DBUG_ASSERT(tables->elements >= 1); + if ((*table)->sj_inner_tables) + { + /* Semi join is not supported. */ + if (!str) + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + /* Semi join should have been skipped in the first pass. */ + else + DBUG_ASSERT(0); + } + int error_num= append_table_array( + fields, str, table, table + tables_to_print, upper_usable_tables, + eliminated_tables); + DBUG_RETURN(error_num); +} + int spider_db_mbase_util::append_from_and_tables( ha_spider *spider, spider_fields *fields, spider_string *str, TABLE_LIST *table_list, uint table_count -) { - int error_num; - uint current_pos = 0, roop_count, backup_pos, outer_join_backup; - TABLE *table; - TABLE_LIST **used_table_list, *prev_table_list = NULL, - *cond_table_list = NULL; +) +{ DBUG_ENTER("spider_db_mbase_util::append_from_and_tables"); - DBUG_PRINT("info",("spider this=%p", this)); - used_table_list = (TABLE_LIST **) - my_alloca(sizeof(TABLE_LIST *) * table_count); - if (!used_table_list) + if (str && str->append(" from ")) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - - if (str) - { - if (str->reserve(SPIDER_SQL_FROM_LEN)) - { - my_afree(used_table_list); - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_FROM_STR, SPIDER_SQL_FROM_LEN); - } - - do { - table = table_list->table; - if (table->const_table) - continue; - - for (roop_count = 0; roop_count < current_pos; ++roop_count) - { - if (used_table_list[roop_count] == table_list) - break; - } - if (roop_count < current_pos) - continue; - - if (prev_table_list) - current_pos = backup_pos; - else - backup_pos = current_pos; - if ((error_num = append_table(spider, fields, str, table_list, used_table_list, - ¤t_pos, &cond_table_list, FALSE, FALSE))) - { - my_afree(used_table_list); - DBUG_RETURN(error_num); - } - if (prev_table_list) - { - outer_join_backup = prev_table_list->outer_join; - prev_table_list->outer_join = JOIN_TYPE_LEFT; - if ((error_num = append_table(spider, fields, str, prev_table_list, - used_table_list, ¤t_pos, &cond_table_list, FALSE, FALSE))) - { - prev_table_list->outer_join = outer_join_backup; - my_afree(used_table_list); - DBUG_RETURN(error_num); - } - prev_table_list->outer_join = outer_join_backup; - prev_table_list = NULL; - } - if (cond_table_list && (cond_table_list->outer_join & JOIN_TYPE_RIGHT)) - { - prev_table_list = cond_table_list; - cond_table_list = NULL; - DBUG_PRINT("info",("spider cond_table_list=%p", cond_table_list)); - } - } while ((table_list = table_list->next_local)); - my_afree(used_table_list); - DBUG_RETURN(0); + const table_map eliminated_tables= table_list->select_lex->join ? + table_list->select_lex->join->eliminated_tables : 0; + int error_num = append_join(fields, str, table_list->select_lex->join_list, + NULL, eliminated_tables); + DBUG_RETURN(error_num); } - -int spider_db_mbase_util::reappend_tables( - spider_fields *fields, - SPIDER_LINK_IDX_CHAIN *link_idx_chain, - spider_string *str -) { - int error_num; - uint32 length; - ha_spider *spider; - spider_mbase_share *db_share; - spider_mbase_handler *dbton_hdl; - SPIDER_TABLE_HOLDER *table_holder; - SPIDER_LINK_IDX_HOLDER *link_idx_holder; - DBUG_ENTER("spider_db_mbase_util::reappend_tables"); - DBUG_PRINT("info",("spider this=%p", this)); - length = str->length(); - fields->set_pos_to_first_table_on_link_idx_chain(link_idx_chain); - fields->set_pos_to_first_table_holder(); - while ((table_holder = fields->get_next_table_holder())) - { - link_idx_holder = - fields->get_next_table_on_link_idx_chain(link_idx_chain); - spider = table_holder->spider; - db_share = (spider_mbase_share *) - spider->share->dbton_share[dbton_id]; - if (!db_share->same_db_table_name) - { - dbton_hdl = (spider_mbase_handler *) spider->dbton_handler[dbton_id]; - str->length(dbton_hdl->table_name_pos); - if ((error_num = db_share->append_table_name_with_adjusting(str, - spider->conn_link_idx[link_idx_holder->link_idx]))) - { - DBUG_RETURN(error_num); - } - } - } - str->length(length); - DBUG_RETURN(0); -} - int spider_db_mbase_util::append_where( spider_string *str ) { @@ -7679,7 +7389,7 @@ spider_mbase_share::spider_mbase_share( { DBUG_ENTER("spider_mbase_share::spider_mbase_share"); DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 71); + spider_alloc_calc_mem_init(mem_calc, SPD_MID_MBASE_SHARE_SPIDER_MBASE_SHARE_1); spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); DBUG_VOID_RETURN; } @@ -7753,7 +7463,7 @@ int spider_mbase_share::init() DBUG_ENTER("spider_mbase_share::init"); DBUG_PRINT("info",("spider this=%p", this)); if (!(key_select_pos = (int *) - spider_bulk_alloc_mem(spider_current_trx, 112, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_MBASE_SHARE_INIT_1, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &key_select_pos, sizeof(int) * keys, @@ -7773,7 +7483,7 @@ int spider_mbase_share::init() } for (roop_count = 0; roop_count < keys; roop_count++) { - key_hint[roop_count].init_calc_mem(189); + key_hint[roop_count].init_calc_mem(SPD_MID_MBASE_SHARE_INIT_2); key_hint[roop_count].set_charset(spider_share->access_charset); } DBUG_PRINT("info",("spider key_hint=%p", key_hint)); @@ -7797,13 +7507,13 @@ int spider_mbase_share::init() DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - table_select->init_calc_mem(96); + table_select->init_calc_mem(SPD_MID_MBASE_SHARE_INIT_3); if (table_share && (error_num = append_table_select())) DBUG_RETURN(error_num); for (roop_count = 0; roop_count < keys; roop_count++) { - key_select[roop_count].init_calc_mem(97); + key_select[roop_count].init_calc_mem(SPD_MID_MBASE_SHARE_INIT_4); if ((error_num = append_key_select(roop_count))) DBUG_RETURN(error_num); } @@ -7954,9 +7664,9 @@ int spider_mbase_share::create_table_names_str() for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { - table_names_str[roop_count].init_calc_mem(86); - db_names_str[roop_count].init_calc_mem(87); - db_table_str[roop_count].init_calc_mem(88); + table_names_str[roop_count].init_calc_mem(SPD_MID_MBASE_SHARE_CREATE_TABLE_NAMES_STR_1); + db_names_str[roop_count].init_calc_mem(SPD_MID_MBASE_SHARE_CREATE_TABLE_NAMES_STR_2); + db_table_str[roop_count].init_calc_mem(SPD_MID_MBASE_SHARE_CREATE_TABLE_NAMES_STR_3); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; if (first_all_link_idx == -1) @@ -8097,7 +7807,7 @@ int spider_mbase_share::create_column_name_str() for (field = table_share->field, str = column_name_str; *field; field++, str++) { - str->init_calc_mem(89); + str->init_calc_mem(SPD_MID_MBASE_SHARE_CREATE_COLUMN_NAME_STR_1); str->set_charset(spider_share->access_charset); if ((error_num = spider_db_append_name_with_quote_str(str, (*field)->field_name, dbton_id))) @@ -8165,8 +7875,8 @@ int spider_mbase_share::append_show_table_status() for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { - show_table_status[0 + (2 * roop_count)].init_calc_mem(90); - show_table_status[1 + (2 * roop_count)].init_calc_mem(91); + show_table_status[0 + (2 * roop_count)].init_calc_mem(SPD_MID_MBASE_SHARE_APPEND_SHOW_TABLE_STATUS_1); + show_table_status[1 + (2 * roop_count)].init_calc_mem(SPD_MID_MBASE_SHARE_APPEND_SHOW_TABLE_STATUS_2); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; @@ -8246,7 +7956,7 @@ int spider_mbase_share::append_show_records() for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { - show_records[roop_count].init_calc_mem(92); + show_records[roop_count].init_calc_mem(SPD_MID_MBASE_SHARE_APPEND_SHOW_RECORDS_1); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; @@ -8296,8 +8006,8 @@ int spider_mbase_share::append_show_index() for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { - show_index[0 + (2 * roop_count)].init_calc_mem(93); - show_index[1 + (2 * roop_count)].init_calc_mem(94); + show_index[0 + (2 * roop_count)].init_calc_mem(SPD_MID_MBASE_SHARE_APPEND_SHOW_INDEX_1); + show_index[1 + (2 * roop_count)].init_calc_mem(SPD_MID_MBASE_SHARE_APPEND_SHOW_INDEX_2); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; @@ -8431,7 +8141,7 @@ int spider_mbase_share::discover_table_structure( uint strlen = str->length(); DBUG_ENTER("spider_mbase_share::discover_table_structure"); DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(228); + sql_str.init_calc_mem(SPD_MID_MBASE_SHARE_DISCOVER_TABLE_STRUCTURE_1); for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { @@ -8768,7 +8478,7 @@ spider_mbase_handler::spider_mbase_handler( { DBUG_ENTER("spider_mbase_handler::spider_mbase_handler"); DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 183); + spider_alloc_calc_mem_init(mem_calc, SPD_MID_MBASE_HANDLER_SPIDER_MBASE_HANDLER_1); spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); DBUG_VOID_RETURN; } @@ -8841,14 +8551,14 @@ int spider_mbase_handler::init() TABLE *table = spider->get_table(); DBUG_ENTER("spider_mbase_handler::init"); DBUG_PRINT("info",("spider this=%p", this)); - sql.init_calc_mem(59); - sql_part.init_calc_mem(60); - sql_part2.init_calc_mem(61); - ha_sql.init_calc_mem(62); - insert_sql.init_calc_mem(64); - update_sql.init_calc_mem(65); - tmp_sql.init_calc_mem(66); - dup_update_sql.init_calc_mem(166); + sql.init_calc_mem(SPD_MID_MBASE_HANDLER_INIT_1); + sql_part.init_calc_mem(SPD_MID_MBASE_HANDLER_INIT_2); + sql_part2.init_calc_mem(SPD_MID_MBASE_HANDLER_INIT_3); + ha_sql.init_calc_mem(SPD_MID_MBASE_HANDLER_INIT_4); + insert_sql.init_calc_mem(SPD_MID_MBASE_HANDLER_INIT_5); + update_sql.init_calc_mem(SPD_MID_MBASE_HANDLER_INIT_6); + tmp_sql.init_calc_mem(SPD_MID_MBASE_HANDLER_INIT_7); + dup_update_sql.init_calc_mem(SPD_MID_MBASE_HANDLER_INIT_8); if ( (sql.real_alloc(init_sql_alloc_size)) || (insert_sql.real_alloc(init_sql_alloc_size)) || @@ -8868,7 +8578,7 @@ int spider_mbase_handler::init() upd_tmp_tbl_prm.init(); upd_tmp_tbl_prm.field_count = 1; if (!(link_for_hash = (SPIDER_LINK_FOR_HASH *) - spider_bulk_alloc_mem(spider_current_trx, 141, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_MBASE_HANDLER_INIT_9, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &link_for_hash, sizeof(SPIDER_LINK_FOR_HASH) * share->link_count, @@ -8984,7 +8694,7 @@ int spider_mbase_handler::append_key_column_types( spider_string tmp_str(tmp_buf, sizeof(tmp_buf), system_charset_info); DBUG_ENTER("spider_mbase_handler::append_key_column_types"); DBUG_PRINT("info",("spider this=%p", this)); - tmp_str.init_calc_mem(115); + tmp_str.init_calc_mem(SPD_MID_MBASE_HANDLER_APPEND_KEY_COLUMN_TYPES_1); start_key_part_map = start_key->keypart_map & full_key_part_map; DBUG_PRINT("info", ("spider spider_user_defined_key_parts=%u", @@ -9114,7 +8824,7 @@ int spider_mbase_handler::append_tmp_table_and_sql_for_bka( const char *table_names[2], *table_aliases[2], *table_dot_aliases[2]; uint table_name_lengths[2], table_alias_lengths[2], table_dot_alias_lengths[2]; - tgt_table_name_str.init_calc_mem(99); + tgt_table_name_str.init_calc_mem(SPD_MID_MBASE_HANDLER_APPEND_TMP_TABLE_AND_SQL_FOR_BKA_1); tgt_table_name_str.length(0); create_tmp_bka_table_name(tmp_table_name, &tmp_table_name_length, first_link_idx); @@ -9367,7 +9077,7 @@ int spider_mbase_handler::append_union_table_and_sql_for_bka( const char *table_names[2], *table_aliases[2], *table_dot_aliases[2]; uint table_name_lengths[2], table_alias_lengths[2], table_dot_alias_lengths[2]; - tgt_table_name_str.init_calc_mem(233); + tgt_table_name_str.init_calc_mem(SPD_MID_MBASE_HANDLER_APPEND_UNION_TABLE_AND_SQL_FOR_BKA_1); tgt_table_name_str.length(0); if ((error_num = append_table_name_with_adjusting(&tgt_table_name_str, first_link_idx, SPIDER_SQL_TYPE_SELECT_SQL))) @@ -11708,7 +11418,7 @@ int spider_mbase_handler::append_match_against( char buf[MAX_FIELD_WIDTH]; spider_string tmp_str(buf, MAX_FIELD_WIDTH, share->access_charset); - tmp_str.init_calc_mem(116); + tmp_str.init_calc_mem(SPD_MID_MBASE_HANDLER_APPEND_MATCH_AGAINST_1); tmp_str.length(0); if ( tmp_str.append(ft_init_key->ptr(), ft_init_key->length(), @@ -14059,14 +13769,10 @@ int spider_mbase_handler::set_sql_for_exec( int link_idx, SPIDER_LINK_IDX_CHAIN *link_idx_chain ) { - int error_num; DBUG_ENTER("spider_mbase_handler::set_sql_for_exec"); DBUG_PRINT("info",("spider this=%p", this)); if (sql_type & SPIDER_SQL_TYPE_SELECT_SQL) { - if ((error_num = spider_db_mbase_utility->reappend_tables( - spider->fields, link_idx_chain, &sql))) - DBUG_RETURN(error_num); exec_sql = &sql; } DBUG_RETURN(0); @@ -14101,7 +13807,7 @@ int spider_mbase_handler::set_sql_for_exec( mysql_share->db_names_str[link_idx].charset()); const char *table_names[2], *table_aliases[2]; uint table_name_lengths[2], table_alias_lengths[2]; - tgt_table_name_str.init_calc_mem(104); + tgt_table_name_str.init_calc_mem(SPD_MID_MBASE_HANDLER_SET_SQL_FOR_EXEC_1); tgt_table_name_str.length(0); if (result_list->tmp_table_join && spider->bka_mode != 2) { @@ -16139,7 +15845,7 @@ int spider_mbase_handler::init_union_table_name_pos() DBUG_PRINT("info",("spider this=%p", this)); if (!union_table_name_pos_first) { - if (!spider_bulk_malloc(spider_current_trx, 236, MYF(MY_WME), + if (!spider_bulk_malloc(spider_current_trx, SPD_MID_MBASE_HANDLER_INIT_UNION_TABLE_NAME_POS_1, MYF(MY_WME), &union_table_name_pos_first, (uint) (sizeof(SPIDER_INT_HLD)), NullS) ) { @@ -16160,7 +15866,7 @@ int spider_mbase_handler::set_union_table_name_pos() { if (!union_table_name_pos_current->next) { - if (!spider_bulk_malloc(spider_current_trx, 237, MYF(MY_WME), + if (!spider_bulk_malloc(spider_current_trx, SPD_MID_MBASE_HANDLER_SET_UNION_TABLE_NAME_POS_1, MYF(MY_WME), &union_table_name_pos_current->next, (uint) (sizeof(SPIDER_INT_HLD)), NullS) ) { @@ -16223,8 +15929,7 @@ int spider_mbase_handler::append_from_and_tables_part( default: DBUG_RETURN(0); } - fields->set_pos_to_first_table_holder(); - table_holder = fields->get_next_table_holder(); + table_holder = fields->get_first_table_holder(); table_list = table_holder->table->pos_in_table_list; error_num = spider_db_mbase_utility->append_from_and_tables( table_holder->spider, fields, str, @@ -16232,27 +15937,6 @@ int spider_mbase_handler::append_from_and_tables_part( DBUG_RETURN(error_num); } -int spider_mbase_handler::reappend_tables_part( - spider_fields *fields, - ulong sql_type -) { - int error_num; - spider_string *str; - DBUG_ENTER("spider_mbase_handler::reappend_tables_part"); - DBUG_PRINT("info",("spider this=%p", this)); - switch (sql_type) - { - case SPIDER_SQL_TYPE_SELECT_SQL: - str = &sql; - break; - default: - DBUG_RETURN(0); - } - error_num = spider_db_mbase_utility->reappend_tables(fields, - link_idx_chain, str); - DBUG_RETURN(error_num); -} - int spider_mbase_handler::append_where_part( ulong sql_type ) { @@ -16608,7 +16292,7 @@ int spider_mbase_copy_table::init() { DBUG_ENTER("spider_mbase_copy_table::init"); DBUG_PRINT("info",("spider this=%p", this)); - sql.init_calc_mem(78); + sql.init_calc_mem(SPD_MID_MBASE_COPY_TABLE_INIT_1); DBUG_RETURN(0); } diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h index 0b9c6b44555..34e5afa481c 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -161,40 +161,22 @@ public: String *from ) override; #ifdef SPIDER_HAS_GROUP_BY_HANDLER - int append_table( - ha_spider *spider, - spider_fields *fields, - spider_string *str, - TABLE_LIST *table_list, - TABLE_LIST **used_table_list, - uint *current_pos, - TABLE_LIST **cond_table_list_ptr, - bool top_down, - bool first - ); - int append_tables_top_down( - ha_spider *spider, - spider_fields *fields, - spider_string *str, - TABLE_LIST *table_list, - TABLE_LIST **used_table_list, - uint *current_pos, - TABLE_LIST **cond_table_list_ptr - ); int append_tables_top_down_check( TABLE_LIST *table_list, TABLE_LIST **used_table_list, uint *current_pos ); - int append_embedding_tables( - ha_spider *spider, - spider_fields *fields, - spider_string *str, - TABLE_LIST *table_list, - TABLE_LIST **used_table_list, - uint *current_pos, - TABLE_LIST **cond_table_list_ptr - ); + int append_table_list(spider_fields *fields, + spider_string *str, TABLE_LIST *table, + table_map *upper_usable_tables, + table_map eliminated_tables); + int append_table_array(spider_fields *fields, + spider_string *str, TABLE_LIST **table, + TABLE_LIST **end, table_map *upper_usable_tables, + table_map eliminated_tables); + int append_join(spider_fields *fields, spider_string *str, + List *tables, table_map *upper_usable_tables, + table_map eliminated_tables); int append_from_and_tables( ha_spider *spider, spider_fields *fields, @@ -202,11 +184,6 @@ public: TABLE_LIST *table_list, uint table_count ) override; - int reappend_tables( - spider_fields *fields, - SPIDER_LINK_IDX_CHAIN *link_idx_chain, - spider_string *str - ) override; int append_where( spider_string *str ) override; @@ -698,8 +675,11 @@ public: spider_string *show_table_status; spider_string *show_records; spider_string *show_index; + /* The remote table names */ spider_string *table_names_str; + /* The remote db names */ spider_string *db_names_str; + /* fixme: this field looks useless */ spider_string *db_table_str; #ifdef SPIDER_HAS_HASH_VALUE_TYPE my_hash_value_type *db_table_str_hash_value; @@ -1625,10 +1605,6 @@ public: spider_fields *fields, ulong sql_type ); - int reappend_tables_part( - spider_fields *fields, - ulong sql_type - ); int append_where_part( ulong sql_type ); diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc index 77d3c808b70..a5b46710418 100644 --- a/storage/spider/spd_db_oracle.cc +++ b/storage/spider/spd_db_oracle.cc @@ -170,7 +170,7 @@ int spider_db_oracle_get_error( char buf2[SPIDER_ORACLE_ERR_BUF_LEN]; spider_string tmp_str(buf2, SPIDER_ORACLE_ERR_BUF_LEN, system_charset_info); DBUG_ENTER("spider_db_oracle_get_error"); - tmp_str.init_calc_mem(176); + tmp_str.init_calc_mem(SPD_MID_DB_ORACLE_GET_ERROR_1); tmp_str.length(0); switch (res) @@ -425,7 +425,7 @@ int spider_db_oracle_row::append_escaped_to_str( DBUG_PRINT("info",("spider this=%p", this)); /* spider_string tmp_str(*val, *rlen, str->charset()); - tmp_str.init_calc_mem(174); + tmp_str.init_calc_mem(SPD_MID_DB_ORACLE_ROW_APPEND_ESCAPED_TO_STR_1); tmp_str.length(*rlen); #ifndef DBUG_OFF tmp_str.c_ptr_safe(); @@ -591,7 +591,7 @@ int spider_db_oracle_row::init() DBUG_PRINT("info",("spider this=%p", this)); if ( !(ind = (sb2 *) - spider_bulk_malloc(spider_current_trx, 161, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_DB_ORACLE_ROW_INIT_1, MYF(MY_WME | MY_ZEROFILL), &ind, (uint) (sizeof(sb2) * field_count), &rlen, (uint) (sizeof(ub2) * field_count), &coltp, (uint) (sizeof(ub2) * field_count), @@ -616,7 +616,7 @@ int spider_db_oracle_row::init() for (i = 0; i < field_count; i++) { val[i] = tmp_val; - val_str[i].init_calc_mem(177); + val_str[i].init_calc_mem(SPD_MID_DB_ORACLE_ROW_INIT_2); val_str[i].set(tmp_val, MAX_FIELD_WIDTH, access_charset); tmp_val += MAX_FIELD_WIDTH; } @@ -890,9 +890,9 @@ SPIDER_DB_ROW *spider_db_oracle_result::fetch_row_from_tmp_table( spider_string tmp_str1, tmp_str2, tmp_str3; DBUG_ENTER("spider_db_oracle_result::fetch_row_from_tmp_table"); DBUG_PRINT("info",("spider this=%p", this)); - tmp_str1.init_calc_mem(175); - tmp_str2.init_calc_mem(178); - tmp_str3.init_calc_mem(179); + tmp_str1.init_calc_mem(SPD_MID_DB_ORACLE_RESULT_FETCH_ROW_FROM_TMP_TABLE_1); + tmp_str2.init_calc_mem(SPD_MID_DB_ORACLE_RESULT_FETCH_ROW_FROM_TMP_TABLE_2); + tmp_str3.init_calc_mem(SPD_MID_DB_ORACLE_RESULT_FETCH_ROW_FROM_TMP_TABLE_3); tmp_table->field[0]->val_str(tmp_str1.get_str()); tmp_table->field[1]->val_str(tmp_str2.get_str()); tmp_table->field[2]->val_str(tmp_str3.get_str()); @@ -1157,7 +1157,7 @@ int spider_db_oracle::init() ) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - spider_alloc_calc_mem_init(lock_table_hash, 199); + spider_alloc_calc_mem_init(lock_table_hash, SPD_MID_DB_ORACLE_INIT_1); spider_alloc_calc_mem(spider_current_trx, lock_table_hash, lock_table_hash.array.max_element * @@ -1170,7 +1170,7 @@ int spider_db_oracle::init() ) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - spider_alloc_calc_mem_init(handler_open_array, 164); + spider_alloc_calc_mem_init(handler_open_array, SPD_MID_DB_ORACLE_INIT_2); spider_alloc_calc_mem(spider_current_trx, handler_open_array, handler_open_array.max_element * @@ -1464,7 +1464,7 @@ int spider_db_oracle::exec_query( uint32 tgt_len = conn->tgt_host_length; spider_string tmp_query_str(length + conn->tgt_wrapper_length + tgt_len + (SPIDER_SQL_SPACE_LEN * 2)); - tmp_query_str.init_calc_mem(232); + tmp_query_str.init_calc_mem(SPD_MID_DB_ORACLE_EXEC_QUERY_1); tmp_query_str.length(0); tmp_query_str.q_append(conn->tgt_wrapper, conn->tgt_wrapper_length); tmp_query_str.q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN); @@ -2719,7 +2719,7 @@ int spider_db_oracle_util::append_column_value( uint length; Time_zone *saved_time_zone = thd->variables.time_zone; DBUG_ENTER("spider_db_oracle_util::append_column_value"); - tmp_str.init_calc_mem(181); + tmp_str.init_calc_mem(SPD_MID_DB_ORACLE_UTIL_APPEND_COLUMN_VALUE_1); thd->variables.time_zone = UTC; @@ -2856,7 +2856,7 @@ int spider_db_oracle_util::append_column_value( DBUG_PRINT("info", ("spider append_escaped")); char buf2[MAX_FIELD_WIDTH]; spider_string tmp_str2(buf2, MAX_FIELD_WIDTH, access_charset); - tmp_str2.init_calc_mem(182); + tmp_str2.init_calc_mem(SPD_MID_DB_ORACLE_UTIL_APPEND_COLUMN_VALUE_2); tmp_str2.length(0); if ( tmp_str2.append(ptr->ptr(), ptr->length(), field->charset()) || @@ -3552,7 +3552,7 @@ int spider_db_oracle_util::open_item_func( { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); - tmp_str.init_calc_mem(123); + tmp_str.init_calc_mem(SPD_MID_DB_ORACLE_UTIL_OPEN_ITEM_FUNC_1); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) @@ -3692,7 +3692,7 @@ int spider_db_oracle_util::open_item_func( { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); - tmp_str.init_calc_mem(124); + tmp_str.init_calc_mem(SPD_MID_DB_ORACLE_UTIL_OPEN_ITEM_FUNC_2); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) @@ -3986,7 +3986,7 @@ int spider_db_oracle_util::open_item_func( { char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); - tmp_str.init_calc_mem(125); + tmp_str.init_calc_mem(SPD_MID_DB_ORACLE_UTIL_OPEN_ITEM_FUNC_3); tmp_str.length(0); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) @@ -4630,7 +4630,7 @@ spider_oracle_share::spider_oracle_share( { DBUG_ENTER("spider_oracle_share::spider_oracle_share"); DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 220); + spider_alloc_calc_mem_init(mem_calc, SPD_MID_ORACLE_SHARE_SPIDER_ORACLE_SHARE_1); spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); DBUG_VOID_RETURN; } @@ -4669,7 +4669,7 @@ int spider_oracle_share::init() DBUG_ENTER("spider_oracle_share::init"); DBUG_PRINT("info",("spider this=%p", this)); if (!(key_select_pos = (int *) - spider_bulk_alloc_mem(spider_current_trx, 221, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_ORACLE_SHARE_INIT_1, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &key_select_pos, sizeof(int) * keys, @@ -4689,7 +4689,7 @@ int spider_oracle_share::init() } for (roop_count = 0; roop_count < keys; roop_count++) { - key_hint[roop_count].init_calc_mem(190); + key_hint[roop_count].init_calc_mem(SPD_MID_ORACLE_SHARE_INIT_2); key_hint[roop_count].set_charset(spider_share->access_charset); } DBUG_PRINT("info",("spider key_hint=%p", key_hint)); @@ -4715,13 +4715,13 @@ int spider_oracle_share::init() DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - table_select->init_calc_mem(191); + table_select->init_calc_mem(SPD_MID_ORACLE_SHARE_INIT_3); if (table_share && (error_num = append_table_select())) DBUG_RETURN(error_num); for (roop_count = 0; roop_count < keys; roop_count++) { - key_select[roop_count].init_calc_mem(192); + key_select[roop_count].init_calc_mem(SPD_MID_ORACLE_SHARE_INIT_4); if ((error_num = append_key_select(roop_count))) DBUG_RETURN(error_num); } @@ -4873,9 +4873,9 @@ int spider_oracle_share::create_table_names_str() for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { - table_names_str[roop_count].init_calc_mem(193); - db_names_str[roop_count].init_calc_mem(194); - db_table_str[roop_count].init_calc_mem(195); + table_names_str[roop_count].init_calc_mem(SPD_MID_ORACLE_SHARE_CREATE_TABLE_NAMES_STR_1); + db_names_str[roop_count].init_calc_mem(SPD_MID_ORACLE_SHARE_CREATE_TABLE_NAMES_STR_2); + db_table_str[roop_count].init_calc_mem(SPD_MID_ORACLE_SHARE_CREATE_TABLE_NAMES_STR_3); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; if (first_all_link_idx == -1) @@ -5017,7 +5017,7 @@ int spider_oracle_share::create_column_name_str() for (field = table_share->field, str = column_name_str; *field; field++, str++) { - str->init_calc_mem(196); + str->init_calc_mem(SPD_MID_ORACLE_SHARE_CREATE_COLUMN_NAME_STR_1); str->set_charset(spider_share->access_charset); if ((error_num = spider_db_append_name_with_quote_str(str, (*field)->field_name, dbton_id))) @@ -5086,8 +5086,8 @@ int spider_oracle_share::append_show_table_status() for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { - show_table_status[0 + (2 * roop_count)].init_calc_mem(197); - show_table_status[1 + (2 * roop_count)].init_calc_mem(207); + show_table_status[0 + (2 * roop_count)].init_calc_mem(SPD_MID_ORACLE_SHARE_APPEND_SHOW_TABLE_STATUS_1); + show_table_status[1 + (2 * roop_count)].init_calc_mem(SPD_MID_ORACLE_SHARE_APPEND_SHOW_TABLE_STATUS_2); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; @@ -5168,7 +5168,7 @@ int spider_oracle_share::append_show_records() for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { - show_records[roop_count].init_calc_mem(208); + show_records[roop_count].init_calc_mem(SPD_MID_ORACLE_SHARE_APPEND_SHOW_RECORDS_1); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; @@ -5226,7 +5226,7 @@ int spider_oracle_share::append_show_autoinc() for (roop_count = 0; roop_count < spider_share->all_link_count; roop_count++) { - show_autoinc[roop_count].init_calc_mem(224); + show_autoinc[roop_count].init_calc_mem(SPD_MID_ORACLE_SHARE_APPEND_SHOW_AUTOINC_1); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; @@ -5296,8 +5296,8 @@ int spider_oracle_share::append_show_last_insert_id() for (roop_count = 0; roop_count < spider_share->all_link_count; roop_count++) { - show_last_insert_id[roop_count].init_calc_mem(225); - nextval_str[roop_count].init_calc_mem(226); + show_last_insert_id[roop_count].init_calc_mem(SPD_MID_ORACLE_SHARE_APPEND_SHOW_LAST_INSERT_ID_1); + nextval_str[roop_count].init_calc_mem(SPD_MID_ORACLE_SHARE_APPEND_SHOW_LAST_INSERT_ID_2); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; @@ -5393,8 +5393,8 @@ int spider_oracle_share::append_show_index() for (roop_count = 0; roop_count < (int) spider_share->all_link_count; roop_count++) { - show_index[0 + (2 * roop_count)].init_calc_mem(209); - show_index[1 + (2 * roop_count)].init_calc_mem(210); + show_index[0 + (2 * roop_count)].init_calc_mem(SPD_MID_ORACLE_SHARE_APPEND_SHOW_INDEX_1); + show_index[1 + (2 * roop_count)].init_calc_mem(SPD_MID_ORACLE_SHARE_APPEND_SHOW_INDEX_2); if (spider_share->sql_dbton_ids[roop_count] != dbton_id) continue; @@ -5565,7 +5565,7 @@ spider_oracle_handler::spider_oracle_handler( { DBUG_ENTER("spider_oracle_handler::spider_oracle_handler"); DBUG_PRINT("info",("spider this=%p", this)); - spider_alloc_calc_mem_init(mem_calc, 222); + spider_alloc_calc_mem_init(mem_calc, SPD_MID_ORACLE_HANDLER_SPIDER_ORACLE_HANDLER_1); spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this)); DBUG_VOID_RETURN; } @@ -5598,14 +5598,14 @@ int spider_oracle_handler::init() TABLE *table = spider->get_table(); DBUG_ENTER("spider_oracle_handler::init"); DBUG_PRINT("info",("spider this=%p", this)); - sql.init_calc_mem(67); - sql_part.init_calc_mem(68); - sql_part2.init_calc_mem(69); - ha_sql.init_calc_mem(70); - insert_sql.init_calc_mem(72); - update_sql.init_calc_mem(73); - tmp_sql.init_calc_mem(74); - dup_update_sql.init_calc_mem(167); + sql.init_calc_mem(SPD_MID_ORACLE_HANDLER_INIT_1); + sql_part.init_calc_mem(SPD_MID_ORACLE_HANDLER_INIT_2); + sql_part2.init_calc_mem(SPD_MID_ORACLE_HANDLER_INIT_3); + ha_sql.init_calc_mem(SPD_MID_ORACLE_HANDLER_INIT_4); + insert_sql.init_calc_mem(SPD_MID_ORACLE_HANDLER_INIT_5); + update_sql.init_calc_mem(SPD_MID_ORACLE_HANDLER_INIT_6); + tmp_sql.init_calc_mem(SPD_MID_ORACLE_HANDLER_INIT_7); + dup_update_sql.init_calc_mem(SPD_MID_ORACLE_HANDLER_INIT_8); if ( (sql.real_alloc(init_sql_alloc_size)) || (insert_sql.real_alloc(init_sql_alloc_size)) || @@ -5625,7 +5625,7 @@ int spider_oracle_handler::init() upd_tmp_tbl_prm.init(); upd_tmp_tbl_prm.field_count = 1; if (!(link_for_hash = (SPIDER_LINK_FOR_HASH *) - spider_bulk_alloc_mem(spider_current_trx, 223, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_ORACLE_HANDLER_INIT_9, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &link_for_hash, sizeof(SPIDER_LINK_FOR_HASH) * share->link_count, @@ -5696,7 +5696,7 @@ int spider_oracle_handler::append_key_column_types( spider_string tmp_str(tmp_buf, sizeof(tmp_buf), system_charset_info); DBUG_ENTER("spider_oracle_handler::append_key_column_types"); DBUG_PRINT("info",("spider this=%p", this)); - tmp_str.init_calc_mem(227); + tmp_str.init_calc_mem(SPD_MID_ORACLE_HANDLER_APPEND_KEY_COLUMN_TYPES_1); start_key_part_map = start_key->keypart_map & full_key_part_map; DBUG_PRINT("info", ("spider spider_user_defined_key_parts=%u", @@ -5817,7 +5817,7 @@ int spider_oracle_handler::append_tmp_table_and_sql_for_bka( const char *table_names[2], *table_aliases[2], *table_dot_aliases[2]; uint table_name_lengths[2], table_alias_lengths[2], table_dot_alias_lengths[2]; - tgt_table_name_str.init_calc_mem(200); + tgt_table_name_str.init_calc_mem(SPD_MID_ORACLE_HANDLER_APPEND_TMP_TABLE_AND_SQL_FOR_BKA_1); tgt_table_name_str.length(0); create_tmp_bka_table_name(tmp_table_name, &tmp_table_name_length, first_link_idx); @@ -6066,7 +6066,7 @@ int spider_oracle_handler::append_union_table_and_sql_for_bka( const char *table_names[2], *table_aliases[2], *table_dot_aliases[2]; uint table_name_lengths[2], table_alias_lengths[2], table_dot_alias_lengths[2]; - tgt_table_name_str.init_calc_mem(234); + tgt_table_name_str.init_calc_mem(SPD_MID_ORACLE_HANDLER_APPEND_UNION_TABLE_AND_SQL_FOR_BKA_1); tgt_table_name_str.length(0); if ((error_num = append_table_name_with_adjusting(&tgt_table_name_str, first_link_idx, SPIDER_SQL_TYPE_SELECT_SQL))) @@ -8046,7 +8046,7 @@ int spider_oracle_handler::append_match_against( char buf[MAX_FIELD_WIDTH]; spider_string tmp_str(buf, MAX_FIELD_WIDTH, share->access_charset); - tmp_str.init_calc_mem(211); + tmp_str.init_calc_mem(SPD_MID_ORACLE_HANDLER_APPEND_MATCH_AGAINST_1); tmp_str.length(0); if ( tmp_str.append(ft_init_key->ptr(), ft_init_key->length(), @@ -10940,7 +10940,7 @@ int spider_oracle_handler::set_sql_for_exec( oracle_share->db_names_str[link_idx].charset()); const char *table_names[2], *table_aliases[2]; uint table_name_lengths[2], table_alias_lengths[2]; - tgt_table_name_str.init_calc_mem(212); + tgt_table_name_str.init_calc_mem(SPD_MID_ORACLE_HANDLER_SET_SQL_FOR_EXEC_1); tgt_table_name_str.length(0); if (result_list->tmp_table_join && spider->bka_mode != 2) { @@ -12713,7 +12713,7 @@ int spider_oracle_handler::init_union_table_name_pos() DBUG_PRINT("info",("spider this=%p", this)); if (!union_table_name_pos_first) { - if (!spider_bulk_malloc(spider_current_trx, 238, MYF(MY_WME), + if (!spider_bulk_malloc(spider_current_trx, SPD_MID_ORACLE_HANDLER_INIT_UNION_TABLE_NAME_POS_1, MYF(MY_WME), &union_table_name_pos_first, (uint) (sizeof(SPIDER_INT_HLD)), NullS) ) { @@ -12734,7 +12734,7 @@ int spider_oracle_handler::set_union_table_name_pos() { if (!union_table_name_pos_current->next) { - if (!spider_bulk_malloc(spider_current_trx, 239, MYF(MY_WME), + if (!spider_bulk_malloc(spider_current_trx, SPD_MID_ORACLE_HANDLER_SET_UNION_TABLE_NAME_POS_1, MYF(MY_WME), &union_table_name_pos_current->next, (uint) (sizeof(SPIDER_INT_HLD)), NullS) ) { @@ -13145,8 +13145,8 @@ int spider_oracle_copy_table::init() { DBUG_ENTER("spider_oracle_copy_table::init"); DBUG_PRINT("info",("spider this=%p", this)); - sql.init_calc_mem(213); - sql_part.init_calc_mem(215); + sql.init_calc_mem(SPD_MID_ORACLE_COPY_TABLE_INIT_1); + sql_part.init_calc_mem(SPD_MID_ORACLE_COPY_TABLE_INIT_2); DBUG_RETURN(0); } @@ -13746,7 +13746,7 @@ int spider_oracle_copy_table::copy_rows( { if (!(first_str = new spider_string[1])) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - first_str->init_calc_mem(216); + first_str->init_calc_mem(SPD_MID_ORACLE_COPY_TABLE_COPY_ROWS_1); first_str->set_charset(sql.charset()); if (first_str->reserve(sql.length())) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -13760,7 +13760,7 @@ int spider_oracle_copy_table::copy_rows( { if (!(current_str->next = new spider_string[1])) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - current_str->next->init_calc_mem(217); + current_str->next->init_calc_mem(SPD_MID_ORACLE_COPY_TABLE_COPY_ROWS_2); current_str->next->set_charset(sql.charset()); if (current_str->next->reserve(sql.length())) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -13812,7 +13812,7 @@ int spider_oracle_copy_table::copy_rows( { if (!(first_str = new spider_string[1])) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - first_str->init_calc_mem(218); + first_str->init_calc_mem(SPD_MID_ORACLE_COPY_TABLE_COPY_ROWS_3); first_str->set_charset(sql.charset()); if (first_str->reserve(sql.length())) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -13826,7 +13826,7 @@ int spider_oracle_copy_table::copy_rows( { if (!(current_str->next = new spider_string[1])) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - current_str->next->init_calc_mem(219); + current_str->next->init_calc_mem(SPD_MID_ORACLE_COPY_TABLE_COPY_ROWS_4); current_str->next->set_charset(sql.charset()); if (current_str->next->reserve(sql.length())) DBUG_RETURN(HA_ERR_OUT_OF_MEM); diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc index 1caaea695b6..2a238f0b374 100644 --- a/storage/spider/spd_direct_sql.cc +++ b/storage/spider/spd_direct_sql.cc @@ -117,7 +117,7 @@ int spider_udf_direct_sql_create_table_list( } #if MYSQL_VERSION_ID < 50500 if (!(direct_sql->db_names = (char**) - spider_bulk_malloc(spider_current_trx, 31, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_UDF_DIRECT_SQL_CREATE_TABLE_LIST_1, MYF(MY_WME | MY_ZEROFILL), &direct_sql->db_names, (uint) (sizeof(char*) * table_count), &direct_sql->table_names, (uint) (sizeof(char*) * table_count), &direct_sql->tables, (uint) (sizeof(TABLE*) * table_count), @@ -131,7 +131,7 @@ int spider_udf_direct_sql_create_table_list( ) #else if (!(direct_sql->db_names = (char**) - spider_bulk_malloc(spider_current_trx, 31, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_UDF_DIRECT_SQL_CREATE_TABLE_LIST_2, MYF(MY_WME | MY_ZEROFILL), &direct_sql->db_names, (uint) (sizeof(char*) * table_count), &direct_sql->table_names, (uint) (sizeof(char*) * table_count), &direct_sql->tables, (uint) (sizeof(TABLE*) * table_count), @@ -303,7 +303,7 @@ int spider_udf_direct_sql_create_conn_key( } #endif if (!(direct_sql->conn_key = (char *) - spider_malloc(spider_current_trx, 9, direct_sql->conn_key_length + 1, + spider_malloc(spider_current_trx, SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_KEY_1, direct_sql->conn_key_length + 1, MYF(MY_WME | MY_ZEROFILL))) ) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -464,7 +464,7 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( spider_dbton[direct_sql->dbton_id].db_util-> tables_on_different_db_are_joinable(); if (!(conn = (SPIDER_CONN *) - spider_bulk_malloc(spider_current_trx, 32, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_1, MYF(MY_WME | MY_ZEROFILL), &conn, (uint) (sizeof(*conn)), &tmp_name, (uint) (direct_sql->conn_key_length + 1), &tmp_host, (uint) (direct_sql->tgt_host_length + 1), @@ -495,11 +495,11 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( *error_num = HA_ERR_OUT_OF_MEM; goto error_alloc_conn; } - conn->default_database.init_calc_mem(138); + conn->default_database.init_calc_mem(SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_2); #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) } else { if (!(conn = (SPIDER_CONN *) - spider_bulk_malloc(spider_current_trx, 33, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_3, MYF(MY_WME | MY_ZEROFILL), &conn, (uint) (sizeof(*conn)), &tmp_name, (uint) (direct_sql->conn_key_length + 1), &tmp_host, (uint) (direct_sql->tgt_host_length + 1), @@ -511,7 +511,7 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( *error_num = HA_ERR_OUT_OF_MEM; goto error_alloc_conn; } - conn->default_database.init_calc_mem(103); + conn->default_database.init_calc_mem(SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_4); } #endif @@ -1733,7 +1733,7 @@ long long spider_direct_sql_body( DBUG_ENTER("spider_direct_sql_body"); SPIDER_BACKUP_DASTATUS; if (!(direct_sql = (SPIDER_DIRECT_SQL *) - spider_bulk_malloc(spider_current_trx, 34, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_DIRECT_SQL_BODY_1, MYF(MY_WME | MY_ZEROFILL), &direct_sql, (uint) (sizeof(SPIDER_DIRECT_SQL)), &sql, (uint) (sizeof(char) * args->lengths[0]), NullS)) @@ -1994,7 +1994,7 @@ my_bool spider_direct_sql_init_body( if (bg) { if (!(bg_direct_sql = (SPIDER_BG_DIRECT_SQL *) - spider_malloc(spider_current_trx, 10, sizeof(SPIDER_BG_DIRECT_SQL), + spider_malloc(spider_current_trx, SPD_MID_DIRECT_SQL_INIT_BODY_1, sizeof(SPIDER_BG_DIRECT_SQL), MYF(MY_WME | MY_ZEROFILL))) ) { strcpy(message, "spider_bg_direct_sql() out of memory"); diff --git a/storage/spider/spd_group_by_handler.cc b/storage/spider/spd_group_by_handler.cc index 91a7e82d23c..b260bde8b57 100644 --- a/storage/spider/spd_group_by_handler.cc +++ b/storage/spider/spd_group_by_handler.cc @@ -26,6 +26,7 @@ #include "probes_mysql.h" #include "sql_class.h" #include "sql_partition.h" +#include "sql_select.h" #include "ha_partition.h" #endif #include "sql_common.h" @@ -47,11 +48,9 @@ extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; spider_fields::spider_fields() : dbton_count(0), current_dbton_num(0), - table_count(0), current_table_num(0), table_holder(NULL), + table_count(0), table_holder(NULL), first_link_idx_chain(NULL), last_link_idx_chain(NULL), current_link_idx_chain(NULL), - first_conn_holder(NULL), last_conn_holder(NULL), current_conn_holder(NULL), - first_field_holder(NULL), last_field_holder(NULL), current_field_holder(NULL), - first_field_chain(NULL), last_field_chain(NULL), current_field_chain(NULL) + first_conn_holder(NULL), last_conn_holder(NULL), current_conn_holder(NULL) { DBUG_ENTER("spider_fields::spider_fields"); DBUG_PRINT("info",("spider this=%p", this)); @@ -70,24 +69,6 @@ spider_fields::~spider_fields() spider_free(spider_current_trx, current_link_idx_chain, MYF(0)); } } - if (first_field_chain) - { - while ((current_field_chain = first_field_chain)) - { - first_field_chain = current_field_chain->next; - spider_free(spider_current_trx, current_field_chain, MYF(0)); - } - } - if (first_field_holder) - { - while ((current_field_holder = first_field_holder)) - { - first_field_holder = current_field_holder->next; - spider_free(spider_current_trx, current_field_holder, MYF(0)); - } - } - if (table_holder) - spider_free(spider_current_trx, table_holder, MYF(0)); if (first_conn_holder) { while ((current_conn_holder = first_conn_holder)) @@ -369,7 +350,7 @@ SPIDER_LINK_IDX_CHAIN *spider_fields::create_link_idx_chain( DBUG_ENTER("spider_fields::create_link_idx_chain"); DBUG_PRINT("info",("spider this=%p", this)); DBUG_RETURN((SPIDER_LINK_IDX_CHAIN *) - spider_malloc(spider_current_trx, 254, sizeof(SPIDER_LINK_IDX_CHAIN), + spider_malloc(spider_current_trx, SPD_MID_FIELDS_CREATE_LINK_IDX_CHAIN_1, sizeof(SPIDER_LINK_IDX_CHAIN), MYF(MY_WME | MY_ZEROFILL))); } @@ -476,7 +457,6 @@ int spider_fields::get_ok_link_idx( void spider_fields::set_first_link_idx( ) { - SPIDER_TABLE_HOLDER *table_holder; SPIDER_LINK_IDX_HOLDER *link_idx_holder; SPIDER_LINK_IDX_CHAIN *link_idx_chain; uint dbton_id; @@ -498,11 +478,10 @@ void spider_fields::set_first_link_idx( DBUG_ASSERT(link_idx_chain); set_pos_to_first_table_on_link_idx_chain(link_idx_chain); - set_pos_to_first_table_holder(); - while ((table_holder = get_next_table_holder())) + for (uint i= 0; i < table_count; i++) { link_idx_holder = get_next_table_on_link_idx_chain(link_idx_chain); - spider = table_holder->spider; + spider = table_holder[i].spider; dbton_hdl = spider->dbton_handler[dbton_id]; dbton_hdl->first_link_idx = link_idx_holder->link_idx; } @@ -559,7 +538,7 @@ SPIDER_LINK_IDX_HOLDER *spider_fields::create_link_idx_holder( DBUG_ENTER("spider_fields::create_link_idx_holder"); DBUG_PRINT("info",("spider this=%p", this)); DBUG_RETURN((SPIDER_LINK_IDX_HOLDER *) - spider_malloc(spider_current_trx, 253, sizeof(SPIDER_LINK_IDX_HOLDER), + spider_malloc(spider_current_trx, SPD_MID_FIELDS_CREATE_LINK_IDX_HOLDER_1, sizeof(SPIDER_LINK_IDX_HOLDER), MYF(MY_WME | MY_ZEROFILL))); } @@ -637,7 +616,7 @@ SPIDER_CONN_HOLDER *spider_fields::create_conn_holder( DBUG_ENTER("spider_fields::create_conn_holder"); DBUG_PRINT("info",("spider this=%p", this)); return_conn_holder = (SPIDER_CONN_HOLDER *) - spider_bulk_malloc(spider_current_trx, 252, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_FIELDS_CREATE_CONN_HOLDER_1, MYF(MY_WME | MY_ZEROFILL), &return_conn_holder, (uint) (sizeof(SPIDER_CONN_HOLDER)), &table_link_idx_holder, (uint) (table_count * sizeof(SPIDER_TABLE_LINK_IDX_HOLDER)), @@ -651,24 +630,6 @@ SPIDER_CONN_HOLDER *spider_fields::create_conn_holder( DBUG_RETURN(return_conn_holder); } -void spider_fields::set_pos_to_first_conn_holder( -) { - DBUG_ENTER("spider_fields::set_pos_to_first_conn_holder"); - DBUG_PRINT("info",("spider this=%p", this)); - current_conn_holder = first_conn_holder; - DBUG_VOID_RETURN; -} - -SPIDER_CONN_HOLDER *spider_fields::get_next_conn_holder( -) { - SPIDER_CONN_HOLDER *return_conn_holder = current_conn_holder; - DBUG_ENTER("spider_fields::get_next_conn_holder"); - DBUG_PRINT("info",("spider this=%p", this)); - if (current_conn_holder) - current_conn_holder = current_conn_holder->next; - DBUG_RETURN(return_conn_holder); -} - bool spider_fields::has_conn_holder( ) { DBUG_ENTER("spider_fields::has_conn_holder"); @@ -867,19 +828,17 @@ void spider_fields::free_conn_holder( DBUG_VOID_RETURN; } -SPIDER_TABLE_HOLDER *spider_fields::add_table( - ha_spider *spider_arg +/* Add the table associated with an ha_spider to a table_holder. +Return the table_holder. */ +static SPIDER_TABLE_HOLDER *spider_add_table_holder( + ha_spider *spider_arg, + SPIDER_TABLE_HOLDER *table_holder ) { spider_string *str; uint length; char tmp_buf[SPIDER_SQL_INT_LEN + 2]; SPIDER_TABLE_HOLDER *return_table_holder; - SPIDER_FIELD_HOLDER *field_holder; - TABLE *table = spider_arg->get_table(); - Field *field; DBUG_ENTER("spider_fields::add_table"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider table_count=%u", table_count)); DBUG_PRINT("info",("spider idx_for_direct_join=%u", spider_arg->idx_for_direct_join)); length = my_sprintf(tmp_buf, (tmp_buf, "t%u", @@ -898,90 +857,49 @@ SPIDER_TABLE_HOLDER *spider_fields::add_table( return_table_holder->spider = spider_arg; return_table_holder->alias = str; - set_pos_to_first_field_holder(); - while ((field_holder = get_next_field_holder())) - { - if (!field_holder->spider) - { - field = field_holder->field; - if ( - field->field_index < table->s->fields && - field == table->field[field->field_index] - ) { - field_holder->spider = spider_arg; - field_holder->alias = str; - } - } - } DBUG_RETURN(return_table_holder); } -/** - Verify that all fields in the query are members of tables that are in the - query. - - @return TRUE All fields in the query are members of tables - that are in the query. - FALSE At least one field in the query is not a - member of a table that is in the query. -*/ - -bool spider_fields::all_query_fields_are_query_table_members() +/* Return the table that field belongs to, or NULL if none exists. */ +SPIDER_TABLE_HOLDER *spider_fields::find_table(Field *field) { - SPIDER_FIELD_HOLDER *field_holder; - DBUG_ENTER("spider_fields::all_query_fields_are_query_table_members"); - DBUG_PRINT("info",("spider this=%p", this)); - - set_pos_to_first_field_holder(); - while ((field_holder = get_next_field_holder())) - { - if (!field_holder->spider) - { - DBUG_PRINT("info", ("spider field is not a member of a query table")); - DBUG_RETURN(FALSE); - } - } - - DBUG_RETURN(TRUE); + for (uint i = 0; i < table_count; i++) + if (field->table == table_holder[i].table) + return &table_holder[i]; + return NULL; } -int spider_fields::create_table_holder( +void spider_fields::set_table_holder(SPIDER_TABLE_HOLDER *table_holder_arg, + uint table_count_arg) +{ + table_holder= table_holder_arg; + table_count= table_count_arg; +} + +/* Allocate space for table_count_arg table holders. */ +static SPIDER_TABLE_HOLDER *spider_create_table_holder( uint table_count_arg ) { - DBUG_ENTER("spider_fields::create_table_holder"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(!table_holder); + SPIDER_TABLE_HOLDER* table_holder; + DBUG_ENTER("spider_create_table_holder"); + if (table_count_arg == 0) + DBUG_RETURN(0); table_holder = (SPIDER_TABLE_HOLDER *) - spider_malloc(spider_current_trx, 249, + spider_malloc(spider_current_trx, SPD_MID_CREATE_TABLE_HOLDER_1, table_count_arg * sizeof(SPIDER_TABLE_HOLDER), MYF(MY_WME | MY_ZEROFILL)); - if (!table_holder) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - table_count = table_count_arg; - current_table_num = 0; - DBUG_RETURN(0); + DBUG_RETURN(table_holder); } -void spider_fields::set_pos_to_first_table_holder( -) { - DBUG_ENTER("spider_fields::set_pos_to_first_table_holder"); - DBUG_PRINT("info",("spider this=%p", this)); - current_table_num = 0; - DBUG_VOID_RETURN; -} - -SPIDER_TABLE_HOLDER *spider_fields::get_next_table_holder( -) { - SPIDER_TABLE_HOLDER *return_table_holder; - DBUG_ENTER("spider_fields::get_next_table_holder"); - DBUG_PRINT("info",("spider this=%p", this)); - if (current_table_num >= table_count) - DBUG_RETURN(NULL); - return_table_holder = &table_holder[current_table_num]; - ++current_table_num; - DBUG_RETURN(return_table_holder); +/* Return pointer to the first table holder. */ +SPIDER_TABLE_HOLDER *spider_fields::get_first_table_holder() +{ + DBUG_ENTER("spider_fields::get_first_spider"); + DBUG_RETURN(table_holder); } +/* Return the first table holder associated with a given table, or +NULL if not found. */ SPIDER_TABLE_HOLDER *spider_fields::get_table_holder(TABLE *table) { uint table_num; @@ -1001,117 +919,12 @@ uint spider_fields::get_table_count() DBUG_RETURN(table_count); } -int spider_fields::add_field( - Field *field_arg -) { - SPIDER_FIELD_HOLDER *field_holder; - SPIDER_FIELD_CHAIN *field_chain; - DBUG_ENTER("spider_fields::add_field"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider field=%p", field_arg)); - if (!first_field_holder) - { - field_holder = create_field_holder(); - DBUG_PRINT("info",("spider field_holder=%p", field_holder)); - if (!field_holder) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - field_holder->field = field_arg; - first_field_holder = field_holder; - last_field_holder = field_holder; - } else { - field_holder = first_field_holder; - do { - if (field_holder->field == field_arg) - break; - } while ((field_holder = field_holder->next)); - if (!field_holder) - { - field_holder = create_field_holder(); - DBUG_PRINT("info",("spider field_holder=%p", field_holder)); - if (!field_holder) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - field_holder->field = field_arg; - last_field_holder->next = field_holder; - last_field_holder = field_holder; - } - } - field_chain = create_field_chain(); - DBUG_PRINT("info",("spider field_chain=%p", field_chain)); - if (!field_chain) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - field_chain->field_holder = field_holder; - if (!first_field_chain) - { - first_field_chain = field_chain; - last_field_chain = field_chain; - } else { - last_field_chain->next = field_chain; - last_field_chain = field_chain; - } - DBUG_RETURN(0); -} - -SPIDER_FIELD_HOLDER *spider_fields::create_field_holder( -) { - DBUG_ENTER("spider_fields::create_field_holder"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN((SPIDER_FIELD_HOLDER *) - spider_malloc(spider_current_trx, 250, sizeof(SPIDER_FIELD_HOLDER), - MYF(MY_WME | MY_ZEROFILL))); -} - -void spider_fields::set_pos_to_first_field_holder( -) { - DBUG_ENTER("spider_fields::set_pos_to_first_field_holder"); - DBUG_PRINT("info",("spider this=%p", this)); - current_field_holder = first_field_holder; - DBUG_VOID_RETURN; -} - -SPIDER_FIELD_HOLDER *spider_fields::get_next_field_holder( -) { - SPIDER_FIELD_HOLDER *return_field_holder = current_field_holder; - DBUG_ENTER("spider_fields::get_next_field_holder"); - DBUG_PRINT("info",("spider this=%p", this)); - if (current_field_holder) - current_field_holder = current_field_holder->next; - DBUG_RETURN(return_field_holder); -} - -SPIDER_FIELD_CHAIN *spider_fields::create_field_chain( -) { - DBUG_ENTER("spider_fields::create_field_chain"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN((SPIDER_FIELD_CHAIN *) - spider_malloc(spider_current_trx, 251, sizeof(SPIDER_FIELD_CHAIN), - MYF(MY_WME | MY_ZEROFILL))); -} - -void spider_fields::set_pos_to_first_field_chain( -) { - DBUG_ENTER("spider_fields::set_pos_to_first_field_chain"); - DBUG_PRINT("info",("spider this=%p", this)); - current_field_chain = first_field_chain; - DBUG_VOID_RETURN; -} - -SPIDER_FIELD_CHAIN *spider_fields::get_next_field_chain( -) { - SPIDER_FIELD_CHAIN *return_field_chain = current_field_chain; - DBUG_ENTER("spider_fields::get_next_field_chain"); - DBUG_PRINT("info",("spider this=%p", this)); - if (current_field_chain) - current_field_chain = current_field_chain->next; - DBUG_RETURN(return_field_chain); -} - void spider_fields::set_field_ptr( Field **field_arg ) { DBUG_ENTER("spider_fields::set_field_ptr"); DBUG_PRINT("info",("spider this=%p", this)); DBUG_PRINT("info",("spider field_ptr=%p", field_arg)); - first_field_ptr = field_arg; current_field_ptr = field_arg; DBUG_VOID_RETURN; } @@ -1134,15 +947,13 @@ int spider_fields::ping_table_mon_from_table( ha_spider *tmp_spider; SPIDER_SHARE *tmp_share; int tmp_link_idx; - SPIDER_TABLE_HOLDER *table_holder; SPIDER_LINK_IDX_HOLDER *link_idx_holder; DBUG_ENTER("spider_fields::ping_table_mon_from_table"); set_pos_to_first_table_on_link_idx_chain(link_idx_chain); - set_pos_to_first_table_holder(); - while ((table_holder = get_next_table_holder())) + for (uint i= 0; i < table_count; i++) { link_idx_holder = get_next_table_on_link_idx_chain(link_idx_chain); - tmp_spider = table_holder->spider; + tmp_spider = table_holder[i].spider; tmp_link_idx = link_idx_holder->link_idx; tmp_share = tmp_spider->share; if (tmp_share->monitoring_kind[tmp_link_idx]) @@ -1179,9 +990,7 @@ spider_group_by_handler::spider_group_by_handler( query(*query_arg), fields(fields_arg) { DBUG_ENTER("spider_group_by_handler::spider_group_by_handler"); - fields->set_pos_to_first_table_holder(); - SPIDER_TABLE_HOLDER *table_holder = fields->get_next_table_holder(); - spider = table_holder->spider; + spider = fields->get_first_table_holder()->spider; trx = spider->wide_handler->trx; DBUG_VOID_RETURN; } @@ -1189,42 +998,21 @@ spider_group_by_handler::spider_group_by_handler( spider_group_by_handler::~spider_group_by_handler() { DBUG_ENTER("spider_group_by_handler::~spider_group_by_handler"); + spider_free(spider_current_trx, fields->get_first_table_holder(), MYF(0)); delete fields; DBUG_VOID_RETURN; } -int spider_group_by_handler::init_scan() +static int spider_prepare_init_scan( + const Query& query, spider_fields *fields, ha_spider *spider, + SPIDER_TRX *trx, longlong& offset_limit, THD *thd) { int error_num, link_idx; - uint dbton_id; - spider_db_handler *dbton_hdl; - st_select_lex *select_lex; - longlong select_limit; - longlong direct_order_limit; - SPIDER_SHARE *share = spider->share; - SPIDER_CONN *conn; SPIDER_RESULT_LIST *result_list = &spider->result_list; - SPIDER_LINK_IDX_CHAIN *link_idx_chain; - SPIDER_LINK_IDX_HOLDER *link_idx_holder; - DBUG_ENTER("spider_group_by_handler::init_scan"); - store_error = 0; -#ifndef DBUG_OFF - Field **field; - for ( - field = table->field; - *field; - field++ - ) { - DBUG_PRINT("info",("spider field_name=%s", - SPIDER_field_name_str(*field))); - } -#endif - - if (trx->thd->killed) - { - my_error(ER_QUERY_INTERRUPTED, MYF(0)); - DBUG_RETURN(ER_QUERY_INTERRUPTED); - } + st_select_lex *select_lex; + longlong select_limit, direct_order_limit; + SPIDER_SHARE *share = spider->share; + DBUG_ENTER("spider_prepare_init_scan"); spider->use_fields = TRUE; spider->fields = fields; @@ -1300,86 +1088,87 @@ int spider_group_by_handler::init_scan() } else { offset_limit = 0; } + DBUG_RETURN(0); +} + +static int spider_make_query(const Query& query, spider_fields* fields, ha_spider *spider, TABLE *table) +{ + uint dbton_id; + spider_db_handler* dbton_hdl; + SPIDER_RESULT_LIST *result_list = &spider->result_list; + int error_num; + DBUG_ENTER("spider_make_query"); - /* making a query */ fields->set_pos_to_first_dbton_id(); while ((dbton_id = fields->get_next_dbton_id()) < SPIDER_DBTON_SIZE) { dbton_hdl = spider->dbton_handler[dbton_id]; result_list->direct_distinct = query.distinct; - fields->set_pos_to_first_field_chain(); if ((error_num = dbton_hdl->reset_sql(SPIDER_SQL_TYPE_SELECT_SQL))) - { DBUG_RETURN(error_num); - } if ((error_num = dbton_hdl->append_select_part(SPIDER_SQL_TYPE_SELECT_SQL))) - { DBUG_RETURN(error_num); - } fields->set_field_ptr(table->field); if ((error_num = dbton_hdl->append_list_item_select_part( - query.select, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) - { + query.select, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } if ((error_num = dbton_hdl->append_from_and_tables_part( - fields, SPIDER_SQL_TYPE_SELECT_SQL))) - { + fields, SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } if (query.where) { if ((error_num = - dbton_hdl->append_where_part(SPIDER_SQL_TYPE_SELECT_SQL))) - { + dbton_hdl->append_where_part(SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } if ((error_num = dbton_hdl->append_item_type_part( - query.where, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) - { + query.where, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } } if (query.group_by) { if ((error_num = dbton_hdl->append_group_by_part( - query.group_by, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) - { + query.group_by, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } } if (query.having) { if ((error_num = - dbton_hdl->append_having_part(SPIDER_SQL_TYPE_SELECT_SQL))) - { + dbton_hdl->append_having_part(SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } if ((error_num = dbton_hdl->append_item_type_part( - query.having, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) - { + query.having, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } } if (query.order_by) { if ((error_num = dbton_hdl->append_order_by_part( - query.order_by, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL))) - { + query.order_by, NULL, 0, TRUE, fields, + SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } } - if ((error_num = dbton_hdl->append_limit_part(result_list->internal_offset, - result_list->limit_num, SPIDER_SQL_TYPE_SELECT_SQL))) - { + if ((error_num = dbton_hdl->append_limit_part( + result_list->internal_offset, result_list->limit_num, + SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } if ((error_num = dbton_hdl->append_select_lock_part( - SPIDER_SQL_TYPE_SELECT_SQL))) - { + SPIDER_SQL_TYPE_SELECT_SQL))) DBUG_RETURN(error_num); - } } + DBUG_RETURN(0); +} + +static int spider_send_query( + spider_fields *fields, ha_spider *spider, SPIDER_TRX *trx, TABLE *table, + int& store_error) +{ + int error_num, link_idx; + spider_db_handler *dbton_hdl; + SPIDER_RESULT_LIST *result_list = &spider->result_list; + SPIDER_SHARE *share = spider->share; + SPIDER_CONN *conn; + SPIDER_LINK_IDX_CHAIN *link_idx_chain; + SPIDER_LINK_IDX_HOLDER *link_idx_holder; + DBUG_ENTER("spider_send_query"); fields->set_pos_to_first_link_idx_chain(); while ((link_idx_chain = fields->get_next_link_idx_chain())) @@ -1399,12 +1188,8 @@ int spider_group_by_handler::init_scan() dbton_hdl->first_link_idx, TRUE, FALSE, !fields->is_first_link_ok_chain(link_idx_chain)))) { - if ( - error_num != HA_ERR_END_OF_FILE && - spider->need_mons[link_idx] - ) { + if (error_num != HA_ERR_END_OF_FILE && spider->need_mons[link_idx]) error_num = fields->ping_table_mon_from_table(link_idx_chain); - } if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) { store_error = HA_ERR_END_OF_FILE; @@ -1415,12 +1200,9 @@ int spider_group_by_handler::init_scan() } else { #endif pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); - if ((error_num = - dbton_hdl->set_sql_for_exec(SPIDER_SQL_TYPE_SELECT_SQL, link_idx, - link_idx_chain))) - { + if ((error_num = dbton_hdl->set_sql_for_exec( + SPIDER_SQL_TYPE_SELECT_SQL, link_idx, link_idx_chain))) DBUG_RETURN(error_num); - } pthread_mutex_lock(&conn->mta_conn_mutex); SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); conn->need_mon = &spider->need_mons[link_idx]; @@ -1430,6 +1212,7 @@ int spider_group_by_handler::init_scan() conn->mta_conn_mutex_unlock_later = TRUE; if ((error_num = spider_db_set_names(spider, conn, link_idx))) + if ((error_num = spider_db_set_names(spider, conn, link_idx))) { DBUG_ASSERT(conn->mta_conn_mutex_lock_already); DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); @@ -1437,37 +1220,32 @@ int spider_group_by_handler::init_scan() conn->mta_conn_mutex_unlock_later = FALSE; SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); pthread_mutex_unlock(&conn->mta_conn_mutex); - if ( - spider->need_mons[link_idx] - ) { + if (spider->need_mons[link_idx]) error_num = fields->ping_table_mon_from_table(link_idx_chain); - } - if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) + if ((error_num = spider->check_error_mode_eof(error_num)) == + HA_ERR_END_OF_FILE) { store_error = HA_ERR_END_OF_FILE; error_num = 0; } DBUG_RETURN(error_num); } - spider_conn_set_timeout_from_share(conn, link_idx, - trx->thd, share); + spider_conn_set_timeout_from_share(conn, link_idx, trx->thd, share); if (dbton_hdl->execute_sql( SPIDER_SQL_TYPE_SELECT_SQL, conn, spider->result_list.quick_mode, - &spider->need_mons[link_idx]) - ) { + &spider->need_mons[link_idx])) + { DBUG_ASSERT(conn->mta_conn_mutex_lock_already); DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); conn->mta_conn_mutex_lock_already = FALSE; conn->mta_conn_mutex_unlock_later = FALSE; error_num = spider_db_errorno(conn); - if ( - spider->need_mons[link_idx] - ) { + if (spider->need_mons[link_idx]) error_num = fields->ping_table_mon_from_table(link_idx_chain); - } - if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) + if ((error_num = spider->check_error_mode_eof(error_num)) == + HA_ERR_END_OF_FILE) { store_error = HA_ERR_END_OF_FILE; error_num = 0; @@ -1483,13 +1261,10 @@ int spider_group_by_handler::init_scan() { if ((error_num = spider_db_store_result(spider, link_idx, table))) { - if ( - error_num != HA_ERR_END_OF_FILE && - spider->need_mons[link_idx] - ) { + if (error_num != HA_ERR_END_OF_FILE && spider->need_mons[link_idx]) error_num = fields->ping_table_mon_from_table(link_idx_chain); - } - if ((error_num = spider->check_error_mode_eof(error_num)) == HA_ERR_END_OF_FILE) + if ((error_num = spider->check_error_mode_eof(error_num)) == + HA_ERR_END_OF_FILE) { store_error = HA_ERR_END_OF_FILE; error_num = 0; @@ -1498,7 +1273,8 @@ int spider_group_by_handler::init_scan() } spider->result_link_idx = link_idx; spider->result_link_idx_chain = link_idx_chain; - } else { + } else + { spider_db_discard_result(spider, link_idx, conn); SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); pthread_mutex_unlock(&conn->mta_conn_mutex); @@ -1507,6 +1283,37 @@ int spider_group_by_handler::init_scan() } #endif } + DBUG_RETURN(0); +} + +/* + Prepare and send query to data nodes and store the query results. +*/ +int spider_group_by_handler::init_scan() +{ + int error_num; + DBUG_ENTER("spider_group_by_handler::init_scan"); + store_error = 0; +#ifndef DBUG_OFF + for (Field **field = table->field; *field; field++) + DBUG_PRINT("info",("spider field_name=%s", SPIDER_field_name_str(*field))); +#endif + + if (trx->thd->killed) + { + my_error(ER_QUERY_INTERRUPTED, MYF(0)); + DBUG_RETURN(ER_QUERY_INTERRUPTED); + } + + if ((error_num = spider_prepare_init_scan( + query, fields, spider, trx, offset_limit, thd))) + DBUG_RETURN(error_num); + + if ((error_num = spider_make_query(query, fields, spider, table))) + DBUG_RETURN(error_num); + + if ((error_num = spider_send_query(fields, spider, trx, table, store_error))) + DBUG_RETURN(error_num); first = TRUE; DBUG_RETURN(0); @@ -1617,7 +1424,8 @@ group_by_handler *spider_create_group_by_handler( bool keep_going; bool find_dbton = FALSE; spider_fields *fields = NULL, *fields_arg = NULL; - uint table_idx, dbton_id; + SPIDER_TABLE_HOLDER *table_holder; + uint table_idx, dbton_id, table_count= 0; long tgt_link_status; DBUG_ENTER("spider_create_group_by_handler"); @@ -1637,8 +1445,7 @@ group_by_handler *spider_create_group_by_handler( from = query->from; do { DBUG_PRINT("info",("spider from=%p", from)); - if (from->table->const_table) - continue; + ++table_count; if (from->table->part_info) { DBUG_PRINT("info",("spider partition handler")); @@ -1660,17 +1467,11 @@ group_by_handler *spider_create_group_by_handler( } while ((from = from->next_local)); #endif + if (!(table_holder= spider_create_table_holder(table_count))) + DBUG_RETURN(NULL); + table_idx = 0; from = query->from; - while (from && from->table->const_table) - { - from = from->next_local; - } - if (!from) - { - /* all tables are const_table */ - DBUG_RETURN(NULL); - } #if defined(PARTITION_HAS_GET_CHILD_HANDLERS) if (from->table->part_info) { @@ -1688,6 +1489,11 @@ group_by_handler *spider_create_group_by_handler( share = spider->share; spider->idx_for_direct_join = table_idx; ++table_idx; + if (!spider_add_table_holder(spider, table_holder)) + { + DBUG_PRINT("info",("spider can not add a table")); + goto skip_free_table_holder; + } memset(dbton_bitmap, 0, spider_bitmap_size(SPIDER_DBTON_SIZE)); for (roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count) { @@ -1701,8 +1507,6 @@ group_by_handler *spider_create_group_by_handler( } while ((from = from->next_local)) { - if (from->table->const_table) - continue; #if defined(PARTITION_HAS_GET_CHILD_HANDLERS) if (from->table->part_info) { @@ -1720,6 +1524,11 @@ group_by_handler *spider_create_group_by_handler( share = spider->share; spider->idx_for_direct_join = table_idx; ++table_idx; + if (!spider_add_table_holder(spider, table_holder)) + { + DBUG_PRINT("info",("spider can not add a table")); + goto skip_free_table_holder; + } memset(dbton_bitmap_tmp, 0, spider_bitmap_size(SPIDER_DBTON_SIZE)); for (roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count) { @@ -1740,8 +1549,6 @@ group_by_handler *spider_create_group_by_handler( from = query->from; do { - if (from->table->const_table) - continue; #if defined(PARTITION_HAS_GET_CHILD_HANDLERS) if (from->table->part_info) { @@ -1773,10 +1580,9 @@ group_by_handler *spider_create_group_by_handler( { fields_arg = new spider_fields(); if (!fields_arg) - { - DBUG_RETURN(NULL); - } + goto skip_free_table_holder; } + fields_arg->set_table_holder(table_holder, table_count); keep_going = TRUE; it.init(*query->select); while ((item = it++)) @@ -1883,21 +1689,9 @@ group_by_handler *spider_create_group_by_handler( } } if (!find_dbton) - { - DBUG_RETURN(NULL); - } - - if (fields->create_table_holder(table_idx)) - { - delete fields; - DBUG_RETURN(NULL); - } + goto skip_free_table_holder; from = query->from; - while (from->table->const_table) - { - from = from->next_local; - } #if defined(PARTITION_HAS_GET_CHILD_HANDLERS) if (from->table->part_info) { @@ -1922,17 +1716,10 @@ group_by_handler *spider_create_group_by_handler( } DBUG_PRINT("info",("spider s->db=%s", from->table->s->db.str)); DBUG_PRINT("info",("spider s->table_name=%s", from->table->s->table_name.str)); - if (!fields->add_table(spider)) - { - DBUG_PRINT("info",("spider can not add a table")); - delete fields; - DBUG_RETURN(NULL); - } if (spider->dml_init()) { DBUG_PRINT("info",("spider can not init for dml")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } for ( roop_count = spider_conn_link_idx_next(share->link_statuses, @@ -1947,10 +1734,7 @@ group_by_handler *spider_create_group_by_handler( { DBUG_PRINT("info",("spider direct_join does not support use_handler")); if (lock_mode) - { - delete fields; - DBUG_RETURN(NULL); - } + goto skip_free_fields; continue; } conn = spider->conns[roop_count]; @@ -1962,8 +1746,7 @@ group_by_handler *spider_create_group_by_handler( DBUG_PRINT("info",("spider direct_join does not support with lock tables yet")); if (lock_mode) { - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } continue; } @@ -1971,26 +1754,21 @@ group_by_handler *spider_create_group_by_handler( share->access_balances[spider->conn_link_idx[roop_count]])) { DBUG_PRINT("info",("spider can not create conn_holder")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } if (fields->add_link_idx(conn->conn_holder_for_direct_join, spider, roop_count)) { DBUG_PRINT("info",("spider can not create link_idx_holder")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } } if (!fields->has_conn_holder()) { - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } while ((from = from->next_local)) { - if (from->table->const_table) - continue; fields->clear_conn_holder_from_conn(); #if defined(PARTITION_HAS_GET_CHILD_HANDLERS) @@ -2008,19 +1786,12 @@ group_by_handler *spider_create_group_by_handler( } #endif share = spider->share; - if (!fields->add_table(spider)) - { - DBUG_PRINT("info",("spider can not add a table")); - delete fields; - DBUG_RETURN(NULL); - } DBUG_PRINT("info",("spider s->db=%s", from->table->s->db.str)); DBUG_PRINT("info",("spider s->table_name=%s", from->table->s->table_name.str)); if (spider->dml_init()) { DBUG_PRINT("info",("spider can not init for dml")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } for ( roop_count = spider_conn_link_idx_next(share->link_statuses, @@ -2036,10 +1807,7 @@ group_by_handler *spider_create_group_by_handler( { DBUG_PRINT("info",("spider direct_join does not support use_handler")); if (lock_mode) - { - delete fields; - DBUG_RETURN(NULL); - } + goto skip_free_fields; continue; } conn = spider->conns[roop_count]; @@ -2049,17 +1817,13 @@ group_by_handler *spider_create_group_by_handler( DBUG_PRINT("info",("spider connection %p can not be used for this query with locking", conn)); if (lock_mode) - { - delete fields; - DBUG_RETURN(NULL); - } + goto skip_free_fields; continue; } if (fields->add_link_idx(conn->conn_holder_for_direct_join, spider, roop_count)) { DBUG_PRINT("info",("spider can not create link_idx_holder")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } } @@ -2068,30 +1832,20 @@ group_by_handler *spider_create_group_by_handler( if (lock_mode) { DBUG_PRINT("info",("spider some connections can not be used for this query with locking")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } } if (!fields->has_conn_holder()) { - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } } - if (!fields->all_query_fields_are_query_table_members()) - { - DBUG_PRINT("info", ("spider found a query field that is not a query table member")); - delete fields; - DBUG_RETURN(NULL); - } - fields->check_support_dbton(dbton_bitmap); if (!fields->has_conn_holder()) { DBUG_PRINT("info",("spider all chosen connections can't match dbton_id")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } /* choose a connection */ @@ -2103,16 +1857,14 @@ group_by_handler *spider_create_group_by_handler( if (fields->make_link_idx_chain(tgt_link_status)) { DBUG_PRINT("info",("spider can not create link_idx_chain")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } /* choose link_id */ if (fields->check_link_ok_chain()) { DBUG_PRINT("info",("spider do not have link ok status")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } fields->set_first_link_idx(); @@ -2120,8 +1872,7 @@ group_by_handler *spider_create_group_by_handler( if (!(group_by_handler = new spider_group_by_handler(thd, query, fields))) { DBUG_PRINT("info",("spider can't create group_by_handler")); - delete fields; - DBUG_RETURN(NULL); + goto skip_free_fields; } query->distinct = FALSE; query->where = NULL; @@ -2129,5 +1880,11 @@ group_by_handler *spider_create_group_by_handler( query->having = NULL; query->order_by = NULL; DBUG_RETURN(group_by_handler); + +skip_free_fields: + delete fields; +skip_free_table_holder: + spider_free(spider_current_trx, table_holder, MYF(0)); + DBUG_RETURN(NULL); } #endif diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index 82a39fcde30..d556b79b08c 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -295,6 +295,279 @@ typedef Open_tables_backup SPIDER_Open_tables_backup; #define SPIDER_MEM_CALC_LIST_NUM 314 #define SPIDER_CONN_META_BUF_LEN 64 +/* + IDs for spider mem alloc functions, including + - spider_alloc_calc_mem_init() + - spider_string::init_calc_mem() + - spider_malloc() + - spider_bulk_alloc_mem() + - spider_bulk_malloc() + In the format of + SPD_MID__ +*/ +enum spider_malloc_id { + SPD_MID_CHECK_HS_PK_UPDATE_1, + SPD_MID_COPY_TABLES_BODY_1, + SPD_MID_COPY_TABLES_BODY_2, + SPD_MID_COPY_TABLES_BODY_3, + SPD_MID_COPY_TABLES_BODY_4, + SPD_MID_COPY_TABLES_BODY_5, + SPD_MID_CREATE_CONN_1, + SPD_MID_CREATE_CONN_2, + SPD_MID_CREATE_CONN_3, + SPD_MID_CREATE_CONN_4, + SPD_MID_CREATE_CONN_5, + SPD_MID_CREATE_CONN_6, + SPD_MID_CREATE_CONN_KEYS_1, + SPD_MID_CREATE_CONN_THREAD_1, + SPD_MID_CREATE_LONGLONG_LIST_1, + SPD_MID_CREATE_LONG_LIST_1, + SPD_MID_CREATE_MON_THREADS_1, + SPD_MID_CREATE_MON_THREADS_2, + SPD_MID_CREATE_SHARE_1, + SPD_MID_CREATE_SHARE_2, + SPD_MID_CREATE_SPIDER_OBJECT_FOR_SHARE_1, + SPD_MID_CREATE_SPIDER_OBJECT_FOR_SHARE_2, + SPD_MID_CREATE_STRING_1, + SPD_MID_CREATE_STRING_LIST_1, + SPD_MID_CREATE_TABLE_HOLDER_1, + SPD_MID_CREATE_TABLE_NAME_STRING_1, + SPD_MID_CREATE_TRX_ALTER_TABLE_1, + SPD_MID_CREATE_TRX_HA_1, + SPD_MID_DB_CONN_QUEUE_ACTION_1, + SPD_MID_DB_FETCH_FOR_ITEM_SUM_FUNC_1, + SPD_MID_DB_FETCH_FOR_ITEM_SUM_FUNC_2, + SPD_MID_DB_FETCH_FOR_ITEM_SUM_FUNC_3, + SPD_MID_DB_HANDLERSOCKET_APPEND_REQUEST_KEY_1, + SPD_MID_DB_HANDLERSOCKET_EXEC_QUERY_1, + SPD_MID_DB_HANDLERSOCKET_INIT_1, + SPD_MID_DB_HANDLERSOCKET_RESULT_FETCH_ROW_FROM_TMP_TABLE_1, + SPD_MID_DB_HANDLERSOCKET_RESULT_FETCH_ROW_FROM_TMP_TABLE_2, + SPD_MID_DB_HANDLERSOCKET_ROW_APPEND_ESCAPED_TO_STR_1, + SPD_MID_DB_HANDLERSOCKET_ROW_CLONE_1, + SPD_MID_DB_HANDLERSOCKET_ROW_STORE_TO_FIELD_1, + SPD_MID_DB_HANDLERSOCKET_UTIL_APPEND_COLUMN_VALUE_1, + SPD_MID_DB_HANDLERSOCKET_UTIL_OPEN_ITEM_FUNC_1, + SPD_MID_DB_HANDLERSOCKET_UTIL_OPEN_ITEM_FUNC_2, + SPD_MID_DB_HANDLERSOCKET_UTIL_OPEN_ITEM_FUNC_3, + SPD_MID_DB_HS_STRING_REF_BUFFER_INIT_1, + SPD_MID_DB_HS_STR_BUFFER_ADD_1, + SPD_MID_DB_HS_STR_BUFFER_ADD_2, + SPD_MID_DB_HS_STR_BUFFER_INIT_1, + SPD_MID_DB_INIT_1, + SPD_MID_DB_INIT_10, + SPD_MID_DB_INIT_11, + SPD_MID_DB_INIT_12, + SPD_MID_DB_INIT_2, + SPD_MID_DB_INIT_3, + SPD_MID_DB_INIT_4, + SPD_MID_DB_INIT_5, + SPD_MID_DB_INIT_6, + SPD_MID_DB_INIT_7, + SPD_MID_DB_INIT_8, + SPD_MID_DB_INIT_9, + SPD_MID_DB_MARIADB_UTIL_APPEND_COLUMN_VALUE_1, + SPD_MID_DB_MARIADB_UTIL_APPEND_COLUMN_VALUE_2, + SPD_MID_DB_MBASE_EXEC_QUERY_1, + SPD_MID_DB_MBASE_EXEC_QUERY_2, + SPD_MID_DB_MBASE_INIT_1, + SPD_MID_DB_MBASE_INIT_2, + SPD_MID_DB_MBASE_RESULT_FETCH_ROW_FROM_TMP_TABLE_1, + SPD_MID_DB_MBASE_RESULT_FETCH_ROW_FROM_TMP_TABLE_2, + SPD_MID_DB_MBASE_RESULT_FETCH_ROW_FROM_TMP_TABLE_3, + SPD_MID_DB_MBASE_ROW_APPEND_ESCAPED_TO_STR_1, + SPD_MID_DB_MBASE_ROW_CLONE_1, + SPD_MID_DB_MBASE_SET_LOOP_CHECK_1, + SPD_MID_DB_MBASE_SET_SQL_MODE_1, + SPD_MID_DB_MBASE_SET_TIME_ZONE_1, + SPD_MID_DB_MBASE_SET_WAIT_TIMEOUT_1, + SPD_MID_DB_MBASE_UTIL_PRINT_ITEM_FUNC_1, + SPD_MID_DB_MBASE_UTIL_PRINT_ITEM_FUNC_2, + SPD_MID_DB_MBASE_UTIL_PRINT_ITEM_FUNC_3, + SPD_MID_DB_MBASE_XA_COMMIT_1, + SPD_MID_DB_MBASE_XA_END_1, + SPD_MID_DB_MBASE_XA_PREPARE_1, + SPD_MID_DB_MBASE_XA_ROLLBACK_1, + SPD_MID_DB_MYSQL_UTIL_APPEND_COLUMN_VALUE_1, + SPD_MID_DB_MYSQL_UTIL_APPEND_COLUMN_VALUE_2, + SPD_MID_DB_OPEN_ITEM_INT_1, + SPD_MID_DB_OPEN_ITEM_STRING_1, + SPD_MID_DB_ORACLE_EXEC_QUERY_1, + SPD_MID_DB_ORACLE_GET_ERROR_1, + SPD_MID_DB_ORACLE_INIT_1, + SPD_MID_DB_ORACLE_INIT_2, + SPD_MID_DB_ORACLE_RESULT_FETCH_ROW_FROM_TMP_TABLE_1, + SPD_MID_DB_ORACLE_RESULT_FETCH_ROW_FROM_TMP_TABLE_2, + SPD_MID_DB_ORACLE_RESULT_FETCH_ROW_FROM_TMP_TABLE_3, + SPD_MID_DB_ORACLE_ROW_APPEND_ESCAPED_TO_STR_1, + SPD_MID_DB_ORACLE_ROW_INIT_1, + SPD_MID_DB_ORACLE_ROW_INIT_2, + SPD_MID_DB_ORACLE_UTIL_APPEND_COLUMN_VALUE_1, + SPD_MID_DB_ORACLE_UTIL_APPEND_COLUMN_VALUE_2, + SPD_MID_DB_ORACLE_UTIL_OPEN_ITEM_FUNC_1, + SPD_MID_DB_ORACLE_UTIL_OPEN_ITEM_FUNC_2, + SPD_MID_DB_ORACLE_UTIL_OPEN_ITEM_FUNC_3, + SPD_MID_DB_QUERY_1, + SPD_MID_DB_STORE_RESULT_1, + SPD_MID_DB_STORE_RESULT_2, + SPD_MID_DB_STORE_RESULT_3, + SPD_MID_DB_STORE_RESULT_4, + SPD_MID_DB_STORE_RESULT_5, + SPD_MID_DB_STORE_RESULT_FOR_REUSE_CURSOR_1, + SPD_MID_DB_UDF_COPY_TABLES_1, + SPD_MID_DB_UDF_PING_TABLE_1, + SPD_MID_DB_UDF_PING_TABLE_2, + SPD_MID_DB_UDF_PING_TABLE_APPEND_MON_NEXT_1, + SPD_MID_DB_UDF_PING_TABLE_APPEND_MON_NEXT_2, + SPD_MID_DB_UDF_PING_TABLE_MON_NEXT_1, + SPD_MID_DIRECT_SQL_BODY_1, + SPD_MID_DIRECT_SQL_INIT_BODY_1, + SPD_MID_DISCOVER_TABLE_STRUCTURE_1, + SPD_MID_FIELDS_CREATE_CONN_HOLDER_1, + SPD_MID_FIELDS_CREATE_LINK_IDX_CHAIN_1, + SPD_MID_FIELDS_CREATE_LINK_IDX_HOLDER_1, + SPD_MID_GET_INIT_ERROR_TABLE_1, + SPD_MID_GET_LGTM_TBLHND_SHARE_1, + SPD_MID_GET_PING_TABLE_MON_1, + SPD_MID_GET_PING_TABLE_TGT_1, + SPD_MID_GET_PT_SHARE_1, + SPD_MID_GET_PT_SHARE_2, + SPD_MID_GET_SHARE_1, + SPD_MID_GET_SHARE_2, + SPD_MID_GET_TRX_1, + SPD_MID_GET_TRX_10, + SPD_MID_GET_TRX_2, + SPD_MID_GET_TRX_3, + SPD_MID_GET_TRX_4, + SPD_MID_GET_TRX_5, + SPD_MID_GET_TRX_6, + SPD_MID_GET_TRX_7, + SPD_MID_GET_TRX_8, + SPD_MID_GET_TRX_9, + SPD_MID_HANDLERSOCKET_HANDLER_INIT_1, + SPD_MID_HANDLERSOCKET_HANDLER_INIT_2, + SPD_MID_HANDLERSOCKET_HANDLER_SPIDER_HANDLERSOCKET_HANDLER_1, + SPD_MID_HANDLERSOCKET_SHARE_CREATE_COLUMN_NAME_STR_1, + SPD_MID_HANDLERSOCKET_SHARE_CREATE_TABLE_NAMES_STR_1, + SPD_MID_HANDLERSOCKET_SHARE_CREATE_TABLE_NAMES_STR_2, + SPD_MID_HANDLERSOCKET_SHARE_CREATE_TABLE_NAMES_STR_3, + SPD_MID_HANDLERSOCKET_SHARE_INIT_1, + SPD_MID_HANDLERSOCKET_SHARE_SPIDER_HANDLERSOCKET_SHARE_1, + SPD_MID_HA_SPIDER_COND_PUSH_1, + SPD_MID_HA_SPIDER_CREATE_1, + SPD_MID_HA_SPIDER_CREATE_2, + SPD_MID_HA_SPIDER_CREATE_BULK_ACCESS_LINK_1, + SPD_MID_HA_SPIDER_FT_INIT_EXT_1, + SPD_MID_HA_SPIDER_HA_SPIDER_1, + SPD_MID_HA_SPIDER_HA_SPIDER_2, + SPD_MID_HA_SPIDER_INFO_PUSH_1, + SPD_MID_HA_SPIDER_MULTI_RANGE_READ_NEXT_FIRST_1, + SPD_MID_HA_SPIDER_MULTI_RANGE_READ_NEXT_FIRST_2, + SPD_MID_HA_SPIDER_MULTI_RANGE_READ_NEXT_FIRST_3, + SPD_MID_HA_SPIDER_OPEN_1, + SPD_MID_HA_SPIDER_OPEN_2, + SPD_MID_HA_SPIDER_OPEN_3, + SPD_MID_HA_SPIDER_OPEN_4, + SPD_MID_HA_SPIDER_OPEN_5, + SPD_MID_HA_SPIDER_OPEN_6, + SPD_MID_HA_SPIDER_OPEN_7, + SPD_MID_INCREASE_LONGLONG_LIST_1, + SPD_MID_INCREASE_LONG_LIST_1, + SPD_MID_INCREASE_NULL_STRING_LIST_1, + SPD_MID_INCREASE_STRING_LIST_1, + SPD_MID_MBASE_COPY_TABLE_INIT_1, + SPD_MID_MBASE_HANDLER_APPEND_KEY_COLUMN_TYPES_1, + SPD_MID_MBASE_HANDLER_APPEND_MATCH_AGAINST_1, + SPD_MID_MBASE_HANDLER_APPEND_TMP_TABLE_AND_SQL_FOR_BKA_1, + SPD_MID_MBASE_HANDLER_APPEND_UNION_TABLE_AND_SQL_FOR_BKA_1, + SPD_MID_MBASE_HANDLER_INIT_1, + SPD_MID_MBASE_HANDLER_INIT_2, + SPD_MID_MBASE_HANDLER_INIT_3, + SPD_MID_MBASE_HANDLER_INIT_4, + SPD_MID_MBASE_HANDLER_INIT_5, + SPD_MID_MBASE_HANDLER_INIT_6, + SPD_MID_MBASE_HANDLER_INIT_7, + SPD_MID_MBASE_HANDLER_INIT_8, + SPD_MID_MBASE_HANDLER_INIT_9, + SPD_MID_MBASE_HANDLER_INIT_UNION_TABLE_NAME_POS_1, + SPD_MID_MBASE_HANDLER_SET_SQL_FOR_EXEC_1, + SPD_MID_MBASE_HANDLER_SET_UNION_TABLE_NAME_POS_1, + SPD_MID_MBASE_HANDLER_SPIDER_MBASE_HANDLER_1, + SPD_MID_MBASE_SHARE_APPEND_SHOW_INDEX_1, + SPD_MID_MBASE_SHARE_APPEND_SHOW_INDEX_2, + SPD_MID_MBASE_SHARE_APPEND_SHOW_RECORDS_1, + SPD_MID_MBASE_SHARE_APPEND_SHOW_TABLE_STATUS_1, + SPD_MID_MBASE_SHARE_APPEND_SHOW_TABLE_STATUS_2, + SPD_MID_MBASE_SHARE_CREATE_COLUMN_NAME_STR_1, + SPD_MID_MBASE_SHARE_CREATE_TABLE_NAMES_STR_1, + SPD_MID_MBASE_SHARE_CREATE_TABLE_NAMES_STR_2, + SPD_MID_MBASE_SHARE_CREATE_TABLE_NAMES_STR_3, + SPD_MID_MBASE_SHARE_DISCOVER_TABLE_STRUCTURE_1, + SPD_MID_MBASE_SHARE_INIT_1, + SPD_MID_MBASE_SHARE_INIT_2, + SPD_MID_MBASE_SHARE_INIT_3, + SPD_MID_MBASE_SHARE_INIT_4, + SPD_MID_MBASE_SHARE_SPIDER_MBASE_SHARE_1, + SPD_MID_OPEN_ALL_TABLES_1, + SPD_MID_OPEN_SYS_TABLE_1, + SPD_MID_ORACLE_COPY_TABLE_COPY_ROWS_1, + SPD_MID_ORACLE_COPY_TABLE_COPY_ROWS_2, + SPD_MID_ORACLE_COPY_TABLE_COPY_ROWS_3, + SPD_MID_ORACLE_COPY_TABLE_COPY_ROWS_4, + SPD_MID_ORACLE_COPY_TABLE_INIT_1, + SPD_MID_ORACLE_COPY_TABLE_INIT_2, + SPD_MID_ORACLE_HANDLER_APPEND_KEY_COLUMN_TYPES_1, + SPD_MID_ORACLE_HANDLER_APPEND_MATCH_AGAINST_1, + SPD_MID_ORACLE_HANDLER_APPEND_TMP_TABLE_AND_SQL_FOR_BKA_1, + SPD_MID_ORACLE_HANDLER_APPEND_UNION_TABLE_AND_SQL_FOR_BKA_1, + SPD_MID_ORACLE_HANDLER_INIT_1, + SPD_MID_ORACLE_HANDLER_INIT_2, + SPD_MID_ORACLE_HANDLER_INIT_3, + SPD_MID_ORACLE_HANDLER_INIT_4, + SPD_MID_ORACLE_HANDLER_INIT_5, + SPD_MID_ORACLE_HANDLER_INIT_6, + SPD_MID_ORACLE_HANDLER_INIT_7, + SPD_MID_ORACLE_HANDLER_INIT_8, + SPD_MID_ORACLE_HANDLER_INIT_9, + SPD_MID_ORACLE_HANDLER_INIT_UNION_TABLE_NAME_POS_1, + SPD_MID_ORACLE_HANDLER_SET_SQL_FOR_EXEC_1, + SPD_MID_ORACLE_HANDLER_SET_UNION_TABLE_NAME_POS_1, + SPD_MID_ORACLE_HANDLER_SPIDER_ORACLE_HANDLER_1, + SPD_MID_ORACLE_SHARE_APPEND_SHOW_AUTOINC_1, + SPD_MID_ORACLE_SHARE_APPEND_SHOW_INDEX_1, + SPD_MID_ORACLE_SHARE_APPEND_SHOW_INDEX_2, + SPD_MID_ORACLE_SHARE_APPEND_SHOW_LAST_INSERT_ID_1, + SPD_MID_ORACLE_SHARE_APPEND_SHOW_LAST_INSERT_ID_2, + SPD_MID_ORACLE_SHARE_APPEND_SHOW_RECORDS_1, + SPD_MID_ORACLE_SHARE_APPEND_SHOW_TABLE_STATUS_1, + SPD_MID_ORACLE_SHARE_APPEND_SHOW_TABLE_STATUS_2, + SPD_MID_ORACLE_SHARE_CREATE_COLUMN_NAME_STR_1, + SPD_MID_ORACLE_SHARE_CREATE_TABLE_NAMES_STR_1, + SPD_MID_ORACLE_SHARE_CREATE_TABLE_NAMES_STR_2, + SPD_MID_ORACLE_SHARE_CREATE_TABLE_NAMES_STR_3, + SPD_MID_ORACLE_SHARE_INIT_1, + SPD_MID_ORACLE_SHARE_INIT_2, + SPD_MID_ORACLE_SHARE_INIT_3, + SPD_MID_ORACLE_SHARE_INIT_4, + SPD_MID_ORACLE_SHARE_SPIDER_ORACLE_SHARE_1, + SPD_MID_PARSE_CONNECT_INFO_1, + SPD_MID_PING_TABLE_BODY_1, + SPD_MID_PING_TABLE_BODY_2, + SPD_MID_PING_TABLE_INIT_BODY_1, + SPD_MID_PING_TABLE_MON_FROM_TABLE_1, + SPD_MID_RELEASE_PING_TABLE_MON_LIST_1, + SPD_MID_TRX_ANOTHER_LOCK_TABLES_1, + SPD_MID_UDF_COPY_TABLES_CREATE_TABLE_LIST_1, + SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_1, + SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_2, + SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_3, + SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_4, + SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_KEY_1, + SPD_MID_UDF_DIRECT_SQL_CREATE_TABLE_LIST_1, + SPD_MID_UDF_DIRECT_SQL_CREATE_TABLE_LIST_2, + SPD_MID_UDF_GET_COPY_TGT_TABLES_1 +}; + #define SPIDER_BACKUP_DASTATUS \ bool da_status; if (thd) da_status = thd->is_error(); else da_status = FALSE; #define SPIDER_RESTORE_DASTATUS \ @@ -324,7 +597,6 @@ typedef struct st_spider_thread volatile bool killed; volatile bool thd_wait; volatile bool first_free_wait; - volatile bool init_command; volatile int error; pthread_t thread; pthread_cond_t cond; diff --git a/storage/spider/spd_init_query.h b/storage/spider/spd_init_query.h index 19b04d50b82..04c9a47e9f2 100644 --- a/storage/spider/spd_init_query.h +++ b/storage/spider/spd_init_query.h @@ -20,6 +20,9 @@ */ static LEX_STRING spider_init_queries[] = { + {C_STRING_WITH_LEN( + "SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'ORACLE', '');" + )}, {C_STRING_WITH_LEN( "create table if not exists mysql.spider_xa(" " format_id int not null default 0," @@ -197,666 +200,504 @@ static LEX_STRING spider_init_queries[] = { If tables already exist and their definition differ from the latest ones, we fix them here. */ - {C_STRING_WITH_LEN( - "drop procedure if exists mysql.spider_fix_one_table" - )}, - {C_STRING_WITH_LEN( - "drop procedure if exists mysql.spider_fix_system_tables" - )}, - {C_STRING_WITH_LEN( - "create procedure mysql.spider_fix_one_table" - " (tab_name char(255) charset utf8 collate utf8_bin," - " test_col_name char(255) charset utf8 collate utf8_bin," - " _sql text charset utf8 collate utf8_bin)" - "begin" - " set @col_exists := 0;" - " select 1 into @col_exists from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = tab_name" - " AND COLUMN_NAME = test_col_name;" - " if @col_exists = 0 then" - " select @stmt := _sql;" - " prepare sp_stmt1 from @stmt;" - " execute sp_stmt1;" - " end if;" - "end;" - )}, - {C_STRING_WITH_LEN( - "create procedure mysql.spider_fix_system_tables()" - "begin" - " select substring_index(substring_index(version(), '-', 2), '-', -1)" - " into @server_name;" - " if @server_name regexp '^[0-9]+$' then" - " select substring_index(substring_index(version(), '-', 3), '-', -1)" - " into @server_name;" - " end if;" - " select substring_index(version(), '.', 1)" - " into @server_major_version;" - " select substring_index(substring_index(version(), '.', 2), '.', -1)" - " into @server_minor_version;" /* Fix for 0.5 */ - " call mysql.spider_fix_one_table('spider_tables', 'server'," - " 'alter table mysql.spider_tables" - " add server char(64) default null," - " add scheme char(64) default null," - " add host char(64) default null," - " add port char(5) default null," - " add socket char(64) default null," - " add username char(64) default null," - " add password char(64) default null," - " add tgt_db_name char(64) default null," - " add tgt_table_name char(64) default null');" + {C_STRING_WITH_LEN( + "alter table mysql.spider_tables" + " add if not exists server char(64) default null," + " add if not exists scheme char(64) default null," + " add if not exists host char(64) default null," + " add if not exists port char(5) default null," + " add if not exists socket char(64) default null," + " add if not exists username char(64) default null," + " add if not exists password char(64) default null," + " add if not exists tgt_db_name char(64) default null," + " add if not exists tgt_table_name char(64) default null," + " algorithm=copy, lock=shared;" + )}, /* Fix for version 0.17 */ - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_xa'" - " AND COLUMN_NAME = 'data';" - " if @col_type != 'binary(128)' then" - " alter table mysql.spider_xa" - " modify data binary(128) not null default '';" - " end if;" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_xa_member'" - " AND COLUMN_NAME = 'data';" - " if @col_type != 'binary(128)' then" - " alter table mysql.spider_xa_member" - " modify data binary(128) not null default '';" - " end if;" + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_xa'" + " AND COLUMN_NAME = 'data';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'binary(128)' then" + " alter table mysql.spider_xa" + " modify data binary(128) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_xa_member'" + " AND COLUMN_NAME = 'data';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'binary(128)' then" + " alter table mysql.spider_xa_member" + " modify data binary(128) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, /* Fix for version 2.7 */ - " call mysql.spider_fix_one_table('spider_tables', 'link_id'," - " 'alter table mysql.spider_tables" - " add column link_id int not null default 0 after table_name," - " drop primary key," - " add primary key (db_name, table_name, link_id)');" + {C_STRING_WITH_LEN( + "alter table mysql.spider_tables" + " add column if not exists link_id int not null default 0 after table_name," + " drop primary key," + " add primary key (db_name, table_name, link_id)," + " algorithm=copy, lock=shared;" + )}, /* Fix for version 2.8 */ - " call mysql.spider_fix_one_table('spider_tables', 'link_status'," - " 'alter table mysql.spider_tables" - " add column link_status tinyint not null default 1');" + {C_STRING_WITH_LEN( + "alter table mysql.spider_tables" + " add column if not exists link_status tinyint not null default 1," + " algorithm=copy, lock=shared;" + )}, /* Fix for version 2.10 */ - " call mysql.spider_fix_one_table('spider_xa_member', 'ssl_ca'," - " 'alter table mysql.spider_xa_member" - " add column ssl_ca char(64) default null after password," - " add column ssl_capath char(64) default null after ssl_ca," - " add column ssl_cert char(64) default null after ssl_capath," - " add column ssl_cipher char(64) default null after ssl_cert," - " add column ssl_key char(64) default null after ssl_cipher," - " add column ssl_verify_server_cert tinyint not null default 0" - " after ssl_key," - " add column default_file char(64) default null" - " after ssl_verify_server_cert," - " add column default_group char(64) default null after default_file');" - " call mysql.spider_fix_one_table('spider_tables', 'ssl_ca'," - " 'alter table mysql.spider_tables" - " add column ssl_ca char(64) default null after password," - " add column ssl_capath char(64) default null after ssl_ca," - " add column ssl_cert char(64) default null after ssl_capath," - " add column ssl_cipher char(64) default null after ssl_cert," - " add column ssl_key char(64) default null after ssl_cipher," - " add column ssl_verify_server_cert tinyint not null default 0" - " after ssl_key," - " add column default_file char(64) default null" - " after ssl_verify_server_cert," - " add column default_group char(64) default null after default_file');" - " call mysql.spider_fix_one_table('spider_link_mon_servers', 'ssl_ca'," - " 'alter table mysql.spider_link_mon_servers" - " add column ssl_ca char(64) default null after password," - " add column ssl_capath char(64) default null after ssl_ca," - " add column ssl_cert char(64) default null after ssl_capath," - " add column ssl_cipher char(64) default null after ssl_cert," - " add column ssl_key char(64) default null after ssl_cipher," - " add column ssl_verify_server_cert tinyint not null default 0" - " after ssl_key," - " add column default_file char(64) default null" - " after ssl_verify_server_cert," - " add column default_group char(64) default null after default_file');" + {C_STRING_WITH_LEN( + "alter table mysql.spider_xa_member" + " add column if not exists ssl_ca char(64) default null after password," + " add column if not exists ssl_capath char(64) default null after ssl_ca," + " add column if not exists ssl_cert char(64) default null after ssl_capath," + " add column if not exists ssl_cipher char(64) default null after ssl_cert," + " add column if not exists ssl_key char(64) default null after ssl_cipher," + " add column if not exists ssl_verify_server_cert tinyint not null default 0" + " after ssl_key," + " add column if not exists default_file char(64) default null" + " after ssl_verify_server_cert," + " add column if not exists default_group char(64) default null after default_file," + " algorithm=copy, lock=shared;" + )}, + {C_STRING_WITH_LEN( + "alter table mysql.spider_tables" + " add column if not exists ssl_ca char(64) default null after password," + " add column if not exists ssl_capath char(64) default null after ssl_ca," + " add column if not exists ssl_cert char(64) default null after ssl_capath," + " add column if not exists ssl_cipher char(64) default null after ssl_cert," + " add column if not exists ssl_key char(64) default null after ssl_cipher," + " add column if not exists ssl_verify_server_cert tinyint not null default 0" + " after ssl_key," + " add column if not exists default_file char(64) default null" + " after ssl_verify_server_cert," + " add column if not exists default_group char(64) default null after default_file," + " algorithm=copy, lock=shared;" + )}, + {C_STRING_WITH_LEN( + "alter table mysql.spider_link_mon_servers" + " add column if not exists ssl_ca char(64) default null after password," + " add column if not exists ssl_capath char(64) default null after ssl_ca," + " add column if not exists ssl_cert char(64) default null after ssl_capath," + " add column if not exists ssl_cipher char(64) default null after ssl_cert," + " add column if not exists ssl_key char(64) default null after ssl_cipher," + " add column if not exists ssl_verify_server_cert tinyint not null default 0" + " after ssl_key," + " add column if not exists default_file char(64) default null" + " after ssl_verify_server_cert," + " add column if not exists default_group char(64) default null after default_file," + " algorithm=copy, lock=shared;" + )}, /* Fix for version 2.28 */ - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_link_mon_servers'" - " AND COLUMN_NAME = 'sid';" - " if @col_type != 'int(10) unsigned' then" - " alter table mysql.spider_link_mon_servers" - " modify sid int unsigned not null default 0;" - " end if;" + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_link_mon_servers'" + " AND COLUMN_NAME = 'sid';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'int(10) unsigned' then" + " alter table mysql.spider_link_mon_servers" + " modify sid int unsigned not null default 0," + " algorithm=copy, lock=shared;" + "end if;" + )}, /* Fix for version 3.1 */ - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_xa_member'" - " AND COLUMN_NAME = 'socket';" - " if @col_type = 'char(64)' then" - " alter table mysql.spider_xa_member" - " drop primary key," - " add index idx1 (data, format_id, gtrid_length, host)," - " modify socket text not null," - " modify ssl_ca text," - " modify ssl_capath text," - " modify ssl_cert text," - " modify ssl_key text," - " modify default_file text;" - " end if;" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_tables'" - " AND COLUMN_NAME = 'socket';" - " if @col_type = 'char(64)' then" - " alter table mysql.spider_tables" - " modify socket text," - " modify ssl_ca text," - " modify ssl_capath text," - " modify ssl_cert text," - " modify ssl_key text," - " modify default_file text;" - " end if;" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_link_mon_servers'" - " AND COLUMN_NAME = 'socket';" - " if @col_type = 'char(64)' then" - " alter table mysql.spider_link_mon_servers" - " modify socket text," - " modify ssl_ca text," - " modify ssl_capath text," - " modify ssl_cert text," - " modify ssl_key text," - " modify default_file text;" - " end if;" + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_xa_member'" + " AND COLUMN_NAME = 'socket';" + )}, + {C_STRING_WITH_LEN( + "if @col_type = 'char(64)' then" + " alter table mysql.spider_xa_member" + " drop primary key," + " add index idx1 (data, format_id, gtrid_length, host)," + " modify socket text not null," + " modify ssl_ca text," + " modify ssl_capath text," + " modify ssl_cert text," + " modify ssl_key text," + " modify default_file text," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_tables'" + " AND COLUMN_NAME = 'socket';" + )}, + {C_STRING_WITH_LEN( + "if @col_type = 'char(64)' then" + " alter table mysql.spider_tables" + " modify socket text," + " modify ssl_ca text," + " modify ssl_capath text," + " modify ssl_cert text," + " modify ssl_key text," + " modify default_file text," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_link_mon_servers'" + " AND COLUMN_NAME = 'socket';" + )}, + {C_STRING_WITH_LEN( + "if @col_type = 'char(64)' then" + " alter table mysql.spider_link_mon_servers" + " modify socket text," + " modify ssl_ca text," + " modify ssl_capath text," + " modify ssl_cert text," + " modify ssl_key text," + " modify default_file text," + " algorithm=copy, lock=shared;" + "end if;" + )}, /* Fix for version 3.3.0 */ - " call mysql.spider_fix_one_table('spider_tables'," - " 'monitoring_binlog_pos_at_failing'," - " 'alter table mysql.spider_tables" - " add monitoring_binlog_pos_at_failing tinyint not null default 0" - " after ssl_verify_server_cert');" + {C_STRING_WITH_LEN( + "alter table mysql.spider_tables" + " add if not exists monitoring_binlog_pos_at_failing tinyint not null default 0" + " after ssl_verify_server_cert," + " algorithm=copy, lock=shared;" + )}, /* Fix for version 3.3.6 */ - " call mysql.spider_fix_one_table('spider_tables', 'block_status'," - " 'alter table mysql.spider_tables" - " add column block_status tinyint not null default 0" - " after link_status');" - " call mysql.spider_fix_one_table('spider_tables', 'static_link_id'," - " 'alter table mysql.spider_tables" - " add column static_link_id char(64) default null after block_status," - " add unique index uidx1 (db_name, table_name, static_link_id)');" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_link_mon_servers'" - " AND COLUMN_NAME = 'link_id';" - " if @col_type != 'char(64)' then" - " alter table mysql.spider_link_mon_servers" - " modify link_id char(64) not null default '';" - " end if;" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_link_failed_log'" - " AND COLUMN_NAME = 'link_id';" - " if @col_type != 'char(64)' then" - " alter table mysql.spider_link_failed_log" - " modify link_id char(64) not null default '';" - " end if;" + {C_STRING_WITH_LEN( + "alter table mysql.spider_tables" + " add column if not exists block_status tinyint not null default 0" + " after link_status," + " algorithm=copy, lock=shared;" + )}, + {C_STRING_WITH_LEN( + "alter table mysql.spider_tables" + " add column if not exists static_link_id char(64) default null after block_status," + " add unique index if not exists uidx1 (db_name, table_name, static_link_id)," + " algorithm=copy, lock=shared;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_link_mon_servers'" + " AND COLUMN_NAME = 'link_id';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'char(64)' then" + " alter table mysql.spider_link_mon_servers" + " modify link_id char(64) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_link_failed_log'" + " AND COLUMN_NAME = 'link_id';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'char(64)' then" + " alter table mysql.spider_link_failed_log" + " modify link_id char(64) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, /* Fix for version 3.3.10 */ - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_tables'" - " AND COLUMN_NAME = 'table_name';" - " if @col_type != 'char(199)' then" - " alter table mysql.spider_tables" - " modify table_name char(199) not null default '';" - " end if;" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_link_mon_servers'" - " AND COLUMN_NAME = 'table_name';" - " if @col_type != 'char(199)' then" - " alter table mysql.spider_link_mon_servers" - " modify table_name char(199) not null default '';" - " end if;" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_link_failed_log'" - " AND COLUMN_NAME = 'table_name';" - " if @col_type != 'char(199)' then" - " alter table mysql.spider_link_failed_log" - " modify table_name char(199) not null default '';" - " end if;" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_table_position_for_recovery'" - " AND COLUMN_NAME = 'table_name';" - " if @col_type != 'char(199)' then" - " alter table mysql.spider_table_position_for_recovery" - " modify table_name char(199) not null default '';" - " end if;" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_table_sts'" - " AND COLUMN_NAME = 'table_name';" - " if @col_type != 'char(199)' then" - " alter table mysql.spider_table_sts" - " modify table_name char(199) not null default '';" - " end if;" - " select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_table_crd'" - " AND COLUMN_NAME = 'table_name';" - " if @col_type != 'char(199)' then" - " alter table mysql.spider_table_crd" - " modify table_name char(199) not null default '';" - " end if;" + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_tables'" + " AND COLUMN_NAME = 'table_name';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'char(199)' then" + " alter table mysql.spider_tables" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_link_mon_servers'" + " AND COLUMN_NAME = 'table_name';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'char(199)' then" + " alter table mysql.spider_link_mon_servers" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_link_failed_log'" + " AND COLUMN_NAME = 'table_name';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'char(199)' then" + " alter table mysql.spider_link_failed_log" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_table_position_for_recovery'" + " AND COLUMN_NAME = 'table_name';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'char(199)' then" + " alter table mysql.spider_table_position_for_recovery" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_table_sts'" + " AND COLUMN_NAME = 'table_name';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'char(199)' then" + " alter table mysql.spider_table_sts" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select COLUMN_TYPE INTO @col_type from INFORMATION_SCHEMA.COLUMNS" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_table_crd'" + " AND COLUMN_NAME = 'table_name';" + )}, + {C_STRING_WITH_LEN( + "if @col_type != 'char(199)' then" + " alter table mysql.spider_table_crd" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" + "end if;" + )}, /* Fix for version 3.3.15 */ - " call mysql.spider_fix_one_table('spider_table_sts', 'checksum'," - " 'alter table mysql.spider_table_sts" - " add column checksum bigint unsigned default null after update_time');" + {C_STRING_WITH_LEN( + "alter table mysql.spider_table_sts" + " add column if not exists checksum bigint unsigned default null after update_time," + " algorithm=copy, lock=shared;" + )}, /* Fix for MariaDB 10.4: Crash-Safe system tables */ - " if @server_name = 'MariaDB' and" - " (" - " @server_major_version > 10 or" - " (" - " @server_major_version = 10 and" - " @server_minor_version >= 4" - " )" - " )" - " then" - " select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_link_failed_log';" - " if @engine_name != 'Aria' then" - " alter table mysql.spider_link_failed_log" - " engine=Aria transactional=1;" - " end if;" - " select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_link_mon_servers';" - " if @engine_name != 'Aria' then" - " alter table mysql.spider_link_mon_servers" - " engine=Aria transactional=1;" - " end if;" - " select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_table_crd';" - " if @engine_name != 'Aria' then" - " alter table mysql.spider_table_crd" - " engine=Aria transactional=1;" - " end if;" - " select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_table_position_for_recovery';" - " if @engine_name != 'Aria' then" - " alter table mysql.spider_table_position_for_recovery" - " engine=Aria transactional=1;" - " end if;" - " select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_table_sts';" - " if @engine_name != 'Aria' then" - " alter table mysql.spider_table_sts" - " engine=Aria transactional=1;" - " end if;" - " select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_tables';" - " if @engine_name != 'Aria' then" - " alter table mysql.spider_tables" - " engine=Aria transactional=1;" - " end if;" - " select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_xa';" - " if @engine_name != 'Aria' then" - " alter table mysql.spider_xa" - " engine=Aria transactional=1;" - " end if;" - " select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_xa_failed_log';" - " if @engine_name != 'Aria' then" - " alter table mysql.spider_xa_failed_log" - " engine=Aria transactional=1;" - " end if;" - " select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" - " where TABLE_SCHEMA = 'mysql'" - " AND TABLE_NAME = 'spider_xa_member';" - " if @engine_name != 'Aria' then" - " alter table mysql.spider_xa_member" - " engine=Aria transactional=1;" - " end if;" - " end if;" - " if @server_name = 'MariaDB' and" - " (" - " @server_major_version > 10 or" - " (" - " @server_major_version = 10 and" - " @server_minor_version >= 7" - " )" - " )" - " then" - " /* table for ddl pushdown */" - " create table if not exists mysql.spider_rewrite_tables(" - " table_id bigint unsigned not null auto_increment," - " db_name char(64) not null default ''," - " table_name char(64) not null default ''," - " primary key (table_id)," - " unique uk1(db_name, table_name)" - " ) engine=Aria transactional=1 default charset=utf8 collate=utf8_bin;" - " create table if not exists mysql.spider_rewrite_table_tables(" - " table_id bigint unsigned not null," - " partition_id bigint unsigned not null auto_increment," - " partition_method varchar(18) default ''," - " partition_expression varchar(64) default ''," - " subpartition_method varchar(12) default ''," - " subpartition_expression varchar(64) default ''," - " connection_str text not null default ''," - " comment_str text not null default ''," - " primary key (table_id, partition_id)," - " unique uk1(table_id, partition_method, partition_expression," - " subpartition_method, subpartition_expression)" - " ) engine=Aria transactional=1 default charset=utf8 collate=utf8_bin;" - " create table if not exists mysql.spider_rewrite_table_partitions(" - " table_id bigint unsigned not null," - " partition_id bigint unsigned not null," - " partition_ordinal_position bigint unsigned not null auto_increment," - " partition_name varchar(64) not null default ''," - " partition_description varchar(64) not null default ''," - " connection_str text not null default ''," - " comment_str text not null default ''," - " primary key (table_id, partition_id, partition_ordinal_position)," - " unique key uk1 (table_id, partition_id, partition_name)" - " ) engine=Aria transactional=1 default charset=utf8 collate=utf8_bin;" - " create table if not exists mysql.spider_rewrite_table_subpartitions(" - " table_id bigint unsigned not null," - " partition_id bigint unsigned not null," - " partition_ordinal_position bigint unsigned not null," - " subpartition_ordinal_position bigint unsigned not null" - " auto_increment," - " subpartition_name varchar(64) not null default ''," - " subpartition_description varchar(64) not null default ''," - " connection_str text not null default ''," - " comment_str text not null default ''," - " primary key (table_id, partition_id, partition_ordinal_position," - " subpartition_ordinal_position)," - " unique key uk1 (table_id, partition_id, partition_ordinal_position," - " subpartition_name)" - " ) engine=Aria transactional=1 default charset=utf8 collate=utf8_bin;" - " create table if not exists mysql.spider_rewritten_tables(" - " db_name char(64) not null," - " table_name char(64) not null," - " table_id bigint unsigned not null," - " partition_id bigint unsigned not null," - " primary key (db_name, table_name, table_id, partition_id)" - " ) engine=Aria transactional=1 default charset=utf8 collate=utf8_bin;" - " end if;" + {C_STRING_WITH_LEN( + "select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_link_failed_log';" + )}, + {C_STRING_WITH_LEN( + "if @engine_name != 'Aria' then" + " alter table mysql.spider_link_failed_log" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_link_mon_servers';" + )}, + {C_STRING_WITH_LEN( + "if @engine_name != 'Aria' then" + " alter table mysql.spider_link_mon_servers" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_table_crd';" + )}, + {C_STRING_WITH_LEN( + "if @engine_name != 'Aria' then" + " alter table mysql.spider_table_crd" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_table_position_for_recovery';" + )}, + {C_STRING_WITH_LEN( + "if @engine_name != 'Aria' then" + " alter table mysql.spider_table_position_for_recovery" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_table_sts';" + )}, + {C_STRING_WITH_LEN( + "if @engine_name != 'Aria' then" + " alter table mysql.spider_table_sts" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_tables';" + )}, + {C_STRING_WITH_LEN( + "if @engine_name != 'Aria' then" + " alter table mysql.spider_tables" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_xa';" + )}, + {C_STRING_WITH_LEN( + "if @engine_name != 'Aria' then" + " alter table mysql.spider_xa" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_xa_failed_log';" + )}, + {C_STRING_WITH_LEN( + "if @engine_name != 'Aria' then" + " alter table mysql.spider_xa_failed_log" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" + "end if;" + )}, + {C_STRING_WITH_LEN( + "select ENGINE INTO @engine_name from INFORMATION_SCHEMA.TABLES" + " where TABLE_SCHEMA = 'mysql'" + " AND TABLE_NAME = 'spider_xa_member';" + )}, + {C_STRING_WITH_LEN( + "if @engine_name != 'Aria' then" + " alter table mysql.spider_xa_member" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" + "end if;" + )}, /* Fix for version 3.4 */ - " call mysql.spider_fix_one_table('spider_link_mon_servers', 'dsn'," - " 'alter table mysql.spider_link_mon_servers" - " add column dsn char(64) default null after default_group');" - " call mysql.spider_fix_one_table('spider_tables', 'dsn'," - " 'alter table mysql.spider_tables" - " add column dsn char(64) default null after default_group');" - " call mysql.spider_fix_one_table('spider_xa_failed_log', 'dsn'," - " 'alter table mysql.spider_xa_failed_log" - " add column dsn char(64) default null after default_group');" - " call mysql.spider_fix_one_table('spider_xa_member', 'dsn'," - " 'alter table mysql.spider_xa_member" - " add column dsn char(64) default null after default_group');" - " call mysql.spider_fix_one_table('spider_link_mon_servers', 'filedsn'," - " 'alter table mysql.spider_link_mon_servers" - " add column filedsn text default null after dsn');" - " call mysql.spider_fix_one_table('spider_tables', 'filedsn'," - " 'alter table mysql.spider_tables" - " add column filedsn text default null after dsn');" - " call mysql.spider_fix_one_table('spider_xa_failed_log', 'filedsn'," - " 'alter table mysql.spider_xa_failed_log" - " add column filedsn text default null after dsn');" - " call mysql.spider_fix_one_table('spider_xa_member', 'filedsn'," - " 'alter table mysql.spider_xa_member" - " add column filedsn text default null after dsn');" - " call mysql.spider_fix_one_table('spider_link_mon_servers', 'driver'," - " 'alter table mysql.spider_link_mon_servers" - " add column driver char(64) default null after filedsn');" - " call mysql.spider_fix_one_table('spider_tables', 'driver'," - " 'alter table mysql.spider_tables" - " add column driver char(64) default null after filedsn');" - " call mysql.spider_fix_one_table('spider_xa_failed_log', 'driver'," - " 'alter table mysql.spider_xa_failed_log" - " add column driver char(64) default null after filedsn');" - " call mysql.spider_fix_one_table('spider_xa_member', 'driver'," - " 'alter table mysql.spider_xa_member" - " add column driver char(64) default null after filedsn');" - "end;" + {C_STRING_WITH_LEN( + "alter table mysql.spider_link_mon_servers" + " add column if not exists dsn char(64) default null after default_group;" )}, {C_STRING_WITH_LEN( - "call mysql.spider_fix_system_tables" + "alter table mysql.spider_tables" + " add column if not exists dsn char(64) default null after default_group;" )}, {C_STRING_WITH_LEN( - "drop procedure mysql.spider_fix_one_table" + "alter table mysql.spider_xa_failed_log" + " add column if not exists dsn char(64) default null after default_group;" )}, {C_STRING_WITH_LEN( - "drop procedure mysql.spider_fix_system_tables" - )}, -/* - Install a plugin and UDFs -*/ - {C_STRING_WITH_LEN( - "drop procedure if exists mysql.spider_plugin_installer" + "alter table mysql.spider_xa_member" + " add column if not exists dsn char(64) default null after default_group;" )}, {C_STRING_WITH_LEN( - "create procedure mysql.spider_plugin_installer()" - "begin" - " set @win_plugin := IF(@@version_compile_os like 'Win%', 1, 0);" -/* - Install spider plugin -*/ -/* - " set @have_spider_i_s_plugin := 0;" - " select @have_spider_i_s_plugin := 1 from INFORMATION_SCHEMA.plugins" - " where PLUGIN_NAME = 'SPIDER';" - " set @have_spider_plugin := 0;" - " select @have_spider_plugin := 1 from mysql.plugin" - " where name = 'spider';" - " if @have_spider_i_s_plugin = 0 then" - " if @have_spider_plugin = 1 then" - " / *" - " spider plugin is present in mysql.plugin but not in" - " information_schema.plugins. Remove spider plugin entry" - " in mysql.plugin first." - " * /" - " delete from mysql.plugin where name = 'spider';" - " end if;" - " if @win_plugin = 0 then " - " install plugin spider soname 'ha_spider.so';" - " else" - " install plugin spider soname 'ha_spider.dll';" - " end if;" - " end if;" -*/ -/* - Install spider_alloc_mem plugin -*/ - " set @have_spider_i_s_alloc_mem_plugin := 0;" - " select @have_spider_i_s_alloc_mem_plugin := 1" - " from INFORMATION_SCHEMA.plugins" - " where PLUGIN_NAME = 'SPIDER_ALLOC_MEM';" - " set @have_spider_alloc_mem_plugin := 0;" - " select @have_spider_alloc_mem_plugin := 1 from mysql.plugin" - " where name = 'spider_alloc_mem';" - " if @have_spider_i_s_alloc_mem_plugin = 0 then" - " if @have_spider_alloc_mem_plugin = 1 then" - " /*" - " spider_alloc_mem plugin is present in mysql.plugin but not in" - " information_schema.plugins. Remove spider_alloc_mem plugin entry" - " in mysql.plugin first." - " */" - " delete from mysql.plugin where name = 'spider_alloc_mem';" - " end if;" - " if @win_plugin = 0 then " - " install plugin spider_alloc_mem soname 'ha_spider.so';" - " else" - " install plugin spider_alloc_mem soname 'ha_spider.dll';" - " end if;" - " end if;" -/* - Install spider_wrapper_protocols plugin -*/ - " set @have_spider_i_s_wrapper_protocols_plugin := 0;" - " select @have_spider_i_s_wrapper_protocols_plugin := 1" - " from INFORMATION_SCHEMA.plugins" - " where PLUGIN_NAME = 'SPIDER_WRAPPER_PROTOCOLS';" - " set @have_spider_wrapper_protocols_plugin := 0;" - " select @have_spider_wrapper_protocols_plugin := 1 from mysql.plugin" - " where name = 'spider_wrapper_protocols';" - " if @have_spider_i_s_wrapper_protocols_plugin = 0 then" - " if @have_spider_wrapper_protocols_plugin = 1 then" - " /*" - " spider_wrapper_protocols plugin is present in mysql.plugin but not in" - " information_schema.plugins. Remove spider_wrapper_protocols plugin entry" - " in mysql.plugin first." - " */" - " delete from mysql.plugin where name = 'spider_wrapper_protocols';" - " end if;" - " if @win_plugin = 0 then " - " install plugin spider_wrapper_protocols soname 'ha_spider.so';" - " else" - " install plugin spider_wrapper_protocols soname 'ha_spider.dll';" - " end if;" - " end if;" - " set @have_spider_direct_sql_udf := 0;" - " select @have_spider_direct_sql_udf := 1 from mysql.func" - " where name = 'spider_direct_sql';" - " if @have_spider_direct_sql_udf = 0 then" - " if @win_plugin = 0 then " - " create function spider_direct_sql returns int" - " soname 'ha_spider.so';" - " else" - " create function spider_direct_sql returns int" - " soname 'ha_spider.dll';" - " end if;" - " end if;" - " set @have_spider_bg_direct_sql_udf := 0;" - " select @have_spider_bg_direct_sql_udf := 1 from mysql.func" - " where name = 'spider_bg_direct_sql';" - " if @have_spider_bg_direct_sql_udf = 0 then" - " if @win_plugin = 0 then " - " create aggregate function spider_bg_direct_sql returns int" - " soname 'ha_spider.so';" - " else" - " create aggregate function spider_bg_direct_sql returns int" - " soname 'ha_spider.dll';" - " end if;" - " end if;" - " set @have_spider_ping_table_udf := 0;" - " select @have_spider_ping_table_udf := 1 from mysql.func" - " where name = 'spider_ping_table';" - " if @have_spider_ping_table_udf = 0 then" - " if @win_plugin = 0 then " - " create function spider_ping_table returns int" - " soname 'ha_spider.so';" - " else" - " create function spider_ping_table returns int" - " soname 'ha_spider.dll';" - " end if;" - " end if;" - " set @have_spider_copy_tables_udf := 0;" - " select @have_spider_copy_tables_udf := 1 from mysql.func" - " where name = 'spider_copy_tables';" - " if @have_spider_copy_tables_udf = 0 then" - " if @win_plugin = 0 then " - " create function spider_copy_tables returns int" - " soname 'ha_spider.so';" - " else" - " create function spider_copy_tables returns int" - " soname 'ha_spider.dll';" - " end if;" - " end if;" - " set @have_spider_flush_table_mon_cache_udf := 0;" - " select @have_spider_flush_table_mon_cache_udf := 1 from mysql.func" - " where name = 'spider_flush_table_mon_cache';" - " if @have_spider_flush_table_mon_cache_udf = 0 then" - " if @win_plugin = 0 then " - " create function spider_flush_table_mon_cache returns int" - " soname 'ha_spider.so';" - " else" - " create function spider_flush_table_mon_cache returns int" - " soname 'ha_spider.dll';" - " end if;" - " end if;" - " if @server_name = 'MariaDB' and" - " (" - " @server_major_version > 10 or" - " (" - " @server_major_version = 10 and" - " @server_minor_version >= 7" - " )" - " )" - " then" -/* - Install spider_rewrite plugin -*/ - " set @have_spider_i_s_rewrite_plugin := 0;" - " select @have_spider_i_s_rewrite_plugin := 1" - " from INFORMATION_SCHEMA.plugins" - " where PLUGIN_NAME = 'SPIDER_REWRITE';" - " set @have_spider_rewrite_plugin := 0;" - " select @have_spider_rewrite_plugin := 1 from mysql.plugin" - " where name = 'spider_rewrite';" - " if @have_spider_i_s_rewrite_plugin = 0 then" - " if @have_spider_rewrite_plugin = 1 then" - " /*" - " spider_rewrite plugin is present in mysql.plugin but not in" - " information_schema.plugins. Remove spider_rewrite plugin entry" - " in mysql.plugin first." - " */" - " delete from mysql.plugin where name = 'spider_rewrite';" - " end if;" - " if @win_plugin = 0 then " - " install plugin spider_rewrite soname 'ha_spider.so';" - " else" - " install plugin spider_rewrite soname 'ha_spider.dll';" - " end if;" - " end if;" - " set @have_spider_flush_rewrite_cache_udf := 0;" - " select @have_spider_flush_rewrite_cache_udf := 1 from mysql.func" - " where name = 'spider_flush_rewrite_cache';" - " if @have_spider_flush_rewrite_cache_udf = 0 then" - " if @win_plugin = 0 then " - " create function spider_flush_rewrite_cache returns int" - " soname 'ha_spider.so';" - " else" - " create function spider_flush_rewrite_cache returns int" - " soname 'ha_spider.dll';" - " end if;" - " end if;" - " end if;" - "end;" + "set @win_plugin := IF(@@version_compile_os like 'Win%', 1, 0);" )}, + /* Install UDFs. If udf is not initialised, then install by + inserting into mysql.func */ {C_STRING_WITH_LEN( - "call mysql.spider_plugin_installer" - )}, - {C_STRING_WITH_LEN( - "drop procedure mysql.spider_plugin_installer" - )}, - {C_STRING_WITH_LEN("")} + "if @win_plugin = 0 then" + " begin not atomic" + " declare exit handler for 1041, 1123" + " replace into mysql.func values" + " ('spider_direct_sql', 2, 'ha_spider.so', 'function')," + " ('spider_bg_direct_sql', 2, 'ha_spider.so', 'aggregate')," + " ('spider_ping_table', 2, 'ha_spider.so', 'function')," + " ('spider_copy_tables', 2, 'ha_spider.so', 'function')," + " ('spider_flush_table_mon_cache', 2, 'ha_spider.so', 'function');" + " create function if not exists spider_direct_sql returns int" + " soname 'ha_spider.so';" + " create aggregate function if not exists spider_bg_direct_sql returns int" + " soname 'ha_spider.so';" + " create function if not exists spider_ping_table returns int" + " soname 'ha_spider.so';" + " create function if not exists spider_copy_tables returns int" + " soname 'ha_spider.so';" + " create function if not exists spider_flush_table_mon_cache returns int" + " soname 'ha_spider.so';" + " end;" + "else" + " begin not atomic" + " declare exit handler for 1041, 1123" + " replace into mysql.func values" + " ('spider_direct_sql', 2, 'ha_spider.dll', 'function')," + " ('spider_bg_direct_sql', 2, 'ha_spider.dll', 'aggregate')," + " ('spider_ping_table', 2, 'ha_spider.dll', 'function')," + " ('spider_copy_tables', 2, 'ha_spider.dll', 'function')," + " ('spider_flush_table_mon_cache', 2, 'ha_spider.dll', 'function');" + " create function if not exists spider_direct_sql returns int" + " soname 'ha_spider.dll';" + " create aggregate function if not exists spider_bg_direct_sql returns int" + " soname 'ha_spider.dll';" + " create function if not exists spider_ping_table returns int" + " soname 'ha_spider.dll';" + " create function if not exists spider_copy_tables returns int" + " soname 'ha_spider.dll';" + " create function if not exists spider_flush_table_mon_cache returns int" + " soname 'ha_spider.dll';" + " end;" + "end if;" + )} }; diff --git a/storage/spider/spd_param.cc b/storage/spider/spd_param.cc index 272ed53ddfc..90be2c045b9 100644 --- a/storage/spider/spd_param.cc +++ b/storage/spider/spd_param.cc @@ -2688,7 +2688,7 @@ static MYSQL_SYSVAR_UINT( "Static thread count of table sts", NULL, NULL, - 10, + 1, 1, 4294967295U, 0 @@ -2707,7 +2707,7 @@ static MYSQL_SYSVAR_UINT( "Static thread count of table crd", NULL, NULL, - 10, + 1, 1, 4294967295U, 0 diff --git a/storage/spider/spd_ping_table.cc b/storage/spider/spd_ping_table.cc index 8c2c8d2ce9e..2ec00d77b31 100644 --- a/storage/spider/spd_ping_table.cc +++ b/storage/spider/spd_ping_table.cc @@ -249,7 +249,7 @@ int spider_release_ping_table_mon_list( } spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1, system_charset_info); - conv_name_str.init_calc_mem(134); + conv_name_str.init_calc_mem(SPD_MID_RELEASE_PING_TABLE_MON_LIST_1); conv_name_str.length(0); conv_name_str.q_append(conv_name, conv_name_length); conv_name_str.q_append(link_idx_str, link_idx_str_length); @@ -363,7 +363,7 @@ create_table_mon: do { if (!(table_mon = (SPIDER_TABLE_MON *) - spider_bulk_malloc(spider_current_trx, 35, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_GET_PING_TABLE_MON_1, MYF(MY_WME | MY_ZEROFILL), &table_mon, (uint) (sizeof(SPIDER_TABLE_MON)), &tmp_share, (uint) (sizeof(SPIDER_SHARE)), &tmp_connect_info, @@ -486,7 +486,7 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); if (!(table_mon_list = (SPIDER_TABLE_MON_LIST *) - spider_bulk_malloc(spider_current_trx, 36, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_GET_PING_TABLE_TGT_1, MYF(MY_WME | MY_ZEROFILL), &table_mon_list, (uint) (sizeof(SPIDER_TABLE_MON_LIST)), &tmp_share, (uint) (sizeof(SPIDER_SHARE)), &tmp_connect_info, @@ -1083,8 +1083,8 @@ long long spider_ping_table_body( int static_link_id_length = 0; bool get_lock = FALSE, status_changed_to_ng = FALSE; DBUG_ENTER("spider_ping_table_body"); - conv_name.init_calc_mem(135); - tmp_str.init_calc_mem(247); + conv_name.init_calc_mem(SPD_MID_PING_TABLE_BODY_1); + tmp_str.init_calc_mem(SPD_MID_PING_TABLE_BODY_2); conv_name.length(0); #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002 server_id = global_system_variables.server_id; @@ -1544,7 +1544,7 @@ my_bool spider_ping_table_init_body( } if (!(mon_table_result = (SPIDER_MON_TABLE_RESULT *) - spider_malloc(spider_current_trx, 11, sizeof(SPIDER_MON_TABLE_RESULT), + spider_malloc(spider_current_trx, SPD_MID_PING_TABLE_INIT_BODY_1, sizeof(SPIDER_MON_TABLE_RESULT), MYF(MY_WME | MY_ZEROFILL))) ) { strcpy(message, "spider_ping_table() out of memory"); @@ -1687,7 +1687,7 @@ int spider_ping_table_mon_from_table( buf[conv_name_length + link_idx_str_length] = '\0'; spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1, system_charset_info); - conv_name_str.init_calc_mem(136); + conv_name_str.init_calc_mem(SPD_MID_PING_TABLE_MON_FROM_TABLE_1); conv_name_str.length(0); conv_name_str.q_append(conv_name, conv_name_length); conv_name_str.q_append(link_idx_str, link_idx_str_length + 1); diff --git a/storage/spider/spd_sys_table.cc b/storage/spider/spd_sys_table.cc index 4bd30573b1c..64b2ba079dc 100644 --- a/storage/spider/spd_sys_table.cc +++ b/storage/spider/spd_sys_table.cc @@ -301,7 +301,7 @@ TABLE *spider_open_sys_table( } else { SPIDER_reset_n_backup_open_tables_state(thd, open_tables_backup, NULL); - if (!(table = (TABLE*) spider_malloc(spider_current_trx, 12, + if (!(table = (TABLE*) spider_malloc(spider_current_trx, SPD_MID_OPEN_SYS_TABLE_1, sizeof(*table), MYF(MY_WME)))) { *error_num = HA_ERR_OUT_OF_MEM; @@ -386,38 +386,6 @@ TABLE *spider_open_sys_table( } break; } - if (!memcmp(table_name, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR, - SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN)) - { - DBUG_PRINT("info",("spider checking for SYS_TABLE_STS")); - if (table->s->fields != SPIDER_SYS_TABLE_STS_COL_CNT) - { - spider_close_sys_table(thd, table, open_tables_backup, need_lock); - table = NULL; - my_printf_error(ER_SPIDER_SYS_TABLE_VERSION_NUM, - ER_SPIDER_SYS_TABLE_VERSION_STR, MYF(0), - SPIDER_SYS_TABLE_STS_TABLE_NAME_STR); - *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM; - goto error_col_num_chk; - } - break; - } - if (!memcmp(table_name, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR, - SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN)) - { - DBUG_PRINT("info",("spider checking for SYS_TABLE_CRD")); - if (table->s->fields != SPIDER_SYS_TABLE_CRD_COL_CNT) - { - spider_close_sys_table(thd, table, open_tables_backup, need_lock); - table = NULL; - my_printf_error(ER_SPIDER_SYS_TABLE_VERSION_NUM, - ER_SPIDER_SYS_TABLE_VERSION_STR, MYF(0), - SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR); - *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM; - goto error_col_num_chk; - } - break; - } DBUG_ASSERT(0); break; case 20: @@ -439,24 +407,6 @@ TABLE *spider_open_sys_table( } DBUG_ASSERT(0); break; - case 21: - if (!memcmp(table_name, SPIDER_SYS_RW_TBLS_TABLE_NAME_STR, - SPIDER_SYS_RW_TBLS_TABLE_NAME_LEN)) - { - DBUG_PRINT("info",("spider checking for SYS_RW_TBLS")); - if (table->s->fields != SPIDER_SYS_RW_TBLS_COL_CNT) - { - spider_close_sys_table(thd, table, open_tables_backup, need_lock); - table = NULL; - my_printf_error(ER_SPIDER_SYS_TABLE_VERSION_NUM, - ER_SPIDER_SYS_TABLE_VERSION_STR, MYF(0), - SPIDER_SYS_RW_TBLS_TABLE_NAME_STR); - *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM; - goto error_col_num_chk; - } - } - DBUG_ASSERT(0); - break; case 22: if (!memcmp(table_name, SPIDER_SYS_LINK_FAILED_TABLE_NAME_STR, SPIDER_SYS_LINK_FAILED_TABLE_NAME_LEN)) @@ -493,60 +443,6 @@ TABLE *spider_open_sys_table( } break; } - if (!memcmp(table_name, SPIDER_SYS_RWN_TBLS_TABLE_NAME_STR, - SPIDER_SYS_RWN_TBLS_TABLE_NAME_LEN)) - { - DBUG_PRINT("info",("spider checking for SYS_RWN_TBLS")); - if (table->s->fields != SPIDER_SYS_RWN_TBLS_COL_CNT) - { - spider_close_sys_table(thd, table, open_tables_backup, need_lock); - table = NULL; - my_printf_error(ER_SPIDER_SYS_TABLE_VERSION_NUM, - ER_SPIDER_SYS_TABLE_VERSION_STR, MYF(0), - SPIDER_SYS_RWN_TBLS_TABLE_NAME_STR); - *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM; - goto error_col_num_chk; - } - break; - } - DBUG_ASSERT(0); - break; - case 27: - if (!memcmp(table_name, SPIDER_SYS_RW_TBL_TBLS_TABLE_NAME_STR, - SPIDER_SYS_RW_TBL_TBLS_TABLE_NAME_LEN)) - { - DBUG_PRINT("info",("spider checking for SYS_RW_TBL_TBLS")); - if (table->s->fields != SPIDER_SYS_RW_TBL_TBLS_COL_CNT) - { - spider_close_sys_table(thd, table, open_tables_backup, need_lock); - table = NULL; - my_printf_error(ER_SPIDER_SYS_TABLE_VERSION_NUM, - ER_SPIDER_SYS_TABLE_VERSION_STR, MYF(0), - SPIDER_SYS_RW_TBL_TBLS_TABLE_NAME_STR); - *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM; - goto error_col_num_chk; - } - break; - } - DBUG_ASSERT(0); - break; - case 31: - if (!memcmp(table_name, SPIDER_SYS_RW_TBL_PTTS_TABLE_NAME_STR, - SPIDER_SYS_RW_TBL_PTTS_TABLE_NAME_LEN)) - { - DBUG_PRINT("info",("spider checking for SYS_RW_TBL_PTTS")); - if (table->s->fields != SPIDER_SYS_RW_TBL_PTTS_COL_CNT) - { - spider_close_sys_table(thd, table, open_tables_backup, need_lock); - table = NULL; - my_printf_error(ER_SPIDER_SYS_TABLE_VERSION_NUM, - ER_SPIDER_SYS_TABLE_VERSION_STR, MYF(0), - SPIDER_SYS_RW_TBL_PTTS_TABLE_NAME_STR); - *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM; - goto error_col_num_chk; - } - break; - } DBUG_ASSERT(0); break; case 34: @@ -566,22 +462,6 @@ TABLE *spider_open_sys_table( } break; } - if (!memcmp(table_name, SPIDER_SYS_RW_TBL_SPTTS_TABLE_NAME_STR, - SPIDER_SYS_RW_TBL_SPTTS_TABLE_NAME_LEN)) - { - DBUG_PRINT("info",("spider checking for SYS_RW_TBL_SPTTS")); - if (table->s->fields != SPIDER_SYS_RW_TBL_SPTTS_COL_CNT) - { - spider_close_sys_table(thd, table, open_tables_backup, need_lock); - table = NULL; - my_printf_error(ER_SPIDER_SYS_TABLE_VERSION_NUM, - ER_SPIDER_SYS_TABLE_VERSION_STR, MYF(0), - SPIDER_SYS_RW_TBL_SPTTS_TABLE_NAME_STR); - *error_num = ER_SPIDER_SYS_TABLE_VERSION_NUM; - goto error_col_num_chk; - } - break; - } DBUG_ASSERT(0); break; default: @@ -1592,52 +1472,6 @@ void spider_store_binlog_pos_gtid( DBUG_VOID_RETURN; } -void spider_store_table_sts_info( - TABLE *table, - ha_statistics *stat -) { - MYSQL_TIME mysql_time; - DBUG_ENTER("spider_store_table_sts_info"); - table->field[SPIDER_TABLE_STS_DATA_FILE_LENGTH_POS]->store( - (longlong) stat->data_file_length, TRUE); - table->field[SPIDER_TABLE_STS_MAX_DATA_FILE_LENGTH_POS]->store( - (longlong) stat->max_data_file_length, TRUE); - table->field[SPIDER_TABLE_STS_INDEX_FILE_LENGTH_POS]->store( - (longlong) stat->index_file_length, TRUE); - table->field[SPIDER_TABLE_STS_RECORDS_POS]->store( - (longlong) stat->records, TRUE); - table->field[SPIDER_TABLE_STS_MEAN_REC_LENGTH_POS]->store( - (longlong) stat->mean_rec_length, TRUE); - spd_tz_system->gmt_sec_to_TIME(&mysql_time, (my_time_t) stat->check_time); - table->field[SPIDER_TABLE_STS_CHECK_TIME_POS]->store_time(&mysql_time); - spd_tz_system->gmt_sec_to_TIME(&mysql_time, (my_time_t) stat->create_time); - table->field[SPIDER_TABLE_STS_CREATE_TIME_POS]->store_time(&mysql_time); - spd_tz_system->gmt_sec_to_TIME(&mysql_time, (my_time_t) stat->update_time); - table->field[SPIDER_TABLE_STS_UPDATE_TIME_POS]->store_time(&mysql_time); - if (stat->checksum_null) - { - table->field[SPIDER_TABLE_STS_CHECKSUM_POS]->set_null(); - table->field[SPIDER_TABLE_STS_CHECKSUM_POS]->reset(); - } else { - table->field[SPIDER_TABLE_STS_CHECKSUM_POS]->set_notnull(); - table->field[SPIDER_TABLE_STS_CHECKSUM_POS]->store( - (longlong) stat->checksum, TRUE); - } - DBUG_VOID_RETURN; -} - -void spider_store_table_crd_info( - TABLE *table, - uint *seq, - longlong *cardinality -) { - DBUG_ENTER("spider_store_table_crd_info"); - table->field[SPIDER_TABLE_CRD_KEY_SEQ_POS]->store((longlong) *seq, TRUE); - table->field[SPIDER_TABLE_CRD_CARDINALITY_POS]->store( - (longlong) *cardinality, FALSE); - DBUG_VOID_RETURN; -} - int spider_insert_xa( TABLE *table, XID *xid, @@ -1744,83 +1578,6 @@ int spider_insert_sys_table( DBUG_RETURN(error_num); } -int spider_insert_or_update_table_sts( - TABLE *table, - const char *name, - uint name_length, - ha_statistics *stat -) { - int error_num; - char table_key[MAX_KEY_LENGTH]; - DBUG_ENTER("spider_insert_or_update_table_sts"); - table->use_all_columns(); - spider_store_tables_name(table, name, name_length); - spider_store_table_sts_info( - table, - stat - ); - - if ((error_num = spider_check_sys_table_for_update_all_columns(table, table_key))) - { - if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) - { - table->file->print_error(error_num, MYF(0)); - DBUG_RETURN(error_num); - } - if ((error_num = spider_write_sys_table_row(table))) - { - DBUG_RETURN(error_num); - } - } else { - if ((error_num = spider_update_sys_table_row(table, FALSE))) - { - table->file->print_error(error_num, MYF(0)); - DBUG_RETURN(error_num); - } - } - - DBUG_RETURN(0); -} - -int spider_insert_or_update_table_crd( - TABLE *table, - const char *name, - uint name_length, - longlong *cardinality, - uint number_of_keys -) { - int error_num; - uint roop_count; - char table_key[MAX_KEY_LENGTH]; - DBUG_ENTER("spider_insert_or_update_table_crd"); - table->use_all_columns(); - spider_store_tables_name(table, name, name_length); - - for (roop_count = 0; roop_count < number_of_keys; ++roop_count) - { - spider_store_table_crd_info(table, &roop_count, &cardinality[roop_count]); - if ((error_num = spider_check_sys_table_for_update_all_columns(table, table_key))) - { - if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) - { - table->file->print_error(error_num, MYF(0)); - DBUG_RETURN(error_num); - } - if ((error_num = spider_write_sys_table_row(table))) - { - DBUG_RETURN(error_num); - } - } else { - if ((error_num = spider_update_sys_table_row(table, FALSE))) - { - table->file->print_error(error_num, MYF(0)); - DBUG_RETURN(error_num); - } - } - } - DBUG_RETURN(0); -} - int spider_log_tables_link_failed( TABLE *table, char *name, @@ -2877,83 +2634,6 @@ int spider_get_sys_tables_static_link_id( DBUG_RETURN(error_num); } -void spider_get_sys_table_sts_info( - TABLE *table, - ha_statistics *stat -) { - MYSQL_TIME mysql_time; -#ifdef MARIADB_BASE_VERSION - uint not_used_uint; -#else - my_bool not_used_my_bool; -#endif - long not_used_long; - DBUG_ENTER("spider_get_sys_table_sts_info"); - stat->data_file_length = (ulonglong) table-> - field[SPIDER_TABLE_STS_DATA_FILE_LENGTH_POS]->val_int(); - stat->max_data_file_length = (ulonglong) table-> - field[SPIDER_TABLE_STS_MAX_DATA_FILE_LENGTH_POS]->val_int(); - stat->index_file_length = (ulonglong) table-> - field[SPIDER_TABLE_STS_INDEX_FILE_LENGTH_POS]->val_int(); - stat->records = (ha_rows) table-> - field[SPIDER_TABLE_STS_RECORDS_POS]->val_int(); - stat->mean_rec_length = (ulong) table-> - field[SPIDER_TABLE_STS_MEAN_REC_LENGTH_POS]->val_int(); - table->field[SPIDER_TABLE_STS_CHECK_TIME_POS]->get_date(&mysql_time, - SPIDER_date_mode_t(0)); -#ifdef MARIADB_BASE_VERSION - stat->check_time = (time_t) my_system_gmt_sec(&mysql_time, - ¬_used_long, ¬_used_uint); -#else - stat->check_time = (time_t) my_system_gmt_sec(&mysql_time, - ¬_used_long, ¬_used_my_bool); -#endif - table->field[SPIDER_TABLE_STS_CREATE_TIME_POS]->get_date(&mysql_time, - SPIDER_date_mode_t(0)); -#ifdef MARIADB_BASE_VERSION - stat->create_time = (time_t) my_system_gmt_sec(&mysql_time, - ¬_used_long, ¬_used_uint); -#else - stat->create_time = (time_t) my_system_gmt_sec(&mysql_time, - ¬_used_long, ¬_used_my_bool); -#endif - table->field[SPIDER_TABLE_STS_UPDATE_TIME_POS]->get_date(&mysql_time, - SPIDER_date_mode_t(0)); -#ifdef MARIADB_BASE_VERSION - stat->update_time = (time_t) my_system_gmt_sec(&mysql_time, - ¬_used_long, ¬_used_uint); -#else - stat->update_time = (time_t) my_system_gmt_sec(&mysql_time, - ¬_used_long, ¬_used_my_bool); -#endif - if (table->field[SPIDER_TABLE_STS_CHECKSUM_POS]->is_null()) - { - stat->checksum_null = TRUE; - stat->checksum = 0; - } else { - stat->checksum_null = FALSE; - stat->checksum = (ha_checksum) table-> - field[SPIDER_TABLE_STS_CHECKSUM_POS]->val_int(); - } - DBUG_VOID_RETURN; -} - -void spider_get_sys_table_crd_info( - TABLE *table, - longlong *cardinality, - uint number_of_keys -) { - uint seq; - DBUG_ENTER("spider_get_sys_table_crd_info"); - seq = (uint) table->field[SPIDER_TABLE_CRD_KEY_SEQ_POS]->val_int(); - if (seq < number_of_keys) - { - cardinality[seq] = (longlong) table-> - field[SPIDER_TABLE_CRD_CARDINALITY_POS]->val_int(); - } - DBUG_VOID_RETURN; -} - int spider_sys_update_tables_link_status( THD *thd, char *name, @@ -3394,260 +3074,6 @@ int spider_get_link_statuses( DBUG_RETURN(0); } -int spider_sys_insert_or_update_table_sts( - THD *thd, - const char *name, - uint name_length, - ha_statistics *stat, - bool need_lock -) { - int error_num; - TABLE *table_sts = NULL; - SPIDER_Open_tables_backup open_tables_backup; - DBUG_ENTER("spider_sys_insert_or_update_table_sts"); - if ( - !(table_sts = spider_open_sys_table( - thd, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR, - SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN, TRUE, - &open_tables_backup, need_lock, &error_num)) - ) { - goto error; - } - if ((error_num = spider_insert_or_update_table_sts( - table_sts, - name, - name_length, - stat - ))) - goto error; - spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); - table_sts = NULL; - DBUG_RETURN(0); - -error: - if (table_sts) - spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); - DBUG_RETURN(error_num); -} - -int spider_sys_insert_or_update_table_crd( - THD *thd, - const char *name, - uint name_length, - longlong *cardinality, - uint number_of_keys, - bool need_lock -) { - int error_num; - TABLE *table_crd = NULL; - SPIDER_Open_tables_backup open_tables_backup; - DBUG_ENTER("spider_sys_insert_or_update_table_crd"); - if ( - !(table_crd = spider_open_sys_table( - thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR, - SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE, - &open_tables_backup, need_lock, &error_num)) - ) { - goto error; - } - if ((error_num = spider_insert_or_update_table_crd( - table_crd, - name, - name_length, - cardinality, - number_of_keys - ))) - goto error; - spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); - table_crd = NULL; - DBUG_RETURN(0); - -error: - if (table_crd) - spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); - DBUG_RETURN(error_num); -} - -int spider_sys_delete_table_sts( - THD *thd, - const char *name, - uint name_length, - bool need_lock -) { - int error_num; - TABLE *table_sts = NULL; - SPIDER_Open_tables_backup open_tables_backup; - DBUG_ENTER("spider_sys_delete_table_sts"); - if ( - !(table_sts = spider_open_sys_table( - thd, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR, - SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN, TRUE, - &open_tables_backup, need_lock, &error_num)) - ) { - goto error; - } - if ((error_num = spider_delete_table_sts( - table_sts, - name, - name_length - ))) - goto error; - spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); - table_sts = NULL; - DBUG_RETURN(0); - -error: - if (table_sts) - spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); - DBUG_RETURN(error_num); -} - -int spider_sys_delete_table_crd( - THD *thd, - const char *name, - uint name_length, - bool need_lock -) { - int error_num; - TABLE *table_crd = NULL; - SPIDER_Open_tables_backup open_tables_backup; - DBUG_ENTER("spider_sys_delete_table_crd"); - if ( - !(table_crd = spider_open_sys_table( - thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR, - SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE, - &open_tables_backup, need_lock, &error_num)) - ) { - goto error; - } - if ((error_num = spider_delete_table_crd( - table_crd, - name, - name_length - ))) - goto error; - spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); - table_crd = NULL; - DBUG_RETURN(0); - -error: - if (table_crd) - spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); - DBUG_RETURN(error_num); -} - -int spider_sys_get_table_sts( - THD *thd, - const char *name, - uint name_length, - ha_statistics *stat, - bool need_lock -) { - int error_num; - char table_key[MAX_KEY_LENGTH]; - TABLE *table_sts = NULL; - SPIDER_Open_tables_backup open_tables_backup; - DBUG_ENTER("spider_sys_get_table_sts"); - if ( - !(table_sts = spider_open_sys_table( - thd, SPIDER_SYS_TABLE_STS_TABLE_NAME_STR, - SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN, TRUE, - &open_tables_backup, need_lock, &error_num)) - ) { - goto error; - } - - table_sts->use_all_columns(); - spider_store_tables_name(table_sts, name, name_length); - if ((error_num = spider_check_sys_table(table_sts, table_key))) - { - if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) - { - table_sts->file->print_error(error_num, MYF(0)); - } - goto error; - } else { - spider_get_sys_table_sts_info( - table_sts, - stat - ); - } - - spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); - table_sts = NULL; - DBUG_RETURN(0); - -error: - if (table_sts) - spider_close_sys_table(thd, table_sts, &open_tables_backup, need_lock); - DBUG_RETURN(error_num); -} - -int spider_sys_get_table_crd( - THD *thd, - const char *name, - uint name_length, - longlong *cardinality, - uint number_of_keys, - bool need_lock -) { - int error_num; - char table_key[MAX_KEY_LENGTH]; - bool index_inited = FALSE; - TABLE *table_crd = NULL; - SPIDER_Open_tables_backup open_tables_backup; - DBUG_ENTER("spider_sys_get_table_crd"); - - if ( - !(table_crd = spider_open_sys_table( - thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR, - SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE, - &open_tables_backup, need_lock, &error_num)) - ) { - goto error; - } - - table_crd->use_all_columns(); - spider_store_tables_name(table_crd, name, name_length); - if ((error_num = spider_get_sys_table_by_idx(table_crd, table_key, 0, - SPIDER_SYS_TABLE_CRD_PK_COL_CNT - 1))) - { - if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) - { - table_crd->file->print_error(error_num, MYF(0)); - } - goto error; - } else { - index_inited = TRUE; - do { - spider_get_sys_table_crd_info( - table_crd, - cardinality, - number_of_keys - ); - error_num = spider_sys_index_next_same(table_crd, table_key); - } while (error_num == 0); - } - index_inited = FALSE; - if ((error_num = spider_sys_index_end(table_crd))) - { - table_crd->file->print_error(error_num, MYF(0)); - goto error; - } - - spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); - table_crd = NULL; - DBUG_RETURN(0); - -error: - if (index_inited) - spider_sys_index_end(table_crd); - - if (table_crd) - spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock); - DBUG_RETURN(error_num); -} - int spider_sys_replace( TABLE *table, bool *modified_non_trans_table diff --git a/storage/spider/spd_sys_table.h b/storage/spider/spd_sys_table.h index 22f48b05dfb..0ac21322bbf 100644 --- a/storage/spider/spd_sys_table.h +++ b/storage/spider/spd_sys_table.h @@ -28,20 +28,6 @@ #define SPIDER_SYS_XA_FAILED_TABLE_NAME_LEN 20 #define SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR "spider_table_position_for_recovery" #define SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN 34 -#define SPIDER_SYS_TABLE_STS_TABLE_NAME_STR "spider_table_sts" -#define SPIDER_SYS_TABLE_STS_TABLE_NAME_LEN 16 -#define SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR "spider_table_crd" -#define SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN 16 -#define SPIDER_SYS_RW_TBLS_TABLE_NAME_STR "spider_rewrite_tables" -#define SPIDER_SYS_RW_TBLS_TABLE_NAME_LEN 21 -#define SPIDER_SYS_RW_TBL_TBLS_TABLE_NAME_STR "spider_rewrite_table_tables" -#define SPIDER_SYS_RW_TBL_TBLS_TABLE_NAME_LEN 27 -#define SPIDER_SYS_RW_TBL_PTTS_TABLE_NAME_STR "spider_rewrite_table_partitions" -#define SPIDER_SYS_RW_TBL_PTTS_TABLE_NAME_LEN 31 -#define SPIDER_SYS_RW_TBL_SPTTS_TABLE_NAME_STR "spider_rewrite_table_subpartitions" -#define SPIDER_SYS_RW_TBL_SPTTS_TABLE_NAME_LEN 34 -#define SPIDER_SYS_RWN_TBLS_TABLE_NAME_STR "spider_rewritten_tables" -#define SPIDER_SYS_RWN_TBLS_TABLE_NAME_LEN 23 #define SPIDER_SYS_XA_PREPARED_STR "PREPARED" #define SPIDER_SYS_XA_NOT_YET_STR "NOT YET" @@ -65,11 +51,6 @@ #define SPIDER_SYS_TABLE_STS_PK_COL_CNT 2 #define SPIDER_SYS_TABLE_CRD_COL_CNT 4 #define SPIDER_SYS_TABLE_CRD_PK_COL_CNT 3 -#define SPIDER_SYS_RW_TBLS_COL_CNT 3 -#define SPIDER_SYS_RW_TBL_TBLS_COL_CNT 8 -#define SPIDER_SYS_RW_TBL_PTTS_COL_CNT 7 -#define SPIDER_SYS_RW_TBL_SPTTS_COL_CNT 8 -#define SPIDER_SYS_RWN_TBLS_COL_CNT 4 #define SPIDER_SYS_LINK_MON_TABLE_DB_NAME_SIZE 64 #define SPIDER_SYS_LINK_MON_TABLE_TABLE_NAME_SIZE 64 @@ -316,21 +297,6 @@ int spider_insert_sys_table( TABLE *table ); -int spider_insert_or_update_table_sts( - TABLE *table, - const char *name, - uint name_length, - ha_statistics *stat -); - -int spider_insert_or_update_table_crd( - TABLE *table, - const char *name, - uint name_length, - longlong *cardinality, - uint number_of_keys -); - int spider_log_tables_link_failed( TABLE *table, char *name, @@ -474,17 +440,6 @@ int spider_get_sys_tables_static_link_id( MEM_ROOT *mem_root ); -void spider_get_sys_table_sts_info( - TABLE *table, - ha_statistics *stat -); - -void spider_get_sys_table_crd_info( - TABLE *table, - longlong *cardinality, - uint number_of_keys -); - int spider_sys_update_tables_link_status( THD *thd, char *name, @@ -536,54 +491,6 @@ int spider_get_link_statuses( MEM_ROOT *mem_root ); -int spider_sys_insert_or_update_table_sts( - THD *thd, - const char *name, - uint name_length, - ha_statistics *stat, - bool need_lock -); - -int spider_sys_insert_or_update_table_crd( - THD *thd, - const char *name, - uint name_length, - longlong *cardinality, - uint number_of_keys, - bool need_lock -); - -int spider_sys_delete_table_sts( - THD *thd, - const char *name, - uint name_length, - bool need_lock -); - -int spider_sys_delete_table_crd( - THD *thd, - const char *name, - uint name_length, - bool need_lock -); - -int spider_sys_get_table_sts( - THD *thd, - const char *name, - uint name_length, - ha_statistics *stat, - bool need_lock -); - -int spider_sys_get_table_crd( - THD *thd, - const char *name, - uint name_length, - longlong *cardinality, - uint number_of_keys, - bool need_lock -); - int spider_sys_replace( TABLE *table, bool *modified_non_trans_table diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index 0c44f817657..c11a6b6a40d 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -129,9 +129,6 @@ const char **spd_mysqld_unix_port; uint *spd_mysqld_port; bool volatile *spd_abort_loop; Time_zone *spd_tz_system; -static int *spd_mysqld_server_started; -static pthread_mutex_t *spd_LOCK_server_started; -static pthread_cond_t *spd_COND_server_started; extern long spider_conn_mutex_id; handlerton *spider_hton_ptr; SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; @@ -1151,7 +1148,7 @@ int spider_create_string_list( } if (!(*string_list = (char**) - spider_bulk_malloc(spider_current_trx, 37, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_STRING_LIST_1, MYF(MY_WME | MY_ZEROFILL), string_list, (uint) (sizeof(char*) * (*list_length)), string_length_list, (uint) (sizeof(int) * (*list_length)), NullS)) @@ -1345,7 +1342,7 @@ int spider_create_long_list( } if (!(*long_list = (long*) - spider_bulk_malloc(spider_current_trx, 38, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_LONG_LIST_1, MYF(MY_WME | MY_ZEROFILL), long_list, (uint) (sizeof(long) * (*list_length)), NullS)) ) { @@ -1424,7 +1421,7 @@ int spider_create_longlong_list( } if (!(*longlong_list = (longlong *) - spider_bulk_malloc(spider_current_trx, 39, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_LONGLONG_LIST_1, MYF(MY_WME | MY_ZEROFILL), longlong_list, (uint) (sizeof(longlong) * (*list_length)), NullS)) ) { @@ -1492,7 +1489,7 @@ int spider_increase_string_list( } if (!(tmp_str_list = (char**) - spider_bulk_malloc(spider_current_trx, 40, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_INCREASE_STRING_LIST_1, MYF(MY_WME | MY_ZEROFILL), &tmp_str_list, (uint) (sizeof(char*) * link_count), &tmp_length_list, (uint) (sizeof(uint) * link_count), NullS)) @@ -1555,7 +1552,7 @@ int spider_increase_null_string_list( DBUG_RETURN(0); if (!(tmp_str_list = (char**) - spider_bulk_malloc(spider_current_trx, 247, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_INCREASE_NULL_STRING_LIST_1, MYF(MY_WME | MY_ZEROFILL), &tmp_str_list, (uint) (sizeof(char*) * link_count), &tmp_length_list, (uint) (sizeof(uint) * link_count), NullS)) @@ -1613,7 +1610,7 @@ int spider_increase_long_list( tmp_long = -1; if (!(tmp_long_list = (long*) - spider_bulk_malloc(spider_current_trx, 41, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_INCREASE_LONG_LIST_1, MYF(MY_WME | MY_ZEROFILL), &tmp_long_list, (uint) (sizeof(long) * link_count), NullS)) ) { @@ -1658,7 +1655,7 @@ int spider_increase_longlong_list( tmp_longlong = -1; if (!(tmp_longlong_list = (longlong*) - spider_bulk_malloc(spider_current_trx, 42, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_INCREASE_LONGLONG_LIST_1, MYF(MY_WME | MY_ZEROFILL), &tmp_longlong_list, (uint) (sizeof(longlong) * link_count), NullS)) ) { @@ -3081,7 +3078,7 @@ int spider_parse_connect_info( share_alter = &share->alter_table; share_alter->all_link_count = share->all_link_count; if (!(share_alter->tmp_server_names = (char **) - spider_bulk_malloc(spider_current_trx, 43, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_PARSE_CONNECT_INFO_1, MYF(MY_WME | MY_ZEROFILL), &share_alter->tmp_server_names, (uint) (sizeof(char *) * share->all_link_count), &share_alter->tmp_tgt_table_names, @@ -4341,7 +4338,7 @@ int spider_create_conn_keys( #endif } if (!(share->conn_keys = (char **) - spider_bulk_alloc_mem(spider_current_trx, 45, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_CREATE_CONN_KEYS_1, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &share->conn_keys, sizeof(char *) * share->all_link_count, &share->conn_keys_lengths, length_base, @@ -4640,7 +4637,7 @@ SPIDER_SHARE *spider_create_share( length = (uint) strlen(table_name); bitmap_size = spider_bitmap_size(table_share->fields); if (!(share = (SPIDER_SHARE *) - spider_bulk_malloc(spider_current_trx, 46, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_SHARE_1, MYF(MY_WME | MY_ZEROFILL), &share, (uint) (sizeof(*share)), &tmp_name, (uint) (length + 1), &tmp_static_key_cardinality, @@ -4694,7 +4691,7 @@ SPIDER_SHARE *spider_create_share( goto error_init_hint_string; } for (roop_count = 0; roop_count < (int) table_share->keys; roop_count++) - share->key_hint[roop_count].init_calc_mem(95); + share->key_hint[roop_count].init_calc_mem(SPD_MID_CREATE_SHARE_2); DBUG_PRINT("info",("spider share->key_hint=%p", share->key_hint)); if ((*error_num = spider_parse_connect_info(share, table_share, @@ -5179,7 +5176,7 @@ SPIDER_SHARE *spider_get_share( #endif if (!(spider->conn_keys = (char **) - spider_bulk_alloc_mem(spider_current_trx, 47, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_GET_SHARE_1, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &spider->conn_keys, sizeof(char *) * share->link_count, &tmp_name, sizeof(char) * share->conn_keys_charlen, @@ -5721,7 +5718,7 @@ SPIDER_SHARE *spider_get_share( #endif if (!(spider->conn_keys = (char **) - spider_bulk_alloc_mem(spider_current_trx, 49, + spider_bulk_alloc_mem(spider_current_trx, SPD_MID_GET_SHARE_2, __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), &spider->conn_keys, sizeof(char *) * share->link_count, &tmp_name, sizeof(char) * share->conn_keys_charlen, @@ -6099,8 +6096,6 @@ int spider_free_share( ) { DBUG_ENTER("spider_free_share"); pthread_mutex_lock(&spider_tbl_mutex); - bool do_delete_thd = false; - THD *thd = current_thd; if (!--share->use_count) { #ifndef WITHOUT_SPIDER_BG_SEARCH @@ -6118,49 +6113,6 @@ int spider_free_share( spider_free_spider_object_for_share(&share->crd_spider); } #endif - if ( - share->sts_init && - share->table_share->tmp_table == NO_TMP_TABLE && - spider_param_store_last_sts(share->store_last_sts) - ) { - if (!thd) - { - /* Create a thread for Spider system table update */ - thd = spider_create_thd(); - if (!thd) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - do_delete_thd = TRUE; - } - spider_sys_insert_or_update_table_sts( - thd, - share->lgtm_tblhnd_share->table_name, - share->lgtm_tblhnd_share->table_name_length, - &share->stat, - FALSE - ); - } - if ( - share->crd_init && - share->table_share->tmp_table == NO_TMP_TABLE && - spider_param_store_last_crd(share->store_last_crd) - ) { - if (!thd) - { - /* Create a thread for Spider system table update */ - thd = spider_create_thd(); - if (!thd) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - do_delete_thd = TRUE; - } - spider_sys_insert_or_update_table_crd( - thd, - share->lgtm_tblhnd_share->table_name, - share->lgtm_tblhnd_share->table_name_length, - share->cardinality, - share->table_share->fields, - FALSE - ); - } spider_free_share_alloc(share); #ifdef HASH_UPDATE_WITH_HASH_VALUE my_hash_delete_with_hash_value(&spider_open_tables, @@ -6174,8 +6126,6 @@ int spider_free_share( free_root(&share->mem_root, MYF(0)); spider_free(spider_current_trx, share, MYF(0)); } - if (do_delete_thd) - spider_destroy_thd(thd); pthread_mutex_unlock(&spider_tbl_mutex); DBUG_RETURN(0); } @@ -6254,7 +6204,7 @@ SPIDER_LGTM_TBLHND_SHARE *spider_get_lgtm_tblhnd_share( { DBUG_PRINT("info",("spider create new lgtm tblhnd share")); if (!(lgtm_tblhnd_share = (SPIDER_LGTM_TBLHND_SHARE *) - spider_bulk_malloc(spider_current_trx, 244, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_GET_LGTM_TBLHND_SHARE_1, MYF(MY_WME | MY_ZEROFILL), &lgtm_tblhnd_share, (uint) (sizeof(*lgtm_tblhnd_share)), &tmp_name, (uint) (table_name_length + 1), NullS)) @@ -6363,7 +6313,7 @@ SPIDER_WIDE_SHARE *spider_get_wide_share( { DBUG_PRINT("info",("spider create new wide share")); if (!(wide_share = (SPIDER_WIDE_SHARE *) - spider_bulk_malloc(spider_current_trx, 51, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_GET_PT_SHARE_1, MYF(MY_WME | MY_ZEROFILL), &wide_share, sizeof(SPIDER_WIDE_SHARE), &tmp_name, (uint) (table_share->path.length + 1), &tmp_cardinality, @@ -6678,7 +6628,7 @@ int spider_open_all_tables( spider->wide_handler->lock_type = TL_READ_NO_INSERT; if (!(share = (SPIDER_SHARE *) - spider_bulk_malloc(spider_current_trx, 52, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_OPEN_ALL_TABLES_1, MYF(MY_WME | MY_ZEROFILL), &share, (uint) (sizeof(*share)), &connect_info, (uint) (sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT), @@ -6828,30 +6778,6 @@ handler* spider_create_handler( MEM_ROOT *mem_root ) { DBUG_ENTER("spider_create_handler"); -#ifndef WITHOUT_SPIDER_BG_SEARCH - SPIDER_THREAD *thread = &spider_table_sts_threads[0]; - if (unlikely(thread->init_command)) - { - THD *thd = current_thd; - pthread_cond_t *cond = thd->mysys_var->current_cond; - pthread_mutex_t *mutex = thd->mysys_var->current_mutex; - /* wait for finishing init_command */ - pthread_mutex_lock(&thread->mutex); - if (unlikely(thread->init_command)) - { - thd->mysys_var->current_cond = &thread->sync_cond; - thd->mysys_var->current_mutex = &thread->mutex; - pthread_cond_wait(&thread->sync_cond, &thread->mutex); - } - pthread_mutex_unlock(&thread->mutex); - thd->mysys_var->current_cond = cond; - thd->mysys_var->current_mutex = mutex; - if (thd->killed) - { - DBUG_RETURN(NULL); - } - } -#endif DBUG_RETURN(new (mem_root) ha_spider(hton, table)); } @@ -6918,26 +6844,13 @@ int spider_db_done( void *p ) { int roop_count; - bool do_delete_thd; - THD *thd = current_thd, *tmp_thd; + THD *tmp_thd; SPIDER_CONN *conn; SPIDER_INIT_ERROR_TABLE *spider_init_error_table; SPIDER_TABLE_MON_LIST *table_mon_list; SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share; DBUG_ENTER("spider_db_done"); - /* Begin Spider plugin deinit */ - if (thd) - do_delete_thd = FALSE; - else - { - /* Create a thread for Spider plugin deinit */ - thd = spider_create_thd(); - if (!thd) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - do_delete_thd = TRUE; - } - for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; roop_count--) { if (spider_dbton[roop_count].deinit) @@ -7154,13 +7067,6 @@ int spider_db_done( )); } - /* End Spider plugin deinit */ - if (do_delete_thd) - spider_destroy_thd(thd); - -/* -DBUG_ASSERT(0); -*/ DBUG_RETURN(0); } @@ -7172,6 +7078,51 @@ int spider_panic( DBUG_RETURN(0); } +/* + Create or fix the system tables. See spd_init_query.h for the details. +*/ +bool spider_init_system_tables() +{ + DBUG_ENTER("spider_init_system_tables"); + + MYSQL *mysql= mysql_init(NULL); + if (!mysql) + { + DBUG_RETURN(TRUE); + } + + if (!mysql_real_connect_local(mysql)) + { + mysql_close(mysql); + DBUG_RETURN(TRUE); + } + + const int size= sizeof(spider_init_queries) / sizeof(spider_init_queries[0]); + for (int i= 0; i < size; i++) + { + const LEX_STRING *query= &spider_init_queries[i]; + if (mysql_real_query(mysql, query->str, query->length)) + { + fprintf(stderr, + "[ERROR] SPIDER plugin initialization failed at '%s' by '%s'\n", + query->str, mysql_error(mysql)); + + mysql_close(mysql); + DBUG_RETURN(TRUE); + } + + if (MYSQL_RES *res= mysql_store_result(mysql)) + { + mysql_free_result(res); + } + } + + mysql_close(mysql); + + DBUG_RETURN(FALSE); +} + + int spider_db_init( void *p ) { @@ -7180,6 +7131,11 @@ int spider_db_init( uchar addr[6]; handlerton *spider_hton = (handlerton *)p; DBUG_ENTER("spider_db_init"); + + const LEX_CSTRING aria_name={STRING_WITH_LEN("Aria")}; + if (!plugin_is_ready(&aria_name, MYSQL_STORAGE_ENGINE_PLUGIN)) + DBUG_RETURN(HA_ERR_RETRY_INIT); + spider_hton_ptr = spider_hton; spider_hton->flags = HTON_TEMPORARY_NOT_SUPPORTED; @@ -7259,9 +7215,6 @@ int spider_db_init( spd_mysqld_port = &mysqld_port; spd_abort_loop = &abort_loop; spd_tz_system = my_tz_SYSTEM; - spd_mysqld_server_started = &mysqld_server_started; - spd_LOCK_server_started = &LOCK_server_started; - spd_COND_server_started = &COND_server_started; #ifdef HAVE_PSI_INTERFACE init_spider_psi_keys(); @@ -7393,7 +7346,7 @@ int spider_db_init( (my_hash_get_key) spider_tbl_get_key, 0, 0)) goto error_open_tables_hash_init; - spider_alloc_calc_mem_init(spider_open_tables, 143); + spider_alloc_calc_mem_init(spider_open_tables, SPD_MID_DB_INIT_1); spider_alloc_calc_mem(NULL, spider_open_tables, spider_open_tables.array.max_element * @@ -7402,7 +7355,7 @@ int spider_db_init( (my_hash_get_key) spider_tbl_get_key, 0, 0)) goto error_init_error_tables_hash_init; - spider_alloc_calc_mem_init(spider_init_error_tables, 144); + spider_alloc_calc_mem_init(spider_init_error_tables, SPD_MID_DB_INIT_2); spider_alloc_calc_mem(NULL, spider_init_error_tables, spider_init_error_tables.array.max_element * @@ -7414,7 +7367,7 @@ int spider_db_init( ) goto error_open_wide_share_hash_init; - spider_alloc_calc_mem_init(spider_open_wide_share, 145); + spider_alloc_calc_mem_init(spider_open_wide_share, SPD_MID_DB_INIT_3); spider_alloc_calc_mem(NULL, spider_open_wide_share, spider_open_wide_share.array.max_element * @@ -7425,7 +7378,7 @@ int spider_db_init( (my_hash_get_key) spider_lgtm_tblhnd_share_hash_get_key, 0, 0)) goto error_lgtm_tblhnd_share_hash_init; - spider_alloc_calc_mem_init(spider_lgtm_tblhnd_share_hash, 245); + spider_alloc_calc_mem_init(spider_lgtm_tblhnd_share_hash, SPD_MID_DB_INIT_4); spider_alloc_calc_mem(NULL, spider_lgtm_tblhnd_share_hash, spider_lgtm_tblhnd_share_hash.array.max_element * @@ -7439,7 +7392,7 @@ int spider_db_init( spider_free_ipport_conn, 0)) goto error_ipport_conn__hash_init; - spider_alloc_calc_mem_init(spider_open_connections, 146); + spider_alloc_calc_mem_init(spider_open_connections, SPD_MID_DB_INIT_5); spider_alloc_calc_mem(NULL, spider_open_connections, spider_open_connections.array.max_element * @@ -7449,7 +7402,7 @@ int spider_db_init( (my_hash_get_key) spider_conn_get_key, 0, 0)) goto error_hs_r_conn_hash_init; - spider_alloc_calc_mem_init(spider_hs_r_conn_hash, 147); + spider_alloc_calc_mem_init(spider_hs_r_conn_hash, SPD_MID_DB_INIT_6); spider_alloc_calc_mem(NULL, spider_hs_r_conn_hash, spider_hs_r_conn_hash.array.max_element * @@ -7458,7 +7411,7 @@ int spider_db_init( (my_hash_get_key) spider_conn_get_key, 0, 0)) goto error_hs_w_conn_hash_init; - spider_alloc_calc_mem_init(spider_hs_w_conn_hash, 148); + spider_alloc_calc_mem_init(spider_hs_w_conn_hash, SPD_MID_DB_INIT_7); spider_alloc_calc_mem(NULL, spider_hs_w_conn_hash, spider_hs_w_conn_hash.array.max_element * @@ -7468,7 +7421,7 @@ int spider_db_init( (my_hash_get_key) spider_allocated_thds_get_key, 0, 0)) goto error_allocated_thds_hash_init; - spider_alloc_calc_mem_init(spider_allocated_thds, 149); + spider_alloc_calc_mem_init(spider_allocated_thds, SPD_MID_DB_INIT_8); spider_alloc_calc_mem(NULL, spider_allocated_thds, spider_allocated_thds.array.max_element * @@ -7478,14 +7431,14 @@ int spider_db_init( NULL, 64, 64, MYF(MY_WME))) goto error_mon_table_cache_array_init; - spider_alloc_calc_mem_init(spider_mon_table_cache, 165); + spider_alloc_calc_mem_init(spider_mon_table_cache, SPD_MID_DB_INIT_9); spider_alloc_calc_mem(NULL, spider_mon_table_cache, spider_mon_table_cache.max_element * spider_mon_table_cache.size_of_element); if (!(spider_udf_table_mon_mutexes = (pthread_mutex_t *) - spider_bulk_malloc(NULL, 53, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(NULL, SPD_MID_DB_INIT_10, MYF(MY_WME | MY_ZEROFILL), &spider_udf_table_mon_mutexes, (uint) (sizeof(pthread_mutex_t) * spider_param_udf_table_mon_mutex_count()), &spider_udf_table_mon_conds, (uint) (sizeof(pthread_cond_t) * @@ -7530,16 +7483,21 @@ int spider_db_init( (my_hash_get_key) spider_udf_tbl_mon_list_key, 0, 0)) goto error_init_udf_table_mon_list_hash; - spider_alloc_calc_mem_init(spider_udf_table_mon_list_hash, 150); + spider_alloc_calc_mem_init(spider_udf_table_mon_list_hash, SPD_MID_DB_INIT_11); spider_alloc_calc_mem(NULL, spider_udf_table_mon_list_hash, spider_udf_table_mon_list_hash[roop_count].array.max_element * spider_udf_table_mon_list_hash[roop_count].array.size_of_element); } + if (spider_init_system_tables()) + { + goto error_system_table_creation; + } + #ifndef WITHOUT_SPIDER_BG_SEARCH if (!(spider_table_sts_threads = (SPIDER_THREAD *) - spider_bulk_malloc(NULL, 256, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(NULL, SPD_MID_DB_INIT_12, MYF(MY_WME | MY_ZEROFILL), &spider_table_sts_threads, (uint) (sizeof(SPIDER_THREAD) * spider_param_table_sts_thread_count()), &spider_table_crd_threads, (uint) (sizeof(SPIDER_THREAD) * @@ -7547,7 +7505,6 @@ int spider_db_init( NullS)) ) goto error_alloc_mon_mutxes; - spider_table_sts_threads[0].init_command = TRUE; for (roop_count = 0; roop_count < (int) spider_param_table_sts_thread_count(); @@ -7638,6 +7595,7 @@ error_init_udf_table_mon_list_hash: error_init_udf_table_mon_cond: for (; roop_count >= 0; roop_count--) pthread_cond_destroy(&spider_udf_table_mon_conds[roop_count]); +error_system_table_creation: roop_count = spider_param_udf_table_mon_mutex_count() - 1; error_init_udf_table_mon_mutex: for (; roop_count >= 0; roop_count--) @@ -7752,7 +7710,7 @@ char *spider_create_string( ) { char *res; DBUG_ENTER("spider_create_string"); - if (!(res = (char*) spider_malloc(spider_current_trx, 13, length + 1, + if (!(res = (char*) spider_malloc(spider_current_trx, SPD_MID_CREATE_STRING_1, length + 1, MYF(MY_WME)))) DBUG_RETURN(NULL); memcpy(res, str, length); @@ -7774,7 +7732,7 @@ char *spider_create_table_name_string( if (sub_name) length += sizeof("#SP#") - 1 + strlen(sub_name); } - if (!(res = (char*) spider_malloc(spider_current_trx, 14, length + 1, + if (!(res = (char*) spider_malloc(spider_current_trx, SPD_MID_CREATE_TABLE_NAME_STRING_1, length + 1, MYF(MY_WME)))) DBUG_RETURN(NULL); tmp = strmov(res, table_name); @@ -7894,7 +7852,6 @@ int spider_get_sts( int get_type; #endif int error_num = 0; - bool need_to_get = TRUE; DBUG_ENTER("spider_get_sts"); #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -7932,38 +7889,16 @@ int spider_get_sts( get_type = 0; } #endif - if ( - !share->sts_init && - share->table_share->tmp_table == NO_TMP_TABLE && - spider_param_load_sts_at_startup(share->load_sts_at_startup) && - (!share->init || share->init_error) - ) { - error_num = spider_sys_get_table_sts( - current_thd, - share->lgtm_tblhnd_share->table_name, - share->lgtm_tblhnd_share->table_name_length, - &share->stat, - FALSE - ); - if ( - !error_num || - (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) - ) - need_to_get = FALSE; - } - if (need_to_get) - { #ifdef WITH_PARTITION_STORAGE_ENGINE - if (get_type == 0) + if (get_type == 0) spider_copy_sts_to_share(share, share->wide_share); - else { + else { #endif error_num = spider_db_show_table_status(spider, link_idx, sts_mode, flag); #ifdef WITH_PARTITION_STORAGE_ENGINE - } -#endif } +#endif #ifdef WITH_PARTITION_STORAGE_ENGINE if (get_type >= 2) pthread_mutex_unlock(&share->wide_share->sts_mutex); @@ -8045,7 +7980,6 @@ int spider_get_crd( int get_type; #endif int error_num = 0; - bool need_to_get = TRUE; DBUG_ENTER("spider_get_crd"); #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -8083,39 +8017,16 @@ int spider_get_crd( get_type = 0; } #endif - if ( - !share->crd_init && - share->table_share->tmp_table == NO_TMP_TABLE && - spider_param_load_sts_at_startup(share->load_crd_at_startup) - ) { - error_num = spider_sys_get_table_crd( - current_thd, - share->lgtm_tblhnd_share->table_name, - share->lgtm_tblhnd_share->table_name_length, - share->cardinality, - table->s->fields, - FALSE - ); - if ( - !error_num || - (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) - ) - need_to_get = FALSE; - } - - if (need_to_get) - { #ifdef WITH_PARTITION_STORAGE_ENGINE - if (get_type == 0) + if (get_type == 0) spider_copy_crd_to_share(share, share->wide_share, - table->s->fields); - else { + table->s->fields); + else { #endif error_num = spider_db_show_index(spider, link_idx, table, crd_mode); #ifdef WITH_PARTITION_STORAGE_ENGINE - } -#endif } +#endif #ifdef WITH_PARTITION_STORAGE_ENGINE if (get_type >= 2) pthread_mutex_unlock(&share->wide_share->crd_mutex); @@ -8244,7 +8155,7 @@ SPIDER_INIT_ERROR_TABLE *spider_get_init_error_table( DBUG_RETURN(NULL); } if (!(spider_init_error_table = (SPIDER_INIT_ERROR_TABLE *) - spider_bulk_malloc(spider_current_trx, 54, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_GET_INIT_ERROR_TABLE_1, MYF(MY_WME | MY_ZEROFILL), &spider_init_error_table, (uint) (sizeof(*spider_init_error_table)), &tmp_name, (uint) (share->table_name_length + 1), NullS)) @@ -8358,7 +8269,7 @@ bool spider_check_hs_pk_update( tmp_str2(buf2, MAX_FIELD_WIDTH, &my_charset_bin); String *str, *str2; DBUG_ENTER("spider_check_hs_pk_update"); - tmp_str.init_calc_mem(137); + tmp_str.init_calc_mem(SPD_MID_CHECK_HS_PK_UPDATE_1); if (table_share->primary_key == MAX_KEY) DBUG_RETURN(FALSE); @@ -9554,7 +9465,7 @@ int spider_discover_table_structure( char buf[MAX_FIELD_WIDTH]; spider_string str(buf, sizeof(buf), system_charset_info); DBUG_ENTER("spider_discover_table_structure"); - str.init_calc_mem(229); + str.init_calc_mem(SPD_MID_DISCOVER_TABLE_STRUCTURE_1); str.length(0); if (str.reserve( SPIDER_SQL_CREATE_TABLE_LEN + share->db.length + @@ -9926,7 +9837,7 @@ int spider_create_spider_object_for_share( DBUG_PRINT("info",("spider spider=%p", (*spider))); #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) if (!(need_mons = (int *) - spider_bulk_malloc(spider_current_trx, 255, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_SPIDER_OBJECT_FOR_SHARE_1, MYF(MY_WME | MY_ZEROFILL), &need_mons, (uint) (sizeof(int) * share->link_count), &conns, (uint) (sizeof(SPIDER_CONN *) * share->link_count), &conn_link_idx, (uint) (sizeof(uint) * share->link_count), @@ -9940,7 +9851,7 @@ int spider_create_spider_object_for_share( ) #else if (!(need_mons = (int *) - spider_bulk_malloc(spider_current_trx, 255, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_SPIDER_OBJECT_FOR_SHARE_2, MYF(MY_WME | MY_ZEROFILL), &need_mons, (uint) (sizeof(int) * share->link_count), &conns, (uint) (sizeof(SPIDER_CONN *) * share->link_count), &conn_link_idx, (uint) (sizeof(uint) * share->link_count), @@ -10103,7 +10014,6 @@ void spider_free_sts_threads( ) { bool thread_killed; DBUG_ENTER("spider_free_sts_threads"); - spider_thread->init_command = FALSE; pthread_mutex_lock(&spider_thread->mutex); thread_killed = spider_thread->killed; spider_thread->killed = TRUE; @@ -10254,59 +10164,6 @@ void *spider_table_bg_sts_action( trx->thd = thd; /* init end */ - if (thread->init_command) - { - uint i = 0; - tmp_disable_binlog(thd); - thd->security_ctx->skip_grants(); - thd->client_capabilities |= CLIENT_MULTI_RESULTS; - if (!(*spd_mysqld_server_started) && !thd->killed && !thread->killed) - { - pthread_mutex_lock(spd_LOCK_server_started); - thd->mysys_var->current_cond = spd_COND_server_started; - thd->mysys_var->current_mutex = spd_LOCK_server_started; - if (!(*spd_mysqld_server_started) && !thd->killed && !thread->killed && - thread->init_command) - { - do - { - struct timespec abstime; - set_timespec_nsec(abstime, 1000); - error_num = pthread_cond_timedwait(spd_COND_server_started, - spd_LOCK_server_started, &abstime); - } while ( - (error_num == ETIMEDOUT || error_num == ETIME) && - !(*spd_mysqld_server_started) && !thd->killed && !thread->killed && - thread->init_command - ); - } - pthread_mutex_unlock(spd_LOCK_server_started); - thd->mysys_var->current_cond = &thread->cond; - thd->mysys_var->current_mutex = &thread->mutex; - } - bool spd_wsrep_on = thd->variables.wsrep_on; - thd->variables.wsrep_on = false; - while (spider_init_queries[i].length && !thd->killed && !thread->killed && - thread->init_command) - { - dispatch_command(COM_QUERY, thd, spider_init_queries[i].str, - (uint) spider_init_queries[i].length); - if (unlikely(thd->is_error())) - { - fprintf(stderr, "[ERROR] %s\n", spider_stmt_da_message(thd)); - thd->clear_error(); - break; - } - ++i; - } - thd->variables.wsrep_on = spd_wsrep_on; - thd->mysys_var->current_cond = &thread->cond; - thd->mysys_var->current_mutex = &thread->mutex; - thd->client_capabilities -= CLIENT_MULTI_RESULTS; - reenable_binlog(thd); - thread->init_command = FALSE; - pthread_cond_broadcast(&thread->sync_cond); - } if (thd->killed) { thread->killed = TRUE; diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index dc02d0b7d11..4c60ef14703 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -179,7 +179,7 @@ int spider_trx_another_lock_tables( spider_string sql_str(sql_buf, sizeof(sql_buf), system_charset_info); DBUG_ENTER("spider_trx_another_lock_tables"); SPIDER_BACKUP_DASTATUS; - sql_str.init_calc_mem(188); + sql_str.init_calc_mem(SPD_MID_TRX_ANOTHER_LOCK_TABLES_1); sql_str.length(0); memset((void*)&tmp_spider, 0, sizeof(ha_spider)); memset((void*)&tmp_share, 0, sizeof(SPIDER_SHARE)); @@ -500,7 +500,7 @@ int spider_create_trx_alter_table( share_alter = &share->alter_table; if (!(alter_table = (SPIDER_ALTER_TABLE *) - spider_bulk_malloc(spider_current_trx, 55, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_TRX_ALTER_TABLE_1, MYF(MY_WME | MY_ZEROFILL), &alter_table, (uint) (sizeof(*alter_table)), &tmp_name, (uint) (sizeof(char) * (share->table_name_length + 1)), @@ -1191,7 +1191,7 @@ SPIDER_TRX *spider_get_trx( ) { DBUG_PRINT("info",("spider create new trx")); if (!(trx = (SPIDER_TRX *) - spider_bulk_malloc(NULL, 56, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(NULL, SPD_MID_GET_TRX_1, MYF(MY_WME | MY_ZEROFILL), &trx, (uint) (sizeof(*trx)), &tmp_share, (uint) (sizeof(SPIDER_SHARE)), &tmp_wide_handler, (uint) sizeof(SPIDER_WIDE_HANDLER), @@ -1225,7 +1225,7 @@ SPIDER_TRX *spider_get_trx( spider_conn_get_key, 0, 0) ) goto error_init_hash; - spider_alloc_calc_mem_init(trx->trx_conn_hash, 151); + spider_alloc_calc_mem_init(trx->trx_conn_hash, SPD_MID_GET_TRX_2); spider_alloc_calc_mem( thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, trx->trx_conn_hash, @@ -1238,7 +1238,7 @@ SPIDER_TRX *spider_get_trx( spider_conn_get_key, 0, 0) ) goto error_init_another_hash; - spider_alloc_calc_mem_init(trx->trx_another_conn_hash, 152); + spider_alloc_calc_mem_init(trx->trx_another_conn_hash, SPD_MID_GET_TRX_3); spider_alloc_calc_mem( thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, trx->trx_another_conn_hash, @@ -1251,7 +1251,7 @@ SPIDER_TRX *spider_get_trx( (my_hash_get_key) spider_conn_get_key, 0, 0) ) goto error_hs_r_init_hash; - spider_alloc_calc_mem_init(trx->trx_hs_r_conn_hash, 153); + spider_alloc_calc_mem_init(trx->trx_hs_r_conn_hash, SPD_MID_GET_TRX_4); spider_alloc_calc_mem( thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, trx->trx_hs_r_conn_hash, @@ -1263,7 +1263,7 @@ SPIDER_TRX *spider_get_trx( (my_hash_get_key) spider_conn_get_key, 0, 0) ) goto error_hs_w_init_hash; - spider_alloc_calc_mem_init(trx->trx_hs_w_conn_hash, 154); + spider_alloc_calc_mem_init(trx->trx_hs_w_conn_hash, SPD_MID_GET_TRX_5); spider_alloc_calc_mem( thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, trx->trx_hs_w_conn_hash, @@ -1277,7 +1277,7 @@ SPIDER_TRX *spider_get_trx( 0, 0, (my_hash_get_key) spider_conn_get_key, 0, 0) ) goto error_direct_hs_r_init_hash; - spider_alloc_calc_mem_init(trx->trx_direct_hs_r_conn_hash, 155); + spider_alloc_calc_mem_init(trx->trx_direct_hs_r_conn_hash, SPD_MID_GET_TRX_6); spider_alloc_calc_mem( thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, trx->trx_direct_hs_r_conn_hash, @@ -1289,7 +1289,7 @@ SPIDER_TRX *spider_get_trx( 0, 0, (my_hash_get_key) spider_conn_get_key, 0, 0) ) goto error_direct_hs_w_init_hash; - spider_alloc_calc_mem_init(trx->trx_direct_hs_w_conn_hash, 156); + spider_alloc_calc_mem_init(trx->trx_direct_hs_w_conn_hash, SPD_MID_GET_TRX_7); spider_alloc_calc_mem( thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, trx->trx_direct_hs_w_conn_hash, @@ -1303,7 +1303,7 @@ SPIDER_TRX *spider_get_trx( spider_alter_tbl_get_key, 0, 0) ) goto error_init_alter_hash; - spider_alloc_calc_mem_init(trx->trx_alter_table_hash, 157); + spider_alloc_calc_mem_init(trx->trx_alter_table_hash, SPD_MID_GET_TRX_8); spider_alloc_calc_mem( thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, trx->trx_alter_table_hash, @@ -1316,7 +1316,7 @@ SPIDER_TRX *spider_get_trx( spider_trx_ha_get_key, 0, 0) ) goto error_init_trx_ha_hash; - spider_alloc_calc_mem_init(trx->trx_ha_hash, 158); + spider_alloc_calc_mem_init(trx->trx_ha_hash, SPD_MID_GET_TRX_9); spider_alloc_calc_mem( thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL, trx->trx_ha_hash, @@ -1381,7 +1381,7 @@ SPIDER_TRX *spider_get_trx( for (roop_count2 = 0; roop_count2 < (int) trx->tmp_share->link_count; ++roop_count2) { - trx->tmp_spider->result_list.sqls[roop_count2].init_calc_mem(121); + trx->tmp_spider->result_list.sqls[roop_count2].init_calc_mem(SPD_MID_GET_TRX_10); trx->tmp_spider->result_list.sqls[roop_count2].set_charset( trx->tmp_share->access_charset); } @@ -3438,6 +3438,14 @@ int spider_rollback( trx->bulk_access_conn_first = NULL; #endif + /* In case the rollback happens due to failure of LOCK TABLE, we + need to clear the list of tables to lock. */ + for (uint i= 0; i < trx->trx_conn_hash.records; i++) + { + conn= (SPIDER_CONN *) my_hash_element(&trx->trx_conn_hash, i); + conn->db_conn->reset_lock_table_hash(); + } + if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { if (trx->trx_start) @@ -3686,9 +3694,6 @@ int spider_check_trx_and_get_conn( for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) { if ( -/* - spider->conn_kind[roop_count] != SPIDER_CONN_KIND_MYSQL && -*/ share->hs_dbton_ids[spider->conn_link_idx[roop_count]] == SPIDER_DBTON_SIZE ) { @@ -4148,7 +4153,7 @@ int spider_create_trx_ha( if (need_create) { if (!(trx_ha = (SPIDER_TRX_HA *) - spider_bulk_malloc(spider_current_trx, 58, MYF(MY_WME), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_TRX_HA_1, MYF(MY_WME), &trx_ha, (uint) (sizeof(SPIDER_TRX_HA)), &tmp_name, (uint) (sizeof(char *) * (share->table_name_length + 1)), &conn_link_idx, (uint) (sizeof(uint) * share->link_count), diff --git a/strings/ctype-uca.inl b/strings/ctype-uca.inl index dcca88c648b..f068f8f2d61 100644 --- a/strings/ctype-uca.inl +++ b/strings/ctype-uca.inl @@ -336,8 +336,20 @@ MY_FUNCTION_NAME(scanner_next_pad_trim)(my_uca_scanner *scanner, flags & MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES ? my_space_weight(scanner->level) : 0; - res.nchars= 1; (*generated)++; + res.nchars++; /* Count all ignorable characters and the padded space */ + if (res.nchars > nchars) + { + /* + We scanned a number of ignorable characters at the end of the + string and reached the "nchars" limit, so the virtual padded space + does not fit. This is possible with CONCAT('a', x'00') with + nchars=2 on the second iteration when we scan the x'00'. + */ + if (scanner->cs->state & MY_CS_NOPAD) + res.weight= 0; + res.nchars= (uint) nchars; + } } else if (res.nchars > nchars) { diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in index c9f78870619..1af0106e929 100644 --- a/support-files/mariadb.service.in +++ b/support-files/mariadb.service.in @@ -138,6 +138,12 @@ PrivateTmp=false TimeoutStartSec=900 TimeoutStopSec=900 +# Set the maximium number of tasks (threads) to 99% of what the system can +# handle as set by the kernel, reserve the 1% for a remote ssh connection, +# some monitoring, or that backup cron job. Without the directive this would +# be 15% (see DefaultTasksMax in systemd man pages). +TasksMax=99% + ## ## Options previously available to be set via [mysqld_safe] ## that now needs to be set by systemd config files as mysqld_safe diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index 1160bf62167..8cb3ab2a4d7 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -252,6 +252,12 @@ PrivateTmp=false TimeoutStartSec=900 TimeoutStopSec=900 +# Set the maximium number of tasks (threads) to 99% of what the system can +# handle as set by the kernel, reserve the 1% for a remote ssh connection, +# some monitoring, or that backup cron job. Without the directive this would +# be 15% (see DefaultTasksMax in systemd man pages). +TasksMax=99% + # Controlling how multiple instances are separated. See top of this file. # Note: This service isn't User=mysql by default so we need to be explicit. # It is as an option here as a user may want to use the MYSQLD_MULTI_INSTANCE diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c index 5c0c7ce2354..c9e64678527 100644 --- a/tests/mysql_client_fw.c +++ b/tests/mysql_client_fw.c @@ -1430,6 +1430,14 @@ int main(int argc, char **argv) tests_to_run[i]= NULL; } +#ifdef _WIN32 + /* must be the same in C/C and embedded, 1208 on 64bit, 968 on 32bit */ + compile_time_assert(sizeof(MYSQL) == 60*sizeof(void*)+728); +#else + /* must be the same in C/C and embedded, 1272 on 64bit, 964 on 32bit */ + compile_time_assert(sizeof(MYSQL) == 77*sizeof(void*)+656); +#endif + if (mysql_server_init(embedded_server_arg_count, embedded_server_args, (char**) embedded_server_groups)) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 3fc4fbc7e6b..6ba91c9647d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -21961,6 +21961,45 @@ static void test_mdev_30159() myquery(rc); } +/* + Check that server_status returned after connecting to server + is consistent with the value of autocommit variable. +*/ +static void test_connect_autocommit() +{ + int rc; + my_bool autocommit[]= {0, 1}; + int i; + rc= mysql_query(mysql, "SET @save_autocommit=@@global.autocommit"); + myquery(rc); + for (i= 0; i < 2; i++) + { + MYSQL *con; + char query[100]; + int autocommit_val; + + con= mysql_client_init(NULL); + DIE_UNLESS(con); + autocommit_val = autocommit[i]; + snprintf(query, sizeof(query), "SET global autocommit=%d", autocommit_val); + rc= mysql_query(mysql, query); + myquery(rc); + + if (!(mysql_real_connect(con, opt_host, opt_user, opt_password, current_db, + opt_port, opt_unix_socket, 0))) + { + fprintf(stderr, "Failed to connect to database: Error: %s\n", + mysql_error(con)); + exit(1); + } + DIE_UNLESS(!!(con->server_status & SERVER_STATUS_AUTOCOMMIT) == autocommit_val); + mysql_close(con); + } + rc= mysql_query(mysql, "SET global autocommit=@save_autocommit"); + myquery(rc); +} + + static void test_execute_direct() { #ifndef EMBEDDED_LIBRARY @@ -22396,6 +22435,7 @@ static struct my_tests_st my_tests[]= { { "test_mdev18408", test_mdev18408 }, { "test_mdev20261", test_mdev20261 }, { "test_mdev_30159", test_mdev_30159 }, + { "test_connect_autocommit", test_connect_autocommit}, { "test_execute_direct", test_execute_direct }, { "test_cache_metadata", test_cache_metadata}, { 0, 0 } diff --git a/unittest/strings/strings-t.c b/unittest/strings/strings-t.c index 4f64b8cd06c..0e3b97c261c 100644 --- a/unittest/strings/strings-t.c +++ b/unittest/strings/strings-t.c @@ -1166,6 +1166,19 @@ static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mb3_unicode_ci[]= {{CSTR("ss")}, {CSTR(UTF8_sz)}, 4, TCHAR, 0}, {{CSTR("ss")}, {CSTR(UTF8_sz)}, 100, TCHAR, 0}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 0, TCHAR, 0}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 1, TCHAR, 0}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 2, TCHAR, 0}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 3, TCHAR, 0}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 100, TCHAR, 0}, + + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 0, TCHAR, 0}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 1, TCHAR, 0}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 2, TCHAR, 0}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 3, TCHAR, 0}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 4, TCHAR, 0}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 100, TCHAR, 0}, + {{NULL, 0}, {NULL, 0}, 0, 0, 0} }; @@ -1193,6 +1206,19 @@ static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mb3_unicode_nopad_ci[]= {{CSTR("ss")}, {CSTR(UTF8_sz)}, 4, TVCHAR, 0}, {{CSTR("ss")}, {CSTR(UTF8_sz)}, 100, TVCHAR, 0}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 0, TCHAR, 0}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 1, TCHAR, 0}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 2, TCHAR, -1}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 3, TCHAR, 0}, + {{CSTR("a" "\x01")}, {CSTR(UTF8_auml)}, 100, TCHAR, 0}, + + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 0, TCHAR, 0}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 1, TCHAR, 0}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 2, TCHAR, -1}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 3, TCHAR, -1}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 4, TCHAR, 0}, + {{CSTR("a" "\x01\x01")}, {CSTR(UTF8_auml)}, 100, TCHAR, 0}, + {{NULL, 0}, {NULL, 0}, 0, 0, 0} }; diff --git a/wsrep-lib b/wsrep-lib index 07af42c0528..a5d95f0175f 160000 --- a/wsrep-lib +++ b/wsrep-lib @@ -1 +1 @@ -Subproject commit 07af42c0528139e54a8018975cf55eee3daffab3 +Subproject commit a5d95f0175f10b6127ea039c542725f6c4aa5cb9