diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c97f9827e59..09704ad84d7 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -32,7 +32,8 @@ Without automated tests, future regressions in the expected behavior can't be au If the changes are not amenable to automated testing, please explain why not and carefully describe how to test manually. ## Basing the PR against the correct MariaDB version - [ ] *This is a new feature and the PR is based against the latest MariaDB development branch.* @@ -43,5 +44,5 @@ Tick one of the following boxes [x] to help us understand if the base branch for Maintainers are happy to point out inconsistencies but in order to speed up the review and merge process we ask you to check the CODING standards. --> ## PR quality check -- [ ] I checked the [CODING_STANDARDS.md](https://github.com/MariaDB/server/blob/11.0/CODING_STANDARDS.md) file and my PR conforms to this where appropriate. +- [ ] I checked the [CODING_STANDARDS.md](https://github.com/MariaDB/server/blob/-/CODING_STANDARDS.md) file and my PR conforms to this where appropriate. - [ ] For any trivial modifications to the PR, I am ok with the reviewer making the changes themselves. diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index 4310fb553e7..136602b37bd 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -37,14 +37,21 @@ The commit messages are typically rendered in [Markdown format](https://docs.git When updating your code, please make sure you perform a rebase, not a merge with the latest branch. Pull requests should be a simple fast-forward of the branch they are intended to land on. -The correct way to rebase (if working on top of 10.3 branch): +The correct way to rebase (if working on top of 10.11 branch): ```sh -git fetch upstream/10.3 # This assumes upstream is github.com/MariaDB/server -git rebase upstream/10.3 +git fetch upstream/10.11 # This assumes upstream is github.com/MariaDB/server +git rebase upstream/10.11 git push --force my_branch ``` +### Target branch + +Pull requests should be based against the correct MariaDB version. +New features should be based against the latest MariaDB development branch, which is the current GitHub default branch: https://github.com/MariaDB/server/blob/-/VERSION +Bug fixes should be based against the earliest maintained branch in which the bug can be reproduced. +The earliest maintained branch is found at https://mariadb.org/about/#maintenance-policy. + ## Coding Style (C / C++ files) Everyone has a preferred coding style, there is no real correct style for all projects around the world. diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 4c93da8a7ef..1f4bd6fc7b0 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1166,6 +1166,8 @@ static int install_used_plugin_data_types(void) DYNAMIC_STRING ds_result; const char *query = "SELECT table_comment FROM information_schema.tables" " WHERE table_comment LIKE 'Unknown data type: %'"; + if (opt_systables_only) + return 0; if (init_dynamic_string(&ds_result, "", 512, 512)) die("Out of memory"); run_query(query, &ds_result, TRUE); @@ -1482,7 +1484,12 @@ int main(int argc, char **argv) open_mysql_upgrade_file(); if (opt_check_upgrade) - exit(upgrade_already_done(0) == 0); + { + int upgrade_needed = upgrade_already_done(0); + free_used_memory(); + my_end(my_end_arg); + exit(upgrade_needed == 0); + } /* Find mysqlcheck */ find_tool(mysqlcheck_path, IF_WIN("mariadb-check.exe", "mariadb-check"), self_name); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 9ce588db7ec..061ef114bf1 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -17,7 +17,7 @@ /* maintenance of mysql databases */ -#define VER "9.1" +#define VER "10.0" #include "client_priv.h" #include #include /* because of signal() */ @@ -36,12 +36,12 @@ char *host= NULL, *user= 0, *opt_password= 0, *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; ulonglong last_values[MAX_MYSQL_VAR+100]; static int interval=0; -static my_bool option_force=0,interrupted=0,new_line=0, - opt_compress= 0, opt_local= 0, opt_relative= 0, opt_verbose= 0, - tty_password= 0, opt_nobeep, opt_shutdown_wait_for_slaves= 0; +static my_bool option_force=0,interrupted=0,new_line=0, opt_compress= 0, + opt_local= 0, opt_relative= 0, tty_password= 0, opt_nobeep, + opt_shutdown_wait_for_slaves= 0, opt_not_used; static my_bool debug_info_flag= 0, debug_check_flag= 0; static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations; -static uint opt_count_iterations= 0, my_end_arg; +static uint opt_count_iterations= 0, my_end_arg, opt_verbose= 0; static ulong opt_connect_timeout, opt_shutdown_timeout; static char * unix_port=0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; @@ -187,8 +187,10 @@ static struct my_option my_long_options[] = {"user", 'u', "User for login if not current user.", &user, &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"verbose", 'v', "Write more information.", &opt_verbose, - &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"verbose", 'v', "Write more information." + "Using it will print more information for 'processlist." + "Using it 2 times will print even more information for 'processlist'.", + &opt_not_used, &opt_not_used, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_UINT, @@ -277,6 +279,11 @@ get_one_option(const struct my_option *opt, const char *argument, case 'I': /* Info */ usage(); exit(0); + case 'v': /* --verbose */ + opt_verbose++; + if (argument == disabled_my_option) + opt_verbose= 0; + break; case OPT_CHARSETS_DIR: #if MYSQL_VERSION_ID > 32300 charsets_dir = argument; @@ -441,6 +448,7 @@ int main(int argc,char *argv[]) if (error > 0) break; + error= -error; /* don't exit with negative error codes */ /* Command was well-formed, but failed on the server. Might succeed on retry (if conditions on server change etc.), but needs --force @@ -806,10 +814,17 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { MYSQL_RES *result; MYSQL_ROW row; + const char *query; - if (mysql_query(mysql, (opt_verbose ? "show full processlist" : - "show processlist")) || - !(result = mysql_store_result(mysql))) + if (!opt_verbose) + query= "show processlist"; + else if (opt_verbose == 1) + query= "show full processlist"; + else + query= "select * from information_schema.processlist where id != connection_id()"; + + if (mysql_query(mysql, query) || + !(result = mysql_store_result(mysql))) { my_printf_error(0, "process list failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1129,24 +1144,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) else if (mysql_query(mysql,buff)) { - if (mysql_errno(mysql)!=1290) - { - my_printf_error(0,"unable to change password; error: '%s'", - error_flags, mysql_error(mysql)); - } - else - { - /* - We don't try to execute 'update mysql.user set..' - because we can't perfectly find out the host - */ - my_printf_error(0,"\n" - "You cannot use 'password' command as mariadbd runs\n" - " with grant tables disabled (was started with" - " --skip-grant-tables).\n" - "Use: \"mysqladmin flush-privileges password '*'\"" - " instead", error_flags); - } + my_printf_error(0,"unable to change password; error: '%s'", + error_flags, mysql_error(mysql)); ret = -1; } password_done: diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index bd33c15dca1..09e01f7bff5 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -3422,8 +3422,13 @@ int main(int argc, char** argv) if (tmpdir.list) free_tmpdir(&tmpdir); - if (result_file && result_file != stdout) - my_fclose(result_file, MYF(0)); + if (result_file) + { + if (result_file != stdout) + my_fclose(result_file, MYF(0)); + else + fflush(result_file); + } /* Ensure the GTID state is correct. If not, end in error. diff --git a/client/mysqldump.c b/client/mysqldump.c index 8fdeb3bfd37..1c6deb1b9fa 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1912,8 +1912,13 @@ static FILE* open_sql_file_for_table(const char* table, int flags) static void free_resources() { - if (md_result_file && md_result_file != stdout) - my_fclose(md_result_file, MYF(0)); + if (md_result_file) + { + if (md_result_file != stdout) + my_fclose(md_result_file, MYF(0)); + else + fflush(md_result_file); + } if (get_table_name_result) mysql_free_result(get_table_name_result); if (routine_res) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 4b34ef63615..e2b229f3756 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 @@ -88,6 +91,8 @@ static my_bool non_blocking_api_enabled= 0; #define CLOSED_CONNECTION "-closed_connection-" +#define dynstr_append DO_NO_USE + #ifndef HAVE_SETENV static int setenv(const char *name, const char *value, int overwrite); #endif @@ -1730,7 +1735,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; } @@ -1866,7 +1871,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,14 +1881,14 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) if (strncmp(arg, "--", 2) == 0) dynstr_append_os_quoted(&ds_cmdline, arg, NullS); else - dynstr_append(&ds_cmdline, arg); - dynstr_append(&ds_cmdline, " "); + dynstr_append_mem(&ds_cmdline, arg, strlen(arg)); + 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)); @@ -2018,8 +2023,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" @@ -2029,17 +2034,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(&ds_tmp, filename1); - dynstr_append(&ds_tmp, " >>>\n"); + dynstr_append_mem(&ds_tmp, STRING_WITH_LEN(" --- ")); + dynstr_append_mem(&ds_tmp, filename1, strlen(filename1)); + dynstr_append_mem(&ds_tmp, STRING_WITH_LEN(" >>>\n")); cat_file(&ds_tmp, filename1); - dynstr_append(&ds_tmp, "<<<\n --- "); - dynstr_append(&ds_tmp, filename1); - dynstr_append(&ds_tmp, " >>>\n"); + dynstr_append_mem(&ds_tmp, STRING_WITH_LEN("<<<\n --- ")); + dynstr_append_mem(&ds_tmp, filename1, strlen(filename1)); + 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) @@ -2819,9 +2825,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); } @@ -3292,13 +3298,15 @@ static int replace(DYNAMIC_STRING *ds_str, { DYNAMIC_STRING ds_tmp; const char *start= strstr(ds_str->str, search_str); + size_t prefixlen= start - ds_str->str; if (!start) return 1; init_dynamic_string(&ds_tmp, "", ds_str->length + replace_len, 256); - dynstr_append_mem(&ds_tmp, ds_str->str, start - ds_str->str); + dynstr_append_mem(&ds_tmp, ds_str->str, prefixlen); dynstr_append_mem(&ds_tmp, replace_str, replace_len); - dynstr_append(&ds_tmp, start + search_len); + dynstr_append_mem(&ds_tmp, start + search_len, + ds_str->length - prefixlen - search_len); dynstr_set(ds_str, ds_tmp.str); dynstr_free(&ds_tmp); return 0; @@ -3413,7 +3421,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'", @@ -3625,9 +3633,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")); } } @@ -3803,7 +3811,7 @@ void do_remove_files_wildcard(struct st_command *command) wild_compare(file->name, ds_wild.str, 0)) continue; ds_file_to_remove.length= directory_length; - dynstr_append(&ds_file_to_remove, file->name); + dynstr_append_mem(&ds_file_to_remove, file->name, strlen(file->name)); DBUG_PRINT("info", ("removing file: %s", ds_file_to_remove.str)); if ((error= (my_delete(ds_file_to_remove.str, MYF(MY_WME)) != 0))) sys_errno= my_errno; @@ -4093,7 +4101,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); @@ -7703,7 +7711,7 @@ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field, } else { - dynstr_append(ds, field->name); + dynstr_append_mem(ds, field->name, strlen(field->name)); dynstr_append_mem(ds, "\t", 1); replace_dynstr_append_mem(ds, val, len); dynstr_append_mem(ds, "\n", 1); @@ -7814,9 +7822,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 ; @@ -7875,13 +7884,13 @@ void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows, const char *info) { char buf[40], buff2[21]; - sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2)); - dynstr_append(ds, buf); + size_t len= sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2)); + dynstr_append_mem(ds, buf, len); if (info) { - dynstr_append(ds, "info: "); - dynstr_append(ds, info); - dynstr_append_mem(ds, "\n", 1); + dynstr_append_mem(ds, STRING_WITH_LEN("info: ")); + dynstr_append_mem(ds, info, strlen(info)); + dynstr_append_mem(ds, STRING_WITH_LEN("\n")); } } @@ -7927,18 +7936,19 @@ 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]); + dynstr_append_mem(ds, trking_info_desc[type], + strlen(trking_info_desc[type])); } 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 @@ -7947,16 +7957,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 */ } @@ -8356,7 +8366,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(); @@ -8435,6 +8446,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 @@ -8455,11 +8545,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", @@ -8475,7 +8571,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"); @@ -8489,6 +8585,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 */ @@ -8524,10 +8626,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)) { @@ -8535,12 +8639,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); + } } /* @@ -8553,6 +8677,8 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, goto end; } + DBUG_ASSERT(ds->length == 0); + int err; do { @@ -8563,75 +8689,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 @@ -8643,7 +8776,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 */ @@ -8675,7 +8807,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); @@ -9187,11 +9327,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; @@ -9204,10 +9347,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 */ @@ -9237,11 +9380,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 @@ -9255,9 +9398,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 */ @@ -9312,7 +9455,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); @@ -9368,9 +9511,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; } /* @@ -9391,20 +9534,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) @@ -9427,11 +9570,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; } @@ -9690,7 +9833,7 @@ void mark_progress(struct st_command* command __attribute__((unused)), dynstr_append_mem(&ds_progress, "\t", 1); /* Filename */ - dynstr_append(&ds_progress, cur_file->file_name); + dynstr_append_mem(&ds_progress, cur_file->file_name, strlen(cur_file->file_name)); dynstr_append_mem(&ds_progress, ":", 1); /* Line in file */ @@ -9888,7 +10031,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); @@ -10316,7 +10459,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; } @@ -10329,7 +10472,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); @@ -11991,8 +12134,8 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, for (i= 0; i < lines.elements ; i++) { const char **line= dynamic_element(&lines, i, const char**); - dynstr_append(ds, *line); - dynstr_append(ds, "\n"); + dynstr_append_mem(ds, *line, strlen(*line)); + 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/autobake-deb.sh b/debian/autobake-deb.sh index 92c6b72a96e..9916ca18953 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -121,10 +121,6 @@ in # there is intentionally no customizations whatsoever. ;; # Ubuntu - "bionic") - remove_rocksdb_tools - [ "$architecture" != amd64 ] && disable_pmem - ;& "focal") replace_uring_with_aio disable_libfmt diff --git a/debian/control b/debian/control index b308e11ac3c..3ed0857d1bd 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: mariadb 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/debian/libmariadb3.symbols b/debian/libmariadb3.symbols index c79676472c6..f7dab874378 100644 --- a/debian/libmariadb3.symbols +++ b/debian/libmariadb3.symbols @@ -1,6 +1,7 @@ libmariadb.so.3 libmariadb3 #MINVER# * Build-Depends-Package: libmariadb-dev libmariadb_3@libmariadb_3 3.0.0 + libmariadb_3_3_5@libmariadb_3_3_5 3.3.5 libmariadbclient_18@libmariadbclient_18 3.0.0 libmysqlclient_18@libmysqlclient_18 3.0.0 ma_pvio_register_callback@libmariadb_3 3.0.0 @@ -8,6 +9,7 @@ libmariadb.so.3 libmariadb3 #MINVER# mariadb_connection@libmariadb_3 3.0.0 mariadb_convert_string@libmariadb_3 3.0.0 mariadb_deinitialize_ssl@libmariadb_3 3.0.0 + mariadb_field_attr@libmariadb_3 3.3.1 mariadb_free_rpl_event@libmariadb_3 3.1.0 mariadb_get_charset_by_name@libmariadb_3 3.0.0 mariadb_get_charset_by_nr@libmariadb_3 3.0.0 @@ -15,8 +17,12 @@ libmariadb.so.3 libmariadb3 #MINVER# mariadb_get_infov@libmariadb_3 3.0.0 mariadb_reconnect@libmariadb_3 3.0.0 mariadb_rpl_close@libmariadb_3 3.1.0 + mariadb_rpl_errno@libmariadb_3_3_5 3.3.2 + mariadb_rpl_error@libmariadb_3_3_5 3.3.2 + mariadb_rpl_extract_rows@libmariadb_3_3_5 3.3.2 mariadb_rpl_fetch@libmariadb_3 3.1.0 mariadb_rpl_get_optionsv@libmariadb_3 3.1.0 + mariadb_rpl_init_ex@libmariadb_3 3.3.0 mariadb_rpl_open@libmariadb_3 3.1.0 mariadb_rpl_optionsv@libmariadb_3 3.1.0 mariadb_stmt_execute_direct@libmariadb_3 3.0.0 diff --git a/extra/mariabackup/ds_local.cc b/extra/mariabackup/ds_local.cc index 4c3016ec8f7..f86612b951a 100644 --- a/extra/mariabackup/ds_local.cc +++ b/extra/mariabackup/ds_local.cc @@ -28,6 +28,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA #include #endif +#ifdef HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE +#include +#endif + typedef struct { File fd; my_bool init_ibd_done; @@ -160,9 +164,18 @@ static int write_compressed(File fd, uchar *data, size_t len, size_t pagesize) if (datasize < n_bytes) { /* This punches a "hole" in the file. */ size_t hole_bytes = n_bytes - datasize; - if (my_seek(fd, hole_bytes, MY_SEEK_CUR, MYF(MY_WME | MY_NABP)) - == MY_FILEPOS_ERROR) - return 1; + my_off_t off = my_seek(fd, hole_bytes, MY_SEEK_CUR, MYF(MY_WME | MY_NABP)); + if (off == MY_FILEPOS_ERROR) + return 1; +#ifdef HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE + /* punch holes harder for filesystems (like XFS) that + heuristically decide whether leave a hole after the + above or not based on the current access pattern + (which is sequential write and not at all typical for + what InnoDB will be doing with the file later */ + fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + off - hole_bytes, hole_bytes); +#endif } written += n_bytes; ptr += n_bytes; diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 3c530e9aef3..a1ec7fb5f8f 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -127,7 +127,8 @@ int sd_notifyf() { return 0; } int sys_var_init(); /* === xtrabackup specific options === */ -char xtrabackup_real_target_dir[FN_REFLEN] = "./mariadb_backup_files/"; +#define DEFAULT_TARGET_DIR "./mariadb_backup_files/" +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; @@ -410,6 +411,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]; @@ -1269,22 +1273,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}, @@ -1405,7 +1412,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}, @@ -1699,8 +1708,11 @@ struct my_option xb_server_options[] = "Path to InnoDB log files.", &srv_log_group_home_dir, &srv_log_group_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_max_dirty_pages_pct", OPT_INNODB_MAX_DIRTY_PAGES_PCT, - "Percentage of dirty pages allowed in bufferpool.", (G_PTR*) &srv_max_buf_pool_modified_pct, - (G_PTR*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, + "Percentage of dirty pages allowed in bufferpool.", + (G_PTR*) &srv_max_buf_pool_modified_pct, + (G_PTR*) &srv_max_buf_pool_modified_pct, 0, GET_DOUBLE, REQUIRED_ARG, + (longlong)getopt_double2ulonglong(90), (longlong)getopt_double2ulonglong(0), + getopt_double2ulonglong(100), 0, 0, 0}, {"innodb_use_native_aio", OPT_INNODB_USE_NATIVE_AIO, "Use native AIO if supported on this platform.", (G_PTR*) &srv_use_native_aio, @@ -1886,7 +1898,7 @@ static int prepare_export() IF_WIN("\"","") "\"%s\" --mysqld \"%s\"" " --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --innodb --innodb-fast-shutdown=0 --loose-partition" - " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" + " --innodb-buffer-pool-size=%llu" " --console --skip-log-error --skip-log-bin --bootstrap %s< " BOOTSTRAP_FILENAME IF_WIN("\"",""), mariabackup_exe, @@ -1900,7 +1912,7 @@ static int prepare_export() IF_WIN("\"","") "\"%s\" --mysqld" " --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --innodb --innodb-fast-shutdown=0 --loose-partition" - " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" + " --innodb-buffer-pool-size=%llu" " --console --log-error= --skip-log-bin --bootstrap %s< " BOOTSTRAP_FILENAME IF_WIN("\"",""), mariabackup_exe, @@ -2448,6 +2460,7 @@ xtrabackup_read_metadata(char *filename) { FILE *fp; my_bool r = TRUE; + int t; fp = fopen(filename,"r"); if(!fp) { @@ -2478,6 +2491,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); @@ -2527,11 +2543,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)); } /*********************************************************************** @@ -5966,6 +5984,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) @@ -6151,6 +6189,20 @@ error: 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. */ @@ -6352,7 +6404,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", "*", "*", @@ -6373,7 +6425,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); } @@ -6586,9 +6638,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 53784a3fb56..d091c4744ab 100644 --- a/extra/mariabackup/xtrabackup.h +++ b/extra/mariabackup/xtrabackup.h @@ -171,7 +171,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/extra/my_print_defaults.c b/extra/my_print_defaults.c index 6fc9f3f4d9b..c15752aa23e 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -170,6 +170,7 @@ int main(int argc, char **argv) if ((error= load_defaults(config_file, (const char **) load_default_groups, &count, &arguments))) { + my_free(load_default_groups); my_end(0); if (error == 4) return 0; 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 9d13989d1fe..55d3cc0aeca 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -448,7 +448,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; @@ -1866,6 +1867,9 @@ my_well_formed_length(CHARSET_INFO *cs, const char *b, const char *e, #include "t_ctype.h" #endif +int my_wc_mb_utf8mb4_bmp_only(CHARSET_INFO *cs, my_wc_t wc, uchar *r, + uchar *e); + #ifdef __cplusplus } #endif diff --git a/include/my_alloc.h b/include/my_alloc.h index caa4be8f0e5..0b777437dbe 100644 --- a/include/my_alloc.h +++ b/include/my_alloc.h @@ -25,6 +25,8 @@ #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 @@ -53,10 +55,6 @@ typedef struct st_mem_root unsigned short first_block_usage; unsigned short flags; -#ifdef PROTECT_STATEMENT_MEMROOT - int read_only; -#endif - void (*error_handler)(void); PSI_memory_key psi_key; diff --git a/include/my_compare.h b/include/my_compare.h index 62bb6ac0ed4..1d66e51ef83 100644 --- a/include/my_compare.h +++ b/include/my_compare.h @@ -110,8 +110,135 @@ static inline void set_rec_bits(uint16 bits, uchar *ptr, uchar ofs, uint len) #define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \ set_rec_bits(0, bit_ptr, bit_ofs, bit_len) -extern int ha_compare_text(CHARSET_INFO *, const uchar *, size_t, - const uchar *, size_t , my_bool); + +/* + Compare two VARCHAR values. + @param charset_info - The character set and collation + @param a - The pointer to the first string + @param a_length - The length of the first string + @param b - The pointer to the second string + @param b_length - The length of the second string + @param b_is_prefix - Whether "b" is a prefix of "a", + e.g. in a prefix key (partial length key). + @returns - The result of comparison + + - If "b_is_prefix" is FALSE, then the two strings are compared + taking into account the PAD SPACE/NO PAD attribute of the collation. + + - If "b_is_prefix" is TRUE, then trailing spaces are compared in NO PAD style. + This is done e.g. when we compare a column value to its prefix key value + (the value of "a" to the value of "key_a"): + CREATE TABLE t1 (a VARCHAR(10), KEY(key_a(5)); +*/ +static inline int ha_compare_char_varying(CHARSET_INFO *charset_info, + const uchar *a, size_t a_length, + const uchar *b, size_t b_length, + my_bool b_is_prefix) +{ + if (!b_is_prefix) + return charset_info->coll->strnncollsp(charset_info, a, a_length, + b, b_length); + return charset_info->coll->strnncoll(charset_info, + a, a_length, + b, b_length, TRUE/*prefix*/); +} + + +/* + Compare two CHAR values of the same declared character length, + e.g. CHAR(5) to CHAR(5). + + @param charset_info - The character set and collation + @param a - The pointer to the first string + @param a_length - The length of the first string + @param b - The pointer to the second string + @param b_length - The length of the second string + @param nchars - The declared length (in characters) + @param b_is_prefix - Whether "b" is a prefix of "a", + e.g. in a prefix key (partial length key). + @returns - The result of comparison + + - If "b_is_prefix" is FALSE, then the two strings are compared + taking into account the PAD SPACE/NO PAD attribute of the collation. + Additionally, this function assumes that the underlying storage could + optionally apply trailing space compression, so values can come into this + comparison function in different states: + - all trailing spaces removed + - some trailing spaced removed + - no trailing spaces removed (exactly "nchars" characters on the two sides) + This function virtually reconstructs trailing spaces up to the defined + length specified in "nchars". + If either of the sides have more than "nchar" characters, + then only leftmost "nchar" characters are compared. + + - If "b_is_prefix" is TRUE, then trailing spaces are compared in NO PAD style. + This is done e.g. when we compare a column value to its prefix key value + (the value of "a" to the value of "key_a"): + CREATE TABLE t1 (a CHAR(10), KEY(key_a(5)); +*/ +static inline int ha_compare_char_fixed(CHARSET_INFO *charset_info, + const uchar *a, size_t a_length, + const uchar *b, size_t b_length, + size_t nchars, + my_bool b_is_prefix) +{ + if (!b_is_prefix) + return charset_info->coll->strnncollsp_nchars(charset_info, + a, a_length, + b, b_length, + nchars, + MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES); + return charset_info->coll->strnncoll(charset_info, + a, a_length, + b, b_length, TRUE/*prefix*/); +} + + +/* + A function to compare words of a text. + This is a common operation in full-text search: + SELECT MATCH (title) AGAINST ('word') FROM t1; +*/ +static inline int ha_compare_word(CHARSET_INFO *charset_info, + const uchar *a, size_t a_length, + const uchar *b, size_t b_length) +{ + return charset_info->coll->strnncollsp(charset_info, + a, a_length, + b, b_length); +} + + +/* + A function to compare a word of a text to a word prefix. + This is a common operation in full-text search: + SELECT MATCH (title) AGAINST ('wor*' IN BOOLEAN MODE) FROM t1; +*/ +static inline int ha_compare_word_prefix(CHARSET_INFO *charset_info, + const uchar *a, size_t a_length, + const uchar *b, size_t b_length) +{ + return charset_info->coll->strnncoll(charset_info, + a, a_length, + b, b_length, + TRUE/*b_is_prefix*/); +} + + +/* + Compare words (full match or prefix match), e.g. for full-text search. +*/ +static inline int ha_compare_word_or_prefix(CHARSET_INFO *charset_info, + const uchar *a, size_t a_length, + const uchar *b, size_t b_length, + my_bool b_is_prefix) +{ + if (!b_is_prefix) + return ha_compare_word(charset_info, a, a_length, b, b_length); + return ha_compare_word_prefix(charset_info, a, a_length, b, b_length); +} + + extern int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a, const uchar *b, uint key_length, uint nextflag, uint *diff_pos); diff --git a/include/my_pthread.h b/include/my_pthread.h index 9d5ace4ec67..f89e6ad132b 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -666,15 +666,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 25fedb63b8f..af509c7df45 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -898,6 +898,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 a66dcc7bd02..486f57fbcd9 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -268,7 +268,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 */ @@ -290,7 +289,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; diff --git a/include/mysql/service_sql.h b/include/mysql/service_sql.h index cb3eec3c626..a4a61cc0f47 100644 --- a/include/mysql/service_sql.h +++ b/include/mysql/service_sql.h @@ -121,5 +121,3 @@ MYSQL *mysql_real_connect_local(MYSQL *mysql); #endif #endif /*MYSQL_SERVICE_SQL */ - - diff --git a/libmariadb b/libmariadb index c0ddc2c8cff..458a4396b44 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit c0ddc2c8cff30aebbedc5ae175e435c2c6fec646 +Subproject commit 458a4396b443dcefedcf464067560078aa09d8b4 diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index 2042f7fe321..b8f805be518 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -51,6 +51,7 @@ ENDIF() SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc libmysql.c ../sql-common/errmsg.c ../sql-common/client.c + ../sql/cset_narrowing.cc ../sql-common/my_user.c ../sql-common/pack.c ../sql-common/client_plugin.c ../sql/password.c ../sql/discover.cc ../sql/derror.cc diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index d4edd24291b..c22127f0807 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -459,6 +459,7 @@ static int emb_read_change_user_result(MYSQL *mysql) 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); @@ -470,6 +471,7 @@ static void emb_on_close_free(MYSQL *mysql) } } + MYSQL_METHODS embedded_methods= { emb_read_query_result, @@ -705,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; @@ -1446,4 +1447,3 @@ int vprint_msg_to_log(enum loglevel level __attribute__((unused)), } return 0; } - diff --git a/man/innochecksum.1 b/man/innochecksum.1 index f149a5cc2d4..ae7a5b03523 100644 --- a/man/innochecksum.1 +++ b/man/innochecksum.1 @@ -34,7 +34,7 @@ CHECK TABLE to check tables within the tablespace\&. .PP If checksum mismatches are found, you would normally restore the tablespace from backup or start the server and attempt to use -\fBmysqldump\fR +\fBmariadb-dump\fR to make a backup of the tables within the tablespace\&. .PP Invoke @@ -75,9 +75,9 @@ Displays help and exits\&. .sp -1 .IP \(bu 2.3 .\} -\fB\-c, --count\fR +\fB\-a \fR\fB\fInum\fB, --allow-mismatches=#\fR .sp -Print a count of the number of pages in the file\&. +Maximum checksum mismatch allowed before innochecksum terminates. Defaults to 0, which terminates on the first mismatch\&. .RE .sp .RS 4 @@ -88,9 +88,9 @@ Print a count of the number of pages in the file\&. .sp -1 .IP \(bu 2.3 .\} -\fB\-d, --debug\fR +\fB\-c, --count\fR .sp -Debug mode; prints checksums for each page\&. +Print a count of the number of pages in the file\&. .RE .sp .RS 4 @@ -140,7 +140,7 @@ Synonym for \fB--help\fR\&. .sp -1 .IP \(bu 2.3 .\} -\fB\-l, --leaf\fR +\fB\-f, --leaf\fR .sp Examine leaf index pages\&. .RE @@ -153,6 +153,19 @@ Examine leaf index pages\&. .sp -1 .IP \(bu 2.3 .\} +\fB\-l \fR\fB\fIfn\fB, --log=fn\fR\fR +.sp +Log output to the specified filename, fn\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} \fB\-m \fR\fB\fInum\fB, --merge=#\fR\fR .sp Leaf page count if merge given number of consecutive pages\&. @@ -166,6 +179,19 @@ Leaf page count if merge given number of consecutive pages\&. .sp -1 .IP \(bu 2.3 .\} +\fB\-n, --no-check\fR\fR +.sp +Ignore the checksum verification. Until MariaDB 10.6, must be used with the --write option\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} \fB\-p \fR\fB\fInum\fB, --page-num=#\fR\fR .sp Check only this page number\&. @@ -179,6 +205,32 @@ Check only this page number\&. .sp -1 .IP \(bu 2.3 .\} +\fB\-D \fR\fB\fIname\fB, --page-type-dump=name\fR\fR +.sp +Dump the page type info for each page in a tablespace\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fB\-S, --page-type-summary\fR\fR +.sp +Display a count of each page type in a tablespace\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} \fB\-s \fR\fB\fInum\fB, --start-page\fR\fR .sp Start at this page number\&. @@ -205,6 +257,32 @@ Skip corrupt pages\&. .sp -1 .IP \(bu 2.3 .\} +\fB\-C \fR\fB\fIname\fB, --strict-check=name\fR\fR +.sp +Specify the strict checksum algorithm. One of: crc32, innodb, none. If not specified, validates against innodb, crc32 and none. Removed in MariaDB 10.6\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fB\-w \fR\fB\fIname\fB, --write=name\fR\fR +.sp +Rewrite the checksum algorithm. One of crc32, innodb, none. An exclusive lock is obtained during use. Use in conjunction with the -no-check option to rewrite an invalid checksum. Removed in MariaDB 10.6\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} \fB\-v, --verbose\fR .sp Verbose mode; print a progress indicator every five seconds\&. @@ -225,7 +303,7 @@ Displays version information and exits\&. .SH "COPYRIGHT" .br .PP -Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2020 MariaDB Foundation +Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2023 MariaDB Foundation .PP This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. .PP diff --git a/mysql-test/README b/mysql-test/README index b2f9979458e..9dc5c6e5220 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/ctype_nopad_prefix_unique.inc b/mysql-test/include/ctype_nopad_prefix_unique.inc index b25128e9fef..ec5bda0eb3a 100644 --- a/mysql-test/include/ctype_nopad_prefix_unique.inc +++ b/mysql-test/include/ctype_nopad_prefix_unique.inc @@ -58,11 +58,6 @@ DROP TABLE t1; # CHAR -# MyISAM is buggy on CHAR+BTREE+UNIQUE+PREFIX (see MDEV-30048), disable for now -# Other engines work fine - -if (`SELECT UPPER(@@storage_engine) != 'MYISAM'`) -{ EXECUTE IMMEDIATE REPLACE( 'CREATE TABLE t1 ( ' ' a CHAR(20) COLLATE ,' @@ -72,7 +67,6 @@ SHOW CREATE TABLE t1; INSERT INTO t1 VALUES ('ss '); INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/; DROP TABLE t1; -} EXECUTE IMMEDIATE REPLACE( 'CREATE TABLE t1 ( ' diff --git a/mysql-test/include/ctype_utf8mb3_uca_char.inc b/mysql-test/include/ctype_utf8mb3_uca_char.inc new file mode 100644 index 00000000000..4540416a6ed --- /dev/null +++ b/mysql-test/include/ctype_utf8mb3_uca_char.inc @@ -0,0 +1,54 @@ +--echo # +--echo # MDEV-30048 Prefix keys for CHAR work differently for MyISAM vs InnoDB +--echo # + +SET NAMES utf8mb3; + +# +# Engines have different conditions based on the column size +# determining when to use trailing space compressions in key values, +# so let's test different column sizes for better coverage. +# + + +# +# CHAR(10) +# + +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; + +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(2))); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; + +# +# CHAR(120) +# + +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; + +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(100))); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; + +--echo # +--echo # MDEV-30050 Inconsistent results of DISTINCT with NOPAD +--echo # + +CREATE TABLE t1 (c CHAR(100) COLLATE utf8mb3_unicode_nopad_ci); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('ss'),('ß'); +SET big_tables=0; +SELECT DISTINCT c FROM t1; +SET big_tables=1; +SELECT DISTINCT c FROM t1; +DROP TABLE t1; +SET big_tables=DEFAULT; diff --git a/mysql-test/include/delete_anonymous_users.inc b/mysql-test/include/delete_anonymous_users.inc index 704e74ae4a3..cc44a01fe8d 100644 --- a/mysql-test/include/delete_anonymous_users.inc +++ b/mysql-test/include/delete_anonymous_users.inc @@ -1,7 +1,7 @@ # Remove anonymous users added by add_anonymous_users.inc disable_warnings; disable_query_log; -DELETE FROM mysql.user where host='localhost' and user=''; +DELETE FROM mysql.global_priv where host='localhost' and user=''; FLUSH PRIVILEGES; enable_query_log; enable_warnings; diff --git a/mysql-test/include/empty_string_literal.inc b/mysql-test/include/empty_string_literal.inc index 9ccedde6dce..5857c26d4ee 100644 --- a/mysql-test/include/empty_string_literal.inc +++ b/mysql-test/include/empty_string_literal.inc @@ -1,6 +1,8 @@ SET SESSION character_set_connection=latin2; SET SESSION character_set_client=cp1250; +--disable_service_connection + --echo # --echo # Test litteral --echo # @@ -129,3 +131,5 @@ EXPLAIN EXTENDED SELECT ''; EXPLAIN EXTENDED SELECT _latin1''; EXPLAIN EXTENDED SELECT N''; EXPLAIN EXTENDED SELECT '' ''; + +--enable_service_connection diff --git a/mysql-test/include/explain_non_select.inc b/mysql-test/include/explain_non_select.inc index 6caa093aab2..c7bf68ff546 100644 --- a/mysql-test/include/explain_non_select.inc +++ b/mysql-test/include/explain_non_select.inc @@ -310,6 +310,19 @@ INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), --source include/explain_utils.inc DROP TABLE t1; +--echo #30a +--echo # +--echo # MDEV-32957 Unusable key notes report wrong predicates for > and >= +--echo # +CREATE TABLE t1(a INT, i CHAR(2), INDEX(i(1))); +INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), + (20),(21),(22),(23),(24),(25),(26),(27),(28),(29), + (30),(31),(32),(33),(34),(35); +--let $query = DELETE FROM t1 WHERE i >= 10 AND i < 18 ORDER BY i LIMIT 5 +--let $select = SELECT * FROM t1 WHERE i >= 10 AND i < 18 ORDER BY i LIMIT 5 +--source include/explain_utils.inc +DROP TABLE t1; + --echo #31 CREATE TABLE t1 (i INT); INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc index c5a60196488..e42645fad74 100644 --- a/mysql-test/include/icp_tests.inc +++ b/mysql-test/include/icp_tests.inc @@ -162,7 +162,7 @@ INSERT INTO t1 VALUES --echo --echo # Execute select with invalid timestamp, desc ordering SELECT * -FROM t1 +FROM t1 FORCE INDEX(PRIMARY) WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; @@ -171,7 +171,7 @@ LIMIT 2; --echo # Should use index condition EXPLAIN SELECT * -FROM t1 +FROM t1 FORCE INDEX(PRIMARY) WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; @@ -458,6 +458,7 @@ INSERT INTO t2 VALUES (11,1); INSERT INTO t2 VALUES (12,2); INSERT INTO t2 VALUES (15,4); +analyze table t1,t2 persistent for all; set @save_optimizer_switch= @@optimizer_switch; set optimizer_switch='semijoin=off'; @@ -729,6 +730,7 @@ INSERT INTO t2 VALUES ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w'); insert into t2 select seq from seq_1_to_100; +analyze table t1,t2 persistent for all; SET SESSION optimizer_switch='index_condition_pushdown=off'; --replace_column 9 # EXPLAIN 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/maria_empty_logs.inc b/mysql-test/include/maria_empty_logs.inc index a4f893d7fd4..24b3e3e6425 100644 --- a/mysql-test/include/maria_empty_logs.inc +++ b/mysql-test/include/maria_empty_logs.inc @@ -11,6 +11,7 @@ connection default; let $default_db=`select database()`; let $MYSQLD_DATADIR= `SELECT @@datadir`; +let $pid_file=`select @@pid_file`; #it will used at end of test for wait_for_status_var.inc primitive #let $status_var= Threads_connected; @@ -23,6 +24,7 @@ wait-maria_empty_logs.inc EOF --source include/mysqladmin_shutdown.inc +--source include/wait_until_no_pidfile.inc --disable_warnings if (!$mel_keep_control_file) 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/include/wait_until_no_pidfile.inc b/mysql-test/include/wait_until_no_pidfile.inc new file mode 100644 index 00000000000..9448400522b --- /dev/null +++ b/mysql-test/include/wait_until_no_pidfile.inc @@ -0,0 +1,30 @@ +# Include this script after a shutdown to wait until the pid file, +# stored in $pid_file, has disappered. + +#--echo $pid_file + +--disable_result_log +--disable_query_log +# Wait one minute +let $counter= 600; +while ($counter) +{ +--error 0,1 +--file_exists $pid_file + if (!$errno) + { + dec $counter; + --real_sleep 0.1 + } + if ($errno) + { + let $counter= 0; + } +} +if (!$errno) +{ + --die Pid file "$pid_file" failed to disappear +} + +--enable_query_log +--enable_result_log diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 903b3e48324..4abb9f11704 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -154,7 +154,17 @@ sub collect_test_cases ($$$$) { { push (@$cases, @this_case); } - else + elsif ($::opt_skip_not_found) + { + push @$cases, My::Test->new + ( + name => "$sname.$tname", + shortname => $tname, + skip => 1, + comment => 'not found', + ); + } + else { mtr_error("Could not find '$tname' in '$sname' suite"); } @@ -614,7 +624,7 @@ sub make_combinations($$@) { my ($test, $test_combs, @combinations) = @_; - return ($test) if $test->{'skip'} or not @combinations; + return ($test) unless @combinations; if ($combinations[0]->{skip}) { $test->{skip} = 1; $test->{comment} = $combinations[0]->{skip} unless $test->{comment}; @@ -647,6 +657,8 @@ sub make_combinations($$@) } } + return ($test) if $test->{'skip'}; + my @cases; foreach my $comb (@combinations) { diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 7d944ade71a..97c48c19112 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -76,6 +76,30 @@ if (-t STDOUT) { } } +# On Windows, stdio does not support line buffering +# This can make MTR output from multiple forked processes interleaved, messed up. +# Below is DYI stdout line buffering. +my $out_line=""; + +# Flush buffered line +sub flush_out { + print $out_line; + $out_line = ""; +} + +# Print to stdout +sub print_out { + if(IS_WIN32PERL) { + $out_line .= $_[0]; + # Flush buffered output on new lines. + if (rindex($_[0], "\n") != -1) { + flush_out(); + } + } else { + print($_[0]); + } +} + sub titlebar_stat($) { sub time_format($) { @@ -116,10 +140,10 @@ sub _mtr_report_test_name ($) { return unless defined $verbose; - print _name(). _timestamp(); - printf "%-40s ", $tname; + print_out _name(). _timestamp(); + print_out (sprintf "%-40s ", $tname); my $worker = $tinfo->{worker}; - print "w$worker " if defined $worker; + print_out "w$worker " if defined $worker; return $tname; } @@ -661,14 +685,14 @@ sub mtr_report (@) { { my @s = split /\[ (\S+) \]/, _name() . "@_\n"; if (@s > 1) { - print $s[0]; + print_out $s[0]; &$set_color($s[1]); - print "[ $s[1] ]"; + print_out "[ $s[1] ]"; &$set_color('reset'); - print $s[2]; + print_out $s[2]; titlebar_stat($s[1]) if $set_titlebar; } else { - print $s[0]; + print_out $s[0]; } } } @@ -676,6 +700,7 @@ sub mtr_report (@) { # Print warning to screen sub mtr_warning (@) { + flush_out(); print STDERR _name(). _timestamp(). "mysql-test-run: WARNING: ". join(" ", @_). "\n"; } @@ -683,7 +708,7 @@ sub mtr_warning (@) { # Print error to screen and then exit sub mtr_error (@) { - IO::Handle::flush(\*STDOUT) if IS_WINDOWS; + flush_out(); print STDERR _name(). _timestamp(). "mysql-test-run: *** ERROR: ". join(" ", @_). "\n"; if (IS_WINDOWS) diff --git a/mysql-test/main/alias.test b/mysql-test/main/alias.test index bc429656b7e..f75fdafea1e 100644 --- a/mysql-test/main/alias.test +++ b/mysql-test/main/alias.test @@ -1,5 +1,3 @@ -#remove this include after fix MDEV-27871 ---source include/no_view_protocol.inc --disable_warnings DROP TABLE IF EXISTS t1; @@ -248,7 +246,9 @@ SET sql_mode=DEFAULT; --echo # in Item::print_item_w_name on SELECT w/ optimizer_trace enabled --echo # +--disable_view_protocol SELECT '' LIMIT 0; +--enable_view_protocol --error ER_WRONG_COLUMN_NAME CREATE TABLE t1 AS SELECT ''; @@ -320,7 +320,9 @@ create or replace table t2 (b int); insert into t1 values(111111111),(-2147483648); insert into t2 values(1),(2); --enable_metadata +--disable_view_protocol select t1.a as a1 from t1 as t1,t2 order by t2.b,t1.a; +--enable_view_protocol --disable_metadata drop table t1,t2; diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index fe53977b160..2db89f77434 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -1973,8 +1973,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 e2a3b2866f1..d37abb0b801 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -1688,6 +1688,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/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result index ecb7ce8518d..f94c785864b 100644 --- a/mysql-test/main/alter_table_online_debug.result +++ b/mysql-test/main/alter_table_online_debug.result @@ -1,3 +1,4 @@ +set global default_storage_engine= innodb; set default_storage_engine= innodb; connect con2, localhost, root,,; connection default; @@ -289,7 +290,7 @@ set debug_sync= 'alter_table_copy_end SIGNAL ended WAIT_FOR end'; alter table t1 add b int NULL, algorithm= copy, lock= none; connection con2; insert into t1 values (1),(2),(3),(4),(5),(6); -ERROR 23000: Duplicate entry '5' for key 'PRIMARY' +Got one of the listed errors select * from t1; a 1 @@ -496,6 +497,7 @@ a b UNIX_TIMESTAMP(row_start) UNIX_TIMESTAMP(row_end) 6 77 1.000000 2147483647.999999 alter table t1 drop system versioning, algorithm= copy, lock= none; ERROR 0A000: LOCK=NONE is not supported. Reason: DROP SYSTEM VERSIONING. Try LOCK=SHARED +drop table t1; # # Test ROLLBACK TO SAVEPOINT # @@ -582,7 +584,7 @@ set debug_sync= 'reset'; drop table t1; drop table t2; drop table t3; -create table t1 (a char(6), b int) engine=innodb; +create table t1 (a char(6), b int); insert t1 values ('abcde1',1),('abcde2',2); set debug_sync= 'now wait_for downgraded'; connection con2; @@ -838,7 +840,7 @@ a b drop table t1; set debug_sync= 'reset'; ## CHECK, UPDATE -create table t1 (a int) engine=innodb; +create table t1 (a int); insert t1 values (1),(2),(3),(4); set debug_sync= 'now wait_for downgraded'; connection con2; @@ -863,7 +865,7 @@ a 14 drop table t1; ## DEFAULT, UPDATE -create table t1 (a int) engine=innodb; +create table t1 (a int); insert t1 values (1),(2),(3),(4); set debug_sync= 'now wait_for downgraded'; connection con2; @@ -892,7 +894,7 @@ a b drop table t1; set debug_sync= 'reset'; ## VCOL + CHECK -create table t1 (a int) engine=innodb; +create table t1 (a int); insert t1 values (1),(2),(3),(4); set debug_sync= 'now wait_for downgraded'; connection con2; @@ -939,8 +941,8 @@ connection default; drop table t1; set debug_sync= reset; ### -create table t1 (a text, unique(a)) engine=innodb; -create table t2 (b text, unique(b)) engine=innodb; +create table t1 (a text, unique(a)); +create table t2 (b text, unique(b)); insert into t2 values (null),(null); set debug_sync= 'now wait_for downgraded'; connection con2; @@ -958,7 +960,7 @@ set debug_sync= reset; # # MDEV-29038 XA assertions failing in binlog_rollback and binlog_commit # -create table t (a int) engine=innodb; +create table t (a int); insert into t values (1); xa begin 'xid'; set debug_sync= 'now wait_for downgraded'; @@ -1303,7 +1305,7 @@ drop table t; # Test that correct fields are marked as explicit: # Drop a, reorder b, add new column with default. # -create table t (a int primary key, b int) engine=innodb; +create table t (a int primary key, b int); insert into t values (1, 1), (2, 2), (3, 3); set debug_sync= "alter_table_copy_end signal copy wait_for goon"; alter table t drop primary key, drop a, @@ -1334,7 +1336,7 @@ c x 3 123456 drop table t; # Test that all the fields are unpacked. -create table t (a int, b int) engine=innodb; +create table t (a int, b int); insert into t values (NULL, 123), (NULL, 456); set debug_sync= "alter_table_copy_end signal copy wait_for goon"; alter table t drop a, add primary key(b), algorithm=copy; @@ -1458,6 +1460,334 @@ connection default; set old_mode= @old_old_mode; drop table t1; set debug_sync= reset; +# +# MDEV-32100 Online ALTER TABLE ends with 1032 under some isolation levels +# +create table iso_levels(id int, level text); +INSERT iso_levels VALUES (0, "READ UNCOMMITTED"), +(1, "READ COMMITTED"), +(2, "REPEATABLE READ"), +(3, "SERIALIZABLE"); +create table t1 (a int, b int, key(b)); +connection con2; +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); +connection default; +set session transaction isolation level SERIALIZABLE; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; +alter table t1 force, algorithm=copy; +connection con2; +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; +connection default; +drop table t1; +create table t1 (a int, b int, key(b)); +connection con2; +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); +connection default; +set session transaction isolation level REPEATABLE READ; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; +alter table t1 force, algorithm=copy; +connection con2; +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; +connection default; +drop table t1; +create table t1 (a int, b int, key(b)); +connection con2; +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); +connection default; +set session transaction isolation level READ COMMITTED; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; +alter table t1 force, algorithm=copy; +connection con2; +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; +connection default; +drop table t1; +create table t1 (a int, b int, key(b)); +connection con2; +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); +connection default; +set session transaction isolation level READ UNCOMMITTED; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; +alter table t1 force, algorithm=copy; +connection con2; +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; +connection default; +drop table t1; +set debug_sync= reset; +drop table iso_levels; +# MDEV-32126 Assertion fails upon online ALTER and binary log enabled +create temporary table tmp (id int, primary key(id)) engine=innodb; +create table t1 (a int, b text); +create table t2 (a int, b int, c char(8), d text, unique(a)); +insert into t2 values (1,1,'f','e'),(1000,1000,'c','b'); +connection default; +set debug_sync= 'alter_table_online_before_lock signal go_trx wait_for go_alter'; +alter table t2 force, algorithm=copy, lock=none; +connection con2; +set debug_sync= 'now wait_for go_trx'; +start transaction; +insert into t1 values (3,'a'); +insert into t2 values (3,3,'a','x'), (3,3,'a','x'); +ERROR 23000: Duplicate entry '3' for key 'a' +insert into t2 values (3,3,'a','x'); +commit; +set debug_sync= 'now signal go_alter'; +connection default; +truncate t2; +set @@binlog_format=mixed; +connection con2; +start transaction; +create temporary table tmp (id int, primary key(id)); +insert into t1 values (1, repeat('x',8000)),(2, repeat('x',8000)); +update t2 set b = null order by b limit 2; +insert into t1 values (3, repeat('x',8000)); +delete from t1; +insert into t2 values (1,1,'f','e'),(1000,1000,'c','b'); +commit; +connection default; +set debug_sync= 'alter_table_online_before_lock signal go_trx wait_for go_alter'; +alter table t2 force, algorithm=copy, lock=none; +connection con2; +set debug_sync= 'now wait_for go_trx'; +start transaction; +drop temporary table if exists tmp; +insert into t2 values (3,3,'a','x'), (3,3,'a','x'); +ERROR 23000: Duplicate entry '3' for key 'a' +insert into t2 values (3,3,'a','x'); +commit; +set debug_sync= 'now signal go_alter'; +connection default; +drop table t1, t2; +set @@binlog_format=default; +set debug_sync= reset; +# MDEV-32444 Data from orphaned XA transaction is lost after online alter +create table t (a int primary key); +insert into t values (1); +# XA commit +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +alter table t force, algorithm=copy, lock=none; +connection con1; +set debug_sync= 'now wait_for downgraded'; +xa begin 'x1'; +update t set a = 2 where a = 1; +xa end 'x1'; +xa prepare 'x1'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +disconnect con1; +connection con2; +set debug_sync= 'now signal close wait_for xa_detach'; +xa commit 'x1'; +set debug_sync= 'now signal go'; +connection default; +select * from t; +a +2 +# XA rollback +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +alter table t force, algorithm=copy, lock=none; +connect con1, localhost, root,,; +set debug_sync= 'now wait_for downgraded'; +xa begin 'x2'; +insert into t values (53); +xa end 'x2'; +xa prepare 'x2'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +disconnect con1; +connection con2; +set debug_sync= 'now signal close wait_for xa_detach'; +xa rollback 'x2'; +set debug_sync= 'now signal go'; +connection default; +select * from t; +a +2 +# XA transaction is left uncommitted +# end then is rollbacked after alter fails +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +set statement innodb_lock_wait_timeout=0, lock_wait_timeout= 0 +for alter table t force, algorithm=copy, lock=none; +connect con1, localhost, root,,; +set debug_sync= 'now wait_for downgraded'; +xa begin 'xuncommitted'; +insert into t values (3); +xa end 'xuncommitted'; +xa prepare 'xuncommitted'; +set debug_sync= 'now signal go'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +disconnect con1; +connection default; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +set debug_sync= 'now signal close wait_for xa_detach'; +xa rollback 'xuncommitted'; +select * from t; +a +2 +# Same, but commit +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +set statement innodb_lock_wait_timeout=0, lock_wait_timeout= 0 +for alter table t force, algorithm=copy, lock=none; +connect con1, localhost, root,,; +set debug_sync= 'now wait_for downgraded'; +xa begin 'committed_later'; +insert into t values (3); +xa end 'committed_later'; +xa prepare 'committed_later'; +set debug_sync= 'now signal go'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +disconnect con1; +connection default; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +set debug_sync= 'now signal close wait_for xa_detach'; +xa commit 'committed_later'; +select * from t; +a +2 +3 +# Commit, but error in statement, and there is some stmt data to rollback +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +alter table t force, algorithm=copy, lock=none; +connect con1, localhost, root,,; +set debug_sync= 'now wait_for downgraded'; +xa begin 'x1'; +insert into t values (4), (3); +ERROR 23000: Duplicate entry '3' for key 'PRIMARY' +insert into t values (5); +xa end 'x1'; +xa prepare 'x1'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +disconnect con1; +connection con2; +set debug_sync= 'now signal close wait_for xa_detach'; +xa commit 'x1'; +set debug_sync= 'now signal go'; +connection default; +select * from t; +a +2 +3 +5 +connect con1, localhost, root,,; +connection default; +drop table t; +set debug_sync= reset; +# MDEV-32771 Server crash upon online alter with concurrent XA +create table t (a int primary key); +insert t values(1),(2),(3); +# First, check that nothing from the rollbacked statement commits +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +alter table t add b int default (555), algorithm=copy; +connection con1; +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +update t set a = 0; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +xa end 'xid'; +xa prepare 'xid'; +xa commit 'xid'; +set debug_sync= 'now signal go'; +connection default; +select * from t; +a b +1 555 +2 555 +3 555 +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +alter table t add c int default(777), algorithm=copy; +connection con1; +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +update t set a = 0; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +xa end 'xid'; +xa prepare 'xid'; +xa rollback 'xid'; +set debug_sync= 'now signal go'; +connection default; +select * from t; +a b c +1 555 777 +2 555 777 +3 555 777 +# Same, but add one successful statement into transaction +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +alter table t drop b, algorithm=copy; +connection con1; +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +update t set a = 10 where a = 1; +update t set a = 0; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +xa end 'xid'; +xa prepare 'xid'; +xa rollback 'xid'; +set debug_sync= 'now signal go'; +connection default; +select * from t; +a c +1 777 +2 777 +3 777 +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +alter table t drop primary key, algorithm=copy; +connection con1; +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +# This statement will take effect. +update t set a = 10 where a = 1; +update t set a = 0; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +xa end 'xid'; +xa prepare 'xid'; +xa commit 'xid'; +set debug_sync= 'now signal go'; +connection default; +select * from t; +a c +10 777 +2 777 +3 777 +# The only statement succeeds (test both commit and rollback) +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +alter table t add d text default ('qwe'), algorithm=copy; +connection con1; +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +update t set a = 0; +xa end 'xid'; +xa prepare 'xid'; +xa rollback 'xid'; +set debug_sync= 'now signal go'; +connection default; +select * from t; +a c d +10 777 qwe +2 777 qwe +3 777 qwe +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +alter table t drop c, algorithm=copy; +connection con1; +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +update t set a = 0; +xa end 'xid'; +xa prepare 'xid'; +xa commit 'xid'; +set debug_sync= 'now signal go'; +connection default; +select * from t; +a d +0 qwe +0 qwe +0 qwe +drop table t; +set global default_storage_engine= MyISAM; disconnect con1; disconnect con2; # diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test index e054c0218f5..cf0062da269 100644 --- a/mysql-test/main/alter_table_online_debug.test +++ b/mysql-test/main/alter_table_online_debug.test @@ -4,8 +4,10 @@ --source include/have_innodb.inc --source include/have_sequence.inc --source include/have_partition.inc -set default_storage_engine= innodb; +let $default_storage_engine= `select @@global.default_storage_engine`; +set global default_storage_engine= innodb; +set default_storage_engine= innodb; --connect (con2, localhost, root,,) --connection default @@ -368,7 +370,7 @@ alter table t1 add b int NULL, algorithm= copy, lock= none; --connection con2 --reap ---error ER_DUP_ENTRY +--error ER_DUP_ENTRY,ER_DUP_KEY insert into t1 values (1),(2),(3),(4),(5),(6); select * from t1; set debug_sync= 'now SIGNAL end'; @@ -629,6 +631,7 @@ alter table t1 drop system versioning, algorithm= copy, lock= none; #--reap #show create table t1; #select * from t1; +drop table t1; --echo # --echo # Test ROLLBACK TO SAVEPOINT @@ -730,7 +733,7 @@ drop table t3; # # Lossy alter, Update_row_log_event cannot find 'abcde2' in the new table # -create table t1 (a char(6), b int) engine=innodb; +create table t1 (a char(6), b int); insert t1 values ('abcde1',1),('abcde2',2); --send set debug_sync= 'now wait_for downgraded' --connection con2 @@ -1007,7 +1010,7 @@ drop table t1; set debug_sync= 'reset'; --echo ## CHECK, UPDATE -create table t1 (a int) engine=innodb; +create table t1 (a int); insert t1 values (1),(2),(3),(4); --send set debug_sync= 'now wait_for downgraded' --connection con2 @@ -1026,7 +1029,7 @@ select * from t1; drop table t1; --echo ## DEFAULT, UPDATE -create table t1 (a int) engine=innodb; +create table t1 (a int); insert t1 values (1),(2),(3),(4); --send set debug_sync= 'now wait_for downgraded' --connection con2 @@ -1048,7 +1051,7 @@ drop table t1; set debug_sync= 'reset'; --echo ## VCOL + CHECK -create table t1 (a int) engine=innodb; +create table t1 (a int); insert t1 values (1),(2),(3),(4); --send set debug_sync= 'now wait_for downgraded' --connection con2 @@ -1097,8 +1100,8 @@ set debug_sync= reset; --echo ### -create table t1 (a text, unique(a)) engine=innodb; -create table t2 (b text, unique(b)) engine=innodb; +create table t1 (a text, unique(a)); +create table t2 (b text, unique(b)); insert into t2 values (null),(null); --send set debug_sync= 'now wait_for downgraded'; @@ -1126,7 +1129,7 @@ set debug_sync= reset; --echo # --echo # MDEV-29038 XA assertions failing in binlog_rollback and binlog_commit --echo # -create table t (a int) engine=innodb; +create table t (a int); insert into t values (1); xa begin 'xid'; --send @@ -1513,7 +1516,7 @@ drop table t; --echo # Test that correct fields are marked as explicit: --echo # Drop a, reorder b, add new column with default. --echo # -create table t (a int primary key, b int) engine=innodb; +create table t (a int primary key, b int); insert into t values (1, 1), (2, 2), (3, 3); set debug_sync= "alter_table_copy_end signal copy wait_for goon"; @@ -1539,7 +1542,7 @@ select * from t; drop table t; --echo # Test that all the fields are unpacked. -create table t (a int, b int) engine=innodb; +create table t (a int, b int); insert into t values (NULL, 123), (NULL, 456); set debug_sync= "alter_table_copy_end signal copy wait_for goon"; @@ -1695,6 +1698,350 @@ set old_mode= @old_old_mode; drop table t1; set debug_sync= reset; +--echo # +--echo # MDEV-32100 Online ALTER TABLE ends with 1032 under some isolation levels +--echo # + +let $tx_iso_id=4; + +create table iso_levels(id int, level text); +INSERT iso_levels VALUES (0, "READ UNCOMMITTED"), + (1, "READ COMMITTED"), + (2, "REPEATABLE READ"), + (3, "SERIALIZABLE"); + +while($tx_iso_id) { +dec $tx_iso_id; +let tx_iso= `select level from iso_levels where id = $tx_iso_id`; + +create table t1 (a int, b int, key(b)); + +--connection con2 +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); + +--connection default + +eval set session transaction isolation level $tx_iso; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; + +send alter table t1 force, algorithm=copy; + +--connection con2 +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; + +--connection default +--reap +drop table t1; +} +set debug_sync= reset; +drop table iso_levels; + + +--echo # MDEV-32126 Assertion fails upon online ALTER and binary log enabled +create temporary table tmp (id int, primary key(id)) engine=innodb; +create table t1 (a int, b text); +create table t2 (a int, b int, c char(8), d text, unique(a)); +insert into t2 values (1,1,'f','e'),(1000,1000,'c','b'); +--connection default +set debug_sync= 'alter_table_online_before_lock signal go_trx wait_for go_alter'; +send alter table t2 force, algorithm=copy, lock=none; + +--connection con2 +set debug_sync= 'now wait_for go_trx'; +start transaction; +insert into t1 values (3,'a'); +--error ER_DUP_ENTRY +insert into t2 values (3,3,'a','x'), (3,3,'a','x'); +insert into t2 values (3,3,'a','x'); +commit; +set debug_sync= 'now signal go_alter'; +--connection default +--reap +truncate t2; +set @@binlog_format=mixed; +--connection con2 +start transaction; +create temporary table tmp (id int, primary key(id)); +insert into t1 values (1, repeat('x',8000)),(2, repeat('x',8000)); +update t2 set b = null order by b limit 2; +insert into t1 values (3, repeat('x',8000)); +delete from t1; +insert into t2 values (1,1,'f','e'),(1000,1000,'c','b'); +commit; + + +--connection default +set debug_sync= 'alter_table_online_before_lock signal go_trx wait_for go_alter'; +send alter table t2 force, algorithm=copy, lock=none; + +--connection con2 +set debug_sync= 'now wait_for go_trx'; +start transaction; +drop temporary table if exists tmp; +--error ER_DUP_ENTRY +insert into t2 values (3,3,'a','x'), (3,3,'a','x'); +insert into t2 values (3,3,'a','x'); +commit; +set debug_sync= 'now signal go_alter'; + +--connection default +--reap + +drop table t1, t2; +set @@binlog_format=default; +set debug_sync= reset; + + +--echo # MDEV-32444 Data from orphaned XA transaction is lost after online alter + +create table t (a int primary key); +insert into t values (1); + +--echo # XA commit + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send alter table t force, algorithm=copy, lock=none; + +--connection con1 +set debug_sync= 'now wait_for downgraded'; +xa begin 'x1'; +update t set a = 2 where a = 1; +xa end 'x1'; +xa prepare 'x1'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +--disconnect con1 + +--connection con2 +set debug_sync= 'now signal close wait_for xa_detach'; +xa commit 'x1'; +set debug_sync= 'now signal go'; +--connection default +--reap # alter table + +select * from t; + +--echo # XA rollback + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send alter table t force, algorithm=copy, lock=none; +--connect(con1, localhost, root,,) +set debug_sync= 'now wait_for downgraded'; +xa begin 'x2'; +insert into t values (53); +xa end 'x2'; +xa prepare 'x2'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +--disconnect con1 + +--connection con2 +set debug_sync= 'now signal close wait_for xa_detach'; +xa rollback 'x2'; +set debug_sync= 'now signal go'; +--connection default +--reap # alter table + +select * from t; + +--echo # XA transaction is left uncommitted +--echo # end then is rollbacked after alter fails + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send set statement innodb_lock_wait_timeout=0, lock_wait_timeout= 0 + for alter table t force, algorithm=copy, lock=none; + +--connect(con1, localhost, root,,) +set debug_sync= 'now wait_for downgraded'; +xa begin 'xuncommitted'; +insert into t values (3); +xa end 'xuncommitted'; +xa prepare 'xuncommitted'; +set debug_sync= 'now signal go'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +--disconnect con1 + +--connection default +--error ER_LOCK_WAIT_TIMEOUT +--reap # alter table +set debug_sync= 'now signal close wait_for xa_detach'; +xa rollback 'xuncommitted'; + +select * from t; + +--echo # Same, but commit + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send set statement innodb_lock_wait_timeout=0, lock_wait_timeout= 0 + for alter table t force, algorithm=copy, lock=none; + +--connect(con1, localhost, root,,) +set debug_sync= 'now wait_for downgraded'; +xa begin 'committed_later'; +insert into t values (3); +xa end 'committed_later'; +xa prepare 'committed_later'; +set debug_sync= 'now signal go'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +--disconnect con1 + +--connection default +--error ER_LOCK_WAIT_TIMEOUT +--reap # alter table +set debug_sync= 'now signal close wait_for xa_detach'; +xa commit 'committed_later'; + + +select * from t; + +--echo # Commit, but error in statement, and there is some stmt data to rollback + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send alter table t force, algorithm=copy, lock=none; +--connect(con1, localhost, root,,) +set debug_sync= 'now wait_for downgraded'; +xa begin 'x1'; +--error ER_DUP_ENTRY +insert into t values (4), (3); +insert into t values (5); +xa end 'x1'; +xa prepare 'x1'; +set debug_sync= 'thread_end signal xa_detach wait_for close'; +--disconnect con1 + +--connection con2 +set debug_sync= 'now signal close wait_for xa_detach'; +xa commit 'x1'; +set debug_sync= 'now signal go'; +--connection default +--reap # alter table + +select * from t; + +--connect(con1, localhost, root,,) +--connection default +drop table t; +set debug_sync= reset; + +--echo # MDEV-32771 Server crash upon online alter with concurrent XA + +create table t (a int primary key); +insert t values(1),(2),(3); + +--echo # First, check that nothing from the rollbacked statement commits + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send alter table t add b int default (555), algorithm=copy; + +--connection con1 +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +--error ER_DUP_ENTRY +update t set a = 0; +xa end 'xid'; +xa prepare 'xid'; +xa commit 'xid'; +set debug_sync= 'now signal go'; + +--connection default +--reap +select * from t; + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send alter table t add c int default(777), algorithm=copy; + +--connection con1 +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +--error ER_DUP_ENTRY +update t set a = 0; +xa end 'xid'; +xa prepare 'xid'; +xa rollback 'xid'; +set debug_sync= 'now signal go'; + +--connection default +--reap +select * from t; + +--echo # Same, but add one successful statement into transaction + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send alter table t drop b, algorithm=copy; + +--connection con1 +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +update t set a = 10 where a = 1; +--error ER_DUP_ENTRY +update t set a = 0; +xa end 'xid'; +xa prepare 'xid'; +xa rollback 'xid'; +set debug_sync= 'now signal go'; + +--connection default +--reap +select * from t; + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send alter table t drop primary key, algorithm=copy; + +--connection con1 +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +--echo # This statement will take effect. +update t set a = 10 where a = 1; +--error ER_DUP_ENTRY +update t set a = 0; +xa end 'xid'; +xa prepare 'xid'; +xa commit 'xid'; +set debug_sync= 'now signal go'; + +--connection default +--reap +select * from t; + + +--echo # The only statement succeeds (test both commit and rollback) + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send alter table t add d text default ('qwe'), algorithm=copy; + +--connection con1 +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +update t set a = 0; +xa end 'xid'; +xa prepare 'xid'; +xa rollback 'xid'; +set debug_sync= 'now signal go'; + +--connection default +--reap +select * from t; + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for go'; +send alter table t drop c, algorithm=copy; + +--connection con1 +set debug_sync= 'now wait_for downgraded'; +xa start 'xid'; +update t set a = 0; +xa end 'xid'; +xa prepare 'xid'; +xa commit 'xid'; +set debug_sync= 'now signal go'; + +--connection default +--reap +select * from t; + +drop table t; + + +eval set global default_storage_engine= $default_storage_engine; --disconnect con1 --disconnect con2 diff --git a/mysql-test/main/analyze.result b/mysql-test/main/analyze.result index aac9ed7b3a2..8819f15f27b 100644 --- a/mysql-test/main/analyze.result +++ b/mysql-test/main/analyze.result @@ -417,5 +417,41 @@ test t1 B 1 NULL test t1 B 2 NULL drop table t1; # +# Crash inis_eits_usable() +# +CREATE TABLE t1 (a int) ENGINE=MyISAM; +CREATE TABLE t2 (b int) ENGINE=MyISAM; +INSERT INTO t1 (a) VALUES (4), (6); +INSERT INTO t2 (b) VALUES (0), (8); +set @save_join_cache_level=@@join_cache_level; +set @save_optimizer_switch=@@optimizer_switch; +SET join_cache_level=3; +SET optimizer_switch='join_cache_hashed=on'; +SET optimizer_switch='join_cache_bka=on'; +set optimizer_switch='hash_join_cardinality=on'; +EXPLAIN +SELECT * FROM t1, t2 WHERE b=a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.a 2 Using where; Using join buffer (flat, BNLH join) +SELECT * FROM t1, t2 WHERE b=a; +a b +DROP TABLE t1,t2; +set @@optimizer_switch=@save_optimizer_switch; +set @@join_cache_level=@save_join_cache_level; +# +# MDEV-32531 MSAN / Valgrind errors in Item_func_like::get_mm_leaf with +# temporal field +# +CREATE TABLE t1 (f DATE); +INSERT INTO t1 VALUES ('1978-08-27'),('1906-04-30'); +ANALYZE TABLE t1 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT * FROM t1 WHERE f LIKE '2023%'; +f +DROP TABLE t1; +# # End of 10.6 tests # diff --git a/mysql-test/main/analyze.test b/mysql-test/main/analyze.test index e3b776f11ca..fb07e11b0c6 100644 --- a/mysql-test/main/analyze.test +++ b/mysql-test/main/analyze.test @@ -269,6 +269,43 @@ alter ignore table t1 rename key `b` to `B`, LOCK=shared; select * from mysql.index_stats where table_name= "t1"; drop table t1; +--echo # +--echo # Crash inis_eits_usable() +--echo # + +CREATE TABLE t1 (a int) ENGINE=MyISAM; + +CREATE TABLE t2 (b int) ENGINE=MyISAM; + +INSERT INTO t1 (a) VALUES (4), (6); +INSERT INTO t2 (b) VALUES (0), (8); + +set @save_join_cache_level=@@join_cache_level; +set @save_optimizer_switch=@@optimizer_switch; +SET join_cache_level=3; +SET optimizer_switch='join_cache_hashed=on'; +SET optimizer_switch='join_cache_bka=on'; +set optimizer_switch='hash_join_cardinality=on'; + +EXPLAIN +SELECT * FROM t1, t2 WHERE b=a; +SELECT * FROM t1, t2 WHERE b=a; +DROP TABLE t1,t2; + +set @@optimizer_switch=@save_optimizer_switch; +set @@join_cache_level=@save_join_cache_level; + +--echo # +--echo # MDEV-32531 MSAN / Valgrind errors in Item_func_like::get_mm_leaf with +--echo # temporal field +--echo # + +CREATE TABLE t1 (f DATE); +INSERT INTO t1 VALUES ('1978-08-27'),('1906-04-30'); +ANALYZE TABLE t1 PERSISTENT FOR ALL; +SELECT * FROM t1 WHERE f LIKE '2023%'; +DROP TABLE t1; + --echo # --echo # End of 10.6 tests --echo # diff --git a/mysql-test/main/backup_interaction.result b/mysql-test/main/backup_interaction.result index e5ddd140516..c2f7cf121c2 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 8744ef2c261..be3b2070136 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 e6c45f6337c..e6fc89d7e5c 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 9de45256d34..fbb5f30c1e8 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 045497dcd0b..0d3f99e8b84 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 7af65284bf4..1f5fb2d6828 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/case.result b/mysql-test/main/case.result index 139267a103c..fcabbc1a968 100644 --- a/mysql-test/main/case.result +++ b/mysql-test/main/case.result @@ -1,67 +1,67 @@ drop table if exists t1, t2; -select CASE "b" when "a" then 1 when "b" then 2 END; -CASE "b" when "a" then 1 when "b" then 2 END +select CASE "b" when "a" then 1 when "b" then 2 END as exp; +exp 2 -select CASE "c" when "a" then 1 when "b" then 2 END; -CASE "c" when "a" then 1 when "b" then 2 END +select CASE "c" when "a" then 1 when "b" then 2 END as exp; +exp NULL -select CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END; -CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END +select CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END as exp; +exp 3 -select CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END; -CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END +select CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END as exp; +exp ok -select CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END; -CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END +select CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END as exp; +exp ok -select CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end; -CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end +select CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end as exp; +exp a -select CASE when 1=0 then "true" else "false" END; -CASE when 1=0 then "true" else "false" END +select CASE when 1=0 then "true" else "false" END as exp; +exp false -select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END; -CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END +select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END as exp; +exp one -explain extended select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END; +explain extended select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END as exp; 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 case 1 when 1 then 'one' when 2 then 'two' else 'more' end AS `CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END` -select CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END; -CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END +Note 1003 select case 1 when 1 then 'one' when 2 then 'two' else 'more' end AS `exp` +select CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END as exp; +exp two -select (CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0; -(CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0 +select (CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0 as exp; +exp 2 -select (CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0; -(CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0 +select (CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0 as exp; +exp 2.00 -select case 1/0 when "a" then "true" else "false" END; -case 1/0 when "a" then "true" else "false" END +select case 1/0 when "a" then "true" else "false" END as exp; +exp false Warnings: Warning 1365 Division by 0 -select case 1/0 when "a" then "true" END; -case 1/0 when "a" then "true" END +select case 1/0 when "a" then "true" END as exp; +exp NULL Warnings: Warning 1365 Division by 0 -select (case 1/0 when "a" then "true" END) | 0; -(case 1/0 when "a" then "true" END) | 0 +select (case 1/0 when "a" then "true" END) | 0 as exp; +exp NULL Warnings: Warning 1365 Division by 0 -select (case 1/0 when "a" then "true" END) + 0.0; -(case 1/0 when "a" then "true" END) + 0.0 +select (case 1/0 when "a" then "true" END) + 0.0 as exp; +exp NULL Warnings: Warning 1365 Division by 0 -select case when 1>0 then "TRUE" else "FALSE" END; -case when 1>0 then "TRUE" else "FALSE" END +select case when 1>0 then "TRUE" else "FALSE" END as exp; +exp TRUE -select case when 1<0 then "TRUE" else "FALSE" END; -case when 1<0 then "TRUE" else "FALSE" END +select case when 1<0 then "TRUE" else "FALSE" END as exp; +exp FALSE create table t1 (a int); insert into t1 values(1),(2),(3),(4); @@ -133,12 +133,12 @@ WHEN _latin1'a' COLLATE latin1_swedish_ci THEN 2 END; ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_danish_ci,EXPLICIT), (latin1_swedish_ci,EXPLICIT) for operation 'case' SELECT -CASE _latin1'a' COLLATE latin1_general_ci WHEN _latin1'A' THEN '1' ELSE 2 END, -CASE _latin1'a' COLLATE latin1_bin WHEN _latin1'A' THEN '1' ELSE 2 END, -CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_swedish_ci THEN '1' ELSE 2 END, -CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_bin THEN '1' ELSE 2 END +CASE _latin1'a' COLLATE latin1_general_ci WHEN _latin1'A' THEN '1' ELSE 2 END as e1, +CASE _latin1'a' COLLATE latin1_bin WHEN _latin1'A' THEN '1' ELSE 2 END as e2, +CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_swedish_ci THEN '1' ELSE 2 END as e3, +CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_bin THEN '1' ELSE 2 END as e4 ; -CASE _latin1'a' COLLATE latin1_general_ci WHEN _latin1'A' THEN '1' ELSE 2 END CASE _latin1'a' COLLATE latin1_bin WHEN _latin1'A' THEN '1' ELSE 2 END CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_swedish_ci THEN '1' ELSE 2 END CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_bin THEN '1' ELSE 2 END +e1 e2 e3 e4 1 2 1 2 CREATE TABLE t1 SELECT COALESCE(_latin1'a',_latin2'a'); ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'coalesce' @@ -403,8 +403,8 @@ DROP TABLE t1; # # End of 10.1 test # -select case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end; -case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end +select case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end as exp; +exp ok Warnings: Warning 1292 Truncated incorrect time value: 'foo' @@ -434,8 +434,8 @@ Warning 1292 Truncated incorrect time value: 'foo' Warning 1292 Truncated incorrect time value: 'foo' Warning 1292 Truncated incorrect time value: 'foo' drop table t1; -select case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end; -case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end +select case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end as exp; +exp ok # # End of 10.2 test diff --git a/mysql-test/main/case.test b/mysql-test/main/case.test index b80408f44d6..10d8aa18db6 100644 --- a/mysql-test/main/case.test +++ b/mysql-test/main/case.test @@ -2,31 +2,29 @@ # Testing of CASE # -#remove this include after fix MDEV-27871 ---source include/no_view_protocol.inc --disable_warnings drop table if exists t1, t2; --enable_warnings -select CASE "b" when "a" then 1 when "b" then 2 END; -select CASE "c" when "a" then 1 when "b" then 2 END; -select CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END; -select CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END; -select CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END; -select CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end; -select CASE when 1=0 then "true" else "false" END; -select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END; -explain extended select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END; -select CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END; -select (CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0; -select (CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0; -select case 1/0 when "a" then "true" else "false" END; -select case 1/0 when "a" then "true" END; -select (case 1/0 when "a" then "true" END) | 0; -select (case 1/0 when "a" then "true" END) + 0.0; -select case when 1>0 then "TRUE" else "FALSE" END; -select case when 1<0 then "TRUE" else "FALSE" END; +select CASE "b" when "a" then 1 when "b" then 2 END as exp; +select CASE "c" when "a" then 1 when "b" then 2 END as exp; +select CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END as exp; +select CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END as exp; +select CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END as exp; +select CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end as exp; +select CASE when 1=0 then "true" else "false" END as exp; +select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END as exp; +explain extended select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END as exp; +select CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END as exp; +select (CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0 as exp; +select (CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0 as exp; +select case 1/0 when "a" then "true" else "false" END as exp; +select case 1/0 when "a" then "true" END as exp; +select (case 1/0 when "a" then "true" END) | 0 as exp; +select (case 1/0 when "a" then "true" END) + 0.0 as exp; +select case when 1>0 then "TRUE" else "FALSE" END as exp; +select case when 1<0 then "TRUE" else "FALSE" END as exp; # # Test bug when using GROUP BY on CASE @@ -83,10 +81,10 @@ SELECT CASE _latin1'a' COLLATE latin1_general_ci END; SELECT -CASE _latin1'a' COLLATE latin1_general_ci WHEN _latin1'A' THEN '1' ELSE 2 END, -CASE _latin1'a' COLLATE latin1_bin WHEN _latin1'A' THEN '1' ELSE 2 END, -CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_swedish_ci THEN '1' ELSE 2 END, -CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_bin THEN '1' ELSE 2 END +CASE _latin1'a' COLLATE latin1_general_ci WHEN _latin1'A' THEN '1' ELSE 2 END as e1, +CASE _latin1'a' COLLATE latin1_bin WHEN _latin1'A' THEN '1' ELSE 2 END as e2, +CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_swedish_ci THEN '1' ELSE 2 END as e3, +CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_bin THEN '1' ELSE 2 END as e4 ; # @@ -297,7 +295,7 @@ DROP TABLE t1; # # should not convert all values to time -select case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end; +select case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end as exp; select 'foo' in (time'10:00:00','0'); create table t1 (a time); @@ -308,7 +306,7 @@ select 'foo' in (a,'0') from t1; drop table t1; # first comparison should be as date, second as time -select case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end; +select case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end as exp; --echo # --echo # End of 10.2 test diff --git a/mysql-test/main/cast.result b/mysql-test/main/cast.result index 0aca1ffa744..81ac3f3e92b 100644 --- a/mysql-test/main/cast.result +++ b/mysql-test/main/cast.result @@ -69,95 +69,95 @@ cast(cast("20:01:01" as time) as datetime) select cast(cast("8:46:06.23434" AS time) as decimal(32,10)); cast(cast("8:46:06.23434" AS time) as decimal(32,10)) 84606.0000000000 -select cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6)); -cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6)) +select cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6)) as exp; +exp 20110405084606.000000 # # Check handling of cast with microseconds # -select cast(cast(20010203101112.121314 as double) as datetime); -cast(cast(20010203101112.121314 as double) as datetime) +select cast(cast(20010203101112.121314 as double) as datetime) as exp; +exp 2001-02-03 10:11:12 -select cast(cast(010203101112.12 as double) as datetime); -cast(cast(010203101112.12 as double) as datetime) +select cast(cast(010203101112.12 as double) as datetime) as exp; +exp 2001-02-03 10:11:12 -select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime); -cast(cast(20010203101112.121314 as decimal(32,6)) as datetime) +select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime) as exp; +exp 2001-02-03 10:11:12 -select cast(20010203101112.121314 as datetime); -cast(20010203101112.121314 as datetime) +select cast(20010203101112.121314 as datetime) as exp; +exp 2001-02-03 10:11:12 -select cast(110203101112.121314 as datetime); -cast(110203101112.121314 as datetime) +select cast(110203101112.121314 as datetime) as exp; +exp 2011-02-03 10:11:12 -select cast(cast(010203101112.12 as double) as datetime); -cast(cast(010203101112.12 as double) as datetime) +select cast(cast(010203101112.12 as double) as datetime) as exp; +exp 2001-02-03 10:11:12 -select cast("2011-02-03 10:11:12.123456" as datetime); -cast("2011-02-03 10:11:12.123456" as datetime) +select cast("2011-02-03 10:11:12.123456" as datetime) as exp; +exp 2011-02-03 10:11:12 -select cast("2011-02-03 10:11:12.123456" as datetime(0)); -cast("2011-02-03 10:11:12.123456" as datetime(0)) +select cast("2011-02-03 10:11:12.123456" as datetime(0)) as exp; +exp 2011-02-03 10:11:12 -select cast("2011-02-03 10:11:12.123456" as datetime(5)); -cast("2011-02-03 10:11:12.123456" as datetime(5)) +select cast("2011-02-03 10:11:12.123456" as datetime(5)) as exp; +exp 2011-02-03 10:11:12.12345 -select cast("2011-02-03 10:11:12.123456" as datetime(6)); -cast("2011-02-03 10:11:12.123456" as datetime(6)) +select cast("2011-02-03 10:11:12.123456" as datetime(6)) as exp; +exp 2011-02-03 10:11:12.123456 -select cast("2011-02-03 10:11:12" as datetime(6)); -cast("2011-02-03 10:11:12" as datetime(6)) +select cast("2011-02-03 10:11:12" as datetime(6)) as exp; +exp 2011-02-03 10:11:12.000000 -select cast(cast(20010203101112.5 as double) as datetime(1)); -cast(cast(20010203101112.5 as double) as datetime(1)) +select cast(cast(20010203101112.5 as double) as datetime(1)) as exp; +exp 2001-02-03 10:11:12.5 -select cast(cast(010203101112.12 as double) as datetime(2)); -cast(cast(010203101112.12 as double) as datetime(2)) +select cast(cast(010203101112.12 as double) as datetime(2)) as exp; +exp 2001-02-03 10:11:12.12 -select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6)); -cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6)) +select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6)) as exp; +exp 2001-02-03 10:11:12.121314 -select cast(20010203101112.121314 as datetime(6)); -cast(20010203101112.121314 as datetime(6)) +select cast(20010203101112.121314 as datetime(6)) as exp; +exp 2001-02-03 10:11:12.121314 -select cast(110203101112.121314 as datetime(6)); -cast(110203101112.121314 as datetime(6)) +select cast(110203101112.121314 as datetime(6)) as exp; +exp 2011-02-03 10:11:12.121314 -select cast(cast(010203101112.12 as double) as datetime(6)); -cast(cast(010203101112.12 as double) as datetime(6)) +select cast(cast(010203101112.12 as double) as datetime(6)) as exp; +exp 2001-02-03 10:11:12.120000 -select cast("2011-02-03 10:11:12.123456" as time); -cast("2011-02-03 10:11:12.123456" as time) +select cast("2011-02-03 10:11:12.123456" as time) as exp; +exp 10:11:12 -select cast("2011-02-03 10:11:12.123456" as time(6)); -cast("2011-02-03 10:11:12.123456" as time(6)) +select cast("2011-02-03 10:11:12.123456" as time(6)) as exp; +exp 10:11:12.123456 -select cast("10:11:12.123456" as time); -cast("10:11:12.123456" as time) +select cast("10:11:12.123456" as time) as exp; +exp 10:11:12 -select cast("10:11:12.123456" as time(0)); -cast("10:11:12.123456" as time(0)) +select cast("10:11:12.123456" as time(0)) as exp; +exp 10:11:12 -select cast("10:11:12.123456" as time(5)); -cast("10:11:12.123456" as time(5)) +select cast("10:11:12.123456" as time(5)) as exp; +exp 10:11:12.12345 -select cast("10:11:12.123456" as time(6)); -cast("10:11:12.123456" as time(6)) +select cast("10:11:12.123456" as time(6)) as exp; +exp 10:11:12.123456 -select cast("10:11:12" as time(6)); -cast("10:11:12" as time(6)) +select cast("10:11:12" as time(6)) as exp; +exp 10:11:12.000000 -select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time); -cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time) +select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time) as exp; +exp 08:46:06 -select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6)); -cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6)) +select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6)) as exp; +exp 08:46:06.000000 -select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time); -cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time) +select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time) as exp; +exp 08:46:06 -select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6)); -cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6)) +select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6)) as exp; +exp 08:46:06.123456 select cast(NULL as unsigned), cast(1/0 as unsigned); cast(NULL as unsigned) cast(1/0 as unsigned) @@ -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 073b5fe0be5..ce4b1f6a574 100644 --- a/mysql-test/main/cast.test +++ b/mysql-test/main/cast.test @@ -2,10 +2,6 @@ # Test of cast function # -#remove this include after fix MDEV-27871 -# discuss what to do with "set names binary" ---source include/no_view_protocol.inc - # For TIME->DATETIME conversion SET timestamp=unix_timestamp('2001-02-03 10:20:30'); @@ -27,41 +23,41 @@ select cast(null as double(5,2)); select cast(12.444 as double); select cast(cast("20:01:01" as time) as datetime); select cast(cast("8:46:06.23434" AS time) as decimal(32,10)); -select cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6)); +select cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6)) as exp; --echo # --echo # Check handling of cast with microseconds --echo # -select cast(cast(20010203101112.121314 as double) as datetime); -select cast(cast(010203101112.12 as double) as datetime); -select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime); -select cast(20010203101112.121314 as datetime); -select cast(110203101112.121314 as datetime); -select cast(cast(010203101112.12 as double) as datetime); +select cast(cast(20010203101112.121314 as double) as datetime) as exp; +select cast(cast(010203101112.12 as double) as datetime) as exp; +select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime) as exp; +select cast(20010203101112.121314 as datetime) as exp; +select cast(110203101112.121314 as datetime) as exp; +select cast(cast(010203101112.12 as double) as datetime) as exp; -select cast("2011-02-03 10:11:12.123456" as datetime); -select cast("2011-02-03 10:11:12.123456" as datetime(0)); -select cast("2011-02-03 10:11:12.123456" as datetime(5)); -select cast("2011-02-03 10:11:12.123456" as datetime(6)); -select cast("2011-02-03 10:11:12" as datetime(6)); -select cast(cast(20010203101112.5 as double) as datetime(1)); -select cast(cast(010203101112.12 as double) as datetime(2)); -select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6)); -select cast(20010203101112.121314 as datetime(6)); -select cast(110203101112.121314 as datetime(6)); -select cast(cast(010203101112.12 as double) as datetime(6)); +select cast("2011-02-03 10:11:12.123456" as datetime) as exp; +select cast("2011-02-03 10:11:12.123456" as datetime(0)) as exp; +select cast("2011-02-03 10:11:12.123456" as datetime(5)) as exp; +select cast("2011-02-03 10:11:12.123456" as datetime(6)) as exp; +select cast("2011-02-03 10:11:12" as datetime(6)) as exp; +select cast(cast(20010203101112.5 as double) as datetime(1)) as exp; +select cast(cast(010203101112.12 as double) as datetime(2)) as exp; +select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6)) as exp; +select cast(20010203101112.121314 as datetime(6)) as exp; +select cast(110203101112.121314 as datetime(6)) as exp; +select cast(cast(010203101112.12 as double) as datetime(6)) as exp; -select cast("2011-02-03 10:11:12.123456" as time); -select cast("2011-02-03 10:11:12.123456" as time(6)); -select cast("10:11:12.123456" as time); -select cast("10:11:12.123456" as time(0)); -select cast("10:11:12.123456" as time(5)); -select cast("10:11:12.123456" as time(6)); -select cast("10:11:12" as time(6)); -select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time); -select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6)); -select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time); -select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6)); +select cast("2011-02-03 10:11:12.123456" as time) as exp; +select cast("2011-02-03 10:11:12.123456" as time(6)) as exp; +select cast("10:11:12.123456" as time) as exp; +select cast("10:11:12.123456" as time(0)) as exp; +select cast("10:11:12.123456" as time(5)) as exp; +select cast("10:11:12.123456" as time(6)) as exp; +select cast("10:11:12" as time(6)) as exp; +select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time) as exp; +select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6)) as exp; +select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time) as exp; +select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6)) as exp; # # Bug #28250: Run-Time Check Failure #3 - The variable 'value' is being used @@ -162,7 +158,9 @@ select cast(1 as double(64,63)); # set names binary; select cast(_latin1'test' as char character set latin2); +--disable_service_connection select cast(_koi8r'ÔÅÓÔ' as char character set cp1251); +--enable_service_connection create table t1 select cast(_koi8r'ÔÅÓÔ' as char character set cp1251) as t; show create table t1; drop table t1; @@ -170,6 +168,7 @@ drop table t1; # # CAST to CHAR with/without length # +--disable_service_connection select cast(_latin1'ab' AS char) as c1, cast(_latin1'a ' AS char) as c2, @@ -177,6 +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_service_connection SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR create table t1 select @@ -237,12 +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'); +--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_service_connection DROP TABLE t1; # @@ -344,9 +346,11 @@ select cast(NULL as decimal(6)) as t1; # Bug #17903: cast to char results in binary # set names latin1; +--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_service_connection # # Bug#29898: Item_date_typecast::val_int doesn't reset the null_value flag. @@ -476,11 +480,13 @@ drop table t1; # # CAST (... BINARY) # +--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_service_connection --echo # --echo # MDEV-11030 Assertion `precision > 0' failed in decimal_bin_size @@ -762,11 +768,14 @@ INSERT INTO t1 VALUES (-1.0); SELECT * FROM t1; DROP TABLE t1; +#enable after MDEV-32645 is fixed +--disable_view_protocol SELECT CAST(-1e0 AS UNSIGNED); 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/change_user.result b/mysql-test/main/change_user.result index fa934fbf09a..c91522dc6ce 100644 --- a/mysql-test/main/change_user.result +++ b/mysql-test/main/change_user.result @@ -1,4 +1,6 @@ set global secure_auth=0; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release create user test_nopw; grant select on test.* to test_nopw; create user test_oldpw identified by password "09301740536db389"; @@ -90,6 +92,8 @@ NULL FLUSH STATUS; Value of com_select did not change set global secure_auth=default; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release set timestamp=unix_timestamp('2010-10-10 10:10:10'); select now(); now() diff --git a/mysql-test/main/check_constraint.result b/mysql-test/main/check_constraint.result index 69eae2e6cea..66cf84d3377 100644 --- a/mysql-test/main/check_constraint.result +++ b/mysql-test/main/check_constraint.result @@ -308,6 +308,19 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; # +# MDEV-32586 incorrect error about cyclic reference about JSON type virtual column +# +create table t1 (a int, b json as (a)); +drop table t1; +create table t1 (a int, b int as (a) check (b > 0)); +insert t1 (a) values (1); +insert t1 (a) values (-1); +ERROR 23000: CONSTRAINT `t1.b` failed for `test`.`t1` +drop table t1; +# +# End of 10.4 tests +# +# # MDEV-32439 INSERT IGNORE VALUES (one row) errors on constraint # CREATE TABLE t1 (v1 varchar(10), v2 varchar(10), constraint unequal check (v1 != v2)); diff --git a/mysql-test/main/check_constraint.test b/mysql-test/main/check_constraint.test index 86e3bf3f50a..73685981263 100644 --- a/mysql-test/main/check_constraint.test +++ b/mysql-test/main/check_constraint.test @@ -231,6 +231,23 @@ alter table t1 force; show create table t1; drop table t1; +--echo # +--echo # MDEV-32586 incorrect error about cyclic reference about JSON type virtual column +--echo # + +create table t1 (a int, b json as (a)); +drop table t1; + +create table t1 (a int, b int as (a) check (b > 0)); +insert t1 (a) values (1); +--error ER_CONSTRAINT_FAILED +insert t1 (a) values (-1); +drop table t1; + +--echo # +--echo # End of 10.4 tests +--echo # + --echo # --echo # MDEV-32439 INSERT IGNORE VALUES (one row) errors on constraint --echo # diff --git a/mysql-test/main/connect.result b/mysql-test/main/connect.result index 1c5045ebe0e..b781b267535 100644 --- a/mysql-test/main/connect.result +++ b/mysql-test/main/connect.result @@ -1,4 +1,6 @@ SET global secure_auth=0; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release connect con1,localhost,root,,mysql; show tables; Tables_in_mysql @@ -412,6 +414,8 @@ test test drop procedure p1; SET global secure_auth=default; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release # # MDEV-19282: Log more specific warning with log_warnings=2 if # connection is aborted prior to authentication diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index 4e96af97326..4bc0afe91d5 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 05c5d25ba15..7c83f3e27a6 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/cset_narrowing.result b/mysql-test/main/cset_narrowing.result new file mode 100644 index 00000000000..377cbdaecf3 --- /dev/null +++ b/mysql-test/main/cset_narrowing.result @@ -0,0 +1,571 @@ +set +@tmp_csetn_os= @@optimizer_switch, +optimizer_switch='cset_narrowing=on'; +set names utf8mb4; +create table t1 ( +mb3name varchar(32), +mb3 varchar(32) collate utf8mb3_general_ci, +key(mb3) +); +insert into t1 select seq, seq from seq_1_to_10000; +insert into t1 values ('mb3-question-mark', '?'); +insert into t1 values ('mb3-replacement-char', _utf8mb3 0xEFBFBD); +create table t10 ( +pk int auto_increment primary key, +mb4name varchar(32), +mb4 varchar(32) character set utf8mb4 collate utf8mb4_general_ci +); +insert into t10 (mb4name, mb4) values +('mb4-question-mark','?'), +('mb4-replacement-char', _utf8mb4 0xEFBFBD), +('mb4-smiley', _utf8mb4 0xF09F988A), +('1', '1'); +analyze table t1,t10 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t10 analyze status Engine-independent statistics collected +test.t10 analyze status OK +# +# Check that constants are already handled: the following should use +# ref/range, because constants are converted into utf8mb3. +# +select collation('abc'); +collation('abc') +utf8mb4_general_ci +explain select * from t1 force index (mb3) where t1.mb3='abc'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref mb3 mb3 99 const 1 Using index condition +explain select * from t1 force index (mb3) where t1.mb3 in ('abc','cde','xyz'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range mb3 mb3 99 NULL 3 Using index condition +explain select * from t1 force index (mb3) where t1.mb3 between 'abc' and 'acc'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range mb3 mb3 99 NULL 1 Using index condition +explain select * from t1 force index (mb3) where t1.mb3 <'000'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range mb3 mb3 99 NULL 1 Using index condition +# If a constant can't be represented in utf8mb3, an error is produced: +explain select * from t1 force index (mb3) where t1.mb3='😊'; +ERROR HY000: Illegal mix of collations (utf8mb3_general_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation '=' +# +# Check ref access on mb3_field=mb4_field +# +explain format=json +select * from t10,t1 where t10.mb4=t1.mb3; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t10.mb4 is not null" + } + }, + { + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["mb3"], + "key": "mb3", + "key_length": "99", + "used_key_parts": ["mb3"], + "ref": ["test.t10.mb4"], + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "t1.mb3 = t10.mb4" + } + } + ] + } +} +select * from t10,t1 where t10.mb4=t1.mb3; +pk mb4name mb4 mb3name mb3 +1 mb4-question-mark ? mb3-question-mark ? +2 mb4-replacement-char � mb3-replacement-char � +3 mb4-smiley 😊 mb3-replacement-char � +4 1 1 1 1 +select * from t10,t1 use index() where t10.mb4=t1.mb3; +pk mb4name mb4 mb3name mb3 +4 1 1 1 1 +1 mb4-question-mark ? mb3-question-mark ? +2 mb4-replacement-char � mb3-replacement-char � +3 mb4-smiley 😊 mb3-replacement-char � +explain format=json +select * from t10,t1 where t10.mb4<=>t1.mb3; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 100 + } + }, + { + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["mb3"], + "key": "mb3", + "key_length": "99", + "used_key_parts": ["mb3"], + "ref": ["test.t10.mb4"], + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "t10.mb4 <=> t1.mb3" + } + } + ] + } +} +select * from t10,t1 where t10.mb4<=>t1.mb3; +pk mb4name mb4 mb3name mb3 +1 mb4-question-mark ? mb3-question-mark ? +2 mb4-replacement-char � mb3-replacement-char � +3 mb4-smiley 😊 mb3-replacement-char � +4 1 1 1 1 +set statement optimizer_switch='cset_narrowing=off', join_cache_level=0 for +explain format=json +select * from t10,t1 where t10.mb4=t1.mb3; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 100 + } + }, + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 4, + "rows": 10002, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t10.mb4 = convert(t1.mb3 using utf8mb4)" + } + } + ] + } +} +# +# Check ref access on mb3_field=mb4_expr +# +explain format=json +select * from t10,t1 where t1.mb3=concat('',t10.mb4); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 100 + } + }, + { + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["mb3"], + "key": "mb3", + "key_length": "99", + "used_key_parts": ["mb3"], + "ref": ["func"], + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "t1.mb3 = concat('',t10.mb4)" + } + } + ] + } +} +select * from t10,t1 where t1.mb3=concat('',t10.mb4); +pk mb4name mb4 mb3name mb3 +1 mb4-question-mark ? mb3-question-mark ? +2 mb4-replacement-char � mb3-replacement-char � +3 mb4-smiley 😊 mb3-replacement-char � +4 1 1 1 1 +select * from t10,t1 use index() where t1.mb3=concat('',t10.mb4); +pk mb4name mb4 mb3name mb3 +4 1 1 1 1 +1 mb4-question-mark ? mb3-question-mark ? +2 mb4-replacement-char � mb3-replacement-char � +3 mb4-smiley 😊 mb3-replacement-char � +# Check that ref optimizer gets the right constant. +# We need a const table for that, because key=const is handled by +# coercing the constant. +# +# So, we take the smiley: +select * from t10 where t10.pk=3; +pk mb4name mb4 +3 mb4-smiley 😊 +set optimizer_trace=1; +# And see that we've got the Replacement Character in the ranges: +explain +select * from t10, t1 where t10.mb4=t1.mb3 and t10.pk=3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t10 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t1 ref mb3 mb3 99 const 3 Using index condition +select +json_detailed(json_extract(trace, '$**.range_scan_alternatives')) as JS +from +information_schema.optimizer_trace; +JS +[ + [ + { + "index": "mb3", + "ranges": + ["(�) <= (mb3) <= (�)"], + "rowid_ordered": true, + "using_mrr": false, + "index_only": false, + "rows": 3, + "cost": "COST_REPLACED", + "chosen": true + } + ] +] +select * from t10, t1 where t10.mb4=t1.mb3 and t10.pk=3; +pk mb4name mb4 mb3name mb3 +3 mb4-smiley 😊 mb3-replacement-char � +# +# Will range optimizer handle t1.mb3>t10.mb4? No... +# +explain format=json +select * from t10, t1 where (t1.mb3=t10.mb4 or t1.mb3='hello') and t10.pk=3; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "const", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["pk"], + "ref": ["const"], + "rows": 1, + "filtered": 100 + } + }, + { + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": ["mb3"], + "key": "mb3", + "key_length": "99", + "used_key_parts": ["mb3"], + "loops": 1, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "t1.mb3 = '????' or t1.mb3 = 'hello'" + } + } + ] + } +} +explain format=json +select * from t10, t1 where t1.mb3>t10.mb4 and t10.pk=3; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "const", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["pk"], + "ref": ["const"], + "rows": 1, + "filtered": 100 + } + }, + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 10002, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "convert(t1.mb3 using utf8mb4) > '????'" + } + } + ] + } +} +# For comparison, it will handle it when collations match: +create table t2 ( +mb4name varchar(32), +mb4 varchar(32) collate utf8mb4_general_ci, +key(mb4) +); +insert into t2 select * from t1; +explain format=json +select * from t10, t2 where t2.mb4>t10.mb4 and t10.pk=3; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "const", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["pk"], + "ref": ["const"], + "rows": 1, + "filtered": 100 + } + }, + { + "table": { + "table_name": "t2", + "access_type": "range", + "possible_keys": ["mb4"], + "key": "mb4", + "key_length": "131", + "used_key_parts": ["mb4"], + "loops": 1, + "rows": 3, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "t2.mb4 > '????'" + } + } + ] + } +} +# +# Check multiple equalities +# +# - ref acccess lookup keys do use equality substitution, +# - concat() arguments don't +explain format=json +select straight_join * from t10,t1 force index(mb3),t2 +where +t1.mb3=t2.mb4 and t2.mb4=t10.mb4 and concat(t1.mb3, t2.mb4, t10.mb4)<>'Bebebe'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t10.mb4 is not null and t10.mb4 is not null" + } + }, + { + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["mb3"], + "key": "mb3", + "key_length": "99", + "used_key_parts": ["mb3"], + "ref": ["test.t10.mb4"], + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "t1.mb3 = t10.mb4" + } + }, + { + "table": { + "table_name": "t2", + "access_type": "ref", + "possible_keys": ["mb4"], + "key": "mb4", + "key_length": "131", + "used_key_parts": ["mb4"], + "ref": ["test.t10.mb4"], + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe'" + } + } + ] + } +} +select json_detailed(json_extract(trace, '$**.condition_processing')) as JS +from information_schema.optimizer_trace; +JS +[ + { + "condition": "WHERE", + "original_condition": "t1.mb3 = t2.mb4 and t2.mb4 = t10.mb4 and concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe'", + "steps": + [ + { + "transformation": "equality_propagation", + "resulting_condition": "concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe' and multiple equal(t1.mb3, t2.mb4, t10.mb4)" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe' and multiple equal(t1.mb3, t2.mb4, t10.mb4)" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe' and multiple equal(t1.mb3, t2.mb4, t10.mb4)" + } + ] + } +] +select straight_join * from t10,t1 force index(mb3),t2 +where +t1.mb3=t2.mb4 and t2.mb4=t10.mb4 and concat(t1.mb3, t2.mb4, t10.mb4)<>'Bebebe'; +pk mb4name mb4 mb3name mb3 mb4name mb4 +1 mb4-question-mark ? mb3-question-mark ? mb3-question-mark ? +2 mb4-replacement-char � mb3-replacement-char � mb3-replacement-char � +3 mb4-smiley 😊 mb3-replacement-char � mb3-replacement-char � +4 1 1 1 1 1 1 +# Equality substitution doesn't happen for constants, for both narrowing +# and non-narrowing comparisons: +explain format=json +select * from t10,t1,t2 +where +t1.mb3=t2.mb4 and t2.mb4=t10.mb4 and t10.mb4='hello' and +concat(t1.mb3, t2.mb4, t10.mb4)<>'Bebebe'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 25, + "attached_condition": "t10.mb4 = 'hello'" + } + }, + { + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["mb3"], + "key": "mb3", + "key_length": "99", + "used_key_parts": ["mb3"], + "ref": ["const"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "t1.mb3 = t10.mb4" + } + }, + { + "table": { + "table_name": "t2", + "access_type": "ref", + "possible_keys": ["mb4"], + "key": "mb4", + "key_length": "131", + "used_key_parts": ["mb4"], + "ref": ["const"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "t2.mb4 = t10.mb4 and concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe'" + } + } + ] + } +} +select json_detailed(json_extract(trace, '$**.condition_processing')) as JS +from information_schema.optimizer_trace; +JS +[ + { + "condition": "WHERE", + "original_condition": "t1.mb3 = t2.mb4 and t2.mb4 = t10.mb4 and t10.mb4 = 'hello' and concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe'", + "steps": + [ + { + "transformation": "equality_propagation", + "resulting_condition": "t10.mb4 = 'hello' and concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe' and multiple equal(t1.mb3, t2.mb4, t10.mb4)" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "t10.mb4 = 'hello' and concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe' and multiple equal(t1.mb3, t2.mb4, t10.mb4)" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "t10.mb4 = 'hello' and concat(convert(t1.mb3 using utf8mb4),t2.mb4,t10.mb4) <> 'Bebebe' and multiple equal(t1.mb3, t2.mb4, t10.mb4)" + } + ] + } +] +drop table t2; +drop table t1, t10; +set optimizer_switch=@tmp_csetn_os; diff --git a/mysql-test/main/cset_narrowing.test b/mysql-test/main/cset_narrowing.test new file mode 100644 index 00000000000..4b97c4f061f --- /dev/null +++ b/mysql-test/main/cset_narrowing.test @@ -0,0 +1,160 @@ +# +# Test character set narrowing +# + +--source include/have_utf8mb4.inc +--source include/have_sequence.inc +--source include/not_embedded.inc + +set + @tmp_csetn_os= @@optimizer_switch, + optimizer_switch='cset_narrowing=on'; + +set names utf8mb4; +create table t1 ( + mb3name varchar(32), + mb3 varchar(32) collate utf8mb3_general_ci, + key(mb3) +); +insert into t1 select seq, seq from seq_1_to_10000; +insert into t1 values ('mb3-question-mark', '?'); +insert into t1 values ('mb3-replacement-char', _utf8mb3 0xEFBFBD); + +create table t10 ( + pk int auto_increment primary key, + mb4name varchar(32), + mb4 varchar(32) character set utf8mb4 collate utf8mb4_general_ci +); + +insert into t10 (mb4name, mb4) values + ('mb4-question-mark','?'), + ('mb4-replacement-char', _utf8mb4 0xEFBFBD), + ('mb4-smiley', _utf8mb4 0xF09F988A), + ('1', '1'); + +analyze table t1,t10 persistent for all; +--echo # +--echo # Check that constants are already handled: the following should use +--echo # ref/range, because constants are converted into utf8mb3. +--echo # +select collation('abc'); +explain select * from t1 force index (mb3) where t1.mb3='abc'; +explain select * from t1 force index (mb3) where t1.mb3 in ('abc','cde','xyz'); +explain select * from t1 force index (mb3) where t1.mb3 between 'abc' and 'acc'; +explain select * from t1 force index (mb3) where t1.mb3 <'000'; + +--echo # If a constant can't be represented in utf8mb3, an error is produced: +--error ER_CANT_AGGREGATE_2COLLATIONS +explain select * from t1 force index (mb3) where t1.mb3='😊'; + +--echo # +--echo # Check ref access on mb3_field=mb4_field +--echo # +--source include/explain-no-costs.inc +explain format=json +select * from t10,t1 where t10.mb4=t1.mb3; + +select * from t10,t1 where t10.mb4=t1.mb3; + +select * from t10,t1 use index() where t10.mb4=t1.mb3; + +--source include/explain-no-costs.inc +explain format=json +select * from t10,t1 where t10.mb4<=>t1.mb3; + +select * from t10,t1 where t10.mb4<=>t1.mb3; + +--source include/explain-no-costs.inc +set statement optimizer_switch='cset_narrowing=off', join_cache_level=0 for +explain format=json +select * from t10,t1 where t10.mb4=t1.mb3; + +--echo # +--echo # Check ref access on mb3_field=mb4_expr +--echo # +--source include/explain-no-costs.inc +explain format=json +select * from t10,t1 where t1.mb3=concat('',t10.mb4); + +select * from t10,t1 where t1.mb3=concat('',t10.mb4); + +select * from t10,t1 use index() where t1.mb3=concat('',t10.mb4); + +--echo # Check that ref optimizer gets the right constant. +--echo # We need a const table for that, because key=const is handled by +--echo # coercing the constant. +--echo # +--echo # So, we take the smiley: +select * from t10 where t10.pk=3; +set optimizer_trace=1; + +--echo # And see that we've got the Replacement Character in the ranges: +explain +select * from t10, t1 where t10.mb4=t1.mb3 and t10.pk=3; + +--source include/explain-no-costs.inc +select + json_detailed(json_extract(trace, '$**.range_scan_alternatives')) as JS +from + information_schema.optimizer_trace; + +select * from t10, t1 where t10.mb4=t1.mb3 and t10.pk=3; + +--echo # +--echo # Will range optimizer handle t1.mb3>t10.mb4? No... +--echo # + +--source include/explain-no-costs.inc +explain format=json +select * from t10, t1 where (t1.mb3=t10.mb4 or t1.mb3='hello') and t10.pk=3; + +--source include/explain-no-costs.inc +explain format=json +select * from t10, t1 where t1.mb3>t10.mb4 and t10.pk=3; + +--echo # For comparison, it will handle it when collations match: +create table t2 ( + mb4name varchar(32), + mb4 varchar(32) collate utf8mb4_general_ci, + key(mb4) +); +insert into t2 select * from t1; +--source include/explain-no-costs.inc +explain format=json +select * from t10, t2 where t2.mb4>t10.mb4 and t10.pk=3; + +--echo # +--echo # Check multiple equalities +--echo # + +--echo # - ref acccess lookup keys do use equality substitution, +--echo # - concat() arguments don't +--source include/explain-no-costs.inc +explain format=json +select straight_join * from t10,t1 force index(mb3),t2 +where + t1.mb3=t2.mb4 and t2.mb4=t10.mb4 and concat(t1.mb3, t2.mb4, t10.mb4)<>'Bebebe'; +select json_detailed(json_extract(trace, '$**.condition_processing')) as JS +from information_schema.optimizer_trace; + +select straight_join * from t10,t1 force index(mb3),t2 +where + t1.mb3=t2.mb4 and t2.mb4=t10.mb4 and concat(t1.mb3, t2.mb4, t10.mb4)<>'Bebebe'; + +--echo # Equality substitution doesn't happen for constants, for both narrowing +--echo # and non-narrowing comparisons: +--source include/explain-no-costs.inc +explain format=json +select * from t10,t1,t2 +where + t1.mb3=t2.mb4 and t2.mb4=t10.mb4 and t10.mb4='hello' and + concat(t1.mb3, t2.mb4, t10.mb4)<>'Bebebe'; + +select json_detailed(json_extract(trace, '$**.condition_processing')) as JS +from information_schema.optimizer_trace; + +drop table t2; +drop table t1, t10; + +set optimizer_switch=@tmp_csetn_os; + diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result index 5989abb7324..316e39b455a 100644 --- a/mysql-test/main/cte_nonrecursive.result +++ b/mysql-test/main/cte_nonrecursive.result @@ -2337,4 +2337,303 @@ set sql_mode="oracle"; with data as (select 1 as id) select id into @myid from data; set sql_mode= @save_sql_mode; +# +# MDEV-31995 Bogus error executing PS for query using CTE with renaming of columns +# +create table t1 (a int, b int); +insert into t1 values (1,1),(1,2),(1,3),(2,1),(2,2); +create table t2 (a int, b int); +insert into t2 values (3,1),(3,2),(3,3),(4,1),(4,2); +with cte (c1,c2) as +(select a as col1, sum(b) as col2 from t1 group by col1) +select * from cte; +c1 c2 +1 6 +2 3 +prepare st from "with cte (c1,c2) as +(select a as col1, sum(b) as col2 from t1 group by col1) +select * from cte"; +execute st; +c1 c2 +1 6 +2 3 +execute st; +c1 c2 +1 6 +2 3 +drop prepare st; +create procedure sp() with cte (c1,c2) as +(select a as col1, sum(b) as col2 from t1 group by col1) +select * from cte; +call sp(); +c1 c2 +1 6 +2 3 +call sp(); +c1 c2 +1 6 +2 3 +drop procedure sp; +with cte (c1,c2) as +(select a as col1, sum(b) as col2 from t1 order by col1) +select * from cte; +c1 c2 +1 9 +prepare st from "with cte (c1,c2) as +(select a as col1, sum(b) as col2 from t1 order by col1) +select * from cte"; +execute st; +c1 c2 +1 9 +execute st; +c1 c2 +1 9 +drop prepare st; +create procedure sp() with cte (c1,c2) as +(select a as col1, sum(b) as col2 from t1 order by col1) +select * from cte; +call sp(); +c1 c2 +1 9 +call sp(); +c1 c2 +1 9 +drop procedure sp; +with cte (c1,c2) as +(select a as col1, sum(b) as col2 from t1 where a > 1 group by col1 +union select a as col3, sum(b) as col4 from t2 where b > 2 group by col3), +cte2 (c3, c4) as +(select a as col5, sum(b) as col6 from t1 where a <= 1 group by col5 +union select a as col7, sum(b) as col8 from t2 where b <= 2 group by col7) +select * from cte where c1=1 union select * from cte2 where c3=3; +c1 c2 +3 3 +prepare st from "with cte (c1,c2) as +(select a as col1, sum(b) as col2 from t1 where a > 1 group by col1 +union select a as col3, sum(b) as col4 from t2 where b > 2 group by col3), +cte2 (c3, c4) as +(select a as col5, sum(b) as col6 from t1 where a <= 1 group by col5 +union select a as col7, sum(b) as col8 from t2 where b <= 2 group by col7) +select * from cte where c1=1 union select * from cte2 where c3=3"; +execute st; +c1 c2 +3 3 +execute st; +c1 c2 +3 3 +drop prepare st; +create procedure sp() with cte (c1,c2) as +(select a as col1, sum(b) as col2 from t1 where a > 1 group by col1 +union select a as col3, sum(b) as col4 from t2 where b > 2 group by col3), +cte2 (c3, c4) as +(select a as col5, sum(b) as col6 from t1 where a <= 1 group by col5 +union select a as col7, sum(b) as col8 from t2 where b <= 2 group by col7) +select * from cte where c1=1 union select * from cte2 where c3=3; +call sp(); +c1 c2 +3 3 +call sp(); +c1 c2 +3 3 +drop procedure sp; +with cte (c1,c2) as (select * from t1) +select cte.c1+1 as col1 , cte.c2 as col2 from cte where cte.c1 > 1 +union +select cte.c1 as col3, cte.c2+1 as col4 from cte where cte.c1 < 0; +col1 col2 +3 1 +3 2 +prepare st from "with cte (c1,c2) as (select * from t1) +select cte.c1+1 as col1 , cte.c2 as col2 from cte where cte.c1 > 1 +union +select cte.c1 as col3, cte.c2+1 as col4 from cte where cte.c1 < 0"; +execute st; +col1 col2 +3 1 +3 2 +execute st; +col1 col2 +3 1 +3 2 +save this to the end to test errors >drop prepare st; +create procedure sp() with cte (c1,c2) as (select * from t1) +select cte.c1+1 as col1 , cte.c2 as col2 from cte where cte.c1 > 1 +union +select cte.c1 as col3, cte.c2+1 as col4 from cte where cte.c1 < 0; +call sp(); +col1 col2 +3 1 +3 2 +call sp(); +col1 col2 +3 1 +3 2 +drop procedure sp; +insert into t1 select * from t2; +with cte (c1, c2) +as (select a, sum(b) from t1 where b > 1 group by a having sum(b) < 5) +select * from cte where c1 < 4 and c2 > 1; +c1 c2 +2 2 +# Check pushdown conditions in JSON output +explain format=json with cte (c1, c2) +as (select a, sum(b) from t1 where b > 1 group by a having sum(b) < 5) +select * from cte where c1 < 4 and c2 > 1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "", + "access_type": "ALL", + "loops": 1, + "rows": 10, + "cost": "REPLACED", + "filtered": 100, + "attached_condition": "cte.c1 < 4 and cte.c2 > 1", + "materialized": { + "query_block": { + "select_id": 2, + "cost": "REPLACED", + "having_condition": "sum(t1.b) < 5 and c2 > 1", + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 10, + "cost": "REPLACED", + "filtered": 100, + "attached_condition": "t1.b > 1 and t1.a < 4" + } + } + ] + } + } + } + } + } + } + ] + } +} +alter table t1 add column c int; +execute st; +ERROR HY000: WITH column list and SELECT field list have different column counts +drop prepare st; +drop table t1,t2; +Test out recursive CTEs +create table distances (src char(1), dest char(1), distance int); +create table city_population (city char(1), population int); +INSERT INTO `distances` VALUES ('A','A',0),('B','A',593),('C','A',800), +('D','A',221),('E','A',707),('F','A',869),('G','A',225),('H','A',519), +('A','B',919),('B','B',0),('C','B',440),('D','B',79),('E','B',79), +('F','B',154),('G','B',537),('H','B',220),('A','C',491),('B','C',794), +('C','C',0),('D','C',100),('E','C',350),('F','C',748),('G','C',712), +('H','C',315),('A','D',440),('B','D',256),('C','D',958),('D','D',0), +('E','D',255),('F','D',161),('G','D',63),('H','D',831),('A','E',968), +('B','E',345),('C','E',823),('D','E',81),('E','E',0),('F','E',436), +('G','E',373),('H','E',558),('A','F',670),('B','F',677),('C','F',375), +('D','F',843),('E','F',90),('F','F',0),('G','F',328),('H','F',881), +('A','G',422),('B','G',467),('C','G',67),('D','G',936),('E','G',480), +('F','G',592),('G','G',0),('H','G',819),('A','H',537),('B','H',229), +('C','H',534),('D','H',984),('E','H',319),('F','H',643),('G','H',257), +('H','H',0); +insert into city_population values ('A', 5000), ('B', 6000), ('C', 100000), +('D', 80000), ('E', 7000), ('F', 1000), ('G', 100), ('H', -80000); +#find the biggest city within 300 kellikams of 'E' +with recursive travel (src, path, dest, distance, population) as ( +select city, cast('' as varchar(10)), city, +0, population +from city_population where city='E' + union all +select src.src, concat(src.path, dst.dest), dst.dest, +src.distance + dst.distance, dstc.population +from travel src +join distances dst on src.dest != dst.dest +join city_population dstc on dst.dest = dstc.city +where dst.src = src.dest and src.distance + dst.distance < 300 +and length(path) < 10 +) +select * from travel where dest != 'E' order by population desc, distance +limit 1; +src path dest distance population +E FD D 251 80000 +prepare st from "with recursive travel (src, path, dest, distance, population) as ( +select city, cast('' as varchar(10)), city, +0, population +from city_population where city='E' + union all +select src.src, concat(src.path, dst.dest), dst.dest, +src.distance + dst.distance, dstc.population +from travel src +join distances dst on src.dest != dst.dest +join city_population dstc on dst.dest = dstc.city +where dst.src = src.dest and src.distance + dst.distance < 300 +and length(path) < 10 +) +select * from travel where dest != 'E' order by population desc, distance +limit 1"; +execute st; +src path dest distance population +E FD D 251 80000 +execute st; +src path dest distance population +E FD D 251 80000 +drop prepare st; +create procedure sp() with recursive travel (src, path, dest, distance, population) as ( +select city, cast('' as varchar(10)), city, +0, population +from city_population where city='E' + union all +select src.src, concat(src.path, dst.dest), dst.dest, +src.distance + dst.distance, dstc.population +from travel src +join distances dst on src.dest != dst.dest +join city_population dstc on dst.dest = dstc.city +where dst.src = src.dest and src.distance + dst.distance < 300 +and length(path) < 10 +) +select * from travel where dest != 'E' order by population desc, distance +limit 1; +call sp(); +src path dest distance population +E FD D 251 80000 +call sp(); +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 c420a5e0483..aa573a76454 100644 --- a/mysql-test/main/cte_nonrecursive.test +++ b/mysql-test/main/cte_nonrecursive.test @@ -1796,4 +1796,187 @@ 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 # + +create table t1 (a int, b int); +insert into t1 values (1,1),(1,2),(1,3),(2,1),(2,2); +create table t2 (a int, b int); +insert into t2 values (3,1),(3,2),(3,3),(4,1),(4,2); + +let $q= +with cte (c1,c2) as + (select a as col1, sum(b) as col2 from t1 group by col1) +select * from cte; + +eval $q; + +eval prepare st from "$q"; +execute st; +execute st; +drop prepare st; + +eval create procedure sp() $q; +call sp(); +call sp(); +drop procedure sp; + +let $q= +with cte (c1,c2) as + (select a as col1, sum(b) as col2 from t1 order by col1) +select * from cte; + +eval $q; + +eval prepare st from "$q"; +execute st; +execute st; +drop prepare st; + +eval create procedure sp() $q; +call sp(); +call sp(); +drop procedure sp; + +let $q= +with cte (c1,c2) as + (select a as col1, sum(b) as col2 from t1 where a > 1 group by col1 + union select a as col3, sum(b) as col4 from t2 where b > 2 group by col3), +cte2 (c3, c4) as + (select a as col5, sum(b) as col6 from t1 where a <= 1 group by col5 + union select a as col7, sum(b) as col8 from t2 where b <= 2 group by col7) +select * from cte where c1=1 union select * from cte2 where c3=3; + +eval $q; + +eval prepare st from "$q"; +execute st; +execute st; +drop prepare st; + +eval create procedure sp() $q; +call sp(); +call sp(); +drop procedure sp; + +let $q= +with cte (c1,c2) as (select * from t1) +select cte.c1+1 as col1 , cte.c2 as col2 from cte where cte.c1 > 1 +union +select cte.c1 as col3, cte.c2+1 as col4 from cte where cte.c1 < 0; + +eval $q; + +eval prepare st from "$q"; +execute st; +execute st; +--echo save this to the end to test errors >drop prepare st; + +eval create procedure sp() $q; +call sp(); +call sp(); +drop procedure sp; + +insert into t1 select * from t2; + +let $q= +with cte (c1, c2) + as (select a, sum(b) from t1 where b > 1 group by a having sum(b) < 5) +select * from cte where c1 < 4 and c2 > 1; + +eval $q; + +--echo # Check pushdown conditions in JSON output +--source include/analyze-format.inc +eval explain format=json $q; + +alter table t1 add column c int; + +--error ER_WITH_COL_WRONG_LIST +execute st; + +drop prepare st; +drop table t1,t2; + +--echo Test out recursive CTEs + +create table distances (src char(1), dest char(1), distance int); +create table city_population (city char(1), population int); +INSERT INTO `distances` VALUES ('A','A',0),('B','A',593),('C','A',800), +('D','A',221),('E','A',707),('F','A',869),('G','A',225),('H','A',519), +('A','B',919),('B','B',0),('C','B',440),('D','B',79),('E','B',79), +('F','B',154),('G','B',537),('H','B',220),('A','C',491),('B','C',794), +('C','C',0),('D','C',100),('E','C',350),('F','C',748),('G','C',712), +('H','C',315),('A','D',440),('B','D',256),('C','D',958),('D','D',0), +('E','D',255),('F','D',161),('G','D',63),('H','D',831),('A','E',968), +('B','E',345),('C','E',823),('D','E',81),('E','E',0),('F','E',436), +('G','E',373),('H','E',558),('A','F',670),('B','F',677),('C','F',375), +('D','F',843),('E','F',90),('F','F',0),('G','F',328),('H','F',881), +('A','G',422),('B','G',467),('C','G',67),('D','G',936),('E','G',480), +('F','G',592),('G','G',0),('H','G',819),('A','H',537),('B','H',229), +('C','H',534),('D','H',984),('E','H',319),('F','H',643),('G','H',257), +('H','H',0); +insert into city_population values ('A', 5000), ('B', 6000), ('C', 100000), +('D', 80000), ('E', 7000), ('F', 1000), ('G', 100), ('H', -80000); + +--echo #find the biggest city within 300 kellikams of 'E' +let $q= +with recursive travel (src, path, dest, distance, population) as ( + select city, cast('' as varchar(10)), city, + 0, population + from city_population where city='E' + union all + select src.src, concat(src.path, dst.dest), dst.dest, + src.distance + dst.distance, dstc.population + from travel src + join distances dst on src.dest != dst.dest + join city_population dstc on dst.dest = dstc.city + where dst.src = src.dest and src.distance + dst.distance < 300 + and length(path) < 10 + ) +select * from travel where dest != 'E' order by population desc, distance +limit 1; + +eval $q; + +eval prepare st from "$q"; +execute st; +execute st; +drop prepare st; + +eval create procedure sp() $q; +call sp(); +call sp(); +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_binary.result b/mysql-test/main/ctype_binary.result index 25685e2732f..418f1c14600 100644 --- a/mysql-test/main/ctype_binary.result +++ b/mysql-test/main/ctype_binary.result @@ -3383,6 +3383,50 @@ INSERT INTO t VALUES (0,0); DELETE FROM t WHERE c2= "'a'" of collation `latin1_german1_ci` EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where +Warnings: +Note 1105 Cannot use key `s2` part[0] for lookup: `test`.`t1`.`s2` of collation `latin1_swedish_ci` = "'a'" of collation `latin1_german1_ci` EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range s1 s1 11 NULL 1 Using index condition EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where +Warnings: +Note 1105 Cannot use key `s2` part[0] for lookup: `test`.`t1`.`s2` of collation `latin1_swedish_ci` like "'a' collate latin1_german1_ci" of collation `latin1_german1_ci` DROP TABLE t1; create table t1(f1 varchar(10) character set latin2 collate latin2_hungarian_ci, key(f1)); insert into t1 set f1=0x3F3F9DC73F; @@ -643,8 +649,8 @@ check table t1 extended; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; -select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); -least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; +f1 a create table t1 select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; @@ -655,12 +661,11 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate -latin5_turkish_ci then 2 else 3 end; -case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate -latin5_turkish_ci then 2 else 3 end +latin5_turkish_ci then 2 else 3 end as exp; +exp 3 -select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); -concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) +select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as exp; +exp abc # # Bug#11765016 57926: ILLEGAL MIX OF COLLATIONS FOR OPERATION 'UNION' .. USING CONCAT/FUNCTION/ diff --git a/mysql-test/main/ctype_collate.test b/mysql-test/main/ctype_collate.test index ab79a6cd51a..2366b130e7c 100644 --- a/mysql-test/main/ctype_collate.test +++ b/mysql-test/main/ctype_collate.test @@ -1,5 +1,3 @@ -#remove this include after fix MDEV-27871 ---source include/no_view_protocol.inc --disable_warnings DROP TABLE IF EXISTS t1; @@ -248,16 +246,16 @@ drop table t1; # # Bug#41627 Illegal mix of collations in LEAST / GREATEST / CASE # -select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); +select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; create table t1 select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; show create table t1; drop table t1; select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate -latin5_turkish_ci then 2 else 3 end; +latin5_turkish_ci then 2 else 3 end as exp; -select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci); +select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as exp; --echo # diff --git a/mysql-test/main/ctype_cp932.result b/mysql-test/main/ctype_cp932.result index 47b3cbc12f8..a66bf1da027 100644 --- a/mysql-test/main/ctype_cp932.result +++ b/mysql-test/main/ctype_cp932.result @@ -888,7 +888,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 # @@ -897,7 +897,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 # @@ -906,7 +906,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 # @@ -916,7 +916,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 # @@ -925,7 +925,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_eucjpms.test b/mysql-test/main/ctype_eucjpms.test index 3b54d667ecb..12f1d5fc507 100644 --- a/mysql-test/main/ctype_eucjpms.test +++ b/mysql-test/main/ctype_eucjpms.test @@ -1,6 +1,4 @@ # remove this include in 10.6 version, -# if MDEV-27871 will be fix ---source include/no_view_protocol.inc -- source include/have_eucjpms.inc diff --git a/mysql-test/main/ctype_gbk.result b/mysql-test/main/ctype_gbk.result index 6e3cddf0032..f27c572098d 100644 --- a/mysql-test/main/ctype_gbk.result +++ b/mysql-test/main/ctype_gbk.result @@ -6138,13 +6138,13 @@ DROP TABLE t1; # MDEV-7661 Unexpected result for: CAST(0xHHHH AS CHAR CHARACTER SET xxx) for incorrect byte sequences # set sql_mode=''; -SELECT HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)); -HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)) +SELECT HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)) as exp; +exp 3F41 Warnings: Warning 1300 Invalid gb2312 character string: '\xA3A' -SELECT HEX(CONVERT(CAST(0xA341 AS CHAR CHARACTER SET gb2312) USING utf8)); -HEX(CONVERT(CAST(0xA341 AS CHAR CHARACTER SET gb2312) USING utf8)) +SELECT HEX(CONVERT(CAST(0xA341 AS CHAR CHARACTER SET gb2312) USING utf8)) as exp; +exp 3F41 Warnings: Warning 1300 Invalid gb2312 character string: '\xA3A' diff --git a/mysql-test/main/ctype_gbk.test b/mysql-test/main/ctype_gbk.test index 0d9d1d8b30a..355638340f6 100644 --- a/mysql-test/main/ctype_gbk.test +++ b/mysql-test/main/ctype_gbk.test @@ -452,8 +452,8 @@ DROP TABLE t1; #enable after fix MDEV-27871 --disable_view_protocol set sql_mode=''; -SELECT HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)); -SELECT HEX(CONVERT(CAST(0xA341 AS CHAR CHARACTER SET gb2312) USING utf8)); +SELECT HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)) as exp; +SELECT HEX(CONVERT(CAST(0xA341 AS CHAR CHARACTER SET gb2312) USING utf8)) as exp; set sql_mode=default; --enable_view_protocol diff --git a/mysql-test/main/ctype_sjis.result b/mysql-test/main/ctype_sjis.result index ee760d9c4eb..7a1f4cf5483 100644 --- a/mysql-test/main/ctype_sjis.result +++ b/mysql-test/main/ctype_sjis.result @@ -19619,7 +19619,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 # @@ -19628,7 +19628,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 # @@ -19637,7 +19637,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 # @@ -19647,7 +19647,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 # @@ -19656,7 +19656,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/ctype_sjis.test b/mysql-test/main/ctype_sjis.test index c05cbbad01c..59c30cb4dd4 100644 --- a/mysql-test/main/ctype_sjis.test +++ b/mysql-test/main/ctype_sjis.test @@ -209,9 +209,6 @@ DROP TABLE t1; --echo # WL#3664 WEIGHT_STRING --echo # -# enable view-protocol after fix MDEV-27871 ---disable_view_protocol - set names sjis; --source include/weight_string.inc --source include/weight_string_l1.inc @@ -223,8 +220,6 @@ set collation_connection=sjis_bin; --source include/weight_string_l1.inc --source include/weight_string_8140.inc ---enable_view_protocol - --echo # --echo # End of 5.6 tests --echo # diff --git a/mysql-test/main/ctype_uca.result b/mysql-test/main/ctype_uca.result index b567137df1e..f9b831176f8 100644 --- a/mysql-test/main/ctype_uca.result +++ b/mysql-test/main/ctype_uca.result @@ -7964,8 +7964,8 @@ hex(weight_string(cast(_latin1 0xDF6368 as char),25, 4,0xC0)) # # Bug#33077 weight of supplementary characters is not 0xfffd # -select hex(weight_string(_utf8mb4 0xF0908080 /* U+10000 */ collate utf8mb4_unicode_ci)); -hex(weight_string(_utf8mb4 0xF0908080 /* U+10000 */ collate utf8mb4_unicode_ci)) +select hex(weight_string(_utf8mb4 0xF0908080 /* U+10000 */ collate utf8mb4_unicode_ci)) as exp; +exp FFFD # # Bug#53064 garbled data when using utf8_german2_ci collation diff --git a/mysql-test/main/ctype_uca.test b/mysql-test/main/ctype_uca.test index bc08714367b..8ccda3e680c 100644 --- a/mysql-test/main/ctype_uca.test +++ b/mysql-test/main/ctype_uca.test @@ -552,10 +552,7 @@ set @@collation_connection=ucs2_czech_ci; --echo # --echo # Bug#33077 weight of supplementary characters is not 0xfffd --echo # -#enable_after_fix MDEV-27871 ---disable_view_protocol -select hex(weight_string(_utf8mb4 0xF0908080 /* U+10000 */ collate utf8mb4_unicode_ci)); ---enable_view_protocol +select hex(weight_string(_utf8mb4 0xF0908080 /* U+10000 */ collate utf8mb4_unicode_ci)) as exp; --echo # --echo # Bug#53064 garbled data when using utf8_german2_ci collation diff --git a/mysql-test/main/ctype_utf32.result b/mysql-test/main/ctype_utf32.result index 3129651defd..f9523a783ea 100644 --- a/mysql-test/main/ctype_utf32.result +++ b/mysql-test/main/ctype_utf32.result @@ -2958,5 +2958,69 @@ HEX(OCT(a)) DROP TABLE t; SET NAMES utf8; # +# MDEV-28835 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on INSERT +# +SET sql_mode='',character_set_connection=utf32; +CREATE TABLE t (c ENUM ('','')) CHARACTER SET utf32; +Warnings: +Note 1291 Column 'c' has duplicated value '' in ENUM +INSERT INTO t VALUES (DATE_FORMAT('2004-02-02','%W')); +Warnings: +Warning 1265 Data truncated for column 'c' at row 1 +DROP TABLE t; +SET sql_mode=DEFAULT; +# utf32 format, utf32 result +SELECT DATE_FORMAT('2004-02-02','%W'); +DATE_FORMAT('2004-02-02','%W') +Monday +SELECT HEX(DATE_FORMAT('2004-02-02','%W')); +HEX(DATE_FORMAT('2004-02-02','%W')) +0000004D0000006F0000006E000000640000006100000079 +SELECT DATE_FORMAT(TIME'-01:01:01','%h'); +DATE_FORMAT(TIME'-01:01:01','%h') +-01 +SELECT HEX(DATE_FORMAT(TIME'-01:01:01','%h')); +HEX(DATE_FORMAT(TIME'-01:01:01','%h')) +0000002D0000003000000031 +# utf8 format, utf32 result +SELECT DATE_FORMAT('2004-02-02',_utf8'%W'); +DATE_FORMAT('2004-02-02',_utf8'%W') +Monday +SELECT HEX(DATE_FORMAT('2004-02-02',_utf8'%W')); +HEX(DATE_FORMAT('2004-02-02',_utf8'%W')) +0000004D0000006F0000006E000000640000006100000079 +SELECT DATE_FORMAT(TIME'-01:01:01',_utf8'%h'); +DATE_FORMAT(TIME'-01:01:01',_utf8'%h') +-01 +SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_utf8'%h')); +HEX(DATE_FORMAT(TIME'-01:01:01',_utf8'%h')) +0000002D0000003000000031 +# utf32 format, utf8 result +SET NAMES utf8; +SELECT DATE_FORMAT('2004-02-02',CONVERT('%W' USING utf32)); +DATE_FORMAT('2004-02-02',CONVERT('%W' USING utf32)) +Monday +SELECT HEX(DATE_FORMAT('2004-02-02',CONVERT('%W' USING utf32))); +HEX(DATE_FORMAT('2004-02-02',CONVERT('%W' USING utf32))) +4D6F6E646179 +SELECT DATE_FORMAT(TIME'-01:01:01',CONVERT('%h' USING utf32)); +DATE_FORMAT(TIME'-01:01:01',CONVERT('%h' USING utf32)) +-01 +SELECT HEX(DATE_FORMAT(TIME'-01:01:01',CONVERT('%h' USING utf32))); +HEX(DATE_FORMAT(TIME'-01:01:01',CONVERT('%h' USING utf32))) +2D3031 +# non-BMP characters in format, utf8mb3 result +# expect non-convertable characters to be replaced to '?' +SET NAMES utf8mb3; +SET @format= CONCAT(CONVERT('%h' USING utf32), +_utf32 0x0010FFFF /*a non-BMP character*/, +CONVERT('%i' USING utf32)); +SELECT DATE_FORMAT(TIME'11:22:33',@format); +DATE_FORMAT(TIME'11:22:33',@format) +11?22 +SELECT HEX(DATE_FORMAT(TIME'11:22:33',@format)); +HEX(DATE_FORMAT(TIME'11:22:33',@format)) +31313F3232 +# # End of 10.4 tests # diff --git a/mysql-test/main/ctype_utf32.test b/mysql-test/main/ctype_utf32.test index 93cfc0d46a7..bcbc3b14691 100644 --- a/mysql-test/main/ctype_utf32.test +++ b/mysql-test/main/ctype_utf32.test @@ -1120,6 +1120,48 @@ SELECT HEX(OCT(a)) FROM t; DROP TABLE t; SET NAMES utf8; +--echo # +--echo # MDEV-28835 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on INSERT +--echo # + +# --view-protocol does not yet work well with character set introducers + +--disable_view_protocol + +SET sql_mode='',character_set_connection=utf32; +CREATE TABLE t (c ENUM ('','')) CHARACTER SET utf32; +INSERT INTO t VALUES (DATE_FORMAT('2004-02-02','%W')); +DROP TABLE t; +SET sql_mode=DEFAULT; + +--echo # utf32 format, utf32 result +SELECT DATE_FORMAT('2004-02-02','%W'); +SELECT HEX(DATE_FORMAT('2004-02-02','%W')); +SELECT DATE_FORMAT(TIME'-01:01:01','%h'); +SELECT HEX(DATE_FORMAT(TIME'-01:01:01','%h')); + +--echo # utf8 format, utf32 result +SELECT DATE_FORMAT('2004-02-02',_utf8'%W'); +SELECT HEX(DATE_FORMAT('2004-02-02',_utf8'%W')); +SELECT DATE_FORMAT(TIME'-01:01:01',_utf8'%h'); +SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_utf8'%h')); + +--echo # utf32 format, utf8 result +SET NAMES utf8; +SELECT DATE_FORMAT('2004-02-02',CONVERT('%W' USING utf32)); +SELECT HEX(DATE_FORMAT('2004-02-02',CONVERT('%W' USING utf32))); +SELECT DATE_FORMAT(TIME'-01:01:01',CONVERT('%h' USING utf32)); +SELECT HEX(DATE_FORMAT(TIME'-01:01:01',CONVERT('%h' USING utf32))); + +--echo # non-BMP characters in format, utf8mb3 result +--echo # expect non-convertable characters to be replaced to '?' +SET NAMES utf8mb3; +SET @format= CONCAT(CONVERT('%h' USING utf32), + _utf32 0x0010FFFF /*a non-BMP character*/, + CONVERT('%i' USING utf32)); +SELECT DATE_FORMAT(TIME'11:22:33',@format); +SELECT HEX(DATE_FORMAT(TIME'11:22:33',@format)); +--enable_view_protocol --echo # --echo # End of 10.4 tests diff --git a/mysql-test/main/ctype_utf8_uca.result b/mysql-test/main/ctype_utf8_uca.result index 97bdadbb97b..49e1dc65b8f 100644 --- a/mysql-test/main/ctype_utf8_uca.result +++ b/mysql-test/main/ctype_utf8_uca.result @@ -977,6 +977,20 @@ INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/; ERROR 23000: Duplicate entry 'ß ' for key 'a' DROP TABLE t1; EXECUTE IMMEDIATE REPLACE( +'CREATE TABLE t1 ( ' + ' a CHAR(20) COLLATE ,' + 'UNIQUE(a(3)))', +'', @@collation_connection); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`(3)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss '); +INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/; +DROP TABLE t1; +EXECUTE IMMEDIATE REPLACE( 'CREATE TABLE t1 ( ' ' a CHAR(20) COLLATE ,' 'UNIQUE(a(3)) USING HASH)', @@ -1053,6 +1067,145 @@ INSERT INTO t1 VALUES ('ss '); INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/; DROP TABLE t1; SET DEFAULT_STORAGE_ENGINE=DEFAULT; +SET default_storage_engine=MyISAM; +# +# MDEV-30048 Prefix keys for CHAR work differently for MyISAM vs InnoDB +# +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(2))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`(2)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(120) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(120) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`(100)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +# +# MDEV-30050 Inconsistent results of DISTINCT with NOPAD +# +CREATE TABLE t1 (c CHAR(100) COLLATE utf8mb3_unicode_nopad_ci); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +SET big_tables=0; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +SET big_tables=1; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +DROP TABLE t1; +SET big_tables=DEFAULT; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SET default_storage_engine=MEMORY; +# +# MDEV-30048 Prefix keys for CHAR work differently for MyISAM vs InnoDB +# +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(2))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`(2)) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(120) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(120) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`(100)) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +# +# MDEV-30050 Inconsistent results of DISTINCT with NOPAD +# +CREATE TABLE t1 (c CHAR(100) COLLATE utf8mb3_unicode_nopad_ci); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +SET big_tables=0; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +SET big_tables=1; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +DROP TABLE t1; +SET big_tables=DEFAULT; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SET default_storage_engine=DEFAULT; # # End of 10.4 tests # diff --git a/mysql-test/main/ctype_utf8_uca.test b/mysql-test/main/ctype_utf8_uca.test index 6f89d646260..df9e70590e3 100644 --- a/mysql-test/main/ctype_utf8_uca.test +++ b/mysql-test/main/ctype_utf8_uca.test @@ -68,6 +68,14 @@ SET DEFAULT_STORAGE_ENGINE=HEAP; SET DEFAULT_STORAGE_ENGINE=DEFAULT; + +SET default_storage_engine=MyISAM; +--source include/ctype_utf8mb3_uca_char.inc +SET default_storage_engine=MEMORY; +--source include/ctype_utf8mb3_uca_char.inc +SET default_storage_engine=DEFAULT; + + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/delayed.result b/mysql-test/main/delayed.result index 472a3cd53d5..2facd37263f 100644 --- a/mysql-test/main/delayed.result +++ b/mysql-test/main/delayed.result @@ -1,4 +1,3 @@ -drop table if exists t1; create table t1 (a char(10), tmsp timestamp); insert into t1 set a = 1; insert delayed into t1 set a = 2; @@ -259,7 +258,6 @@ INSERT DELAYED INTO t1 SET b= b(); ERROR 42000: FUNCTION test.b does not exist DROP TABLE t1; End of 5.0 tests -DROP TABLE IF EXISTS t1,t2; SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'; CREATE TABLE `t1` ( `id` int(11) PRIMARY KEY auto_increment, @@ -293,7 +291,6 @@ set global low_priority_updates = 1; select @@global.low_priority_updates; @@global.low_priority_updates 1 -drop table if exists t1; create table t1 (a int, b int); insert into t1 values (1,1); lock table t1 read; @@ -322,7 +319,6 @@ set global low_priority_updates = @old_delayed_updates; # # Bug #47682 strange behaviour of INSERT DELAYED # -DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 (f1 integer); CREATE TABLE t2 (f1 integer); FLUSH TABLES WITH READ LOCK; @@ -335,8 +331,6 @@ End of 5.1 tests # # Bug #47274 assert in open_table on CREATE TABLE # -DROP TABLE IF EXISTS t1; -DROP TABLE IF EXISTS t2; CREATE TABLE t1 ( f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1)); # The following CREATE TABLEs before gave an assert. INSERT DELAYED t1 VALUES (4); @@ -352,14 +346,12 @@ CREATE TABLE t2 (f1 INTEGER); INSERT DELAYED t1 VALUES (7); CREATE TABLE t1 LIKE t2; ERROR 42S01: Table 't1' already exists -DROP TABLE t2; -DROP TABLE t1; +DROP TABLE t2, t1; # # Test for bug #56251 "Deadlock with INSERT DELAYED and MERGE tables". # connect con1,localhost,root,,; connection default; -drop table if exists t1, t2, tm; create table t1(a int); create table t2(a int); create table tm(a int) engine=merge union=(t1, t2); diff --git a/mysql-test/main/delayed.test b/mysql-test/main/delayed.test index 50d1c1e8c0a..36f2b6653c9 100644 --- a/mysql-test/main/delayed.test +++ b/mysql-test/main/delayed.test @@ -21,9 +21,6 @@ select @@global.default_storage_engine in ("memory","myisam","archive","blackhole") as `TRUE`; enable_query_log; ---disable_warnings -drop table if exists t1; ---enable_warnings create table t1 (a char(10), tmsp timestamp); insert into t1 set a = 1; insert delayed into t1 set a = 2; @@ -276,9 +273,6 @@ DROP TABLE t1; # # Bug#27358 INSERT DELAYED does not honour SQL_MODE of the client # ---disable_warnings -DROP TABLE IF EXISTS t1,t2; ---enable_warnings SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'; CREATE TABLE `t1` ( `id` int(11) PRIMARY KEY auto_increment, @@ -315,9 +309,6 @@ set @old_delayed_updates = @@global.low_priority_updates; set global low_priority_updates = 1; select @@global.low_priority_updates; ---disable_warnings -drop table if exists t1; ---enable_warnings create table t1 (a int, b int); insert into t1 values (1,1); lock table t1 read; @@ -351,10 +342,6 @@ set global low_priority_updates = @old_delayed_updates; --echo # Bug #47682 strange behaviour of INSERT DELAYED --echo # ---disable_warnings -DROP TABLE IF EXISTS t1, t2; ---enable_warnings - CREATE TABLE t1 (f1 integer); CREATE TABLE t2 (f1 integer); @@ -378,11 +365,6 @@ DROP TABLE t1, t2; --echo # Bug #47274 assert in open_table on CREATE TABLE --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; -DROP TABLE IF EXISTS t2; ---enable_warnings - CREATE TABLE t1 ( f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1)); --echo # The following CREATE TABLEs before gave an assert. @@ -404,9 +386,7 @@ INSERT DELAYED t1 VALUES (7); --error ER_TABLE_EXISTS_ERROR CREATE TABLE t1 LIKE t2; -DROP TABLE t2; -DROP TABLE t1; - +DROP TABLE t2, t1; # The following test is disabled as it fails randomly if (0) @@ -420,10 +400,6 @@ if (0) --disable_ps_protocol --disable_view_protocol ---disable_warnings -DROP TABLE IF EXISTS t1, t2; ---enable_warnings - CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT); CREATE TABLE t3 (a INT); @@ -577,9 +553,6 @@ DROP TABLE t1, t2, t3; --disable_view_protocol connect (con1,localhost,root,,); connection default; ---disable_warnings -drop table if exists t1, t2, tm; ---enable_warnings create table t1(a int); create table t2(a int); create table tm(a int) engine=merge union=(t1, t2); diff --git a/mysql-test/main/delete.result b/mysql-test/main/delete.result index c4bf335091a..21a3bedcaed 100644 --- a/mysql-test/main/delete.result +++ b/mysql-test/main/delete.result @@ -610,4 +610,49 @@ c1 c2 c3 2 1 4 2 2 5 drop table t1; +# +# MDEV-32212 DELETE with ORDER BY and semijoin optimization causing crash +# +CREATE TABLE t1 (c1 INT) ENGINE=InnoDB; +CREATE TABLE t2 (c2 INT) ENGINE=InnoDB; +INSERT INTO t1 values (1),(2),(3),(4),(5),(6); +INSERT INTO t2 values (2); +DELETE FROM t1 WHERE c1 IN (select c2 from t2); +select * from t1; +c1 +1 +3 +4 +5 +6 +truncate t1; +truncate t2; +INSERT INTO t1 values (1),(2),(3),(4),(5),(6); +INSERT INTO t2 values (2); +check sj optimization with order-by +analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using filesort +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 1.00 100.00 16.67 Using where; FirstMatch(t1) +select * from t1; +c1 +1 +3 +4 +5 +6 +truncate t2; +INSERT INTO t2 values (3); +disallows sj optimization +analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1 limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 1.00 100.00 100.00 Using where; Using filesort +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 1 1.00 100.00 20.00 Using where +select * from t1; +c1 +1 +4 +5 +6 +DROP TABLE t1, t2; End of 11.1 tests diff --git a/mysql-test/main/delete.test b/mysql-test/main/delete.test index 583d8223168..54d0ed7f014 100644 --- a/mysql-test/main/delete.test +++ b/mysql-test/main/delete.test @@ -667,4 +667,31 @@ select *from t1; drop table t1; +--echo # +--echo # MDEV-32212 DELETE with ORDER BY and semijoin optimization causing crash +--echo # +--source include/have_innodb.inc + +CREATE TABLE t1 (c1 INT) ENGINE=InnoDB; +CREATE TABLE t2 (c2 INT) ENGINE=InnoDB; +INSERT INTO t1 values (1),(2),(3),(4),(5),(6); +INSERT INTO t2 values (2); + +DELETE FROM t1 WHERE c1 IN (select c2 from t2); +select * from t1; +truncate t1; +truncate t2; +INSERT INTO t1 values (1),(2),(3),(4),(5),(6); +INSERT INTO t2 values (2); +--echo check sj optimization with order-by +analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1; +select * from t1; +truncate t2; +INSERT INTO t2 values (3); +--echo disallows sj optimization +analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1 limit 1; +select * from t1; + +DROP TABLE t1, t2; + --echo End of 11.1 tests diff --git a/mysql-test/main/delete_use_source.test b/mysql-test/main/delete_use_source.test index 9625431c1a8..a0135e6b4d4 100644 --- a/mysql-test/main/delete_use_source.test +++ b/mysql-test/main/delete_use_source.test @@ -16,6 +16,7 @@ analyze table t1; --echo # Delete with limit (quick select - range acces) --echo # +--disable_view_protocol start transaction; --enable_info delete from t1 where (select count(*) from t1 b where b.c1=t1.c1) = 500 limit 1; @@ -111,6 +112,7 @@ rollback; start transaction; delete from t1 where (select count(*) from t1 b where b.c1=t1.c1) = 500 order by c2 desc limit 10 returning c1,c2; rollback; +--enable_view_protocol drop view v1; drop table t1; diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index a83374f469d..d91b4510dee 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -22791,6 +22791,121 @@ a SUBQ 4 1=11373 5 1=11612 drop table t1,t2,t3; +# +# MDEV-32064: usage of splittable derived table in query +# with IN subquery in WHERE +# +CREATE TABLE t1 ( +id int unsigned NOT NULL, +valint1 int unsigned, +valdouble double, +valdate datetime, +PRIMARY KEY (id), +KEY (valint1), +KEY (valint1,valdate) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES +(1,3289763,1,'2021-02-09 18:31:35'),(2,3289750,1,'2021-02-09 18:31:35'), +(3,3289780,1173,'2021-02-09 18:31:35'),(4,3289762,2,'2021-02-09 18:31:36'), +(5,3289774,2334,'2021-02-09 18:31:36'),(6,3289739,1934,'2021-02-09 18:31:36'), +(7,3289761,1,'2021-02-09 18:31:37'),(8,3289763,1,'2021-02-10 11:05:19'), +(9,3289750,1,'2021-02-10 11:05:19'),(10,3289780,0,'2021-02-10 11:05:35'), +(11,3289762,2,'2021-02-10 11:05:47'),(12,3289774,429,'2021-02-10 11:05:47'), +(13,3289739,1958,'2021-02-10 11:06:00'),(14,3289761,1,'2021-02-10 11:06:08'), +(15,3289957,0,'2021-02-10 13:04:44'),(16,3289988,1993,'2021-02-10 13:04:45'), +(17,3289951,1896,'2021-02-10 13:04:59'),(18,3289957,1994,'2021-02-10 13:07:40'), +(19,3289988,5,'2021-02-10 13:07:40'),(20,3289951,1897,'2021-02-10 13:07:40'), +(21,3289594,0,'2021-02-11 14:19:38'),(22,3289642,0,'2021-02-11 14:19:38'), +(23,3289626,2150,'2021-02-11 14:19:38'),(24,3289562,0,'2021-02-11 14:19:39'), +(25,3289593,1046,'2021-02-11 14:19:39'),(26,3289496,1,'2021-02-11 14:19:45'), +(27,3289475,1074,'2021-02-11 14:19:50'),(28,3289658,1155,'2021-02-11 14:19:56'), +(29,3289595,0,'2021-02-11 14:20:01'),(30,3290334,903,'2021-02-11 16:22:44'), +(31,3290284,479,'2021-02-11 16:23:00'),(32,3290327,236,'2021-02-11 16:23:00'), +(33,3290854,0,'2021-02-15 17:29:59'),(34,3290824,0,'2021-02-15 17:30:13'), +(35,3290875,0,'2021-02-15 17:30:14'),(36,3290897,2,'2021-02-15 17:30:19'), +(37,3290800,0,'2021-02-15 17:30:24'),(38,3290822,0,'2021-02-15 17:30:25'), +(39,3290901,2667,'2021-02-15 17:30:30'),(40,3290835,0,'2021-02-15 17:30:36'), +(41,3290875,0,'2021-02-15 17:35:33'),(42,3290824,1330,'2021-02-15 17:35:39'), +(43,3290854,769,'2021-02-15 17:35:44'),(44,3290897,2,'2021-02-15 17:35:50'), +(45,3290822,748,'2021-02-15 17:35:50'),(46,3290800,1007,'2021-02-15 17:35:56'), +(47,3290901,7018,'2021-02-15 17:35:56'),(48,3290835,779,'2021-02-15 17:36:17'), +(49,3290824,1329,'2021-02-15 17:40:30'),(50,3290875,764,'2021-02-15 17:40:31'), +(51,3290854,763,'2021-02-15 17:40:36'),(52,3290897,2347,'2021-02-15 17:40:47'), +(53,3290822,1,'2021-02-15 17:41:01'),(54,3290800,1018,'2021-02-15 17:41:07'), +(55,3290901,3936,'2021-02-15 17:41:08'),(56,3290835,784,'2021-02-15 17:41:24'), +(57,3290824,1313,'2021-02-15 17:44:47'),(58,3290875,758,'2021-02-15 17:44:48'), +(59,3290854,767,'2021-02-15 17:44:48'),(60,3290897,2438,'2021-02-15 17:44:48'), +(61,3290822,738,'2021-02-15 17:44:49'),(62,3290800,1003,'2021-02-15 17:44:54'), +(63,3290901,4686,'2021-02-15 17:44:55'),(64,3290835,778,'2021-02-15 17:45:13'), +(65,3290824,1303,'2021-02-15 17:51:16'),(66,3290875,753,'2021-02-15 17:51:16'), +(67,3290854,766,'2021-02-15 17:51:22'),(68,3290897,1,'2021-02-15 17:51:22'), +(69,3290822,743,'2021-02-15 17:51:28'),(70,3290901,5718,'2021-02-15 17:51:33'), +(71,3290800,1018,'2021-02-15 17:51:34'),(72,3290835,785,'2021-02-15 17:51:48'), +(73,3290824,1310,'2021-02-15 18:21:30'),(74,3290875,754,'2021-02-15 18:21:30'), +(75,3290854,782,'2021-02-15 18:21:36'),(76,3290897,2,'2021-02-15 18:21:36'), +(77,3290822,745,'2021-02-15 18:21:53'),(78,3290800,1011,'2021-02-15 18:21:54'), +(79,3290901,8998,'2021-02-15 18:21:54'),(80,3290835,0,'2021-02-15 18:22:00'), +(81,3290936,0,'2021-02-15 18:25:28'),(82,3290895,0,'2021-02-15 18:25:28'), +(83,3290832,0,'2021-02-15 18:25:28'),(84,3290878,796,'2021-02-15 18:25:52'), +(85,3290900,730,'2021-02-15 18:25:52'),(86,3290856,0,'2021-02-15 18:26:11'), +(87,3290904,816,'2021-02-15 18:26:17'),(88,3290882,0,'2021-02-15 18:26:25'), +(89,3290883,1031,'2021-02-15 18:27:16'),(90,3290918,1749,'2021-02-15 18:27:17'), +(91,3290831,0,'2021-02-15 18:59:11'),(92,3290884,477,'2021-02-15 18:59:12'), +(93,3290899,483,'2021-02-15 18:59:12'),(94,3290848,486,'2021-02-15 18:59:35'), +(95,3290880,487,'2021-02-15 18:59:35'),(96,3290798,0,'2021-02-15 18:59:52'), +(97,3290777,983,'2021-02-15 19:00:10'),(98,3290811,488,'2021-02-15 19:00:10'), +(99,3290917,1283,'2021-02-15 19:00:36'),(100,3290858,482,'2021-02-15 19:00:42'); +CREATE TABLE t2 (a int) ENGINE=MYISAM; +INSERT INTO t2 VALUES +(3289475),(3289496),(3289562),(3289593),(3289594),(3289595),(3289626), +(3289642),(3289658),(3289739),(3289750),(3289761),(3289762),(3289763), +(3289774),(3289780),(3289951),(3289957),(3289988),(3290034),(1231562); +ANALYZE TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +EXPLAIN SELECT t1.valdouble, t1.valint1 +FROM t1, +(SELECT max(t.valdate) AS maxdate, t.valint1 FROM t1 t GROUP BY t.valint1) +AS dt +WHERE t1.valint1 = dt.valint1 AND +t1.valdate = dt.maxdate AND +t1.valint1 IN (SELECT * FROM t2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 21 Using where; Start temporary +1 PRIMARY t1 ref valint1,valint1_2 valint1 5 test.t2.a 2 Using index condition; Using where; End temporary +1 PRIMARY ref key0 key0 11 test.t1.valdate,test.t1.valint1 1 +2 LATERAL DERIVED t ref valint1,valint1_2 valint1 5 test.t2.a 2 Using index condition +SELECT t1.valdouble, t1.valint1 +FROM t1, +(SELECT max(t.valdate) AS maxdate, t.valint1 FROM t1 t GROUP BY t.valint1) +AS dt +WHERE t1.valint1 = dt.valint1 AND +t1.valdate = dt.maxdate AND +t1.valint1 IN (SELECT * FROM t2); +valdouble valint1 +1074 3289475 +1 3289496 +0 3289562 +1046 3289593 +0 3289594 +0 3289595 +2150 3289626 +0 3289642 +1155 3289658 +1958 3289739 +1 3289750 +1 3289761 +2 3289762 +1 3289763 +429 3289774 +0 3289780 +1897 3289951 +1994 3289957 +5 3289988 +DROP TABLE t1,t2; # End of 10.4 tests # # MDEV-28958: condition pushable into view after simplification diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index 5d67780782d..0dca9ce70a7 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -4214,6 +4214,94 @@ eval $q; drop table t1,t2,t3; +--echo # +--echo # MDEV-32064: usage of splittable derived table in query +--echo # with IN subquery in WHERE +--echo # + +CREATE TABLE t1 ( + id int unsigned NOT NULL, + valint1 int unsigned, + valdouble double, + valdate datetime, + PRIMARY KEY (id), + KEY (valint1), + KEY (valint1,valdate) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES +(1,3289763,1,'2021-02-09 18:31:35'),(2,3289750,1,'2021-02-09 18:31:35'), +(3,3289780,1173,'2021-02-09 18:31:35'),(4,3289762,2,'2021-02-09 18:31:36'), +(5,3289774,2334,'2021-02-09 18:31:36'),(6,3289739,1934,'2021-02-09 18:31:36'), +(7,3289761,1,'2021-02-09 18:31:37'),(8,3289763,1,'2021-02-10 11:05:19'), +(9,3289750,1,'2021-02-10 11:05:19'),(10,3289780,0,'2021-02-10 11:05:35'), +(11,3289762,2,'2021-02-10 11:05:47'),(12,3289774,429,'2021-02-10 11:05:47'), +(13,3289739,1958,'2021-02-10 11:06:00'),(14,3289761,1,'2021-02-10 11:06:08'), +(15,3289957,0,'2021-02-10 13:04:44'),(16,3289988,1993,'2021-02-10 13:04:45'), +(17,3289951,1896,'2021-02-10 13:04:59'),(18,3289957,1994,'2021-02-10 13:07:40'), +(19,3289988,5,'2021-02-10 13:07:40'),(20,3289951,1897,'2021-02-10 13:07:40'), +(21,3289594,0,'2021-02-11 14:19:38'),(22,3289642,0,'2021-02-11 14:19:38'), +(23,3289626,2150,'2021-02-11 14:19:38'),(24,3289562,0,'2021-02-11 14:19:39'), +(25,3289593,1046,'2021-02-11 14:19:39'),(26,3289496,1,'2021-02-11 14:19:45'), +(27,3289475,1074,'2021-02-11 14:19:50'),(28,3289658,1155,'2021-02-11 14:19:56'), +(29,3289595,0,'2021-02-11 14:20:01'),(30,3290334,903,'2021-02-11 16:22:44'), +(31,3290284,479,'2021-02-11 16:23:00'),(32,3290327,236,'2021-02-11 16:23:00'), +(33,3290854,0,'2021-02-15 17:29:59'),(34,3290824,0,'2021-02-15 17:30:13'), +(35,3290875,0,'2021-02-15 17:30:14'),(36,3290897,2,'2021-02-15 17:30:19'), +(37,3290800,0,'2021-02-15 17:30:24'),(38,3290822,0,'2021-02-15 17:30:25'), +(39,3290901,2667,'2021-02-15 17:30:30'),(40,3290835,0,'2021-02-15 17:30:36'), +(41,3290875,0,'2021-02-15 17:35:33'),(42,3290824,1330,'2021-02-15 17:35:39'), +(43,3290854,769,'2021-02-15 17:35:44'),(44,3290897,2,'2021-02-15 17:35:50'), +(45,3290822,748,'2021-02-15 17:35:50'),(46,3290800,1007,'2021-02-15 17:35:56'), +(47,3290901,7018,'2021-02-15 17:35:56'),(48,3290835,779,'2021-02-15 17:36:17'), +(49,3290824,1329,'2021-02-15 17:40:30'),(50,3290875,764,'2021-02-15 17:40:31'), +(51,3290854,763,'2021-02-15 17:40:36'),(52,3290897,2347,'2021-02-15 17:40:47'), +(53,3290822,1,'2021-02-15 17:41:01'),(54,3290800,1018,'2021-02-15 17:41:07'), +(55,3290901,3936,'2021-02-15 17:41:08'),(56,3290835,784,'2021-02-15 17:41:24'), +(57,3290824,1313,'2021-02-15 17:44:47'),(58,3290875,758,'2021-02-15 17:44:48'), +(59,3290854,767,'2021-02-15 17:44:48'),(60,3290897,2438,'2021-02-15 17:44:48'), +(61,3290822,738,'2021-02-15 17:44:49'),(62,3290800,1003,'2021-02-15 17:44:54'), +(63,3290901,4686,'2021-02-15 17:44:55'),(64,3290835,778,'2021-02-15 17:45:13'), +(65,3290824,1303,'2021-02-15 17:51:16'),(66,3290875,753,'2021-02-15 17:51:16'), +(67,3290854,766,'2021-02-15 17:51:22'),(68,3290897,1,'2021-02-15 17:51:22'), +(69,3290822,743,'2021-02-15 17:51:28'),(70,3290901,5718,'2021-02-15 17:51:33'), +(71,3290800,1018,'2021-02-15 17:51:34'),(72,3290835,785,'2021-02-15 17:51:48'), +(73,3290824,1310,'2021-02-15 18:21:30'),(74,3290875,754,'2021-02-15 18:21:30'), +(75,3290854,782,'2021-02-15 18:21:36'),(76,3290897,2,'2021-02-15 18:21:36'), +(77,3290822,745,'2021-02-15 18:21:53'),(78,3290800,1011,'2021-02-15 18:21:54'), +(79,3290901,8998,'2021-02-15 18:21:54'),(80,3290835,0,'2021-02-15 18:22:00'), +(81,3290936,0,'2021-02-15 18:25:28'),(82,3290895,0,'2021-02-15 18:25:28'), +(83,3290832,0,'2021-02-15 18:25:28'),(84,3290878,796,'2021-02-15 18:25:52'), +(85,3290900,730,'2021-02-15 18:25:52'),(86,3290856,0,'2021-02-15 18:26:11'), +(87,3290904,816,'2021-02-15 18:26:17'),(88,3290882,0,'2021-02-15 18:26:25'), +(89,3290883,1031,'2021-02-15 18:27:16'),(90,3290918,1749,'2021-02-15 18:27:17'), +(91,3290831,0,'2021-02-15 18:59:11'),(92,3290884,477,'2021-02-15 18:59:12'), +(93,3290899,483,'2021-02-15 18:59:12'),(94,3290848,486,'2021-02-15 18:59:35'), +(95,3290880,487,'2021-02-15 18:59:35'),(96,3290798,0,'2021-02-15 18:59:52'), +(97,3290777,983,'2021-02-15 19:00:10'),(98,3290811,488,'2021-02-15 19:00:10'), +(99,3290917,1283,'2021-02-15 19:00:36'),(100,3290858,482,'2021-02-15 19:00:42'); + +CREATE TABLE t2 (a int) ENGINE=MYISAM; +INSERT INTO t2 VALUES +(3289475),(3289496),(3289562),(3289593),(3289594),(3289595),(3289626), +(3289642),(3289658),(3289739),(3289750),(3289761),(3289762),(3289763), +(3289774),(3289780),(3289951),(3289957),(3289988),(3290034),(1231562); + +ANALYZE TABLE t1,t2; + +let $q= +SELECT t1.valdouble, t1.valint1 +FROM t1, + (SELECT max(t.valdate) AS maxdate, t.valint1 FROM t1 t GROUP BY t.valint1) + AS dt +WHERE t1.valint1 = dt.valint1 AND + t1.valdate = dt.maxdate AND + t1.valint1 IN (SELECT * FROM t2); + +eval EXPLAIN $q; +eval $q; + +DROP TABLE t1,t2; + --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 81a0165ab03..2fbb6da2d03 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -891,5 +891,20 @@ SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v); a b DROP VIEW v; DROP TABLE t1, t2, t3; +# +# MDEV-31279 Crash when lateral derived is guaranteed to return no rows +# +CREATE TABLE t1 (a CHAR(1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('1'),('2'); +CREATE TABLE t2 (b INT, KEY(b)) ENGINE=MyISAM; +ALTER TABLE t2 DISABLE KEYS; +INSERT INTO t2 VALUES (1),(2),(3); +ALTER TABLE t2 ENABLE KEYS; +CREATE TABLE t3 (c INT) ENGINE=MyISAM; +INSERT INTO t3 (c) SELECT seq FROM seq_1_to_101; +SELECT * FROM t1 WHERE t1.a IN (SELECT b FROM +(SELECT t2.b FROM t2 WHERE NOT EXISTS (SELECT 1 FROM t3) GROUP BY b) sq); +a +DROP TABLE t1, t2, t3; # End of 10.4 tests SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test index af38a8d71ab..acd7674786a 100644 --- a/mysql-test/main/derived_split_innodb.test +++ b/mysql-test/main/derived_split_innodb.test @@ -499,6 +499,24 @@ SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v); DROP VIEW v; DROP TABLE t1, t2, t3; +--echo # +--echo # MDEV-31279 Crash when lateral derived is guaranteed to return no rows +--echo # + +CREATE TABLE t1 (a CHAR(1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('1'),('2'); +CREATE TABLE t2 (b INT, KEY(b)) ENGINE=MyISAM; +ALTER TABLE t2 DISABLE KEYS; +INSERT INTO t2 VALUES (1),(2),(3); +ALTER TABLE t2 ENABLE KEYS; +CREATE TABLE t3 (c INT) ENGINE=MyISAM; +INSERT INTO t3 (c) SELECT seq FROM seq_1_to_101; + +SELECT * FROM t1 WHERE t1.a IN (SELECT b FROM + (SELECT t2.b FROM t2 WHERE NOT EXISTS (SELECT 1 FROM t3) GROUP BY b) sq); + +DROP TABLE t1, t2, t3; + --echo # End of 10.4 tests SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result index 75c92b23089..130516cc950 100644 --- a/mysql-test/main/derived_view.result +++ b/mysql-test/main/derived_view.result @@ -4309,6 +4309,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 f5f334e34c5..a7b09e7b02c 100644 --- a/mysql-test/main/derived_view.test +++ b/mysql-test/main/derived_view.test @@ -2767,6 +2767,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 7d0c59e1c84..a38906361c5 100644 --- a/mysql-test/main/disabled.def +++ b/mysql-test/main/disabled.def @@ -16,4 +16,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.result b/mysql-test/main/dyncol.result index 041e3040867..88cec1c50f0 100644 --- a/mysql-test/main/dyncol.result +++ b/mysql-test/main/dyncol.result @@ -1,20 +1,20 @@ # # column create # -select hex(COLUMN_CREATE(1, NULL AS char character set utf8)); -hex(COLUMN_CREATE(1, NULL AS char character set utf8)) +select hex(COLUMN_CREATE(1, NULL AS char character set utf8)) as exp; +exp 000000 -select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8)); -hex(COLUMN_CREATE(1, "afaf" AS char character set utf8)) +select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8)) as ex; +ex 0001000100032161666166 -select hex(COLUMN_CREATE(1, 1212 AS char character set utf8)); -hex(COLUMN_CREATE(1, 1212 AS char character set utf8)) +select hex(COLUMN_CREATE(1, 1212 AS char character set utf8)) as ex; +ex 0001000100032131323132 -select hex(COLUMN_CREATE(1, 12.12 AS char character set utf8)); -hex(COLUMN_CREATE(1, 12.12 AS char character set utf8)) +select hex(COLUMN_CREATE(1, 12.12 AS char character set utf8)) as ex; +ex 0001000100032131322E3132 -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS char character set utf8)); -hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS char character set utf8)) +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS char character set utf8)) as ex; +ex 000100010003213939393939393939393939393939393939393939393939393939393939 select hex(COLUMN_CREATE(1, NULL AS unsigned int)); hex(COLUMN_CREATE(1, NULL AS unsigned int)) @@ -43,8 +43,8 @@ hex(COLUMN_CREATE(1, ~0)) select hex(COLUMN_CREATE(1, -1)); hex(COLUMN_CREATE(1, -1)) 00010001000001 -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int)); -hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int)) +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int)) as ex; +ex 000100010001FFFFFFFFFFFFFF7F Warnings: Warning 1916 Got overflow when converting '99999999999999999999999999999' to INT. Value truncated @@ -69,8 +69,8 @@ hex(COLUMN_CREATE(1, 128 AS int)) select hex(COLUMN_CREATE(1, 12.12 AS int)); hex(COLUMN_CREATE(1, 12.12 AS int)) 00010001000018 -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS int)); -hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS int)) +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS int)) as ex; +ex 000100010000FEFFFFFFFFFFFFFF Warnings: Warning 1916 Got overflow when converting '99999999999999999999999999999' to INT. Value truncated @@ -83,8 +83,8 @@ hex(COLUMN_CREATE(1, 1212 AS double)) select hex(COLUMN_CREATE(1, 12.12 AS double)); hex(COLUMN_CREATE(1, 12.12 AS double)) 0001000100023D0AD7A3703D2840 -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS double)); -hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS double)) +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS double)) as ex; +ex 00010001000221D7E6FAE031F445 select hex(COLUMN_CREATE(1, NULL AS decimal)); hex(COLUMN_CREATE(1, NULL AS decimal)) @@ -107,8 +107,8 @@ hex(COLUMN_CREATE(1, 128 AS decimal)) select hex(COLUMN_CREATE(1, 12.12 AS decimal)); hex(COLUMN_CREATE(1, 12.12 AS decimal)) 00010001000402028C0C -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS decimal)); -hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS decimal)) +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS decimal)) as ex; +ex 0001000100041D00E33B9AC9FF3B9AC9FF3B9AC9FF select hex(COLUMN_CREATE(1, NULL AS date)); hex(COLUMN_CREATE(1, NULL AS date)) @@ -125,8 +125,8 @@ hex(COLUMN_CREATE(1, "0:45:49.000001" AS time)) select hex(COLUMN_CREATE(1, NULL AS datetime)); hex(COLUMN_CREATE(1, NULL AS datetime)) 000000 -select hex(COLUMN_CREATE(1, "2011-04-05 0:45:49.000001" AS datetime)); -hex(COLUMN_CREATE(1, "2011-04-05 0:45:49.000001" AS datetime)) +select hex(COLUMN_CREATE(1, "2011-04-05 0:45:49.000001" AS datetime)) as ex; +ex 00010001000585B60F010010B70000 select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, 2, 1212 AS unsigned int, @@ -135,15 +135,8 @@ select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, 4+1, 12.12 AS decimal, 6, "2011-04-05" AS date, 7, "- 0:45:49.000001" AS time, -8, "2011-04-05 0:45:49.000001" AS datetime)); -hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, -2, 1212 AS unsigned int, -3, 1212 AS int, -4, 12.12 AS double, -4+1, 12.12 AS decimal, -6, "2011-04-05" AS date, -7, "- 0:45:49.000001" AS time, -8, "2011-04-05 0:45:49.000001" AS datetime)) +8, "2011-04-05 0:45:49.000001" AS datetime)) as ex; +ex 01080001000300020029000300380004004A0005008C000600AE000700C7000800F5002161666166BC0478093D0AD7A3703D284002028C0C85B60F010010B7000485B60F010010B70000 explain extended select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, @@ -153,18 +146,11 @@ select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, 4+1, 12.12 AS decimal, 6, "2011-04-05" AS date, 7, "- 0:45:49.000001" AS time, -8, "2011-04-05 0:45:49.000001" AS datetime)); +8, "2011-04-05 0:45:49.000001" AS datetime)) as ex; 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 hex(column_create(1,'afaf' AS char charset utf8mb3 ,2,1212 AS unsigned int,3,1212 AS int,4,12.12 AS double,4 + 1,12.12 AS decimal,6,'2011-04-05' AS date,7,'- 0:45:49.000001' AS time,8,'2011-04-05 0:45:49.000001' AS datetime)) AS `hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, -2, 1212 AS unsigned int, -3, 1212 AS int, -4, 12.12 AS double, -4+1, 12.12 AS decimal, -6, "2011-04-05" AS date, -7, "- 0:45:49.000001" AS time, -8, "2011-04-05 0:45:49.000001" AS datetime))` +Note 1003 select hex(column_create(1,'afaf' AS char charset utf8mb3 ,2,1212 AS unsigned int,3,1212 AS int,4,12.12 AS double,4 + 1,12.12 AS decimal,6,'2011-04-05' AS date,7,'- 0:45:49.000001' AS time,8,'2011-04-05 0:45:49.000001' AS datetime)) AS `ex` select hex(column_create(1, 0.0 AS decimal)); hex(column_create(1, 0.0 AS decimal)) 000100010004 @@ -174,969 +160,969 @@ hex(column_create(1, 1.0 AS decimal)) # # column get uint # -select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int); -column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int) +select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int) as ex; +ex 1212 explain extended -select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int); +select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int) as ex; 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 column_get(column_create(1,1212 AS unsigned int),1 as unsigned) AS `column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int)` +Note 1003 select column_get(column_create(1,1212 AS unsigned int),1 as unsigned) AS `ex` explain extended -select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned); +select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned) as ex; 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 column_get(column_create(1,1212 AS unsigned int),1 as unsigned) AS `column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned)` -select column_get(column_create(1, 1212 AS decimal), 1 as unsigned int); -column_get(column_create(1, 1212 AS decimal), 1 as unsigned int) +Note 1003 select column_get(column_create(1,1212 AS unsigned int),1 as unsigned) AS `ex` +select column_get(column_create(1, 1212 AS decimal), 1 as unsigned int) as ex; +ex 1212 -select column_get(column_create(1, 1212 AS double), 1 as unsigned int); -column_get(column_create(1, 1212 AS double), 1 as unsigned int) +select column_get(column_create(1, 1212 AS double), 1 as unsigned int) as ex; +ex 1212 -select column_get(column_create(1, 1212 AS int), 1 as unsigned int); -column_get(column_create(1, 1212 AS int), 1 as unsigned int) +select column_get(column_create(1, 1212 AS int), 1 as unsigned int) as ex; +ex 1212 -select column_get(column_create(1, "1212" AS char), 1 as unsigned int); -column_get(column_create(1, "1212" AS char), 1 as unsigned int) +select column_get(column_create(1, "1212" AS char), 1 as unsigned int) as ex; +ex 1212 -select column_get(column_create(1, "2011-04-05" AS date), 1 as unsigned int); -column_get(column_create(1, "2011-04-05" AS date), 1 as unsigned int) +select column_get(column_create(1, "2011-04-05" AS date), 1 as unsigned int) as ex; +ex 20110405 -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as unsigned int); -column_get(column_create(1, "8:46:06.23434" AS time), 1 as unsigned int) +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as unsigned int) as ex; +ex 84606 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as unsigned int); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as unsigned int) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as unsigned int) as ex; +ex 20110405084606 -select column_get(column_create(1, NULL AS unsigned int), 1 as unsigned int); -column_get(column_create(1, NULL AS unsigned int), 1 as unsigned int) +select column_get(column_create(1, NULL AS unsigned int), 1 as unsigned int) as ex; +ex NULL # column geint truncation & warnings -select column_get(column_create(1, -1212 AS int), 1 as unsigned int); -column_get(column_create(1, -1212 AS int), 1 as unsigned int) +select column_get(column_create(1, -1212 AS int), 1 as unsigned int) as ex; +ex 18446744073709550404 Warnings: Note 1105 Cast to unsigned converted negative integer to it's positive complement -select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as unsigned int); -column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as unsigned int) +select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as unsigned int) as ex; +ex 18446744073709551615 Warnings: Warning 1916 Got overflow when converting '99999999999999999999999999999' to UNSIGNED INT. Value truncated -select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as unsigned int); -column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as unsigned int) +select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as unsigned int) as ex; +ex 1000 -select column_get(column_create(1, -1 AS decimal), 1 as unsigned int); -column_get(column_create(1, -1 AS decimal), 1 as unsigned int) +select column_get(column_create(1, -1 AS decimal), 1 as unsigned int) as ex; +ex 0 Warnings: Warning 1916 Got overflow when converting '-1' to UNSIGNED INT. Value truncated -select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int); -column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int) +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int) as ex; +ex 18446744073709551615 Warnings: Warning 1916 Got overflow when converting '1e29' to UNSIGNED INT. Value truncated -select column_get(column_create(1, 999.9 AS double), 1 as unsigned int); -column_get(column_create(1, 999.9 AS double), 1 as unsigned int) +select column_get(column_create(1, 999.9 AS double), 1 as unsigned int) as ex; +ex 1000 -select column_get(column_create(1, -1 AS double), 1 as unsigned int); -column_get(column_create(1, -1 AS double), 1 as unsigned int) +select column_get(column_create(1, -1 AS double), 1 as unsigned int) as ex; +ex 0 Warnings: Warning 1916 Got overflow when converting '-1' to UNSIGNED INT. Value truncated -select column_get(column_create(1, "1212III" AS char), 1 as unsigned int); -column_get(column_create(1, "1212III" AS char), 1 as unsigned int) +select column_get(column_create(1, "1212III" AS char), 1 as unsigned int) as ex; +ex 1212 Warnings: Warning 1918 Encountered illegal value '1212III' when converting to UNSIGNED INT # # column get int # -select column_get(column_create(1, 1212 AS int), 1 as int); -column_get(column_create(1, 1212 AS int), 1 as int) +select column_get(column_create(1, 1212 AS int), 1 as int) as ex; +ex 1212 explain extended -select column_get(column_create(1, 1212 AS int), 1 as int); +select column_get(column_create(1, 1212 AS int), 1 as int) as ex; 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 column_get(column_create(1,1212 AS int),1 as signed) AS `column_get(column_create(1, 1212 AS int), 1 as int)` +Note 1003 select column_get(column_create(1,1212 AS int),1 as signed) AS `ex` explain extended -select column_get(column_create(1, 1212 AS int), 1 as signed int); +select column_get(column_create(1, 1212 AS int), 1 as signed int) as ex; 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 column_get(column_create(1,1212 AS int),1 as signed) AS `column_get(column_create(1, 1212 AS int), 1 as signed int)` -select column_get(column_create(1, -1212 AS int), 1 as int); -column_get(column_create(1, -1212 AS int), 1 as int) +Note 1003 select column_get(column_create(1,1212 AS int),1 as signed) AS `ex` +select column_get(column_create(1, -1212 AS int), 1 as int) as ex; +ex -1212 -select column_get(column_create(1, 1212 AS decimal), 1 as int); -column_get(column_create(1, 1212 AS decimal), 1 as int) +select column_get(column_create(1, 1212 AS decimal), 1 as int) as ex; +ex 1212 -select column_get(column_create(1, 1212 AS double), 1 as int); -column_get(column_create(1, 1212 AS double), 1 as int) +select column_get(column_create(1, 1212 AS double), 1 as int) as ex; +ex 1212 -select column_get(column_create(1, 1212 AS unsigned int), 1 as int); -column_get(column_create(1, 1212 AS unsigned int), 1 as int) +select column_get(column_create(1, 1212 AS unsigned int), 1 as int) as ex; +ex 1212 -select column_get(column_create(1, "1212" AS char), 1 as int); -column_get(column_create(1, "1212" AS char), 1 as int) +select column_get(column_create(1, "1212" AS char), 1 as int) as ex; +ex 1212 -select column_get(column_create(1, "-1212" AS char), 1 as int); -column_get(column_create(1, "-1212" AS char), 1 as int) +select column_get(column_create(1, "-1212" AS char), 1 as int) as ex; +ex -1212 -select column_get(column_create(1, "2011-04-05" AS date), 1 as int); -column_get(column_create(1, "2011-04-05" AS date), 1 as int) +select column_get(column_create(1, "2011-04-05" AS date), 1 as int) as ex; +ex 20110405 -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as int); -column_get(column_create(1, "8:46:06.23434" AS time), 1 as int) +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as int) as ex; +ex 84606 -select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as int); -column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as int) +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as int) as ex; +ex 84606 -select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as int); -column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as int) +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as int) as ex; +ex -8084606 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as int); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as int) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as int) as ex; +ex 20110405084606 -select column_get(column_create(1, NULL AS int), 1 as int); -column_get(column_create(1, NULL AS int), 1 as int) +select column_get(column_create(1, NULL AS int), 1 as int) as ex; +ex NULL #column gett truncation & warnings -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as int); -column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as int) +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as int) as ex; +ex -1 Warnings: Note 1105 Cast to signed converted positive out-of-range integer to it's negative complement -select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as int); -column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as int) +select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as int) as ex; +ex 9223372036854775807 Warnings: Warning 1916 Got overflow when converting '99999999999999999999999999999' to INT. Value truncated -select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as int); -column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as int) +select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as int) as ex; +ex -9223372036854775808 Warnings: Warning 1916 Got overflow when converting '-99999999999999999999999999999' to INT. Value truncated -select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as int); -column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as int) +select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as int) as ex; +ex 1000 -select column_get(column_create(1, 999.9 AS double), 1 as int); -column_get(column_create(1, 999.9 AS double), 1 as int) +select column_get(column_create(1, 999.9 AS double), 1 as int) as ex; +ex 1000 -select column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int); -column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int) +select column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int) as ex; +ex -9223372036854775808 Warnings: Warning 1916 Got overflow when converting '-1e29' to INT. Value truncated -select column_get(column_create(1, "-1212III" AS char), 1 as int); -column_get(column_create(1, "-1212III" AS char), 1 as int) +select column_get(column_create(1, "-1212III" AS char), 1 as int) as ex; +ex -1212 Warnings: Warning 1918 Encountered illegal value '-1212III' when converting to INT -select column_get(column_create(1, "1212III" AS char), 1 as int); -column_get(column_create(1, "1212III" AS char), 1 as int) +select column_get(column_create(1, "1212III" AS char), 1 as int) as ex; +ex 1212 Warnings: Warning 1918 Encountered illegal value '1212III' when converting to INT -select column_get(COLUMN_CREATE(1, ~0), 1 as signed); -column_get(COLUMN_CREATE(1, ~0), 1 as signed) +select column_get(COLUMN_CREATE(1, ~0), 1 as signed) as ex; +ex -1 Warnings: Note 1105 Cast to signed converted positive out-of-range integer to it's negative complement -select column_get(COLUMN_CREATE(1, ~0), 1 as unsigned); -column_get(COLUMN_CREATE(1, ~0), 1 as unsigned) +select column_get(COLUMN_CREATE(1, ~0), 1 as unsigned) as ex; +ex 18446744073709551615 -select column_get(COLUMN_CREATE(1, -1), 1 as signed); -column_get(COLUMN_CREATE(1, -1), 1 as signed) +select column_get(COLUMN_CREATE(1, -1), 1 as signed) as ex; +ex -1 -select column_get(COLUMN_CREATE(1, -1), 1 as unsigned); -column_get(COLUMN_CREATE(1, -1), 1 as unsigned) +select column_get(COLUMN_CREATE(1, -1), 1 as unsigned) as ex; +ex 18446744073709551615 Warnings: Note 1105 Cast to unsigned converted negative integer to it's positive complement # #column get char # -select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8); -column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8) +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8) as ex; +ex 1212 explain extended -select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8); +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8) as ex; 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 column_get(column_create(1,'1212' AS char charset utf8mb3 ),1 as char charset utf8mb3) AS `column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8)` -select column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8); -column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8) +Note 1003 select column_get(column_create(1,'1212' AS char charset utf8mb3 ),1 as char charset utf8mb3) AS `ex` +select column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8) as ex; +ex 1212 -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as char charset utf8); -column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as char charset utf8) +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as char charset utf8) as ex; +ex 18446744073709551615 -select column_get(column_create(1, 1212 AS int), 1 as char charset utf8); -column_get(column_create(1, 1212 AS int), 1 as char charset utf8) +select column_get(column_create(1, 1212 AS int), 1 as char charset utf8) as ex; +ex 1212 -select column_get(column_create(1, -1212 AS int), 1 as char charset utf8); -column_get(column_create(1, -1212 AS int), 1 as char charset utf8) +select column_get(column_create(1, -1212 AS int), 1 as char charset utf8) as ex; +ex -1212 -select column_get(column_create(1, 9223372036854775807 AS int), 1 as char charset utf8); -column_get(column_create(1, 9223372036854775807 AS int), 1 as char charset utf8) +select column_get(column_create(1, 9223372036854775807 AS int), 1 as char charset utf8) as ex; +ex 9223372036854775807 -select column_get(column_create(1, -9223372036854775808 AS int), 1 as char charset utf8); -column_get(column_create(1, -9223372036854775808 AS int), 1 as char charset utf8) +select column_get(column_create(1, -9223372036854775808 AS int), 1 as char charset utf8) as ex; +ex -9223372036854775808 -select column_get(column_create(1, 1212.12 AS decimal), 1 as char charset utf8); -column_get(column_create(1, 1212.12 AS decimal), 1 as char charset utf8) +select column_get(column_create(1, 1212.12 AS decimal), 1 as char charset utf8) as ex; +ex 1212.12 -select column_get(column_create(1, 1212.12 AS double), 1 as char charset utf8); -column_get(column_create(1, 1212.12 AS double), 1 as char charset utf8) +select column_get(column_create(1, 1212.12 AS double), 1 as char charset utf8) as ex; +ex 1212.12 -select column_get(column_create(1, "2011-04-05" AS date), 1 as char charset utf8); -column_get(column_create(1, "2011-04-05" AS date), 1 as char charset utf8) +select column_get(column_create(1, "2011-04-05" AS date), 1 as char charset utf8) as ex; +ex 2011-04-05 -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as char charset utf8); -column_get(column_create(1, "8:46:06.23434" AS time), 1 as char charset utf8) +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as char charset utf8) as ex; +ex 08:46:06.234340 -select column_get(column_create(1, "8:46:06.23434" AS time(0)), 1 as char charset utf8); -column_get(column_create(1, "8:46:06.23434" AS time(0)), 1 as char charset utf8) +select column_get(column_create(1, "8:46:06.23434" AS time(0)), 1 as char charset utf8) as ex; +ex 08:46:06.234340 -select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as char charset utf8); -column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as char charset utf8) +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as char charset utf8) as ex; +ex 08:46:06.234340 -select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as char charset utf8); -column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as char charset utf8) +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as char charset utf8) as ex; +ex -808:46:06.234340 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as char charset utf8); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as char charset utf8) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as char charset utf8) as ex; +ex 2011-04-05 08:46:06.234340 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(0)), 1 as char charset utf8); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(0)), 1 as char charset utf8) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(0)), 1 as char charset utf8) as ex; +ex 2011-04-05 08:46:06.234340 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as char charset utf8); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as char charset utf8) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as char charset utf8) as ex; +ex 2011-04-05 08:46:06.234340 -select column_get(column_create(1, NULL AS char charset utf8), 1 as char charset utf8); -column_get(column_create(1, NULL AS char charset utf8), 1 as char charset utf8) +select column_get(column_create(1, NULL AS char charset utf8), 1 as char charset utf8) as ex; +ex NULL -select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary); -column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary) +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary) as ex; +ex 1212 explain extended -select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary); +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary) as ex; 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 column_get(column_create(1,'1212' AS char charset utf8mb3 ),1 as char charset binary) AS `column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary)` +Note 1003 select column_get(column_create(1,'1212' AS char charset utf8mb3 ),1 as char charset binary) AS `ex` # # column get real # -select column_get(column_create(1, 1212.12 AS double), 1 as double); -column_get(column_create(1, 1212.12 AS double), 1 as double) +select column_get(column_create(1, 1212.12 AS double), 1 as double) as ex; +ex 1212.12 explain extended -select column_get(column_create(1, 1212.12 AS double), 1 as double); +select column_get(column_create(1, 1212.12 AS double), 1 as double) as ex; 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 column_get(column_create(1,1212.12 AS double),1 as double) AS `column_get(column_create(1, 1212.12 AS double), 1 as double)` +Note 1003 select column_get(column_create(1,1212.12 AS double),1 as double) AS `ex` explain extended -select column_get(column_create(1, 1212.12 AS double), 1 as double(6,2)); +select column_get(column_create(1, 1212.12 AS double), 1 as double(6,2)) as ex; 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 column_get(column_create(1,1212.12 AS double),1 as double(6,2)) AS `column_get(column_create(1, 1212.12 AS double), 1 as double(6,2))` -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as double); -column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as double) +Note 1003 select column_get(column_create(1,1212.12 AS double),1 as double(6,2)) AS `ex` +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as double) as ex; +ex 1.8446744073709552e19 -select column_get(column_create(1, 9223372036854775807 AS int), 1 as double); -column_get(column_create(1, 9223372036854775807 AS int), 1 as double) +select column_get(column_create(1, 9223372036854775807 AS int), 1 as double) as ex; +ex 9.223372036854776e18 -select column_get(column_create(1, -9223372036854775808 AS int), 1 as double); -column_get(column_create(1, -9223372036854775808 AS int), 1 as double) +select column_get(column_create(1, -9223372036854775808 AS int), 1 as double) as ex; +ex -9.223372036854776e18 -select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as double); -column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as double) +select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as double) as ex; +ex 1e29 -select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as double); -column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as double) +select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as double) as ex; +ex -1e29 -select column_get(column_create(1, "2011-04-05" AS date), 1 as double); -column_get(column_create(1, "2011-04-05" AS date), 1 as double) +select column_get(column_create(1, "2011-04-05" AS date), 1 as double) as ex; +ex 20110405 -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as double); -column_get(column_create(1, "8:46:06.23434" AS time), 1 as double) +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as double) as ex; +ex 84606.23434 -select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as double); -column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as double) +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as double) as ex; +ex 84606.23434 -select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as double); -column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as double) +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as double) as ex; +ex -8084606.23434 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double) as ex; +ex 20110405084606.234 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as double); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as double) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as double) as ex; +ex 20110405084606.234 -select round(column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double(20,6)),3); -round(column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double(20,6)),3) +select round(column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double(20,6)),3) as ex; +ex 20110405084606.234 -select column_get(column_create(1, NULL AS double), 1 as double); -column_get(column_create(1, NULL AS double), 1 as double) +select column_get(column_create(1, NULL AS double), 1 as double) as ex; +ex NULL # column get real truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as double); -column_get(column_create(1, "1223.5aa" AS char), 1 as double) +select column_get(column_create(1, "1223.5aa" AS char), 1 as double) as ex; +ex 1223.5 Warnings: Warning 1918 Encountered illegal value '1223.5aa' when converting to DOUBLE -select column_get(column_create(1, "aa" AS char), 1 as double); -column_get(column_create(1, "aa" AS char), 1 as double) +select column_get(column_create(1, "aa" AS char), 1 as double) as ex; +ex 0 Warnings: Warning 1918 Encountered illegal value 'aa' when converting to DOUBLE -select column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2)); -column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2)) +select column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2)) as ex; +ex 999.99 Warnings: -Note 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2))' at row 1 -select column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2)); -column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2)) +Note 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2)) as ex; +ex 9.99 Warnings: -Note 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2))' at row 1 +Note 1264 Out of range value for column 'ex' at row 1 # # column get decimal # -select column_get(column_create(1, 1212.12 AS double), 1 as decimal); -column_get(column_create(1, 1212.12 AS double), 1 as decimal) +select column_get(column_create(1, 1212.12 AS double), 1 as decimal) as ex; +ex 1212 -select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)); -column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)) +select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)) as ex; +ex 1212.12 explain extended -select column_get(column_create(1, 1212.12 AS double), 1 as decimal); +select column_get(column_create(1, 1212.12 AS double), 1 as decimal) as ex; 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 column_get(column_create(1,1212.12 AS double),1 as decimal(10,0)) AS `column_get(column_create(1, 1212.12 AS double), 1 as decimal)` +Note 1003 select column_get(column_create(1,1212.12 AS double),1 as decimal(10,0)) AS `ex` explain extended -select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)); +select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)) as ex; 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 column_get(column_create(1,1212.12 AS double),1 as decimal(6,2)) AS `column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2))` -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal(20,0)); -column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal(20,0)) +Note 1003 select column_get(column_create(1,1212.12 AS double),1 as decimal(6,2)) AS `ex` +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal(20,0)) as ex; +ex 18446744073709551615 -select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal(32,0)); -column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal(32,0)) +select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal(32,0)) as ex; +ex 9223372036854775807 -select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal(32,0)); -column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal(32,0)) +select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal(32,0)) as ex; +ex -9223372036854775808 -select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as decimal(40,10)); -column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as decimal(40,10)) +select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as decimal(40,10)) as ex; +ex -99999999999999999999999999999.0000000000 -select column_get(column_create(1, "2011-04-05" AS date), 1 as decimal(32,6)); -column_get(column_create(1, "2011-04-05" AS date), 1 as decimal(32,6)) +select column_get(column_create(1, "2011-04-05" AS date), 1 as decimal(32,6)) as ex; +ex 20110405.000000 -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as decimal(32,6)); -column_get(column_create(1, "8:46:06.23434" AS time), 1 as decimal(32,6)) +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as decimal(32,6)) as ex; +ex 84606.234340 -select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as decimal(32,6)); -column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as decimal(32,6)) +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as decimal(32,6)) as ex; +ex 84606.234340 -select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as decimal(32,6)); -column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as decimal(32,6)) +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as decimal(32,6)) as ex; +ex -8084606.234340 -select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime), 1 as decimal(32,6)); -column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime), 1 as decimal(32,6)) +select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime), 1 as decimal(32,6)) as ex; +ex 20110405084606.123456 -select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime(6)), 1 as decimal(32,6)); -column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime(6)), 1 as decimal(32,6)) +select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime(6)), 1 as decimal(32,6)) as ex; +ex 20110405084606.123456 -select column_get(column_create(1, "2011-04-05 8:46:06.12345678" AS datetime(6)), 1 as decimal(32,8)); -column_get(column_create(1, "2011-04-05 8:46:06.12345678" AS datetime(6)), 1 as decimal(32,8)) +select column_get(column_create(1, "2011-04-05 8:46:06.12345678" AS datetime(6)), 1 as decimal(32,8)) as ex; +ex 20110405084606.12345600 Warnings: Note 1292 Truncated incorrect datetime value: '2011-04-05 8:46:06.12345678' -select column_get(column_create(1, NULL as decimal), 1 as decimal(32,10)); -column_get(column_create(1, NULL as decimal), 1 as decimal(32,10)) +select column_get(column_create(1, NULL as decimal), 1 as decimal(32,10)) as ex; +ex NULL -select column_get(column_create(1, "1223.5555" as decimal(10,5)), 1 as decimal(6,2)); -column_get(column_create(1, "1223.5555" as decimal(10,5)), 1 as decimal(6,2)) +select column_get(column_create(1, "1223.5555" as decimal(10,5)), 1 as decimal(6,2)) as ex; +ex 1223.56 # column get decimal truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as decimal(32,10)); -column_get(column_create(1, "1223.5aa" AS char), 1 as decimal(32,10)) +select column_get(column_create(1, "1223.5aa" AS char), 1 as decimal(32,10)) as ex; +ex 1223.5000000000 Warnings: Warning 1918 Encountered illegal value '1223.5aa' when converting to DECIMAL -select column_get(column_create(1, "aa" AS char), 1 as decimal(32,10)); -column_get(column_create(1, "aa" AS char), 1 as decimal(32,10)) +select column_get(column_create(1, "aa" AS char), 1 as decimal(32,10)) as ex; +ex 0.0000000000 Warnings: Warning 1918 Encountered illegal value 'aa' when converting to DECIMAL -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal); -column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal) +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal) as ex; +ex 9999999999 Warnings: -Warning 1264 Out of range value for column 'column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal)' at row 1 -select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal); -column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal) +Warning 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal) as ex; +ex 9999999999 Warnings: -Warning 1264 Out of range value for column 'column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal)' at row 1 -select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal); -column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal) +Warning 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal) as ex; +ex -9999999999 Warnings: -Warning 1264 Out of range value for column 'column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal)' at row 1 -select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal); -column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal) +Warning 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal) as ex; +ex 9999999999 Warnings: -Warning 1264 Out of range value for column 'column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal)' at row 1 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal) +Warning 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal) as ex; +ex 9999999999 Warnings: -Warning 1264 Out of range value for column 'column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal)' at row 1 -select column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2)); -column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2)) +Warning 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2)) as ex; +ex 999.99 Warnings: -Warning 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2))' at row 1 -select column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2)); -column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2)) +Warning 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2)) as ex; +ex -999.99 Warnings: -Warning 1264 Out of range value for column 'column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2))' at row 1 -select column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2)); -column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2)) +Warning 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2)) as ex; +ex 9.99 Warnings: -Warning 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2))' at row 1 -select column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2)); -column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2)) +Warning 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2)) as ex; +ex 9.99 Warnings: -Warning 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2))' at row 1 -select column_get(column_create(1, 0.0 AS decimal,2, 0.0 as decimal), 1 as decimal); -column_get(column_create(1, 0.0 AS decimal,2, 0.0 as decimal), 1 as decimal) +Warning 1264 Out of range value for column 'ex' at row 1 +select column_get(column_create(1, 0.0 AS decimal,2, 0.0 as decimal), 1 as decimal) as ex; +ex 0 # # column get datetime # -select column_get(column_create(1, 20010203101112.121314 as double), 1 as datetime); -column_get(column_create(1, 20010203101112.121314 as double), 1 as datetime) +select column_get(column_create(1, 20010203101112.121314 as double), 1 as datetime) as ex; +ex 2001-02-03 10:11:12 -select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as datetime); -column_get(column_create(1, 20010203101112.121314 as decimal), 1 as datetime) +select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as datetime) as ex; +ex 2001-02-03 10:11:12 -select column_get(column_create(1, 20010203101112 as unsigned int), 1 as datetime); -column_get(column_create(1, 20010203101112 as unsigned int), 1 as datetime) +select column_get(column_create(1, 20010203101112 as unsigned int), 1 as datetime) as ex; +ex 2001-02-03 10:11:12 -select column_get(column_create(1, 20010203101112 as int), 1 as datetime); -column_get(column_create(1, 20010203101112 as int), 1 as datetime) +select column_get(column_create(1, 20010203101112 as int), 1 as datetime) as ex; +ex 2001-02-03 10:11:12 -select column_get(column_create(1, "20010203101112" as char), 1 as datetime); -column_get(column_create(1, "20010203101112" as char), 1 as datetime) +select column_get(column_create(1, "20010203101112" as char), 1 as datetime) as ex; +ex 2001-02-03 10:11:12 -select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as datetime); -column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as datetime) +select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as datetime) as ex; +ex 2001-02-03 10:11:12 -select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as datetime); -column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as datetime) +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as datetime) as ex; +ex 2001-02-03 10:11:12 -select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as datetime); -column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as datetime) +select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as datetime) as ex; +ex 2001-02-03 10:11:12 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime) as ex; +ex 2011-04-05 08:46:06 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(0)); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(0)) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(0)) as ex; +ex 2011-04-05 08:46:06 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(6)); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(6)) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(6)) as ex; +ex 2011-04-05 08:46:06.234340 -select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as datetime); -column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as datetime) +select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as datetime) as ex; +ex 2011-00-00 08:46:06 -select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as datetime); -column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as datetime) +select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as datetime) as ex; +ex 2011-00-01 08:46:06 -select column_get(column_create(1, 20010203 as unsigned int), 1 as datetime); -column_get(column_create(1, 20010203 as unsigned int), 1 as datetime) +select column_get(column_create(1, 20010203 as unsigned int), 1 as datetime) as ex; +ex 2001-02-03 00:00:00 -select column_get(column_create(1, 20010203 as int), 1 as datetime); -column_get(column_create(1, 20010203 as int), 1 as datetime) +select column_get(column_create(1, 20010203 as int), 1 as datetime) as ex; +ex 2001-02-03 00:00:00 -select column_get(column_create(1, 20010203), 1 as datetime); -column_get(column_create(1, 20010203), 1 as datetime) +select column_get(column_create(1, 20010203), 1 as datetime) as ex; +ex 2001-02-03 00:00:00 -select column_get(column_create(1, 20010203.0), 1 as datetime); -column_get(column_create(1, 20010203.0), 1 as datetime) +select column_get(column_create(1, 20010203.0), 1 as datetime) as ex; +ex 2001-02-03 00:00:00 -select column_get(column_create(1, 20010203.0 as double), 1 as datetime); -column_get(column_create(1, 20010203.0 as double), 1 as datetime) +select column_get(column_create(1, 20010203.0 as double), 1 as datetime) as ex; +ex 2001-02-03 00:00:00 -select column_get(column_create(1, "2001-02-03"), 1 as datetime); -column_get(column_create(1, "2001-02-03"), 1 as datetime) +select column_get(column_create(1, "2001-02-03"), 1 as datetime) as ex; +ex 2001-02-03 00:00:00 -select column_get(column_create(1, "20010203"), 1 as datetime); -column_get(column_create(1, "20010203"), 1 as datetime) +select column_get(column_create(1, "20010203"), 1 as datetime) as ex; +ex 2001-02-03 00:00:00 -select column_get(column_create(1, 0), 1 as datetime); -column_get(column_create(1, 0), 1 as datetime) +select column_get(column_create(1, 0), 1 as datetime) as ex; +ex 0000-00-00 00:00:00 -select column_get(column_create(1, "2001021"), 1 as datetime); -column_get(column_create(1, "2001021"), 1 as datetime) +select column_get(column_create(1, "2001021"), 1 as datetime) as ex; +ex 2020-01-02 01:00:00 SET timestamp=unix_timestamp('2001-02-03 10:20:30'); -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as datetime); -column_get(column_create(1, "8:46:06.23434" AS time), 1 as datetime) +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as datetime) as ex; +ex 2001-02-03 08:46:06 -select column_get(column_create(1, "-808:46:06.23434" AS time), 1 as datetime); -column_get(column_create(1, "-808:46:06.23434" AS time), 1 as datetime) +select column_get(column_create(1, "-808:46:06.23434" AS time), 1 as datetime) as ex; +ex 2000-12-31 07:13:53 SET timestamp=DEFAULT; set @@sql_mode="allow_invalid_dates"; -select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as datetime); -column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as datetime) +select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as datetime) as ex; +ex 2011-02-30 18:46:06 -select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as datetime); -column_get(column_create(1, "0000-00-000" AS CHAR), 1 as datetime) +select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as datetime) as ex; +ex 0000-00-00 00:00:00 -select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as datetime); -column_get(column_create(1, "2001-00-02" AS CHAR), 1 as datetime) +select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as datetime) as ex; +ex 2001-00-02 00:00:00 set @@sql_mode=""; # column get datetime truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as datetime); -column_get(column_create(1, "1223.5aa" AS char), 1 as datetime) +select column_get(column_create(1, "1223.5aa" AS char), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '1223.5aa' -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as datetime); -column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as datetime) +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '1.8446744073709552e19' -select column_get(column_create(1, 9223372036854775807 AS int), 1 as datetime); -column_get(column_create(1, 9223372036854775807 AS int), 1 as datetime) +select column_get(column_create(1, 9223372036854775807 AS int), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '9223372036854775807' -select column_get(column_create(1, -9223372036854775808 AS int), 1 as datetime); -column_get(column_create(1, -9223372036854775808 AS int), 1 as datetime) +select column_get(column_create(1, -9223372036854775808 AS int), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '-9223372036854775808' -select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as datetime); -column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as datetime) +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '99999999999999999999999999999' -select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as datetime); -column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as datetime) +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '1e29' -select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as datetime); -column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as datetime) +select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '2011-02-32 8:46:06.23434' -select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as datetime); -column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as datetime) +select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '2011-13-01 8:46:06.23434' -select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as datetime); -column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as datetime) +select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '2011-02-30 8:46:06.23434' -select column_get(column_create(1, "20010231"), 1 as datetime); -column_get(column_create(1, "20010231"), 1 as datetime) +select column_get(column_create(1, "20010231"), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '20010231' -select column_get(column_create(1, "0" AS CHAR), 1 as datetime); -column_get(column_create(1, "0" AS CHAR), 1 as datetime) +select column_get(column_create(1, "0" AS CHAR), 1 as datetime) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '0' # # column get date # -select column_get(column_create(1, 20010203101112.121314 as double), 1 as date); -column_get(column_create(1, 20010203101112.121314 as double), 1 as date) +select column_get(column_create(1, 20010203101112.121314 as double), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as date); -column_get(column_create(1, 20010203101112.121314 as decimal), 1 as date) +select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, 20010203101112 as unsigned int), 1 as date); -column_get(column_create(1, 20010203101112 as unsigned int), 1 as date) +select column_get(column_create(1, 20010203101112 as unsigned int), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, 20010203101112 as int), 1 as date); -column_get(column_create(1, 20010203101112 as int), 1 as date) +select column_get(column_create(1, 20010203101112 as int), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, "20010203101112" as char), 1 as date); -column_get(column_create(1, "20010203101112" as char), 1 as date) +select column_get(column_create(1, "20010203101112" as char), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as date); -column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as date) +select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as date); -column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as date) +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as date); -column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as date) +select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as date); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as date) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as date) as ex; +ex 2011-04-05 -select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as date); -column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as date) +select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as date) as ex; +ex 2011-00-00 -select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as date); -column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as date) +select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as date) as ex; +ex 2011-00-01 -select column_get(column_create(1, 20010203 as unsigned int), 1 as date); -column_get(column_create(1, 20010203 as unsigned int), 1 as date) +select column_get(column_create(1, 20010203 as unsigned int), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, 20010203 as int), 1 as date); -column_get(column_create(1, 20010203 as int), 1 as date) +select column_get(column_create(1, 20010203 as int), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, 20010203), 1 as date); -column_get(column_create(1, 20010203), 1 as date) +select column_get(column_create(1, 20010203), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, 20010203.0), 1 as date); -column_get(column_create(1, 20010203.0), 1 as date) +select column_get(column_create(1, 20010203.0), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, 20010203.0 as double), 1 as date); -column_get(column_create(1, 20010203.0 as double), 1 as date) +select column_get(column_create(1, 20010203.0 as double), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, "2001-02-03"), 1 as date); -column_get(column_create(1, "2001-02-03"), 1 as date) +select column_get(column_create(1, "2001-02-03"), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, "20010203"), 1 as date); -column_get(column_create(1, "20010203"), 1 as date) +select column_get(column_create(1, "20010203"), 1 as date) as ex; +ex 2001-02-03 -select column_get(column_create(1, 0), 1 as date); -column_get(column_create(1, 0), 1 as date) +select column_get(column_create(1, 0), 1 as date) as ex; +ex 0000-00-00 -select column_get(column_create(1, "2001021"), 1 as date); -column_get(column_create(1, "2001021"), 1 as date) +select column_get(column_create(1, "2001021"), 1 as date) as ex; +ex 2020-01-02 set @@sql_mode="allow_invalid_dates"; -select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date); -column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date) +select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date) as ex; +ex 2011-02-30 -select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date); -column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date) +select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date) as ex; +ex 0000-00-00 -select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as date); -column_get(column_create(1, "2001-00-02" AS CHAR), 1 as date) +select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as date) as ex; +ex 2001-00-02 set @@sql_mode=""; # column get date truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as date); -column_get(column_create(1, "1223.5aa" AS char), 1 as date) +select column_get(column_create(1, "1223.5aa" AS char), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '1223.5aa' -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as date); -column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as date) +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '1.8446744073709552e19' -select column_get(column_create(1, 9223372036854775807 AS int), 1 as date); -column_get(column_create(1, 9223372036854775807 AS int), 1 as date) +select column_get(column_create(1, 9223372036854775807 AS int), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '9223372036854775807' -select column_get(column_create(1, -9223372036854775808 AS int), 1 as date); -column_get(column_create(1, -9223372036854775808 AS int), 1 as date) +select column_get(column_create(1, -9223372036854775808 AS int), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '-9223372036854775808' -select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as date); -column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as date) +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '99999999999999999999999999999' -select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as date); -column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as date) +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '1e29' -select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as date); -column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as date) +select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '2011-02-32 8:46:06.23434' -select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as date); -column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as date) +select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '2011-13-01 8:46:06.23434' -select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as date); -column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as date) +select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '2011-02-30 8:46:06.23434' -select column_get(column_create(1, "20010231"), 1 as date); -column_get(column_create(1, "20010231"), 1 as date) +select column_get(column_create(1, "20010231"), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '20010231' -select column_get(column_create(1, "0" AS CHAR), 1 as date); -column_get(column_create(1, "0" AS CHAR), 1 as date) +select column_get(column_create(1, "0" AS CHAR), 1 as date) as ex; +ex NULL Warnings: Warning 1292 Incorrect datetime value: '0' # # column get time # -select column_get(column_create(1, 20010203101112.121314 as double), 1 as time); -column_get(column_create(1, 20010203101112.121314 as double), 1 as time) +select column_get(column_create(1, 20010203101112.121314 as double), 1 as time) as ex; +ex 10:11:12 -select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as time); -column_get(column_create(1, 20010203101112.121314 as decimal), 1 as time) +select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as time) as ex; +ex 10:11:12 -select column_get(column_create(1, 20010203101112 as unsigned int), 1 as time); -column_get(column_create(1, 20010203101112 as unsigned int), 1 as time) +select column_get(column_create(1, 20010203101112 as unsigned int), 1 as time) as ex; +ex 10:11:12 -select column_get(column_create(1, 8080102 as unsigned int), 1 as time); -column_get(column_create(1, 8080102 as unsigned int), 1 as time) +select column_get(column_create(1, 8080102 as unsigned int), 1 as time) as ex; +ex 808:01:02 -select column_get(column_create(1, 20010203101112 as int), 1 as time); -column_get(column_create(1, 20010203101112 as int), 1 as time) +select column_get(column_create(1, 20010203101112 as int), 1 as time) as ex; +ex 10:11:12 -select column_get(column_create(1, -8080102 as int), 1 as time); -column_get(column_create(1, -8080102 as int), 1 as time) +select column_get(column_create(1, -8080102 as int), 1 as time) as ex; +ex -808:01:02 -select column_get(column_create(1, "20010203101112" as char), 1 as time); -column_get(column_create(1, "20010203101112" as char), 1 as time) +select column_get(column_create(1, "20010203101112" as char), 1 as time) as ex; +ex 10:11:12 -select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as time); -column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as time) +select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as time) as ex; +ex 10:11:12 -select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time); -column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time) +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time) as ex; +ex 10:11:12 -select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time(6)); -column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time(6)) +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time(6)) as ex; +ex 10:11:12.121314 -select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as time); -column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as time) +select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as time) as ex; +ex 10:11:12 -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as time(6)); -column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as time(6)) +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as time(6)) as ex; +ex 08:46:06.234340 -select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as time(6)); -column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as time(6)) +select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as time(6)) as ex; +ex 08:46:06.234340 -select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as time(6)); -column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as time(6)) +select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as time(6)) as ex; +ex 08:46:06.234340 -select column_get(column_create(1, "830:46:06.23434" AS CHAR), 1 as time(6)); -column_get(column_create(1, "830:46:06.23434" AS CHAR), 1 as time(6)) +select column_get(column_create(1, "830:46:06.23434" AS CHAR), 1 as time(6)) as ex; +ex 830:46:06.234340 -select column_get(column_create(1, "830:46:06" AS CHAR), 1 as time(6)); -column_get(column_create(1, "830:46:06" AS CHAR), 1 as time(6)) +select column_get(column_create(1, "830:46:06" AS CHAR), 1 as time(6)) as ex; +ex 830:46:06.000000 -select cast("-830:46:06.23434" AS time(6)); -cast("-830:46:06.23434" AS time(6)) +select cast("-830:46:06.23434" AS time(6)) as ex; +ex -830:46:06.234340 -select 1,cast("-830:46:06.23434" AS time(6)); -1 cast("-830:46:06.23434" AS time(6)) +select 1,cast("-830:46:06.23434" AS time(6)) as ex; +1 ex 1 -830:46:06.234340 -select hex(column_create(1, "-830:46:06.23434" AS CHAR)); -hex(column_create(1, "-830:46:06.23434" AS CHAR)) +select hex(column_create(1, "-830:46:06.23434" AS CHAR)) as ex; +ex 000100010003082D3833303A34363A30362E3233343334 -select column_get(column_create(1, "-830:46:06.23434" AS CHAR), 1 as time(6)); -column_get(column_create(1, "-830:46:06.23434" AS CHAR), 1 as time(6)) +select column_get(column_create(1, "-830:46:06.23434" AS CHAR), 1 as time(6)) as ex; +ex -830:46:06.234340 -select column_get(column_create(1, "0" AS CHAR), 1 as time); -column_get(column_create(1, "0" AS CHAR), 1 as time) +select column_get(column_create(1, "0" AS CHAR), 1 as time) as ex; +ex 00:00:00 -select column_get(column_create(1, "6" AS CHAR), 1 as time); -column_get(column_create(1, "6" AS CHAR), 1 as time) +select column_get(column_create(1, "6" AS CHAR), 1 as time) as ex; +ex 00:00:06 -select column_get(column_create(1, "1:6" AS CHAR), 1 as time); -column_get(column_create(1, "1:6" AS CHAR), 1 as time) +select column_get(column_create(1, "1:6" AS CHAR), 1 as time) as ex; +ex 01:06:00 -select column_get(column_create(1, "2:1:6" AS CHAR), 1 as time); -column_get(column_create(1, "2:1:6" AS CHAR), 1 as time) +select column_get(column_create(1, "2:1:6" AS CHAR), 1 as time) as ex; +ex 02:01:06 -select column_get(column_create(1, 0), 1 as time); -column_get(column_create(1, 0), 1 as time) +select column_get(column_create(1, 0), 1 as time) as ex; +ex 00:00:00 -select column_get(column_create(1, "2001021"), 1 as time); -column_get(column_create(1, "2001021"), 1 as time) +select column_get(column_create(1, "2001021"), 1 as time) as ex; +ex 200:10:21 set @@sql_mode="allow_invalid_dates"; -select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as time); -column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as time) +select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as time) as ex; +ex 18:46:06 set @@sql_mode=""; # column get date truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as time); -column_get(column_create(1, "1223.5aa" AS char), 1 as time) +select column_get(column_create(1, "1223.5aa" AS char), 1 as time) as ex; +ex 00:12:23 Warnings: Warning 1292 Truncated incorrect time value: '1223.5aa' -select column_get(column_create(1, "1223.5aa" AS char), 1 as time(3)); -column_get(column_create(1, "1223.5aa" AS char), 1 as time(3)) +select column_get(column_create(1, "1223.5aa" AS char), 1 as time(3)) as ex; +ex 00:12:23.500 Warnings: Warning 1292 Truncated incorrect time value: '1223.5aa' -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time); -column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time) +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time) as ex; +ex 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '1.8446744073709552e19' -select column_get(column_create(1, 9223372036854775807 AS int), 1 as time); -column_get(column_create(1, 9223372036854775807 AS int), 1 as time) +select column_get(column_create(1, 9223372036854775807 AS int), 1 as time) as ex; +ex 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '9223372036854775807' -select column_get(column_create(1, -9223372036854775808 AS int), 1 as time); -column_get(column_create(1, -9223372036854775808 AS int), 1 as time) +select column_get(column_create(1, -9223372036854775808 AS int), 1 as time) as ex; +ex -838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '-9223372036854775808' -select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time); -column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time) +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time) as ex; +ex 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '99999999999999999999999999999' -select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time); -column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time) +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time) as ex; +ex 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '1e29' -select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time); -column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time) +select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time) as ex; +ex NULL Warnings: Warning 1292 Incorrect time value: '2011-02-32 8:46:06.23434' -select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as time); -column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as time) +select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as time) as ex; +ex NULL Warnings: Warning 1292 Incorrect time value: '2011-13-01 8:46:06.23434' -select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as time); -column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as time) +select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as time) as ex; +ex 08:46:06 -select column_get(column_create(1, "2001-02-03"), 1 as time); -column_get(column_create(1, "2001-02-03"), 1 as time) +select column_get(column_create(1, "2001-02-03"), 1 as time) as ex; +ex 00:20:01 Warnings: Warning 1292 Truncated incorrect time value: '2001-02-03' -select column_get(column_create(1, "20010203"), 1 as time); -column_get(column_create(1, "20010203"), 1 as time) +select column_get(column_create(1, "20010203"), 1 as time) as ex; +ex 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '20010203' # column add -select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer)); -hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer)) +select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer)) as ex; +ex 00020001000002001078097809 -select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer)); -hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer)) +select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer)) as ex; +ex 0001000100007809 -select hex(column_add(column_create(1, 1212 as integer), 1, NULL as integer)); -hex(column_add(column_create(1, 1212 as integer), 1, NULL as integer)) +select hex(column_add(column_create(1, 1212 as integer), 1, NULL as integer)) as ex; +ex 000000 -select hex(column_add(column_create(1, 1212 as integer), 2, NULL as integer)); -hex(column_add(column_create(1, 1212 as integer), 2, NULL as integer)) +select hex(column_add(column_create(1, 1212 as integer), 2, NULL as integer)) as ex; +ex 0001000100007809 -select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer)); -hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer)) +select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer)) as ex; +ex 000200010000020008167809 -select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 1 as integer); -column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 1 as integer) +select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 1 as integer) as ex; +ex 11 -select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 2 as integer); -column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 2 as integer) +select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 2 as integer) as ex; +ex 1212 -select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer, 2, 11 as integer)); -hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer, 2, 11 as integer)) +select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer, 2, 11 as integer)) as ex; +ex 000200010000020010780916 -select hex(column_add(column_create(1, NULL as integer), 1, 1212 as integer, 2, 11 as integer)); -hex(column_add(column_create(1, NULL as integer), 1, 1212 as integer, 2, 11 as integer)) +select hex(column_add(column_create(1, NULL as integer), 1, 1212 as integer, 2, 11 as integer)) as ex; +ex 000200010000020010780916 -select hex(column_add(column_create(1, 1212 as integer, 2, 1212 as integer), 1, 11 as integer)); -hex(column_add(column_create(1, 1212 as integer, 2, 1212 as integer), 1, 11 as integer)) +select hex(column_add(column_create(1, 1212 as integer, 2, 1212 as integer), 1, 11 as integer)) as ex; +ex 000200010000020008167809 -select hex(column_add(column_create(1, 1), 1, null)); -hex(column_add(column_create(1, 1), 1, null)) +select hex(column_add(column_create(1, 1), 1, null)) as ex; +ex 000000 -select column_list(column_add(column_create(1, 1), 1, null)); -column_list(column_add(column_create(1, 1), 1, null)) +select column_list(column_add(column_create(1, 1), 1, null)) as ex; +ex -select column_list(column_add(column_create(1, 1), 1, "")); -column_list(column_add(column_create(1, 1), 1, "")) +select column_list(column_add(column_create(1, 1), 1, "")) as ex; +ex `1` -select hex(column_add("", 1, 1)); -hex(column_add("", 1, 1)) +select hex(column_add("", 1, 1)) as ex; +ex 00010001000002 # column delete -select hex(column_delete(column_create(1, 1212 as integer, 2, 1212 as integer), 1)); -hex(column_delete(column_create(1, 1212 as integer, 2, 1212 as integer), 1)) +select hex(column_delete(column_create(1, 1212 as integer, 2, 1212 as integer), 1)) as ex; +ex 0001000200007809 -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2)); -hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2)) +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2)) as ex; +ex 0002000100000300080206 -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 3)); -hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 3)) +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 3)) as ex; +ex 0002000100000200080204 -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 4)); -hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 4)) +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 4)) as ex; +ex 000300010000020008030010020406 -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 1)); -hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 1)) +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 1)) as ex; +ex 00010003000006 -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 3)); -hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 3)) +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 3)) as ex; +ex 00010001000002 -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3)); -hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3)) +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3)) as ex; +ex 000000 -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3, 10)); -hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3, 10)) +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3, 10)) as ex; +ex 000000 -select hex(column_delete(column_create(1, 1), 1)); -hex(column_delete(column_create(1, 1), 1)) +select hex(column_delete(column_create(1, 1), 1)) as ex; +ex 000000 -select hex(column_delete("", 1)); -hex(column_delete("", 1)) +select hex(column_delete("", 1)) as ex; +ex # column exists -select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 1); -column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 1) +select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 1) as ex; +ex 1 -select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4); -column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4) +select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4) as ex; +ex 0 # column list -select column_list(column_create(1, 1212 as integer, 2, 1212 as integer)); -column_list(column_create(1, 1212 as integer, 2, 1212 as integer)) +select column_list(column_create(1, 1212 as integer, 2, 1212 as integer)) as ex; +ex `1`,`2` -select column_list(column_create(1, 1212 as integer)); -column_list(column_create(1, 1212 as integer)) +select column_list(column_create(1, 1212 as integer)) as ex; +ex `1` -select column_list(column_create(1, NULL as integer)); -column_list(column_create(1, NULL as integer)) +select column_list(column_create(1, NULL as integer)) as ex; +ex # # check error handling @@ -1321,17 +1307,17 @@ set @a=0x00020008000009000C2C010080; select COLUMN_GET(@a, 9 AS DECIMAL); COLUMN_GET(@a, 9 AS DECIMAL) 0 -select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL))); -hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL))) +select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL))) as ex; +ex 000100000004 -select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0)))); -hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0)))) +select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0)))) as ex; +ex 000100000004 -select hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal))); -hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal))) +select hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal))) as ex; +ex 000100000004 -select hex(COLUMN_CREATE(0, 0.0 as decimal)); -hex(COLUMN_CREATE(0, 0.0 as decimal)) +select hex(COLUMN_CREATE(0, 0.0 as decimal)) as ex; +ex 000100000004 # # MDEV-4292: parse error when selecting on views using dynamic column @@ -1427,12 +1413,12 @@ CREATE TABLE t1 (dyncol TINYBLOB) ENGINE=MyISAM; INSERT INTO t1 SET dyncol = COLUMN_CREATE( 7, REPEAT('k',487), 209, REPEAT('x',464) ); Warnings: Warning 1265 Data truncated for column 'dyncol' at row 1 -SELECT COLUMN_ADD( dyncol, 7, '22:22:22', 8, REPEAT('x',270) AS CHAR ) FROM t1; +SELECT COLUMN_ADD( dyncol, 7, '22:22:22', 8, REPEAT('x',270) AS CHAR ) as ex FROM t1; delete from t1; INSERT INTO t1 SET dyncol = COLUMN_CREATE( 'a', REPEAT('k',487), 'b', REPEAT('x',464) ); Warnings: Warning 1265 Data truncated for column 'dyncol' at row 1 -SELECT COLUMN_ADD( dyncol, 'a', '22:22:22', 'c', REPEAT('x',270) AS CHAR ) FROM t1; +SELECT COLUMN_ADD( dyncol, 'a', '22:22:22', 'c', REPEAT('x',270) AS CHAR ) as ex FROM t1; DROP table t1; # # MDEV-4858 Wrong results for a huge unsigned value inserted into a TIME column @@ -1448,8 +1434,8 @@ Warning 1292 Truncated incorrect time value: '-9223372036854775808' # # end of 5.3 tests # -select column_get(column_create(1, "18446744073709552001" as char), 1 as int); -column_get(column_create(1, "18446744073709552001" as char), 1 as int) +select column_get(column_create(1, "18446744073709552001" as char), 1 as int) as ex; +ex -1 Warnings: Warning 1918 Encountered illegal value '18446744073709552001' when converting to INT @@ -1486,149 +1472,149 @@ hex(column_create("1212", 2, "адын", 1, 3, 3)) set names latin1; # fetching column test (names) set names utf8; -select column_get(column_create("адын", 1212), "адын" as int); -column_get(column_create("адын", 1212), "адын" as int) +select column_get(column_create("адын", 1212), "адын" as int) as ex; +ex 1212 -select column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int); -column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int) +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int) as ex; +ex 1 -select column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int); -column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int) +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int) as ex; +ex 2 -select column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int); -column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int) +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int) as ex; +ex 3 -select column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int); -column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int) +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int) as ex; +ex 3 -select column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int); -column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int) +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int) as ex; +ex NULL -select column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int); -column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int) +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int) as ex; +ex NULL set names latin1; # column existence test (names) set names utf8; -select column_exists(column_create("адын", 1212), "адын"); -column_exists(column_create("адын", 1212), "адын") +select column_exists(column_create("адын", 1212), "адын") as ex; +ex 1 -select column_exists(column_create("адын", 1212), "aады"); -column_exists(column_create("адын", 1212), "aады") +select column_exists(column_create("адын", 1212), "aады") as ex; +ex 0 -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын"); -column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын") +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын") as ex; +ex 1 -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212); -column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212) +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212) as ex; +ex 1 -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3"); -column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3") +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3") as ex; +ex 1 -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3); -column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3) +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3) as ex; +ex 1 -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4); -column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4) +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4) as ex; +ex 0 -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4"); -column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4") +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4") as ex; +ex 0 set names latin1; # column changing test (names) -select hex(column_add(column_create(1, "AAA"), "b", "BBB")); -hex(column_add(column_create(1, "AAA"), "b", "BBB")) +select hex(column_add(column_create(1, "AAA"), "b", "BBB")) as ex; +ex 0402000200000003000100430031620841414108424242 -select hex(column_add(column_create("1", "AAA"), "b", "BBB")); -hex(column_add(column_create("1", "AAA"), "b", "BBB")) +select hex(column_add(column_create("1", "AAA"), "b", "BBB")) as ex; +ex 0402000200000003000100430031620841414108424242 -select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char); -column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char) +select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char) as ex; +ex AAA -select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char); -column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char) +select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char) as ex; +ex BBB -select hex(column_add(column_create("a", "AAA"), 1, "BBB")); -hex(column_add(column_create("a", "AAA"), 1, "BBB")) +select hex(column_add(column_create("a", "AAA"), 1, "BBB")) as ex; +ex 0402000200000003000100430031610842424208414141 -select hex(column_add(column_create("a", "AAA"), "1", "BBB")); -hex(column_add(column_create("a", "AAA"), "1", "BBB")) +select hex(column_add(column_create("a", "AAA"), "1", "BBB")) as ex; +ex 0402000200000003000100430031610842424208414141 -select hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)); -hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)) +select hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)) as ex; +ex 04020002000000000001002000616278097809 -select hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)); -hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)) +select hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)) as ex; +ex 040100010000000000617809 -select hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)); -hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)) +select hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)) as ex; +ex 0400000000 -select hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)); -hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)) +select hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)) as ex; +ex 040100010000000000617809 -select hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)); -hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)) +select hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)) as ex; +ex 040200020000000000010010006162167809 -select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer); -column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer) +select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer) as ex; +ex 11 -select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer); -column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer) +select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer) as ex; +ex 1212 -select hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)); -hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)) +select hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)) as ex; +ex 040200020000000000010020006162780916 -select hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)); -hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)) +select hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)) as ex; +ex 040200020000000000010020006162780916 -select hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)); -hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)) +select hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)) as ex; +ex 040200020000000000010010006162167809 -select hex(column_add(column_create("a", 1), "a", null)); -hex(column_add(column_create("a", 1), "a", null)) +select hex(column_add(column_create("a", 1), "a", null)) as ex; +ex 0400000000 -select column_list(column_add(column_create("a", 1), "a", null)); -column_list(column_add(column_create("a", 1), "a", null)) +select column_list(column_add(column_create("a", 1), "a", null)) as ex; +ex -select column_list(column_add(column_create("a", 1), "a", "")); -column_list(column_add(column_create("a", 1), "a", "")) +select column_list(column_add(column_create("a", 1), "a", "")) as ex; +ex `a` -select hex(column_add("", "a", 1)); -hex(column_add("", "a", 1)) +select hex(column_add("", "a", 1)) as ex; +ex 0401000100000000006102 # column delete (names) -select hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")); -hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")) +select hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")) as ex; +ex 040100010000000000627809 -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")); -hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")) +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")) as ex; +ex 0402000200000000000100100061630206 -select hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)); -hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)) +select hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)) as ex; +ex 0403000300000000000100100002002000616263020406 -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")); -hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")) +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")) as ex; +ex 0402000200000000000100100061620204 -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")); -hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")) +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")) as ex; +ex 0403000300000000000100100002002000616263020406 -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")); -hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")) +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")) as ex; +ex 0401000100000000006306 -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")); -hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")) +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")) as ex; +ex 0401000100000000006102 -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")); -hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")) +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")) as ex; +ex 0400000000 -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e")); -hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e")) +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e")) as ex; +ex 0400000000 -select hex(column_delete(column_create("a", 1), "a")); -hex(column_delete(column_create("a", 1), "a")) +select hex(column_delete(column_create("a", 1), "a")) as ex; +ex 0400000000 -select hex(column_delete("", "a")); -hex(column_delete("", "a")) +select hex(column_delete("", "a")) as ex; +ex # # MDEV-458 DNAMES: Server crashes on using an unquoted string @@ -1661,23 +1647,23 @@ drop table t1; # # MDEV-490/MDEV-491 null as arguments # -SELECT COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR ); -COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR ) +SELECT COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR ) as ex; +ex NULL -SELECT COLUMN_GET( NULL, 'col' as char ); -COLUMN_GET( NULL, 'col' as char ) +SELECT COLUMN_GET( NULL, 'col' as char ) as ex; +ex NULL -SELECT COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL); -COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL) +SELECT COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL) as ex; +ex NULL -SELECT COLUMN_EXISTS( NULL, 'col'); -COLUMN_EXISTS( NULL, 'col') +SELECT COLUMN_EXISTS( NULL, 'col') as ex; +ex NULL -SELECT COLUMN_CREATE( NULL, 'val' ); -COLUMN_CREATE( NULL, 'val' ) +SELECT COLUMN_CREATE( NULL, 'val' ) as ex; +ex NULL -SELECT COLUMN_ADD( NULL, 'val', 'col'); -COLUMN_ADD( NULL, 'val', 'col') +SELECT COLUMN_ADD( NULL, 'val', 'col') as ex; +ex NULL # # MDEV-488: Assertion `column_name->length < 255' failed on a @@ -1691,11 +1677,11 @@ ERROR 22007: Illegal value used as argument of dynamic column function # # JSON conversion # -select column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" AS datetime, "date", "2011-04-05" AS date)); -column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" +select column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" AS datetime, "date", "2011-04-05" AS date)) as ex; +ex {"int":-1212,"date":"2011-04-05","time":"00:45:49.000001","uint":12334,"double":1.23444e50,"string":"gdgd\\dhdjh\"dhdhd","decimal":23.344,"datetime":"2011-04-05 00:45:49.000001"} -select column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)); -column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)) +select column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)) as ex; +ex {"1":-1212,"2":12334,"3":23.344,"4":1.23444e50,"5":"gdgd\\dhdjh\"dhdhd","6":"00:45:49.000001","7":"2011-04-05 00:45:49.000001","8":"2011-04-05"} # # CHECK test @@ -1721,11 +1707,11 @@ column_json(column_create("string", "'\"/\\`.,whatever")) hex(column_create("str # # embedding test # -select column_json(column_create("val", "val", "emb", column_create("val2", "val2"))); -column_json(column_create("val", "val", "emb", column_create("val2", "val2"))) +select column_json(column_create("val", "val", "emb", column_create("val2", "val2"))) as ex; +ex {"emb":{"val2":"val2"},"val":"val"} -select column_json(column_create(1, "val", 2, column_create(3, "val2"))); -column_json(column_create(1, "val", 2, column_create(3, "val2"))) +select column_json(column_create(1, "val", 2, column_create(3, "val2"))) as ex; +ex {"1":"val","2":{"3":"val2"}} # # Time encoding @@ -1778,8 +1764,8 @@ DROP TABLE t1; # create table t1 (dyn blob); insert into t1 values (column_create('name1','value1','name2','value2')); -select group_concat(cast(column_json(dyn) as char)) from t1; -group_concat(cast(column_json(dyn) as char)) +select group_concat(cast(column_json(dyn) as char)) as ex from t1; +ex {"name1":"value1","name2":"value2"} drop table t1; # @@ -1827,25 +1813,20 @@ COLUMN_CREATE( 'one', 123.456, 'two', 123.456 as DOUBLE ) -); -COLUMN_JSON( -COLUMN_CREATE( -'one', 123.456, -'two', 123.456 as DOUBLE -) -) +) as ex; +ex {"one":123.456,"two":123.456} # # MDEV-8521: Drastic loss of precision in COLUMN_JSON() on DOUBLEs # -select column_get(column_create('float', 1.23456789012345E+100 as double), 'float' as double); -column_get(column_create('float', 1.23456789012345E+100 as double), 'float' as double) +select column_get(column_create('float', 1.23456789012345E+100 as double), 'float' as double) as ex; +ex 1.23456789012345e100 -select column_json(column_create('float', 1.23456789012345E+100 as double)); -column_json(column_create('float', 1.23456789012345E+100 as double)) +select column_json(column_create('float', 1.23456789012345E+100 as double)) as ex; +ex {"float":1.23456789012345e100} -select column_json(column_create('float', 1.23456789012345E+10 as double)); -column_json(column_create('float', 1.23456789012345E+10 as double)) +select column_json(column_create('float', 1.23456789012345E+10 as double)) as ex; +ex {"float":12345678901.2345} # # MDEV-9147: Character set is ignored in Dynamic Column for saved string @@ -1860,17 +1841,17 @@ a # # MDEV-9167: COLUMN_CHECK fails on valid decimal data # -SELECT COLUMN_CHECK(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)); -COLUMN_CHECK(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)) +SELECT COLUMN_CHECK(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)) as ex; +ex 1 -SELECT COLUMN_CHECK(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)); -COLUMN_CHECK(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)) +SELECT COLUMN_CHECK(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)) as ex; +ex 1 -SELECT COLUMN_JSON(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)); -COLUMN_JSON(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)) +SELECT COLUMN_JSON(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)) as ex; +ex {"a":0,"b":1} -SELECT COLUMN_JSON(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)); -COLUMN_JSON(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)) +SELECT COLUMN_JSON(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)) as ex; +ex {"a":1,"b":1} # # MDEV-7533: COLUMN_JSON() doesn't escape control characters @@ -1956,3 +1937,15 @@ DROP TABLE t1; # # End of 10.2 tests # +# +# MDEV-32140: Valgrind/MSAN warnings in dynamic_column_update_move_left +# +SELECT COLUMN_GET(COLUMN_ADD(COLUMN_CREATE(1,10),2,NULL,1,NULL),3 AS INTEGER) as ex; +ex +NULL +SELECT HEX(COLUMN_ADD(COLUMN_CREATE(1,10),2,NULL,1,NULL)) as ex; +ex +000000 +# +# End of 10.4 tests +# diff --git a/mysql-test/main/dyncol.test b/mysql-test/main/dyncol.test index 493e9b3842d..8b3164217d1 100644 --- a/mysql-test/main/dyncol.test +++ b/mysql-test/main/dyncol.test @@ -1,19 +1,17 @@ # # Dynamic column function test # -# enable view-protocol after fix MDEV-27871 --- source include/no_view_protocol.inc --source include/default_charset.inc --echo # --echo # column create --echo # -select hex(COLUMN_CREATE(1, NULL AS char character set utf8)); -select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8)); -select hex(COLUMN_CREATE(1, 1212 AS char character set utf8)); -select hex(COLUMN_CREATE(1, 12.12 AS char character set utf8)); -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS char character set utf8)); +select hex(COLUMN_CREATE(1, NULL AS char character set utf8)) as exp; +select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8)) as ex; +select hex(COLUMN_CREATE(1, 1212 AS char character set utf8)) as ex; +select hex(COLUMN_CREATE(1, 12.12 AS char character set utf8)) as ex; +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS char character set utf8)) as ex; select hex(COLUMN_CREATE(1, NULL AS unsigned int)); select hex(COLUMN_CREATE(1, 1212 AS unsigned int)); select hex(COLUMN_CREATE(1, 7 AS unsigned int)); @@ -23,7 +21,7 @@ select hex(COLUMN_CREATE(1, 128 AS unsigned int)); select hex(COLUMN_CREATE(1, 12.12 AS unsigned int)); select hex(COLUMN_CREATE(1, ~0)); select hex(COLUMN_CREATE(1, -1)); -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int)); +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int)) as ex; select hex(COLUMN_CREATE(1, NULL AS int)); select hex(COLUMN_CREATE(1, 1212 AS int)); select hex(COLUMN_CREATE(1, 7 AS int)); @@ -31,11 +29,11 @@ select hex(COLUMN_CREATE(1, 8 AS int)); select hex(COLUMN_CREATE(1, 127 AS int)); select hex(COLUMN_CREATE(1, 128 AS int)); select hex(COLUMN_CREATE(1, 12.12 AS int)); -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS int)); +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS int)) as ex; select hex(COLUMN_CREATE(1, NULL AS double)); select hex(COLUMN_CREATE(1, 1212 AS double)); select hex(COLUMN_CREATE(1, 12.12 AS double)); -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS double)); +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS double)) as ex; select hex(COLUMN_CREATE(1, NULL AS decimal)); select hex(COLUMN_CREATE(1, 1212 AS decimal)); select hex(COLUMN_CREATE(1, 7 AS decimal)); @@ -43,13 +41,13 @@ select hex(COLUMN_CREATE(1, 8 AS decimal)); select hex(COLUMN_CREATE(1, 127 AS decimal)); select hex(COLUMN_CREATE(1, 128 AS decimal)); select hex(COLUMN_CREATE(1, 12.12 AS decimal)); -select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS decimal)); +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS decimal)) as ex; select hex(COLUMN_CREATE(1, NULL AS date)); select hex(COLUMN_CREATE(1, "2011-04-05" AS date)); select hex(COLUMN_CREATE(1, NULL AS time)); select hex(COLUMN_CREATE(1, "0:45:49.000001" AS time)); select hex(COLUMN_CREATE(1, NULL AS datetime)); -select hex(COLUMN_CREATE(1, "2011-04-05 0:45:49.000001" AS datetime)); +select hex(COLUMN_CREATE(1, "2011-04-05 0:45:49.000001" AS datetime)) as ex; select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, 2, 1212 AS unsigned int, 3, 1212 AS int, @@ -57,7 +55,7 @@ select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, 4+1, 12.12 AS decimal, 6, "2011-04-05" AS date, 7, "- 0:45:49.000001" AS time, - 8, "2011-04-05 0:45:49.000001" AS datetime)); + 8, "2011-04-05 0:45:49.000001" AS datetime)) as ex; explain extended select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, 2, 1212 AS unsigned int, @@ -66,353 +64,353 @@ select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, 4+1, 12.12 AS decimal, 6, "2011-04-05" AS date, 7, "- 0:45:49.000001" AS time, - 8, "2011-04-05 0:45:49.000001" AS datetime)); + 8, "2011-04-05 0:45:49.000001" AS datetime)) as ex; select hex(column_create(1, 0.0 AS decimal)); select hex(column_create(1, 1.0 AS decimal)); --echo # --echo # column get uint --echo # -select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int); +select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int) as ex; explain extended -select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int); +select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int) as ex; explain extended -select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned); -select column_get(column_create(1, 1212 AS decimal), 1 as unsigned int); -select column_get(column_create(1, 1212 AS double), 1 as unsigned int); -select column_get(column_create(1, 1212 AS int), 1 as unsigned int); -select column_get(column_create(1, "1212" AS char), 1 as unsigned int); -select column_get(column_create(1, "2011-04-05" AS date), 1 as unsigned int); -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as unsigned int); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as unsigned int); -select column_get(column_create(1, NULL AS unsigned int), 1 as unsigned int); +select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned) as ex; +select column_get(column_create(1, 1212 AS decimal), 1 as unsigned int) as ex; +select column_get(column_create(1, 1212 AS double), 1 as unsigned int) as ex; +select column_get(column_create(1, 1212 AS int), 1 as unsigned int) as ex; +select column_get(column_create(1, "1212" AS char), 1 as unsigned int) as ex; +select column_get(column_create(1, "2011-04-05" AS date), 1 as unsigned int) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as unsigned int) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as unsigned int) as ex; +select column_get(column_create(1, NULL AS unsigned int), 1 as unsigned int) as ex; --echo # column geint truncation & warnings -select column_get(column_create(1, -1212 AS int), 1 as unsigned int); -select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as unsigned int); -select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as unsigned int); -select column_get(column_create(1, -1 AS decimal), 1 as unsigned int); +select column_get(column_create(1, -1212 AS int), 1 as unsigned int) as ex; +select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as unsigned int) as ex; +select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as unsigned int) as ex; +select column_get(column_create(1, -1 AS decimal), 1 as unsigned int) as ex; --replace_result e+029 e+29 -select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int); -select column_get(column_create(1, 999.9 AS double), 1 as unsigned int); -select column_get(column_create(1, -1 AS double), 1 as unsigned int); -select column_get(column_create(1, "1212III" AS char), 1 as unsigned int); +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int) as ex; +select column_get(column_create(1, 999.9 AS double), 1 as unsigned int) as ex; +select column_get(column_create(1, -1 AS double), 1 as unsigned int) as ex; +select column_get(column_create(1, "1212III" AS char), 1 as unsigned int) as ex; --echo # --echo # column get int --echo # -select column_get(column_create(1, 1212 AS int), 1 as int); +select column_get(column_create(1, 1212 AS int), 1 as int) as ex; explain extended -select column_get(column_create(1, 1212 AS int), 1 as int); +select column_get(column_create(1, 1212 AS int), 1 as int) as ex; explain extended -select column_get(column_create(1, 1212 AS int), 1 as signed int); -select column_get(column_create(1, -1212 AS int), 1 as int); -select column_get(column_create(1, 1212 AS decimal), 1 as int); -select column_get(column_create(1, 1212 AS double), 1 as int); -select column_get(column_create(1, 1212 AS unsigned int), 1 as int); -select column_get(column_create(1, "1212" AS char), 1 as int); -select column_get(column_create(1, "-1212" AS char), 1 as int); -select column_get(column_create(1, "2011-04-05" AS date), 1 as int); -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as int); -select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as int); -select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as int); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as int); -select column_get(column_create(1, NULL AS int), 1 as int); +select column_get(column_create(1, 1212 AS int), 1 as signed int) as ex; +select column_get(column_create(1, -1212 AS int), 1 as int) as ex; +select column_get(column_create(1, 1212 AS decimal), 1 as int) as ex; +select column_get(column_create(1, 1212 AS double), 1 as int) as ex; +select column_get(column_create(1, 1212 AS unsigned int), 1 as int) as ex; +select column_get(column_create(1, "1212" AS char), 1 as int) as ex; +select column_get(column_create(1, "-1212" AS char), 1 as int) as ex; +select column_get(column_create(1, "2011-04-05" AS date), 1 as int) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as int) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as int) as ex; +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as int) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as int) as ex; +select column_get(column_create(1, NULL AS int), 1 as int) as ex; --echo #column gett truncation & warnings -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as int); -select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as int); -select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as int); -select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as int); -select column_get(column_create(1, 999.9 AS double), 1 as int); +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as int) as ex; +select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as int) as ex; +select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as int) as ex; +select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as int) as ex; +select column_get(column_create(1, 999.9 AS double), 1 as int) as ex; --replace_result e+029 e+29 -select column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int); -select column_get(column_create(1, "-1212III" AS char), 1 as int); -select column_get(column_create(1, "1212III" AS char), 1 as int); -select column_get(COLUMN_CREATE(1, ~0), 1 as signed); -select column_get(COLUMN_CREATE(1, ~0), 1 as unsigned); -select column_get(COLUMN_CREATE(1, -1), 1 as signed); -select column_get(COLUMN_CREATE(1, -1), 1 as unsigned); +select column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int) as ex; +select column_get(column_create(1, "-1212III" AS char), 1 as int) as ex; +select column_get(column_create(1, "1212III" AS char), 1 as int) as ex; +select column_get(COLUMN_CREATE(1, ~0), 1 as signed) as ex; +select column_get(COLUMN_CREATE(1, ~0), 1 as unsigned) as ex; +select column_get(COLUMN_CREATE(1, -1), 1 as signed) as ex; +select column_get(COLUMN_CREATE(1, -1), 1 as unsigned) as ex; --echo # --echo #column get char --echo # -select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8); +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8) as ex; explain extended -select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8); -select column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8); -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as char charset utf8); -select column_get(column_create(1, 1212 AS int), 1 as char charset utf8); -select column_get(column_create(1, -1212 AS int), 1 as char charset utf8); -select column_get(column_create(1, 9223372036854775807 AS int), 1 as char charset utf8); -select column_get(column_create(1, -9223372036854775808 AS int), 1 as char charset utf8); -select column_get(column_create(1, 1212.12 AS decimal), 1 as char charset utf8); -select column_get(column_create(1, 1212.12 AS double), 1 as char charset utf8); -select column_get(column_create(1, "2011-04-05" AS date), 1 as char charset utf8); -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as char charset utf8); -select column_get(column_create(1, "8:46:06.23434" AS time(0)), 1 as char charset utf8); -select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as char charset utf8); -select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as char charset utf8); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as char charset utf8); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(0)), 1 as char charset utf8); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as char charset utf8); -select column_get(column_create(1, NULL AS char charset utf8), 1 as char charset utf8); -select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary); +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8) as ex; +select column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8) as ex; +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as char charset utf8) as ex; +select column_get(column_create(1, 1212 AS int), 1 as char charset utf8) as ex; +select column_get(column_create(1, -1212 AS int), 1 as char charset utf8) as ex; +select column_get(column_create(1, 9223372036854775807 AS int), 1 as char charset utf8) as ex; +select column_get(column_create(1, -9223372036854775808 AS int), 1 as char charset utf8) as ex; +select column_get(column_create(1, 1212.12 AS decimal), 1 as char charset utf8) as ex; +select column_get(column_create(1, 1212.12 AS double), 1 as char charset utf8) as ex; +select column_get(column_create(1, "2011-04-05" AS date), 1 as char charset utf8) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as char charset utf8) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time(0)), 1 as char charset utf8) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as char charset utf8) as ex; +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as char charset utf8) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as char charset utf8) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(0)), 1 as char charset utf8) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as char charset utf8) as ex; +select column_get(column_create(1, NULL AS char charset utf8), 1 as char charset utf8) as ex; +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary) as ex; explain extended -select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary); +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary) as ex; --echo # --echo # column get real --echo # -select column_get(column_create(1, 1212.12 AS double), 1 as double); +select column_get(column_create(1, 1212.12 AS double), 1 as double) as ex; explain extended -select column_get(column_create(1, 1212.12 AS double), 1 as double); +select column_get(column_create(1, 1212.12 AS double), 1 as double) as ex; explain extended -select column_get(column_create(1, 1212.12 AS double), 1 as double(6,2)); -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as double); -select column_get(column_create(1, 9223372036854775807 AS int), 1 as double); -select column_get(column_create(1, -9223372036854775808 AS int), 1 as double); -select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as double); -select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as double); -select column_get(column_create(1, "2011-04-05" AS date), 1 as double); -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as double); -select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as double); -select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as double); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as double); +select column_get(column_create(1, 1212.12 AS double), 1 as double(6,2)) as ex; +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as double) as ex; +select column_get(column_create(1, 9223372036854775807 AS int), 1 as double) as ex; +select column_get(column_create(1, -9223372036854775808 AS int), 1 as double) as ex; +select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as double) as ex; +select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as double) as ex; +select column_get(column_create(1, "2011-04-05" AS date), 1 as double) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as double) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as double) as ex; +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as double) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as double) as ex; # The replace result is needed for windows. -select round(column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double(20,6)),3); -select column_get(column_create(1, NULL AS double), 1 as double); +select round(column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double(20,6)),3) as ex; +select column_get(column_create(1, NULL AS double), 1 as double) as ex; -- echo # column get real truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as double); -select column_get(column_create(1, "aa" AS char), 1 as double); -select column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2)); -select column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2)); +select column_get(column_create(1, "1223.5aa" AS char), 1 as double) as ex; +select column_get(column_create(1, "aa" AS char), 1 as double) as ex; +select column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2)) as ex; +select column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2)) as ex; --echo # --echo # column get decimal --echo # -select column_get(column_create(1, 1212.12 AS double), 1 as decimal); -select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)); +select column_get(column_create(1, 1212.12 AS double), 1 as decimal) as ex; +select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)) as ex; explain extended -select column_get(column_create(1, 1212.12 AS double), 1 as decimal); +select column_get(column_create(1, 1212.12 AS double), 1 as decimal) as ex; explain extended -select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)); -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal(20,0)); -select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal(32,0)); -select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal(32,0)); -select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as decimal(40,10)); -select column_get(column_create(1, "2011-04-05" AS date), 1 as decimal(32,6)); -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as decimal(32,6)); -select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as decimal(32,6)); -select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as decimal(32,6)); -select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime), 1 as decimal(32,6)); -select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime(6)), 1 as decimal(32,6)); -select column_get(column_create(1, "2011-04-05 8:46:06.12345678" AS datetime(6)), 1 as decimal(32,8)); -select column_get(column_create(1, NULL as decimal), 1 as decimal(32,10)); -select column_get(column_create(1, "1223.5555" as decimal(10,5)), 1 as decimal(6,2)); +select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)) as ex; +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal(20,0)) as ex; +select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal(32,0)) as ex; +select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal(32,0)) as ex; +select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as decimal(40,10)) as ex; +select column_get(column_create(1, "2011-04-05" AS date), 1 as decimal(32,6)) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as decimal(32,6)) as ex; +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as decimal(32,6)) as ex; +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as decimal(32,6)) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime), 1 as decimal(32,6)) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime(6)), 1 as decimal(32,6)) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.12345678" AS datetime(6)), 1 as decimal(32,8)) as ex; +select column_get(column_create(1, NULL as decimal), 1 as decimal(32,10)) as ex; +select column_get(column_create(1, "1223.5555" as decimal(10,5)), 1 as decimal(6,2)) as ex; -- echo # column get decimal truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as decimal(32,10)); -select column_get(column_create(1, "aa" AS char), 1 as decimal(32,10)); -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal); -select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal); -select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal); -select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal); -select column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2)); -select column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2)); -select column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2)); -select column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2)); -select column_get(column_create(1, 0.0 AS decimal,2, 0.0 as decimal), 1 as decimal); +select column_get(column_create(1, "1223.5aa" AS char), 1 as decimal(32,10)) as ex; +select column_get(column_create(1, "aa" AS char), 1 as decimal(32,10)) as ex; +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal) as ex; +select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal) as ex; +select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal) as ex; +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal) as ex; +select column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2)) as ex; +select column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2)) as ex; +select column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2)) as ex; +select column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2)) as ex; +select column_get(column_create(1, 0.0 AS decimal,2, 0.0 as decimal), 1 as decimal) as ex; --echo # --echo # column get datetime --echo # -select column_get(column_create(1, 20010203101112.121314 as double), 1 as datetime); -select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as datetime); -select column_get(column_create(1, 20010203101112 as unsigned int), 1 as datetime); -select column_get(column_create(1, 20010203101112 as int), 1 as datetime); -select column_get(column_create(1, "20010203101112" as char), 1 as datetime); -select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as datetime); -select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as datetime); -select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as datetime); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(0)); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(6)); -select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as datetime); -select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as datetime); +select column_get(column_create(1, 20010203101112.121314 as double), 1 as datetime) as ex; +select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as datetime) as ex; +select column_get(column_create(1, 20010203101112 as unsigned int), 1 as datetime) as ex; +select column_get(column_create(1, 20010203101112 as int), 1 as datetime) as ex; +select column_get(column_create(1, "20010203101112" as char), 1 as datetime) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as datetime) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as datetime) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as datetime) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(0)) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(6)) as ex; +select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as datetime) as ex; +select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as datetime) as ex; -select column_get(column_create(1, 20010203 as unsigned int), 1 as datetime); -select column_get(column_create(1, 20010203 as int), 1 as datetime); -select column_get(column_create(1, 20010203), 1 as datetime); -select column_get(column_create(1, 20010203.0), 1 as datetime); -select column_get(column_create(1, 20010203.0 as double), 1 as datetime); -select column_get(column_create(1, "2001-02-03"), 1 as datetime); -select column_get(column_create(1, "20010203"), 1 as datetime); -select column_get(column_create(1, 0), 1 as datetime); -select column_get(column_create(1, "2001021"), 1 as datetime); +select column_get(column_create(1, 20010203 as unsigned int), 1 as datetime) as ex; +select column_get(column_create(1, 20010203 as int), 1 as datetime) as ex; +select column_get(column_create(1, 20010203), 1 as datetime) as ex; +select column_get(column_create(1, 20010203.0), 1 as datetime) as ex; +select column_get(column_create(1, 20010203.0 as double), 1 as datetime) as ex; +select column_get(column_create(1, "2001-02-03"), 1 as datetime) as ex; +select column_get(column_create(1, "20010203"), 1 as datetime) as ex; +select column_get(column_create(1, 0), 1 as datetime) as ex; +select column_get(column_create(1, "2001021"), 1 as datetime) as ex; SET timestamp=unix_timestamp('2001-02-03 10:20:30'); -select column_get(column_create(1, "8:46:06.23434" AS time), 1 as datetime); -select column_get(column_create(1, "-808:46:06.23434" AS time), 1 as datetime); +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as datetime) as ex; +select column_get(column_create(1, "-808:46:06.23434" AS time), 1 as datetime) as ex; SET timestamp=DEFAULT; set @@sql_mode="allow_invalid_dates"; -select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as datetime); -select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as datetime); -select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as datetime); +select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as datetime) as ex; +select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as datetime) as ex; +select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as datetime) as ex; set @@sql_mode=""; -- echo # column get datetime truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as datetime); +select column_get(column_create(1, "1223.5aa" AS char), 1 as datetime) as ex; --replace_result e+019 e+19 -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as datetime); -select column_get(column_create(1, 9223372036854775807 AS int), 1 as datetime); -select column_get(column_create(1, -9223372036854775808 AS int), 1 as datetime); -select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as datetime); +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as datetime) as ex; +select column_get(column_create(1, 9223372036854775807 AS int), 1 as datetime) as ex; +select column_get(column_create(1, -9223372036854775808 AS int), 1 as datetime) as ex; +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as datetime) as ex; --replace_result e+029 e+29 -select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as datetime); -select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as datetime); -select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as datetime); -select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as datetime); -select column_get(column_create(1, "20010231"), 1 as datetime); -select column_get(column_create(1, "0" AS CHAR), 1 as datetime); +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as datetime) as ex; +select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as datetime) as ex; +select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as datetime) as ex; +select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as datetime) as ex; +select column_get(column_create(1, "20010231"), 1 as datetime) as ex; +select column_get(column_create(1, "0" AS CHAR), 1 as datetime) as ex; --echo # --echo # column get date --echo # -select column_get(column_create(1, 20010203101112.121314 as double), 1 as date); -select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as date); -select column_get(column_create(1, 20010203101112 as unsigned int), 1 as date); -select column_get(column_create(1, 20010203101112 as int), 1 as date); -select column_get(column_create(1, "20010203101112" as char), 1 as date); -select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as date); -select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as date); -select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as date); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as date); -select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as date); -select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as date); +select column_get(column_create(1, 20010203101112.121314 as double), 1 as date) as ex; +select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as date) as ex; +select column_get(column_create(1, 20010203101112 as unsigned int), 1 as date) as ex; +select column_get(column_create(1, 20010203101112 as int), 1 as date) as ex; +select column_get(column_create(1, "20010203101112" as char), 1 as date) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as date) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as date) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as date) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as date) as ex; +select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as date) as ex; +select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as date) as ex; -select column_get(column_create(1, 20010203 as unsigned int), 1 as date); -select column_get(column_create(1, 20010203 as int), 1 as date); -select column_get(column_create(1, 20010203), 1 as date); -select column_get(column_create(1, 20010203.0), 1 as date); -select column_get(column_create(1, 20010203.0 as double), 1 as date); -select column_get(column_create(1, "2001-02-03"), 1 as date); -select column_get(column_create(1, "20010203"), 1 as date); -select column_get(column_create(1, 0), 1 as date); -select column_get(column_create(1, "2001021"), 1 as date); +select column_get(column_create(1, 20010203 as unsigned int), 1 as date) as ex; +select column_get(column_create(1, 20010203 as int), 1 as date) as ex; +select column_get(column_create(1, 20010203), 1 as date) as ex; +select column_get(column_create(1, 20010203.0), 1 as date) as ex; +select column_get(column_create(1, 20010203.0 as double), 1 as date) as ex; +select column_get(column_create(1, "2001-02-03"), 1 as date) as ex; +select column_get(column_create(1, "20010203"), 1 as date) as ex; +select column_get(column_create(1, 0), 1 as date) as ex; +select column_get(column_create(1, "2001021"), 1 as date) as ex; set @@sql_mode="allow_invalid_dates"; -select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date); -select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date); -select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as date); +select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date) as ex; +select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date) as ex; +select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as date) as ex; set @@sql_mode=""; -- echo # column get date truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as date); +select column_get(column_create(1, "1223.5aa" AS char), 1 as date) as ex; --replace_result e+019 e+19 -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as date); -select column_get(column_create(1, 9223372036854775807 AS int), 1 as date); -select column_get(column_create(1, -9223372036854775808 AS int), 1 as date); -select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as date); +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as date) as ex; +select column_get(column_create(1, 9223372036854775807 AS int), 1 as date) as ex; +select column_get(column_create(1, -9223372036854775808 AS int), 1 as date) as ex; +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as date) as ex; --replace_result e+029 e+29 -select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as date); -select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as date); -select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as date); -select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as date); -select column_get(column_create(1, "20010231"), 1 as date); -select column_get(column_create(1, "0" AS CHAR), 1 as date); +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as date) as ex; +select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as date) as ex; +select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as date) as ex; +select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as date) as ex; +select column_get(column_create(1, "20010231"), 1 as date) as ex; +select column_get(column_create(1, "0" AS CHAR), 1 as date) as ex; --echo # --echo # column get time --echo # -select column_get(column_create(1, 20010203101112.121314 as double), 1 as time); -select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as time); -select column_get(column_create(1, 20010203101112 as unsigned int), 1 as time); -select column_get(column_create(1, 8080102 as unsigned int), 1 as time); -select column_get(column_create(1, 20010203101112 as int), 1 as time); -select column_get(column_create(1, -8080102 as int), 1 as time); -select column_get(column_create(1, "20010203101112" as char), 1 as time); -select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as time); -select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time); -select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time(6)); -select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as time); -select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as time(6)); -select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as time(6)); -select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as time(6)); -select column_get(column_create(1, "830:46:06.23434" AS CHAR), 1 as time(6)); -select column_get(column_create(1, "830:46:06" AS CHAR), 1 as time(6)); -select cast("-830:46:06.23434" AS time(6)); -select 1,cast("-830:46:06.23434" AS time(6)); -select hex(column_create(1, "-830:46:06.23434" AS CHAR)); -select column_get(column_create(1, "-830:46:06.23434" AS CHAR), 1 as time(6)); -select column_get(column_create(1, "0" AS CHAR), 1 as time); -select column_get(column_create(1, "6" AS CHAR), 1 as time); -select column_get(column_create(1, "1:6" AS CHAR), 1 as time); -select column_get(column_create(1, "2:1:6" AS CHAR), 1 as time); +select column_get(column_create(1, 20010203101112.121314 as double), 1 as time) as ex; +select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as time) as ex; +select column_get(column_create(1, 20010203101112 as unsigned int), 1 as time) as ex; +select column_get(column_create(1, 8080102 as unsigned int), 1 as time) as ex; +select column_get(column_create(1, 20010203101112 as int), 1 as time) as ex; +select column_get(column_create(1, -8080102 as int), 1 as time) as ex; +select column_get(column_create(1, "20010203101112" as char), 1 as time) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as time) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time(6)) as ex; +select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as time) as ex; +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as time(6)) as ex; +select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as time(6)) as ex; +select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as time(6)) as ex; +select column_get(column_create(1, "830:46:06.23434" AS CHAR), 1 as time(6)) as ex; +select column_get(column_create(1, "830:46:06" AS CHAR), 1 as time(6)) as ex; +select cast("-830:46:06.23434" AS time(6)) as ex; +select 1,cast("-830:46:06.23434" AS time(6)) as ex; +select hex(column_create(1, "-830:46:06.23434" AS CHAR)) as ex; +select column_get(column_create(1, "-830:46:06.23434" AS CHAR), 1 as time(6)) as ex; +select column_get(column_create(1, "0" AS CHAR), 1 as time) as ex; +select column_get(column_create(1, "6" AS CHAR), 1 as time) as ex; +select column_get(column_create(1, "1:6" AS CHAR), 1 as time) as ex; +select column_get(column_create(1, "2:1:6" AS CHAR), 1 as time) as ex; -select column_get(column_create(1, 0), 1 as time); -select column_get(column_create(1, "2001021"), 1 as time); +select column_get(column_create(1, 0), 1 as time) as ex; +select column_get(column_create(1, "2001021"), 1 as time) as ex; set @@sql_mode="allow_invalid_dates"; -select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as time); +select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as time) as ex; set @@sql_mode=""; -- echo # column get date truncation & warnings -select column_get(column_create(1, "1223.5aa" AS char), 1 as time); -select column_get(column_create(1, "1223.5aa" AS char), 1 as time(3)); +select column_get(column_create(1, "1223.5aa" AS char), 1 as time) as ex; +select column_get(column_create(1, "1223.5aa" AS char), 1 as time(3)) as ex; --replace_result e+019 e+19 -select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time); -select column_get(column_create(1, 9223372036854775807 AS int), 1 as time); -select column_get(column_create(1, -9223372036854775808 AS int), 1 as time); -select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time); +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time) as ex; +select column_get(column_create(1, 9223372036854775807 AS int), 1 as time) as ex; +select column_get(column_create(1, -9223372036854775808 AS int), 1 as time) as ex; +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time) as ex; --replace_result e+029 e+29 -select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time); -select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time); -select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as time); -select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as time); -select column_get(column_create(1, "2001-02-03"), 1 as time); -select column_get(column_create(1, "20010203"), 1 as time); +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time) as ex; +select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time) as ex; +select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as time) as ex; +select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as time) as ex; +select column_get(column_create(1, "2001-02-03"), 1 as time) as ex; +select column_get(column_create(1, "20010203"), 1 as time) as ex; -- echo # column add -select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer)); -select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer)); -select hex(column_add(column_create(1, 1212 as integer), 1, NULL as integer)); -select hex(column_add(column_create(1, 1212 as integer), 2, NULL as integer)); -select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer)); -select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 1 as integer); -select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 2 as integer); -select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer, 2, 11 as integer)); -select hex(column_add(column_create(1, NULL as integer), 1, 1212 as integer, 2, 11 as integer)); -select hex(column_add(column_create(1, 1212 as integer, 2, 1212 as integer), 1, 11 as integer)); -select hex(column_add(column_create(1, 1), 1, null)); -select column_list(column_add(column_create(1, 1), 1, null)); -select column_list(column_add(column_create(1, 1), 1, "")); -select hex(column_add("", 1, 1)); +select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer)) as ex; +select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer)) as ex; +select hex(column_add(column_create(1, 1212 as integer), 1, NULL as integer)) as ex; +select hex(column_add(column_create(1, 1212 as integer), 2, NULL as integer)) as ex; +select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer)) as ex; +select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 1 as integer) as ex; +select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 2 as integer) as ex; +select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer, 2, 11 as integer)) as ex; +select hex(column_add(column_create(1, NULL as integer), 1, 1212 as integer, 2, 11 as integer)) as ex; +select hex(column_add(column_create(1, 1212 as integer, 2, 1212 as integer), 1, 11 as integer)) as ex; +select hex(column_add(column_create(1, 1), 1, null)) as ex; +select column_list(column_add(column_create(1, 1), 1, null)) as ex; +select column_list(column_add(column_create(1, 1), 1, "")) as ex; +select hex(column_add("", 1, 1)) as ex; -- echo # column delete -select hex(column_delete(column_create(1, 1212 as integer, 2, 1212 as integer), 1)); -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2)); -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 3)); -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 4)); -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 1)); -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 3)); -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3)); -select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3, 10)); -select hex(column_delete(column_create(1, 1), 1)); -select hex(column_delete("", 1)); +select hex(column_delete(column_create(1, 1212 as integer, 2, 1212 as integer), 1)) as ex; +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2)) as ex; +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 3)) as ex; +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 4)) as ex; +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 1)) as ex; +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 3)) as ex; +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3)) as ex; +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3, 10)) as ex; +select hex(column_delete(column_create(1, 1), 1)) as ex; +select hex(column_delete("", 1)) as ex; -- echo # column exists -select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 1); -select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4); +select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 1) as ex; +select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4) as ex; -- echo # column list -select column_list(column_create(1, 1212 as integer, 2, 1212 as integer)); -select column_list(column_create(1, 1212 as integer)); -select column_list(column_create(1, NULL as integer)); +select column_list(column_create(1, 1212 as integer, 2, 1212 as integer)) as ex; +select column_list(column_create(1, 1212 as integer)) as ex; +select column_list(column_create(1, NULL as integer)) as ex; --echo # --echo # check error handling @@ -551,11 +549,11 @@ select column_add(@a, 3, "a"); set @a=0x00020008000009000C2C010080; select COLUMN_GET(@a, 9 AS DECIMAL); -select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL))); -select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0)))); +select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL))) as ex; +select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0)))) as ex; -select hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal))); -select hex(COLUMN_CREATE(0, 0.0 as decimal)); +select hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal))) as ex; +select hex(COLUMN_CREATE(0, 0.0 as decimal)) as ex; --echo # --echo # MDEV-4292: parse error when selecting on views using dynamic column @@ -635,11 +633,11 @@ CREATE TABLE t1 (dyncol TINYBLOB) ENGINE=MyISAM; INSERT INTO t1 SET dyncol = COLUMN_CREATE( 7, REPEAT('k',487), 209, REPEAT('x',464) ); --error 0,ER_DYN_COL_WRONG_FORMAT -SELECT COLUMN_ADD( dyncol, 7, '22:22:22', 8, REPEAT('x',270) AS CHAR ) FROM t1; +SELECT COLUMN_ADD( dyncol, 7, '22:22:22', 8, REPEAT('x',270) AS CHAR ) as ex FROM t1; delete from t1; INSERT INTO t1 SET dyncol = COLUMN_CREATE( 'a', REPEAT('k',487), 'b', REPEAT('x',464) ); --error 0,ER_DYN_COL_WRONG_FORMAT -SELECT COLUMN_ADD( dyncol, 'a', '22:22:22', 'c', REPEAT('x',270) AS CHAR ) FROM t1; +SELECT COLUMN_ADD( dyncol, 'a', '22:22:22', 'c', REPEAT('x',270) AS CHAR ) as ex FROM t1; DROP table t1; @@ -658,7 +656,7 @@ SELECT # MySQL Bug#16997513 MY_STRTOLL10 ACCEPTING OVERFLOWED UNSIGNED LONG LONG VALUES AS NORMAL ONES # (incorrect overflow check in my_strtoll10()) # -select column_get(column_create(1, "18446744073709552001" as char), 1 as int); +select column_get(column_create(1, "18446744073709552001" as char), 1 as int) as ex; --echo # --echo # MDEV-7505 - Too large scale in DECIMAL dynamic column getter crashes @@ -672,71 +670,77 @@ SELECT COLUMN_GET(`x`, 'y' AS DECIMAL(5,50)); --echo # --echo # creation test (names) set names utf8; +--disable_service_connection select hex(column_create("адын", 1212)); +--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)); +--disable_service_connection select hex(column_create("1212", 2, "адын", 1, 3, 3)); +--enable_service_connection set names latin1; --echo # fetching column test (names) set names utf8; -select column_get(column_create("адын", 1212), "адын" as int); -select column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int); -select column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int); -select column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int); -select column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int); -select column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int); -select column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int); +select column_get(column_create("адын", 1212), "адын" as int) as ex; +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int) as ex; +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int) as ex; +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int) as ex; +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int) as ex; +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int) as ex; +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int) as ex; set names latin1; --echo # column existence test (names) set names utf8; -select column_exists(column_create("адын", 1212), "адын"); -select column_exists(column_create("адын", 1212), "aады"); -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын"); -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212); -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3"); -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3); -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4); -select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4"); +select column_exists(column_create("адын", 1212), "адын") as ex; +select column_exists(column_create("адын", 1212), "aады") as ex; +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын") as ex; +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212) as ex; +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3") as ex; +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3) as ex; +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4) as ex; +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4") as ex; set names latin1; --echo # column changing test (names) -select hex(column_add(column_create(1, "AAA"), "b", "BBB")); -select hex(column_add(column_create("1", "AAA"), "b", "BBB")); -select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char); -select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char); -select hex(column_add(column_create("a", "AAA"), 1, "BBB")); -select hex(column_add(column_create("a", "AAA"), "1", "BBB")); -select hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)); -select hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)); -select hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)); -select hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)); -select hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)); -select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer); -select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer); -select hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)); -select hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)); -select hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)); -select hex(column_add(column_create("a", 1), "a", null)); -select column_list(column_add(column_create("a", 1), "a", null)); -select column_list(column_add(column_create("a", 1), "a", "")); -select hex(column_add("", "a", 1)); +--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_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; +select hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)) as ex; +select hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)) as ex; +select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer) as ex; +select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer) as ex; +select hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)) as ex; +select hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)) as ex; +select hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)) as ex; +select hex(column_add(column_create("a", 1), "a", null)) as ex; +select column_list(column_add(column_create("a", 1), "a", null)) as ex; +select column_list(column_add(column_create("a", 1), "a", "")) as ex; +select hex(column_add("", "a", 1)) as ex; -- echo # column delete (names) -select hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")); -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")); -select hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)); -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")); -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")); -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")); -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")); -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")); -select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e")); -select hex(column_delete(column_create("a", 1), "a")); -select hex(column_delete("", "a")); +select hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")) as ex; +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")) as ex; +select hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)) as ex; +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")) as ex; +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")) as ex; +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")) as ex; +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")) as ex; +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")) as ex; +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e")) as ex; +select hex(column_delete(column_create("a", 1), "a")) as ex; +select hex(column_delete("", "a")) as ex; --echo # --echo # MDEV-458 DNAMES: Server crashes on using an unquoted string @@ -765,12 +769,12 @@ drop table t1; --echo # --echo # MDEV-490/MDEV-491 null as arguments --echo # -SELECT COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR ); -SELECT COLUMN_GET( NULL, 'col' as char ); -SELECT COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL); -SELECT COLUMN_EXISTS( NULL, 'col'); -SELECT COLUMN_CREATE( NULL, 'val' ); -SELECT COLUMN_ADD( NULL, 'val', 'col'); +SELECT COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR ) as ex; +SELECT COLUMN_GET( NULL, 'col' as char ) as ex; +SELECT COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL) as ex; +SELECT COLUMN_EXISTS( NULL, 'col') as ex; +SELECT COLUMN_CREATE( NULL, 'val' ) as ex; +SELECT COLUMN_ADD( NULL, 'val', 'col') as ex; --echo # --echo # MDEV-488: Assertion `column_name->length < 255' failed on a @@ -783,8 +787,8 @@ SELECT hex(COLUMN_CREATE(REPEAT('a',65536),1)); --echo # --echo # JSON conversion --echo # -select column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" AS datetime, "date", "2011-04-05" AS date)); -select column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)); +select column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" AS datetime, "date", "2011-04-05" AS date)) as ex; +select column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)) as ex; --echo # --echo # CHECK test @@ -802,8 +806,8 @@ select column_json(column_create("string", "'\"/\\`.,whatever")),hex(column_crea --echo # --echo # embedding test --echo # -select column_json(column_create("val", "val", "emb", column_create("val2", "val2"))); -select column_json(column_create(1, "val", 2, column_create(3, "val2"))); +select column_json(column_create("val", "val", "emb", column_create("val2", "val2"))) as ex; +select column_json(column_create(1, "val", 2, column_create(3, "val2"))) as ex; --echo # --echo # Time encoding @@ -845,7 +849,7 @@ DROP TABLE t1; --echo # create table t1 (dyn blob); insert into t1 values (column_create('name1','value1','name2','value2')); -select group_concat(cast(column_json(dyn) as char)) from t1; +select group_concat(cast(column_json(dyn) as char)) as ex from t1; drop table t1; @@ -895,15 +899,15 @@ SELECT COLUMN_JSON( 'one', 123.456, 'two', 123.456 as DOUBLE ) -); +) as ex; --echo # --echo # MDEV-8521: Drastic loss of precision in COLUMN_JSON() on DOUBLEs --echo # -select column_get(column_create('float', 1.23456789012345E+100 as double), 'float' as double); -select column_json(column_create('float', 1.23456789012345E+100 as double)); -select column_json(column_create('float', 1.23456789012345E+10 as double)); +select column_get(column_create('float', 1.23456789012345E+100 as double), 'float' as double) as ex; +select column_json(column_create('float', 1.23456789012345E+100 as double)) as ex; +select column_json(column_create('float', 1.23456789012345E+10 as double)) as ex; --echo # --echo # MDEV-9147: Character set is ignored in Dynamic Column for saved string @@ -916,13 +920,13 @@ SELECT COLUMN_GET(COLUMN_CREATE(1, 0xC2A2 AS CHAR CHARACTER SET utf8), 1 AS CHAR --echo # MDEV-9167: COLUMN_CHECK fails on valid decimal data --echo # -SELECT COLUMN_CHECK(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)); +SELECT COLUMN_CHECK(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)) as ex; -SELECT COLUMN_CHECK(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)); +SELECT COLUMN_CHECK(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)) as ex; -SELECT COLUMN_JSON(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)); +SELECT COLUMN_JSON(COLUMN_CREATE('a',0 AS DECIMAL,'b',1 AS DECIMAL)) as ex; -SELECT COLUMN_JSON(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)); +SELECT COLUMN_JSON(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)) as ex; --echo # @@ -986,3 +990,13 @@ DROP TABLE t1; --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # MDEV-32140: Valgrind/MSAN warnings in dynamic_column_update_move_left +--echo # +SELECT COLUMN_GET(COLUMN_ADD(COLUMN_CREATE(1,10),2,NULL,1,NULL),3 AS INTEGER) as ex; +SELECT HEX(COLUMN_ADD(COLUMN_CREATE(1,10),2,NULL,1,NULL)) as ex; + +--echo # +--echo # End of 10.4 tests +--echo # 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/execution_constants.test b/mysql-test/main/execution_constants.test index 285197cd1f4..49b1da8f8e9 100644 --- a/mysql-test/main/execution_constants.test +++ b/mysql-test/main/execution_constants.test @@ -1,5 +1,6 @@ # In embedded server we don't really have a control over stack usage -- source include/not_embedded.inc +-- source include/not_asan.inc # # Bug#21476: Lost Database Connection During Query diff --git a/mysql-test/main/fulltext.result b/mysql-test/main/fulltext.result index 3a338fdc847..4c879c01cc4 100644 --- a/mysql-test/main/fulltext.result +++ b/mysql-test/main/fulltext.result @@ -750,8 +750,9 @@ DROP TABLE t1; # CREATE TABLE t1 (f VARCHAR(8)); INSERT INTO t1 VALUES ('foo'),('bar'); -SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) ); -'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) ) +SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN +BOOLEAN MODE ) ) as exp; +exp 1 SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE )) as f1, MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) as f2 from t1 ; f1 f2 diff --git a/mysql-test/main/fulltext.test b/mysql-test/main/fulltext.test index ef690be2314..acc016b082e 100644 --- a/mysql-test/main/fulltext.test +++ b/mysql-test/main/fulltext.test @@ -697,11 +697,10 @@ DROP TABLE t1; CREATE TABLE t1 (f VARCHAR(8)); INSERT INTO t1 VALUES ('foo'),('bar'); -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) ); ---enable_view_protocol +SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN +BOOLEAN MODE ) ) as exp; SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE )) as f1, MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) as f2 from t1 ; + explain extended SELECT 'foo' IN ( SELECT f FROM t1 GROUP BY MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE )) as f1, MATCH(f) AGAINST ( 'qux' IN BOOLEAN MODE ) as f2 from t1 ; diff --git a/mysql-test/main/func_concat.result b/mysql-test/main/func_concat.result index acde1be051b..4303c97d35c 100644 --- a/mysql-test/main/func_concat.result +++ b/mysql-test/main/func_concat.result @@ -70,10 +70,9 @@ a a a0.0000 select concat((select x from (select 'a' as x) as t1 ), -(select y from (select 'b' as y) as t2 )) from (select 1 union select 2 ) +(select y from (select 'b' as y) as t2 )) as exp from (select 1 union select 2 ) as t3; -concat((select x from (select 'a' as x) as t1 ), -(select y from (select 'b' as y) as t2 )) +exp ab ab create table t1(f1 varchar(6)) charset=utf8; diff --git a/mysql-test/main/func_concat.test b/mysql-test/main/func_concat.test index 070d341cb2d..44dea7e35b1 100644 --- a/mysql-test/main/func_concat.test +++ b/mysql-test/main/func_concat.test @@ -57,15 +57,10 @@ select 'a' union select concat('a', -0.0000); # Bug#16716: subselect in concat() may lead to a wrong result # -#enable after fix MDEV-27871 ---disable_view_protocol - select concat((select x from (select 'a' as x) as t1 ), - (select y from (select 'b' as y) as t2 )) from (select 1 union select 2 ) + (select y from (select 'b' as y) as t2 )) as exp from (select 1 union select 2 ) as t3; ---enable_view_protocol - # End of 4.1 tests # diff --git a/mysql-test/main/func_debug.result b/mysql-test/main/func_debug.result index 37f2a19fc6c..a8a00a567cc 100644 --- a/mysql-test/main/func_debug.result +++ b/mysql-test/main/func_debug.result @@ -113,29 +113,29 @@ Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (longblob) Note 1105 DBUG: [1] arg=2 handler=0 (longblob) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30'); -TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30') +SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30') as exp; +exp 1 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL); -TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL) +SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL) as exp; +exp 1 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30'); -TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30') +SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30') as exp; +exp 0 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL); -TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL) +SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL) as exp; +exp 0 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) @@ -351,8 +351,8 @@ Note 1105 DBUG: [2] arg=3 handler=0 (longblob) Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a DATE); -SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1; -a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) +SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (date) Note 1105 DBUG: [1] arg=2 handler=0 (date) @@ -360,8 +360,8 @@ Note 1105 DBUG: [2] arg=3 handler=0 (date) Note 1105 DBUG: [3] arg=4 handler=0 (date) Note 1105 DBUG: [4] arg=5 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1; -a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) +SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (date) Note 1105 DBUG: [1] arg=2 handler=0 (date) @@ -369,8 +369,8 @@ Note 1105 DBUG: [2] arg=3 handler=0 (date) Note 1105 DBUG: [3] arg=4 handler=0 (date) Note 1105 DBUG: [4] arg=5 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1; -a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) +SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (date) Note 1105 DBUG: [1] arg=2 handler=0 (date) @@ -378,8 +378,8 @@ Note 1105 DBUG: [2] arg=3 handler=0 (date) Note 1105 DBUG: [3] arg=4 handler=0 (date) Note 1105 DBUG: [4] arg=5 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1; -a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) +SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (date) Note 1105 DBUG: [1] arg=2 handler=0 (date) @@ -389,8 +389,8 @@ Note 1105 DBUG: [4] arg=5 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a TIME); -SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) FROM t1; -a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) +SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) @@ -398,8 +398,8 @@ Note 1105 DBUG: [2] arg=3 handler=0 (time) Note 1105 DBUG: [3] arg=4 handler=0 (time) Note 1105 DBUG: [4] arg=5 handler=0 (time) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) FROM t1; -a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) +SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) @@ -407,8 +407,8 @@ Note 1105 DBUG: [2] arg=3 handler=0 (time) Note 1105 DBUG: [3] arg=4 handler=0 (time) Note 1105 DBUG: [4] arg=5 handler=0 (time) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) FROM t1; -a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) +SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) @@ -416,8 +416,8 @@ Note 1105 DBUG: [2] arg=3 handler=0 (time) Note 1105 DBUG: [3] arg=4 handler=0 (time) Note 1105 DBUG: [4] arg=5 handler=0 (time) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) FROM t1; -a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) +SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) @@ -427,8 +427,8 @@ Note 1105 DBUG: [4] arg=5 handler=0 (time) Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a DATETIME); -SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) FROM t1; -a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) +SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) @@ -438,8 +438,8 @@ Note 1105 DBUG: [4] arg=5 handler=0 (datetime) Note 1105 DBUG: [5] arg=6 handler=0 (datetime) Note 1105 DBUG: [6] arg=7 handler=0 (datetime) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) FROM t1; -a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) +SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) @@ -449,8 +449,8 @@ Note 1105 DBUG: [4] arg=5 handler=0 (datetime) Note 1105 DBUG: [5] arg=6 handler=0 (datetime) Note 1105 DBUG: [6] arg=7 handler=0 (datetime) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) FROM t1; -a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) +SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) @@ -460,8 +460,8 @@ Note 1105 DBUG: [4] arg=5 handler=0 (datetime) Note 1105 DBUG: [5] arg=6 handler=0 (datetime) Note 1105 DBUG: [6] arg=7 handler=0 (datetime) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) FROM t1; -a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) +SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) @@ -659,26 +659,26 @@ Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a DATETIME); -SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30') FROM t1; -TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30') +SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30') as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) Note 1105 DBUG: types_compatible=yes bisect=no -SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) FROM t1; -TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) +SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) Note 1105 DBUG: types_compatible=yes bisect=no -SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30') FROM t1; -TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30') +SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30') as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) Note 1105 DBUG: types_compatible=yes bisect=no -SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) FROM t1; -TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) +SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (datetime) Note 1105 DBUG: [1] arg=2 handler=0 (datetime) @@ -797,38 +797,38 @@ Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (longblob) Note 1105 DBUG: [1] arg=2 handler=1 (decimal) Note 1105 DBUG: types_compatible=no bisect=no -SELECT TIME'10:20:30' IN (1,TIME'10:20:30'); -TIME'10:20:30' IN (1,TIME'10:20:30') +SELECT TIME'10:20:30' IN (1,TIME'10:20:30') as exp; +exp 1 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT TIME'10:20:30' IN (1,TIME'10:20:30',NULL); -TIME'10:20:30' IN (1,TIME'10:20:30',NULL) +SELECT TIME'10:20:30' IN (1,TIME'10:20:30',NULL) as exp; +exp 1 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); -TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp; +exp 1 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=2 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); -TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp; +exp 1 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=2 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); -TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp; +exp 1 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) @@ -836,8 +836,8 @@ Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=0 (time) Note 1105 DBUG: [3] arg=4 handler=3 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); -TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp; +exp 1 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) @@ -845,38 +845,38 @@ Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=0 (time) Note 1105 DBUG: [3] arg=4 handler=3 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30'); -TIME'10:20:30' NOT IN (1,TIME'10:20:30') +SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30') as exp; +exp 0 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30',NULL); -TIME'10:20:30' NOT IN (1,TIME'10:20:30',NULL) +SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30',NULL) as exp; +exp 0 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); -TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp; +exp 0 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=2 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); -TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp; +exp 0 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=2 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); -TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp; +exp 0 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) @@ -884,8 +884,8 @@ Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=0 (time) Note 1105 DBUG: [3] arg=4 handler=3 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); -TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp; +exp 0 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) @@ -907,28 +907,28 @@ Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (bigint) Note 1105 DBUG: [1] arg=2 handler=1 (double) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; -a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) +SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (bigint) Note 1105 DBUG: [1] arg=2 handler=1 (decimal) Note 1105 DBUG: found a mix of UINT and SINT Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; -a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) +SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (bigint) Note 1105 DBUG: [1] arg=2 handler=1 (decimal) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; -a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) +SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (decimal) Note 1105 DBUG: [1] arg=2 handler=1 (bigint) Note 1105 DBUG: [2] arg=3 handler=0 (decimal) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; -a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) +SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (decimal) Note 1105 DBUG: [1] arg=2 handler=1 (bigint) @@ -946,28 +946,28 @@ Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (bigint) Note 1105 DBUG: [1] arg=2 handler=1 (double) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; -a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) +SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (bigint) Note 1105 DBUG: [1] arg=2 handler=1 (decimal) Note 1105 DBUG: found a mix of UINT and SINT Note 1105 DBUG: types_compatible=yes bisect=yes -SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; -a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) +SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (bigint) Note 1105 DBUG: [1] arg=2 handler=1 (decimal) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; -a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) +SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (decimal) Note 1105 DBUG: [1] arg=2 handler=1 (bigint) Note 1105 DBUG: [2] arg=3 handler=0 (decimal) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; -a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) +SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (decimal) Note 1105 DBUG: [1] arg=2 handler=1 (bigint) @@ -1221,60 +1221,60 @@ Note 1105 DBUG: [1] arg=2 handler=1 (time) Note 1105 DBUG: types_compatible=no bisect=no DROP TABLE t1; CREATE TABLE t1 (a TIME); -SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; -a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=2 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; -a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=2 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; -a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=0 (time) Note 1105 DBUG: [3] arg=4 handler=3 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; -a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=0 (time) Note 1105 DBUG: [3] arg=4 handler=3 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; -a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=2 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; -a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=2 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; -a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) Note 1105 DBUG: [2] arg=3 handler=0 (time) Note 1105 DBUG: [3] arg=4 handler=3 (datetime) Note 1105 DBUG: types_compatible=no bisect=no -SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; -a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp FROM t1; +exp Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) Note 1105 DBUG: [1] arg=2 handler=0 (time) @@ -1513,8 +1513,8 @@ DROP TABLE t1; # # MDEV-11514 IN with a mixture of TIME and DATETIME returns a wrong result # -SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); -TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') as exp; +exp 1 Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (time) diff --git a/mysql-test/main/func_debug.test b/mysql-test/main/func_debug.test index 1fbc652bb48..b65676dec97 100644 --- a/mysql-test/main/func_debug.test +++ b/mysql-test/main/func_debug.test @@ -24,15 +24,10 @@ SELECT 'a' IN ('a','b',NULL); SELECT 'a' NOT IN ('a','b'); SELECT 'a' NOT IN ('a','b',NULL); -#enable after fix MDEV-27871 ---disable_view_protocol - -SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30'); -SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL); -SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30'); -SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL); - ---enable_view_protocol +SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30') as exp; +SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL) as exp; +SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30') as exp; +SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL) as exp; SELECT TIME'10:20:30' IN ('10:20:30','10:20:30'); SELECT TIME'10:20:30' IN ('10:20:30','10:20:30',NULL); @@ -86,32 +81,27 @@ SELECT a NOT IN ('a','b','c') FROM t1; SELECT a NOT IN ('a','b','c',NULL) FROM t1; DROP TABLE t1; -#enable after fix MDEV-27871 ---disable_view_protocol - CREATE TABLE t1 (a DATE); -SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1; -SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1; -SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1; -SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1; +SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) as exp FROM t1; +SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) as exp FROM t1; +SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) as exp FROM t1; +SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) as exp FROM t1; DROP TABLE t1; CREATE TABLE t1 (a TIME); -SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) FROM t1; -SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) FROM t1; -SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) FROM t1; -SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) FROM t1; +SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) as exp FROM t1; +SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) as exp FROM t1; +SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) as exp FROM t1; +SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) as exp FROM t1; DROP TABLE t1; CREATE TABLE t1 (a DATETIME); -SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) FROM t1; -SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) FROM t1; -SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) FROM t1; -SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) FROM t1; +SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) as exp FROM t1; +SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) as exp FROM t1; +SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) as exp FROM t1; +SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) as exp FROM t1; DROP TABLE t1; ---enable_view_protocol - --echo # Constant predicant, compatible types, no bisect --echo # Bisect is not used because of non-constant expressions in the list CREATE TABLE t1 (a INT); @@ -156,18 +146,13 @@ SELECT TIME'10:20:30' NOT IN (a,'10:20:30') FROM t1; SELECT TIME'10:20:30' NOT IN (a,'10:20:30',NULL) FROM t1; DROP TABLE t1; -#enable after fix MDEV-27871 ---disable_view_protocol - CREATE TABLE t1 (a DATETIME); -SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30') FROM t1; -SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) FROM t1; -SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30') FROM t1; -SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) FROM t1; +SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30') as exp FROM t1; +SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) as exp FROM t1; +SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30') as exp FROM t1; +SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) as exp FROM t1; DROP TABLE t1; ---enable_view_protocol - --echo # Constant predicant, incompatible types, no bisect SELECT 1 IN (1,2e0); SELECT 1 IN (1,2e0,NULL); @@ -189,38 +174,33 @@ SELECT 'a' IN ('a',2,NULL); SELECT 'a' NOT IN ('a',2); SELECT 'a' NOT IN ('a',2,NULL); -#enable after fix MDEV-27871 ---disable_view_protocol - -SELECT TIME'10:20:30' IN (1,TIME'10:20:30'); -SELECT TIME'10:20:30' IN (1,TIME'10:20:30',NULL); -SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); -SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); -SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); -SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); -SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30'); -SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30',NULL); -SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); -SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); -SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); -SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); +SELECT TIME'10:20:30' IN (1,TIME'10:20:30') as exp; +SELECT TIME'10:20:30' IN (1,TIME'10:20:30',NULL) as exp; +SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp; +SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp; +SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp; +SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp; +SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30') as exp; +SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30',NULL) as exp; +SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp; +SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp; +SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp; +SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp; --echo # Column predicant, incompatible types, no bisect CREATE TABLE t1 (a INT); SELECT a IN (1,1e0) FROM t1; SELECT a IN (1,1e0,NULL) FROM t1; -SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; -SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; -SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; -SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; +SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) as exp FROM t1; +SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) as exp FROM t1; +SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) as exp FROM t1; +SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) as exp FROM t1; SELECT a NOT IN (1,1e0) FROM t1; SELECT a NOT IN (1,1e0,NULL) FROM t1; -SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; -SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; -SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; -SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; - ---enable_view_protocol +SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) as exp FROM t1; +SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) as exp FROM t1; +SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) as exp FROM t1; +SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) as exp FROM t1; SELECT a IN (1,1.0) FROM t1; SELECT a IN (1,1.0,NULL) FROM t1; @@ -279,22 +259,17 @@ SELECT a NOT IN ('a',1) FROM t1; SELECT a NOT IN ('a',TIME'10:20:30') FROM t1; DROP TABLE t1; -#enable after fix MDEV-27871 ---disable_view_protocol - CREATE TABLE t1 (a TIME); -SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; -SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; -SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; -SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; -SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; -SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; -SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; -SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; +SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp FROM t1; +SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp FROM t1; +SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp FROM t1; +SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp FROM t1; +SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp FROM t1; +SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp FROM t1; +SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') as exp FROM t1; +SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) as exp FROM t1; DROP TABLE t1; ---enable_view_protocol - # # ROW tests # @@ -437,12 +412,8 @@ DROP TABLE t1; --echo # --echo # MDEV-11514 IN with a mixture of TIME and DATETIME returns a wrong result --echo # -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); - ---enable_view_protocol +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') as exp; PREPARE stmt FROM "SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32')"; diff --git a/mysql-test/main/func_hybrid_type.result b/mysql-test/main/func_hybrid_type.result index 1c40d50b2e7..a1adde0b993 100644 --- a/mysql-test/main/func_hybrid_type.result +++ b/mysql-test/main/func_hybrid_type.result @@ -3419,8 +3419,8 @@ DROP TABLE t1; # # MDEV-9653 Assertion `length || !scale' failed in uint my_decimal_length_to_precision(uint, uint, bool) # -SELECT CASE 0 WHEN 1 THEN (CASE 2 WHEN 3 THEN NULL END) WHEN 4 THEN 5 END; -CASE 0 WHEN 1 THEN (CASE 2 WHEN 3 THEN NULL END) WHEN 4 THEN 5 END +SELECT CASE 0 WHEN 1 THEN (CASE 2 WHEN 3 THEN NULL END) WHEN 4 THEN 5 END as exp; +exp NULL SELECT CASE 0 WHEN 1 THEN (COALESCE(NULL)) WHEN 4 THEN 5 END; CASE 0 WHEN 1 THEN (COALESCE(NULL)) WHEN 4 THEN 5 END diff --git a/mysql-test/main/func_hybrid_type.test b/mysql-test/main/func_hybrid_type.test index 1b903f78b3f..508cdcfb668 100644 --- a/mysql-test/main/func_hybrid_type.test +++ b/mysql-test/main/func_hybrid_type.test @@ -470,10 +470,7 @@ DROP TABLE t1; --echo # --echo # MDEV-9653 Assertion `length || !scale' failed in uint my_decimal_length_to_precision(uint, uint, bool) --echo # -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT CASE 0 WHEN 1 THEN (CASE 2 WHEN 3 THEN NULL END) WHEN 4 THEN 5 END; ---enable_view_protocol +SELECT CASE 0 WHEN 1 THEN (CASE 2 WHEN 3 THEN NULL END) WHEN 4 THEN 5 END as exp; SELECT CASE 0 WHEN 1 THEN (COALESCE(NULL)) WHEN 4 THEN 5 END; SELECT CASE WHEN TRUE THEN COALESCE(NULL) ELSE 4 END; diff --git a/mysql-test/main/func_if.result b/mysql-test/main/func_if.result index 6a8e578767e..069d9bf2e3c 100644 --- a/mysql-test/main/func_if.result +++ b/mysql-test/main/func_if.result @@ -162,19 +162,9 @@ IF((ROUND(t1.a,2)=1), 2, IF((ROUND(t1.a,2)=1), 2, IF((ROUND(t1.a,2)=1), 2, IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2,0)))))))))))))))))))))))))))))) + 1 +IF((ROUND(t1.a,2)=1), 2,0)))))))))))))))))))))))))))))) + 1 as exp FROM t1; -a IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2, -IF((ROUND(t1.a,2)=1), 2, -IF((R +a exp DROP TABLE t1; CREATE TABLE t1 (c LONGTEXT); INSERT INTO t1 VALUES(1), (2), (3), (4), ('1234567890123456789'); diff --git a/mysql-test/main/func_if.test b/mysql-test/main/func_if.test index d18bdc3070e..35bf5bde529 100644 --- a/mysql-test/main/func_if.test +++ b/mysql-test/main/func_if.test @@ -119,8 +119,6 @@ select if(0, 18446744073709551610, 18446744073709551610); CREATE TABLE t1(a DECIMAL(10,3)); -#enable after fix MDEV-27871 ---disable_view_protocol # check : should be fast. more than few secs means failure. SELECT t1.a, IF((ROUND(t1.a,2)=1), 2, @@ -152,9 +150,8 @@ SELECT t1.a, IF((ROUND(t1.a,2)=1), 2, IF((ROUND(t1.a,2)=1), 2, IF((ROUND(t1.a,2)=1), 2, - IF((ROUND(t1.a,2)=1), 2,0)))))))))))))))))))))))))))))) + 1 + IF((ROUND(t1.a,2)=1), 2,0)))))))))))))))))))))))))))))) + 1 as exp FROM t1; ---enable_view_protocol DROP TABLE t1; # diff --git a/mysql-test/main/func_in.result b/mysql-test/main/func_in.result index 4627208d79f..b3865babca2 100644 --- a/mysql-test/main/func_in.result +++ b/mysql-test/main/func_in.result @@ -531,6 +531,8 @@ Warning 1292 Truncated incorrect DECIMAL value: 'b' explain select f1 from t1 where f1 in (2,1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index t1f1_idx t1f1_idx 2 NULL 3 Using where; Using index +Warnings: +Note 1105 Cannot use key `t1f1_idx` part[0] for lookup: `test`.`t1`.`f1` of type `char` = "2" of type `int` create table t2(f2 int, index t2f2(f2)); insert into t2 values(0),(1),(2); select f2 from t2 where f2 in ('a',2); diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index ab35822a6ce..9f032171169 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -28,8 +28,8 @@ NULL select json_value('{"key1": [1,2,3], "key1":123}', '$.key1'); json_value('{"key1": [1,2,3], "key1":123}', '$.key1') 123 -select JSON_VALUE('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z'); -JSON_VALUE('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z') +select JSON_VALUE('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z') as exp; +exp Mon"t"y select json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key2'); json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key2') @@ -43,8 +43,8 @@ NULL select json_query('{"key1":123, "key1": [1,2,3]}', '$.key1'); json_query('{"key1":123, "key1": [1,2,3]}', '$.key1') [1,2,3] -select json_query('{"key1":123, "key1": [1,2,3]}', concat('$', repeat('.k', 1000))); -json_query('{"key1":123, "key1": [1,2,3]}', concat('$', repeat('.k', 1000))) +select json_query('{"key1":123, "key1": [1,2,3]}', concat('$', repeat('.k', 1000))) as exp; +exp NULL select json_array(); json_array() @@ -76,14 +76,14 @@ json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[3]', 'x') select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[4]', 'x'); json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[4]', 'x') ["a", {"b": [1, 2]}, [3, 4], "x"] -select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[1].b[0]', 'x'); -json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[1].b[0]', 'x') +select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[1].b[0]', 'x') as exp; +exp ["a", {"b": ["x", 1, 2]}, [3, 4]] select json_array_insert('true', '$', 1); json_array_insert('true', '$', 1) NULL -select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[2][1]', 'y'); -json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[2][1]', 'y') +select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[2][1]', 'y') as exp; +exp ["a", {"b": [1, 2]}, [3, "y", 4]] select json_contains('{"k1":123, "k2":345}', '123', '$.k1'); json_contains('{"k1":123, "k2":345}', '123', '$.k1') @@ -152,98 +152,98 @@ json_contains('[1, {"a":1}]', '{"a":1}') select json_contains('[{"abc":"def", "def":"abc"}]', '["foo","bar"]'); json_contains('[{"abc":"def", "def":"abc"}]', '["foo","bar"]') 0 -select json_contains('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]'); -json_contains('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]') +select json_contains('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]') as exp; +exp 1 select json_contains('[{"a":"b"},{"c":"d"}]','{"c":"d"}'); json_contains('[{"a":"b"},{"c":"d"}]','{"c":"d"}') 1 -select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]"); -json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]") +select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]") as exp; +exp 1 -select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]"); -json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]") +select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]") as exp; +exp 0 -select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.ma"); -json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.ma") +select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.ma") as exp; +exp 0 -select json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1"); -json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1") +select json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1") as exp; +exp 1 -select json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1", "$.ma"); -json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1", "$.ma") +select json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1", "$.ma") as exp; +exp 1 -select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.ma"); -json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.ma") +select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.ma") as exp; +exp 0 -select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2"); -json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2") +select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2") as exp; +exp 1 -select json_contains_path('{ "a": true }', NULL, '$.a' ); -json_contains_path('{ "a": true }', NULL, '$.a' ) +select json_contains_path('{ "a": true }', NULL, '$.a' ) as exp; +exp NULL -select json_contains_path('{ "a": true }', 'all', NULL ); -json_contains_path('{ "a": true }', 'all', NULL ) +select json_contains_path('{ "a": true }', 'all', NULL ) as exp; +exp NULL -select json_contains_path('{"a":{"b":"c"}}', 'one', '$.a.*'); -json_contains_path('{"a":{"b":"c"}}', 'one', '$.a.*') +select json_contains_path('{"a":{"b":"c"}}', 'one', '$.a.*') as exp; +exp 1 -select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1"); -json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1") +select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1") as exp; +exp "asd" -select json_extract('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY"); -json_extract('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY") +select json_extract('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY") as exp; +exp NULL -select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2"); -json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2") +select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2") as exp; +exp ["asd", [2, 3]] -select json_extract('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2"); -json_extract('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2") +select json_extract('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2") as exp; +exp [5, [2, 3]] -select json_extract('{"key0":true, "key1":"qwe"}', "$.key1"); -json_extract('{"key0":true, "key1":"qwe"}', "$.key1") +select json_extract('{"key0":true, "key1":"qwe"}', "$.key1") as exp; +exp "qwe" -select json_extract(json_object('foo', 'foobar'),'$'); -json_extract(json_object('foo', 'foobar'),'$') +select json_extract(json_object('foo', 'foobar'),'$') as exp; +exp {"foo": "foobar"} -select json_extract('[10, 20, [30, 40]]', '$[2][*]'); -json_extract('[10, 20, [30, 40]]', '$[2][*]') +select json_extract('[10, 20, [30, 40]]', '$[2][*]') as exp; +exp [30, 40] -select json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'); -json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]') +select json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]') as exp; +exp [{"a": 3}, 30, 40] -select json_extract('1', '$'); -json_extract('1', '$') +select json_extract('1', '$') as exp; +exp 1 -select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]'); -json_extract('[10, 20, [30, 40], 1, 10]', '$[1]') +select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]') as exp; +exp 20 -select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]'); -json_extract('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]') +select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]') as exp; +exp [20] -select json_extract( '[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a'); -json_extract( '[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a') +select json_extract( '[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a') as exp; +exp [[3, 4]] -select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word'); -json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word') +select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word') as exp; +exp {"a": 1, "b": {"c": 1, "k1": "word"}, "d": [1, 2]} -select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3); -json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3) +select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3) as exp; +exp {"a": 1, "b": {"c": 1}, "d": [1, 2, 3]} -select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2); -json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2) +select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2) as exp; +exp {"a": [1, 2], "b": {"c": 1}, "d": [1, 2]} -select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word'); -json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word') +select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word') as exp; +exp {"a": 1, "b": {"c": 1}, "d": [1, 2]} -select json_set('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]'); -json_set('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') +select json_set('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') as exp; +exp {"a": 10, "b": [2, 3], "c": "[true, false]"} -select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]'); -json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') +select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') as exp; +exp {"a": 10, "b": [2, 3]} -select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.b', '[true, false]'); -json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.b', '[true, false]') +select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.b', '[true, false]') as exp; +exp {"a": 10, "b": "[true, false]"} set @j = '["a", ["b", "c"], "d"]'; select json_remove(@j, '$[0]'); @@ -278,14 +278,14 @@ select * from t1; f {"id": 87, "name": "carrot"} drop table t1; -select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2"); -json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2") +select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2") as ex; +ex 1 -select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[1]"); -json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[1]") +select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[1]") as ex; +ex 1 -select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[10]"); -json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[10]") +select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[10]") as ex; +ex 0 select json_quote('"string"'); json_quote('"string"') @@ -362,43 +362,43 @@ json_keys('foo') NULL Warnings: Warning 4038 Syntax error in JSON text in argument 1 to function 'json_keys' at position 1 -select json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}'); -json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}') +select json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}') as ex; +ex ["a", "b", "c"] -select json_keys('{"c1": "value 1", "c1": "value 2"}'); -json_keys('{"c1": "value 1", "c1": "value 2"}') +select json_keys('{"c1": "value 1", "c1": "value 2"}') as ex; +ex ["c1"] SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]'; -select json_search(@j, 'one', 'abc'); -json_search(@j, 'one', 'abc') +select json_search(@j, 'one', 'abc') as ex; +ex "$[0]" -select json_search(@j, 'all', 'abc'); -json_search(@j, 'all', 'abc') +select json_search(@j, 'all', 'abc') as ex; +ex ["$[0]", "$[2].x"] -select json_search(@j, 'all', 'abc', NULL, '$[2]'); -json_search(@j, 'all', 'abc', NULL, '$[2]') +select json_search(@j, 'all', 'abc', NULL, '$[2]') as ex; +ex "$[2].x" -select json_search(@j, 'all', 'abc', NULL, '$'); -json_search(@j, 'all', 'abc', NULL, '$') +select json_search(@j, 'all', 'abc', NULL, '$') as ex; +ex ["$[0]", "$[2].x"] -select json_search(@j, 'all', '10', NULL, '$'); -json_search(@j, 'all', '10', NULL, '$') +select json_search(@j, 'all', '10', NULL, '$') as ex; +ex "$[1][0].k" -select json_search(@j, 'all', '10', NULL, '$[*]'); -json_search(@j, 'all', '10', NULL, '$[*]') +select json_search(@j, 'all', '10', NULL, '$[*]') as ex; +ex "$[1][0].k" -select json_search(@j, 'all', '10', NULL, '$[*][0].k'); -json_search(@j, 'all', '10', NULL, '$[*][0].k') +select json_search(@j, 'all', '10', NULL, '$[*][0].k') as ex; +ex "$[1][0].k" -select json_search(@j, 'all', '10', NULL, '$**.k'); -json_search(@j, 'all', '10', NULL, '$**.k') +select json_search(@j, 'all', '10', NULL, '$**.k') as ex; +ex "$[1][0].k" create table t1( json_col text ); insert into t1 values ('{ "a": "foobar" }'), ('{ "a": "foobar", "b": "focus", "c": [ "arm", "foot", "shoulder" ] }'); -select json_search( json_col, 'all', 'foot' ) from t1; -json_search( json_col, 'all', 'foot' ) +select json_search( json_col, 'all', 'foot' ) as ex from t1; +ex NULL "$.c[1]" drop table t1; @@ -468,32 +468,32 @@ json CREATE TABLE `json` ( `j` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table json; -select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2]' ); -json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2]' ) +select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2]' ) as ex; +ex 1 -select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' ); -json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' ) +select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' ) as ex; +ex 1 -select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0]' ); -json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0]' ) +select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0]' ) as ex; +ex 1 -select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0][0]' ); -json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0][0]' ) +select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0][0]' ) as ex; +ex 1 -select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2]' ); -json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2]' ) +select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2]' ) as ex; +ex 2 -select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0]' ); -json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0]' ) +select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0]' ) as ex; +ex 2 -select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0]' ); -json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0]' ) +select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0]' ) as ex; +ex 2 -select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0][0]' ); -json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0][0]' ) +select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0][0]' ) as ex; +ex 2 -select json_length( '{"a":{"b":{"d":1}}, "a":{"c":{"d":1, "j":2}}}', '$.a[0][0][0].c' ); -json_length( '{"a":{"b":{"d":1}}, "a":{"c":{"d":1, "j":2}}}', '$.a[0][0][0].c' ) +select json_length( '{"a":{"b":{"d":1}}, "a":{"c":{"d":1, "j":2}}}', '$.a[0][0][0].c' ) as ex; +ex 2 select json_set('1', '$[0]', 100); json_set('1', '$[0]', 100) @@ -516,20 +516,20 @@ json_set('{"a":12}', '$[0][0].a', 100) select json_set('{"a":12}', '$[0][1].a', 100); json_set('{"a":12}', '$[0][1].a', 100) {"a": 12} -select json_value('{"\\"key1":123}', '$."\\"key1"'); -json_value('{"\\"key1":123}', '$."\\"key1"') +select json_value('{"\\"key1":123}', '$."\\"key1"') as ex; +ex 123 -select json_value('{"\\"key1\\"":123}', '$."\\"key1\\""'); -json_value('{"\\"key1\\"":123}', '$."\\"key1\\""') +select json_value('{"\\"key1\\"":123}', '$."\\"key1\\""') as ex; +ex 123 -select json_value('{"key 1":123}', '$."key 1"'); -json_value('{"key 1":123}', '$."key 1"') +select json_value('{"key 1":123}', '$."key 1"') as ex; +ex 123 -select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[2]"); -json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[2]") +select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[2]") as ex; +ex 1 -select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[3]"); -json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[3]") +select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[3]") as ex; +ex 0 select json_extract( '[1]', '$[0][0]' ); json_extract( '[1]', '$[0][0]' ) @@ -579,26 +579,26 @@ json_set('[]', '$[0][0][0]', 100) SELECT JSON_search( '{"": "a"}', "one", 'a'); JSON_search( '{"": "a"}', "one", 'a') "$." -select json_merge('{"a":"b"}', '{"a":"c"}') ; -json_merge('{"a":"b"}', '{"a":"c"}') +select json_merge('{"a":"b"}', '{"a":"c"}') as ex ; +ex {"a": ["b", "c"]} -select json_merge('{"a":{"x":"b"}}', '{"a":"c"}') ; -json_merge('{"a":{"x":"b"}}', '{"a":"c"}') +select json_merge('{"a":{"x":"b"}}', '{"a":"c"}') as ex ; +ex {"a": [{"x": "b"}, "c"]} -select json_merge('{"a":{"u":12, "x":"b"}}', '{"a":{"x":"c"}}') ; -json_merge('{"a":{"u":12, "x":"b"}}', '{"a":{"x":"c"}}') +select json_merge('{"a":{"u":12, "x":"b"}}', '{"a":{"x":"c"}}') as ex ; +ex {"a": {"u": 12, "x": ["b", "c"]}} -select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') ; -json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') +select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') as ex ; +ex {"a": {"u": 12, "x": ["b", "c"], "r": [1, 2]}} -select json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}'); -json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') +select json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') as ex; +ex {"a":1,"b":[1,2,3],"c":{"aa":"v1","bb":"v2"}} -select json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}'); -json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') +select json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') as ex; +ex {"a": 1, "b": [1, 2, 3], "c": {"aa": "v1", "bb": "v2"}} -select json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}'); -json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') +select json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') as ex; +ex { "a": 1, "b": @@ -613,11 +613,11 @@ json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') "bb": "v2" } } -SELECT JSON_search( '{"x": "\\""}', "one", '"'); -JSON_search( '{"x": "\\""}', "one", '"') +SELECT JSON_search( '{"x": "\\""}', "one", '"') as ex; +ex "$.x" -SELECT JSON_search( '{"x": "\\""}', "one", '\\"'); -JSON_search( '{"x": "\\""}', "one", '\\"') +SELECT JSON_search( '{"x": "\\""}', "one", '\\"') as ex; +ex "$.x" set @save_max_allowed_packet=@@max_allowed_packet; set @save_net_buffer_length=@@net_buffer_length; @@ -630,13 +630,13 @@ net_buffer_length 1024 show variables like 'max_allowed_packet'; Variable_name Value max_allowed_packet 2048 -select json_array(repeat('a',1024),repeat('a',1024)); -json_array(repeat('a',1024),repeat('a',1024)) +select json_array(repeat('a',1024),repeat('a',1024)) as ex; +ex NULL Warnings: Warning 1301 Result of json_array() was larger than max_allowed_packet (2048) - truncated -select json_object("a", repeat('a',1024),"b", repeat('a',1024)); -json_object("a", repeat('a',1024),"b", repeat('a',1024)) +select json_object("a", repeat('a',1024),"b", repeat('a',1024)) as ex; +ex NULL Warnings: Warning 1301 Result of json_object() was larger than max_allowed_packet (2048) - truncated @@ -674,31 +674,31 @@ NULL SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*]'); JSON_EXTRACT( '{"foo":"bar"}', '$[*]') NULL -select JSON_EXTRACT('{"name":"value"}', '$.name') = 'value'; -JSON_EXTRACT('{"name":"value"}', '$.name') = 'value' +select JSON_EXTRACT('{"name":"value"}', '$.name') = 'value' as ex; +ex 1 -select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true; -JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true +select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true as ex; +ex 1 -select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false; -JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false +select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false as ex; +ex 0 -select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1; -JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1 +select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1 as ex; +ex 1 -select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"'); -JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"') +select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"') as ex; +ex "\u00f6" -select JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo'); -JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo') +select JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo') as ex; +ex NULL Warnings: Warning 4038 Syntax error in JSON text in argument 1 to function 'json_extract' at position 15 -SELECT JSON_OBJECT('foo', '`'); -JSON_OBJECT('foo', '`') +SELECT JSON_OBJECT('foo', '`') as ex; +ex {"foo": "`"} -SELECT JSON_OBJECT("foo", "bar`bar"); -JSON_OBJECT("foo", "bar`bar") +SELECT JSON_OBJECT("foo", "bar`bar") as ex; +ex {"foo": "bar`bar"} SELECT JSON_SET('{}', '$.age', 87); JSON_SET('{}', '$.age', 87) @@ -776,21 +776,21 @@ insert into t1 values (_latin1 X'7B226B657931223A2253EC227D'); select JSON_VALUE(json_col, '$.key1')= _latin1 X'53EC' from t1; JSON_VALUE(json_col, '$.key1')= _latin1 X'53EC' 1 -select REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' from t1; -REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' +select REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' as exp from t1; +exp 1 drop table t1; # # MDEV-16750 JSON_SET mishandles unicode every second pair of arguments. # -SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6); -JSON_SET('{}', '$.a', _utf8 0xC3B6) +SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6) as exp; +exp {"a": "ö"} -SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6); -JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6) +SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6) as exp; +exp {"a": "ö", "b": "ö"} -SELECT JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6'); -JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6') +SELECT JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6') as exp; +exp {"a": "ö", "x": 1, "b": "ö"} # # MDEV-17121 JSON_ARRAY_APPEND @@ -835,14 +835,14 @@ JSON_VALID( '{"a":1]' ) # # MDEV-18886 JSON_ARRAY() does not recognise JSON argument. # -SELECT JSON_ARRAY(_UTF8 'str', JSON_OBJECT(_LATIN1 'plugin', _LATIN1'unix_socket')); -JSON_ARRAY(_UTF8 'str', JSON_OBJECT(_LATIN1 'plugin', _LATIN1'unix_socket')) +SELECT JSON_ARRAY(_UTF8 'str', JSON_OBJECT(_LATIN1 'plugin', _LATIN1'unix_socket')) as exp; +exp ["str", {"plugin": "unix_socket"}] -SELECT CHARSET(JSON_ARRAY()); -CHARSET(JSON_ARRAY()) +SELECT CHARSET(JSON_ARRAY()) as exp; +exp latin1 -SELECT CHARSET(JSON_OBJECT()); -CHARSET(JSON_OBJECT()) +SELECT CHARSET(JSON_OBJECT()) as exp; +exp latin1 # # MDEV-13992 Implement JSON_MERGE_PATCH @@ -892,31 +892,31 @@ id target patch merged a 16 NULL {} NULL NULL 17 {} NULL NULL NULL DROP TABLE merge_t; -SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '{"c":"d"}'); -JSON_MERGE_PATCH('{"a":"b"}', NULL, '{"c":"d"}') +SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '{"c":"d"}') as exp; +exp NULL -SELECT JSON_MERGE_PATCH(NULL, '[1,2,3]'); -JSON_MERGE_PATCH(NULL, '[1,2,3]') +SELECT JSON_MERGE_PATCH(NULL, '[1,2,3]') as exp; +exp [1, 2, 3] -SELECT JSON_MERGE_PATCH(NULL, 'a'); -JSON_MERGE_PATCH(NULL, 'a') +SELECT JSON_MERGE_PATCH(NULL, 'a') as exp; +exp NULL Warnings: Warning 4038 Syntax error in JSON text in argument 2 to function 'json_merge_patch' at position 1 -SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '[1,2,3]', '{"c":null,"d":"e"}'); -JSON_MERGE_PATCH('{"a":"b"}', NULL, '[1,2,3]', '{"c":null,"d":"e"}') +SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '[1,2,3]', '{"c":null,"d":"e"}') as exp; +exp {"d": "e"} -SELECT JSON_MERGE_PATCH(); +SELECT JSON_MERGE_PATCH() as exp; ERROR 42000: Incorrect parameter count in the call to native function 'JSON_MERGE_PATCH' -SELECT JSON_MERGE_PATCH('{}'); +SELECT JSON_MERGE_PATCH('{}') as exp; ERROR 42000: Incorrect parameter count in the call to native function 'JSON_MERGE_PATCH' -SELECT JSON_MERGE_PATCH('{', '[1,2,3]'); -JSON_MERGE_PATCH('{', '[1,2,3]') +SELECT JSON_MERGE_PATCH('{', '[1,2,3]') as exp; +exp NULL Warnings: Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_merge_patch' -SELECT JSON_MERGE_PATCH('{"a":"b"}', '[1,'); -JSON_MERGE_PATCH('{"a":"b"}', '[1,') +SELECT JSON_MERGE_PATCH('{"a":"b"}', '[1,') as exp; +exp NULL Warnings: Warning 4037 Unexpected end of JSON text in argument 2 to function 'json_merge_patch' @@ -1379,8 +1379,8 @@ insert into t200 values } ] }'); -select JSON_DETAILED(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) from t200; -JSON_DETAILED(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) +select JSON_DETAILED(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; +exp [ { "range_scan_alternatives": @@ -1410,8 +1410,8 @@ JSON_DETAILED(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) ["123"] } ] -select JSON_PRETTY(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) from t200; -JSON_PRETTY(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) +select JSON_PRETTY(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; +exp [ { "range_scan_alternatives": @@ -1441,8 +1441,8 @@ JSON_PRETTY(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) ["123"] } ] -select JSON_LOOSE(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) from t200; -JSON_LOOSE(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) +select JSON_LOOSE(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; +exp [{"range_scan_alternatives": [{"index": "a_b", "ranges": ["2 <= a <= 2 AND 4 <= b <= 4", "123"], "rowid_ordered": true, "using_mrr": false, "index_only": true, "rows": 1, "cost": 1.1752, "chosen": true}], "analyzing_roworder_intersect": {"cause": "too few roworder scans"}, "analyzing_index_merge_union": [], "test_one_line_array": ["123"]}] drop table t200; # @@ -1615,11 +1615,11 @@ DROP TABLE t2; # # MDEV-27018 IF and COALESCE lose "json" property # -SELECT json_object('a', if(1, json_object('b', 'c'), json_object('e', 'f'))); -json_object('a', if(1, json_object('b', 'c'), json_object('e', 'f'))) +SELECT json_object('a', if(1, json_object('b', 'c'), json_object('e', 'f'))) as exp; +exp {"a": {"b": "c"}} -SELECT json_object('a', coalesce(json_object('b', 'c'))); -json_object('a', coalesce(json_object('b', 'c'))) +SELECT json_object('a', coalesce(json_object('b', 'c'))) as exp; +exp {"a": {"b": "c"}} # # MDEV-26392: Crash with json_get_path_next and 10.5.12 @@ -1646,6 +1646,17 @@ SELECT JSON_OBJECTAGG('\\', 1); JSON_OBJECTAGG('\\', 1) {"\\":1} # +# MDEV-24784 JSON_ARRAYAGG charset issue +# +set names utf8; +select json_arrayagg('ä'), json_objectagg(1, 'ä'); +json_arrayagg('ä') json_objectagg(1, 'ä') +["ä"] {"1":"ä"} +set names latin1; +select json_arrayagg('ä'), json_objectagg(1, 'ä'); +json_arrayagg('ä') json_objectagg(1, 'ä') +["ä"] {"1":"ä"} +# # End of 10.5 tests # # @@ -1757,15 +1768,8 @@ SELECT JSON_OVERLAPS('{ '{ "A": 2, "B": "string1" - }'); -JSON_OVERLAPS('{ - "A": 1, - "B": "string1" - }', -'{ - "A": 2, - "B": "string1" - }') + }') as exp; +exp 1 SELECT JSON_OVERLAPS('{ "A": 1, @@ -1774,15 +1778,8 @@ SELECT JSON_OVERLAPS('{ '{ "A": 2, "B": "string2" - }'); -JSON_OVERLAPS('{ - "A": 1, - "B": "string1" - }', -'{ - "A": 2, - "B": "string2" - }') + }') as exp; +exp 0 # Comparing nested object with other nested object SELECT JSON_OVERLAPS('{ @@ -1792,15 +1789,8 @@ SELECT JSON_OVERLAPS('{ '{ "A": 2, "B": {"C":1} - }'); -JSON_OVERLAPS('{ - "A": 1, - "B": {"C":2} - }', -'{ - "A": 2, - "B": {"C":1} - }') + }') as exp; +exp 0 SELECT JSON_OVERLAPS('{ "A": 1, @@ -1809,15 +1799,8 @@ SELECT JSON_OVERLAPS('{ '{ "A": 2, "B": {"C":2} - }'); -JSON_OVERLAPS('{ - "A": 1, - "B": {"C":2} - }', -'{ - "A": 2, - "B": {"C":2} - }') + }') as exp; +exp 1 SELECT JSON_OVERLAPS('{ "A": { @@ -1829,171 +1812,136 @@ SELECT JSON_OVERLAPS('{ "B": true, "C": false } - }'); -JSON_OVERLAPS('{ - "A": { - "B": true - } - }', -'{ - "A": { - "B": true, - "C": false - + }') as exp; +exp 0 SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":5}}', -'{"C":3, "B":{"E":5, "D":4}}'); -JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":5}}', -'{"C":3, "B":{"E":5, "D":4}}') +'{"C":3, "B":{"E":5, "D":4}}') as exp; +exp 1 SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', -'{"C":3, "B":{"E":5, "D":4}}'); -JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', -'{"C":3, "B":{"E":5, "D":4}}') +'{"C":3, "B":{"E":5, "D":4}}') as exp; +exp 0 SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', -'{"C":3, "B":{"E":[5, 6, 7], "D":4}}'); -JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', -'{"C":3, "B":{"E":[5, 6, 7], "D":4}}') +'{"C":3, "B":{"E":[5, 6, 7], "D":4}}') as exp; +exp 1 SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', -'{"C":3, "B":{"E":[7, 6 ,5], "D":4}}'); -JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', -'{"C":3, "B":{"E":[7, 6 ,5], "D":4}}') +'{"C":3, "B":{"E":[7, 6 ,5], "D":4}}') as exp; +exp 0 SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', -'{"C":3, "F":{"E":[5, 6, 7], "D":4}}'); -JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', -'{"C":3, "F":{"E":[5, 6, 7], "D":4}}') +'{"C":3, "F":{"E":[5, 6, 7], "D":4}}') as exp; +exp 0 # Comparing array with array (non-nested) SELECT JSON_OVERLAPS('[1, 2, true, false, null]', -'[3, 4, 1]'); -JSON_OVERLAPS('[1, 2, true, false, null]', -'[3, 4, 1]') +'[3, 4, 1]') as exp; +exp 1 SELECT JSON_OVERLAPS('[1, 2, true, false, null]', '[3, 4, 5]'); JSON_OVERLAPS('[1, 2, true, false, null]', '[3, 4, 5]') 0 -SELECT JSON_OVERLAPS('[1,2,3]','[]'); -JSON_OVERLAPS('[1,2,3]','[]') +SELECT JSON_OVERLAPS('[1,2,3]','[]') as exp; +exp 0 # Comparing nested arrays SELECT JSON_OVERLAPS('[1, 2, true, false, null]', -'[3, 4, [1]]'); -JSON_OVERLAPS('[1, 2, true, false, null]', -'[3, 4, [1]]') +'[3, 4, [1]]') as exp; +exp 0 SELECT JSON_OVERLAPS('[1, 2, [true, false], null]', -'[[1], [true, false]]'); -JSON_OVERLAPS('[1, 2, [true, false], null]', -'[[1], [true, false]]') +'[[1], [true, false]]') as exp; +exp 1 -SELECT JSON_OVERLAPS('[1, 2, 3, [4, 5, 6]]','[7, 8, 9, [6, 5, 4]]'); -JSON_OVERLAPS('[1, 2, 3, [4, 5, 6]]','[7, 8, 9, [6, 5, 4]]') +SELECT JSON_OVERLAPS('[1, 2, 3, [4, 5, 6]]','[7, 8, 9, [6, 5, 4]]') as exp; +exp 0 # Comparing one non-scalar json datatypes with another non-scalar # json datatype # Comparing array with object SELECT JSON_OVERLAPS('[1, 2, true, false, null]', -'{"A": 1}'); -JSON_OVERLAPS('[1, 2, true, false, null]', -'{"A": 1}') +'{"A": 1}') as exp; +exp 0 SELECT JSON_OVERLAPS('[1, 2, true, false, null, {"A":2}]', -'{"A": 1}'); -JSON_OVERLAPS('[1, 2, true, false, null, {"A":2}]', -'{"A": 1}') +'{"A": 1}') as exp; +exp 0 SELECT JSON_OVERLAPS('[1, {"A": 2}, {"A": 1}]', -'{"A": 1}'); -JSON_OVERLAPS('[1, {"A": 2}, {"A": 1}]', -'{"A": 1}') +'{"A": 1}') as exp; +exp 1 SELECT JSON_OVERLAPS('[1, 2, true, false, {"A": 1, "B": 2}]', -'{"A": 1, "B": 2}'); -JSON_OVERLAPS('[1, 2, true, false, {"A": 1, "B": 2}]', -'{"A": 1, "B": 2}') +'{"A": 1, "B": 2}') as exp; +exp 1 SELECT JSON_OVERLAPS('[1, 2, true, false, {"A": 1, "B": 2}]', -'{"A": 1, "B": 3}'); -JSON_OVERLAPS('[1, 2, true, false, {"A": 1, "B": 2}]', -'{"A": 1, "B": 3}') +'{"A": 1, "B": 3}') as exp; +exp 0 # Comparing nested array with object SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": 2}]]', -'{"A": 1, "B": 2}'); -JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": 2}]]', -'{"A": 1, "B": 2}') +'{"A": 1, "B": 2}') as exp; +exp 0 SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": 2}]]', -'{"A": 1, "B": 3}'); -JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": 2}]]', -'{"A": 1, "B": 3}') +'{"A": 1, "B": 3}') as exp; +exp 0 SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": 2}]]', -'{"A": 1}'); -JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": 2}]]', -'{"A": 1}') +'{"A": 1}') as exp; +exp 0 # Comparing array with nested object SELECT JSON_OVERLAPS('[1, 2, true, false, {"A": 1, "B": {"C": 12}}]', -'{"A": 1, "B": {"C": 12}}'); -JSON_OVERLAPS('[1, 2, true, false, {"A": 1, "B": {"C": 12}}]', -'{"A": 1, "B": {"C": 12}}') +'{"A": 1, "B": {"C": 12}}') as exp; +exp 1 SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": {"C": 12}}]]', -'{"A": 1, "B": {"C": 12}}'); -JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": {"C": 12}}]]', -'{"A": 1, "B": {"C": 12}}') +'{"A": 1, "B": {"C": 12}}') as exp; +exp 0 # Comparing nested array with nested objects SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": {"C": 12}}]]', -'{"A": 1, "B":{"C": 12}}'); -JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": {"C": 12}}]]', -'{"A": 1, "B":{"C": 12}}') +'{"A": 1, "B":{"C": 12}}') as exp; +exp 0 SELECT JSON_OVERLAPS('[[1, 2, true, false, {"A": 1, "B": {"C": 12}}]]', -'{"A": 1, "B": {"C": 12}}'); -JSON_OVERLAPS('[[1, 2, true, false, {"A": 1, "B": {"C": 12}}]]', -'{"A": 1, "B": {"C": 12}}') +'{"A": 1, "B": {"C": 12}}') as exp; +exp 0 # Comparing object with array SELECT JSON_OVERLAPS('{"A": 1, "B": 3}', -'[1, 2, true, false, {"A": 1, "B": 2}]'); -JSON_OVERLAPS('{"A": 1, "B": 3}', -'[1, 2, true, false, {"A": 1, "B": 2}]') +'[1, 2, true, false, {"A": 1, "B": 2}]') as exp; +exp 0 SELECT JSON_OVERLAPS('{"A": 1, "B": 3}', -'[1, 2, true, false, {"A": 1, "B": 3}]'); -JSON_OVERLAPS('{"A": 1, "B": 3}', -'[1, 2, true, false, {"A": 1, "B": 3}]') +'[1, 2, true, false, {"A": 1, "B": 3}]') as exp; +exp 1 SELECT JSON_OVERLAPS('{"A": 1, "B": 3}', -'[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": 3}]'); -JSON_OVERLAPS('{"A": 1, "B": 3}', -'[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": 3}]') +'[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": 3}]') as exp; +exp 1 SELECT JSON_OVERLAPS('{"A": 1, "B": [1, 2, 3]}', -'[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": [1, 2, 3]}]'); -JSON_OVERLAPS('{"A": 1, "B": [1, 2, 3]}', -'[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": [1, 2, 3]}]') +'[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": [1, 2, 3]}]') as exp; +exp 1 SELECT JSON_OVERLAPS('{"A": 1, "B": [1, 2, {"C": 3, "D": 5}]}', -'[1, 2, true, false, {"A": 1, "B": 2}, {"A":1, "B":[1, 2, {"C": 3, "D": 5}]}]'); -JSON_OVERLAPS('{"A": 1, "B": [1, 2, {"C": 3, "D": 5}]}', -'[1, 2, true, false, {"A": 1, "B": 2}, {"A":1, "B":[1, 2, {"C": 3, "D": 5}]}]') +'[1, 2, true, false, {"A": 1, "B": 2}, {"A":1, "B":[1, 2, {"C": 3, "D": 5}]}]') as exp; +exp 1 SELECT JSON_OVERLAPS('{"A": 1, "B": [1, 2, {"C": 3, "D": 5}]}', -'[1, 2, true, false, {"A": 1, "B": 2},{"A": 1, "B": [1, 2, {"C": 3, "D": 4}]}]'); -JSON_OVERLAPS('{"A": 1, "B": [1, 2, {"C": 3, "D": 5}]}', -'[1, 2, true, false, {"A": 1, "B": 2},{"A": 1, "B": [1, 2, {"C": 3, "D": 4}]}]') +'[1, 2, true, false, {"A": 1, "B": 2},{"A": 1, "B": [1, 2, {"C": 3, "D": 4}]}]') as exp; +exp 0 # Comparing object with nested array -SELECT JSON_OVERLAPS('{"A": 1, "B": 3}','[1, 2, true, false, [{"A": 1, "B": 2}, {"A": 1, "B": 3}]]'); -JSON_OVERLAPS('{"A": 1, "B": 3}','[1, 2, true, false, [{"A": 1, "B": 2}, {"A": 1, "B": 3}]]') +SELECT JSON_OVERLAPS('{"A": 1, "B": 3}','[1, 2, true, false, [{"A": 1, "B": 2}, {"A": 1, "B": 3}]]') as exp; +exp 0 # Checking errors and warnings SELECT JSON_OVERLAPS('[1,2,{"A":B}]', '{"A":B}', '{"C":"string1"}'); @@ -2608,7 +2556,27 @@ SET @@collation_connection= @save_collation_connection; # # End of 10.9 Test # -# Beginning of 11.1 test +# +# MDEV-32007: JSON_VALUE and JSON_EXTRACT doesn't handle dash (-) +# as first character in key +# +CREATE TEMPORARY TABLE IF NOT EXISTS jsonTest AS +SELECT '{ "-1234" : "something", + "12-34" : "else", + "1234-" : "and", + "1234" : "match" }' AS 'message'; +SELECT JSON_SEARCH(message, 'one', 'something') AS t1_path, +JSON_VALUE(message, JSON_UNQUOTE(JSON_SEARCH(message, 'one', 'something'))) AS t1_result, +JSON_SEARCH(message, 'one', 'else') AS t2_path, +JSON_VALUE(message, JSON_UNQUOTE(JSON_SEARCH(message, 'one', 'else'))) AS t2_result, +JSON_SEARCH(message, 'one', 'and') AS t3_path, +JSON_VALUE(message, JSON_UNQUOTE(JSON_SEARCH(message, 'one', 'and'))) AS t3_result, +JSON_SEARCH(message, 'one', 'match') AS t4_path, +JSON_VALUE(message, JSON_UNQUOTE(JSON_SEARCH(message, 'one', 'match'))) AS t4_result +FROM jsonTest; +t1_path t1_result t2_path t2_result t3_path t3_result t4_path t4_result +"$.-1234" something "$.12-34" else "$.1234-" and "$.1234" match +# End of 11.0 test # # MDEV-27128: Implement JSON Schema Validation FUNCTION # @@ -4762,6 +4730,20 @@ NULL SELECT JSON_SCHEMA_VALID(NULL, NULL); JSON_SCHEMA_VALID(NULL, NULL) NULL +# +# MDEV-31599: Assertion `0' failed in Item_param::can_return_value from Item::val_json, +# UBSAN: member access within null pointer of type 'struct String' in +# sql/item_jsonfunc.cc +# +PREPARE s FROM 'SELECT JSON_SCHEMA_VALID (?,''{}'') FROM DUAL'; +ERROR HY000: Variable schema is not supported. +# +# MDEV-33015: Server crashes upon JSON_SCHEMA_VALID reading NULL from a user variable +# +SET @a= NULL; +SELECT JSON_SCHEMA_VALID(@a,'{}'); +JSON_SCHEMA_VALID(@a,'{}') +NULL # End of 11.1 test # Beginning of 11.2 # @@ -4864,8 +4846,9 @@ FROM JSON_TABLE( JSON_KEY_VALUE('[[1, 2, 3], 2, 3]', '$[0][1]'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; k v id -SELECT JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1]'); -JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1]') +SELECT JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', +'$[0][1]') as exp; +exp [{"key": "key1", "value": "val1"}, {"key": "key2", "value": "val2"}] SELECT jt.* FROM JSON_TABLE( @@ -4874,24 +4857,27 @@ JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1]'), '$[ k v id key1 val1 1 key2 val2 2 -SELECT JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1].key1'); -JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1].key1') +SELECT JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', +'$[0][1].key1') as exp; +exp NULL SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1].key1'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; k v id -SELECT JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', '$[0][1]'); -JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', '$[0][1]') +SELECT JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', +'$[0][1]') as exp; +exp NULL SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', '$[0][1]'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; k v id -SELECT JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', '$[0][1][0]'); -JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', '$[0][1][0]') +SELECT JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', +'$[0][1][0]') as exp; +exp [{"key": "key1", "value": "val1"}, {"key": "key2", "value": "val2"}] SELECT jt.* FROM JSON_TABLE( @@ -4904,8 +4890,8 @@ key2 val2 2 SELECT JSON_KEY_VALUE('{}', '$.key1'); JSON_KEY_VALUE('{}', '$.key1') NULL -SELECT JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$'); -JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$') +SELECT JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$') as exp; +exp [{"key": "key1", "value": "val1"}, {"key": "key2", "value": "val2"}] SELECT jt.* FROM JSON_TABLE( @@ -4914,16 +4900,16 @@ JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$'), '$[*]' k v id key1 val1 1 key2 val2 2 -SELECT JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$.key1'); -JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$.key1') +SELECT JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$.key1') as exp; +exp NULL SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$.key1'), '$[*]' COLUMNS (k VARCHAR(11) PATH '$.key', v VARCHAR(5) PATH '$.value', id FOR ORDINALITY)) AS jt; k v id -SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b":2}, "key2":"val2"}', '$.key1'); -JSON_KEY_VALUE('{"key1":{"a":1, "b":2}, "key2":"val2"}', '$.key1') +SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b":2}, "key2":"val2"}', '$.key1') as exp; +exp [{"key": "a", "value": 1}, {"key": "b", "value": 2}] SELECT jt.* FROM JSON_TABLE( @@ -4932,8 +4918,8 @@ JSON_KEY_VALUE('{"key1":{"a":1, "b":2}, "key2":"val2"}', '$.key1'), '$[*]' k v id a 1 1 b 2 2 -SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[3]'); -JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[3]') +SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[3]') as exp; +exp [{"key": "some_key", "value": "some_val"}, {"key": "c", "value": 3}] SELECT jt.* FROM JSON_TABLE( @@ -4942,8 +4928,8 @@ JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, " k v id some_key some_val 1 c 3 2 -SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[0]'); -JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[0]') +SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[0]') as exp; +exp NULL SELECT jt.* FROM JSON_TABLE( @@ -5126,5 +5112,19 @@ SELECT JSON_OBJECT_TO_ARRAY(@arr1); JSON_OBJECT_TO_ARRAY(@arr1) NULL # +# MDEV-31411: JSON_ARRAY_INTERSECT/JSON_OBJECT_FILTER_KEYS should fetch +# data from a table similar to other JSON functions +# +CREATE TABLE t1 ( +c1 longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(c1)), +c2 longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`c2`)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +INSERT INTO t1 VALUES('[1,2,3]', '[2, 3, 4]'), ('[2 ,3, 4]', '[4, 5, 6]'); +SELECT JSON_ARRAY_INTERSECT(c1, c2) FROM t1; +JSON_ARRAY_INTERSECT(c1, c2) +[2, 3] +[4] +DROP TABLE t1; +# # End of 11.2 Test # diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 494a681243a..f76dd232893 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -1,3 +1,5 @@ +--source include/have_innodb.inc + select json_valid('[1, 2]'); select json_valid('"string"}'); select json_valid('{"key1":1, "key2":[2,3]}'); @@ -10,19 +12,13 @@ select json_value('{"key1":123}', '$.key1'); select json_value('{"key1":[1,2,3]}', '$.key1'); select json_value('{"key1": [1,2,3], "key1":123}', '$.key1'); -#enable after fix MDEV-27871 ---disable_view_protocol -select JSON_VALUE('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z'); ---enable_view_protocol +select JSON_VALUE('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z') as exp; select json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key2'); select json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key1'); select json_query('{"key1": 1}', '$.key1'); select json_query('{"key1":123, "key1": [1,2,3]}', '$.key1'); -#enable after fix MDEV-27871 ---disable_view_protocol -select json_query('{"key1":123, "key1": [1,2,3]}', concat('$', repeat('.k', 1000))); ---enable_view_protocol +select json_query('{"key1":123, "key1": [1,2,3]}', concat('$', repeat('.k', 1000))) as exp; select json_array(); select json_array(1); @@ -39,15 +35,9 @@ select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[1]', 'x'); select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[2]', 'x'); select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[3]', 'x'); select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[4]', 'x'); -#enable after fix MDEV-27871 ---disable_view_protocol -select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[1].b[0]', 'x'); ---enable_view_protocol +select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[1].b[0]', 'x') as exp; select json_array_insert('true', '$', 1); -#enable after fix MDEV-27871 ---disable_view_protocol -select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[2][1]', 'y'); ---enable_view_protocol +select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[2][1]', 'y') as exp; select json_contains('{"k1":123, "k2":345}', '123', '$.k1'); select json_contains('"you"', '"you"'); @@ -72,45 +62,45 @@ select json_contains('{"a":1}', '{}'); select json_contains('[1, {"a":1}]', '{}'); select json_contains('[1, {"a":1}]', '{"a":1}'); select json_contains('[{"abc":"def", "def":"abc"}]', '["foo","bar"]'); -#enable after fix MDEV-27871 ---disable_view_protocol -select json_contains('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]'); ---disable_view_protocol +select json_contains('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]') as exp; select json_contains('[{"a":"b"},{"c":"d"}]','{"c":"d"}'); -select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]"); -select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]"); -select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.ma"); -select json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1"); -select json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1", "$.ma"); -select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.ma"); -select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2"); -select json_contains_path('{ "a": true }', NULL, '$.a' ); -select json_contains_path('{ "a": true }', 'all', NULL ); -select json_contains_path('{"a":{"b":"c"}}', 'one', '$.a.*'); +select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]") as exp; +select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]") as exp; +select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.ma") as exp; +select json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1") as exp; +select json_contains_path('{"key1":1, "key2":[2,3]}', "one", "$.key1", "$.ma") as exp; +select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.ma") as exp; +select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2") as exp; +select json_contains_path('{ "a": true }', NULL, '$.a' ) as exp; +select json_contains_path('{ "a": true }', 'all', NULL ) as exp; +select json_contains_path('{"a":{"b":"c"}}', 'one', '$.a.*') as exp; -select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1"); -select json_extract('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY"); -select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2"); -select json_extract('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2"); -select json_extract('{"key0":true, "key1":"qwe"}', "$.key1"); -select json_extract(json_object('foo', 'foobar'),'$'); -select json_extract('[10, 20, [30, 40]]', '$[2][*]'); -select json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'); -select json_extract('1', '$'); -select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]'); -select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]'); -select json_extract( '[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a'); +select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1") as exp; +select json_extract('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY") as exp; +select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2") as exp; +select json_extract('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2") as exp; +select json_extract('{"key0":true, "key1":"qwe"}', "$.key1") as exp; +select json_extract(json_object('foo', 'foobar'),'$') as exp; +select json_extract('[10, 20, [30, 40]]', '$[2][*]') as exp; +select json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]') as exp; +select json_extract('1', '$') as exp; +select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]') as exp; +select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]') as exp; +select json_extract( '[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a') as exp; -select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word'); -select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3); -select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2); -select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word'); +#enable after MDEV-32454 fix +--disable_view_protocol +select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word') as exp; +select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3) as exp; +select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2) as exp; +select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word') as exp; -select json_set('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]'); +select json_set('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') as exp; +--enable_view_protocol -select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]'); -select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.b', '[true, false]'); +select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') as exp; +select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.b', '[true, false]') as exp; set @j = '["a", ["b", "c"], "d"]'; select json_remove(@j, '$[0]'); @@ -127,9 +117,9 @@ show create table t1; select * from t1; drop table t1; -select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2"); -select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[1]"); -select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[10]"); +select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2") as ex; +select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[1]") as ex; +select json_exists('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[10]") as ex; select json_quote('"string"'); create table t1 as select json_quote('foo'); @@ -149,11 +139,14 @@ select json_merge('a','b'); select json_merge('{"a":"b"}','{"c":"d"}'); SELECT JSON_MERGE('[1, 2]', '{"id": 47}'); +#enable after MDEV-32454 fix +--disable_view_protocol select json_type('{"k1":123, "k2":345}'); select json_type('[123, "k2", 345]'); select json_type("true"); select json_type('123'); select json_type('123.12'); +--enable_view_protocol select json_keys('{"a":{"c":1, "d":2}, "b":2}'); select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a"); @@ -162,28 +155,31 @@ select json_keys('foo'); # # mdev-12789 JSON_KEYS returns duplicate keys twice # -select json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}'); -select json_keys('{"c1": "value 1", "c1": "value 2"}'); +select json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}') as ex; +select json_keys('{"c1": "value 1", "c1": "value 2"}') as ex; SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]'; -select json_search(@j, 'one', 'abc'); -select json_search(@j, 'all', 'abc'); -select json_search(@j, 'all', 'abc', NULL, '$[2]'); -select json_search(@j, 'all', 'abc', NULL, '$'); -select json_search(@j, 'all', '10', NULL, '$'); -select json_search(@j, 'all', '10', NULL, '$[*]'); -select json_search(@j, 'all', '10', NULL, '$[*][0].k'); -select json_search(@j, 'all', '10', NULL, '$**.k'); +select json_search(@j, 'one', 'abc') as ex; +select json_search(@j, 'all', 'abc') as ex; +select json_search(@j, 'all', 'abc', NULL, '$[2]') as ex; +select json_search(@j, 'all', 'abc', NULL, '$') as ex; +select json_search(@j, 'all', '10', NULL, '$') as ex; +select json_search(@j, 'all', '10', NULL, '$[*]') as ex; +select json_search(@j, 'all', '10', NULL, '$[*][0].k') as ex; +select json_search(@j, 'all', '10', NULL, '$**.k') as ex; create table t1( json_col text ); insert into t1 values ('{ "a": "foobar" }'), ('{ "a": "foobar", "b": "focus", "c": [ "arm", "foot", "shoulder" ] }'); -select json_search( json_col, 'all', 'foot' ) from t1; +select json_search( json_col, 'all', 'foot' ) as ex from t1; drop table t1; +#enable after MDEV-32454 fix +--disable_view_protocol select json_unquote('"abc"'); select json_unquote('abc'); +--enable_view_protocol # # MDEV-13703 Illegal mix of collations for operation 'json_object' on using JSON_UNQUOTE as an argument. # @@ -193,9 +189,14 @@ insert into t1 values ('abc'),('def'); select json_object('foo', json_unquote(json_object('bar', c)),'qux', c) as fld from t1; drop table t1; + +#enable after MDEV-32454 fix +--disable_view_protocol select json_object("a", json_object("b", "abcd")); select json_object("a", '{"b": "abcd"}'); select json_object("a", json_compact('{"b": "abcd"}')); +--enable_view_protocol + select json_compact(NULL); select json_depth(json_compact(NULL)); @@ -214,15 +215,15 @@ create table json (j INT); show create table json; drop table json; -select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2]' ); -select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' ); -select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0]' ); -select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0][0]' ); -select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2]' ); -select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0]' ); -select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0]' ); -select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0][0]' ); -select json_length( '{"a":{"b":{"d":1}}, "a":{"c":{"d":1, "j":2}}}', '$.a[0][0][0].c' ); +select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2]' ) as ex; +select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' ) as ex; +select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0]' ) as ex; +select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0][0]' ) as ex; +select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2]' ) as ex; +select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0]' ) as ex; +select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0]' ) as ex; +select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0][0]' ) as ex; +select json_length( '{"a":{"b":{"d":1}}, "a":{"c":{"d":1, "j":2}}}', '$.a[0][0][0].c' ) as ex; select json_set('1', '$[0]', 100); select json_set('1', '$[0][0]', 100); @@ -232,12 +233,12 @@ select json_set('{"a":12}', '$[0].a', 100); select json_set('{"a":12}', '$[0][0].a', 100); select json_set('{"a":12}', '$[0][1].a', 100); -select json_value('{"\\"key1":123}', '$."\\"key1"'); -select json_value('{"\\"key1\\"":123}', '$."\\"key1\\""'); -select json_value('{"key 1":123}', '$."key 1"'); +select json_value('{"\\"key1":123}', '$."\\"key1"') as ex; +select json_value('{"\\"key1\\"":123}', '$."\\"key1\\""') as ex; +select json_value('{"key 1":123}', '$."key 1"') as ex; -select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[2]"); -select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[3]"); +select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[2]") as ex; +select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[3]") as ex; select json_extract( '[1]', '$[0][0]' ); select json_extract( '[1]', '$[1][0]' ); @@ -265,21 +266,24 @@ SELECT JSON_search( '{"": "a"}', "one", 'a'); # MDEV-11858 json_merge() concatenates instead of merging. # -select json_merge('{"a":"b"}', '{"a":"c"}') ; -select json_merge('{"a":{"x":"b"}}', '{"a":"c"}') ; -select json_merge('{"a":{"u":12, "x":"b"}}', '{"a":{"x":"c"}}') ; -select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') ; +select json_merge('{"a":"b"}', '{"a":"c"}') as ex ; +select json_merge('{"a":{"x":"b"}}', '{"a":"c"}') as ex ; +select json_merge('{"a":{"u":12, "x":"b"}}', '{"a":{"x":"c"}}') as ex ; +select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') as ex ; -select json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}'); -select json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}'); -select json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}'); +select json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') as ex; +#enable after MDEV-32454 fix +--disable_view_protocol +select json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') as ex; +select json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') as ex; +--enable_view_protocol # # MDEV-11856 json_search doesn't search for values with double quotes character (") # -SELECT JSON_search( '{"x": "\\""}', "one", '"'); -SELECT JSON_search( '{"x": "\\""}', "one", '\\"'); +SELECT JSON_search( '{"x": "\\""}', "one", '"') as ex; +SELECT JSON_search( '{"x": "\\""}', "one", '\\"') as ex; # # MDEV-11833 JSON functions don't seem to respect max_allowed_packet. @@ -293,8 +297,8 @@ set @@global.max_allowed_packet=2048; show variables like 'net_buffer_length'; show variables like 'max_allowed_packet'; -select json_array(repeat('a',1024),repeat('a',1024)); -select json_object("a", repeat('a',1024),"b", repeat('a',1024)); +select json_array(repeat('a',1024),repeat('a',1024)) as ex; +select json_object("a", repeat('a',1024),"b", repeat('a',1024)) as ex; --connection default set @@global.max_allowed_packet = @save_max_allowed_packet; @@ -344,27 +348,30 @@ SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*]'); # MDEV-12604 Comparison of JSON_EXTRACT result differs with Mysql. # -select JSON_EXTRACT('{"name":"value"}', '$.name') = 'value'; -select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true; -select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false; -select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1; -select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"'); +select JSON_EXTRACT('{"name":"value"}', '$.name') = 'value' as ex; +select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true as ex; +select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false as ex; +select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1 as ex; +select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"') as ex; # # MDEV-129892 JSON_EXTRACT returns data for invalid JSON # -select JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo'); +select JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo') as ex; # # MDEV-13138 JSON_OBJECT returns null with strings containing backticks. # -SELECT JSON_OBJECT('foo', '`'); -SELECT JSON_OBJECT("foo", "bar`bar"); +SELECT JSON_OBJECT('foo', '`') as ex; +SELECT JSON_OBJECT("foo", "bar`bar") as ex; # # MDEV-13324 JSON_SET returns NULL instead of object. # +#enable after MDEV-32454 fix +--disable_view_protocol SELECT JSON_SET('{}', '$.age', 87); +--enable_view_protocol # # MDEV-13104 Json functions. @@ -457,16 +464,19 @@ select json_array(1,user(),compress(5.140264e+307)); create table t1(json_col TEXT) DEFAULT CHARSET=latin1; insert into t1 values (_latin1 X'7B226B657931223A2253EC227D'); select JSON_VALUE(json_col, '$.key1')= _latin1 X'53EC' from t1; -select REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' from t1; +select REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' as exp from t1; drop table t1; --echo # --echo # MDEV-16750 JSON_SET mishandles unicode every second pair of arguments. --echo # -SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6); -SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6); -SELECT JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6'); +#enable after MDEV-32454 fix +--disable_view_protocol +SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6) as exp; +SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6) as exp; +SELECT JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6') as exp; +--enable_view_protocol --echo # --echo # MDEV-17121 JSON_ARRAY_APPEND @@ -509,9 +519,9 @@ select JSON_VALID( '{"a":1]' ); --echo # --echo # MDEV-18886 JSON_ARRAY() does not recognise JSON argument. --echo # -SELECT JSON_ARRAY(_UTF8 'str', JSON_OBJECT(_LATIN1 'plugin', _LATIN1'unix_socket')); -SELECT CHARSET(JSON_ARRAY()); -SELECT CHARSET(JSON_OBJECT()); +SELECT JSON_ARRAY(_UTF8 'str', JSON_OBJECT(_LATIN1 'plugin', _LATIN1'unix_socket')) as exp; +SELECT CHARSET(JSON_ARRAY()) as exp; +SELECT CHARSET(JSON_OBJECT()) as exp; --echo # --echo # MDEV-13992 Implement JSON_MERGE_PATCH @@ -545,17 +555,17 @@ SELECT id, target, patch, FROM merge_t ORDER BY id; DROP TABLE merge_t; -SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '{"c":"d"}'); -SELECT JSON_MERGE_PATCH(NULL, '[1,2,3]'); -SELECT JSON_MERGE_PATCH(NULL, 'a'); -SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '[1,2,3]', '{"c":null,"d":"e"}'); +SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '{"c":"d"}') as exp; +SELECT JSON_MERGE_PATCH(NULL, '[1,2,3]') as exp; +SELECT JSON_MERGE_PATCH(NULL, 'a') as exp; +SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '[1,2,3]', '{"c":null,"d":"e"}') as exp; --error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT -SELECT JSON_MERGE_PATCH(); +SELECT JSON_MERGE_PATCH() as exp; --error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT -SELECT JSON_MERGE_PATCH('{}'); -SELECT JSON_MERGE_PATCH('{', '[1,2,3]'); -SELECT JSON_MERGE_PATCH('{"a":"b"}', '[1,'); +SELECT JSON_MERGE_PATCH('{}') as exp; +SELECT JSON_MERGE_PATCH('{', '[1,2,3]') as exp; +SELECT JSON_MERGE_PATCH('{"a":"b"}', '[1,') as exp; --echo # --echo # MDEV-22976 CAST(JSON_EXTRACT() AS DECIMAL) does not handle boolean values @@ -601,6 +611,7 @@ DROP TABLE json_test; --enable_metadata --disable_ps_protocol +--disable_view_protocol SELECT JSON_VALID('{"id": 1, "name": "Monty"}') AS json_valid, @@ -612,6 +623,7 @@ SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}') AS json_length, JSON_DEPTH('[10, {"a": 20}]') AS json_depnth; +--enable_view_protocol --enable_ps_protocol --disable_metadata @@ -674,10 +686,13 @@ SELECT JSON_EXTRACT('{"a":null, "b":10, "c":"null"}', '$.a'); --echo # --vertical_results +#enable after fix MDEV-28649 +--disable_view_protocol SELECT JSON_OBJECT("cond", true) AS j1, JSON_OBJECT("cond", COALESCE(true, false)) j2, JSON_OBJECT("cond", COALESCE(COALESCE(true, false))) j3; +--enable_view_protocol --horizontal_results CREATE TABLE t1 (a INT); @@ -742,7 +757,10 @@ INSERT INTO t1 VALUES (TRUE, TRUE), (TRUE, FALSE), (FALSE, TRUE), (FALSE, FALSE) SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1; SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1; SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1 GROUP BY b; +#enable after MDEV-32454 fix +--disable_view_protocol SELECT JSON_ARRAYAGG(TRUE), JSON_ARRAYAGG(FALSE) FROM t1; +--enable_view_protocol DROP TABLE t1; -- echo # @@ -908,9 +926,9 @@ insert into t200 values }'); -select JSON_DETAILED(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) from t200; -select JSON_PRETTY(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) from t200; -select JSON_LOOSE(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) from t200; +select JSON_DETAILED(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; +select JSON_PRETTY(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; +select JSON_LOOSE(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; drop table t200; --echo # @@ -1019,9 +1037,12 @@ create table t1 (a varchar(254)); insert into t1 values (concat('x64-', repeat('a', 60))); insert into t1 values (concat('x64-', repeat('b', 60))); insert into t1 values (concat('x64-', repeat('c', 60))); +#enable after MDEV-32454 fix +--disable_view_protocol --disable_ps2_protocol select json_arrayagg(a) from t1; --enable_ps2_protocol +--enable_view_protocol drop table t1; SET group_concat_max_len= default; @@ -1068,8 +1089,8 @@ DROP TABLE t2; --echo # MDEV-27018 IF and COALESCE lose "json" property --echo # -SELECT json_object('a', if(1, json_object('b', 'c'), json_object('e', 'f'))); -SELECT json_object('a', coalesce(json_object('b', 'c'))); +SELECT json_object('a', if(1, json_object('b', 'c'), json_object('e', 'f'))) as exp; +SELECT json_object('a', coalesce(json_object('b', 'c'))) as exp; --echo # --echo # MDEV-26392: Crash with json_get_path_next and 10.5.12 @@ -1092,6 +1113,16 @@ SELECT JSON_OBJECTAGG('"', 1); SELECT JSON_OBJECTAGG('\"', 1); SELECT JSON_OBJECTAGG('\\', 1); +--echo # +--echo # MDEV-24784 JSON_ARRAYAGG charset issue +--echo # +--disable_service_connection +set names utf8; +select json_arrayagg('ä'), json_objectagg(1, 'ä'); +set names latin1; +select json_arrayagg('ä'), json_objectagg(1, 'ä'); +--enable_service_connection + --echo # --echo # End of 10.5 tests --echo # @@ -1175,7 +1206,7 @@ SELECT JSON_OVERLAPS('{ '{ "A": 2, "B": "string1" - }'); + }') as exp; SELECT JSON_OVERLAPS('{ "A": 1, "B": "string1" @@ -1183,7 +1214,7 @@ SELECT JSON_OVERLAPS('{ '{ "A": 2, "B": "string2" - }'); + }') as exp; --echo # Comparing nested object with other nested object SELECT JSON_OVERLAPS('{ @@ -1193,7 +1224,7 @@ SELECT JSON_OVERLAPS('{ '{ "A": 2, "B": {"C":1} - }'); + }') as exp; SELECT JSON_OVERLAPS('{ "A": 1, "B": {"C":2} @@ -1201,7 +1232,7 @@ SELECT JSON_OVERLAPS('{ '{ "A": 2, "B": {"C":2} - }'); + }') as exp; SELECT JSON_OVERLAPS('{ "A": { "B": true @@ -1212,32 +1243,32 @@ SELECT JSON_OVERLAPS('{ "B": true, "C": false } - }'); + }') as exp; SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":5}}', - '{"C":3, "B":{"E":5, "D":4}}'); + '{"C":3, "B":{"E":5, "D":4}}') as exp; SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', - '{"C":3, "B":{"E":5, "D":4}}'); + '{"C":3, "B":{"E":5, "D":4}}') as exp; SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', - '{"C":3, "B":{"E":[5, 6, 7], "D":4}}'); + '{"C":3, "B":{"E":[5, 6, 7], "D":4}}') as exp; SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', - '{"C":3, "B":{"E":[7, 6 ,5], "D":4}}'); + '{"C":3, "B":{"E":[7, 6 ,5], "D":4}}') as exp; SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', - '{"C":3, "F":{"E":[5, 6, 7], "D":4}}'); + '{"C":3, "F":{"E":[5, 6, 7], "D":4}}') as exp; --echo # Comparing array with array (non-nested) SELECT JSON_OVERLAPS('[1, 2, true, false, null]', - '[3, 4, 1]'); + '[3, 4, 1]') as exp; SELECT JSON_OVERLAPS('[1, 2, true, false, null]', '[3, 4, 5]'); -SELECT JSON_OVERLAPS('[1,2,3]','[]'); +SELECT JSON_OVERLAPS('[1,2,3]','[]') as exp; --echo # Comparing nested arrays SELECT JSON_OVERLAPS('[1, 2, true, false, null]', - '[3, 4, [1]]'); + '[3, 4, [1]]') as exp; SELECT JSON_OVERLAPS('[1, 2, [true, false], null]', - '[[1], [true, false]]'); -SELECT JSON_OVERLAPS('[1, 2, 3, [4, 5, 6]]','[7, 8, 9, [6, 5, 4]]'); + '[[1], [true, false]]') as exp; +SELECT JSON_OVERLAPS('[1, 2, 3, [4, 5, 6]]','[7, 8, 9, [6, 5, 4]]') as exp; --echo # Comparing one non-scalar json datatypes with another non-scalar @@ -1245,52 +1276,52 @@ SELECT JSON_OVERLAPS('[1, 2, 3, [4, 5, 6]]','[7, 8, 9, [6, 5, 4]]'); --echo # Comparing array with object SELECT JSON_OVERLAPS('[1, 2, true, false, null]', - '{"A": 1}'); + '{"A": 1}') as exp; SELECT JSON_OVERLAPS('[1, 2, true, false, null, {"A":2}]', - '{"A": 1}'); + '{"A": 1}') as exp; SELECT JSON_OVERLAPS('[1, {"A": 2}, {"A": 1}]', - '{"A": 1}'); + '{"A": 1}') as exp; SELECT JSON_OVERLAPS('[1, 2, true, false, {"A": 1, "B": 2}]', - '{"A": 1, "B": 2}'); + '{"A": 1, "B": 2}') as exp; SELECT JSON_OVERLAPS('[1, 2, true, false, {"A": 1, "B": 2}]', - '{"A": 1, "B": 3}'); + '{"A": 1, "B": 3}') as exp; -- echo # Comparing nested array with object SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": 2}]]', - '{"A": 1, "B": 2}'); + '{"A": 1, "B": 2}') as exp; SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": 2}]]', - '{"A": 1, "B": 3}'); + '{"A": 1, "B": 3}') as exp; SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": 2}]]', - '{"A": 1}'); + '{"A": 1}') as exp; --echo # Comparing array with nested object SELECT JSON_OVERLAPS('[1, 2, true, false, {"A": 1, "B": {"C": 12}}]', - '{"A": 1, "B": {"C": 12}}'); + '{"A": 1, "B": {"C": 12}}') as exp; SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": {"C": 12}}]]', - '{"A": 1, "B": {"C": 12}}'); + '{"A": 1, "B": {"C": 12}}') as exp; --echo # Comparing nested array with nested objects SELECT JSON_OVERLAPS('[1, 2, true, false, [{"A": 1, "B": {"C": 12}}]]', - '{"A": 1, "B":{"C": 12}}'); + '{"A": 1, "B":{"C": 12}}') as exp; SELECT JSON_OVERLAPS('[[1, 2, true, false, {"A": 1, "B": {"C": 12}}]]', - '{"A": 1, "B": {"C": 12}}'); + '{"A": 1, "B": {"C": 12}}') as exp; --echo # Comparing object with array SELECT JSON_OVERLAPS('{"A": 1, "B": 3}', - '[1, 2, true, false, {"A": 1, "B": 2}]'); + '[1, 2, true, false, {"A": 1, "B": 2}]') as exp; SELECT JSON_OVERLAPS('{"A": 1, "B": 3}', - '[1, 2, true, false, {"A": 1, "B": 3}]'); + '[1, 2, true, false, {"A": 1, "B": 3}]') as exp; SELECT JSON_OVERLAPS('{"A": 1, "B": 3}', - '[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": 3}]'); + '[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": 3}]') as exp; SELECT JSON_OVERLAPS('{"A": 1, "B": [1, 2, 3]}', - '[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": [1, 2, 3]}]'); + '[1, 2, true, false, {"A": 1, "B": 2}, {"A": 1, "B": [1, 2, 3]}]') as exp; SELECT JSON_OVERLAPS('{"A": 1, "B": [1, 2, {"C": 3, "D": 5}]}', - '[1, 2, true, false, {"A": 1, "B": 2}, {"A":1, "B":[1, 2, {"C": 3, "D": 5}]}]'); + '[1, 2, true, false, {"A": 1, "B": 2}, {"A":1, "B":[1, 2, {"C": 3, "D": 5}]}]') as exp; SELECT JSON_OVERLAPS('{"A": 1, "B": [1, 2, {"C": 3, "D": 5}]}', - '[1, 2, true, false, {"A": 1, "B": 2},{"A": 1, "B": [1, 2, {"C": 3, "D": 4}]}]'); + '[1, 2, true, false, {"A": 1, "B": 2},{"A": 1, "B": [1, 2, {"C": 3, "D": 4}]}]') as exp; --echo # Comparing object with nested array -SELECT JSON_OVERLAPS('{"A": 1, "B": 3}','[1, 2, true, false, [{"A": 1, "B": 2}, {"A": 1, "B": 3}]]'); +SELECT JSON_OVERLAPS('{"A": 1, "B": 3}','[1, 2, true, false, [{"A": 1, "B": 2}, {"A": 1, "B": 3}]]') as exp; --echo # Checking errors and warnings @@ -1810,7 +1841,28 @@ SET @@collation_connection= @save_collation_connection; --echo # End of 10.9 Test --echo # ---echo # Beginning of 11.1 test +--echo # +--echo # MDEV-32007: JSON_VALUE and JSON_EXTRACT doesn't handle dash (-) +--echo # as first character in key +--echo # + +CREATE TEMPORARY TABLE IF NOT EXISTS jsonTest AS + SELECT '{ "-1234" : "something", + "12-34" : "else", + "1234-" : "and", + "1234" : "match" }' AS 'message'; + +SELECT JSON_SEARCH(message, 'one', 'something') AS t1_path, + JSON_VALUE(message, JSON_UNQUOTE(JSON_SEARCH(message, 'one', 'something'))) AS t1_result, + JSON_SEARCH(message, 'one', 'else') AS t2_path, + JSON_VALUE(message, JSON_UNQUOTE(JSON_SEARCH(message, 'one', 'else'))) AS t2_result, + JSON_SEARCH(message, 'one', 'and') AS t3_path, + JSON_VALUE(message, JSON_UNQUOTE(JSON_SEARCH(message, 'one', 'and'))) AS t3_result, + JSON_SEARCH(message, 'one', 'match') AS t4_path, + JSON_VALUE(message, JSON_UNQUOTE(JSON_SEARCH(message, 'one', 'match'))) AS t4_result +FROM jsonTest; + +--echo # End of 11.0 test --echo # --echo # MDEV-27128: Implement JSON Schema Validation FUNCTION @@ -3636,7 +3688,9 @@ SELECT JSON_SCHEMA_VALID(@schema, '-#'); SET @schema_array= '{"type":"array"}'; SELECT JSON_SCHEMA_VALID(@schema_array, '['); +--disable_view_protocol SELECT JSON_SCHEMA_VALID(repeat('[', 100000), json_object()); +--enable_view_protocol SELECT JSON_SCHEMA_VALID(json_object(), repeat('[', 10000000)); @@ -3647,6 +3701,23 @@ SELECT JSON_SCHEMA_VALID('{}', NULL); SELECT JSON_SCHEMA_VALID(NULL, '{}'); SELECT JSON_SCHEMA_VALID(NULL, NULL); +--echo # +--echo # MDEV-31599: Assertion `0' failed in Item_param::can_return_value from Item::val_json, +--echo # UBSAN: member access within null pointer of type 'struct String' in +--echo # sql/item_jsonfunc.cc +--echo # + +--error ER_JSON_NO_VARIABLE_SCHEMA +PREPARE s FROM 'SELECT JSON_SCHEMA_VALID (?,''{}'') FROM DUAL'; + +--echo # +--echo # MDEV-33015: Server crashes upon JSON_SCHEMA_VALID reading NULL from a user variable +--echo # + +SET @a= NULL; +SELECT JSON_SCHEMA_VALID(@a,'{}'); + + --echo # End of 11.1 test --echo # Beginning of 11.2 @@ -3732,25 +3803,29 @@ FROM JSON_TABLE( JSON_KEY_VALUE('[[1, 2, 3], 2, 3]', '$[0][1]'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; -SELECT JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1]'); +SELECT JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', +'$[0][1]') as exp; SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1]'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; -SELECT JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1].key1'); +SELECT JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', +'$[0][1].key1') as exp; SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('[[1, {"key1":"val1", "key2":"val2"}, 3], 2, 3]', '$[0][1].key1'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; -SELECT JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', '$[0][1]'); +SELECT JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', +'$[0][1]') as exp; SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', '$[0][1]'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; -SELECT JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', '$[0][1][0]'); +SELECT JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', +'$[0][1][0]') as exp; SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('[[1, [{"key1":"val1", "key2":"val2"}], 3], 2, 3]', '$[0][1][0]'), '$[*]' @@ -3760,31 +3835,34 @@ FROM JSON_TABLE( SELECT JSON_KEY_VALUE('{}', '$.key1'); -SELECT JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$'); +#enable after MDEV-32454 fix +--disable_view_protocol +SELECT JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$') as exp; +--enable_view_protocol SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$'), '$[*]' COLUMNS (k VARCHAR(11) PATH '$.key', v VARCHAR(5) PATH '$.value', id FOR ORDINALITY)) AS jt; -SELECT JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$.key1'); +SELECT JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$.key1') as exp; SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('{"key1":"val1", "key2":"val2"}', '$.key1'), '$[*]' COLUMNS (k VARCHAR(11) PATH '$.key', v VARCHAR(5) PATH '$.value', id FOR ORDINALITY)) AS jt; -SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b":2}, "key2":"val2"}', '$.key1'); +SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b":2}, "key2":"val2"}', '$.key1') as exp; SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('{"key1":{"a":1, "b":2}, "key2":"val2"}', '$.key1'), '$[*]' COLUMNS (k VARCHAR(11) PATH '$.key', v VARCHAR(5) PATH '$.value', id FOR ORDINALITY)) AS jt; -SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[3]'); +SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[3]') as exp; SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[3]'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; -SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[0]'); +SELECT JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[0]') as exp; SELECT jt.* FROM JSON_TABLE( JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[0]'), '$[*]' @@ -3947,6 +4025,24 @@ SELECT JSON_OBJECT_TO_ARRAY(@obj1); SET @arr1= '[1, 2, 3]'; SELECT JSON_OBJECT_TO_ARRAY(@arr1); + +--echo # +--echo # MDEV-31411: JSON_ARRAY_INTERSECT/JSON_OBJECT_FILTER_KEYS should fetch +--echo # data from a table similar to other JSON functions +--echo # + +CREATE TABLE t1 ( + c1 longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(c1)), + c2 longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`c2`)) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; + +INSERT INTO t1 VALUES('[1,2,3]', '[2, 3, 4]'), ('[2 ,3, 4]', '[4, 5, 6]'); + +SELECT JSON_ARRAY_INTERSECT(c1, c2) FROM t1; + +DROP TABLE t1; + + --echo # --echo # End of 11.2 Test --echo # diff --git a/mysql-test/main/func_math.result b/mysql-test/main/func_math.result index 2b4c0162ff8..1c6c780e380 100644 --- a/mysql-test/main/func_math.result +++ b/mysql-test/main/func_math.result @@ -931,8 +931,8 @@ STDDEV_POP(ROUND(0,@A:=2009)) # CREATE TABLE t1 ( pk int NOT NULL, i1 int NOT NULL, d1 date NOT NULL, t1 time); INSERT INTO t1 VALUES (7,9,'2007-08-15','03:55:02'),(8,7,'1993-06-05','04:17:51'),(9,7,'2034-07-01','17:31:12'),(10,0,'1998-08-24','08:09:27'); -SELECT DISTINCT STDDEV_SAMP(EXPORT_SET(t1, -1379790335835635712, (i1 + 'o'), (MD5(d1)))) FROM t1; -STDDEV_SAMP(EXPORT_SET(t1, -1379790335835635712, (i1 + 'o'), (MD5(d1)))) +SELECT DISTINCT STDDEV_SAMP(EXPORT_SET(t1, -1379790335835635712, (i1 + 'o'), (MD5(d1)))) as exp FROM t1; +exp NULL Warnings: Warning 1292 Truncated incorrect DOUBLE value: 'o' diff --git a/mysql-test/main/func_math.test b/mysql-test/main/func_math.test index 0e9549b542a..d4e853938ad 100644 --- a/mysql-test/main/func_math.test +++ b/mysql-test/main/func_math.test @@ -685,10 +685,7 @@ SELECT STDDEV_POP(ROUND(0,@A:=2009)) FROM (SELECT 1 UNION SELECT 2) fake_table; CREATE TABLE t1 ( pk int NOT NULL, i1 int NOT NULL, d1 date NOT NULL, t1 time); INSERT INTO t1 VALUES (7,9,'2007-08-15','03:55:02'),(8,7,'1993-06-05','04:17:51'),(9,7,'2034-07-01','17:31:12'),(10,0,'1998-08-24','08:09:27'); -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT DISTINCT STDDEV_SAMP(EXPORT_SET(t1, -1379790335835635712, (i1 + 'o'), (MD5(d1)))) FROM t1; ---enable_view_protocol +SELECT DISTINCT STDDEV_SAMP(EXPORT_SET(t1, -1379790335835635712, (i1 + 'o'), (MD5(d1)))) as exp FROM t1; DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(128)); diff --git a/mysql-test/main/func_misc.result b/mysql-test/main/func_misc.result index 8ae2cf4ad6b..91cc4bc206a 100644 --- a/mysql-test/main/func_misc.result +++ b/mysql-test/main/func_misc.result @@ -163,8 +163,8 @@ select @invoked; @invoked 10 set @invoked := 0; -select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093)); -benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093)) +select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093)) as exp; +exp 0 select @invoked; @invoked @@ -1184,11 +1184,11 @@ INET6_NTOA(INET6_ATON('1:2:3:4:5:6:7::')) SELECT INET6_NTOA(INET6_ATON('0000:0000::0000:0001')); INET6_NTOA(INET6_ATON('0000:0000::0000:0001')) ::1 -SELECT INET6_NTOA(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed')); -INET6_NTOA(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed')) +SELECT INET6_NTOA(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed')) as exp; +exp 1234:5678:9abc:def0:4321:8765:cba9:fed -SELECT INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001')); -INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001')) +SELECT INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001')) as exp; +exp ::1 SELECT INET6_NTOA(INET6_ATON('::C0A8:0102')); INET6_NTOA(INET6_ATON('::C0A8:0102')) diff --git a/mysql-test/main/func_misc.test b/mysql-test/main/func_misc.test index f508eda2009..5b2c350497d 100644 --- a/mysql-test/main/func_misc.test +++ b/mysql-test/main/func_misc.test @@ -164,10 +164,7 @@ select @invoked; set @invoked := 0; --disable_ps2_protocol -#enable after fix MDEV-27871 ---disable_view_protocol -select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093)); ---enable_view_protocol +select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093)) as exp; --enable_ps2_protocol # Returns 1000, due to rand() preventing caching. select @invoked; @@ -958,11 +955,8 @@ SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5::7:8')); SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5:6::8')); SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5:6:7::')); SELECT INET6_NTOA(INET6_ATON('0000:0000::0000:0001')); -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT INET6_NTOA(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed')); -SELECT INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001')); ---enable_view_protocol +SELECT INET6_NTOA(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed')) as exp; +SELECT INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001')) as exp; SELECT INET6_NTOA(INET6_ATON('::C0A8:0102')); SELECT INET6_NTOA(INET6_ATON('::c0a8:0102')); SELECT INET6_NTOA(INET6_ATON('::192.168.1.2')); 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/func_sapdb.result b/mysql-test/main/func_sapdb.result index 27f1d74bc41..5098752a433 100644 --- a/mysql-test/main/func_sapdb.result +++ b/mysql-test/main/func_sapdb.result @@ -17,35 +17,35 @@ extract(MICROSECOND FROM "1999-01-02 10:11:12.000123") select date_format("1997-12-31 23:59:59.000002", "%f"); date_format("1997-12-31 23:59:59.000002", "%f") 000002 -select date_add("1997-12-31 23:59:59.000002",INTERVAL "10000 99:99:99.999999" DAY_MICROSECOND); -date_add("1997-12-31 23:59:59.000002",INTERVAL "10000 99:99:99.999999" DAY_MICROSECOND) +select date_add("1997-12-31 23:59:59.000002",INTERVAL "10000 99:99:99.999999" DAY_MICROSECOND) as exp; +exp 2025-05-23 04:40:39.000001 -select date_add("1997-12-31 23:59:59.000002",INTERVAL "10000:99:99.999999" HOUR_MICROSECOND); -date_add("1997-12-31 23:59:59.000002",INTERVAL "10000:99:99.999999" HOUR_MICROSECOND) +select date_add("1997-12-31 23:59:59.000002",INTERVAL "10000:99:99.999999" HOUR_MICROSECOND) as exp; +exp 1999-02-21 17:40:39.000001 -select date_add("1997-12-31 23:59:59.000002",INTERVAL "10000:99.999999" MINUTE_MICROSECOND); -date_add("1997-12-31 23:59:59.000002",INTERVAL "10000:99.999999" MINUTE_MICROSECOND) +select date_add("1997-12-31 23:59:59.000002",INTERVAL "10000:99.999999" MINUTE_MICROSECOND) as exp; +exp 1998-01-07 22:41:39.000001 -select date_add("1997-12-31 23:59:59.000002",INTERVAL "10000.999999" SECOND_MICROSECOND); -date_add("1997-12-31 23:59:59.000002",INTERVAL "10000.999999" SECOND_MICROSECOND) +select date_add("1997-12-31 23:59:59.000002",INTERVAL "10000.999999" SECOND_MICROSECOND) as exp; +exp 1998-01-01 02:46:40.000001 -select date_add("1997-12-31 23:59:59.000002",INTERVAL "999999" MICROSECOND); -date_add("1997-12-31 23:59:59.000002",INTERVAL "999999" MICROSECOND) +select date_add("1997-12-31 23:59:59.000002",INTERVAL "999999" MICROSECOND) as exp; +exp 1998-01-01 00:00:00.000001 -select date_sub("1998-01-01 00:00:00.000001",INTERVAL "1 1:1:1.000002" DAY_MICROSECOND); -date_sub("1998-01-01 00:00:00.000001",INTERVAL "1 1:1:1.000002" DAY_MICROSECOND) +select date_sub("1998-01-01 00:00:00.000001",INTERVAL "1 1:1:1.000002" DAY_MICROSECOND) as exp; +exp 1997-12-30 22:58:58.999999 -select date_sub("1998-01-01 00:00:00.000001",INTERVAL "1:1:1.000002" HOUR_MICROSECOND); -date_sub("1998-01-01 00:00:00.000001",INTERVAL "1:1:1.000002" HOUR_MICROSECOND) +select date_sub("1998-01-01 00:00:00.000001",INTERVAL "1:1:1.000002" HOUR_MICROSECOND) as exp; +exp 1997-12-31 22:58:58.999999 -select date_sub("1998-01-01 00:00:00.000001",INTERVAL "1:1.000002" MINUTE_MICROSECOND); -date_sub("1998-01-01 00:00:00.000001",INTERVAL "1:1.000002" MINUTE_MICROSECOND) +select date_sub("1998-01-01 00:00:00.000001",INTERVAL "1:1.000002" MINUTE_MICROSECOND) as exp; +exp 1997-12-31 23:58:58.999999 -select date_sub("1998-01-01 00:00:00.000001",INTERVAL "1.000002" SECOND_MICROSECOND); -date_sub("1998-01-01 00:00:00.000001",INTERVAL "1.000002" SECOND_MICROSECOND) +select date_sub("1998-01-01 00:00:00.000001",INTERVAL "1.000002" SECOND_MICROSECOND) as exp; +exp 1997-12-31 23:59:58.999999 -select date_sub("1998-01-01 00:00:00.000001",INTERVAL "000002" MICROSECOND); -date_sub("1998-01-01 00:00:00.000001",INTERVAL "000002" MICROSECOND) +select date_sub("1998-01-01 00:00:00.000001",INTERVAL "000002" MICROSECOND) as exp; +exp 1997-12-31 23:59:59.999999 select adddate("1997-12-31 23:59:59.000001", 10); adddate("1997-12-31 23:59:59.000001", 10) @@ -98,47 +98,47 @@ NULL select makedate(100,1); makedate(100,1) 0100-01-01 -select addtime("1997-12-31 23:59:59.999999", "1 1:1:1.000002"); -addtime("1997-12-31 23:59:59.999999", "1 1:1:1.000002") +select addtime("1997-12-31 23:59:59.999999", "1 1:1:1.000002") as exp; +exp 1998-01-02 01:01:01.000001 -select subtime("1997-12-31 23:59:59.000001", "1 1:1:1.000002"); -subtime("1997-12-31 23:59:59.000001", "1 1:1:1.000002") +select subtime("1997-12-31 23:59:59.000001", "1 1:1:1.000002") as exp; +exp 1997-12-30 22:58:57.999999 -select addtime("1997-12-31 23:59:59.999999", "1998-01-01 01:01:01.999999"); -addtime("1997-12-31 23:59:59.999999", "1998-01-01 01:01:01.999999") +select addtime("1997-12-31 23:59:59.999999", "1998-01-01 01:01:01.999999") as exp; +exp NULL Warnings: Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '1998-01-01 01:01:01.999999' -select subtime("1997-12-31 23:59:59.999999", "1998-01-01 01:01:01.999999"); -subtime("1997-12-31 23:59:59.999999", "1998-01-01 01:01:01.999999") +select subtime("1997-12-31 23:59:59.999999", "1998-01-01 01:01:01.999999") as exp; +exp NULL Warnings: Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '1998-01-01 01:01:01.999999' -select subtime("01:00:00.999999", "02:00:00.999998"); -subtime("01:00:00.999999", "02:00:00.999998") +select subtime("01:00:00.999999", "02:00:00.999998") as exp; +exp -00:59:59.999999 -select subtime("02:01:01.999999", "01:01:01.999999"); -subtime("02:01:01.999999", "01:01:01.999999") +select subtime("02:01:01.999999", "01:01:01.999999") as exp; +exp 01:00:00 -select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002"); -timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002") +select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002") as exp; +exp 838:59:59.999999 Warnings: Warning 1292 Truncated incorrect time value: '8807:59:59.999999' -select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002"); -timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") +select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") as exp; +exp 46:58:57.999999 -select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); -timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") +select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") as exp; +exp -24:00:00.000001 -select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); -timediff("1997-12-31 23:59:59.000001","23:59:59.000001") +select timediff("1997-12-31 23:59:59.000001","23:59:59.000001") as exp; +exp NULL -select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"); -timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001") +select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001") as exp; +exp -00:00:00.000001 -select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); -timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50") +select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50") as exp; +exp -00:00:00.000001 select maketime(10,11,12); maketime(10,11,12) @@ -262,14 +262,14 @@ a select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f"); str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") 2003-01-02 10:11:12.001200 -select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10'),time('00:00:00'); -timediff('2008-09-29 20:10:10','2008-09-30 20:10:10') time('00:00:00') +select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10'),time('00:00:00') as exp; +timediff('2008-09-29 20:10:10','2008-09-30 20:10:10') exp -24:00:00 00:00:00 -select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')>time('00:00:00'); -timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')>time('00:00:00') +select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')>time('00:00:00') as exp; +exp 0 -select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')time('00:00:00'); -select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')time('00:00:00') as exp; +select timediff('2008-09-29 20:10:10','2008-09-30 20:10:10')new year', '/a', '2019-01-01 00:00:00' ) f 2019-01-01 00:00:00F}^i # +# MDEV-31184 Remove parser tokens DECODE_MARIADB_SYM and DECODE_ORACLE_SYM +# +SELECT DECODE(); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +SELECT DECODE(NULL); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +SELECT DECODE(NULL,NULL); +DECODE(NULL,NULL) +NULL +SELECT DECODE(NULL, NULL, NULL); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +# # End of 10.4 tests # # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 1b43991e3ca..4c579b50b8c 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2316,6 +2316,19 @@ DROP TABLE t1,t2; SELECT GROUP_CONCAT( UpdateXML( 'new year', '/a', '2019-01-01 00:00:00' ), ENCODE('text','pass') ) AS f; +--echo # +--echo # MDEV-31184 Remove parser tokens DECODE_MARIADB_SYM and DECODE_ORACLE_SYM +--echo # + +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT DECODE(); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT DECODE(NULL); +SELECT DECODE(NULL,NULL); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT DECODE(NULL, NULL, NULL); + + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index c3c2a883270..ff9b91ad1d5 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -9,8 +9,8 @@ period_add("9602",-12) period_diff(199505,"9404") select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now()); now()-now() weekday(curdate())-weekday(now()) unix_timestamp()-unix_timestamp(now()) 0 0 0 -select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0; -from_unixtime(unix_timestamp("1994-03-02 10:11:12")) from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s") from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0 +select from_unixtime(unix_timestamp("1994-03-02 10:11:12")) as e1,from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s") as e2,from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0 as e3; +e1 e2 e3 1994-03-02 10:11:12 1994-03-02 10:11:12 19940302101112 select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"), sec_to_time(time_to_sec("0:30:47")/6.21); @@ -45,20 +45,20 @@ Warning 1292 Truncated incorrect seconds value: '99999999999999999999999999999' select now()-curdate()*1000000-curtime(); now()-curdate()*1000000-curtime() 0 -select strcmp(current_timestamp(),concat(current_date()," ",current_time())); -strcmp(current_timestamp(),concat(current_date()," ",current_time())) +select strcmp(current_timestamp(),concat(current_date()," ",current_time())) as exp; +exp 0 -select strcmp(localtime(),concat(current_date()," ",current_time())); -strcmp(localtime(),concat(current_date()," ",current_time())) +select strcmp(localtime(),concat(current_date()," ",current_time())) as exp; +exp 0 -select strcmp(localtimestamp(),concat(current_date()," ",current_time())); -strcmp(localtimestamp(),concat(current_date()," ",current_time())) +select strcmp(localtimestamp(),concat(current_date()," ",current_time())) as exp; +exp 0 -select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w"); -date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w") +select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w") as exp; +exp January Thursday 2nd 1997 97 01 02 03 04 05 4 -select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w")); -date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w")) +select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w")) as exp; +exp January Thursday 2nd 1997 97 01 02 12 00 00 4 select dayofmonth("1997-01-02"),dayofmonth(19970323); dayofmonth("1997-01-02") dayofmonth(19970323) @@ -179,11 +179,11 @@ time_format(131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T') date_format(19980131131415,'%H| select time_format(010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); time_format(010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T') date_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T') 01|01|1|1|00|AM|01:00:15 AM|15|01:00:15 01|01|1|1|00|AM|01:00:15 AM|15|01:00:15 -select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w'); -date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w') +select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w') as exp; +exp 13|01|13|1|14|PM|01:14:15 PM|15|13:14:15| January|Saturday|31st|1998|98|Sat|Jan|031|01|31|01|15|6 -select date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w'); -date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w') +select date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w') as exp; +exp NULL select date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND); date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND) @@ -297,14 +297,14 @@ date_add("1997-12-31 23:59:59",INTERVAL "10000:1" DAY_HOUR) select date_add("1997-12-31 23:59:59",INTERVAL "-100 1" YEAR_MONTH); date_add("1997-12-31 23:59:59",INTERVAL "-100 1" YEAR_MONTH) 1897-11-30 23:59:59 -select date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND); -date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND) +select date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND) as exp; +exp 1999-02-21 17:40:38 -select date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE); -date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE) +select date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE) as exp; +exp 1970-08-11 19:20:59 -select date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND); -date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND) +select date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND) as exp; +exp 2025-05-23 04:40:38 select "1997-12-31 23:59:59" + INTERVAL 1 SECOND; "1997-12-31 23:59:59" + INTERVAL 1 SECOND @@ -427,11 +427,11 @@ quarter SELECT EXTRACT(QUARTER FROM '2004-12-15') AS quarter; quarter 4 -SELECT DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE); -DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE) +SELECT DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE) as exp; +exp 9999-12-31 00:00:00 -SELECT DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE); -DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE) +SELECT DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE) as exp; +exp 9999-12-31 00:00:00 SELECT "1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND; "1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND @@ -439,8 +439,8 @@ SELECT "1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND; SELECT "1900-01-01 00:00:00" + INTERVAL "1:2147483647" MINUTE_SECOND; "1900-01-01 00:00:00" + INTERVAL "1:2147483647" MINUTE_SECOND 1968-01-20 03:15:07 -SELECT "1900-01-01 00:00:00" + INTERVAL "100000000:214748364700" MINUTE_SECOND; -"1900-01-01 00:00:00" + INTERVAL "100000000:214748364700" MINUTE_SECOND +SELECT "1900-01-01 00:00:00" + INTERVAL "100000000:214748364700" MINUTE_SECOND as exp; +exp 8895-03-27 22:11:40 SELECT "1900-01-01 00:00:00" + INTERVAL 1<<37 SECOND; "1900-01-01 00:00:00" + INTERVAL 1<<37 SECOND @@ -466,8 +466,8 @@ SELECT "1900-01-01 00:00:00" + INTERVAL 1<<30 HOUR; NULL Warnings: Warning 1441 Datetime function: datetime field overflow -SELECT "1900-01-01 00:00:00" + INTERVAL "1000000000:214748364700" MINUTE_SECOND; -"1900-01-01 00:00:00" + INTERVAL "1000000000:214748364700" MINUTE_SECOND +SELECT "1900-01-01 00:00:00" + INTERVAL "1000000000:214748364700" MINUTE_SECOND as exp; +exp NULL Warnings: Warning 1441 Datetime function: datetime field overflow @@ -856,14 +856,14 @@ last_day("1997-12-1")+0 select last_day("1997-12-1")+0.0; last_day("1997-12-1")+0.0 19971231.0 -select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0; -strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0 +select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0 as exp; +exp 1 -select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0; -strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0 +select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0 as exp; +exp 1 -select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0; -strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0 +select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0 as exp; +exp 1 select strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0; strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0 @@ -1239,8 +1239,8 @@ set time_zone= @@global.time_zone; select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE 22:10:00 -select str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute; -str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute +select str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute as exp; +exp NULL Warnings: Warning 1292 Truncated incorrect date value: '1997-00-04 22:23:00' @@ -1310,8 +1310,8 @@ DATE_ADD(20071108, INTERVAL 1 DAY) select LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND; LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND 2007-12-30 23:59:59 -select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond); -date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond) +select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond) as exp; +exp 1000-01-02 03:02:01.050000 select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond); date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond) @@ -1756,8 +1756,8 @@ UNIX_TIMESTAMP('2015-06-00') NULL Warnings: Warning 1292 Incorrect datetime value: '2015-06-00' -SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')); -UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')) +SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')) as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '0000-00-00 10:30:30' for function str_to_date @@ -1775,8 +1775,8 @@ UNIX_TIMESTAMP('2015-06-00') NULL Warnings: Warning 1292 Incorrect datetime value: '2015-06-00' -SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')); -UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')) +SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')) as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '0000-00-00 10:30:30' for function str_to_date @@ -1847,8 +1847,8 @@ cast('131415.123e0' as time) NULL Warnings: Warning 1292 Incorrect time value: '131415.123e0' -select cast('2010-01-02 03:04:05' as datetime) between null and '2010-01-02 03:04:04'; -cast('2010-01-02 03:04:05' as datetime) between null and '2010-01-02 03:04:04' +select cast('2010-01-02 03:04:05' as datetime) between null and '2010-01-02 03:04:04' as exp; +exp 0 select least(time('1:2:3'), '01:02:04', null) div 1; least(time('1:2:3'), '01:02:04', null) div 1 @@ -1902,8 +1902,9 @@ f2 0 drop table t1; SET timestamp=unix_timestamp('2001-02-03 10:20:30'); -select convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow'); -convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow') +select convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' +as datetime)), 'UTC', 'Europe/Moscow') as exp; +exp NULL SET timestamp=DEFAULT; create table t1 (f1 integer, f2 date); @@ -1972,17 +1973,17 @@ SET timestamp=UNIX_TIMESTAMP('2014-06-01 10:20:30'); select greatest(cast("0-0-0" as date), cast("10:20:05" as time)); greatest(cast("0-0-0" as date), cast("10:20:05" as time)) 2014-06-01 10:20:05 -select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00'; -greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00' +select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00' as exp; +exp 0 -select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01'; -greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01' +select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01' as exp; +exp 0 -select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01 10:20:05'; -greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01 10:20:05' +select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01 10:20:05' as exp; +exp 1 -select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6)); -cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6)) +select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6)) as exp; +exp 2014-06-01 10:20:05.000000 SET timestamp=DEFAULT; select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010'); @@ -3016,66 +3017,66 @@ Warning 1292 Truncated incorrect time value: '-1441:00:00' # CREATE TABLE t1 (d DATE); INSERT INTO t1 VALUES ('2005-07-20'),('2012-12-21'); -SELECT REPLACE( ADDDATE( d, INTERVAL 0.6732771076944444 HOUR_SECOND ), '2', 'x' ) FROM t1; -REPLACE( ADDDATE( d, INTERVAL 0.6732771076944444 HOUR_SECOND ), '2', 'x' ) +SELECT REPLACE( ADDDATE( d, INTERVAL 0.6732771076944444 HOUR_SECOND ), '2', 'x' ) as exp FROM t1; +exp NULL NULL Warnings: Warning 1441 Datetime function: datetime field overflow Warning 1441 Datetime function: datetime field overflow -SELECT REPLACE( ADDDATE( d, INTERVAL '0.6732771076944444' HOUR_SECOND ), '2', 'x' ) FROM t1; -REPLACE( ADDDATE( d, INTERVAL '0.6732771076944444' HOUR_SECOND ), '2', 'x' ) +SELECT REPLACE( ADDDATE( d, INTERVAL '0.6732771076944444' HOUR_SECOND ), '2', 'x' ) as exp FROM t1; +exp NULL NULL Warnings: Warning 1441 Datetime function: datetime field overflow Warning 1441 Datetime function: datetime field overflow -SELECT CAST(ADDDATE( d, INTERVAL 6732771076944444 SECOND) AS CHAR) FROM t1; -CAST(ADDDATE( d, INTERVAL 6732771076944444 SECOND) AS CHAR) +SELECT CAST(ADDDATE( d, INTERVAL 6732771076944444 SECOND) AS CHAR) as exp FROM t1; +exp NULL NULL Warnings: Warning 1441 Datetime function: datetime field overflow Warning 1441 Datetime function: datetime field overflow -SELECT CAST(ADDDATE( d, INTERVAL '67327710769444:44' HOUR_SECOND) AS CHAR) FROM t1; -CAST(ADDDATE( d, INTERVAL '67327710769444:44' HOUR_SECOND) AS CHAR) +SELECT CAST(ADDDATE( d, INTERVAL '67327710769444:44' HOUR_SECOND) AS CHAR) as exp FROM t1; +exp NULL NULL Warnings: Warning 1441 Datetime function: datetime field overflow Warning 1441 Datetime function: datetime field overflow -SELECT CAST(ADDDATE( d, INTERVAL '673277107694:44:44' HOUR_SECOND) AS CHAR) FROM t1; -CAST(ADDDATE( d, INTERVAL '673277107694:44:44' HOUR_SECOND) AS CHAR) +SELECT CAST(ADDDATE( d, INTERVAL '673277107694:44:44' HOUR_SECOND) AS CHAR) as exp FROM t1; +exp NULL NULL Warnings: Warning 1441 Datetime function: datetime field overflow Warning 1441 Datetime function: datetime field overflow DROP TABLE t1; -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '3652423:23:59:59' DAY_SECOND); -ADDDATE(DATE'0000-01-01', INTERVAL '3652423:23:59:59' DAY_SECOND) +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '3652423:23:59:59' DAY_SECOND) as exp; +exp 9999-12-31 23:59:59 -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:59:59' DAY_SECOND); -ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:59:59' DAY_SECOND) +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:59:59' DAY_SECOND) as exp; +exp 9999-12-31 23:59:59 -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:59' DAY_SECOND); -ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:59' DAY_SECOND) +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:59' DAY_SECOND) as exp; +exp 9999-12-31 23:59:59 -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:0:315569433599' DAY_SECOND); -ADDDATE(DATE'0000-01-01', INTERVAL '0:0:0:315569433599' DAY_SECOND) +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:0:315569433599' DAY_SECOND) as exp; +exp 9999-12-31 23:59:59 -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '3652423:0:0:315569433559' DAY_SECOND); -ADDDATE(DATE'0000-01-01', INTERVAL '3652423:0:0:315569433559' DAY_SECOND) +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '3652423:0:0:315569433559' DAY_SECOND) as exp; +exp NULL Warnings: Warning 1441 Datetime function: datetime field overflow -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:0:315569433559' DAY_SECOND); -ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:0:315569433559' DAY_SECOND) +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:0:315569433559' DAY_SECOND) as exp; +exp NULL Warnings: Warning 1441 Datetime function: datetime field overflow -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:315569433599' DAY_SECOND); -ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:315569433599' DAY_SECOND) +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:315569433599' DAY_SECOND) as exp; +exp NULL Warnings: Warning 1441 Datetime function: datetime field overflow @@ -3098,8 +3099,8 @@ NULL Warnings: Warning 1441 Datetime function: datetime field overflow DROP TABLE t1; -SELECT CONCAT(DATE_SUB(TIMESTAMP'1970-01-01 00:00:00', INTERVAL 17300000 HOUR)); -CONCAT(DATE_SUB(TIMESTAMP'1970-01-01 00:00:00', INTERVAL 17300000 HOUR)) +SELECT CONCAT(DATE_SUB(TIMESTAMP'1970-01-01 00:00:00', INTERVAL 17300000 HOUR)) as exp; +exp NULL Warnings: Warning 1441 Datetime function: datetime field overflow diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test index 9aa45342236..fb184ab4e16 100644 --- a/mysql-test/main/func_time.test +++ b/mysql-test/main/func_time.test @@ -12,10 +12,7 @@ select from_days(to_days("960101")),to_days(960201)-to_days("19960101"),to_days( select period_add("9602",-12),period_diff(199505,"9404") ; select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now()); -#enable after fix MDEV-27871 ---disable_view_protocol -select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0; ---enable_view_protocol +select from_unixtime(unix_timestamp("1994-03-02 10:11:12")) as e1,from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s") as e2,from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0 as e3; select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"), sec_to_time(time_to_sec("0:30:47")/6.21); select sec_to_time(9001.1), time_to_sec('15:12:22.123456'), time_to_sec(15.5566778899); @@ -27,14 +24,11 @@ select sec_to_time(-9001.1), sec_to_time(-9001.1) / 1, select sec_to_time(90011e-1), sec_to_time(1234567890123e30); select sec_to_time(1234567890123), sec_to_time('99999999999999999999999999999'); select now()-curdate()*1000000-curtime(); -#enable after fix MDEV-27871 ---disable_view_protocol -select strcmp(current_timestamp(),concat(current_date()," ",current_time())); -select strcmp(localtime(),concat(current_date()," ",current_time())); -select strcmp(localtimestamp(),concat(current_date()," ",current_time())); -select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w"); -select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w")); ---enable_view_protocol +select strcmp(current_timestamp(),concat(current_date()," ",current_time())) as exp; +select strcmp(localtime(),concat(current_date()," ",current_time())) as exp; +select strcmp(localtimestamp(),concat(current_date()," ",current_time())) as exp; +select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w") as exp; +select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w")) as exp; select dayofmonth("1997-01-02"),dayofmonth(19970323); select month("1997-01-02"),year("98-02-03"),dayofyear("1997-12-31"); select month("2001-02-00"),year("2001-00-00"); @@ -84,11 +78,8 @@ select time_format(000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(199801310000 select time_format(010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); select time_format(131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); select time_format(010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); -#enable after fix MDEV-27871 ---disable_view_protocol -select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w'); -select date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w'); ---enable_view_protocol +select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w') as exp; +select date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w') as exp; select date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND); select date_add("1997-12-31 23:59:59",INTERVAL 1 MINUTE); select date_add("1997-12-31 23:59:59",INTERVAL 1 HOUR); @@ -127,12 +118,9 @@ select date_add("1997-12-31 23:59:59",INTERVAL "10000:1" MINUTE_SECOND); select date_add("1997-12-31 23:59:59",INTERVAL "-10000:1" HOUR_MINUTE); select date_add("1997-12-31 23:59:59",INTERVAL "10000:1" DAY_HOUR); select date_add("1997-12-31 23:59:59",INTERVAL "-100 1" YEAR_MONTH); -#enable after fix MDEV-27871 ---disable_view_protocol -select date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND); -select date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE); -select date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND); ---enable_view_protocol +select date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND) as exp; +select date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE) as exp; +select date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND) as exp; select "1997-12-31 23:59:59" + INTERVAL 1 SECOND; select INTERVAL 1 DAY + "1997-12-31"; select "1998-01-01 00:00:00" - INTERVAL 1 SECOND; @@ -181,21 +169,15 @@ SELECT EXTRACT(QUARTER FROM '2004-12-15') AS quarter; # # MySQL Bugs: #12356: DATE_SUB or DATE_ADD incorrectly returns null # -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE); -SELECT DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE); ---enable_view_protocol +SELECT DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE) as exp; +SELECT DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE) as exp; # # Test big intervals (Bug #3498) # SELECT "1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND; SELECT "1900-01-01 00:00:00" + INTERVAL "1:2147483647" MINUTE_SECOND; -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT "1900-01-01 00:00:00" + INTERVAL "100000000:214748364700" MINUTE_SECOND; ---disable_view_protocol +SELECT "1900-01-01 00:00:00" + INTERVAL "100000000:214748364700" MINUTE_SECOND as exp; SELECT "1900-01-01 00:00:00" + INTERVAL 1<<37 SECOND; SELECT "1900-01-01 00:00:00" + INTERVAL 1<<31 MINUTE; SELECT "1900-01-01 00:00:00" + INTERVAL 1<<20 HOUR; @@ -203,7 +185,7 @@ SELECT "1900-01-01 00:00:00" + INTERVAL 1<<20 HOUR; SELECT "1900-01-01 00:00:00" + INTERVAL 1<<38 SECOND; SELECT "1900-01-01 00:00:00" + INTERVAL 1<<33 MINUTE; SELECT "1900-01-01 00:00:00" + INTERVAL 1<<30 HOUR; -SELECT "1900-01-01 00:00:00" + INTERVAL "1000000000:214748364700" MINUTE_SECOND; +SELECT "1900-01-01 00:00:00" + INTERVAL "1000000000:214748364700" MINUTE_SECOND as exp; # # Bug #614 (multiple extracts in where) @@ -445,12 +427,9 @@ select last_day("1997-12-1")+0.0; # Test SAPDB UTC_% functions. This part is TZ dependant (It is supposed that # TZ variable set to GMT-3 -#enable after fix MDEV-27871 ---disable_view_protocol -select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0; -select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0; -select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0; ---enable_view_protocol +select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0 as exp; +select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0 as exp; +select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0 as exp; select strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0; select strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0; select strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0; @@ -755,10 +734,7 @@ set time_zone= @@global.time_zone; # select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; -#enable after fix MDEV-27871 ---disable_view_protocol -select str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute; ---enable_view_protocol +select str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute as exp; # # Bug #21103: DATE column not compared as DATE @@ -848,10 +824,7 @@ select LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND; # show that we treat fractions of seconds correctly (zerofill from right to # six places) even if we left out fields on the left. -#enable after fix MDEV-27871 ---disable_view_protocol -select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond); ---enable_view_protocol +select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond) as exp; select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond); @@ -1092,19 +1065,13 @@ SET timestamp=DEFAULT; SELECT UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%m")); SELECT UNIX_TIMESTAMP('2015-06-00'); -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')); ---enable_view_protocol +SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')) as exp; set sql_mode= 'TRADITIONAL'; SELECT @@sql_mode; SELECT UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%m")); SELECT UNIX_TIMESTAMP('2015-06-00'); -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')); ---enable_view_protocol +SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')) as exp; set sql_mode= default; @@ -1133,10 +1100,7 @@ select time('10 02:03:04') + interval 1 year; # specially constructed queries to reach obscure places in the code # not touched by the more "normal" queries (and to increase the coverage) select cast('131415.123e0' as time); -#enable after fix MDEV-27871 ---disable_view_protocol -select cast('2010-01-02 03:04:05' as datetime) between null and '2010-01-02 03:04:04'; ---enable_view_protocol +select cast('2010-01-02 03:04:05' as datetime) between null and '2010-01-02 03:04:04' as exp; select least(time('1:2:3'), '01:02:04', null) div 1; select truncate(least(time('1:2:3'), '01:02:04', null), 6); select cast(least(time('1:2:3'), '01:02:04', null) as decimal(3,1)); @@ -1173,12 +1137,10 @@ drop table t1; # # lp:731815 Crash/valgrind warning Item::send with 5.1-micro # -#enable after fix MDEV-27871 ---disable_view_protocol SET timestamp=unix_timestamp('2001-02-03 10:20:30'); -select convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow'); +select convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' +as datetime)), 'UTC', 'Europe/Moscow') as exp; SET timestamp=DEFAULT; ---enable_view_protocol # # lp:736370 Datetime functions in subquery context cause wrong result and bogus warnings in mysql-5.1-micr @@ -1249,13 +1211,10 @@ drop table t1; SET timestamp=UNIX_TIMESTAMP('2014-06-01 10:20:30'); select greatest(cast("0-0-0" as date), cast("10:20:05" as time)); -#enable after fix MDEV-27871 ---disable_view_protocol -select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00'; -select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01'; -select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01 10:20:05'; -select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6)); ---enable_view_protocol +select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00' as exp; +select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01' as exp; +select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01 10:20:05' as exp; +select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6)) as exp; SET timestamp=DEFAULT; select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010'); @@ -1854,28 +1813,25 @@ SELECT --echo # --echo # MDEV-10787 Assertion `ltime->neg == 0' failed in void date_to_datetime(MYSQL_TIME*) --echo # -#enable after fix MDEV-27871 ---disable_view_protocol CREATE TABLE t1 (d DATE); INSERT INTO t1 VALUES ('2005-07-20'),('2012-12-21'); -SELECT REPLACE( ADDDATE( d, INTERVAL 0.6732771076944444 HOUR_SECOND ), '2', 'x' ) FROM t1; -SELECT REPLACE( ADDDATE( d, INTERVAL '0.6732771076944444' HOUR_SECOND ), '2', 'x' ) FROM t1; -SELECT CAST(ADDDATE( d, INTERVAL 6732771076944444 SECOND) AS CHAR) FROM t1; -SELECT CAST(ADDDATE( d, INTERVAL '67327710769444:44' HOUR_SECOND) AS CHAR) FROM t1; -SELECT CAST(ADDDATE( d, INTERVAL '673277107694:44:44' HOUR_SECOND) AS CHAR) FROM t1; +SELECT REPLACE( ADDDATE( d, INTERVAL 0.6732771076944444 HOUR_SECOND ), '2', 'x' ) as exp FROM t1; +SELECT REPLACE( ADDDATE( d, INTERVAL '0.6732771076944444' HOUR_SECOND ), '2', 'x' ) as exp FROM t1; +SELECT CAST(ADDDATE( d, INTERVAL 6732771076944444 SECOND) AS CHAR) as exp FROM t1; +SELECT CAST(ADDDATE( d, INTERVAL '67327710769444:44' HOUR_SECOND) AS CHAR) as exp FROM t1; +SELECT CAST(ADDDATE( d, INTERVAL '673277107694:44:44' HOUR_SECOND) AS CHAR) as exp FROM t1; DROP TABLE t1; # Maximum possible DAY_SECOND values in various formats -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '3652423:23:59:59' DAY_SECOND); -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:59:59' DAY_SECOND); -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:59' DAY_SECOND); -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:0:315569433599' DAY_SECOND); +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '3652423:23:59:59' DAY_SECOND) as exp; +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:59:59' DAY_SECOND) as exp; +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:59' DAY_SECOND) as exp; +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:0:315569433599' DAY_SECOND) as exp; # Out-of-range INTERVAL DAY_SECOND values -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '3652423:0:0:315569433559' DAY_SECOND); -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:0:315569433559' DAY_SECOND); -SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:315569433599' DAY_SECOND); ---disable_view_protocol +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '3652423:0:0:315569433559' DAY_SECOND) as exp; +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:0:315569433559' DAY_SECOND) as exp; +SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:315569433599' DAY_SECOND) as exp; --echo # --echo # MDEV-13202 Assertion `ltime->neg == 0' failed in date_to_datetime @@ -1891,7 +1847,7 @@ INSERT INTO t1 VALUES (1, '1970-01-01'); SELECT CONCAT(DATE_SUB(d, INTERVAL 17300000 HOUR)) FROM t1; DROP TABLE t1; -SELECT CONCAT(DATE_SUB(TIMESTAMP'1970-01-01 00:00:00', INTERVAL 17300000 HOUR)); +SELECT CONCAT(DATE_SUB(TIMESTAMP'1970-01-01 00:00:00', INTERVAL 17300000 HOUR)) as exp; --echo # diff --git a/mysql-test/main/gis-json.result b/mysql-test/main/gis-json.result index 644684f5a73..4ea2fec7674 100644 --- a/mysql-test/main/gis-json.result +++ b/mysql-test/main/gis-json.result @@ -1,44 +1,44 @@ -select st_asgeojson(geomfromtext('POINT(1 1)')); -st_asgeojson(geomfromtext('POINT(1 1)')) +select st_asgeojson(geomfromtext('POINT(1 1)')) as exp; +exp {"type": "Point", "coordinates": [1, 1]} -select st_asgeojson(geomfromtext('LINESTRING(10 10,20 10,20 20,10 20,10 10)')); -st_asgeojson(geomfromtext('LINESTRING(10 10,20 10,20 20,10 20,10 10)')) +select st_asgeojson(geomfromtext('LINESTRING(10 10,20 10,20 20,10 20,10 10)')) as exp; +exp {"type": "LineString", "coordinates": [[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]} -select st_asgeojson(geomfromtext('POLYGON((10 10,20 10,20 20,10 20,10 10))')); -st_asgeojson(geomfromtext('POLYGON((10 10,20 10,20 20,10 20,10 10))')) +select st_asgeojson(geomfromtext('POLYGON((10 10,20 10,20 20,10 20,10 10))')) as exp; +exp {"type": "Polygon", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]} -select st_asgeojson(geomfromtext('MULTIPOLYGON(((10 10,20 10,20 20,10 20,10 10)))')); -st_asgeojson(geomfromtext('MULTIPOLYGON(((10 10,20 10,20 20,10 20,10 10)))')) +select st_asgeojson(geomfromtext('MULTIPOLYGON(((10 10,20 10,20 20,10 20,10 10)))')) as exp; +exp {"type": "MultiPolygon", "coordinates": [[[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]]} -select st_asgeojson(geomfromtext('multilinestring((10 10,20 10,20 20,10 20,10 10))')); -st_asgeojson(geomfromtext('multilinestring((10 10,20 10,20 20,10 20,10 10))')) +select st_asgeojson(geomfromtext('multilinestring((10 10,20 10,20 20,10 20,10 10))')) as exp; +exp {"type": "MultiLineString", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]} -select st_asgeojson(geomfromtext('multipoint(10 10,20 10,20 20,10 20,10 10)')); -st_asgeojson(geomfromtext('multipoint(10 10,20 10,20 20,10 20,10 10)')) +select st_asgeojson(geomfromtext('multipoint(10 10,20 10,20 20,10 20,10 10)')) as exp; +exp {"type": "MultiPoint", "coordinates": [[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]} -select st_asgeojson(st_geomfromtext('GEOMETRYCOLLECTION(POINT(100 0),LINESTRING(101 0,102 1))')); -st_asgeojson(st_geomfromtext('GEOMETRYCOLLECTION(POINT(100 0),LINESTRING(101 0,102 1))')) +select st_asgeojson(st_geomfromtext('GEOMETRYCOLLECTION(POINT(100 0),LINESTRING(101 0,102 1))')) as exp; +exp {"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [100, 0]}, {"type": "LineString", "coordinates": [[101, 0], [102, 1]]}]} -SELECT st_astext(st_geomfromgeojson('{"type":"point","coordinates":[1,2]}')); -st_astext(st_geomfromgeojson('{"type":"point","coordinates":[1,2]}')) +SELECT st_astext(st_geomfromgeojson('{"type":"point","coordinates":[1,2]}')) as exp; +exp POINT(1 2) -SELECT st_astext(st_geomfromgeojson('{"type":"LineString","coordinates":[[1,2],[4,5],[7,8]]}')); -st_astext(st_geomfromgeojson('{"type":"LineString","coordinates":[[1,2],[4,5],[7,8]]}')) +SELECT st_astext(st_geomfromgeojson('{"type":"LineString","coordinates":[[1,2],[4,5],[7,8]]}')) as exp; +exp LINESTRING(1 2,4 5,7 8) -SELECT st_astext(st_geomfromgeojson('{"type": "polygon", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')); -st_astext(st_geomfromgeojson('{"type": "polygon", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')) +SELECT st_astext(st_geomfromgeojson('{"type": "polygon", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')) as exp; +exp POLYGON((10 10,20 10,20 20,10 20,10 10)) -SELECT st_astext(st_geomfromgeojson('{"type":"multipoint","coordinates":[[1,2],[4,5],[7,8]]}')); -st_astext(st_geomfromgeojson('{"type":"multipoint","coordinates":[[1,2],[4,5],[7,8]]}')) +SELECT st_astext(st_geomfromgeojson('{"type":"multipoint","coordinates":[[1,2],[4,5],[7,8]]}')) as exp; +exp MULTIPOINT(1 2,4 5,7 8) -SELECT st_astext(st_geomfromgeojson('{"type": "multilinestring", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')); -st_astext(st_geomfromgeojson('{"type": "multilinestring", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')) +SELECT st_astext(st_geomfromgeojson('{"type": "multilinestring", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')) as exp; +exp MULTILINESTRING((10 10,20 10,20 20,10 20,10 10)) -SELECT st_astext(st_geomfromgeojson('{"type": "multipolygon", "coordinates": [[[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]]}')); -st_astext(st_geomfromgeojson('{"type": "multipolygon", "coordinates": [[[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]]}')) +SELECT st_astext(st_geomfromgeojson('{"type": "multipolygon", "coordinates": [[[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]]}')) as exp; +exp MULTIPOLYGON(((10 10,20 10,20 20,10 20,10 10))) -SELECT st_astext(st_geomfromgeojson('{"type": "GeometryCollection", "geometries": [{"type": "Point","coordinates": [100.0, 0.0]}, {"type": "LineString","coordinates": [[101.0, 0.0],[102.0, 1.0]]}]}')); -st_astext(st_geomfromgeojson('{"type": "GeometryCollection", "geometries": [{"type": "Point","coordinates": [100.0, 0.0]}, {"type": "LineString","coordinates": [[101.0, 0.0],[102.0, 1.0]]}]}')) +SELECT st_astext(st_geomfromgeojson('{"type": "GeometryCollection", "geometries": [{"type": "Point","coordinates": [100.0, 0.0]}, {"type": "LineString","coordinates": [[101.0, 0.0],[102.0, 1.0]]}]}')) as exp; +exp GEOMETRYCOLLECTION(POINT(100 0),LINESTRING(101 0,102 1)) SELECT st_astext(st_geomfromgeojson('{"type":"point"}')); st_astext(st_geomfromgeojson('{"type":"point"}')) @@ -55,27 +55,27 @@ st_astext(st_geomfromgeojson('{"type""point"}')) NULL Warnings: Warning 4038 Syntax error in JSON text in argument 1 to function 'st_geomfromgeojson' at position 7 -SELECT st_astext(st_geomfromgeojson('{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] } }')); -st_astext(st_geomfromgeojson('{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] } }')) +SELECT st_astext(st_geomfromgeojson('{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] } }')) as exp; +exp POINT(102 0.5) -SELECT st_astext(st_geomfromgeojson('{ "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "type": "Feature" }')); -st_astext(st_geomfromgeojson('{ "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "type": "Feature" }')) +SELECT st_astext(st_geomfromgeojson('{ "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "type": "Feature" }')) as exp; +exp POINT(102 0.5) -SELECT st_astext(st_geomfromgeojson('{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "properties": { "prop0": "value0" } }]}')); -st_astext(st_geomfromgeojson('{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "properties": { "prop0": "value0" } }]}')) +SELECT st_astext(st_geomfromgeojson('{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "properties": { "prop0": "value0" } }]}')) as exp; +exp GEOMETRYCOLLECTION(POINT(102 0.5)) SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',5)); ERROR HY000: Incorrect option value: '5' for function ST_GeomFromGeoJSON -SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',1)); +SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',1)) as exp; ERROR 22023: Invalid GIS data provided to function ST_GeomFromGeoJSON. -SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',2)); -ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',2)) +SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',2)) as exp; +exp POINT(5.3 15) -SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',3)); -ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',3)) +SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',3)) as exp; +exp POINT(5.3 15) -SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',4)); -ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',4)) +SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',4)) as exp; +exp POINT(5.3 15) SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),2); ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),2) @@ -107,16 +107,16 @@ a NULL Warnings: Warning 4076 Incorrect GeoJSON format - empty 'coordinates' array. -SELECT ST_GEOMFROMGEOJSON("{ \"type\": \"Feature\", \"geometry\": [10, 20] }"); -ST_GEOMFROMGEOJSON("{ \"type\": \"Feature\", \"geometry\": [10, 20] }") +SELECT ST_GEOMFROMGEOJSON("{ \"type\": \"Feature\", \"geometry\": [10, 20] }") as exp; +exp NULL -SELECT ST_ASTEXT (ST_GEOMFROMGEOJSON ('{ "type": "GEOMETRYCOLLECTION", "coordinates": [102.0, 0.0]}')); -ST_ASTEXT (ST_GEOMFROMGEOJSON ('{ "type": "GEOMETRYCOLLECTION", "coordinates": [102.0, 0.0]}')) +SELECT ST_ASTEXT (ST_GEOMFROMGEOJSON ('{ "type": "GEOMETRYCOLLECTION", "coordinates": [102.0, 0.0]}')) as exp; +exp NULL Warnings: Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function. -SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type": ["POINT"], "coINates": [0,0] }')); -ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type": ["POINT"], "coINates": [0,0] }')) +SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type": ["POINT"], "coINates": [0,0] }')) as exp; +exp NULL Warnings: Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function. diff --git a/mysql-test/main/gis-json.test b/mysql-test/main/gis-json.test index cda395acab5..766a036609c 100644 --- a/mysql-test/main/gis-json.test +++ b/mysql-test/main/gis-json.test @@ -1,46 +1,39 @@ -- source include/have_geometry.inc -#enable after fix MDEV-27871 ---disable_view_protocol -select st_asgeojson(geomfromtext('POINT(1 1)')); -select st_asgeojson(geomfromtext('LINESTRING(10 10,20 10,20 20,10 20,10 10)')); -select st_asgeojson(geomfromtext('POLYGON((10 10,20 10,20 20,10 20,10 10))')); -select st_asgeojson(geomfromtext('MULTIPOLYGON(((10 10,20 10,20 20,10 20,10 10)))')); -select st_asgeojson(geomfromtext('multilinestring((10 10,20 10,20 20,10 20,10 10))')); -select st_asgeojson(geomfromtext('multipoint(10 10,20 10,20 20,10 20,10 10)')); -select st_asgeojson(st_geomfromtext('GEOMETRYCOLLECTION(POINT(100 0),LINESTRING(101 0,102 1))')); +select st_asgeojson(geomfromtext('POINT(1 1)')) as exp; +select st_asgeojson(geomfromtext('LINESTRING(10 10,20 10,20 20,10 20,10 10)')) as exp; +select st_asgeojson(geomfromtext('POLYGON((10 10,20 10,20 20,10 20,10 10))')) as exp; +select st_asgeojson(geomfromtext('MULTIPOLYGON(((10 10,20 10,20 20,10 20,10 10)))')) as exp; +select st_asgeojson(geomfromtext('multilinestring((10 10,20 10,20 20,10 20,10 10))')) as exp; +select st_asgeojson(geomfromtext('multipoint(10 10,20 10,20 20,10 20,10 10)')) as exp; +select st_asgeojson(st_geomfromtext('GEOMETRYCOLLECTION(POINT(100 0),LINESTRING(101 0,102 1))')) as exp; -SELECT st_astext(st_geomfromgeojson('{"type":"point","coordinates":[1,2]}')); -SELECT st_astext(st_geomfromgeojson('{"type":"LineString","coordinates":[[1,2],[4,5],[7,8]]}')); -SELECT st_astext(st_geomfromgeojson('{"type": "polygon", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')); -SELECT st_astext(st_geomfromgeojson('{"type":"multipoint","coordinates":[[1,2],[4,5],[7,8]]}')); -SELECT st_astext(st_geomfromgeojson('{"type": "multilinestring", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')); -SELECT st_astext(st_geomfromgeojson('{"type": "multipolygon", "coordinates": [[[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]]}')); -SELECT st_astext(st_geomfromgeojson('{"type": "GeometryCollection", "geometries": [{"type": "Point","coordinates": [100.0, 0.0]}, {"type": "LineString","coordinates": [[101.0, 0.0],[102.0, 1.0]]}]}')); ---enable_view_protocol +SELECT st_astext(st_geomfromgeojson('{"type":"point","coordinates":[1,2]}')) as exp; +SELECT st_astext(st_geomfromgeojson('{"type":"LineString","coordinates":[[1,2],[4,5],[7,8]]}')) as exp; +SELECT st_astext(st_geomfromgeojson('{"type": "polygon", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')) as exp; +SELECT st_astext(st_geomfromgeojson('{"type":"multipoint","coordinates":[[1,2],[4,5],[7,8]]}')) as exp; +SELECT st_astext(st_geomfromgeojson('{"type": "multilinestring", "coordinates": [[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]}')) as exp; +SELECT st_astext(st_geomfromgeojson('{"type": "multipolygon", "coordinates": [[[[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]]]}')) as exp; +SELECT st_astext(st_geomfromgeojson('{"type": "GeometryCollection", "geometries": [{"type": "Point","coordinates": [100.0, 0.0]}, {"type": "LineString","coordinates": [[101.0, 0.0],[102.0, 1.0]]}]}')) as exp; SELECT st_astext(st_geomfromgeojson('{"type":"point"}')); SELECT st_astext(st_geomfromgeojson('{"type":"point"')); SELECT st_astext(st_geomfromgeojson('{"type""point"}')); -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT st_astext(st_geomfromgeojson('{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] } }')); -SELECT st_astext(st_geomfromgeojson('{ "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "type": "Feature" }')); -SELECT st_astext(st_geomfromgeojson('{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "properties": { "prop0": "value0" } }]}')); +SELECT st_astext(st_geomfromgeojson('{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] } }')) as exp; +SELECT st_astext(st_geomfromgeojson('{ "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "type": "Feature" }')) as exp; +SELECT st_astext(st_geomfromgeojson('{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "properties": { "prop0": "value0" } }]}')) as exp; --error ER_WRONG_VALUE_FOR_TYPE SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',5)); --error ER_GIS_INVALID_DATA -SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',1)); +SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',1)) as exp; -SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',2)); -SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',3)); -SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',4)); - ---enable_view_protocol +SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',2)) as exp; +SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',3)) as exp; +SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',4)) as exp; SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),2); SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),1); @@ -53,20 +46,15 @@ SELECT st_astext(st_geomfromgeojson('{"type": "MultiLineString","coordinates": [ SELECT st_astext(st_geomfromgeojson('{"type": "Polygon","coordinates": []}')) as a; SELECT st_astext(st_geomfromgeojson('{"type": "MultiPolygon","coordinates": []}')) as a; -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT ST_GEOMFROMGEOJSON("{ \"type\": \"Feature\", \"geometry\": [10, 20] }"); +SELECT ST_GEOMFROMGEOJSON("{ \"type\": \"Feature\", \"geometry\": [10, 20] }") as exp; # # MDEV-25461 Assertion `je->state == JST_KEY' failed in Geometry::create_from_json. # -SELECT ST_ASTEXT (ST_GEOMFROMGEOJSON ('{ "type": "GEOMETRYCOLLECTION", "coordinates": [102.0, 0.0]}')); - -SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type": ["POINT"], "coINates": [0,0] }')); - ---enable_view_protocol +SELECT ST_ASTEXT (ST_GEOMFROMGEOJSON ('{ "type": "GEOMETRYCOLLECTION", "coordinates": [102.0, 0.0]}')) as exp; +SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type": ["POINT"], "coINates": [0,0] }')) as exp; --echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/gis.result b/mysql-test/main/gis.result index 5b323bb598c..99d41aad0f5 100644 --- a/mysql-test/main/gis.result +++ b/mysql-test/main/gis.result @@ -463,8 +463,8 @@ gc geometrycollection YES NULL gm geometry YES NULL fid int(11) NO NULL DROP TABLE t1; -SELECT AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)')))); -AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)')))) +SELECT AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)')))) as exp; +exp POINT(1 4) explain extended SELECT AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)')))); id select_type table type possible_keys key key_len ref rows filtered Extra @@ -696,11 +696,11 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field insert into t1 values (pointfromtext('point(1,1)')); ERROR 23000: Column 'fl' cannot be null drop table t1; -select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))); -(asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))) +select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))) as exp; +exp POINT(10 10) -select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))); -(asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))) +select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))) as exp; +exp POINT(10 10) create table t1 (g GEOMETRY); select * from t1; @@ -1135,30 +1135,30 @@ NULL select envelope(0x0100000000030000000100000000000010); envelope(0x0100000000030000000100000000000010) NULL -select geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1); -geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1) +select geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1) as exp; +exp NULL -select geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1); -geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1) +select geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1) as exp; +exp NULL # # MDEV-4296 Assertion `n_linear_rings > 0' fails in Gis_polygon::centroid_xy # -SELECT Centroid( AsBinary( LineString(Point(0,0), Point(0,0), Point(0,0) ))); -Centroid( AsBinary( LineString(Point(0,0), Point(0,0), Point(0,0) ))) +SELECT Centroid( AsBinary( LineString(Point(0,0), Point(0,0), Point(0,0) ))) as exp; +exp NULL # # MDEV-4295 Server crashes in get_point on a query with Area, AsBinary, MultiPoint # -SELECT Area(AsBinary(MultiPoint(Point(0,9), Point(0,1), Point(2,2)))); -Area(AsBinary(MultiPoint(Point(0,9), Point(0,1), Point(2,2)))) +SELECT Area(AsBinary(MultiPoint(Point(0,9), Point(0,1), Point(2,2)))) as exp; +exp NULL End of 5.1 tests -select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))')); -ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))')) +select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))')) as exp; +exp 1.5 -select ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))')); -ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))')) +select ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))')) as exp; +exp 160 DROP DATABASE IF EXISTS gis_ogs; CREATE DATABASE gis_ogs; @@ -1369,16 +1369,16 @@ FROM road_segments WHERE fid = 102; AsText(EndPoint(centerline)) POINT(44 31) -SELECT IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) +SELECT IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) as exp FROM named_places WHERE name = 'Goose Island'; -IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) +exp 1 # Conformance Item T20 -SELECT IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) +SELECT IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) as exp FROM named_places WHERE name = 'Goose Island'; -IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) +exp 1 # Conformance Item T21 SELECT GLength(centerline) @@ -1477,11 +1477,10 @@ Area(shores) 8 # Conformance Item T37 SELECT ST_Equals(boundary, -PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1)) +PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1)) as exp FROM named_places WHERE name = 'Goose Island'; -ST_Equals(boundary, -PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1)) +exp 1 # Conformance Item T38 SELECT ST_Disjoint(centerlines, boundary) @@ -1519,11 +1518,11 @@ AND divided_routes.name = 'Route 75'; Crosses(road_segments.centerline, divided_routes.centerlines) 1 # Conformance Item T43 -SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines) +SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines) as exp FROM road_segments, divided_routes WHERE road_segments.fid = 102 AND divided_routes.name = 'Route 75'; -ST_Intersects(road_segments.centerline, divided_routes.centerlines) +exp 1 # Conformance Item T44 SELECT ST_Contains(forests.boundary, named_places.boundary) @@ -1594,21 +1593,15 @@ select st_distance(geomfromtext('LINESTRING(-95.9673005697771 36.13509598461, -95.9673057475387 36.1344478941074, -95.9673063519371 36.134484524621, -95.9673049102515 36.1343976584193)'), -geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)')) ; -st_distance(geomfromtext('LINESTRING(-95.9673005697771 36.13509598461, - -95.9673057475387 36.1344478941074, - -95.9673063519371 36.134484524621, - +geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)')) as exp ; +exp 0.008148695928146028 select st_distance(geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)'), geomfromtext('LINESTRING(-95.9673005697771 36.13509598461, -95.9673057475387 36.1344478941074, -95.9673063519371 36.134484524621, - -95.9673049102515 36.1343976584193) ')) ; -st_distance(geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)'), -geomfromtext('LINESTRING(-95.9673005697771 36.13509598461, - -95.9673057475387 36.1344478941074, - -95.9673063519371 36. + -95.9673049102515 36.1343976584193) ')) as exp ; +exp 0.008148695928146028 # # MDEV-4310 geometry function equals hangs forever. @@ -1670,13 +1663,13 @@ ENVELOPE(0x0100000000030000000100000000000010) NULL #should not crash SELECT -GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffff0000, 1); -GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffff0000, 1) +GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffff0000, 1) as exp; +exp NULL #should not crash SELECT -GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1); -GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1) +GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1) as exp; +exp NULL # # MDEV-3819 missing constraints for spatial column types @@ -1685,8 +1678,8 @@ create table t1 (pt point); insert into t1 values(Geomfromtext('POLYGON((1 1, 2 2, 2 1, 1 1))')); ERROR 22007: Incorrect POINT value: 'POLYGON((1 1,2 2,2 1,1 1))' for column `test`.`t1`.`pt` at row 1 drop table t1; -SELECT st_astext(ST_Buffer(ST_PolygonFromText('POLYGON((3 5, 2 4, 2 5, 3 5))'), -100)); -st_astext(ST_Buffer(ST_PolygonFromText('POLYGON((3 5, 2 4, 2 5, 3 5))'), -100)) +SELECT st_astext(ST_Buffer(ST_PolygonFromText('POLYGON((3 5, 2 4, 2 5, 3 5))'), -100)) as exp; +exp GEOMETRYCOLLECTION EMPTY CREATE VIEW v1 AS SELECT POINT(1,1) AS p; SHOW CREATE VIEW v1; @@ -1824,14 +1817,14 @@ drop table t1; select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,0 0)')); ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,0 0)')) 1 -select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)')); -ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)')) +select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)')) as exp; +exp 0 # # MDEV-7514 GIS: PointOnSurface returns NULL instead of the point. # -SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))'))); -ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))'))) +SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))'))) as exp; +exp NULL # # MDEV-7529 GIS: ST_Relate returns unexpected results for POINT relations diff --git a/mysql-test/main/gis.test b/mysql-test/main/gis.test index 17151b1bc86..e68b1f140b2 100644 --- a/mysql-test/main/gis.test +++ b/mysql-test/main/gis.test @@ -83,11 +83,15 @@ SELECT fid, Dimension(g) FROM gis_geometry; SELECT fid, GeometryType(g) FROM gis_geometry; SELECT fid, IsEmpty(g) FROM gis_geometry; SELECT fid, AsText(Envelope(g)) FROM gis_geometry; +--disable_view_protocol explain extended select Dimension(g), GeometryType(g), IsEmpty(g), AsText(Envelope(g)) from gis_geometry; +--enable_view_protocol SELECT fid, X(g) FROM gis_point; SELECT fid, Y(g) FROM gis_point; +--disable_view_protocol explain extended select X(g),Y(g) FROM gis_point; +--enable_view_protocol SELECT fid, AsText(StartPoint(g)) FROM gis_line; SELECT fid, AsText(EndPoint(g)) FROM gis_line; @@ -95,7 +99,9 @@ SELECT fid, GLength(g) FROM gis_line; SELECT fid, NumPoints(g) FROM gis_line; SELECT fid, AsText(PointN(g, 2)) FROM gis_line; SELECT fid, IsClosed(g) FROM gis_line; +--disable_view_protocol explain extended select AsText(StartPoint(g)),AsText(EndPoint(g)),GLength(g),NumPoints(g),AsText(PointN(g, 2)),IsClosed(g) FROM gis_line; +--enable_view_protocol SELECT fid, AsText(Centroid(g)) FROM gis_polygon; SELECT fid, Area(g) FROM gis_polygon; @@ -113,14 +119,18 @@ SELECT fid, NumGeometries(g) from gis_multi_point; SELECT fid, NumGeometries(g) from gis_multi_line; SELECT fid, NumGeometries(g) from gis_multi_polygon; SELECT fid, NumGeometries(g) from gis_geometrycollection; +--disable_view_protocol explain extended SELECT fid, NumGeometries(g) from gis_multi_point; +--enable_view_protocol SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point; SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_line; SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_polygon; SELECT fid, AsText(GeometryN(g, 2)) from gis_geometrycollection; SELECT fid, AsText(GeometryN(g, 1)) from gis_geometrycollection; +--disable_view_protocol explain extended SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point; +--enable_view_protocol #query plan for view protocol doesn't contain database name --disable_view_protocol @@ -157,13 +167,18 @@ ALTER TABLE t1 ADD fid INT NOT NULL; SHOW FIELDS FROM t1; DROP TABLE t1; -SELECT AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)')))); +SELECT AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)')))) as exp; +--disable_view_protocol explain extended SELECT AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)')))); explain extended SELECT AsText(GeometryFromWKB(AsWKB(PointFromText('POINT(1 4)')))); +--enable_view_protocol SELECT SRID(GeomFromText('LineString(1 1,2 2)',101)); + +--disable_view_protocol explain extended SELECT SRID(GeomFromText('LineString(1 1,2 2)',101)); #select issimple(MultiPoint(Point(3, 6), Point(4, 10))), issimple(Point(3, 6)),issimple(PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),issimple(GeometryFromText('POINT(1 4)')), issimple(AsWKB(GeometryFromText('POINT(1 4)'))); explain extended select issimple(MultiPoint(Point(3, 6), Point(4, 10))), issimple(Point(3, 6)); +--enable_view_protocol create table t1 (a geometry not null); insert into t1 values (GeomFromText('Point(1 2)')); @@ -380,10 +395,10 @@ insert into t1 values (pointfromtext('point(1,1)')); drop table t1; -#enable after fix MDEV-27871 +#enable after MDEV-32456 --disable_view_protocol -select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))); -select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))); +select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))) as exp; +select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))) as exp; --enable_view_protocol --enable_metadata @@ -846,30 +861,27 @@ select astext(0x0100000000030000000100000000000010); select astext(st_centroid(0x0100000000030000000100000000000010)); select astext(st_exteriorring(0x0100000000030000000100000000000010)); select envelope(0x0100000000030000000100000000000010); -#enable after fix MDEV-27871 ---disable_view_protocol -select geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1); -select geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1); +select geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1) as exp; +select geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1) as exp; --echo # --echo # MDEV-4296 Assertion `n_linear_rings > 0' fails in Gis_polygon::centroid_xy --echo # -SELECT Centroid( AsBinary( LineString(Point(0,0), Point(0,0), Point(0,0) ))); +SELECT Centroid( AsBinary( LineString(Point(0,0), Point(0,0), Point(0,0) ))) as exp; --echo # --echo # MDEV-4295 Server crashes in get_point on a query with Area, AsBinary, MultiPoint --echo # -SELECT Area(AsBinary(MultiPoint(Point(0,9), Point(0,1), Point(2,2)))); +SELECT Area(AsBinary(MultiPoint(Point(0,9), Point(0,1), Point(2,2)))) as exp; --echo End of 5.1 tests #bug 850775 ST_AREA does not work on GEOMETRYCOLLECTIONs in maria-5.3-gis -select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))')); +select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))')) as exp; #bug 855336 ST_LENGTH does not work on GEOMETRYCOLLECTIONs -select ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))')); +select ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))')) as exp; ---enable_view_protocol # Conformance tests # @@ -1178,20 +1190,15 @@ SELECT AsText(EndPoint(centerline)) FROM road_segments WHERE fid = 102; -#enable after fix MDEV-27871 ---disable_view_protocol - -SELECT IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) +SELECT IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) as exp FROM named_places WHERE name = 'Goose Island'; --echo # Conformance Item T20 -SELECT IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) +SELECT IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary))) as exp FROM named_places WHERE name = 'Goose Island'; ---enable_view_protocol - --echo # Conformance Item T21 SELECT GLength(centerline) FROM road_segments @@ -1272,15 +1279,11 @@ SELECT Area(shores) FROM ponds WHERE fid = 120; -#enable after fix MDEV-27871 ---disable_view_protocol - --echo # Conformance Item T37 SELECT ST_Equals(boundary, -PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1)) +PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1)) as exp FROM named_places WHERE name = 'Goose Island'; ---enable_view_protocol --echo # Conformance Item T38 SELECT ST_Disjoint(centerlines, boundary) @@ -1312,17 +1315,12 @@ FROM road_segments, divided_routes WHERE road_segments.fid = 102 AND divided_routes.name = 'Route 75'; -#enable after fix MDEV-27871 ---disable_view_protocol - --echo # Conformance Item T43 -SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines) +SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines) as exp FROM road_segments, divided_routes WHERE road_segments.fid = 102 AND divided_routes.name = 'Route 75'; ---enable_view_protocol - --echo # Conformance Item T44 SELECT ST_Contains(forests.boundary, named_places.boundary) FROM forests, named_places @@ -1382,20 +1380,17 @@ USE test; --echo # BUG #1043845 st_distance() results are incorrect depending on variable order --echo # -#enable after fix MDEV-27871 ---disable_view_protocol select st_distance(geomfromtext('LINESTRING(-95.9673005697771 36.13509598461, -95.9673057475387 36.1344478941074, -95.9673063519371 36.134484524621, -95.9673049102515 36.1343976584193)'), - geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)')) ; + geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)')) as exp ; select st_distance(geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)'), geomfromtext('LINESTRING(-95.9673005697771 36.13509598461, -95.9673057475387 36.1344478941074, -95.9673063519371 36.134484524621, - -95.9673049102515 36.1343976584193) ')) ; + -95.9673049102515 36.1343976584193) ')) as exp ; ---enable_view_protocol --echo # --echo # MDEV-4310 geometry function equals hangs forever. @@ -1457,16 +1452,13 @@ SELECT ASTEXT(0x0100000000030000000100000000000010); --echo #should not crash SELECT ENVELOPE(0x0100000000030000000100000000000010); -#enable after fix MDEV-27871 ---disable_view_protocol --echo #should not crash SELECT - GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffff0000, 1); + GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffff0000, 1) as exp; --echo #should not crash SELECT - GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1); ---enable_view_protocol + GEOMETRYN(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1) as exp; --echo # --echo # MDEV-3819 missing constraints for spatial column types @@ -1480,10 +1472,7 @@ drop table t1; # # MDEV-7516 Assertion `!cur_p->event' failed in Gcalc_scan_iterator::arrange_event(int, int) # -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT st_astext(ST_Buffer(ST_PolygonFromText('POLYGON((3 5, 2 4, 2 5, 3 5))'), -100)); ---enable_view_protocol +SELECT st_astext(ST_Buffer(ST_PolygonFromText('POLYGON((3 5, 2 4, 2 5, 3 5))'), -100)) as exp; # # MDEV-7779 View definition changes upon creation @@ -1579,15 +1568,12 @@ drop table t1; --echo # MDEV-7510 GIS: IsRing returns false for a primitive triangle. --echo # select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,0 0)')); -#enable after fix MDEV-27871 ---disable_view_protocol -select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)')); +select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)')) as exp; --echo # --echo # MDEV-7514 GIS: PointOnSurface returns NULL instead of the point. --echo # -SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))'))); ---enable_view_protocol +SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))'))) as exp; --echo # --echo # MDEV-7529 GIS: ST_Relate returns unexpected results for POINT relations diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result index cedaf10b3f6..a4ec3959a9b 100644 --- a/mysql-test/main/grant.result +++ b/mysql-test/main/grant.result @@ -1990,6 +1990,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 69bb050778d..52f2f78bfe1 100644 --- a/mysql-test/main/grant.test +++ b/mysql-test/main/grant.test @@ -1824,6 +1824,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/grant4.result b/mysql-test/main/grant4.result index bc38f281e8e..321eee1847d 100644 --- a/mysql-test/main/grant4.result +++ b/mysql-test/main/grant4.result @@ -101,7 +101,6 @@ ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table ** SHOW INDEX FROM t6 will succeed because there exist a privilege on a column combination on t6. SHOW INDEX FROM t6; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored -t6 1 i 1 s1 A NULL NULL NULL YES BTREE NO ** CHECK TABLE requires any privilege on any column combination and should succeed for t6: CHECK TABLE t6; Table Op Msg_type Msg_text diff --git a/mysql-test/main/group_min_max.result b/mysql-test/main/group_min_max.result index 960bfce7566..d8844fcee8a 100644 --- a/mysql-test/main/group_min_max.result +++ b/mysql-test/main/group_min_max.result @@ -3312,6 +3312,8 @@ explain SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref b b 4 const 1 Using where; Using index +Warnings: +Note 1105 Cannot use key `b` part[1] for lookup: `test`.`t1`.`a` of type `varchar` > "'0' = 'z'" of type `boolean` SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b; b min(a) explain @@ -4018,12 +4020,18 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND DATE'2001-01-05' GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL id 27 NULL 64 Using where; Using index +Warnings: +Note 1105 Cannot use key `id` part[1] for lookup: `test`.`t1`.`a` of type `varchar` >= "DATE'2001-01-04'" of type `date` EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND '2001-01-05' GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL id 27 NULL 64 Using where; Using index +Warnings: +Note 1105 Cannot use key `id` part[1] for lookup: `test`.`t1`.`a` of type `varchar` >= "DATE'2001-01-04'" of type `date` EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND DATE'2001-01-05' GROUP BY id; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL id 27 NULL 64 Using where; Using index +Warnings: +Note 1105 Cannot use key `id` part[1] for lookup: `test`.`t1`.`a` of type `varchar` >= "('2001-01-04')" of type `date` DROP TABLE t1; # # MIN() optimization didn't work correctly with BETWEEN when using too diff --git a/mysql-test/main/group_min_max_innodb.result b/mysql-test/main/group_min_max_innodb.result index 5041f6587f9..c14fed88666 100644 --- a/mysql-test/main/group_min_max_innodb.result +++ b/mysql-test/main/group_min_max_innodb.result @@ -331,6 +331,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 d9639f12031..419c53dbd18 100644 --- a/mysql-test/main/group_min_max_innodb.test +++ b/mysql-test/main/group_min_max_innodb.test @@ -276,6 +276,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/information_schema_db.result b/mysql-test/main/information_schema_db.result index b5687956414..b14cacc4720 100644 --- a/mysql-test/main/information_schema_db.result +++ b/mysql-test/main/information_schema_db.result @@ -1,9 +1,5 @@ set local sql_mode=""; set global sql_mode=""; -drop table if exists t1,t2; -drop view if exists v1,v2; -drop function if exists f1; -drop function if exists f2; show tables from INFORMATION_SCHEMA like 'T%'; Tables_in_information_schema (T%) TABLES @@ -17,6 +13,10 @@ create database mbase; use `inf%`; show tables; Tables_in_inf% +# +# Bug#18113 SELECT * FROM information_schema.xxx crashes server +# Bug#17204 second CALL to procedure crashes Server +# grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost'; grant all privileges on `mbase`.* to 'mysqltest_1'@'localhost'; create table t1 (f1 int); @@ -63,6 +63,9 @@ drop database `inf%`; drop procedure mbase.p1; drop database mbase; disconnect user1; +# +# Bug#18282 INFORMATION_SCHEMA.TABLES provides inconsistent info about invalid views +# use test; create table t1 (i int); create function f1 () returns int return (select max(i) from t1); @@ -86,6 +89,10 @@ v2 VIEW VIEW drop function f1; drop function f2; drop view v1, v2; +# +# Bug#20543 select on information_schema strange warnings, view, different +# schemas/users +# create database testdb_1; create user testdb_1@localhost; grant all on testdb_1.* to testdb_1@localhost with grant option; @@ -213,6 +220,9 @@ disconnect testdb_2; connection default; drop user testdb_1@localhost; drop user testdb_2@localhost; +# +# Bug#22763 Disrepancy between SHOW CREATE VIEW and I_S.VIEWS +# create database testdb_1; create table testdb_1.t1 (a int); create view testdb_1.v1 as select * from testdb_1.t1; @@ -243,11 +253,14 @@ connection user1; disconnect user1; connection default; set global sql_mode=default; +# +# MDEV-20549 SQL SECURITY DEFINER does not work for INFORMATION_SCHEMA tables +# create user foo@localhost; grant select on test.* to foo@localhost; create procedure rootonly() select 1; -create sql security definer view v1d as select current_user(),user from information_schema.processlist; -create sql security invoker view v1i as select current_user(),user from information_schema.processlist; +create sql security definer view v1d as select current_user(),user from information_schema.processlist where command!='daemon'; +create sql security invoker view v1i as select current_user(),user from information_schema.processlist where command!='daemon'; create sql security definer view v2d as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%'; create sql security invoker view v2i as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%'; create sql security definer view v3d as select schema_name from information_schema.schemata where schema_name like '%mysql%'; @@ -322,3 +335,50 @@ disconnect foo; drop view v1d, v1i, v2d, v2i, v3d, v3i, v4d, v4i, v5d, v5i; drop user foo@localhost; drop procedure rootonly; +# +# End of 10.2 tests +# +# +# MDEV-32500 Information schema leaks table names and structure to unauthorized users +# +create database db; +create table db.t1 (x int, key(x)) engine=InnoDB; +create table db.t2 (a int, b int, c int, unique(b), check(c>b), foreign key(c) references db.t1(x)) engine=InnoDB; +create table db.t3 (d int, e int, f int, unique(e), check(f>e), foreign key(f) references db.t1(x), +foreign key(e) references db.t2(b), +foreign key(d) references db.t3(f) +) engine=InnoDB; +create user u@localhost; +grant select (a) on db.t2 to u@localhost; +grant update (d) on db.t3 to u@localhost; +connect con1,localhost,u,,db; +select table_name, column_name from information_schema.columns where table_name like 't_'; +table_name column_name +t2 a +t3 d +select table_name, column_name from information_schema.key_column_usage where table_name like 't_'; +table_name column_name +select table_name, unique_constraint_name, referenced_table_name from information_schema.referential_constraints where table_name like 't_'; +table_name unique_constraint_name referenced_table_name +t3 x NULL +t3 b NULL +t3 f t3 +select table_name, constraint_name, constraint_type from information_schema.table_constraints where table_name like 't_'; +table_name constraint_name constraint_type +t3 e UNIQUE +t3 CONSTRAINT_1 CHECK +t3 t3_ibfk_1 FOREIGN KEY +t3 t3_ibfk_2 FOREIGN KEY +t3 t3_ibfk_3 FOREIGN KEY +show index in t2; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored +show index in t3; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored +t3 1 d 1 d A 0 NULL NULL YES BTREE NO +disconnect con1; +connection default; +drop user u@localhost; +drop database db; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/information_schema_db.test b/mysql-test/main/information_schema_db.test index fabc42e38b8..c63355d4e0e 100644 --- a/mysql-test/main/information_schema_db.test +++ b/mysql-test/main/information_schema_db.test @@ -1,19 +1,12 @@ # this test mostly test privilege control (what doesn't work # in the embedded server by default). So skip the test in embedded-server mode. -- source include/not_embedded.inc - +-- source include/have_innodb.inc -- source include/testdb_only.inc set local sql_mode=""; set global sql_mode=""; ---disable_warnings -drop table if exists t1,t2; -drop view if exists v1,v2; -drop function if exists f1; -drop function if exists f2; ---enable_warnings - --replace_result 'Tables_in_INFORMATION_SCHEMA (T%)' 'Tables_in_information_schema (T%)' --sorted_result show tables from INFORMATION_SCHEMA like 'T%'; @@ -22,9 +15,10 @@ create database mbase; use `inf%`; show tables; -# -# Bug#18113 SELECT * FROM information_schema.xxx crashes server -# Bug#17204 second CALL to procedure crashes Server +--echo # +--echo # Bug#18113 SELECT * FROM information_schema.xxx crashes server +--echo # Bug#17204 second CALL to procedure crashes Server +--echo # # Crash happened when one selected data from one of INFORMATION_SCHEMA # tables and in order to build its contents server had to open view which # used stored function and table or view on which one had not global or @@ -88,9 +82,9 @@ drop procedure mbase.p1; drop database mbase; disconnect user1; -# -# Bug#18282 INFORMATION_SCHEMA.TABLES provides inconsistent info about invalid views -# +--echo # +--echo # Bug#18282 INFORMATION_SCHEMA.TABLES provides inconsistent info about invalid views +--echo # use test; create table t1 (i int); create function f1 () returns int return (select max(i) from t1); @@ -109,11 +103,10 @@ drop function f2; drop view v1, v2; --enable_view_protocol -# -# Bug#20543 select on information_schema strange warnings, view, different -# schemas/users -# -# +--echo # +--echo # Bug#20543 select on information_schema strange warnings, view, different +--echo # schemas/users +--echo # --disable_service_connection create database testdb_1; create user testdb_1@localhost; @@ -223,9 +216,9 @@ connection default; drop user testdb_1@localhost; drop user testdb_2@localhost; -# -# Bug#22763 Disrepancy between SHOW CREATE VIEW and I_S.VIEWS -# +--echo # +--echo # Bug#22763 Disrepancy between SHOW CREATE VIEW and I_S.VIEWS +--echo # create database testdb_1; create table testdb_1.t1 (a int); create view testdb_1.v1 as select * from testdb_1.t1; @@ -257,15 +250,15 @@ connection default; set global sql_mode=default; -# -# MDEV-20549 SQL SECURITY DEFINER does not work for INFORMATION_SCHEMA tables -# +--echo # +--echo # MDEV-20549 SQL SECURITY DEFINER does not work for INFORMATION_SCHEMA tables +--echo # create user foo@localhost; grant select on test.* to foo@localhost; create procedure rootonly() select 1; -create sql security definer view v1d as select current_user(),user from information_schema.processlist; -create sql security invoker view v1i as select current_user(),user from information_schema.processlist; +create sql security definer view v1d as select current_user(),user from information_schema.processlist where command!='daemon'; +create sql security invoker view v1i as select current_user(),user from information_schema.processlist where command!='daemon'; create sql security definer view v2d as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%'; create sql security invoker view v2i as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%'; create sql security definer view v3d as select schema_name from information_schema.schemata where schema_name like '%mysql%'; @@ -301,3 +294,40 @@ drop view v1d, v1i, v2d, v2i, v3d, v3i, v4d, v4i, v5d, v5i; drop user foo@localhost; drop procedure rootonly; --enable_service_connection + +--echo # +--echo # End of 10.2 tests +--echo # + +--echo # +--echo # MDEV-32500 Information schema leaks table names and structure to unauthorized users +--echo # +create database db; +create table db.t1 (x int, key(x)) engine=InnoDB; +create table db.t2 (a int, b int, c int, unique(b), check(c>b), foreign key(c) references db.t1(x)) engine=InnoDB; +create table db.t3 (d int, e int, f int, unique(e), check(f>e), foreign key(f) references db.t1(x), + foreign key(e) references db.t2(b), + foreign key(d) references db.t3(f) + ) engine=InnoDB; + +create user u@localhost; +grant select (a) on db.t2 to u@localhost; +grant update (d) on db.t3 to u@localhost; + +--connect con1,localhost,u,,db +--sorted_result +select table_name, column_name from information_schema.columns where table_name like 't_'; +select table_name, column_name from information_schema.key_column_usage where table_name like 't_'; +select table_name, unique_constraint_name, referenced_table_name from information_schema.referential_constraints where table_name like 't_'; +select table_name, constraint_name, constraint_type from information_schema.table_constraints where table_name like 't_'; +show index in t2; +show index in t3; + +--disconnect con1 +--connection default +drop user u@localhost; +drop database db; + +--echo # +--echo # End of 10.4 tests +--echo # 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/innodb_icp.result b/mysql-test/main/innodb_icp.result index bdbc2f6ccc1..e8ed6013ab4 100644 --- a/mysql-test/main/innodb_icp.result +++ b/mysql-test/main/innodb_icp.result @@ -156,7 +156,7 @@ INSERT INTO t1 VALUES # Execute select with invalid timestamp, desc ordering SELECT * -FROM t1 +FROM t1 FORCE INDEX(PRIMARY) WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; @@ -167,7 +167,7 @@ ts c # Should use index condition EXPLAIN SELECT * -FROM t1 +FROM t1 FORCE INDEX(PRIMARY) WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; @@ -429,6 +429,12 @@ CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL); INSERT INTO t2 VALUES (11,1); INSERT INTO t2 VALUES (12,2); INSERT INTO t2 VALUES (15,4); +analyze table t1,t2 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK set @save_optimizer_switch= @@optimizer_switch; set optimizer_switch='semijoin=off'; EXPLAIN @@ -698,6 +704,12 @@ CREATE TABLE t2 (a varchar(1024), KEY (a(512))); INSERT INTO t2 VALUES ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w'); insert into t2 select seq from seq_1_to_100; +analyze table t1,t2 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK SET SESSION optimizer_switch='index_condition_pushdown=off'; EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) diff --git a/mysql-test/main/join_cache.result b/mysql-test/main/join_cache.result index 7e58aff63da..26a57dda173 100644 --- a/mysql-test/main/join_cache.result +++ b/mysql-test/main/join_cache.result @@ -6338,5 +6338,131 @@ ERROR HY001: Could not create a join buffer. Please check and adjust the value o SET JOIN_buffer_size=16384; SELECT * FROM information_schema.statistics JOIN information_schema.COLUMNS USING (table_name,column_name); # +# MDEV-32351: Join buffer used for outer join with ON condition +# depending only on outer tables +# +CREATE TABLE t1 (b int NOT NULL, PRIMARY KEY (b)) ENGINE=MYISAM; +INSERT INTO t1 select seq from seq_1_to_10000; +CREATE TABLE t2 (b int NOT NULL, d varchar(255), KEY (b)) ENGINE=MYISAM ; +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +CREATE TABLE t3 (c int NOT NULL, PRIMARY KEY (c)) ENGINE=MYISAM ; +INSERT INTO t3 select seq from seq_1_to_3000; +CREATE TABLE t4 (c int NOT NULL, PRIMARY KEY (c)) ENGINE=MYISAM; +INSERT INTO t4 select seq from seq_1_to_3000; +ANALYZE TABLE t1,t2,t3,t4; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +test.t4 analyze status Engine-independent statistics collected +test.t4 analyze status OK +set join_cache_level=0; +EXPLAIN SELECT COUNT(*) +FROM t1 +LEFT JOIN t2 ON t1.b = t2.b +LEFT JOIN t3 ON t2.d = t3.c +LEFT JOIN t4 ON t3.c=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 10000 Using index +1 SIMPLE t2 ref b b 4 test.t1.b 1 +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.d 1 Using where; Using index +1 SIMPLE t4 index NULL PRIMARY 4 NULL 3000 Using where; Using index +SELECT COUNT(*) +FROM t1 +LEFT JOIN t2 ON t1.b = t2.b +LEFT JOIN t3 ON t2.d = t3.c +LEFT JOIN t4 ON t3.c=1; +COUNT(*) +12999 +set join_cache_level=default; +EXPLAIN SELECT COUNT(*) +FROM t1 +LEFT JOIN t2 ON t1.b = t2.b +LEFT JOIN t3 ON t2.d = t3.c +LEFT JOIN t4 ON t3.c=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 10000 Using index +1 SIMPLE t2 ref b b 4 test.t1.b 1 +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.d 1 Using where; Using index +1 SIMPLE t4 index NULL PRIMARY 4 NULL 3000 Using where; Using index; Using join buffer (flat, BNL join) +SELECT COUNT(*) +FROM t1 +LEFT JOIN t2 ON t1.b = t2.b +LEFT JOIN t3 ON t2.d = t3.c +LEFT JOIN t4 ON t3.c=1; +COUNT(*) +12999 +DROP TABLE t1,t2,t3,t4; +CREATE TABLE t1 (b int NOT NULL, PRIMARY KEY (b)); +INSERT INTO t1 select seq from seq_1_to_10; +CREATE TABLE t2 (b int NOT NULL, d varchar(255), KEY (b)) ; +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +CREATE TABLE t3 (c int NOT NULL, PRIMARY KEY (c)) ; +INSERT INTO t3 select seq from seq_1_to_3; +CREATE TABLE t4 (c int NOT NULL, PRIMARY KEY (c)) ; +INSERT INTO t4 select seq from seq_1_to_3; +set join_cache_level=0; +EXPLAIN SELECT * +FROM t1 +LEFT JOIN t2 ON t1.b = t2.b +LEFT JOIN t3 ON t2.d = t3.c +LEFT JOIN t4 ON t3.c=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 10 Using index +1 SIMPLE t2 ref b b 4 test.t1.b 1 +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.d 1 Using where; Using index +1 SIMPLE t4 index NULL PRIMARY 4 NULL 3 Using where; Using index +SELECT * +FROM t1 +LEFT JOIN t2 ON t1.b = t2.b +LEFT JOIN t3 ON t2.d = t3.c +LEFT JOIN t4 ON t3.c=1; +b b d c c +1 1 1 1 1 +1 1 1 1 2 +1 1 1 1 3 +2 2 2 2 NULL +3 3 3 3 NULL +4 NULL NULL NULL NULL +5 NULL NULL NULL NULL +6 NULL NULL NULL NULL +7 NULL NULL NULL NULL +8 NULL NULL NULL NULL +9 NULL NULL NULL NULL +10 NULL NULL NULL NULL +set join_cache_level=default; +EXPLAIN SELECT * +FROM t1 +LEFT JOIN t2 ON t1.b = t2.b +LEFT JOIN t3 ON t2.d = t3.c +LEFT JOIN t4 ON t3.c=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 10 Using index +1 SIMPLE t2 ref b b 4 test.t1.b 1 +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.d 1 Using where; Using index +1 SIMPLE t4 index NULL PRIMARY 4 NULL 3 Using where; Using index; Using join buffer (flat, BNL join) +SELECT * +FROM t1 +LEFT JOIN t2 ON t1.b = t2.b +LEFT JOIN t3 ON t2.d = t3.c +LEFT JOIN t4 ON t3.c=1; +b b d c c +1 1 1 1 1 +1 1 1 1 2 +1 1 1 1 3 +2 2 2 2 NULL +3 3 3 3 NULL +4 NULL NULL NULL NULL +5 NULL NULL NULL NULL +6 NULL NULL NULL NULL +7 NULL NULL NULL NULL +8 NULL NULL NULL NULL +9 NULL NULL NULL NULL +10 NULL NULL NULL NULL +DROP TABLE t1,t2,t3,t4; +# # End of 10.4 tests # diff --git a/mysql-test/main/join_cache.test b/mysql-test/main/join_cache.test index 9a5f1bf3fe3..dddc0c1a316 100644 --- a/mysql-test/main/join_cache.test +++ b/mysql-test/main/join_cache.test @@ -4304,6 +4304,64 @@ SET JOIN_buffer_size=16384; SELECT * FROM information_schema.statistics JOIN information_schema.COLUMNS USING (table_name,column_name); --enable_result_log +--echo # +--echo # MDEV-32351: Join buffer used for outer join with ON condition +--echo # depending only on outer tables +--echo # + +--source include/have_sequence.inc + +CREATE TABLE t1 (b int NOT NULL, PRIMARY KEY (b)) ENGINE=MYISAM; +INSERT INTO t1 select seq from seq_1_to_10000; +CREATE TABLE t2 (b int NOT NULL, d varchar(255), KEY (b)) ENGINE=MYISAM ; +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +CREATE TABLE t3 (c int NOT NULL, PRIMARY KEY (c)) ENGINE=MYISAM ; +INSERT INTO t3 select seq from seq_1_to_3000; +CREATE TABLE t4 (c int NOT NULL, PRIMARY KEY (c)) ENGINE=MYISAM; +INSERT INTO t4 select seq from seq_1_to_3000; +ANALYZE TABLE t1,t2,t3,t4; + +let $q1= +SELECT COUNT(*) +FROM t1 + LEFT JOIN t2 ON t1.b = t2.b + LEFT JOIN t3 ON t2.d = t3.c + LEFT JOIN t4 ON t3.c=1; + +set join_cache_level=0; +eval EXPLAIN $q1; +eval $q1; +set join_cache_level=default; +eval EXPLAIN $q1; +eval $q1; + +DROP TABLE t1,t2,t3,t4; + +CREATE TABLE t1 (b int NOT NULL, PRIMARY KEY (b)); +INSERT INTO t1 select seq from seq_1_to_10; +CREATE TABLE t2 (b int NOT NULL, d varchar(255), KEY (b)) ; +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +CREATE TABLE t3 (c int NOT NULL, PRIMARY KEY (c)) ; +INSERT INTO t3 select seq from seq_1_to_3; +CREATE TABLE t4 (c int NOT NULL, PRIMARY KEY (c)) ; +INSERT INTO t4 select seq from seq_1_to_3; + +let $q2= +SELECT * +FROM t1 + LEFT JOIN t2 ON t1.b = t2.b + LEFT JOIN t3 ON t2.d = t3.c + LEFT JOIN t4 ON t3.c=1; + +set join_cache_level=0; +eval EXPLAIN $q2; +eval $q2; +set join_cache_level=default; +eval EXPLAIN $q2; +eval $q2; + +DROP TABLE t1,t2,t3,t4; + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/join_cache_debug.result b/mysql-test/main/join_cache_debug.result new file mode 100644 index 00000000000..0f66550ff26 --- /dev/null +++ b/mysql-test/main/join_cache_debug.result @@ -0,0 +1,128 @@ +# +# MDEV-32351: Significant slowdown for query with many outer joins +# +CREATE TABLE t1 (b int NOT NULL, PRIMARY KEY (b)) ENGINE=MYISAM; +INSERT INTO t1 select seq from seq_1_to_10000; +CREATE TABLE t2 (b int NOT NULL, d varchar(255), KEY (b)) ENGINE=MYISAM ; +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +CREATE TABLE t3 (c int NOT NULL, PRIMARY KEY (c)) ENGINE=MYISAM ; +INSERT INTO t3 select seq from seq_1_to_3000; +CREATE TABLE t4 (c int NOT NULL, PRIMARY KEY (c)) ENGINE=MYISAM; +INSERT INTO t4 select seq from seq_1_to_3000; +ANALYZE TABLE t1,t2,t3,t4; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +test.t4 analyze status Engine-independent statistics collected +test.t4 analyze status OK +create table t1_t2 as +select +t1.b as t1_b, t2.b as t2_b, t2.d as t2_d +FROM t1 +LEFT JOIN t2 ON t1.b = t2.b; +SET statement debug_dbug='+d,analyze_print_r_unpack_ops' for +analyze +format=json +SELECT COUNT(*) +FROM t1_t2 +LEFT JOIN t3 ON t2_d = t3.c +LEFT JOIN t4 ON t3.c=1 +select '$js' as JSON; +JSON +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "const_condition": "1", + "nested_loop": [ + { + "table": { + "table_name": "t1_t2", + "access_type": "ALL", + "loops": 1, + "r_loops": 1, + "rows": 10000, + "r_rows": 10000, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "filtered": 100, + "r_filtered": 100 + } + }, + { + "table": { + "table_name": "t3", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["c"], + "ref": ["test.t1_t2.t2_d"], + "loops": 10000, + "r_loops": 10000, + "r_table_loops": 3, + "rows": 1, + "r_rows": 0.0003, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "filtered": 100, + "r_filtered": 100, + "attached_condition": "trigcond(t1_t2.t2_d = t3.c and trigcond(t1_t2.t2_d is not null))", + "using_index": true + } + }, + { + "block-nl-join": { + "table": { + "table_name": "t4", + "access_type": "index", + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["c"], + "loops": 10000, + "r_loops": 1, + "rows": 3000, + "r_rows": 3000, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "filtered": 100, + "r_filtered": 100, + "using_index": true + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "trigcond(trigcond(t3.c = 1))", + "r_loops": 10000, + "r_filtered": 0.04333, + "r_unpack_time_ms": "REPLACED", + "r_unpack_ops": 3000, + "r_other_time_ms": "REPLACED", + "r_effective_rows": 3000 + } + } + ] + } +} +# This must show 3000, not 30000000: +select json_extract('$js', '\$**.r_unpack_ops') as R_UNPACK_OPS; +R_UNPACK_OPS +[3000] +SET debug_dbug=@old_debug; +drop table t1,t2,t3,t4; +drop table t1_t2; diff --git a/mysql-test/main/join_cache_debug.test b/mysql-test/main/join_cache_debug.test new file mode 100644 index 00000000000..aba36b14f29 --- /dev/null +++ b/mysql-test/main/join_cache_debug.test @@ -0,0 +1,43 @@ +--source include/have_sequence.inc +--source include/have_debug.inc + +--echo # +--echo # MDEV-32351: Significant slowdown for query with many outer joins +--echo # +CREATE TABLE t1 (b int NOT NULL, PRIMARY KEY (b)) ENGINE=MYISAM; +INSERT INTO t1 select seq from seq_1_to_10000; +CREATE TABLE t2 (b int NOT NULL, d varchar(255), KEY (b)) ENGINE=MYISAM ; +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +CREATE TABLE t3 (c int NOT NULL, PRIMARY KEY (c)) ENGINE=MYISAM ; +INSERT INTO t3 select seq from seq_1_to_3000; +CREATE TABLE t4 (c int NOT NULL, PRIMARY KEY (c)) ENGINE=MYISAM; +INSERT INTO t4 select seq from seq_1_to_3000; +ANALYZE TABLE t1,t2,t3,t4; + +create table t1_t2 as +select + t1.b as t1_b, t2.b as t2_b, t2.d as t2_d +FROM t1 + LEFT JOIN t2 ON t1.b = t2.b; + +let $q= +SET statement debug_dbug='+d,analyze_print_r_unpack_ops' for +analyze +format=json +SELECT COUNT(*) +FROM t1_t2 + LEFT JOIN t3 ON t2_d = t3.c + LEFT JOIN t4 ON t3.c=1; + +echo $q; +let $js=`$q`; + +--source include/analyze-format.inc +evalp select '$js' as JSON; + +--echo # This must show 3000, not 30000000: +evalp select json_extract('$js', '\$**.r_unpack_ops') as R_UNPACK_OPS; +SET debug_dbug=@old_debug; + +drop table t1,t2,t3,t4; +drop table t1_t2; 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/leaks.result b/mysql-test/main/leaks.result new file mode 100644 index 00000000000..386459b622a --- /dev/null +++ b/mysql-test/main/leaks.result @@ -0,0 +1,13 @@ +# +# MDEV-32476 LeakSanitizer errors in get_quick_select or +# Assertion `status_var.local_memory_used == 0 +# +CREATE TABLE t1 (pk INT AUTO_INCREMENT, f INT, PRIMARY KEY (pk), KEY(f)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,10),(2,20); +INSERT INTO t1 (f) SELECT t2.f FROM t1 t2, t1 t3 WHERE t2.f = 10 AND t3.pk > 'foo'; +ERROR 22007: Truncated incorrect DECIMAL value: 'foo' +DROP TABLE t1; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/leaks.test b/mysql-test/main/leaks.test new file mode 100644 index 00000000000..3482aac702a --- /dev/null +++ b/mysql-test/main/leaks.test @@ -0,0 +1,22 @@ +# +# Collection of small tests that finds leaks and does not fit in any other +# tests +# + +--source include/have_innodb.inc + +--echo # +--echo # MDEV-32476 LeakSanitizer errors in get_quick_select or +--echo # Assertion `status_var.local_memory_used == 0 +--echo # + +CREATE TABLE t1 (pk INT AUTO_INCREMENT, f INT, PRIMARY KEY (pk), KEY(f)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,10),(2,20); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 (f) SELECT t2.f FROM t1 t2, t1 t3 WHERE t2.f = 10 AND t3.pk > 'foo'; +DROP TABLE t1; + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/mysql-test/main/loaddata.result b/mysql-test/main/loaddata.result index b7d51a13c85..d00eb034505 100644 --- a/mysql-test/main/loaddata.result +++ b/mysql-test/main/loaddata.result @@ -231,8 +231,8 @@ load data infile 'MYSQL_TEST_DIR/t/loaddata.test' into table t1; Got one of the listed errors select * from t1; a b c -select load_file("MYSQL_TEST_DIR/t/loaddata.test"); -load_file("MYSQL_TEST_DIR/t/loaddata.test") +select load_file("MYSQL_TEST_DIR/t/loaddata.test") as exp; +exp NULL drop table t1, t2; create table t1(f1 int); @@ -405,8 +405,8 @@ after 4 \r 5C72 before 5 tab 09746162 after 5 tab 09746162 TRUNCATE t2; -SELECT LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt"); -LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt") +SELECT LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt") as exp; +exp 3 \tx 4 \r 5 tab @@ -424,8 +424,8 @@ after 4 \r 5C72 before 5 tab 09746162 after 5 tab 09746162 TRUNCATE t2; -SELECT LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt"); -LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt") +SELECT LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt") exp; +exp 3 \\tx 4 \\r 5 tab @@ -445,8 +445,8 @@ before 5 tab 09746162 after 5 tab 09746162 TRUNCATE t2; SET sql_mode = 'NO_BACKSLASH_ESCAPES'; -SELECT LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt"); -LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt") +SELECT LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt") as ep; +ep 3 \\tx 4 \\r 5 tab @@ -466,8 +466,8 @@ before 5 tab 09746162 after 5 tab 09746162 TRUNCATE t2; SET sql_mode = 'NO_BACKSLASH_ESCAPES'; -SELECT LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt"); -LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt") +SELECT LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt") as exp; +exp 3 \tx 4 \r 5 tab @@ -478,8 +478,9 @@ DROP TABLE t1,t2; # Bug #51893: crash with certain characters given to load_file # function on windows # -select load_file(0x0A9FB76C661B409C4BEC88098C5DD71B1072F9691F2E827D7EC8F092B299868A3CE196C04F0FB18CAB4E1557EB72331D812379DE7A75CA21C32E7C722C59E5CC33EF262EF04187B0F0EE756FA984DF2EAD37B1E4ADB064C3C5038F2E3B2D661B1C1150AAEB5425512E14D7506166D92D4533872E662F4B2D1428AAB5CCA72E75AA2EF325E196A5A02E2E8278873C64375845994B0F39BE2FF7B478332A7B0AA5E48877C47B6F513E997848AF8CCB8A899F3393AB35333CF0871E36698193862D486B4B9078B70C0A0A507B8A250F3F876F5A067632D5E65193E4445A1EC3A2C9B4C6F07AC334F0F62BC33357CB502E9B1C19D2398B6972AEC2EF21630F8C9134C4F7DD662D8AD7BDC9E19C46720F334B66C22D4BF32ED275144E20E7669FFCF6FC143667C9F02A577F32960FA9F2371BE1FA90E49CBC69C01531F140556854D588DD0E55E1307D78CA38E975CD999F9AEA604266329EE62BFB5ADDA67F549E211ECFBA906C60063696352ABB82AA782D25B17E872EA587871F450446DB1BAE0123D20404A8F2D2698B371002E986C8FCB969A99FF0E150A2709E2ED7633D02ADA87D5B3C9487D27B2BD9D21E2EC3215DCC3CDCD884371281B95A2E9987AAF82EB499C058D9C3E7DC1B66635F60DB121C72F929622DD47B6B2E69F59FF2AE6B63CC2EC60FFBA20EA50569DBAB5DAEFAEB4F03966C9637AB55662EDD28439155A82D053A5299448EDB2E7BEB0F62889E2F84E6C7F34B3212C9AAC32D521D5AB8480993F1906D5450FAB342A0FA6ED223E178BAC036B81E15783604C32A961EA1EF20BE2EBB93D34ED37BC03142B7583303E4557E48551E4BD7CBDDEA146D5485A5D212C35189F0BD6497E66912D2780A59A53B532E12C0A5ED1EC0445D96E8F2DD825221CFE4A65A87AA21DC8750481B9849DD81694C3357A0ED9B78D608D8EDDE28FAFBEC17844DE5709F41E121838DB55639D77E32A259A416D7013B2EB1259FDE1B498CBB9CAEE1D601DF3C915EA91C69B44E6B72062F5F4B3C73F06F2D5AD185E1692E2E0A01E7DD5133693681C52EE13B2BE42D03BDCF48E4E133CF06662339B778E1C3034F9939A433E157449172F7969ACCE1F5D2F65A4E09E4A5D5611EBEDDDBDB0C0C0A); -load_file(0x0A9FB76C661B409C4BEC88098C5DD71B1072F9691F2E827D7EC8F092B299868A3CE196C04F0FB18CAB4E1557EB72331D812379DE7A75CA21C32E7C722C59E5CC33EF262EF04187B0F0EE756FA984DF2EAD37B1E4ADB064C3C5038F2E3B2D661B1C1150AAEB5425512E14D7506166D92D4533872E662F4B2D142 +select +load_file(0x0A9FB76C661B409C4BEC88098C5DD71B1072F9691F2E827D7EC8F092B299868A3CE196C04F0FB18CAB4E1557EB72331D812379DE7A75CA21C32E7C722C59E5CC33EF262EF04187B0F0EE756FA984DF2EAD37B1E4ADB064C3C5038F2E3B2D661B1C1150AAEB5425512E14D7506166D92D4533872E662F4B2D1428AAB5CCA72E75AA2EF325E196A5A02E2E8278873C64375845994B0F39BE2FF7B478332A7B0AA5E48877C47B6F513E997848AF8CCB8A899F3393AB35333CF0871E36698193862D486B4B9078B70C0A0A507B8A250F3F876F5A067632D5E65193E4445A1EC3A2C9B4C6F07AC334F0F62BC33357CB502E9B1C19D2398B6972AEC2EF21630F8C9134C4F7DD662D8AD7BDC9E19C46720F334B66C22D4BF32ED275144E20E7669FFCF6FC143667C9F02A577F32960FA9F2371BE1FA90E49CBC69C01531F140556854D588DD0E55E1307D78CA38E975CD999F9AEA604266329EE62BFB5ADDA67F549E211ECFBA906C60063696352ABB82AA782D25B17E872EA587871F450446DB1BAE0123D20404A8F2D2698B371002E986C8FCB969A99FF0E150A2709E2ED7633D02ADA87D5B3C9487D27B2BD9D21E2EC3215DCC3CDCD884371281B95A2E9987AAF82EB499C058D9C3E7DC1B66635F60DB121C72F929622DD47B6B2E69F59FF2AE6B63CC2EC60FFBA20EA50569DBAB5DAEFAEB4F03966C9637AB55662EDD28439155A82D053A5299448EDB2E7BEB0F62889E2F84E6C7F34B3212C9AAC32D521D5AB8480993F1906D5450FAB342A0FA6ED223E178BAC036B81E15783604C32A961EA1EF20BE2EBB93D34ED37BC03142B7583303E4557E48551E4BD7CBDDEA146D5485A5D212C35189F0BD6497E66912D2780A59A53B532E12C0A5ED1EC0445D96E8F2DD825221CFE4A65A87AA21DC8750481B9849DD81694C3357A0ED9B78D608D8EDDE28FAFBEC17844DE5709F41E121838DB55639D77E32A259A416D7013B2EB1259FDE1B498CBB9CAEE1D601DF3C915EA91C69B44E6B72062F5F4B3C73F06F2D5AD185E1692E2E0A01E7DD5133693681C52EE13B2BE42D03BDCF48E4E133CF06662339B778E1C3034F9939A433E157449172F7969ACCE1F5D2F65A4E09E4A5D5611EBEDDDBDB0C0C0A) as exp; +exp NULL End of 5.0 tests CREATE TABLE t1 (a int); diff --git a/mysql-test/main/loaddata.test b/mysql-test/main/loaddata.test index 0a5e3c27007..9c1a583831b 100644 --- a/mysql-test/main/loaddata.test +++ b/mysql-test/main/loaddata.test @@ -159,8 +159,6 @@ select * from t1; # # It should not be possible to load from a file outside of vardir -#enable after fix MDEV-27871 ---disable_view_protocol --error 1238 set @@secure_file_priv= 0; @@ -173,11 +171,10 @@ select * from t1; # Test "load_file" returns NULL --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR -eval select load_file("$MYSQL_TEST_DIR/t/loaddata.test"); +eval select load_file("$MYSQL_TEST_DIR/t/loaddata.test") as exp; # cleanup drop table t1, t2; ---enable_view_protocol # # Bug#27586: Wrong autoinc value assigned by LOAD DATA in the @@ -447,15 +444,10 @@ SELECT 'before' AS t, id, val1, hex(val1) FROM t1 UNION TRUNCATE t2; -#enable after fix MDEV-27871 ---disable_view_protocol - --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -eval SELECT LOAD_FILE("$file"); +eval SELECT LOAD_FILE("$file") as exp; --remove_file $file ---enable_view_protocol - --echo 1.2 NO_BACKSLASH_ESCAPES, override defaults for ESCAPED BY --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR @@ -471,14 +463,10 @@ SELECT 'before' AS t, id, val1, hex(val1) FROM t1 UNION TRUNCATE t2; -#enable after fix MDEV-27871 ---disable_view_protocol - --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -eval SELECT LOAD_FILE("$file"); +eval SELECT LOAD_FILE("$file") exp; --remove_file $file ---enable_view_protocol # 2. with NO_BACKSLASH_ESCAPES off @@ -501,15 +489,10 @@ TRUNCATE t2; SET sql_mode = 'NO_BACKSLASH_ESCAPES'; -#enable after fix MDEV-27871 ---disable_view_protocol - --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -eval SELECT LOAD_FILE("$file"); +eval SELECT LOAD_FILE("$file") as ep; --remove_file $file ---enable_view_protocol - SET sql_mode = ''; @@ -531,15 +514,10 @@ TRUNCATE t2; SET sql_mode = 'NO_BACKSLASH_ESCAPES'; -#enable after fix MDEV-27871 ---disable_view_protocol - --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -eval SELECT LOAD_FILE("$file"); +eval SELECT LOAD_FILE("$file") as exp; --remove_file $file ---enable_view_protocol - # clean up set session sql_mode=@OLD_SQL_MODE; DROP TABLE t1,t2; @@ -550,12 +528,8 @@ DROP TABLE t1,t2; --echo # function on windows --echo # -#enable after fix MDEV-27871 ---disable_view_protocol - -select load_file(0x0A9FB76C661B409C4BEC88098C5DD71B1072F9691F2E827D7EC8F092B299868A3CE196C04F0FB18CAB4E1557EB72331D812379DE7A75CA21C32E7C722C59E5CC33EF262EF04187B0F0EE756FA984DF2EAD37B1E4ADB064C3C5038F2E3B2D661B1C1150AAEB5425512E14D7506166D92D4533872E662F4B2D1428AAB5CCA72E75AA2EF325E196A5A02E2E8278873C64375845994B0F39BE2FF7B478332A7B0AA5E48877C47B6F513E997848AF8CCB8A899F3393AB35333CF0871E36698193862D486B4B9078B70C0A0A507B8A250F3F876F5A067632D5E65193E4445A1EC3A2C9B4C6F07AC334F0F62BC33357CB502E9B1C19D2398B6972AEC2EF21630F8C9134C4F7DD662D8AD7BDC9E19C46720F334B66C22D4BF32ED275144E20E7669FFCF6FC143667C9F02A577F32960FA9F2371BE1FA90E49CBC69C01531F140556854D588DD0E55E1307D78CA38E975CD999F9AEA604266329EE62BFB5ADDA67F549E211ECFBA906C60063696352ABB82AA782D25B17E872EA587871F450446DB1BAE0123D20404A8F2D2698B371002E986C8FCB969A99FF0E150A2709E2ED7633D02ADA87D5B3C9487D27B2BD9D21E2EC3215DCC3CDCD884371281B95A2E9987AAF82EB499C058D9C3E7DC1B66635F60DB121C72F929622DD47B6B2E69F59FF2AE6B63CC2EC60FFBA20EA50569DBAB5DAEFAEB4F03966C9637AB55662EDD28439155A82D053A5299448EDB2E7BEB0F62889E2F84E6C7F34B3212C9AAC32D521D5AB8480993F1906D5450FAB342A0FA6ED223E178BAC036B81E15783604C32A961EA1EF20BE2EBB93D34ED37BC03142B7583303E4557E48551E4BD7CBDDEA146D5485A5D212C35189F0BD6497E66912D2780A59A53B532E12C0A5ED1EC0445D96E8F2DD825221CFE4A65A87AA21DC8750481B9849DD81694C3357A0ED9B78D608D8EDDE28FAFBEC17844DE5709F41E121838DB55639D77E32A259A416D7013B2EB1259FDE1B498CBB9CAEE1D601DF3C915EA91C69B44E6B72062F5F4B3C73F06F2D5AD185E1692E2E0A01E7DD5133693681C52EE13B2BE42D03BDCF48E4E133CF06662339B778E1C3034F9939A433E157449172F7969ACCE1F5D2F65A4E09E4A5D5611EBEDDDBDB0C0C0A); - ---enable_view_protocol +select +load_file(0x0A9FB76C661B409C4BEC88098C5DD71B1072F9691F2E827D7EC8F092B299868A3CE196C04F0FB18CAB4E1557EB72331D812379DE7A75CA21C32E7C722C59E5CC33EF262EF04187B0F0EE756FA984DF2EAD37B1E4ADB064C3C5038F2E3B2D661B1C1150AAEB5425512E14D7506166D92D4533872E662F4B2D1428AAB5CCA72E75AA2EF325E196A5A02E2E8278873C64375845994B0F39BE2FF7B478332A7B0AA5E48877C47B6F513E997848AF8CCB8A899F3393AB35333CF0871E36698193862D486B4B9078B70C0A0A507B8A250F3F876F5A067632D5E65193E4445A1EC3A2C9B4C6F07AC334F0F62BC33357CB502E9B1C19D2398B6972AEC2EF21630F8C9134C4F7DD662D8AD7BDC9E19C46720F334B66C22D4BF32ED275144E20E7669FFCF6FC143667C9F02A577F32960FA9F2371BE1FA90E49CBC69C01531F140556854D588DD0E55E1307D78CA38E975CD999F9AEA604266329EE62BFB5ADDA67F549E211ECFBA906C60063696352ABB82AA782D25B17E872EA587871F450446DB1BAE0123D20404A8F2D2698B371002E986C8FCB969A99FF0E150A2709E2ED7633D02ADA87D5B3C9487D27B2BD9D21E2EC3215DCC3CDCD884371281B95A2E9987AAF82EB499C058D9C3E7DC1B66635F60DB121C72F929622DD47B6B2E69F59FF2AE6B63CC2EC60FFBA20EA50569DBAB5DAEFAEB4F03966C9637AB55662EDD28439155A82D053A5299448EDB2E7BEB0F62889E2F84E6C7F34B3212C9AAC32D521D5AB8480993F1906D5450FAB342A0FA6ED223E178BAC036B81E15783604C32A961EA1EF20BE2EBB93D34ED37BC03142B7583303E4557E48551E4BD7CBDDEA146D5485A5D212C35189F0BD6497E66912D2780A59A53B532E12C0A5ED1EC0445D96E8F2DD825221CFE4A65A87AA21DC8750481B9849DD81694C3357A0ED9B78D608D8EDDE28FAFBEC17844DE5709F41E121838DB55639D77E32A259A416D7013B2EB1259FDE1B498CBB9CAEE1D601DF3C915EA91C69B44E6B72062F5F4B3C73F06F2D5AD185E1692E2E0A01E7DD5133693681C52EE13B2BE42D03BDCF48E4E133CF06662339B778E1C3034F9939A433E157449172F7969ACCE1F5D2F65A4E09E4A5D5611EBEDDDBDB0C0C0A) as exp; --echo End of 5.0 tests diff --git a/mysql-test/main/log_slow.test b/mysql-test/main/log_slow.test index ea8b9127658..39467e7e800 100644 --- a/mysql-test/main/log_slow.test +++ b/mysql-test/main/log_slow.test @@ -185,6 +185,7 @@ drop function get_zero; --enable_view_protocol --enable_ps2_protocol +--enable_view_protocol --echo # --echo # End of 10.4 tests diff --git a/mysql-test/main/log_slow_debug.result b/mysql-test/main/log_slow_debug.result index 5f4f4c6a059..be825584ec3 100644 --- a/mysql-test/main/log_slow_debug.result +++ b/mysql-test/main/log_slow_debug.result @@ -301,15 +301,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_host.result b/mysql-test/main/long_host.result index 52b479b66f7..c11dcd5207c 100644 --- a/mysql-test/main/long_host.result +++ b/mysql-test/main/long_host.result @@ -19,9 +19,9 @@ create table mariadbtestdb2.t2 (a int); create table mariadbtestdb.t3 (a int); SET @saved_dbug = @@GLOBAL.debug_dbug; set global debug_dbug= "+d,vio_peer_addr_fake_ipv4,getnameinfo_fake_long_host,getaddrinfo_fake_good_ipv4"; +flush hosts; # check connect connect con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,; -connection con1; select current_user(); current_user() user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345 @@ -34,7 +34,6 @@ connection default; grant SELECT ON *.* TO user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,test,$MASTER_MYPORT,; -connection con1; select * from mariadbtestdb.t1; a b select * from mariadbtestdb2.t2; @@ -44,7 +43,6 @@ connection default; REVOKE ALL PRIVILEGES, GRANT OPTION FROM user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,; -connection con1; select * from mariadbtestdb.t1; ERROR 42000: SELECT command denied to user 'user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678'@'host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345' for table `mariadbtestdb`.`t1` select * from mariadbtestdb2.t2; @@ -54,7 +52,6 @@ connection default; grant SELECT ON mariadbtestdb.* TO user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,; -connection con1; select * from mariadbtestdb.t1; a b select * from mariadbtestdb2.t2; @@ -67,7 +64,6 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM user5678901_345678902_345678903_3456789 grant SELECT ON mariadbtestdb.t1 TO user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,; -connection con1; select * from mariadbtestdb.t1; a b select * from mariadbtestdb2.t2; @@ -80,7 +76,6 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM user5678901_345678902_345678903_3456789 grant SELECT (a) ON mariadbtestdb.t1 TO user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,; -connection con1; select * from mariadbtestdb.t1; ERROR 42000: SELECT command denied to user 'user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678'@'host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345' for table `mariadbtestdb`.`t1` select * from mariadbtestdb2.t2; @@ -100,7 +95,6 @@ GRANT CREATE ROUTINE on test.* to user5678901_345678902_345678903_345678904_3456 grant role5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678 to user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,test,$MASTER_MYPORT,; -connection con1; select * from mariadbtestdb.t1; ERROR 42000: SELECT command denied to user 'user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678'@'host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345' for table `mariadbtestdb`.`t1` select * from mariadbtestdb2.t2; diff --git a/mysql-test/main/long_host.test b/mysql-test/main/long_host.test index 301744a1f11..8ba1a12078c 100644 --- a/mysql-test/main/long_host.test +++ b/mysql-test/main/long_host.test @@ -33,11 +33,11 @@ create table mariadbtestdb.t3 (a int); SET @saved_dbug = @@GLOBAL.debug_dbug; set global debug_dbug= "+d,vio_peer_addr_fake_ipv4,getnameinfo_fake_long_host,getaddrinfo_fake_good_ipv4"; +flush hosts; --echo # check connect connect (con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,); -connection con1; select current_user(); --echo # check global privileges @@ -51,7 +51,6 @@ connection default; grant SELECT ON *.* TO user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect (con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,test,$MASTER_MYPORT,); -connection con1; select * from mariadbtestdb.t1; select * from mariadbtestdb2.t2; @@ -62,7 +61,6 @@ connection default; REVOKE ALL PRIVILEGES, GRANT OPTION FROM user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect (con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,); -connection con1; --error ER_TABLEACCESS_DENIED_ERROR select * from mariadbtestdb.t1; --error ER_TABLEACCESS_DENIED_ERROR @@ -75,7 +73,6 @@ connection default; grant SELECT ON mariadbtestdb.* TO user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect (con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,); -connection con1; select * from mariadbtestdb.t1; --error ER_TABLEACCESS_DENIED_ERROR select * from mariadbtestdb2.t2; @@ -88,7 +85,6 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM user5678901_345678902_345678903_3456789 grant SELECT ON mariadbtestdb.t1 TO user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect (con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,); -connection con1; select * from mariadbtestdb.t1; --error ER_TABLEACCESS_DENIED_ERROR select * from mariadbtestdb2.t2; @@ -102,7 +98,6 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM user5678901_345678902_345678903_3456789 grant SELECT (a) ON mariadbtestdb.t1 TO user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678@host5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678913_345678914_345678915_345678916_345678917_345678918_345678919_345678920_345678921_345678922_345678923_345678924_345678925_345; disconnect con1; connect (con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,"*NO-ONE*",$MASTER_MYPORT,); -connection con1; --error ER_TABLEACCESS_DENIED_ERROR select * from mariadbtestdb.t1; --error ER_TABLEACCESS_DENIED_ERROR @@ -132,7 +127,6 @@ grant role5678901_345678902_345678903_345678904_345678905_345678906_345678907_34 disconnect con1; connect (con1,"127.0.0.1","user5678901_345678902_345678903_345678904_345678905_345678906_345678907_345678908_345678909_345678910_345678911_345678912_345678",,test,$MASTER_MYPORT,); -connection con1; --error ER_TABLEACCESS_DENIED_ERROR select * from mariadbtestdb.t1; 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 c06b4169afe..ad6220dfa30 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/lotofstack.result b/mysql-test/main/lotofstack.result new file mode 100644 index 00000000000..553dcb3b1b4 --- /dev/null +++ b/mysql-test/main/lotofstack.result @@ -0,0 +1,101 @@ +create function bug10100f(prm int) returns int +begin +if prm > 1 then +return prm * bug10100f(prm - 1); +end if; +return 1; +end| +set statement sql_mode = '' for +create procedure bug10100p(prm int, inout res int) +begin +set res = res * prm; +if prm > 1 then +call bug10100p(prm - 1, res); +end if; +end| +set statement sql_mode = '' for +create procedure bug10100t(prm int) +begin +declare res int; +set res = 1; +call bug10100p(prm, res); +select res; +end| +create table t3 (a int)| +insert into t3 values (0)| +create view v1 as select a from t3| +create procedure bug10100pt(level int, lim int) +begin +if level < lim then +update t3 set a=level; +FLUSH TABLES; +call bug10100pt(level+1, lim); +else +select * from t3; +end if; +end| +create procedure bug10100pv(level int, lim int) +begin +if level < lim then +update v1 set a=level; +FLUSH TABLES; +call bug10100pv(level+1, lim); +else +select * from v1; +end if; +end| +prepare stmt2 from "select * from t3;"; +create procedure bug10100pd(level int, lim int) +begin +if level < lim then +select level; +prepare stmt1 from "update t3 set a=a+2"; +execute stmt1; +FLUSH TABLES; +execute stmt1; +FLUSH TABLES; +execute stmt1; +FLUSH TABLES; +deallocate prepare stmt1; +execute stmt2; +select * from t3; +call bug10100pd(level+1, lim); +else +execute stmt2; +end if; +end| +create procedure bug10100pc(level int, lim int) +begin +declare lv int; +declare c cursor for select a from t3; +open c; +if level < lim then +select level; +fetch c into lv; +select lv; +update t3 set a=level+lv; +FLUSH TABLES; +call bug10100pc(level+1, lim); +else +select * from t3; +end if; +close c; +end| +set @@max_sp_recursion_depth=255| +set @var=1| +call bug10100p(255, @var)| +call bug10100pt(1,255)| +call bug10100pv(1,255)| +call bug10100pd(1,255)| +call bug10100pc(1,255)| +set @@max_sp_recursion_depth=0| +deallocate prepare stmt2| +drop function bug10100f| +drop procedure bug10100p| +drop procedure bug10100t| +drop procedure bug10100pt| +drop procedure bug10100pv| +drop procedure bug10100pd| +drop procedure bug10100pc| +drop view v1| +drop table t3| diff --git a/mysql-test/main/lotofstack.test b/mysql-test/main/lotofstack.test new file mode 100644 index 00000000000..a658fb00e9f --- /dev/null +++ b/mysql-test/main/lotofstack.test @@ -0,0 +1,133 @@ +# +# For tests that need a lot of stack - they likely won't work under ASAN +# +source include/not_asan.inc; +source include/not_embedded.inc; + +# +# Bug#10100 function (and stored procedure?) recursivity problem +# +# routines with simple recursion +delimiter |; +create function bug10100f(prm int) returns int +begin + if prm > 1 then + return prm * bug10100f(prm - 1); + end if; + return 1; +end| +set statement sql_mode = '' for +create procedure bug10100p(prm int, inout res int) +begin + set res = res * prm; + if prm > 1 then + call bug10100p(prm - 1, res); + end if; +end| +set statement sql_mode = '' for +create procedure bug10100t(prm int) +begin + declare res int; + set res = 1; + call bug10100p(prm, res); + select res; +end| + +# a procedure which use tables and recursion +create table t3 (a int)| +insert into t3 values (0)| +create view v1 as select a from t3| +create procedure bug10100pt(level int, lim int) +begin + if level < lim then + update t3 set a=level; + FLUSH TABLES; + call bug10100pt(level+1, lim); + else + select * from t3; + end if; +end| +# view & recursion +create procedure bug10100pv(level int, lim int) +begin + if level < lim then + update v1 set a=level; + FLUSH TABLES; + call bug10100pv(level+1, lim); + else + select * from v1; + end if; +end| +# dynamic sql & recursion +prepare stmt2 from "select * from t3;"; +create procedure bug10100pd(level int, lim int) +begin + if level < lim then + select level; + prepare stmt1 from "update t3 set a=a+2"; + execute stmt1; + FLUSH TABLES; + execute stmt1; + FLUSH TABLES; + execute stmt1; + FLUSH TABLES; + deallocate prepare stmt1; + execute stmt2; + select * from t3; + call bug10100pd(level+1, lim); + else + execute stmt2; + end if; +end| +# cursor & recursion +create procedure bug10100pc(level int, lim int) +begin + declare lv int; + declare c cursor for select a from t3; + open c; + if level < lim then + select level; + fetch c into lv; + select lv; + update t3 set a=level+lv; + FLUSH TABLES; + call bug10100pc(level+1, lim); + else + select * from t3; + end if; + close c; +end| + +# end of the stack checking +set @@max_sp_recursion_depth=255| +set @var=1| +# disable log because error about stack overrun contains numbers which +# depend on a system +-- disable_ps_protocol +-- disable_result_log +-- error ER_STACK_OVERRUN_NEED_MORE +call bug10100p(255, @var)| +-- error ER_STACK_OVERRUN_NEED_MORE +call bug10100pt(1,255)| +-- error ER_STACK_OVERRUN_NEED_MORE +call bug10100pv(1,255)| +-- error ER_STACK_OVERRUN_NEED_MORE +call bug10100pd(1,255)| +-- error ER_STACK_OVERRUN_NEED_MORE +call bug10100pc(1,255)| +-- enable_result_log +-- enable_ps_protocol +set @@max_sp_recursion_depth=0| + +deallocate prepare stmt2| + +drop function bug10100f| +drop procedure bug10100p| +drop procedure bug10100t| +drop procedure bug10100pt| +drop procedure bug10100pv| +drop procedure bug10100pd| +drop procedure bug10100pc| +drop view v1| +drop table t3| +delimiter ;| diff --git a/mysql-test/main/lowercase_table2.result b/mysql-test/main/lowercase_table2.result index 05dd061732b..4180635e6af 100755 --- a/mysql-test/main/lowercase_table2.result +++ b/mysql-test/main/lowercase_table2.result @@ -357,6 +357,27 @@ drop user 'mysqltest_1'@'localhost'; drop tables a, B; drop database db1; # +# MDEV-32025 Crashes in MDL_key::mdl_key_init with lower-case-table-names=2 +# +CREATE DATABASE `#mysql50#D+b1`; +ALTER DATABASE `#mysql50#D+b1` UPGRADE DATA DIRECTORY NAME; +SHOW CREATE DATABASE `D+b1`; +Database Create Database +D+b1 CREATE DATABASE `D+b1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */ +SHOW CREATE DATABASE `d+b1`; +Database Create Database +d+b1 CREATE DATABASE `d+b1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */ +DROP DATABASE `D+b1`; +CREATE DATABASE Db1; +ALTER DATABASE Db1 DEFAULT CHARACTER SET utf8; +SHOW CREATE DATABASE Db1; +Database Create Database +Db1 CREATE DATABASE `Db1` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci */ +SHOW CREATE DATABASE db1; +Database Create Database +db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci */ +DROP DATABASE Db1; +# # MDEV-32026 lowercase_table2.test failures in 11.3 # CREATE DATABASE Db1; diff --git a/mysql-test/main/lowercase_table2.test b/mysql-test/main/lowercase_table2.test index 71b48c2ad54..3addb13e2f9 100644 --- a/mysql-test/main/lowercase_table2.test +++ b/mysql-test/main/lowercase_table2.test @@ -313,6 +313,22 @@ drop user 'mysqltest_1'@'localhost'; drop tables a, B; drop database db1; +--echo # +--echo # MDEV-32025 Crashes in MDL_key::mdl_key_init with lower-case-table-names=2 +--echo # + +CREATE DATABASE `#mysql50#D+b1`; +ALTER DATABASE `#mysql50#D+b1` UPGRADE DATA DIRECTORY NAME; +SHOW CREATE DATABASE `D+b1`; +SHOW CREATE DATABASE `d+b1`; +DROP DATABASE `D+b1`; + +CREATE DATABASE Db1; +ALTER DATABASE Db1 DEFAULT CHARACTER SET utf8; +SHOW CREATE DATABASE Db1; +SHOW CREATE DATABASE db1; +DROP DATABASE Db1; + --echo # --echo # MDEV-32026 lowercase_table2.test failures in 11.3 --echo # diff --git a/mysql-test/main/mdl.result b/mysql-test/main/mdl.result index 343895803b2..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; @@ -98,3 +98,47 @@ disconnect purge_control; connection default; disconnect locker; DROP TABLE t1,t3; +# +# MDEV-28820 MyISAM wrong server status flags +# +create table t1 (a int); +set autocommit=0; +select @@in_transaction; +@@in_transaction +0 +select * from t1; +a +select @@in_transaction; +@@in_transaction +0 +connect foo,localhost,root; +drop table t1; +connection default; +set autocommit=1; +create table t1 (a int); +create table t2 (b int) engine=innodb; +set autocommit=0; +select @@in_transaction; +@@in_transaction +0 +select * from t2; +b +select @@in_transaction; +@@in_transaction +1 +select * from t1; +a +connection foo; +drop table t1; +connection default; +select * from t1; +a +commit; +connection foo; +disconnect foo; +connection default; +set autocommit=default; +drop table t2; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/mdl.test b/mysql-test/main/mdl.test index 13c2caf097e..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; @@ -90,3 +90,48 @@ connection default; disconnect locker; DROP TABLE t1,t3; --enable_service_connection + +--echo # +--echo # MDEV-28820 MyISAM wrong server status flags +--echo # +--disable_view_protocol +# MyISAM alone doesn't start a transaction or takes transactional MDL +create table t1 (a int); +set autocommit=0; +select @@in_transaction; +select * from t1; +select @@in_transaction; +connect foo,localhost,root; +drop table t1; +connection default; +set autocommit=1; + +# MyISAM in a transaction (started by InnoDB) takes transactional MDL all right +create table t1 (a int); +create table t2 (b int) engine=innodb; +set autocommit=0; +select @@in_transaction; +select * from t2; +select @@in_transaction; +select * from t1; +connection foo; +send drop table t1; +connection default; +let $wait_condition= + select count(*) > 0 from information_schema.processlist + where state = "Waiting for table metadata lock"; +--source include/wait_condition.inc +select * from t1; +commit; + +connection foo; +reap; +disconnect foo; +connection default; +set autocommit=default; +drop table t2; +--enable_view_protocol + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/main/mdl_sync.result b/mysql-test/main/mdl_sync.result index 939e6a01ed2..032b686bae5 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 ca91528882e..27e2ff4393c 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/metadata.result b/mysql-test/main/metadata.result index ab28cab52cb..3bd9dde4a6c 100644 --- a/mysql-test/main/metadata.result +++ b/mysql-test/main/metadata.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2; select 1, 1.0, -1, "hello", NULL; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def 1 3 1 1 N 32897 0 63 @@ -222,6 +221,9 @@ def v3 v3 renamed renamed 8 12 0 Y 32896 0 63 renamed drop table t1; drop view v1,v2,v3; +# +# End of 4.1 tests +# select a.* from (select 2147483648 as v_large) a; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def a v_large v_large 8 10 10 N 32769 0 63 @@ -301,7 +303,9 @@ def test va va f1 f1 3 11 0 Y 32768 0 63 f1 DROP VIEW v1; DROP TABLE t1; -End of 5.0 tests +# +# End of 5.0 tests +# create table t1( # numeric types bool_col bool, @@ -802,3 +806,6 @@ t1 CREATE TABLE `t1` ( `@b2:=111111111111` bigint(12) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1; +# +# End of 10.3 tests +# diff --git a/mysql-test/main/metadata.test b/mysql-test/main/metadata.test index 6cbf99d16b7..7cfdef5e118 100644 --- a/mysql-test/main/metadata.test +++ b/mysql-test/main/metadata.test @@ -4,9 +4,6 @@ #View protocol gives slightly different metadata --source include/no_view_protocol.inc ---disable_warnings -drop table if exists t1,t2; ---enable_warnings --enable_metadata # PS protocol gives slightly different metadata --disable_ps_protocol @@ -127,7 +124,9 @@ drop table t1; drop view v1,v2,v3; --disable_metadata -# End of 4.1 tests +--echo # +--echo # End of 4.1 tests +--echo # # # Bug #28492: subselect returns LONG in >5.0.24a and LONGLONG in <=5.0.24a @@ -189,7 +188,9 @@ SELECT f1 FROM v1 va; DROP VIEW v1; DROP TABLE t1; ---echo End of 5.0 tests +--echo # +--echo # End of 5.0 tests +--echo # # Verify that column metadata is correct for all possible data types. # Originally about BUG#42980 "Client doesn't set NUM_FLAG for DECIMAL" @@ -485,3 +486,7 @@ SELECT @b1:=10, @b2:=@b2:=111111111111; CREATE TABLE t1 AS SELECT @b1:=10, @b2:=111111111111; SHOW CREATE TABLE t1; DROP TABLE t1; + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/main/mrr_icp_extra.result b/mysql-test/main/mrr_icp_extra.result index 1b33b008f35..48b3b91d271 100644 --- a/mysql-test/main/mrr_icp_extra.result +++ b/mysql-test/main/mrr_icp_extra.result @@ -38,18 +38,24 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where +Warnings: +Note 1105 Cannot use key `s2` part[0] for lookup: `test`.`t1`.`s2` of collation `latin1_swedish_ci` >= "'a'" of collation `latin1_german1_ci` EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition; Rowid-ordered scan EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where +Warnings: +Note 1105 Cannot use key `s2` part[0] for lookup: `test`.`t1`.`s2` of collation `latin1_swedish_ci` = "'a'" of collation `latin1_german1_ci` EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range s1 s1 11 NULL 1 Using index condition; Rowid-ordered scan EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where +Warnings: +Note 1105 Cannot use key `s2` part[0] for lookup: `test`.`t1`.`s2` of collation `latin1_swedish_ci` like "'a' collate latin1_german1_ci" of collation `latin1_german1_ci` DROP TABLE t1; # # diff --git a/mysql-test/main/myisam_explain_non_select_all.result b/mysql-test/main/myisam_explain_non_select_all.result index b036d4870cd..9741d641161 100644 --- a/mysql-test/main/myisam_explain_non_select_all.result +++ b/mysql-test/main/myisam_explain_non_select_all.result @@ -1385,7 +1385,7 @@ EXPLAIN DELETE FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where; Using filesort Warnings: -Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` > "10" of type `int` Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` <= "18" of type `int` FLUSH STATUS; FLUSH TABLES; @@ -1393,7 +1393,7 @@ EXPLAIN EXTENDED DELETE FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 26 100.00 Using where; Using filesort Warnings: -Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` > "10" of type `int` Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` <= "18" of type `int` Note 1003 delete from `test`.`t1` using dual where `test`.`t1`.`i` > 10 and `test`.`t1`.`i` <= 18 order by `test`.`t1`.`i` limit 5 # Status of EXPLAIN EXTENDED query @@ -1405,7 +1405,9 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL i NULL NULL NULL 26 100.00 Using where; Using filesort Warnings: -Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` > "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` <= "18" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` > "10" of type `int` Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` <= "18" of type `int` Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`i` AS `i` from `test`.`t1` where `test`.`t1`.`i` > 10 and `test`.`t1`.`i` <= 18 order by `test`.`t1`.`i` limit 5 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution @@ -1427,6 +1429,67 @@ Handler_read_rnd_next 27 Sort_rows 8 Sort_scan 1 +DROP TABLE t1; +#30a +# +# MDEV-32957 Unusable key notes report wrong predicates for > and >= +# +CREATE TABLE t1(a INT, i CHAR(2), INDEX(i(1))); +INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), +(20),(21),(22),(23),(24),(25),(26),(27),(28),(29), +(30),(31),(32),(33),(34),(35); +# +# query: DELETE FROM t1 WHERE i >= 10 AND i < 18 ORDER BY i LIMIT 5 +# select: SELECT * FROM t1 WHERE i >= 10 AND i < 18 ORDER BY i LIMIT 5 +# +EXPLAIN DELETE FROM t1 WHERE i >= 10 AND i < 18 ORDER BY i LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where; Using filesort +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` < "18" of type `int` +FLUSH STATUS; +FLUSH TABLES; +EXPLAIN EXTENDED DELETE FROM t1 WHERE i >= 10 AND i < 18 ORDER BY i LIMIT 5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 100.00 Using where; Using filesort +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` < "18" of type `int` +Note 1003 delete from `test`.`t1` using dual where `test`.`t1`.`i` >= 10 and `test`.`t1`.`i` < 18 order by `test`.`t1`.`i` limit 5 +# Status of EXPLAIN EXTENDED query +Variable_name Value +Handler_read_key 4 +FLUSH STATUS; +FLUSH TABLES; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE i >= 10 AND i < 18 ORDER BY i LIMIT 5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL i NULL NULL NULL 26 100.00 Using where; Using filesort +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` < "18" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` < "18" of type `int` +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`i` AS `i` from `test`.`t1` where `test`.`t1`.`i` >= 10 and `test`.`t1`.`i` < 18 order by `test`.`t1`.`i` limit 5 +# Status of EXPLAIN EXTENDED "equivalent" SELECT query execution +Variable_name Value +Handler_read_key 4 +# Status of "equivalent" SELECT query execution: +Variable_name Value +Handler_read_key 4 +Handler_read_rnd_next 27 +Sort_priority_queue_sorts 1 +Sort_rows 5 +Sort_scan 1 +# Status of testing query execution: +Variable_name Value +Handler_delete 5 +Handler_read_key 4 +Handler_read_rnd 5 +Handler_read_rnd_next 27 +Sort_rows 8 +Sort_scan 1 + DROP TABLE t1; #31 CREATE TABLE t1 (i INT); @@ -1892,7 +1955,7 @@ EXPLAIN UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using where; Using filesort Warnings: -Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` > "10" of type `int` Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` <= "18" of type `int` FLUSH STATUS; FLUSH TABLES; @@ -1900,7 +1963,7 @@ EXPLAIN EXTENDED UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 26 100.00 Using where; Using filesort Warnings: -Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` > "10" of type `int` Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` <= "18" of type `int` Note 1003 update `test`.`t2` set `test`.`t2`.`a` = 10 where `test`.`t2`.`i` > 10 and `test`.`t2`.`i` <= 18 order by `test`.`t2`.`i` limit 5 # Status of EXPLAIN EXTENDED query @@ -1912,7 +1975,9 @@ EXPLAIN EXTENDED SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL i NULL NULL NULL 26 100.00 Using where; Using filesort Warnings: -Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` > "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` <= "18" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` > "10" of type `int` Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t2`.`i` of type `char` <= "18" of type `int` Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`i` AS `i` from `test`.`t2` where `test`.`t2`.`i` > 10 and `test`.`t2`.`i` <= 18 order by `test`.`t2`.`i` limit 5 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution diff --git a/mysql-test/main/myisam_icp.result b/mysql-test/main/myisam_icp.result index 2ffd2d9ad4b..1c06c6d87ff 100644 --- a/mysql-test/main/myisam_icp.result +++ b/mysql-test/main/myisam_icp.result @@ -149,7 +149,7 @@ INSERT INTO t1 VALUES # Execute select with invalid timestamp, desc ordering SELECT * -FROM t1 +FROM t1 FORCE INDEX(PRIMARY) WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; @@ -160,7 +160,7 @@ ts c # Should use index condition EXPLAIN SELECT * -FROM t1 +FROM t1 FORCE INDEX(PRIMARY) WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; @@ -422,6 +422,12 @@ CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL); INSERT INTO t2 VALUES (11,1); INSERT INTO t2 VALUES (12,2); INSERT INTO t2 VALUES (15,4); +analyze table t1,t2 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK set @save_optimizer_switch= @@optimizer_switch; set optimizer_switch='semijoin=off'; EXPLAIN @@ -691,6 +697,12 @@ CREATE TABLE t2 (a varchar(1024), KEY (a(512))); INSERT INTO t2 VALUES ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w'); insert into t2 select seq from seq_1_to_100; +analyze table t1,t2 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK SET SESSION optimizer_switch='index_condition_pushdown=off'; EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) diff --git a/mysql-test/main/myisam_recover.result b/mysql-test/main/myisam_recover.result index 87fe754d072..2d487719e2a 100644 --- a/mysql-test/main/myisam_recover.result +++ b/mysql-test/main/myisam_recover.result @@ -22,7 +22,6 @@ call mtr.add_suppression(" '\..test.t1'"); set @save_table_open_cache=@@table_open_cache; set global table_open_cache=256; set global table_definition_cache=400; -drop procedure if exists p_create; create procedure p_create() begin declare i int default 1; @@ -44,13 +43,13 @@ end while; end| call p_create(); drop procedure p_create; +$lock; connection default; # # We have to disable the ps-protocol, to avoid # "Prepared statement needs to be re-prepared" errors # -- table def versions change all the time with full table cache. # -drop table if exists t1, t1_mrg, t1_copy; # # Prepare a MERGE engine table, that refers to a corrupted # child. @@ -127,7 +126,7 @@ test.t1 check error Record-count is not ok; is 2 Should be: 1 test.t1 check warning Found 2 key parts. Should be: 1 test.t1 check error Corrupt # At this point we have a corrupt t1 -set autocommit = 0; +start transaction; select * from t2; a 1 @@ -146,7 +145,6 @@ ALTER TABLE t2 ADD val INT; connection default; # With fix we should have alter table waiting for t2 lock here. ROLLBACK; -SET autocommit = 1; connection con2; connection default; disconnect con2; diff --git a/mysql-test/main/myisam_recover.test b/mysql-test/main/myisam_recover.test index 6fe250197d5..65062eb1e96 100644 --- a/mysql-test/main/myisam_recover.test +++ b/mysql-test/main/myisam_recover.test @@ -28,9 +28,6 @@ call mtr.add_suppression(" '\..test.t1'"); set @save_table_open_cache=@@table_open_cache; set global table_open_cache=256; set global table_definition_cache=400; ---disable_warnings -drop procedure if exists p_create; ---enable_warnings delimiter |; create procedure p_create() begin @@ -54,10 +51,9 @@ end| delimiter ;| call p_create(); drop procedure p_create; ---disable_query_log let $lock=`select @lock_table_stmt`; -eval $lock; ---enable_query_log +evalp $lock; + connection default; --echo # --echo # We have to disable the ps-protocol, to avoid @@ -65,9 +61,6 @@ connection default; --echo # -- table def versions change all the time with full table cache. --echo # --disable_ps_protocol ---disable_warnings -drop table if exists t1, t1_mrg, t1_copy; ---enable_warnings let $MYSQLD_DATADIR=`select @@datadir`; --echo # --echo # Prepare a MERGE engine table, that refers to a corrupted @@ -142,7 +135,7 @@ flush table t1; check table t1; --echo # At this point we have a corrupt t1 -set autocommit = 0; +start transaction; select * from t2; --echo # Without fix select from t1 will break the transaction. After the fix --echo # transaction should be active and should hold lock on table t2. Alter @@ -151,20 +144,18 @@ select * from t2; select * from t1; connect(con2, localhost, root); ---SEND ALTER TABLE t2 ADD val INT +--send ALTER TABLE t2 ADD val INT connection default; --echo # With fix we should have alter table waiting for t2 lock here. let $wait_condition= SELECT count(*) = 1 FROM information_schema.processlist WHERE state LIKE "Waiting%" AND info = "ALTER TABLE t2 ADD val INT"; - --source include/wait_condition.inc ROLLBACK; -SET autocommit = 1; connection con2; ---REAP +--reap connection default; disconnect con2; diff --git a/mysql-test/main/mysql_connector_net.ps1 b/mysql-test/main/mysql_connector_net.ps1 new file mode 100644 index 00000000000..159acf9361c --- /dev/null +++ b/mysql-test/main/mysql_connector_net.ps1 @@ -0,0 +1,58 @@ +$assembly = [system.reflection.Assembly]::LoadWithPartialName("MySql.Data") +if ($assembly -eq $null) +{ + "Can't load assembly MySql.Data" + exit 100 +} + +try +{ + $connectionString =[string]::Format("server=127.0.0.1;uid=root;port={0};Connection Reset=true;",$Env:MASTER_MYPORT) + $connection = [MySql.Data.MySqlClient.MySqlConnection]@{ConnectionString=$connectionString} + $connection.Open() + + # Test ExecuteReader() + $command = New-Object MySql.Data.MySqlClient.MySqlCommand + $command.Connection = $connection + $command.CommandText = "SELECT @@old_mode" + $reader = $command.ExecuteReader() + $reader.GetName(0) + while ($reader.Read()) + { + $reader.GetValue(0) + } + + # Test connection reset + $connection.Close() + $connection.Open() + # Test ExecuteNonQuery() + $command.CommandText="do 1"; + $affected_rows = $command.ExecuteNonQuery() + if ($affected_rows -ne 0) + { + "Expected affected rows 0, actual $affected_rows" + exit 1 + } + # Test Prepared Statement + $command.CommandText = "SELECT @var"; + [void]$command.Parameters.AddWithValue("@var", 1); + $command.Prepare(); + $out = $command.ExecuteScalar(); + if ($out -ne 1) + { + "Expected output 1, actual $out" + exit 1 + } + $connection.Close() +} +catch +{ + # Dump exception + $_ + $inner = $PSItem.Exception.InnerException + if ($inner -ne $null) + { + $PSItem.Exception.InnerException.Message + $PSItem.Exception.InnerException.StackTrace + } +} diff --git a/mysql-test/main/mysql_connector_net.result b/mysql-test/main/mysql_connector_net.result new file mode 100644 index 00000000000..f2fa39df3e7 --- /dev/null +++ b/mysql-test/main/mysql_connector_net.result @@ -0,0 +1,2 @@ +@@old_mode +UTF8_IS_UTF8MB3,NO_NULL_COLLATION_IDS diff --git a/mysql-test/main/mysql_connector_net.test b/mysql-test/main/mysql_connector_net.test new file mode 100644 index 00000000000..c1dce65adc8 --- /dev/null +++ b/mysql-test/main/mysql_connector_net.test @@ -0,0 +1,11 @@ +--source include/windows.inc +let $sys_errno=0; + +# Error 100 is returned by the powershell script +# if MySql.Data is not installed +--error 0,100 +--exec powershell -NoLogo -NoProfile -File main\mysql_connector_net.ps1 +if ($sys_errno != 0) +{ + --skip Connector/NET is not installed +} diff --git a/mysql-test/main/mysql_install_db_win.test b/mysql-test/main/mysql_install_db_win.test index f6113847b8d..f0ce4805e46 100644 --- a/mysql-test/main/mysql_install_db_win.test +++ b/mysql-test/main/mysql_install_db_win.test @@ -24,7 +24,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/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result index 1924fe3d0ce..0232c20d766 100644 --- a/mysql-test/main/mysql_upgrade.result +++ b/mysql-test/main/mysql_upgrade.result @@ -2363,6 +2363,170 @@ disconnect con1; connection default; drop table mysql.global_priv; rename table mysql.global_priv_bak to mysql.global_priv; +# +# mariadb-upgrade fails with sql_safe_updates = on +# +set @orig_sql_safe_updates = @@GLOBAL.sql_safe_updates; +set global sql_safe_updates=ON; +Phase 1/8: Checking and upgrading mysql database +Processing databases +mysql +mysql.column_stats OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.global_priv OK +mysql.gtid_slave_pos OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.index_stats OK +mysql.innodb_index_stats OK +mysql.innodb_table_stats OK +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.proxies_priv OK +mysql.roles_mapping OK +mysql.servers OK +mysql.table_stats OK +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.transaction_registry OK +Phase 2/8: Installing used storage engines... Skipped +Phase 3/8: Running 'mysql_fix_privilege_tables' +Phase 4/8: Fixing views +mysql.user OK +sys.host_summary OK +sys.host_summary_by_file_io OK +sys.host_summary_by_file_io_type OK +sys.host_summary_by_stages OK +sys.host_summary_by_statement_latency OK +sys.host_summary_by_statement_type OK +sys.innodb_buffer_stats_by_schema OK +sys.innodb_buffer_stats_by_table OK +sys.innodb_lock_waits OK +sys.io_by_thread_by_latency OK +sys.io_global_by_file_by_bytes OK +sys.io_global_by_file_by_latency OK +sys.io_global_by_wait_by_bytes OK +sys.io_global_by_wait_by_latency OK +sys.latest_file_io OK +sys.memory_by_host_by_current_bytes OK +sys.memory_by_thread_by_current_bytes OK +sys.memory_by_user_by_current_bytes OK +sys.memory_global_by_current_bytes OK +sys.memory_global_total OK +sys.metrics OK +sys.privileges_by_table_by_level OK +sys.processlist OK +sys.ps_check_lost_instrumentation OK +sys.schema_auto_increment_columns OK +sys.schema_index_statistics OK +sys.schema_object_overview OK +sys.schema_redundant_indexes OK +sys.schema_table_lock_waits OK +sys.schema_table_statistics OK +sys.schema_table_statistics_with_buffer OK +sys.schema_tables_with_full_table_scans OK +sys.schema_unused_indexes OK +sys.session OK +sys.session_ssl_status OK +sys.statement_analysis OK +sys.statements_with_errors_or_warnings OK +sys.statements_with_full_table_scans OK +sys.statements_with_runtimes_in_95th_percentile OK +sys.statements_with_sorting OK +sys.statements_with_temp_tables OK +sys.user_summary OK +sys.user_summary_by_file_io OK +sys.user_summary_by_file_io_type OK +sys.user_summary_by_stages OK +sys.user_summary_by_statement_latency OK +sys.user_summary_by_statement_type OK +sys.version OK +sys.wait_classes_global_by_avg_latency OK +sys.wait_classes_global_by_latency OK +sys.waits_by_host_by_latency OK +sys.waits_by_user_by_latency OK +sys.waits_global_by_latency OK +sys.x$host_summary OK +sys.x$host_summary_by_file_io OK +sys.x$host_summary_by_file_io_type OK +sys.x$host_summary_by_stages OK +sys.x$host_summary_by_statement_latency OK +sys.x$host_summary_by_statement_type OK +sys.x$innodb_buffer_stats_by_schema OK +sys.x$innodb_buffer_stats_by_table OK +sys.x$innodb_lock_waits OK +sys.x$io_by_thread_by_latency OK +sys.x$io_global_by_file_by_bytes OK +sys.x$io_global_by_file_by_latency OK +sys.x$io_global_by_wait_by_bytes OK +sys.x$io_global_by_wait_by_latency OK +sys.x$latest_file_io OK +sys.x$memory_by_host_by_current_bytes OK +sys.x$memory_by_thread_by_current_bytes OK +sys.x$memory_by_user_by_current_bytes OK +sys.x$memory_global_by_current_bytes OK +sys.x$memory_global_total OK +sys.x$processlist OK +sys.x$ps_digest_95th_percentile_by_avg_us OK +sys.x$ps_digest_avg_latency_distribution OK +sys.x$ps_schema_table_statistics_io OK +sys.x$schema_flattened_keys OK +sys.x$schema_index_statistics OK +sys.x$schema_table_lock_waits OK +sys.x$schema_table_statistics OK +sys.x$schema_table_statistics_with_buffer OK +sys.x$schema_tables_with_full_table_scans OK +sys.x$session OK +sys.x$statement_analysis OK +sys.x$statements_with_errors_or_warnings OK +sys.x$statements_with_full_table_scans OK +sys.x$statements_with_runtimes_in_95th_percentile OK +sys.x$statements_with_sorting OK +sys.x$statements_with_temp_tables OK +sys.x$user_summary OK +sys.x$user_summary_by_file_io OK +sys.x$user_summary_by_file_io_type OK +sys.x$user_summary_by_stages OK +sys.x$user_summary_by_statement_latency OK +sys.x$user_summary_by_statement_type OK +sys.x$wait_classes_global_by_avg_latency OK +sys.x$wait_classes_global_by_latency OK +sys.x$waits_by_host_by_latency OK +sys.x$waits_by_user_by_latency OK +sys.x$waits_global_by_latency OK +Phase 5/8: Fixing table and database names +Phase 6/8: Checking and upgrading tables +Processing databases +information_schema +mtr +mtr.global_suppressions OK +mtr.test_suppressions OK +performance_schema +sys +sys.sys_config OK +test +Phase 7/8: uninstalling plugins +Phase 8/8: Running 'FLUSH PRIVILEGES' +OK +set global sql_safe_updates=@orig_sql_safe_updates; +# +# MDEV-32043 Remove plugins previously external that are now built in (unix_socket) +# +INSERT INTO mysql.plugin SELECT 'unix_socket', 'auth_socket.so' + FROM dual WHERE convert(@@version_compile_os using latin1) not in ('Win32', 'Win64', 'Windows'); +# mariadb-upgrade --force --silent 2>&1 +SELECT * FROM mysql.plugin WHERE name='unix_socket'; +name dl # End of 10.4 tests # # Check that mysql_upgrade can be run on mysqldump diff --git a/mysql-test/main/mysql_upgrade.test b/mysql-test/main/mysql_upgrade.test index 8d2a3334d7c..42efb4174d8 100644 --- a/mysql-test/main/mysql_upgrade.test +++ b/mysql-test/main/mysql_upgrade.test @@ -507,6 +507,27 @@ drop table mysql.global_priv; rename table mysql.global_priv_bak to mysql.global_priv; --remove_file $MYSQLD_DATADIR/mariadb_upgrade_info +--echo # +--echo # mariadb-upgrade fails with sql_safe_updates = on +--echo # + +set @orig_sql_safe_updates = @@GLOBAL.sql_safe_updates; +set global sql_safe_updates=ON; +--exec $MYSQL_UPGRADE --force 2>&1 +--remove_file $MYSQLD_DATADIR/mariadb_upgrade_info +set global sql_safe_updates=@orig_sql_safe_updates; + +--echo # +--echo # MDEV-32043 Remove plugins previously external that are now built in (unix_socket) +--echo # + +INSERT INTO mysql.plugin SELECT 'unix_socket', 'auth_socket.so' + FROM dual WHERE convert(@@version_compile_os using latin1) not in ('Win32', 'Win64', 'Windows'); +--echo # mariadb-upgrade --force --silent 2>&1 +--exec $MYSQL_UPGRADE --force --silent 2>&1 +SELECT * FROM mysql.plugin WHERE name='unix_socket'; +--remove_file $MYSQLD_DATADIR/mariadb_upgrade_info + --echo # End of 10.4 tests # diff --git a/mysql-test/main/mysql_upgrade_file_leak.result b/mysql-test/main/mysql_upgrade_file_leak.result new file mode 100644 index 00000000000..648a0c97802 --- /dev/null +++ b/mysql-test/main/mysql_upgrade_file_leak.result @@ -0,0 +1,4 @@ +Running mysql_upgrade with --check-if-upgrade-is-needed +Checking for absence of temporary files by mysql_upgrade +No temporary files found +End of 10.4 tests diff --git a/mysql-test/main/mysql_upgrade_file_leak.test b/mysql-test/main/mysql_upgrade_file_leak.test new file mode 100644 index 00000000000..7f1a0495161 --- /dev/null +++ b/mysql-test/main/mysql_upgrade_file_leak.test @@ -0,0 +1,24 @@ +-- source include/mysql_upgrade_preparation.inc + +# +# MDEV-31925 mysqld_upgrade --check-if-upgrade-is-needed leaks files +# + +# Run mysql_upgrade with --check-if-upgrade-is-needed +--echo Running mysql_upgrade with --check-if-upgrade-is-needed +--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed 2>&1 + +# Check if temporary files related to mysql_upgrade are cleared +--echo Checking for absence of temporary files by mysql_upgrade +--perl + +# Use the temporary directory path from the MySQL configuration +my $tmpdir = "$ENV{MYSQL_TMP_DIR}"; + +die "Test failed: Found temporary file left by mysql_upgrade\n" if (glob("$tmpdir/mysql_upgrade-*")); +print "No temporary files found\n"; +EOF + +let $MYSQLD_DATADIR= `select @@datadir`; +--remove_file $MYSQLD_DATADIR/mariadb_upgrade_info +--echo End of 10.4 tests diff --git a/mysql-test/main/mysql_json_mysql_upgrade.result b/mysql-test/main/mysql_upgrade_mysql_json.result similarity index 100% rename from mysql-test/main/mysql_json_mysql_upgrade.result rename to mysql-test/main/mysql_upgrade_mysql_json.result diff --git a/mysql-test/main/mysql_json_mysql_upgrade.test b/mysql-test/main/mysql_upgrade_mysql_json.test similarity index 100% rename from mysql-test/main/mysql_json_mysql_upgrade.test rename to mysql-test/main/mysql_upgrade_mysql_json.test diff --git a/mysql-test/main/mysql_upgrade_mysql_json_system_tables.result b/mysql-test/main/mysql_upgrade_mysql_json_system_tables.result new file mode 100644 index 00000000000..237b19c4429 --- /dev/null +++ b/mysql-test/main/mysql_upgrade_mysql_json_system_tables.result @@ -0,0 +1,94 @@ +# +# MDEV-32462: mysql_upgrade -s still checks for non system tables +# +call mtr.add_suppression("Table rebuild required"); +SET NAMES utf8; +# mariadb_upgrade on system and user table +show tables from mysql like '%json%'; +Tables_in_mysql (%json%) +mysql_json_test +use mysql; +show create table mysql.mysql_json_test; +ERROR HY000: Unknown data type: 'MYSQL_JSON' +show create table test.mysql_json_test; +ERROR HY000: Unknown data type: 'MYSQL_JSON' +SET @old_general_log= @@global.general_log; +SET @old_log_output= @@global.log_output; +SET @@global.general_log = ON; +SET @@global.log_output = "TABLE"; +The --upgrade-system-tables option was used, user tables won't be touched. +Phase 1/8: Checking and upgrading mysql database +Processing databases +mysql +mysql.column_stats OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.global_priv OK +mysql.gtid_slave_pos OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.index_stats OK +mysql.innodb_index_stats +Error : Unknown storage engine 'InnoDB' +error : Corrupt +mysql.innodb_table_stats +Error : Unknown storage engine 'InnoDB' +error : Corrupt +mysql.mysql_json_test +Error : Unknown data type: 'MYSQL_JSON' +error : Corrupt +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.proxies_priv OK +mysql.roles_mapping OK +mysql.servers OK +mysql.table_stats OK +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.transaction_registry +Error : Unknown storage engine 'InnoDB' +error : Corrupt + +Repairing tables +mysql.innodb_index_stats +Error : Unknown storage engine 'InnoDB' +error : Corrupt +mysql.innodb_table_stats +Error : Unknown storage engine 'InnoDB' +error : Corrupt +mysql.mysql_json_test +Error : Unknown data type: 'MYSQL_JSON' +error : Corrupt +mysql.transaction_registry +Error : Unknown storage engine 'InnoDB' +error : Corrupt +Phase 2/8: Installing used storage engines... Skipped +Phase 3/8: Running 'mysql_fix_privilege_tables' +Phase 4/8: Fixing views... Skipped +Phase 5/8: Fixing table and database names ... Skipped +Phase 6/8: Checking and upgrading tables... Skipped +Phase 7/8: uninstalling plugins +Phase 8/8: Running 'FLUSH PRIVILEGES' +OK +SET @@global.general_log = @old_general_log; +SET @@global.log_output = @old_log_output; +select command_type, argument from mysql.general_log where argument like "%SELECT table_comment FROM information_schema.tables%"; +command_type argument +show create table mysql.mysql_json_test; +ERROR HY000: Unknown data type: 'MYSQL_JSON' +show create table test.mysql_json_test; +ERROR HY000: Unknown data type: 'MYSQL_JSON' +drop table mysql.mysql_json_test; +drop table test.mysql_json_test; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/mysql_upgrade_mysql_json_system_tables.test b/mysql-test/main/mysql_upgrade_mysql_json_system_tables.test new file mode 100644 index 00000000000..2410892ab4d --- /dev/null +++ b/mysql-test/main/mysql_upgrade_mysql_json_system_tables.test @@ -0,0 +1,52 @@ +--echo # +--echo # MDEV-32462: mysql_upgrade -s still checks for non system tables +--echo # + +# Let's now load plugin first +--source include/have_utf8.inc +--source include/not_embedded.inc + +--source include/mysql_upgrade_preparation.inc +call mtr.add_suppression("Table rebuild required"); + +SET NAMES utf8; + +let $MYSQLD_DATADIR= `select @@datadir`; + +--echo # mariadb_upgrade on system and user table +--copy_file std_data/mysql_json/mysql_json_test.frm $MYSQLD_DATADIR/mysql/mysql_json_test.frm +--copy_file std_data/mysql_json/mysql_json_test.MYI $MYSQLD_DATADIR/mysql/mysql_json_test.MYI +--copy_file std_data/mysql_json/mysql_json_test.MYD $MYSQLD_DATADIR/mysql/mysql_json_test.MYD +--copy_file std_data/mysql_json/mysql_json_test.frm $MYSQLD_DATADIR/test/mysql_json_test.frm +--copy_file std_data/mysql_json/mysql_json_test.MYI $MYSQLD_DATADIR/test/mysql_json_test.MYI +--copy_file std_data/mysql_json/mysql_json_test.MYD $MYSQLD_DATADIR/test/mysql_json_test.MYD + +show tables from mysql like '%json%'; +use mysql; +--error ER_UNKNOWN_DATA_TYPE +show create table mysql.mysql_json_test; +--error ER_UNKNOWN_DATA_TYPE +show create table test.mysql_json_test; + +SET @old_general_log= @@global.general_log; +SET @old_log_output= @@global.log_output; +SET @@global.general_log = ON; +SET @@global.log_output = "TABLE"; +--exec $MYSQL_UPGRADE -s --force 2>&1 +--remove_file $MYSQLD_DATADIR/mariadb_upgrade_info +SET @@global.general_log = @old_general_log; +SET @@global.log_output = @old_log_output; + +select command_type, argument from mysql.general_log where argument like "%SELECT table_comment FROM information_schema.tables%"; + +# User table is not upgraded in `mysql\test` DB, so we cannot see it. +--error ER_UNKNOWN_DATA_TYPE +show create table mysql.mysql_json_test; +--error ER_UNKNOWN_DATA_TYPE +show create table test.mysql_json_test; +drop table mysql.mysql_json_test; +drop table test.mysql_json_test; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/main/mysql_json_mysql_upgrade_with_plugin_loaded.result b/mysql-test/main/mysql_upgrade_mysql_json_with_plugin_loaded.result similarity index 100% rename from mysql-test/main/mysql_json_mysql_upgrade_with_plugin_loaded.result rename to mysql-test/main/mysql_upgrade_mysql_json_with_plugin_loaded.result diff --git a/mysql-test/main/mysql_json_mysql_upgrade_with_plugin_loaded.test b/mysql-test/main/mysql_upgrade_mysql_json_with_plugin_loaded.test similarity index 100% rename from mysql-test/main/mysql_json_mysql_upgrade_with_plugin_loaded.test rename to mysql-test/main/mysql_upgrade_mysql_json_with_plugin_loaded.test diff --git a/mysql-test/main/mysqld--help,win.rdiff b/mysql-test/main/mysqld--help,win.rdiff index 3e9541d7d2f..a42c0c6f81f 100644 --- a/mysql-test/main/mysqld--help,win.rdiff +++ b/mysql-test/main/mysqld--help,win.rdiff @@ -1,4 +1,6 @@ -@@ -180,6 +180,7 @@ +--- main/mysqld--help.result 2023-11-30 02:21:51.951132200 +0100 ++++ main/mysqld--help,win.reject 2023-11-30 02:35:44.404612300 +0100 +@@ -191,6 +191,7 @@ --console Write error output on screen; don't remove the console window on windows. --core-file Write core on crashes @@ -6,7 +8,7 @@ -h, --datadir=name Path to the database root directory --date-format=name The DATE format (ignored) --datetime-format=name -@@ -650,6 +651,7 @@ +@@ -696,6 +697,7 @@ Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME, DATETIME, TIMESTAMP columns. (Defaults to on; use --skip-mysql56-temporal-format to disable.) @@ -14,7 +16,7 @@ --net-buffer-length=# Buffer length for TCP/IP and socket communication --net-read-timeout=# -@@ -1327,6 +1328,10 @@ +@@ -1351,6 +1353,10 @@ Alias for log_slow_query_file. Log slow queries to given log file. Defaults logging to 'hostname'-slow.log. Must be enabled to activate other slow log options @@ -25,7 +27,7 @@ --socket=name Socket file to use for connection --sort-buffer-size=# Each thread that needs to do a sort allocates a buffer of -@@ -1351,6 +1356,7 @@ +@@ -1376,6 +1382,7 @@ deleting or updating every row in a table. --stack-trace Print a symbolic stack trace on failure (Defaults to on; use --skip-stack-trace to disable.) @@ -33,7 +35,7 @@ --standard-compliant-cte Allow only CTEs compliant to SQL standard (Defaults to on; use --skip-standard-compliant-cte to disable.) -@@ -1426,6 +1432,11 @@ +@@ -1454,6 +1461,11 @@ --thread-pool-max-threads=# Maximum allowed number of worker threads in the thread pool @@ -45,7 +47,7 @@ --thread-pool-oversubscribe=# How many additional active worker threads in a group are allowed. -@@ -1464,8 +1475,8 @@ +@@ -1493,8 +1505,8 @@ automatically convert it to an on-disk MyISAM or Aria table. -t, --tmpdir=name Path for temporary files. Several paths may be specified, @@ -56,7 +58,7 @@ --transaction-alloc-block-size=# Allocation block size for transactions to be stored in binary log -@@ -1685,6 +1696,7 @@ +@@ -1716,6 +1728,7 @@ myisam-stats-method NULLS_UNEQUAL myisam-use-mmap FALSE mysql56-temporal-format TRUE @@ -64,7 +66,7 @@ net-buffer-length 16384 net-read-timeout 30 net-retry-count 10 -@@ -1841,6 +1853,7 @@ +@@ -1874,6 +1887,7 @@ slave-type-conversions slow-launch-time 2 slow-query-log FALSE @@ -72,7 +74,7 @@ sort-buffer-size 2097152 sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION sql-safe-updates FALSE -@@ -1867,6 +1880,8 @@ +@@ -1901,6 +1915,8 @@ thread-pool-exact-stats FALSE thread-pool-idle-timeout 60 thread-pool-max-threads 65536 diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 6d00ae56b4b..66565065714 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -577,9 +577,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=# Alias for log_slow_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 @@ -729,7 +728,7 @@ The following specify which files/extra groups are read (specified before remain NO_DUP_KEY_WARNINGS_WITH_IGNORE, NO_PROGRESS_INFO, ZERO_DATE_TIME_CAST, UTF8_IS_UTF8MB3, IGNORE_INDEX_ONLY_FOR_JOIN, COMPAT_5_1_CHECKSUM, - LOCK_ALTER_TABLE_COPY + NO_NULL_COLLATION_IDS, LOCK_ALTER_TABLE_COPY Use 'ALL' to set all combinations. --old-passwords Use old password encryption method (needed for 4.0 and older clients) @@ -827,7 +826,7 @@ The following specify which files/extra groups are read (specified before remain condition_pushdown_for_derived, split_materialized, condition_pushdown_for_subquery, rowid_filter, condition_pushdown_from_having, not_null_range_scan, - hash_join_cardinality, sargable_casefold + hash_join_cardinality, cset_narrowing, sargable_casefold --optimizer-trace=name Controls tracing of the Optimizer: optimizer_trace=option=val[,option=val...], where option @@ -1792,7 +1791,7 @@ optimizer-rowid-copy-cost 0.002653 optimizer-scan-setup-cost 10 optimizer-search-depth 62 optimizer-selectivity-sampling-limit 100 -optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,sargable_casefold=on +optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=off,sargable_casefold=on optimizer-trace optimizer-trace-max-mem-size 1048576 optimizer-use-condition-selectivity 4 diff --git a/mysql-test/main/mysqltest_tracking_info.result b/mysql-test/main/mysqltest_tracking_info.result index 71a1e5413a2..d4010961077 100644 --- a/mysql-test/main/mysqltest_tracking_info.result +++ b/mysql-test/main/mysqltest_tracking_info.result @@ -38,7 +38,7 @@ SET @@session.session_track_system_variables='optimizer_switch'; set optimizer_switch='index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES -- optimizer_switch --- index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,sargable_casefold=on +-- index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=off,sargable_casefold=on set @@optimizer_switch=@save_optimizer_switch; SET @@session.session_track_system_variables= @save_session_track_system_variables; diff --git a/mysql-test/main/null.result b/mysql-test/main/null.result index 364b7f73202..858d24f29b1 100644 --- a/mysql-test/main/null.result +++ b/mysql-test/main/null.result @@ -1767,8 +1767,8 @@ c1 c2 c3 SELECT NULLIF(COUNT(DISTINCT c1),0) FROM t1; NULLIF(COUNT(DISTINCT c1),0) 2 -SELECT CASE WHEN COUNT(DISTINCT c1)=0 THEN NULL ELSE COUNT(DISTINCT c1) END FROM t1; -CASE WHEN COUNT(DISTINCT c1)=0 THEN NULL ELSE COUNT(DISTINCT c1) END +SELECT CASE WHEN COUNT(DISTINCT c1)=0 THEN NULL ELSE COUNT(DISTINCT c1) END as exp FROM t1; +exp 2 DROP TABLE t1; CREATE TABLE t1 ( diff --git a/mysql-test/main/null.test b/mysql-test/main/null.test index 977a93b1b48..7256ce1cc5b 100644 --- a/mysql-test/main/null.test +++ b/mysql-test/main/null.test @@ -1061,12 +1061,7 @@ SELECT CASE WHEN COUNT(c1)=0 THEN NULL ELSE COUNT(c1) END FROM t1; SELECT NULLIF(COUNT(c1)+0,0) AS c1,NULLIF(CAST(COUNT(c1) AS SIGNED),0) AS c2,NULLIF(CONCAT(COUNT(c1)),0) AS c3 FROM t1; SELECT NULLIF(COUNT(DISTINCT c1),0) FROM t1; -#enable view protocol after fix MDEV-27871 ---disable_view_protocol - -SELECT CASE WHEN COUNT(DISTINCT c1)=0 THEN NULL ELSE COUNT(DISTINCT c1) END FROM t1; - ---enable_view_protocol +SELECT CASE WHEN COUNT(DISTINCT c1)=0 THEN NULL ELSE COUNT(DISTINCT c1) END as exp FROM t1; DROP TABLE t1; diff --git a/mysql-test/main/old-mode.result b/mysql-test/main/old-mode.result index cf2c50872a3..9f911f8d17c 100644 --- a/mysql-test/main/old-mode.result +++ b/mysql-test/main/old-mode.result @@ -264,3 +264,15 @@ Warning 1264 Out of range value for column 'a' at row 2 DROP TABLE t1; SET @@time_zone=DEFAULT; SET TIMESTAMP=DEFAULT; +# +# MDEV-31608 - Connector/NET fails to connect since 10.10 +# +select count(*) > 0 from information_schema.collations where id IS NULL; +count(*) > 0 +1 +SET old_mode=no_null_collation_ids; +Warnings: +Warning 1287 'NO_NULL_COLLATION_IDS' is deprecated and will be removed in a future release +select count(*) > 0 from information_schema.collations where id IS NULL; +count(*) > 0 +0 diff --git a/mysql-test/main/old-mode.test b/mysql-test/main/old-mode.test index 3077b9b8537..cc44423d957 100644 --- a/mysql-test/main/old-mode.test +++ b/mysql-test/main/old-mode.test @@ -164,3 +164,11 @@ DROP TABLE t1; SET @@time_zone=DEFAULT; SET TIMESTAMP=DEFAULT; + +--echo # +--echo # MDEV-31608 - Connector/NET fails to connect since 10.10 +--echo # +select count(*) > 0 from information_schema.collations where id IS NULL; +SET old_mode=no_null_collation_ids; +select count(*) > 0 from information_schema.collations where id IS NULL; + diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index 757ebefaf04..3528c363d0b 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -543,6 +543,9 @@ select * from v2 { }, { "make_join_readinfo": [] + }, + { + "test_if_skip_sort_order": [] } ] } @@ -928,6 +931,9 @@ explain select * from v1 { }, { "make_join_readinfo": [] + }, + { + "test_if_skip_sort_order": [] } ] } @@ -1531,6 +1537,9 @@ EXPLAIN SELECT DISTINCT a FROM t1 { }, { "make_join_readinfo": [] + }, + { + "test_if_skip_sort_order": [] } ] } @@ -1757,26 +1766,30 @@ set statement optimizer_scan_setup_cost=0 for EXPLAIN SELECT MIN(d) FROM t1 wher "make_join_readinfo": [] }, { - "reconsidering_access_paths_for_index_ordering": { - "clause": "GROUP BY", - "table": "t1", - "rows_estimation": 1, - "filesort_cost": 4.579083e-5, - "read_cost": 0.001804223, - "filesort_type": "priority_queue with addon fields", - "fanout": 1, - "possible_keys": [ - { - "index": "a", - "can_resolve_order": true, - "direction": 1, - "rows_to_examine": 7, - "range_scan": false, - "scan_cost": 0.001758432, - "chosen": true + "test_if_skip_sort_order": [ + { + "reconsidering_access_paths_for_index_ordering": { + "clause": "GROUP BY", + "table": "t1", + "rows_estimation": 1, + "filesort_cost": 4.579083e-5, + "read_cost": 0.001804223, + "filesort_type": "priority_queue with addon fields", + "fanout": 1, + "possible_keys": [ + { + "index": "a", + "can_resolve_order": true, + "direction": 1, + "rows_to_examine": 7, + "range_scan": false, + "scan_cost": 0.001758432, + "chosen": true + } + ] } - ] - } + } + ] } ] } @@ -1994,6 +2007,9 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { }, { "make_join_readinfo": [] + }, + { + "test_if_skip_sort_order": [] } ] } @@ -2200,6 +2216,9 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { }, { "make_join_readinfo": [] + }, + { + "test_if_skip_sort_order": [] } ] } @@ -2504,97 +2523,101 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "make_join_readinfo": [] }, { - "reconsidering_access_paths_for_index_ordering": { - "clause": "ORDER BY", - "table": "t1", - "rows_estimation": 41, - "filesort_cost": 9.387121e-4, - "read_cost": 0.052317883, - "filesort_type": "priority_queue with addon fields", - "fanout": 1, - "possible_keys": [ - { - "index": "c", - "can_resolve_order": true, - "direction": 1, - "rows_to_examine": 24, - "range_scan": false, - "scan_cost": 0.030403398, - "chosen": true - }, - { - "index": "a_c", - "can_resolve_order": true, - "direction": 1, - "rows_to_examine": 4.390243902, - "range_scan": true, - "scan_cost": 0.023415994, - "chosen": true - }, - { - "index": "a_b", - "can_resolve_order": false, - "cause": "not usable index for the query" + "test_if_skip_sort_order": [ + { + "reconsidering_access_paths_for_index_ordering": { + "clause": "ORDER BY", + "table": "t1", + "rows_estimation": 41, + "filesort_cost": 9.387121e-4, + "read_cost": 0.052317883, + "filesort_type": "priority_queue with addon fields", + "fanout": 1, + "possible_keys": [ + { + "index": "c", + "can_resolve_order": true, + "direction": 1, + "rows_to_examine": 24, + "range_scan": false, + "scan_cost": 0.030403398, + "chosen": true + }, + { + "index": "a_c", + "can_resolve_order": true, + "direction": 1, + "rows_to_examine": 4.390243902, + "range_scan": true, + "scan_cost": 0.023415994, + "chosen": true + }, + { + "index": "a_b", + "can_resolve_order": false, + "cause": "not usable index for the query" + } + ] } - ] - } - }, - { - "table": "t1", - "range_analysis": { - "potential_range_indexes": [ - { - "index": "c", - "usable": false, - "cause": "not applicable" - }, - { - "index": "a_c", - "usable": true, - "key_parts": ["a", "c"] - }, - { - "index": "a_b", - "usable": false, - "cause": "not applicable" - } - ], - "setup_range_conditions": [], - "analyzing_range_alternatives": { - "range_scan_alternatives": [ - { - "index": "a_c", - "ranges": ["(1) <= (a) <= (1)"], - "rowid_ordered": false, - "using_mrr": false, - "index_only": false, - "rows": 180, - "cost": 0.223677504, - "cost_with_limit": 0.002574553, + }, + { + "table": "t1", + "range_analysis": { + "potential_range_indexes": [ + { + "index": "c", + "usable": false, + "cause": "not applicable" + }, + { + "index": "a_c", + "usable": true, + "key_parts": ["a", "c"] + }, + { + "index": "a_b", + "usable": false, + "cause": "not applicable" + } + ], + "setup_range_conditions": [], + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "a_c", + "ranges": ["(1) <= (a) <= (1)"], + "rowid_ordered": false, + "using_mrr": false, + "index_only": false, + "rows": 180, + "cost": 0.223677504, + "cost_with_limit": 0.002574553, + "chosen": true + } + ], + "analyzing_roworder_intersect": { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": [] + }, + "group_index_range": { + "chosen": false, + "cause": "no group by or distinct" + }, + "chosen_range_access_summary": { + "range_access_plan": { + "type": "range_scan", + "index": "a_c", + "rows": 180, + "ranges": ["(1) <= (a) <= (1)"] + }, + "rows_for_plan": 180, + "cost_for_plan": 0.223677504, "chosen": true } - ], - "analyzing_roworder_intersect": { - "cause": "too few roworder scans" - }, - "analyzing_index_merge_union": [] - }, - "group_index_range": { - "chosen": false, - "cause": "no group by or distinct" - }, - "chosen_range_access_summary": { - "range_access_plan": { - "type": "range_scan", - "index": "a_c", - "rows": 180, - "ranges": ["(1) <= (a) <= (1)"] - }, - "rows_for_plan": 180, - "cost_for_plan": 0.223677504, - "chosen": true + } } - } + ] } ] } @@ -11607,6 +11630,7 @@ drop table t1; # (on optimized builds) # CREATE TABLE t1( a INT, b INT, PRIMARY KEY( a ) ); +insert t1 values (2,3); SELECT sum(b), row_number() OVER (order by b) FROM t1 WHERE a = 101; sum(b) row_number() OVER (order by b) NULL 1 @@ -11622,8 +11646,8 @@ JS "rowid_ordered": true, "using_mrr": false, "index_only": false, - "rows": 0, - "cost": 0.001340684, + "rows": 1, + "cost": 0.002483968, "chosen": true } ] diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index aef6a4693fc..1a4f0c4b041 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -530,7 +530,6 @@ insert into t1 values ('foo'), ('bar'); EXPLAIN SELECT * FROM t1 WHERE a= REPEAT('a', 0); SELECT * FROM t1 WHERE a= REPEAT('a', 0); -#enable after fix MDEV-27871 select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) AS JS from INFORMATION_SCHEMA.OPTIMIZER_TRACE; DROP TABLE t1; @@ -561,7 +560,6 @@ create table t1 (kp1 int, kp2 int, key(kp1, kp2)); insert into t1 values (1,1),(1,5),(5,1),(5,5); set optimizer_trace=1; select * from t1 force index(kp1) where (kp1=2 and kp2 >=4); -#enable after fix MDEV-27871 select JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) AS JS from INFORMATION_SCHEMA.OPTIMIZER_TRACE; drop table t1; @@ -574,7 +572,6 @@ INSERT INTO t1 SELECT seq, seq from seq_1_to_10; CREATE TABLE t2(a INT, b INT, key(a)); INSERT INTO t2 SELECT seq, seq from seq_1_to_100; -#enable after fix MDEV-27871 SET OPTIMIZER_TRACE=1; EXPLAIN SELECT * FROM t1, t2 WHERE t1.a=t2.a ORDER BY t2.b; select JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) AS JS from INFORMATION_SCHEMA.OPTIMIZER_TRACE; @@ -603,6 +600,7 @@ drop table t1; --echo # CREATE TABLE t1( a INT, b INT, PRIMARY KEY( a ) ); +insert t1 values (2,3); SELECT sum(b), row_number() OVER (order by b) FROM t1 WHERE a = 101; UPDATE t1 SET b=10 WHERE a=1; SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) AS JS from INFORMATION_SCHEMA.OPTIMIZER_TRACE; diff --git a/mysql-test/main/order_by.result b/mysql-test/main/order_by.result index 274f29e34dc..3e6460ae653 100644 --- a/mysql-test/main/order_by.result +++ b/mysql-test/main/order_by.result @@ -3761,6 +3761,151 @@ Note 1003 select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` A set histogram_size=@tmp_h, histogram_type=@tmp_ht, use_stat_tables=@tmp_u, optimizer_use_condition_selectivity=@tmp_o; drop table t1,t2,t3,t4; +# +# MDEV-32324: Server crashes inside filesort at my_decimal::to_binary +# +SELECT 1.000000 two UNION SELECT 1 ORDER BY ( SELECT two LIMIT 1 OFFSET 1 ) ; +two +1.000000 +# MDEV-32475: test_if_skip_sort_order() should catch the join types +# JT_EQ_REF, JT_CONST and JT_SYSTEM and skip sort order for these +# +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, KEY(b)); +CREATE TABLE t2 (a INT, b INT); +INSERT INTO t1 SELECT seq, seq+1 FROM seq_1_to_100; +INSERT INTO t2 VALUES (0, 1),(1, 2); +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +# Table t1 must use eq_ref, not index below: +EXPLAIN SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FROM t2; +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 e343c0b8adb..f28f7e36de0 100644 --- a/mysql-test/main/order_by.test +++ b/mysql-test/main/order_by.test @@ -2451,6 +2451,86 @@ set histogram_size=@tmp_h, histogram_type=@tmp_ht, use_stat_tables=@tmp_u, drop table t1,t2,t3,t4; +--echo # +--echo # MDEV-32324: Server crashes inside filesort at my_decimal::to_binary +--echo # +SELECT 1.000000 two UNION SELECT 1 ORDER BY ( SELECT two LIMIT 1 OFFSET 1 ) ; + +--echo # MDEV-32475: test_if_skip_sort_order() should catch the join types +--echo # JT_EQ_REF, JT_CONST and JT_SYSTEM and skip sort order for these +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, KEY(b)); +CREATE TABLE t2 (a INT, b INT); +INSERT INTO t1 SELECT seq, seq+1 FROM seq_1_to_100; +INSERT INTO t2 VALUES (0, 1),(1, 2); + +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; + +--echo # Table t1 must use eq_ref, not index below: +EXPLAIN SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FROM t2; + +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/order_by_innodb.result b/mysql-test/main/order_by_innodb.result index ad4acad3319..5516c5636a0 100644 --- a/mysql-test/main/order_by_innodb.result +++ b/mysql-test/main/order_by_innodb.result @@ -171,6 +171,12 @@ insert into t2 values (1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'), (2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'), (3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00'); +analyze table t1,t2 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK select t1.id,t2.id from @@ -189,6 +195,10 @@ id id 2 1 3 3 create index for_latest_sort on t2 (d1, d2, id); +analyze table t2 persistent for all; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK select t1.id,t2.id from @@ -258,7 +268,7 @@ dd.d1, dd.d2, dd.id limit 1 id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL # 1 PRIMARY t2 eq_ref PRIMARY,id2 id2 8 test.t1.id,func # Using where; Using index -2 DEPENDENT SUBQUERY dd range id2,for_latest_sort for_latest_sort 6 NULL # Using where +2 DEPENDENT SUBQUERY dd ref id2,for_latest_sort id2 4 test.t1.id # Using where; Using filesort drop table t1,t2,t3; # End of 10.2 tests # @@ -296,3 +306,13 @@ a b c 6 2 26 6 3 36 drop table t1; +# +# MDEV-31116: SIGSEGV in test_if_skip_sort_order|JOIN::optimize_stage2 +# +CREATE TABLE t1 (a BINARY (2),b BINARY (1),KEY(a)) ENGINE=innodb; +INSERT INTO t1 select 'ab', NULL from seq_1_to_14; +SELECT * FROM t1 WHERE a IN (SELECT a FROM t1 WHERE a >'') ORDER BY a LIMIT 1; +a b +ab NULL +DROP TABLE t1; +# End of 11.0 tests diff --git a/mysql-test/main/order_by_innodb.test b/mysql-test/main/order_by_innodb.test index acce96c7603..6dab3baac13 100644 --- a/mysql-test/main/order_by_innodb.test +++ b/mysql-test/main/order_by_innodb.test @@ -152,6 +152,7 @@ insert into t2 values (2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'), (3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00'); +analyze table t1,t2 persistent for all; select t1.id,t2.id from @@ -167,6 +168,7 @@ from ); create index for_latest_sort on t2 (d1, d2, id); +analyze table t2 persistent for all; select t1.id,t2.id @@ -250,3 +252,12 @@ explain select * from t1 force index(r) order by a,b limit 20; explain select * from t1 force index(r) order by a desc,b limit 20; select * from t1 force index(r) order by a desc,b limit 20; drop table t1; + +--echo # +--echo # MDEV-31116: SIGSEGV in test_if_skip_sort_order|JOIN::optimize_stage2 +--echo # +CREATE TABLE t1 (a BINARY (2),b BINARY (1),KEY(a)) ENGINE=innodb; +INSERT INTO t1 select 'ab', NULL from seq_1_to_14; +SELECT * FROM t1 WHERE a IN (SELECT a FROM t1 WHERE a >'') ORDER BY a LIMIT 1; +DROP TABLE t1; +--echo # End of 11.0 tests diff --git a/mysql-test/main/order_by_optimizer_innodb.result b/mysql-test/main/order_by_optimizer_innodb.result index cbb5551b7cf..ad0bebdc7ef 100644 --- a/mysql-test/main/order_by_optimizer_innodb.result +++ b/mysql-test/main/order_by_optimizer_innodb.result @@ -3,10 +3,6 @@ SET GLOBAL innodb_stats_persistent=OFF; # # MDEV-6402: Optimizer doesn't choose best execution plan when composite key is used # -create table t0(a int); -insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -create table t1(a int); -insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C; CREATE TABLE t2 ( pk1 int(11) NOT NULL, pk2 int(11) NOT NULL, @@ -18,13 +14,17 @@ UNIQUE KEY ux_pk1_fd5 (pk1,fd5) ) ENGINE=InnoDB; insert into t2 select -round(log(2,t1.a+1)), -t1.a, -t1.a, +round(log(2,seq+1)), +seq, +seq, REPEAT('filler-data-', 10), REPEAT('filler-data-', 10) from -t1; +seq_0_to_1999; +analyze table t2 persistent for all; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK select pk1, count(*) from t2 group by pk1; pk1 count(*) 0 1 @@ -37,7 +37,8 @@ pk1 count(*) 7 91 8 181 9 362 -10 276 +10 724 +11 552 # The following should use range(ux_pk1_fd5), two key parts (key_len=5+8=13) EXPLAIN SELECT * FROM t2 USE INDEX(ux_pk1_fd5) WHERE pk1=9 AND fd5 < 500 ORDER BY fd5 DESC LIMIT 10; id select_type table type possible_keys key key_len ref rows Extra @@ -46,7 +47,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM t2 WHERE pk1=9 AND fd5 < 500 ORDER BY fd5 DESC LIMIT 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range PRIMARY,ux_pk1_fd5 ux_pk1_fd5 13 NULL 138 Using where -drop table t0,t1, t2; +drop table t2; # # MDEV-6814: Server crashes in calculate_key_len on query with ORDER BY # diff --git a/mysql-test/main/order_by_optimizer_innodb.test b/mysql-test/main/order_by_optimizer_innodb.test index 33f67e522ad..67f4b11be4f 100644 --- a/mysql-test/main/order_by_optimizer_innodb.test +++ b/mysql-test/main/order_by_optimizer_innodb.test @@ -1,4 +1,5 @@ --source include/have_innodb.inc +--source include/have_sequence.inc SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; SET GLOBAL innodb_stats_persistent=OFF; @@ -6,11 +7,6 @@ SET GLOBAL innodb_stats_persistent=OFF; --echo # --echo # MDEV-6402: Optimizer doesn't choose best execution plan when composite key is used --echo # -create table t0(a int); -insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); - -create table t1(a int); -insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C; CREATE TABLE t2 ( pk1 int(11) NOT NULL, @@ -24,14 +20,15 @@ CREATE TABLE t2 ( insert into t2 select - round(log(2,t1.a+1)), - t1.a, - t1.a, + round(log(2,seq+1)), + seq, + seq, REPEAT('filler-data-', 10), REPEAT('filler-data-', 10) from - t1; + seq_0_to_1999; +analyze table t2 persistent for all; select pk1, count(*) from t2 group by pk1; --echo # The following should use range(ux_pk1_fd5), two key parts (key_len=5+8=13) @@ -39,7 +36,7 @@ EXPLAIN SELECT * FROM t2 USE INDEX(ux_pk1_fd5) WHERE pk1=9 AND fd5 < 500 ORDER B --echo # This also must use range, not ref. key_len must be 13 EXPLAIN SELECT * FROM t2 WHERE pk1=9 AND fd5 < 500 ORDER BY fd5 DESC LIMIT 10; -drop table t0,t1, t2; +drop table t2; --echo # --echo # MDEV-6814: Server crashes in calculate_key_len on query with ORDER BY diff --git a/mysql-test/main/outfile_loaddata.result b/mysql-test/main/outfile_loaddata.result index 1449cb19453..d153fbbceeb 100644 --- a/mysql-test/main/outfile_loaddata.result +++ b/mysql-test/main/outfile_loaddata.result @@ -8,8 +8,8 @@ INSERT INTO t1 VALUES (101, 202, '-r-', '=raker='); SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug31663.txt' FIELDS TERMINATED BY 'raker' FROM t1; Warnings: Warning 1475 First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY -SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt'); -LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') +SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp; +exp 101raker202raker-r-raker=raker= CREATE TABLE t2 SELECT * FROM t1; @@ -23,8 +23,8 @@ i1 i2 c1 c2 DROP TABLE t2; # Only numeric fields, FIELDS TERMINATED BY 'r', no warnings: SELECT i1, i2 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug31663.txt' FIELDS TERMINATED BY 'r' FROM t1; -SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt'); -LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') +SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp; +exp 101r202 CREATE TABLE t2 SELECT i1, i2 FROM t1; @@ -38,8 +38,8 @@ DROP TABLE t2; SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug31663.txt' FIELDS TERMINATED BY '0' FROM t1; Warnings: Warning 1475 First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY -SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt'); -LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') +SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp; +exp 10102020-r-0=raker= CREATE TABLE t2 SELECT * FROM t1; @@ -55,8 +55,8 @@ DROP TABLE t2; SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug31663.txt' FIELDS OPTIONALLY ENCLOSED BY '"' TERMINATED BY '0' FROM t1; Warnings: Warning 1475 First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY -SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt'); -LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') +SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp; +exp 10102020"-r-"0"=raker=" CREATE TABLE t2 SELECT * FROM t1; @@ -70,8 +70,8 @@ i1 i2 c1 c2 DROP TABLE t2; # Only string fields, FIELDS OPTIONALLY ENCLOSED BY '"' TERMINATED BY '0', no warnings: SELECT c1, c2 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug31663.txt' FIELDS OPTIONALLY ENCLOSED BY '"' TERMINATED BY '0' FROM t1; -SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt'); -LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') +SELECT LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp; +exp "-r-"0"=raker=" CREATE TABLE t2 SELECT c1, c2 FROM t1; @@ -94,8 +94,8 @@ SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug32533.txt' FIELDS ENCLOSED BY 0xC Warnings: Warning 1638 Non-ASCII separator arguments are not fully supported TRUNCATE t1; -SELECT HEX(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug32533.txt')); -HEX(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug32533.txt')) +SELECT HEX(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug32533.txt')) as exp; +exp C35CC3C30A LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug32533.txt' INTO TABLE t1 FIELDS ENCLOSED BY 0xC3; Warnings: @@ -122,17 +122,17 @@ SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS ESCAPED BY '1 ERROR 42000: Field separator argument is not what is expected; check the manual # "Not implemented" warning on multibyte ENCLOSED/ESCAPED BY character, # LOAD DATA rises error or has unpredictable result -- to be fixed later -SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS ENCLOSED BY 'ÑŠ'; +SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS ENCLOSED BY 'ÑŠ' FROM t1; Warnings: Warning 1638 Non-ASCII separator arguments are not fully supported LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t2 CHARACTER SET binary FIELDS ENCLOSED BY 'ÑŠ'; ERROR 42000: Field separator argument is not what is expected; check the manual -SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS ESCAPED BY 'ÑŠ'; +SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS ESCAPED BY 'ÑŠ' FROM t1; Warnings: Warning 1638 Non-ASCII separator arguments are not fully supported LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t2 CHARACTER SET binary FIELDS ESCAPED BY 'ÑŠ'; ERROR 42000: Field separator argument is not what is expected; check the manual -SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS TERMINATED BY 'ÑŠ'; +SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS TERMINATED BY 'ÑŠ' FROM t1; Warnings: Warning 1638 Non-ASCII separator arguments are not fully supported ################################################## @@ -155,7 +155,7 @@ SELECT * FROM t2; a b c 1 ABC-ÐБВ DEF-ÂÃÄ 2 NULL NULL -SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES STARTING BY 'ÑŠ'; +SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES STARTING BY 'ÑŠ' FROM t1; Warnings: Warning 1638 Non-ASCII separator arguments are not fully supported ################################################## @@ -170,7 +170,7 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c; a b c 1 ABC-ÐБВ DEF-ÂÃÄ 2 NULL NULL -SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES TERMINATED BY 'ÑŠ'; +SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES TERMINATED BY 'ÑŠ' FROM t1; Warnings: Warning 1638 Non-ASCII separator arguments are not fully supported ################################################## @@ -258,8 +258,8 @@ CREATE TABLE t2 LIKE t1; INSERT INTO t1 VALUES (REPEAT('.', 800)); SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug53088.txt' CHARACTER SET latin1 FROM t1; # should be greater than 800 -SELECT LENGTH(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug53088.txt')); -LENGTH(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug53088.txt')) +SELECT LENGTH(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug53088.txt')) as exp; +exp 801 LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug53088.txt' INTO TABLE t2; # should be 800 diff --git a/mysql-test/main/outfile_loaddata.test b/mysql-test/main/outfile_loaddata.test index e35b40a0979..bb0ced72717 100644 --- a/mysql-test/main/outfile_loaddata.test +++ b/mysql-test/main/outfile_loaddata.test @@ -2,10 +2,6 @@ DROP TABLE IF EXISTS t1, t2; --enable_warnings -#enable view protocol after fix MDEV-27871 --- source include/no_view_protocol.inc - ---enable_prepare_warnings --disable_ps2_protocol --echo # --echo # Bug#31663 FIELDS TERMINATED BY special character @@ -21,7 +17,7 @@ INSERT INTO t1 VALUES (101, 202, '-r-', '=raker='); --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval SELECT $fields INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' $clauses FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') +--eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp --eval CREATE TABLE t2 SELECT $fields FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' INTO TABLE t2 $clauses @@ -36,7 +32,7 @@ DROP TABLE t2; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval SELECT $fields INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' $clauses FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') +--eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp --eval CREATE TABLE t2 SELECT $fields FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' INTO TABLE t2 $clauses @@ -51,7 +47,7 @@ DROP TABLE t2; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval SELECT $fields INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' $clauses FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') +--eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp --eval CREATE TABLE t2 SELECT $fields FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' INTO TABLE t2 $clauses @@ -66,7 +62,7 @@ DROP TABLE t2; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval SELECT $fields INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' $clauses FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') +--eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp --eval CREATE TABLE t2 SELECT $fields FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' INTO TABLE t2 $clauses @@ -81,7 +77,7 @@ DROP TABLE t2; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval SELECT $fields INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' $clauses FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') +--eval SELECT LOAD_FILE('$MYSQLTEST_VARDIR/tmp/bug31663.txt') as exp --eval CREATE TABLE t2 SELECT $fields FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/bug31663.txt' INTO TABLE t2 $clauses @@ -106,7 +102,7 @@ SELECT HEX(c1) FROM t1; TRUNCATE t1; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT HEX(LOAD_FILE('$file')) +--eval SELECT HEX(LOAD_FILE('$file')) as exp --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval LOAD DATA INFILE '$file' INTO TABLE t1 FIELDS ENCLOSED BY 0xC3 @@ -151,21 +147,21 @@ INSERT INTO t1 VALUES (1, 'ABC-ÐБВ', 'DEF-ÂÃÄ'), (2, NULL, NULL); --echo # LOAD DATA rises error or has unpredictable result -- to be fixed later --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT * FROM t1 INTO OUTFILE '$file' FIELDS ENCLOSED BY 'ÑŠ' +--eval SELECT * INTO OUTFILE '$file' FIELDS ENCLOSED BY 'ÑŠ' FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --error 1083 # backward compatibility --eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary FIELDS ENCLOSED BY 'ÑŠ' --remove_file $file --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT * FROM t1 INTO OUTFILE '$file' FIELDS ESCAPED BY 'ÑŠ' +--eval SELECT * INTO OUTFILE '$file' FIELDS ESCAPED BY 'ÑŠ' FROM t1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --error 1083 # backward compatibility --eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary FIELDS ESCAPED BY 'ÑŠ' --remove_file $file --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT * FROM t1 INTO OUTFILE '$file' FIELDS TERMINATED BY 'ÑŠ' +--eval SELECT * INTO OUTFILE '$file' FIELDS TERMINATED BY 'ÑŠ' FROM t1 --echo ################################################## --cat_file $file --echo ################################################## @@ -178,7 +174,7 @@ SELECT * FROM t1; SELECT * FROM t2; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT * FROM t1 INTO OUTFILE '$file' LINES STARTING BY 'ÑŠ' +--eval SELECT * INTO OUTFILE '$file' LINES STARTING BY 'ÑŠ' FROM t1 --echo ################################################## --cat_file $file --echo ################################################## @@ -189,7 +185,7 @@ TRUNCATE t2; SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT * FROM t1 INTO OUTFILE '$file' LINES TERMINATED BY 'ÑŠ' +--eval SELECT * INTO OUTFILE '$file' LINES TERMINATED BY 'ÑŠ' FROM t1 --echo ################################################## --cat_file $file --echo ################################################## @@ -282,7 +278,7 @@ let $length= 800; --echo # should be greater than $length --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---eval SELECT LENGTH(LOAD_FILE($file)) +--eval SELECT LENGTH(LOAD_FILE($file)) as exp --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval LOAD DATA INFILE $file INTO TABLE t2 diff --git a/mysql-test/main/partition_geometries.result b/mysql-test/main/partition_geometries.result new file mode 100644 index 00000000000..ec63b92b3da --- /dev/null +++ b/mysql-test/main/partition_geometries.result @@ -0,0 +1,125 @@ +# +# MDEV-19177: Geometry support for partition feature +# Test partition/geometry type cross-compatibility for the 4 storage engines that support +# geometries (Aria, MyISAM, InnoDB, Archive) +# Geometries to test - point, multipolygon, geometry collection +# Note: Archive does not support additional indices. +# +SET @point = Point(3,3); +SET @poly = MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))); +SET @collection = GeometryCollection(Point(1,1), Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))); +# +# Aria engine +# +CREATE TABLE t1 ( +`id` int(11) NOT NULL AUTO_INCREMENT, +`geom` geometry NOT NULL, +PRIMARY KEY (id), +SPATIAL INDEX(geom) +) Engine=Aria PARTITION BY HASH (id) +PARTITIONS 10; +INSERT INTO t1 VALUES (NULL, @point), (NULL, @poly), (NULL, @collection); +SELECT ST_AsGeoJSON(geom) FROM t1; +ST_AsGeoJSON(geom) +{"type": "Point", "coordinates": [3, 3]} +{"type": "MultiPolygon", "coordinates": [[[[0, 3], [3, 3], [3, 0], [0, 3]]]]} +{"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [1, 1]}, {"type": "Polygon", "coordinates": [[[0, 3], [3, 3], [3, 0], [0, 3]]]}]} +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `geom` geometry NOT NULL, + PRIMARY KEY (`id`), + SPATIAL KEY `geom` (`geom`) +) ENGINE=Aria AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`id`) +PARTITIONS 10 +DROP TABLE t1; +# +# MyISAM engine +# +CREATE TABLE t1 ( +`id` int(11) NOT NULL AUTO_INCREMENT, +`geom` geometry NOT NULL, +PRIMARY KEY (id), +SPATIAL INDEX(geom) +) Engine=myisam PARTITION BY HASH (id) +PARTITIONS 10; +INSERT INTO t1 VALUES (NULL, @point), (NULL, @poly), (NULL, @collection); +SELECT ST_AsGeoJSON(geom) FROM t1; +ST_AsGeoJSON(geom) +{"type": "Point", "coordinates": [3, 3]} +{"type": "MultiPolygon", "coordinates": [[[[0, 3], [3, 3], [3, 0], [0, 3]]]]} +{"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [1, 1]}, {"type": "Polygon", "coordinates": [[[0, 3], [3, 3], [3, 0], [0, 3]]]}]} +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `geom` geometry NOT NULL, + PRIMARY KEY (`id`), + SPATIAL KEY `geom` (`geom`) +) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`id`) +PARTITIONS 10 +DROP TABLE t1; +# +# InnoDB engine +# +CREATE TABLE t1 ( +`id` int(11) NOT NULL AUTO_INCREMENT, +`geom` geometry NOT NULL, +PRIMARY KEY (id), +SPATIAL INDEX(geom) +) Engine=innodb PARTITION BY HASH (id) +PARTITIONS 10; +INSERT INTO t1 VALUES (NULL, @point), (NULL, @poly), (NULL, @collection); +SELECT ST_AsGeoJSON(geom) FROM t1; +ST_AsGeoJSON(geom) +{"type": "Point", "coordinates": [3, 3]} +{"type": "MultiPolygon", "coordinates": [[[[0, 3], [3, 3], [3, 0], [0, 3]]]]} +{"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [1, 1]}, {"type": "Polygon", "coordinates": [[[0, 3], [3, 3], [3, 0], [0, 3]]]}]} +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `geom` geometry NOT NULL, + PRIMARY KEY (`id`), + SPATIAL KEY `geom` (`geom`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`id`) +PARTITIONS 10 +DROP TABLE t1; +# +# Archive engine +# +INSTALL SONAME 'ha_archive'; +CREATE TABLE t1 ( +`id` int(11) NOT NULL AUTO_INCREMENT, +`geom` geometry, +SPATIAL INDEX(geom) +) Engine=archive PARTITION BY HASH (id) +PARTITIONS 10; +ERROR HY000: The storage engine partition doesn't support SPATIAL indexes +CREATE TABLE t1 ( +`id` int(11) NOT NULL AUTO_INCREMENT, +`geom` geometry, +PRIMARY KEY (id) +) Engine=archive PARTITION BY HASH (id) +PARTITIONS 10; +INSERT INTO t1 VALUES (NULL, @point), (NULL, @poly), (NULL, @collection); +SELECT ST_AsGeoJSON(geom) FROM t1; +ST_AsGeoJSON(geom) +{"type": "Point", "coordinates": [3, 3]} +{"type": "MultiPolygon", "coordinates": [[[[0, 3], [3, 3], [3, 0], [0, 3]]]]} +{"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [1, 1]}, {"type": "Polygon", "coordinates": [[[0, 3], [3, 3], [3, 0], [0, 3]]]}]} +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `geom` geometry DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=ARCHIVE AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`id`) +PARTITIONS 10 +DROP TABLE t1; +UNINSTALL SONAME 'ha_archive'; diff --git a/mysql-test/main/partition_geometries.test b/mysql-test/main/partition_geometries.test new file mode 100644 index 00000000000..34e72463058 --- /dev/null +++ b/mysql-test/main/partition_geometries.test @@ -0,0 +1,93 @@ +-- source include/have_geometry.inc + +if (!$HA_ARCHIVE_SO) { + skip Needs Archive plugin; +} + +--echo # +--echo # MDEV-19177: Geometry support for partition feature +--echo # Test partition/geometry type cross-compatibility for the 4 storage engines that support +--echo # geometries (Aria, MyISAM, InnoDB, Archive) +--echo # Geometries to test - point, multipolygon, geometry collection +--echo # Note: Archive does not support additional indices. +--echo # +SET @point = Point(3,3); +SET @poly = MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))); +SET @collection = GeometryCollection(Point(1,1), Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))); + +--source include/have_partition.inc + +--echo # +--echo # Aria engine +--echo # +CREATE TABLE t1 ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `geom` geometry NOT NULL, + PRIMARY KEY (id), + SPATIAL INDEX(geom) +) Engine=Aria PARTITION BY HASH (id) +PARTITIONS 10; + +INSERT INTO t1 VALUES (NULL, @point), (NULL, @poly), (NULL, @collection); +SELECT ST_AsGeoJSON(geom) FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # MyISAM engine +--echo # +CREATE TABLE t1 ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `geom` geometry NOT NULL, + PRIMARY KEY (id), + SPATIAL INDEX(geom) +) Engine=myisam PARTITION BY HASH (id) +PARTITIONS 10; + +INSERT INTO t1 VALUES (NULL, @point), (NULL, @poly), (NULL, @collection); +SELECT ST_AsGeoJSON(geom) FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # InnoDB engine +--echo # +--source include/have_innodb.inc +CREATE TABLE t1 ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `geom` geometry NOT NULL, + PRIMARY KEY (id), + SPATIAL INDEX(geom) +) Engine=innodb PARTITION BY HASH (id) +PARTITIONS 10; + +INSERT INTO t1 VALUES (NULL, @point), (NULL, @poly), (NULL, @collection); +SELECT ST_AsGeoJSON(geom) FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # Archive engine +--echo # + +INSTALL SONAME 'ha_archive'; +--error ER_TABLE_CANT_HANDLE_SPKEYS +CREATE TABLE t1 ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `geom` geometry, + SPATIAL INDEX(geom) +) Engine=archive PARTITION BY HASH (id) +PARTITIONS 10; +CREATE TABLE t1 ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `geom` geometry, + PRIMARY KEY (id) +) Engine=archive PARTITION BY HASH (id) +PARTITIONS 10; + +INSERT INTO t1 VALUES (NULL, @point), (NULL, @poly), (NULL, @collection); +SELECT ST_AsGeoJSON(geom) FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; +UNINSTALL SONAME 'ha_archive'; + diff --git a/mysql-test/main/partition_innodb.result b/mysql-test/main/partition_innodb.result index 8238650012f..7f9b6406ea6 100644 --- a/mysql-test/main/partition_innodb.result +++ b/mysql-test/main/partition_innodb.result @@ -38,7 +38,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK EXPLAIN SELECT b FROM t1 WHERE b between 'L' and 'N' AND a > -100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,b b 67 NULL 90 Using where; Using index +1 SIMPLE t1 index PRIMARY,b b 67 NULL 308 Using where; Using index DROP TABLE t1; # # Bug#13007154: Crash in keys_to_use_for_scanning with ORDER BY @@ -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) @@ -567,7 +571,7 @@ test.t1 optimize note Table does not support optimize, doing recreate + analyze test.t1 optimize error Invalid default value for 'b' test.t1 optimize status Operation failed Warnings: -Warning 1265 Data truncated for column 'b' at row 1 +Warning 1265 Data truncated for column 'b' at row 0 Error 1067 Invalid default value for 'b' SET SESSION sql_mode = @old_mode; DROP TABLE t1; diff --git a/mysql-test/main/partition_innodb.test b/mysql-test/main/partition_innodb.test index aaca678750b..2ed0c10c85c 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/partition_pruning.result b/mysql-test/main/partition_pruning.result index eef1df4095f..5461011d5b2 100644 --- a/mysql-test/main/partition_pruning.result +++ b/mysql-test/main/partition_pruning.result @@ -3529,3 +3529,17 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t3 p3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 10 Using where; Using join buffer (incremental, BNL join) drop table t0,t1,t2,t3; +# +# End of 10.3 tests +# +# +# MDEV-24283 Assertion `bitmap_is_set(&m_part_info->read_partitions, m_part_spec.start_part)' failed in ha_partition::handle_ordered_index_scan +# +create table t1 (c int key) partition by list (c) (partition p values in (0)); +select max(c) from t1 where c>0; +max(c) +NULL +drop table t1; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/partition_pruning.test b/mysql-test/main/partition_pruning.test index 78924d27550..2cfcf5d084e 100644 --- a/mysql-test/main/partition_pruning.test +++ b/mysql-test/main/partition_pruning.test @@ -1583,3 +1583,18 @@ select * from t1 left join (t3 join t2) on (t1.a=t3.a and t3.a=t2.b and t3.part_ drop table t0,t1,t2,t3; +--echo # +--echo # End of 10.3 tests +--echo # + +--echo # +--echo # MDEV-24283 Assertion `bitmap_is_set(&m_part_info->read_partitions, m_part_spec.start_part)' failed in ha_partition::handle_ordered_index_scan +--echo # + +create table t1 (c int key) partition by list (c) (partition p values in (0)); +select max(c) from t1 where c>0; +drop table t1; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/main/partition_range.result b/mysql-test/main/partition_range.result index be1689b218e..2f1a73a008c 100644 --- a/mysql-test/main/partition_range.result +++ b/mysql-test/main/partition_range.result @@ -1008,7 +1008,7 @@ SHOW status LIKE 'handler_read%'; 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 @@ -1024,7 +1024,7 @@ SHOW status LIKE 'handler_read%'; 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/ps.result b/mysql-test/main/ps.result index 36a0d47432a..39c93729e9e 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -5798,5 +5798,15 @@ END; $ ERROR 42000: EXECUTE..USING does not support subqueries or stored functions # +# MDEV-32965: Assertion `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' failed +# +CREATE TABLE t (f VARCHAR(8)) CHARACTER SET utf8; +INSERT INTO t VALUES ('foo'),('bar'); +EXECUTE IMMEDIATE 'SELECT GROUP_CONCAT(@x) FROM t GROUP BY @x := f'; +GROUP_CONCAT(@x) +0 +0 +DROP TABLE t; +# # End of 10.4 tests # diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test index e5ab2fcba1b..d6a3822832c 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -5236,6 +5236,18 @@ $ delimiter ;$ +--echo # +--echo # MDEV-32965: Assertion `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' failed +--echo # +CREATE TABLE t (f VARCHAR(8)) CHARACTER SET utf8; + +INSERT INTO t VALUES ('foo'),('bar'); +EXECUTE IMMEDIATE 'SELECT GROUP_CONCAT(@x) FROM t GROUP BY @x := f'; + +# Cleanup + +DROP TABLE t; + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/ps_mem_leaks.result b/mysql-test/main/ps_mem_leaks.result new file mode 100644 index 00000000000..2ddf47a992c --- /dev/null +++ b/mysql-test/main/ps_mem_leaks.result @@ -0,0 +1,91 @@ +# +# MDEV-32369: Memory leak when executing PS for query with 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'), ('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)"; +EXECUTE stmt; +a +b +EXECUTE stmt; +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 new file mode 100644 index 00000000000..dacb4ecabba --- /dev/null +++ b/mysql-test/main/ps_mem_leaks.test @@ -0,0 +1,112 @@ +# This file contains test cases that use the memory leaks detection feature +# provided by the cmake build option -DWITH_PROTECT_STATEMENT_MEMROOT + +--source include/not_embedded.inc +# The cmake option -DWITH_PROTECT_STATEMENT_MEMROOT is used only +# for debug build +--source include/have_debug.inc + +--echo # +--echo # MDEV-32369: Memory leak when executing PS for query with 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'), ('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'); + +PREPARE stmt FROM "SELECT 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-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/require_secure_transport.test b/mysql-test/main/require_secure_transport.test index fbabd7bc7a2..51ace6291cf 100644 --- a/mysql-test/main/require_secure_transport.test +++ b/mysql-test/main/require_secure_transport.test @@ -1,3 +1,4 @@ +-- source include/no_view_protocol.inc -- source include/have_ssl_communication.inc SET GLOBAL require_secure_transport=ON; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT @@ -6,7 +7,9 @@ connect without_ssl,localhost,root,,,,,TCP NOSSL; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT connect with_ssl,localhost,root,,,,,TCP SSL; +--disable_view_protocol SELECT (VARIABLE_VALUE <> '') AS have_ssl FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_cipher'; +--enable_view_protocol disconnect with_ssl; connection default; diff --git a/mysql-test/main/require_secure_transport_on.test b/mysql-test/main/require_secure_transport_on.test index 09db2fa0175..2cdeb66f581 100644 --- a/mysql-test/main/require_secure_transport_on.test +++ b/mysql-test/main/require_secure_transport_on.test @@ -1,3 +1,4 @@ +--source include/no_view_protocol.inc --source include/not_windows.inc --source include/have_ssl_communication.inc diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result index d7946de7a7f..276b57a106c 100644 --- a/mysql-test/main/rowid_filter_innodb.result +++ b/mysql-test/main/rowid_filter_innodb.result @@ -2470,6 +2470,35 @@ SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a; a 1 5 +# +# MDEV-25163 Rowid filter does not process storage engine error correctly. +# +CREATE TABLE two(tw int) Engine=MyISAM; +INSERT INTO two VALUES (1),(2); +SET GLOBAL innodb_stats_persistent= OFF; +EXPLAIN EXTENDED +SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a FOR UPDATE; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range|filter b,c b|c 13|1027 NULL 5 (21%) 20.83 Using index condition; Using where; Using filesort; Using rowid filter +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`c` < 'e' and `test`.`t1`.`b` > 't' order by `test`.`t1`.`a` for update +EXPLAIN EXTENDED +SELECT a FROM t1,two WHERE c < 'e' AND b > 't' ORDER BY a FOR UPDATE; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range|filter b,c b|c 13|1027 NULL 5 (21%) 20.83 Using index condition; Using where; Using temporary; Using filesort; Using rowid filter +1 SIMPLE two ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`two` where `test`.`t1`.`c` < 'e' and `test`.`t1`.`b` > 't' order by `test`.`t1`.`a` for update +SET @saved_dbug = @@SESSION.debug_dbug; +SET debug_dbug = '+d,innodb_report_deadlock'; +SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a FOR UPDATE; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET debug_dbug = @saved_dbug; +SET debug_dbug = '+d,innodb_report_deadlock'; +SELECT a FROM t1,two WHERE c < 'e' AND b > 't' ORDER BY a FOR UPDATE; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET debug_dbug = @saved_dbug; +DROP TABLE two; DROP TABLE t1; SET GLOBAL innodb_stats_persistent= @stats.save; # diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test index 77f2e7c1b59..7e8e1e210fc 100644 --- a/mysql-test/main/rowid_filter_innodb.test +++ b/mysql-test/main/rowid_filter_innodb.test @@ -1,5 +1,6 @@ --source include/no_valgrind_without_big.inc --source include/have_innodb.inc +--source include/have_debug.inc SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; @@ -139,6 +140,50 @@ SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a; SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a; +--echo # +--echo # MDEV-25163 Rowid filter does not process storage engine error correctly. +--echo # +#INSERT INTO t1 VALUES +# (100,'z','a'), +# (100,'z','a'), +# (100,'z','a'), +# (100,'z','a'); + + +#ANALYZE TABLE t1; + + +CREATE TABLE two(tw int) Engine=MyISAM; +INSERT INTO two VALUES (1),(2); + +# Switch off statistics update to catch correct create lock function call +SET GLOBAL innodb_stats_persistent= OFF; + +# Make sure it's still rowid filter + filesort +#--optimizer_trace +EXPLAIN EXTENDED +SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a FOR UPDATE; + +EXPLAIN EXTENDED +SELECT a FROM t1,two WHERE c < 'e' AND b > 't' ORDER BY a FOR UPDATE; + +SET @saved_dbug = @@SESSION.debug_dbug; +# Deadlock error should be returned from InnoDB during rowid filter container +# filling. If MDEV-25163 is not fixed, there will be assertion failure in +# InnoDB, as allready rolled back trx_t object will be used in filesort +# operation. +SET debug_dbug = '+d,innodb_report_deadlock'; +--error ER_LOCK_DEADLOCK +SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a FOR UPDATE; +SET debug_dbug = @saved_dbug; + +# Same as above for the join query: +SET debug_dbug = '+d,innodb_report_deadlock'; +--error ER_LOCK_DEADLOCK +SELECT a FROM t1,two WHERE c < 'e' AND b > 't' ORDER BY a FOR UPDATE; +SET debug_dbug = @saved_dbug; + +DROP TABLE two; DROP TABLE t1; SET GLOBAL innodb_stats_persistent= @stats.save; 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/schema.result b/mysql-test/main/schema.result index 74a8bf9b562..1f130db738c 100644 --- a/mysql-test/main/schema.result +++ b/mysql-test/main/schema.result @@ -1,4 +1,3 @@ -drop database if exists mysqltest1; create schema foo; show create schema foo; Database Create Database @@ -16,26 +15,24 @@ drop schema foo; # # Bug #48940 MDL deadlocks against mysql_rm_db # -DROP SCHEMA IF EXISTS schema1; connect con2, localhost, root; connection default; CREATE SCHEMA schema1; CREATE TABLE schema1.t1 (a INT); -SET autocommit= FALSE; +START TRANSACTION; INSERT INTO schema1.t1 VALUES (1); connection con2; DROP SCHEMA schema1; connection default; ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8; Got one of the listed errors -SET autocommit= TRUE; +COMMIT; connection con2; connection default; disconnect con2; # # Bug #49988 MDL deadlocks with mysql_create_db, reload_acl_and_cache # -DROP SCHEMA IF EXISTS schema1; connect con2, localhost, root; connection default; CREATE SCHEMA schema1; @@ -78,8 +75,6 @@ disconnect con2; # Tests for increased CREATE/ALTER/DROP DATABASE concurrency with # database name locks. # -DROP DATABASE IF EXISTS db1; -DROP DATABASE IF EXISTS db2; connect con2, localhost, root; connect con3, localhost, root; connection default; diff --git a/mysql-test/main/schema.test b/mysql-test/main/schema.test index e8ab4e406c0..b984ebb8639 100644 --- a/mysql-test/main/schema.test +++ b/mysql-test/main/schema.test @@ -8,10 +8,6 @@ --source include/count_sessions.inc --source include/default_charset.inc ---disable_warnings -drop database if exists mysqltest1; ---enable_warnings - create schema foo; show create schema foo; show schemas; @@ -22,10 +18,6 @@ drop schema foo; --echo # Bug #48940 MDL deadlocks against mysql_rm_db --echo # ---disable_warnings -DROP SCHEMA IF EXISTS schema1; ---enable_warnings - connect(con2, localhost, root); connection default; @@ -33,7 +25,7 @@ connection default; CREATE SCHEMA schema1; CREATE TABLE schema1.t1 (a INT); -SET autocommit= FALSE; +START TRANSACTION; INSERT INTO schema1.t1 VALUES (1); connection con2; @@ -48,7 +40,7 @@ let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist # Listing the error twice to prevent result diffences based on filename. --error 1,1 ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8; -SET autocommit= TRUE; +COMMIT; connection con2; --reap @@ -61,10 +53,6 @@ disconnect con2; --echo # Bug #49988 MDL deadlocks with mysql_create_db, reload_acl_and_cache --echo # ---disable_warnings -DROP SCHEMA IF EXISTS schema1; ---enable_warnings - connect (con2, localhost, root); connection default; @@ -134,11 +122,6 @@ disconnect con2; --echo # database name locks. --echo # ---disable_warnings -DROP DATABASE IF EXISTS db1; -DROP DATABASE IF EXISTS db2; ---enable_warnings - connect (con2, localhost, root); connect (con3, localhost, root); diff --git a/mysql-test/main/second_frac-9175.result b/mysql-test/main/second_frac-9175.result index dbf268b5c3b..fd99fac16cb 100644 --- a/mysql-test/main/second_frac-9175.result +++ b/mysql-test/main/second_frac-9175.result @@ -1,13 +1,13 @@ -select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456'); -timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456') +select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456') as exp; +exp 31622400123456 -explain extended select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456'); +explain extended select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456') as exp; 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 timestampdiff(MICROSECOND,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456') AS `timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456')` -create view v1 as select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456'); +Note 1003 select timestampdiff(MICROSECOND,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456') AS `exp` +create view v1 as select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456') as exp; select * from v1; -Name_exp_1 +exp 31622400123456 drop view v1; diff --git a/mysql-test/main/second_frac-9175.test b/mysql-test/main/second_frac-9175.test index 4cda672b820..1c918aae24e 100644 --- a/mysql-test/main/second_frac-9175.test +++ b/mysql-test/main/second_frac-9175.test @@ -2,13 +2,8 @@ # MDEV-9175 Query parser tansforms MICROSECOND into SECOND_FRAC, which does not work # -#enable after fix MDEV-27871 ---disable_view_protocol - -select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456'); -explain extended select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456'); -create view v1 as select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456'); +select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456') as exp; +explain extended select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456') as exp; +create view v1 as select timestampdiff(microsecond,'2000-01-01 00:00:00','2001-01-01 00:00:00.123456') as exp; select * from v1; drop view v1; - ---enable_view_protocol diff --git a/mysql-test/main/secure_file_priv_win.test b/mysql-test/main/secure_file_priv_win.test index be5345dc161..40a7b4ea40d 100644 --- a/mysql-test/main/secure_file_priv_win.test +++ b/mysql-test/main/secure_file_priv_win.test @@ -12,6 +12,8 @@ INSERT INTO t1 values ('a'); LET $MYSQL_TMP_DIR_UCASE= `SELECT upper('$MYSQL_TMP_DIR')`; LET $MYSQL_TMP_DIR_LCASE= `SELECT lower('$MYSQL_TMP_DIR')`; +--disable_ps2_protocol + #create the file --replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR eval SELECT * INTO OUTFILE '$MYSQL_TMP_DIR/B11764517.tmp' FROM t1; @@ -77,3 +79,4 @@ eval SELECT * INTO OUTFILE '$MYSQL_TMP_DIR_LCASE/B11764517-5.tmp' FROM t1; --error 0,1 --remove_file $MYSQL_TMP_DIR/B11764517-5.tmp; DROP TABLE t1; +--enable_ps2_protocol diff --git a/mysql-test/main/select.result b/mysql-test/main/select.result index 19fd2858f5f..db2c5ba2728 100644 --- a/mysql-test/main/select.result +++ b/mysql-test/main/select.result @@ -4184,106 +4184,103 @@ ALTER VIEW v1 AS SELECT 1 AS ` `; ERROR 42000: Incorrect column name ' ' DROP VIEW v1; select str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' - and '2007/10/20 00:00:00 GMT'; -str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' - and '2007/10/20 00:00:00 GMT' + and '2007/10/20 00:00:00 GMT' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT' Warning 1292 Truncated incorrect datetime value: '2007/10/20 00:00:00 GMT' -select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6'; -str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT-6' -select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6'; -str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/20 00:00:00 GMT-6' -select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6'; -str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6' as exp; +exp 0 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/2000:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-1 00:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect date value: '2007-10-01 x00:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:x00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect date value: '2007-10-01 x12:34:56 GMT-6' -select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; -str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' +select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6' -select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; -str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' as exp; +exp 0 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6' -select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56'; -str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56' +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56' as exp; +exp 1 -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00'; -str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00' as exp; +exp 0 -select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00'; -str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00' +select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00' as exp; +exp 1 -select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00'; -str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00' +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34' -select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34'; -str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34' +select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34' as exp; +exp 1 -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +exp 1 select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' - and '2007/10/20 00:00:00'; -str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' - and '2007/10/20 00:00:00' + and '2007/10/20 00:00:00' as exp; +exp 1 set SQL_MODE=TRADITIONAL; -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '2007-10-00 12:34' for function str_to_date -select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +exp 0 -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34'; -str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34' as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '2007-10-00 12:34' for function str_to_date select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' - and '2007/10/20'; -str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' - and '2007/10/20' + and '2007/10/20' as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '2007-10-00' for function str_to_date @@ -4322,23 +4319,23 @@ str_to_date('','%Y-%m-%d') = '' 1 Warnings: Warning 1292 Truncated incorrect datetime value: '' -select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01'; -str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01' +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01' as exp; +exp 1 -select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL; -str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL as exp; +exp NULL -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01'; -str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01' +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01' as exp; +exp NULL -select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL; -str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL +select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL as exp; +exp 0 -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01'; -str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01' +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01' as exp; +exp 0 -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL; -str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL as exp; +exp NULL CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY); CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL, diff --git a/mysql-test/main/select.test b/mysql-test/main/select.test index 5101d73ff17..6ac103f56b1 100644 --- a/mysql-test/main/select.test +++ b/mysql-test/main/select.test @@ -3583,51 +3583,48 @@ DROP VIEW v1; # On DATETIME-like literals with trailing garbage, BETWEEN fudged in a # DATETIME comparator, while greater/less-than used bin-string comparisons. # Should correctly be compared as DATE or DATETIME, but throw a warning: -#enable after fix MDEV-27871 ---disable_view_protocol select str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' - and '2007/10/20 00:00:00 GMT'; -select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6'; -select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6'; -select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6'; + and '2007/10/20 00:00:00 GMT' as exp; +select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6' as exp; +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6' as exp; +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6' as exp; # We have all we need -- and trailing garbage: # (leaving out a leading zero in first example to prove it's a # value-comparison, not a string-comparison!) -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6'; -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6'; -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6'; -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6'; +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6' as exp; +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6' as exp; +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6' as exp; +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6' as exp; # no time at all: -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6'; +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6' as exp; # partial time: -select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; +select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' as exp; # fail, different second part: -select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' as exp; # correct syntax, no trailing nonsense -- this one must throw no warning: -select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56'; +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56' as exp; # no warning, but failure (different hour parts): -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00'; +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00' as exp; # succeed: -select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00'; +select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00' as exp; # succeed, but warn for "trailing garbage" (":34"): -select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00'; +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00' as exp; # invalid date (Feb 30) succeeds -select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34'; +select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34' as exp; # 0-day for both, just works in default SQL mode. -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; # 0-day, succeed select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' - and '2007/10/20 00:00:00'; + and '2007/10/20 00:00:00' as exp; set SQL_MODE=TRADITIONAL; # 0-day throws warning in traditional mode, and fails -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; # different code-path: get_datetime_value() with 0-day -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34'; +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34' as exp; select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' - and '2007/10/20'; ---enable_view_protocol + and '2007/10/20' as exp; set SQL_MODE=DEFAULT; select str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20'; select str_to_date('','%Y-%m-%d') between '2007/10/01' and '2007/10/20'; @@ -3639,15 +3636,12 @@ select str_to_date('1','%Y-%m-%d') = '1'; select str_to_date('1','%Y-%m-%d') = '1'; select str_to_date('','%Y-%m-%d') = ''; -#enable after fix MDEV-27871 ---disable_view_protocol -select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01'; -select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL; -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01'; -select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL; -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01'; -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL; ---enable_view_protocol +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01' as exp; +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL as exp; +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01' as exp; +select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL as exp; +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01' as exp; +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL as exp; # # Bug #30666: Incorrect order when using range conditions on 2 tables or more diff --git a/mysql-test/main/select_jcl6.result b/mysql-test/main/select_jcl6.result index 97b05171a1d..f683adf5d80 100644 --- a/mysql-test/main/select_jcl6.result +++ b/mysql-test/main/select_jcl6.result @@ -4195,106 +4195,103 @@ ALTER VIEW v1 AS SELECT 1 AS ` `; ERROR 42000: Incorrect column name ' ' DROP VIEW v1; select str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' - and '2007/10/20 00:00:00 GMT'; -str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' - and '2007/10/20 00:00:00 GMT' + and '2007/10/20 00:00:00 GMT' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT' Warning 1292 Truncated incorrect datetime value: '2007/10/20 00:00:00 GMT' -select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6'; -str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT-6' -select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6'; -str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/20 00:00:00 GMT-6' -select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6'; -str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6' as exp; +exp 0 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/2000:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-1 00:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect date value: '2007-10-01 x00:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:x00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect date value: '2007-10-01 x12:34:56 GMT-6' -select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; -str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' +select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6' -select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; -str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' as exp; +exp 0 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6' -select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56'; -str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56' +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56' as exp; +exp 1 -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00'; -str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00' as exp; +exp 0 -select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00'; -str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00' +select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00' as exp; +exp 1 -select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00'; -str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00' +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34' -select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34'; -str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34' +select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34' as exp; +exp 1 -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +exp 1 select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' - and '2007/10/20 00:00:00'; -str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' - and '2007/10/20 00:00:00' + and '2007/10/20 00:00:00' as exp; +exp 1 set SQL_MODE=TRADITIONAL; -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '2007-10-00 12:34' for function str_to_date -select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +exp 0 -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34'; -str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34' as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '2007-10-00 12:34' for function str_to_date select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' - and '2007/10/20'; -str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' - and '2007/10/20' + and '2007/10/20' as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '2007-10-00' for function str_to_date @@ -4333,23 +4330,23 @@ str_to_date('','%Y-%m-%d') = '' 1 Warnings: Warning 1292 Truncated incorrect datetime value: '' -select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01'; -str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01' +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01' as exp; +exp 1 -select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL; -str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL as exp; +exp NULL -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01'; -str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01' +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01' as exp; +exp NULL -select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL; -str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL +select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL as exp; +exp 0 -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01'; -str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01' +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01' as exp; +exp 0 -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL; -str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL as exp; +exp NULL CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY); CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL, diff --git a/mysql-test/main/select_pkeycache.result b/mysql-test/main/select_pkeycache.result index 19fd2858f5f..db2c5ba2728 100644 --- a/mysql-test/main/select_pkeycache.result +++ b/mysql-test/main/select_pkeycache.result @@ -4184,106 +4184,103 @@ ALTER VIEW v1 AS SELECT 1 AS ` `; ERROR 42000: Incorrect column name ' ' DROP VIEW v1; select str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' - and '2007/10/20 00:00:00 GMT'; -str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' - and '2007/10/20 00:00:00 GMT' + and '2007/10/20 00:00:00 GMT' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT' Warning 1292 Truncated incorrect datetime value: '2007/10/20 00:00:00 GMT' -select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6'; -str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT-6' -select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6'; -str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/20 00:00:00 GMT-6' -select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6'; -str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6' +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6' as exp; +exp 0 Warnings: Warning 1292 Truncated incorrect datetime value: '2007/10/2000:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-1 00:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect date value: '2007-10-01 x00:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:x00:00 GMT-6' -select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6'; -str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6' +select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect date value: '2007-10-01 x12:34:56 GMT-6' -select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; -str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' +select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6' -select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'; -str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6' as exp; +exp 0 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6' -select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56'; -str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56' +select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56' as exp; +exp 1 -select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00'; -str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00' +select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00' as exp; +exp 0 -select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00'; -str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00' +select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00' as exp; +exp 1 -select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00'; -str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00' +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00' as exp; +exp 1 Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34' -select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34'; -str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34' +select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34' as exp; +exp 1 -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +exp 1 select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' - and '2007/10/20 00:00:00'; -str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' - and '2007/10/20 00:00:00' + and '2007/10/20 00:00:00' as exp; +exp 1 set SQL_MODE=TRADITIONAL; -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '2007-10-00 12:34' for function str_to_date -select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; -str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' +select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' as exp; +exp 0 -select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34'; -str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34' +select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34' as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '2007-10-00 12:34' for function str_to_date select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' - and '2007/10/20'; -str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' - and '2007/10/20' + and '2007/10/20' as exp; +exp NULL Warnings: Warning 1411 Incorrect datetime value: '2007-10-00' for function str_to_date @@ -4322,23 +4319,23 @@ str_to_date('','%Y-%m-%d') = '' 1 Warnings: Warning 1292 Truncated incorrect datetime value: '' -select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01'; -str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01' +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01' as exp; +exp 1 -select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL; -str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL as exp; +exp NULL -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01'; -str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01' +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01' as exp; +exp NULL -select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL; -str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL +select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL as exp; +exp 0 -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01'; -str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01' +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01' as exp; +exp 0 -select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL; -str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL as exp; +exp NULL CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY); CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL, diff --git a/mysql-test/main/sequence_debug.result b/mysql-test/main/sequence_debug.result new file mode 100644 index 00000000000..5147837bade --- /dev/null +++ b/mysql-test/main/sequence_debug.result @@ -0,0 +1,12 @@ +# +# MDEV-20471 Assertion during cleanup of failed CREATE TABLE LIKE +# +CREATE SEQUENCE s; +set @save_debug_dbug=@@debug_dbug; +set debug_dbug='+d,kill_query_on_sequence_insert'; +CREATE TABLE t LIKE s; +ERROR 70100: Query execution was interrupted +DROP TABLE t; +ERROR 42S02: Unknown table 'test.t' +DROP SEQUENCE s; +set debug_dbug=@save_debug_dbug; diff --git a/mysql-test/main/sequence_debug.test b/mysql-test/main/sequence_debug.test new file mode 100644 index 00000000000..a9ccc2c61b2 --- /dev/null +++ b/mysql-test/main/sequence_debug.test @@ -0,0 +1,16 @@ +--source include/have_debug.inc + +--echo # +--echo # MDEV-20471 Assertion during cleanup of failed CREATE TABLE LIKE +--echo # + +CREATE SEQUENCE s; +set @save_debug_dbug=@@debug_dbug; +set debug_dbug='+d,kill_query_on_sequence_insert'; +--error ER_QUERY_INTERRUPTED +CREATE TABLE t LIKE s; +--error ER_BAD_TABLE_ERROR +DROP TABLE t; + +DROP SEQUENCE s; +set debug_dbug=@save_debug_dbug; diff --git a/mysql-test/main/set_password.result b/mysql-test/main/set_password.result index a3d8683ee64..19ca628f1f7 100644 --- a/mysql-test/main/set_password.result +++ b/mysql-test/main/set_password.result @@ -1,4 +1,6 @@ set global secure_auth=0; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release create user natauth@localhost identified via 'mysql_native_password' using '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; create user invalidauth@localhost identified via 'mysql_native_password' using 'invalid'; create user newpass@localhost identified by password '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; @@ -186,6 +188,8 @@ drop user natauth@localhost, newpass@localhost, newpassnat@localhost; drop user invalidauth@localhost, invalidpass@localhost, invalidpassnat@localhost,invalidmysql57auth@localhost; drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; set global secure_auth=default; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release # switching from mysql.global_priv to mysql.user create user foo@localhost identified with mysql_native_password; update mysql.user set authentication_string=password('foo'), plugin='mysql_native_password' where user='foo' and host='localhost'; diff --git a/mysql-test/main/show_check.result b/mysql-test/main/show_check.result index 5058f6d6db0..30637e12ca0 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/show_explain.result b/mysql-test/main/show_explain.result index 1f6f3a0feb2..7d41a58ef33 100644 --- a/mysql-test/main/show_explain.result +++ b/mysql-test/main/show_explain.result @@ -244,9 +244,7 @@ set @foo= (select max(a) from t0 where sin(a) >0); connection default; show explain for $thr2; ERROR HY000: Target is not executing an operation with a query plan -kill query $thr2; connection con1; -ERROR 70100: Query execution was interrupted SET debug_dbug=@old_debug; # # Attempt SHOW EXPLAIN for an UPDATE @@ -568,9 +566,14 @@ SELECT * FROM v1, t2; connection default; show explain for $thr2; ERROR HY000: Target is not executing an operation with a query plan -kill query $thr2; connection con1; -ERROR 70100: Query execution was interrupted +a b +8 4 +8 5 +8 6 +8 7 +8 8 +8 9 SET debug_dbug=@old_debug; DROP VIEW v1; DROP TABLE t2, t3; diff --git a/mysql-test/main/show_explain.test b/mysql-test/main/show_explain.test index 6d7207b0832..d10c4eeb6fa 100644 --- a/mysql-test/main/show_explain.test +++ b/mysql-test/main/show_explain.test @@ -273,9 +273,7 @@ connection default; --source include/wait_condition.inc --error ER_TARGET_NOT_EXPLAINABLE evalp show explain for $thr2; -evalp kill query $thr2; connection con1; ---error ER_QUERY_INTERRUPTED reap; SET debug_dbug=@old_debug; @@ -504,9 +502,7 @@ connection default; --source include/wait_condition.inc --error ER_TARGET_NOT_EXPLAINABLE evalp show explain for $thr2; -evalp kill query $thr2; connection con1; ---error ER_QUERY_INTERRUPTED reap; SET debug_dbug=@old_debug; DROP VIEW v1; diff --git a/mysql-test/main/sp-code.result b/mysql-test/main/sp-code.result index 462c9f80263..a9dbe716b6c 100644 --- a/mysql-test/main/sp-code.result +++ b/mysql-test/main/sp-code.result @@ -1357,6 +1357,333 @@ drop function f1; # End of 10.3 tests # # +# Start of 10.4 tests +# +# +# MDEV-32275 getting error 'Illegal parameter data types row and bigint for operation '+' ' when using ITERATE in a FOR..DO +# +# +# Unlabeled FOR/cursor with a nested labeled LOOP inside +# +CREATE OR REPLACE PROCEDURE p1() +BEGIN +DECLARE loopDone TINYINT DEFAULT FALSE; +FOR _row IN (SELECT '' AS a) DO +SELECT 'start of outerLoop'; +innerLoop: LOOP +SELECT 'start of innerLoop'; +IF loopDone THEN +LEAVE innerLoop; +END IF; +SET loopDone = TRUE; +IF _row.a = 'v1' + THEN +SELECT 'start of THEN block'; +ITERATE innerLoop; +END IF; +SELECT 'end of innerLoop'; +END LOOP; +SELECT 'end of outerLoop'; +END FOR; +END +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set loopDone@0 0 +1 cpush [implicit_cursor]@0 +2 cursor_copy_struct [implicit_cursor] _row@1 +3 copen [implicit_cursor]@0 +4 cfetch [implicit_cursor]@0 _row@1 +5 jump_if_not 19(19) `[implicit_cursor]`%FOUND +6 stmt 0 "SELECT 'start of outerLoop'" +7 stmt 0 "SELECT 'start of innerLoop'" +8 jump_if_not 10(10) loopDone@0 +9 jump 16 +10 set loopDone@0 1 +11 jump_if_not 14(14) _row.a@1["a"] = 'v1' +12 stmt 0 "SELECT 'start of THEN block'" +13 jump 7 +14 stmt 0 "SELECT 'end of innerLoop'" +15 jump 7 +16 stmt 0 "SELECT 'end of outerLoop'" +17 cfetch [implicit_cursor]@0 _row@1 +18 jump 5 +19 cpop 1 +DROP PROCEDURE p1; +# +# Labeled FOR/cursor with a nested labeled LOOP +# +CREATE OR REPLACE PROCEDURE p1() +BEGIN +DECLARE loopDone TINYINT DEFAULT FALSE; +outerLoop: +FOR _row IN (SELECT '' AS a) DO +SELECT 'start of outerLoop'; +innerLoop: LOOP +SELECT 'start of innerLoop'; +IF loopDone THEN +LEAVE innerLoop; +END IF; +SET loopDone = TRUE; +IF _row.a = 'v1' + THEN +SELECT 'start of IF/v1/THEN block'; +ITERATE innerLoop; +END IF; +IF _row.a = 'v2' + THEN +SELECT 'start of IF/v2/THEN block'; +ITERATE outerLoop; +END IF; +SELECT 'end of innerLoop'; +END LOOP; +SELECT 'end of outerLoop'; +END FOR; +END +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set loopDone@0 0 +1 cpush [implicit_cursor]@0 +2 cursor_copy_struct [implicit_cursor] _row@1 +3 copen [implicit_cursor]@0 +4 cfetch [implicit_cursor]@0 _row@1 +5 jump_if_not 23(23) `[implicit_cursor]`%FOUND +6 stmt 0 "SELECT 'start of outerLoop'" +7 stmt 0 "SELECT 'start of innerLoop'" +8 jump_if_not 10(10) loopDone@0 +9 jump 20 +10 set loopDone@0 1 +11 jump_if_not 14(14) _row.a@1["a"] = 'v1' +12 stmt 0 "SELECT 'start of IF/v1/THEN block'" +13 jump 7 +14 jump_if_not 18(18) _row.a@1["a"] = 'v2' +15 stmt 0 "SELECT 'start of IF/v2/THEN block'" +16 cfetch [implicit_cursor]@0 _row@1 +17 jump 5 +18 stmt 0 "SELECT 'end of innerLoop'" +19 jump 7 +20 stmt 0 "SELECT 'end of outerLoop'" +21 cfetch [implicit_cursor]@0 _row@1 +22 jump 5 +23 cpop 1 +DROP PROCEDURE p1; +# +# Unlabeled FOR/integer with a labeled LOOP inside +# +CREATE OR REPLACE PROCEDURE p1() +BEGIN +DECLARE loopDone TINYINT DEFAULT FALSE; +FOR _index IN 1..10 DO +SELECT 'start of outerLoop'; +innerLoop: LOOP +SELECT 'start of innerLoop'; +IF loopDone THEN +LEAVE innerLoop; +END IF; +SET loopDone = TRUE; +IF _index = 1 +THEN +SELECT 'start of THEN block'; +ITERATE innerLoop; +END IF; +SELECT 'end of innerLoop'; +END LOOP; +SELECT 'end of outerLoop'; +END FOR; +END +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set loopDone@0 0 +1 set _index@1 1 +2 set [target_bound]@2 10 +3 jump_if_not 19(19) _index@1 <= [target_bound]@2 +4 stmt 0 "SELECT 'start of outerLoop'" +5 stmt 0 "SELECT 'start of innerLoop'" +6 jump_if_not 8(8) loopDone@0 +7 jump 14 +8 set loopDone@0 1 +9 jump_if_not 12(12) _index@1 = 1 +10 stmt 0 "SELECT 'start of THEN block'" +11 jump 5 +12 stmt 0 "SELECT 'end of innerLoop'" +13 jump 5 +14 stmt 0 "SELECT 'end of outerLoop'" +15 set _index@1 _index@1 + 1 +16 jump 3 +DROP PROCEDURE p1; +# +# Labeled FOR/integer with a labeled LOOP inside +# +CREATE OR REPLACE PROCEDURE p1() +BEGIN +DECLARE loopDone TINYINT DEFAULT FALSE; +outerLoop: +FOR _index IN 1..10 DO +SELECT 'start of outerLoop'; +innerLoop: LOOP +SELECT 'start of innerLoop'; +IF loopDone THEN +LEAVE innerLoop; +END IF; +SET loopDone = TRUE; +IF _index = 1 +THEN +SELECT 'start of IF/1/THEN block'; +ITERATE innerLoop; +END IF; +IF _index = 2 +THEN +SELECT 'start of IF/2/THEN block'; +ITERATE outerLoop; +END IF; +SELECT 'end of innerLoop'; +END LOOP; +SELECT 'end of outerLoop'; +END FOR; +END +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set loopDone@0 0 +1 set _index@1 1 +2 set [target_bound]@2 10 +3 jump_if_not 24(24) _index@1 <= [target_bound]@2 +4 stmt 0 "SELECT 'start of outerLoop'" +5 stmt 0 "SELECT 'start of innerLoop'" +6 jump_if_not 8(8) loopDone@0 +7 jump 18 +8 set loopDone@0 1 +9 jump_if_not 12(12) _index@1 = 1 +10 stmt 0 "SELECT 'start of IF/1/THEN block'" +11 jump 5 +12 jump_if_not 16(16) _index@1 = 2 +13 stmt 0 "SELECT 'start of IF/2/THEN block'" +14 set _index@1 _index@1 + 1 +15 jump 3 +16 stmt 0 "SELECT 'end of innerLoop'" +17 jump 5 +18 stmt 0 "SELECT 'end of outerLoop'" +19 set _index@1 _index@1 + 1 +20 jump 3 +DROP PROCEDURE p1; +# +# Unlabeled FOR/integer with a labeled FOR inside +# +CREATE OR REPLACE PROCEDURE p1() +BEGIN +DECLARE loopDone TINYINT DEFAULT FALSE; +FOR _index_outer IN 1..10 DO +SELECT 'start of outerLoop'; +innerLoop: +FOR _index_inner IN 1..10 DO +SELECT 'start of innerLoop'; +IF loopDone THEN +LEAVE innerLoop; +END IF; +SET loopDone = TRUE; +IF _index_inner = 1 +THEN +SELECT 'start of IF/1/THEN block'; +ITERATE innerLoop; +END IF; +SELECT 'end of innerLoop'; +END FOR; +SELECT 'end of outerLoop'; +END FOR; +END +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set loopDone@0 0 +1 set _index_outer@1 1 +2 set [target_bound]@2 10 +3 jump_if_not 24(24) _index_outer@1 <= [target_bound]@2 +4 stmt 0 "SELECT 'start of outerLoop'" +5 set _index_inner@3 1 +6 set [target_bound]@4 10 +7 jump_if_not 19(19) _index_inner@3 <= [target_bound]@4 +8 stmt 0 "SELECT 'start of innerLoop'" +9 jump_if_not 11(11) loopDone@0 +10 jump 19 +11 set loopDone@0 1 +12 jump_if_not 16(16) _index_inner@3 = 1 +13 stmt 0 "SELECT 'start of IF/1/THEN block'" +14 set _index_inner@3 _index_inner@3 + 1 +15 jump 7 +16 stmt 0 "SELECT 'end of innerLoop'" +17 set _index_inner@3 _index_inner@3 + 1 +18 jump 7 +19 stmt 0 "SELECT 'end of outerLoop'" +20 set _index_outer@1 _index_outer@1 + 1 +21 jump 3 +DROP PROCEDURE p1; +# +# Labeled FOR/integer with a labeled FOR inside +# +CREATE OR REPLACE PROCEDURE p1() +BEGIN +DECLARE loopDone TINYINT DEFAULT FALSE; +outerLoop: +FOR _index_outer IN 1..10 DO +SELECT 'start of outerLoop'; +innerLoop: +FOR _index_inner IN 1..10 DO +SELECT 'start of innerLoop'; +IF loopDone THEN +LEAVE innerLoop; +END IF; +SET loopDone = TRUE; +IF _index_inner = 1 +THEN +SELECT 'start of IF/1/THEN block'; +ITERATE innerLoop; +END IF; +IF _index_inner = 2 +THEN +SELECT 'start of IF/2/THEN block'; +ITERATE outerLoop; +END IF; +SELECT 'end of innerLoop'; +END FOR; +SELECT 'end of outerLoop'; +END FOR; +END +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set loopDone@0 0 +1 set _index_outer@1 1 +2 set [target_bound]@2 10 +3 jump_if_not 29(29) _index_outer@1 <= [target_bound]@2 +4 stmt 0 "SELECT 'start of outerLoop'" +5 set _index_inner@3 1 +6 set [target_bound]@4 10 +7 jump_if_not 23(23) _index_inner@3 <= [target_bound]@4 +8 stmt 0 "SELECT 'start of innerLoop'" +9 jump_if_not 11(11) loopDone@0 +10 jump 23 +11 set loopDone@0 1 +12 jump_if_not 16(16) _index_inner@3 = 1 +13 stmt 0 "SELECT 'start of IF/1/THEN block'" +14 set _index_inner@3 _index_inner@3 + 1 +15 jump 7 +16 jump_if_not 20(20) _index_inner@3 = 2 +17 stmt 0 "SELECT 'start of IF/2/THEN block'" +18 set _index_outer@1 _index_outer@1 + 1 +19 jump 3 +20 stmt 0 "SELECT 'end of innerLoop'" +21 set _index_inner@3 _index_inner@3 + 1 +22 jump 7 +23 stmt 0 "SELECT 'end of outerLoop'" +24 set _index_outer@1 _index_outer@1 + 1 +25 jump 3 +DROP PROCEDURE p1; +# +# End of 10.4 tests +# +# # MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr # CREATE OR REPLACE PROCEDURE p1() diff --git a/mysql-test/main/sp-code.test b/mysql-test/main/sp-code.test index eef3382f214..5bb9466907a 100644 --- a/mysql-test/main/sp-code.test +++ b/mysql-test/main/sp-code.test @@ -976,6 +976,230 @@ drop function f1; --echo # End of 10.3 tests --echo # +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-32275 getting error 'Illegal parameter data types row and bigint for operation '+' ' when using ITERATE in a FOR..DO +--echo # + +--echo # +--echo # Unlabeled FOR/cursor with a nested labeled LOOP inside +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE p1() +BEGIN + DECLARE loopDone TINYINT DEFAULT FALSE; + FOR _row IN (SELECT '' AS a) DO + SELECT 'start of outerLoop'; + innerLoop: LOOP + SELECT 'start of innerLoop'; + IF loopDone THEN + LEAVE innerLoop; + END IF; + SET loopDone = TRUE; + IF _row.a = 'v1' + THEN + SELECT 'start of THEN block'; + ITERATE innerLoop; + END IF; + SELECT 'end of innerLoop'; + END LOOP; + SELECT 'end of outerLoop'; + END FOR; +END +$$ +DELIMITER ;$$ +SHOW PROCEDURE CODE p1; +DROP PROCEDURE p1; + + +--echo # +--echo # Labeled FOR/cursor with a nested labeled LOOP +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE p1() +BEGIN + DECLARE loopDone TINYINT DEFAULT FALSE; +outerLoop: + FOR _row IN (SELECT '' AS a) DO + SELECT 'start of outerLoop'; + innerLoop: LOOP + SELECT 'start of innerLoop'; + IF loopDone THEN + LEAVE innerLoop; + END IF; + SET loopDone = TRUE; + IF _row.a = 'v1' + THEN + SELECT 'start of IF/v1/THEN block'; + ITERATE innerLoop; + END IF; + IF _row.a = 'v2' + THEN + SELECT 'start of IF/v2/THEN block'; + ITERATE outerLoop; + END IF; + SELECT 'end of innerLoop'; + END LOOP; + SELECT 'end of outerLoop'; + END FOR; +END +$$ +DELIMITER ;$$ +SHOW PROCEDURE CODE p1; +DROP PROCEDURE p1; + + +--echo # +--echo # Unlabeled FOR/integer with a labeled LOOP inside +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE p1() +BEGIN + DECLARE loopDone TINYINT DEFAULT FALSE; + FOR _index IN 1..10 DO + SELECT 'start of outerLoop'; + innerLoop: LOOP + SELECT 'start of innerLoop'; + IF loopDone THEN + LEAVE innerLoop; + END IF; + SET loopDone = TRUE; + IF _index = 1 + THEN + SELECT 'start of THEN block'; + ITERATE innerLoop; + END IF; + SELECT 'end of innerLoop'; + END LOOP; + SELECT 'end of outerLoop'; + END FOR; +END +$$ +DELIMITER ;$$ +SHOW PROCEDURE CODE p1; +DROP PROCEDURE p1; + + +--echo # +--echo # Labeled FOR/integer with a labeled LOOP inside +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE p1() +BEGIN + DECLARE loopDone TINYINT DEFAULT FALSE; +outerLoop: + FOR _index IN 1..10 DO + SELECT 'start of outerLoop'; + innerLoop: LOOP + SELECT 'start of innerLoop'; + IF loopDone THEN + LEAVE innerLoop; + END IF; + SET loopDone = TRUE; + IF _index = 1 + THEN + SELECT 'start of IF/1/THEN block'; + ITERATE innerLoop; + END IF; + IF _index = 2 + THEN + SELECT 'start of IF/2/THEN block'; + ITERATE outerLoop; + END IF; + SELECT 'end of innerLoop'; + END LOOP; + SELECT 'end of outerLoop'; + END FOR; +END +$$ +DELIMITER ;$$ +SHOW PROCEDURE CODE p1; +DROP PROCEDURE p1; + + +--echo # +--echo # Unlabeled FOR/integer with a labeled FOR inside +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE p1() +BEGIN + DECLARE loopDone TINYINT DEFAULT FALSE; + FOR _index_outer IN 1..10 DO + SELECT 'start of outerLoop'; + innerLoop: + FOR _index_inner IN 1..10 DO + SELECT 'start of innerLoop'; + IF loopDone THEN + LEAVE innerLoop; + END IF; + SET loopDone = TRUE; + IF _index_inner = 1 + THEN + SELECT 'start of IF/1/THEN block'; + ITERATE innerLoop; + END IF; + SELECT 'end of innerLoop'; + END FOR; + SELECT 'end of outerLoop'; + END FOR; +END +$$ +DELIMITER ;$$ +SHOW PROCEDURE CODE p1; +DROP PROCEDURE p1; + + + +--echo # +--echo # Labeled FOR/integer with a labeled FOR inside +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE p1() +BEGIN + DECLARE loopDone TINYINT DEFAULT FALSE; +outerLoop: + FOR _index_outer IN 1..10 DO + SELECT 'start of outerLoop'; + innerLoop: + FOR _index_inner IN 1..10 DO + SELECT 'start of innerLoop'; + IF loopDone THEN + LEAVE innerLoop; + END IF; + SET loopDone = TRUE; + IF _index_inner = 1 + THEN + SELECT 'start of IF/1/THEN block'; + ITERATE innerLoop; + END IF; + IF _index_inner = 2 + THEN + SELECT 'start of IF/2/THEN block'; + ITERATE outerLoop; + END IF; + SELECT 'end of innerLoop'; + END FOR; + SELECT 'end of outerLoop'; + END FOR; +END +$$ +DELIMITER ;$$ +SHOW PROCEDURE CODE p1; +DROP PROCEDURE p1; + +--echo # +--echo # End of 10.4 tests +--echo # + --echo # --echo # MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr diff --git a/mysql-test/main/sp-for-loop.result b/mysql-test/main/sp-for-loop.result index d62d6ae3612..72fad0643b1 100644 --- a/mysql-test/main/sp-for-loop.result +++ b/mysql-test/main/sp-for-loop.result @@ -206,3 +206,33 @@ SELECT f1(3), f1(4), f1(5) FROM DUAL; f1(3) f1(4) f1(5) 6 8 8 DROP FUNCTION f1; +# +# End of 10.3 tests +# +# +# Start of 10.4 tests +# +# +# MDEV-32275 getting error 'Illegal parameter data types row and bigint for operation '+' ' when using ITERATE in a FOR..DO +# +CREATE OR REPLACE PROCEDURE forIterateBug() +BEGIN +DECLARE loopDone TINYINT DEFAULT FALSE; +FOR _unused IN (SELECT '') DO +innerLoop: LOOP +IF loopDone THEN +LEAVE innerLoop; +END IF; +SET loopDone = TRUE; +BEGIN +ITERATE innerLoop; +END; +END LOOP; +END FOR; +END; +$$ +CALL forIterateBug; +DROP PROCEDURE forIterateBug; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/sp-for-loop.test b/mysql-test/main/sp-for-loop.test index 420ab58aaa7..d6b30b0e99f 100644 --- a/mysql-test/main/sp-for-loop.test +++ b/mysql-test/main/sp-for-loop.test @@ -210,3 +210,41 @@ END; DELIMITER ;/ SELECT f1(3), f1(4), f1(5) FROM DUAL; DROP FUNCTION f1; + +--echo # +--echo # End of 10.3 tests +--echo # + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-32275 getting error 'Illegal parameter data types row and bigint for operation '+' ' when using ITERATE in a FOR..DO +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE forIterateBug() +BEGIN + DECLARE loopDone TINYINT DEFAULT FALSE; + FOR _unused IN (SELECT '') DO + innerLoop: LOOP + IF loopDone THEN + LEAVE innerLoop; + END IF; + SET loopDone = TRUE; + BEGIN + ITERATE innerLoop; + END; + END LOOP; + END FOR; +END; +$$ +DELIMITER ;$$ +CALL forIterateBug; +DROP PROCEDURE forIterateBug; + + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/main/sp-lock.result b/mysql-test/main/sp-lock.result index ec8d8970ae3..e7ebc3aecb8 100644 --- a/mysql-test/main/sp-lock.result +++ b/mysql-test/main/sp-lock.result @@ -13,12 +13,6 @@ # Start a transaction, create a savepoint, # then call a DDL operation on a procedure, and then check # that the savepoint is no longer present. -drop table if exists t1; -drop procedure if exists p1; -drop procedure if exists p2; -drop procedure if exists p3; -drop procedure if exists p4; -drop function if exists f1; create table t1 (a int); # # Test 'CREATE PROCEDURE'. @@ -469,8 +463,8 @@ drop function f1; create function f1() returns varchar(20) return "f1()"; create function f2() returns varchar(20) return "f2()"; create view v1 as select f1() as a; -set @@session.autocommit=0; lock table v1 read; +start transaction; select * from v1; a f1() @@ -492,6 +486,7 @@ connection con2; # Reaping 'drop function f2'... connection default; unlock tables; +commit; connection con1; # Reaping 'drop function f1'... connection default; @@ -500,7 +495,6 @@ ERROR 42000: FUNCTION test.f1 does not exist drop function f2; ERROR 42000: FUNCTION test.f2 does not exist drop view v1; -set @@session.autocommit=default; # # 8) Check the situation when we're preparing or executing a # prepared statement, and as part of that try to flush the @@ -744,8 +738,6 @@ DROP PROCEDURE p1; # Bug#57663 Concurrent statement using stored function and DROP DATABASE # breaks SBR # -DROP DATABASE IF EXISTS db1; -DROP FUNCTION IF EXISTS f1; connect con1, localhost, root; connect con2, localhost, root; # Test 1: Check that DROP DATABASE block if a function is used diff --git a/mysql-test/main/sp-lock.test b/mysql-test/main/sp-lock.test index f31a8268231..9ca071070ac 100644 --- a/mysql-test/main/sp-lock.test +++ b/mysql-test/main/sp-lock.test @@ -23,14 +23,6 @@ # Tests will be skipped for the view protocol -- source include/no_view_protocol.inc ---disable_warnings -drop table if exists t1; -drop procedure if exists p1; -drop procedure if exists p2; -drop procedure if exists p3; -drop procedure if exists p4; -drop function if exists f1; ---enable_warnings create table t1 (a int); --echo # --echo # Test 'CREATE PROCEDURE'. @@ -545,8 +537,8 @@ drop function f1; create function f1() returns varchar(20) return "f1()"; create function f2() returns varchar(20) return "f2()"; create view v1 as select f1() as a; -set @@session.autocommit=0; lock table v1 read; +start transaction; select * from v1; savepoint sv; select f2(); @@ -573,6 +565,7 @@ connection con2; reap; connection default; unlock tables; +commit; connection con1; --echo # Reaping 'drop function f1'... reap; @@ -582,7 +575,6 @@ drop function f1; --error ER_SP_DOES_NOT_EXIST drop function f2; drop view v1; -set @@session.autocommit=default; --echo # --echo # 8) Check the situation when we're preparing or executing a @@ -861,11 +853,6 @@ DROP PROCEDURE p1; --echo # breaks SBR --echo # ---disable_warnings -DROP DATABASE IF EXISTS db1; -DROP FUNCTION IF EXISTS f1; ---enable_warnings - connect(con1, localhost, root); connect(con2, localhost, root); diff --git a/mysql-test/main/sp_notembedded.result b/mysql-test/main/sp_notembedded.result index e03361598a6..927e03d2a4d 100644 --- a/mysql-test/main/sp_notembedded.result +++ b/mysql-test/main/sp_notembedded.result @@ -1,7 +1,5 @@ set @old_concurrent_insert= @@global.concurrent_insert; set @@global.concurrent_insert= 0; -drop table if exists t1,t3; -drop procedure if exists bug4902| create procedure bug4902() begin show grants for 'root'@'localhost'; @@ -15,7 +13,6 @@ Grants for root@localhost GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION drop procedure bug4902| -drop procedure if exists bug4902_2| create procedure bug4902_2() begin show processlist; @@ -23,13 +20,10 @@ end| call bug4902_2()| show warnings| Level Code Message -Note 1305 PROCEDURE test.bug4902_2 does not exist call bug4902_2()| show warnings| Level Code Message -Note 1305 PROCEDURE test.bug4902_2 does not exist drop procedure bug4902_2| -drop procedure if exists bug6807| create procedure bug6807() begin declare a int; @@ -42,116 +36,6 @@ ERROR 70100: Query execution was interrupted call bug6807()| ERROR 70100: Query execution was interrupted drop procedure bug6807| -drop function if exists bug10100f| -drop procedure if exists bug10100p| -drop procedure if exists bug10100t| -drop procedure if exists bug10100pt| -drop procedure if exists bug10100pv| -drop procedure if exists bug10100pd| -drop procedure if exists bug10100pc| -create function bug10100f(prm int) returns int -begin -if prm > 1 then -return prm * bug10100f(prm - 1); -end if; -return 1; -end| -set statement sql_mode = '' for -create procedure bug10100p(prm int, inout res int) -begin -set res = res * prm; -if prm > 1 then -call bug10100p(prm - 1, res); -end if; -end| -set statement sql_mode = '' for -create procedure bug10100t(prm int) -begin -declare res int; -set res = 1; -call bug10100p(prm, res); -select res; -end| -create table t3 (a int)| -insert into t3 values (0)| -create view v1 as select a from t3| -create procedure bug10100pt(level int, lim int) -begin -if level < lim then -update t3 set a=level; -FLUSH TABLES; -call bug10100pt(level+1, lim); -else -select * from t3; -end if; -end| -create procedure bug10100pv(level int, lim int) -begin -if level < lim then -update v1 set a=level; -FLUSH TABLES; -call bug10100pv(level+1, lim); -else -select * from v1; -end if; -end| -prepare stmt2 from "select * from t3;"; -create procedure bug10100pd(level int, lim int) -begin -if level < lim then -select level; -prepare stmt1 from "update t3 set a=a+2"; -execute stmt1; -FLUSH TABLES; -execute stmt1; -FLUSH TABLES; -execute stmt1; -FLUSH TABLES; -deallocate prepare stmt1; -execute stmt2; -select * from t3; -call bug10100pd(level+1, lim); -else -execute stmt2; -end if; -end| -create procedure bug10100pc(level int, lim int) -begin -declare lv int; -declare c cursor for select a from t3; -open c; -if level < lim then -select level; -fetch c into lv; -select lv; -update t3 set a=level+lv; -FLUSH TABLES; -call bug10100pc(level+1, lim); -else -select * from t3; -end if; -close c; -end| -set @@max_sp_recursion_depth=255| -set @var=1| -call bug10100p(255, @var)| -call bug10100pt(1,255)| -call bug10100pv(1,255)| -call bug10100pd(1,255)| -call bug10100pc(1,255)| -set @@max_sp_recursion_depth=0| -deallocate prepare stmt2| -drop function bug10100f| -drop procedure bug10100p| -drop procedure bug10100t| -drop procedure bug10100pt| -drop procedure bug10100pv| -drop procedure bug10100pd| -drop procedure bug10100pc| -drop view v1| -drop table t3| -drop procedure if exists bug15298_1; -drop procedure if exists bug15298_2; create user 'mysqltest_1'@'localhost'; grant all privileges on test.* to 'mysqltest_1'@'localhost'; create procedure 15298_1 () sql security definer show grants for current_user; @@ -170,8 +54,6 @@ disconnect con1; drop user mysqltest_1@localhost; drop procedure 15298_1; drop procedure 15298_2; -drop table if exists t1; -drop procedure if exists p1; create table t1 (value varchar(15)); create procedure p1() update t1 set value='updated' where value='old'; call p1(); @@ -283,7 +165,6 @@ disconnect con2; # functions in databases which names contained dot. # connection default; -DROP DATABASE IF EXISTS `my.db`; create database `my.db`; use `my.db`; CREATE FUNCTION f1(a int) RETURNS INT RETURN a; diff --git a/mysql-test/main/sp_notembedded.test b/mysql-test/main/sp_notembedded.test index 12bacff4e87..9aca03fbdc5 100644 --- a/mysql-test/main/sp_notembedded.test +++ b/mysql-test/main/sp_notembedded.test @@ -7,19 +7,12 @@ set @@global.concurrent_insert= 0; # Save the initial number of concurrent sessions --source include/count_sessions.inc ---disable_warnings -drop table if exists t1,t3; ---enable_warnings delimiter |; - # # Bug#4902 Stored procedure with SHOW WARNINGS leads to packet error # # Added tests for show grants command ---disable_warnings -drop procedure if exists bug4902| ---enable_warnings create procedure bug4902() begin show grants for 'root'@'localhost'; @@ -38,9 +31,6 @@ call bug4902()| drop procedure bug4902| # We need separate SP for SHOW PROCESSLIST since we want use replace_column ---disable_warnings -drop procedure if exists bug4902_2| ---enable_warnings create procedure bug4902_2() begin show processlist; @@ -58,9 +48,6 @@ drop procedure bug4902_2| # # Bug#6807 Stored procedure crash if CREATE PROCEDURE ... KILL QUERY # ---disable_warnings -drop procedure if exists bug6807| ---enable_warnings create procedure bug6807() begin declare a int; @@ -77,152 +64,11 @@ call bug6807()| drop procedure bug6807| - -# -# Bug#10100 function (and stored procedure?) recursivity problem -# ---disable_warnings -drop function if exists bug10100f| -drop procedure if exists bug10100p| -drop procedure if exists bug10100t| -drop procedure if exists bug10100pt| -drop procedure if exists bug10100pv| -drop procedure if exists bug10100pd| -drop procedure if exists bug10100pc| ---enable_warnings -# routines with simple recursion -create function bug10100f(prm int) returns int -begin - if prm > 1 then - return prm * bug10100f(prm - 1); - end if; - return 1; -end| -set statement sql_mode = '' for -create procedure bug10100p(prm int, inout res int) -begin - set res = res * prm; - if prm > 1 then - call bug10100p(prm - 1, res); - end if; -end| -set statement sql_mode = '' for -create procedure bug10100t(prm int) -begin - declare res int; - set res = 1; - call bug10100p(prm, res); - select res; -end| - -# a procedure which use tables and recursion -create table t3 (a int)| -insert into t3 values (0)| -create view v1 as select a from t3| -create procedure bug10100pt(level int, lim int) -begin - if level < lim then - update t3 set a=level; - FLUSH TABLES; - call bug10100pt(level+1, lim); - else - select * from t3; - end if; -end| -# view & recursion -create procedure bug10100pv(level int, lim int) -begin - if level < lim then - update v1 set a=level; - FLUSH TABLES; - call bug10100pv(level+1, lim); - else - select * from v1; - end if; -end| -# dynamic sql & recursion -prepare stmt2 from "select * from t3;"; -create procedure bug10100pd(level int, lim int) -begin - if level < lim then - select level; - prepare stmt1 from "update t3 set a=a+2"; - execute stmt1; - FLUSH TABLES; - execute stmt1; - FLUSH TABLES; - execute stmt1; - FLUSH TABLES; - deallocate prepare stmt1; - execute stmt2; - select * from t3; - call bug10100pd(level+1, lim); - else - execute stmt2; - end if; -end| -# cursor & recursion -create procedure bug10100pc(level int, lim int) -begin - declare lv int; - declare c cursor for select a from t3; - open c; - if level < lim then - select level; - fetch c into lv; - select lv; - update t3 set a=level+lv; - FLUSH TABLES; - call bug10100pc(level+1, lim); - else - select * from t3; - end if; - close c; -end| - -# end of the stack checking -set @@max_sp_recursion_depth=255| -set @var=1| -# disable log because error about stack overrun contains numbers which -# depend on a system --- disable_ps_protocol --- disable_result_log --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100p(255, @var)| --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100pt(1,255)| --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100pv(1,255)| --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100pd(1,255)| --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100pc(1,255)| --- enable_result_log --- enable_ps_protocol -set @@max_sp_recursion_depth=0| - -deallocate prepare stmt2| - -drop function bug10100f| -drop procedure bug10100p| -drop procedure bug10100t| -drop procedure bug10100pt| -drop procedure bug10100pv| -drop procedure bug10100pd| -drop procedure bug10100pc| -drop view v1| -drop table t3| - delimiter ;| - # # Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context # ---disable_warnings -drop procedure if exists bug15298_1; -drop procedure if exists bug15298_2; ---enable_warnings create user 'mysqltest_1'@'localhost'; grant all privileges on test.* to 'mysqltest_1'@'localhost'; create procedure 15298_1 () sql security definer show grants for current_user; @@ -242,11 +88,6 @@ drop procedure 15298_2; # Bug#29936 Stored Procedure DML ignores low_priority_updates setting # ---disable_warnings -drop table if exists t1; -drop procedure if exists p1; ---enable_warnings - create table t1 (value varchar(15)); create procedure p1() update t1 set value='updated' where value='old'; @@ -411,10 +252,6 @@ DROP FUNCTION f1; connection default; ---disable_warnings -DROP DATABASE IF EXISTS `my.db`; ---enable_warnings - create database `my.db`; use `my.db`; diff --git a/mysql-test/main/sql_mode.test b/mysql-test/main/sql_mode.test index bfcaff39253..56c4bd2ace0 100644 --- a/mysql-test/main/sql_mode.test +++ b/mysql-test/main/sql_mode.test @@ -575,7 +575,9 @@ DELIMITER ;$$ SET sql_mode='ORACLE,EMPTY_STRING_IS_NULL'; SELECT @@sql_mode; +--disable_service_connection SELECT '' AS empty; +--enable_service_connection SET sql_mode=''; SELECT @@sql_mode; SET sql_mode=DEFAULT; diff --git a/mysql-test/main/ssl.result b/mysql-test/main/ssl.result index 2694d177056..07ba2bbaece 100644 --- a/mysql-test/main/ssl.result +++ b/mysql-test/main/ssl.result @@ -1,4 +1,22 @@ connect ssl_con,localhost,root,,,,,SSL; +select variable_name from performance_schema.status_by_thread where VARIABLE_NAME LIKE 'Ssl%'; +variable_name +Ssl_cipher +Ssl_cipher_list +Ssl_default_timeout +Ssl_server_not_after +Ssl_server_not_before +Ssl_verify_depth +Ssl_verify_mode +Ssl_version +Ssl_cipher +Ssl_cipher_list +Ssl_default_timeout +Ssl_server_not_after +Ssl_server_not_before +Ssl_verify_depth +Ssl_verify_mode +Ssl_version SELECT (VARIABLE_VALUE <> '') AS have_ssl FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_cipher'; have_ssl 1 diff --git a/mysql-test/main/ssl.test b/mysql-test/main/ssl.test index d3830bb7007..642af380be9 100644 --- a/mysql-test/main/ssl.test +++ b/mysql-test/main/ssl.test @@ -10,9 +10,12 @@ --source include/count_sessions.inc --source include/default_charset.inc +--source include/have_perfschema.inc connect (ssl_con,localhost,root,,,,,SSL); +select variable_name from performance_schema.status_by_thread where VARIABLE_NAME LIKE 'Ssl%'; + # Check ssl turned on SELECT (VARIABLE_VALUE <> '') AS have_ssl FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_cipher'; diff --git a/mysql-test/main/subselect.result b/mysql-test/main/subselect.result index 6e0c956b77e..627090703b4 100644 --- a/mysql-test/main/subselect.result +++ b/mysql-test/main/subselect.result @@ -1332,7 +1332,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); @@ -7191,23 +7191,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` @@ -7220,6 +7223,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 @@ -7525,5 +7529,107 @@ 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 # +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.6 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +insert into t2 select (('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)); +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +drop view v1; +drop table t1, t2, t3; +# +# End of 10.6 tests +# +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.10 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE (select 1 where ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)) <> 0"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e') IN (SELECT v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +DROP VIEW v1; +DROP TABLE t1, t2, t3; +# +# End of 10.10 tests +# diff --git a/mysql-test/main/subselect.test b/mysql-test/main/subselect.test index 434eae2bf2b..5ad1aabd001 100644 --- a/mysql-test/main/subselect.test +++ b/mysql-test/main/subselect.test @@ -1181,13 +1181,16 @@ DROP TABLE t1; # Bug#2198 SELECT INTO OUTFILE (with Sub-Select) Problem # +--disable_service_connection --disable_ps2_protocol 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; @@ -1195,6 +1198,7 @@ eval load data infile "$outfile_rel" into table t1; select * from t1; drop table t1; --enable_ps2_protocol +--enable_service_connection # # Bug#2479 dependant subquery with limit crash @@ -6008,24 +6012,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` @@ -6037,6 +6045,7 @@ call procedure2(); call procedure2(); drop procedure procedure2; +drop table t1; --echo # @@ -6358,6 +6367,113 @@ 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 # + + + +--echo # +--echo # MDEV-32656: ASAN errors in base_list_iterator::next / +--echo # setup_table_map upon 2nd execution of PS +--echo # (10.6 part) +--echo # + +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; + +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); + +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); + +insert into t2 select (('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)); + +drop view v1; +drop table t1, t2, t3; + +--echo # +--echo # End of 10.6 tests +--echo # + +--echo # +--echo # MDEV-32656: ASAN errors in base_list_iterator::next / +--echo # setup_table_map upon 2nd execution of PS +--echo # (10.10 part) +--echo # + +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; + +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); + +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); + +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE (select 1 where ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)) <> 0"; +EXECUTE stmt; +EXECUTE stmt; + +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e') IN (SELECT v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +EXECUTE stmt; + +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +EXECUTE stmt; + +# Cleanup +DROP VIEW v1; +DROP TABLE t1, t2, t3; + +--echo # +--echo # End of 10.10 tests +--echo # diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index 2042dadeb70..7203710f305 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -309,8 +309,8 @@ pk i 0 10 2 30 3 40 -SELECT (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk) from t1; -(NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk) +SELECT (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk) as exp from t1; +exp 1 NULL 1 @@ -325,8 +325,8 @@ pk i 0 10 2 30 3 40 -SELECT (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk) from t1; -(NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk) +SELECT (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk) as exp from t1; +exp 1 NULL 1 @@ -341,8 +341,8 @@ pk i 0 10 2 30 3 40 -SELECT (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk) from t1; -(NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk) +SELECT (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk) as exp from t1; +exp 1 NULL 1 @@ -357,8 +357,8 @@ pk i 0 10 2 30 3 40 -SELECT (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk) from t1; -(NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk) +SELECT (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk) as exp from t1; +exp 1 NULL 1 @@ -1731,7 +1731,7 @@ CREATE TABLE t3 ( f1 int NOT NULL , f2 int) ; INSERT INTO t3 VALUES (0,0), (0,0); EXPLAIN SELECT STRAIGHT_JOIN ( SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 ) -); +) as exp; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where @@ -1739,10 +1739,8 @@ id select_type table type possible_keys key key_len ref rows Extra 3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) SELECT STRAIGHT_JOIN ( SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 ) -); -( -SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 ) -) +) as exp; +exp NULL drop table t1, t2, t3; # @@ -1866,6 +1864,8 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY SUBQUERY2_t1 index NULL col_int_key 5 NULL 2 Using index 2 SUBQUERY SUBQUERY2_t2 ALL col_varchar_key NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) 3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1105 Cannot use key `col_varchar_key` part[0] for lookup: `test`.`t1`.`col_varchar_key` of type `varchar` < "0" of type `bigint` SELECT col_int_key FROM t2 WHERE (SELECT SUBQUERY2_t1.col_int_key @@ -1891,6 +1891,8 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY SUBQUERY2_t1 index NULL col_int_key 5 NULL 2 Using index 2 SUBQUERY SUBQUERY2_t2 ALL col_varchar_key NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) 3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1105 Cannot use key `col_varchar_key` part[0] for lookup: `test`.`t1`.`col_varchar_key` of type `varchar` < "0" of type `bigint` SELECT col_int_key FROM t2 WHERE (SELECT SUBQUERY2_t1.col_int_key @@ -2630,8 +2632,8 @@ SET @save_optimizer_switch=@@optimizer_switch; SET optimizer_switch='subquery_cache=off'; CREATE TABLE t1 (a INT,b INT); INSERT INTO t1 VALUES (0,0),(0,0); -SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) FROM t1 AS t1o; -(SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) +SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) as exp FROM t1 AS t1o; +exp 0 SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; @@ -2792,17 +2794,8 @@ WHERE t1_outer.id <> id FROM t1 AS t1_outer GROUP BY f -); -1 IN ( -SELECT -(SELECT COUNT(id) -FROM t1 -WHERE t1_outer.id <> id -) AS f -FROM -t1 AS t1_outer -GROUP BY f -) +) as exp; +exp 1 SELECT 1 IN ( @@ -2814,17 +2807,8 @@ WHERE t1_outer.id <> id FROM t1 AS t1_outer GROUP BY 1 -); -1 IN ( -SELECT -(SELECT COUNT(id) -FROM t1 -WHERE t1_outer.id <> id -) AS f -FROM -t1 AS t1_outer -GROUP BY 1 -) +) as exp; +exp 1 DROP TABLE t1; # @@ -3213,4 +3197,34 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 100 drop table t0, t1, t2; +# +# MDEV-32320: Server crashes at TABLE::add_tmp_key +# +select +( ( 'x' , 1.000000 ) , 1 ) +IN +(SELECT +'x' , 'x' + WHERE ( 'x' ) +UNION +SELECT 1 , 'x' + HAVING 1 != 1 +) as T; +ERROR 21000: Operand should contain 2 column(s) +SELECT +EXISTS ( +WITH x ( x ) AS ( SELECT 1 ) +SELECT NULL +WHERE ( 1 , 1 ) = +(SELECT +1 , ( ( x , 1.000000 ) , 1 ) +IN +(SELECT 'x' , 'x' WHERE ( ( 'x' ) ) +UNION +SELECT 1 , x HAVING 1 != 1 +) +FROM x +) +); +ERROR 21000: Operand should contain 2 column(s) # End of 10.4 tests diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test index 7d3716beb07..c65dcdb2186 100644 --- a/mysql-test/main/subselect4.test +++ b/mysql-test/main/subselect4.test @@ -1,7 +1,5 @@ # General purpose bug fix tests go here : subselect.test too large -#remove this include after fix MDEV-27871, MDEV-27957 ---source include/no_view_protocol.inc --source include/default_optimizer_switch.inc @@ -243,22 +241,22 @@ SELECT t1.pk, NULL NOT IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk) FROM t1; EXPLAIN SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk); SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk); -SELECT (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk) from t1; +SELECT (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk) as exp from t1; EXPLAIN SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk); SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk); -SELECT (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk) from t1; +SELECT (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk) as exp from t1; EXPLAIN SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk); SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk); -SELECT (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk) from t1; +SELECT (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk) as exp from t1; EXPLAIN SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk); SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk); -SELECT (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk) from t1; +SELECT (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk) as exp from t1; drop table t1, t2a, t2b, t2c, t2d; @@ -1334,10 +1332,10 @@ INSERT INTO t3 VALUES (0,0), (0,0); EXPLAIN SELECT STRAIGHT_JOIN ( SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 ) -); +) as exp; SELECT STRAIGHT_JOIN ( SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 ) -); +) as exp; drop table t1, t2, t3; @@ -2158,7 +2156,7 @@ SET @save_optimizer_switch=@@optimizer_switch; SET optimizer_switch='subquery_cache=off'; CREATE TABLE t1 (a INT,b INT); INSERT INTO t1 VALUES (0,0),(0,0); -SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) FROM t1 AS t1o; +SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) as exp FROM t1 AS t1o; SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; @@ -2322,7 +2320,7 @@ SELECT FROM t1 AS t1_outer GROUP BY f - ); + ) as exp; SELECT 1 IN ( @@ -2334,7 +2332,7 @@ SELECT FROM t1 AS t1_outer GROUP BY 1 - ); + ) as exp; DROP TABLE t1; @@ -2579,5 +2577,39 @@ select * from t1 where t1.a in (select t2.a from t2 order by t2.b); drop table t0, t1, t2; +--echo # +--echo # MDEV-32320: Server crashes at TABLE::add_tmp_key +--echo # + +--error ER_OPERAND_COLUMNS +select + ( ( 'x' , 1.000000 ) , 1 ) +IN +(SELECT + 'x' , 'x' + WHERE ( 'x' ) + UNION + SELECT 1 , 'x' + HAVING 1 != 1 +) as T; + +--error ER_OPERAND_COLUMNS +SELECT + EXISTS ( + WITH x ( x ) AS ( SELECT 1 ) + SELECT NULL + WHERE ( 1 , 1 ) = + (SELECT + 1 , ( ( x , 1.000000 ) , 1 ) + IN + (SELECT 'x' , 'x' WHERE ( ( 'x' ) ) + UNION + SELECT 1 , x HAVING 1 != 1 + ) + FROM x + ) + ); + + --echo # End of 10.4 tests diff --git a/mysql-test/main/subselect_exists2in.result b/mysql-test/main/subselect_exists2in.result index 8ecdbad6b97..90d8dcefa59 100644 --- a/mysql-test/main/subselect_exists2in.result +++ b/mysql-test/main/subselect_exists2in.result @@ -331,44 +331,44 @@ CREATE TABLE t3 ( c INT ); INSERT INTO t3 VALUES (4),(5); SET optimizer_switch='exists_to_in=on,subquery_cache=off,materialization=on,in_to_exists=off,semijoin=off'; explain extended -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 2 SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1276 Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2 -Note 1003 /* select#1 */ select (/* select#2 */ select 1 from dual where !(1 is not null and (1,1 in ( (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` is not null ), (1 in on distinct_key where 1 = ``.`c`))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1` -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; -( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) +Note 1003 /* select#1 */ select (/* select#2 */ select 1 from dual where !(1 is not null and (1,1 in ( (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` is not null ), (1 in on distinct_key where 1 = ``.`c`))))) AS `exp` from `test`.`t1` +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; +exp 1 1 SET optimizer_switch='exists_to_in=on,subquery_cache=off'; explain extended -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 2 SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1276 Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2 -Note 1003 /* select#1 */ select (/* select#2 */ select 1 from dual where !(1 is not null and (1,1 in ( (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` is not null ), (1 in on distinct_key where 1 = ``.`c`))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1` -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; -( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) +Note 1003 /* select#1 */ select (/* select#2 */ select 1 from dual where !(1 is not null and (1,1 in ( (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` is not null ), (1 in on distinct_key where 1 = ``.`c`))))) AS `exp` from `test`.`t1` +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; +exp 1 1 SET optimizer_switch='exists_to_in=off,subquery_cache=off'; explain extended -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 2 SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1276 Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2 -Note 1003 /* select#1 */ select (/* select#2 */ select 1 from dual where !exists(/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` = 1 limit 1)) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1` -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; -( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) +Note 1003 /* select#1 */ select (/* select#2 */ select 1 from dual where !exists(/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` = 1 limit 1)) AS `exp` from `test`.`t1` +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; +exp 1 1 set optimizer_switch=default; diff --git a/mysql-test/main/subselect_exists2in.test b/mysql-test/main/subselect_exists2in.test index 03c2003f1f9..d8210d83b54 100644 --- a/mysql-test/main/subselect_exists2in.test +++ b/mysql-test/main/subselect_exists2in.test @@ -272,24 +272,22 @@ INSERT INTO t3 VALUES (4),(5); SET optimizer_switch='exists_to_in=on,subquery_cache=off,materialization=on,in_to_exists=off,semijoin=off'; -#enable after fix MDEV-27871 ---disable_view_protocol explain extended -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; SET optimizer_switch='exists_to_in=on,subquery_cache=off'; explain extended -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; SET optimizer_switch='exists_to_in=off,subquery_cache=off'; explain extended -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; -SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; +SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) as exp FROM t1; set optimizer_switch=default; set optimizer_switch='exists_to_in=on'; @@ -329,8 +327,6 @@ set optimizer_switch='exists_to_in=on'; drop table t1,t3; ---enable_view_protocol - --echo # --echo # MDEV-159 Assertion about not marked for read failed in --echo # String* Field_varstring::val_str(String*, String*) diff --git a/mysql-test/main/subselect_mat.result b/mysql-test/main/subselect_mat.result index a8cad01c674..e964413d60d 100644 --- a/mysql-test/main/subselect_mat.result +++ b/mysql-test/main/subselect_mat.result @@ -2699,6 +2699,48 @@ i1 i2 1 4 2 6 DROP TABLE t1; +# +# MDEV-31983 jointable materialization subquery optimization ignoring errors, then failing ASSERT. +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +CREATE TABLE t3 (c DATETIME, d INT, KEY(c)); +INSERT INTO t3 VALUES ('2012-11-11',5),('2012-12-12',6); +UPDATE t1, t2 SET t1.a = 26 WHERE t2.b IN (SELECT MIN(d) FROM t3 WHERE c >= '2012-01'); +ERROR 22007: Truncated incorrect datetime value: '2012-01' +DROP TABLE t1, t2, t3; +# +# a followup fix: +# MDEV-32682: Assertion `range->rows >= s->found_records' failed in best_access_path +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b VARCHAR(10), pk INT, PRIMARY KEY (pk)) ENGINE=MyISAM; +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status Table is already up to date +SELECT STRAIGHT_JOIN t2.* FROM t1 JOIN t2 WHERE t2.b IS NULL AND t2.pk > 1; +b pk +DROP TABLE t1, t2; +# +# MDEV-32612 Assertion `tab->select->quick' failed in test_if_skip_sort_order +# +CREATE TABLE t1 (l_orderkey int, l_linenumber int, l_quantity double, +PRIMARY KEY (l_orderkey,l_linenumber), KEY (l_orderkey), +KEY (l_orderkey,l_quantity)) engine=MyISAM; +INSERT INTO t1 VALUES (290,1,35),(290,2,2); +SELECT * FROM t1 +WHERE l_quantity = 31 +AND (l_quantity = 50 OR l_orderkey = 41) +ORDER BY l_orderkey, l_linenumber; +l_orderkey l_linenumber l_quantity +DROP TABLE t1; +# end of 10.6 tests set @subselect_mat_test_optimizer_switch_value=null; set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; diff --git a/mysql-test/main/subselect_mat_cost_bugs.result b/mysql-test/main/subselect_mat_cost_bugs.result index 7237a62d222..5df4cf8a47d 100644 --- a/mysql-test/main/subselect_mat_cost_bugs.result +++ b/mysql-test/main/subselect_mat_cost_bugs.result @@ -416,14 +416,14 @@ pk1 int, a1 varchar(3), b1 varchar(3), PRIMARY KEY (pk1), KEY(a1), KEY(b1) INSERT INTO t1 VALUES (1,'foo','bar'),(2,'bar','foo'); CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 VARCHAR(3), KEY(a2)) ENGINE=MyISAM; INSERT INTO t2 VALUES (1,'abc'),(2,'xyz'),(3,'foo'); -SELECT 'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ); -'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ) +SELECT 'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ) as exp; +exp 0 -SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ); -'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ) +SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ) as exp; +exp 1 EXPLAIN -SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ); +SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ) as exp; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 2 SUBQUERY t2 const PRIMARY,a2 PRIMARY 4 const 1 diff --git a/mysql-test/main/subselect_mat_cost_bugs.test b/mysql-test/main/subselect_mat_cost_bugs.test index 4f837efcdd8..b66c0e076ef 100644 --- a/mysql-test/main/subselect_mat_cost_bugs.test +++ b/mysql-test/main/subselect_mat_cost_bugs.test @@ -442,13 +442,10 @@ INSERT INTO t1 VALUES (1,'foo','bar'),(2,'bar','foo'); CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 VARCHAR(3), KEY(a2)) ENGINE=MyISAM; INSERT INTO t2 VALUES (1,'abc'),(2,'xyz'),(3,'foo'); -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT 'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ); -SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ); +SELECT 'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ) as exp; +SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ) as exp; EXPLAIN -SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ); ---enable_view_protocol +SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 ) as exp; DROP TABLE t1,t2; diff --git a/mysql-test/main/subselect_no_exists_to_in.result b/mysql-test/main/subselect_no_exists_to_in.result index 3750c96871b..d3f5e6d6ce4 100644 --- a/mysql-test/main/subselect_no_exists_to_in.result +++ b/mysql-test/main/subselect_no_exists_to_in.result @@ -1336,7 +1336,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); @@ -7193,23 +7193,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` @@ -7222,6 +7225,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 @@ -7527,8 +7531,110 @@ 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 # +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.6 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +insert into t2 select (('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)); +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +drop view v1; +drop table t1, t2, t3; +# +# End of 10.6 tests +# +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.10 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE (select 1 where ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)) <> 0"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e') IN (SELECT v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +DROP VIEW v1; +DROP TABLE t1, t2, t3; +# +# End of 10.10 tests +# set optimizer_switch=default; select @@optimizer_switch like '%exists_to_in=off%'; @@optimizer_switch like '%exists_to_in=off%' diff --git a/mysql-test/main/subselect_no_mat.result b/mysql-test/main/subselect_no_mat.result index f837e20be8b..25924f3d247 100644 --- a/mysql-test/main/subselect_no_mat.result +++ b/mysql-test/main/subselect_no_mat.result @@ -1339,7 +1339,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); @@ -7188,23 +7188,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` @@ -7217,6 +7220,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 @@ -7522,8 +7526,110 @@ 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 # +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.6 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +insert into t2 select (('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)); +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +drop view v1; +drop table t1, t2, t3; +# +# End of 10.6 tests +# +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.10 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE (select 1 where ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)) <> 0"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e') IN (SELECT v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +DROP VIEW v1; +DROP TABLE t1, t2, t3; +# +# End of 10.10 tests +# set optimizer_switch=default; select @@optimizer_switch like '%materialization=on%'; @@optimizer_switch like '%materialization=on%' diff --git a/mysql-test/main/subselect_no_opts.result b/mysql-test/main/subselect_no_opts.result index e2352090797..191dfc828aa 100644 --- a/mysql-test/main/subselect_no_opts.result +++ b/mysql-test/main/subselect_no_opts.result @@ -1335,7 +1335,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); @@ -7186,23 +7186,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` @@ -7215,6 +7218,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 @@ -7520,6 +7524,108 @@ 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 # +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.6 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +insert into t2 select (('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)); +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +drop view v1; +drop table t1, t2, t3; +# +# End of 10.6 tests +# +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.10 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE (select 1 where ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)) <> 0"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e') IN (SELECT v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +DROP VIEW v1; +DROP TABLE t1, t2, t3; +# +# End of 10.10 tests +# set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/main/subselect_no_scache.result b/mysql-test/main/subselect_no_scache.result index 0e5216eb120..0d18c5cc5eb 100644 --- a/mysql-test/main/subselect_no_scache.result +++ b/mysql-test/main/subselect_no_scache.result @@ -1338,7 +1338,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); @@ -7197,23 +7197,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` @@ -7226,6 +7229,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 @@ -7531,8 +7535,110 @@ 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 # +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.6 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +insert into t2 select (('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)); +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +drop view v1; +drop table t1, t2, t3; +# +# End of 10.6 tests +# +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.10 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE (select 1 where ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)) <> 0"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e') IN (SELECT v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +DROP VIEW v1; +DROP TABLE t1, t2, t3; +# +# End of 10.10 tests +# set optimizer_switch=default; select @@optimizer_switch like '%subquery_cache=on%'; @@optimizer_switch like '%subquery_cache=on%' diff --git a/mysql-test/main/subselect_no_semijoin.result b/mysql-test/main/subselect_no_semijoin.result index c7acdc2990c..0e2b6a9d9d7 100644 --- a/mysql-test/main/subselect_no_semijoin.result +++ b/mysql-test/main/subselect_no_semijoin.result @@ -1335,7 +1335,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); @@ -7186,23 +7186,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` @@ -7215,6 +7218,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 @@ -7520,9 +7524,111 @@ 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 # # +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.6 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +insert into t2 select (('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)); +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +drop view v1; +drop table t1, t2, t3; +# +# End of 10.6 tests +# +# +# MDEV-32656: ASAN errors in base_list_iterator::next / +# setup_table_map upon 2nd execution of PS +# (10.10 part) +# +CREATE TABLE t1 (id BIGINT); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (b INT); +INSERT INTO t3 VALUES (3),(4); +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE (select 1 where ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)) <> 0"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e') IN (SELECT v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +PREPARE stmt FROM "UPDATE t2 SET a = 1 WHERE ('e','e') IN (SELECT v1.id, v1.id FROM v1 JOIN t3)"; +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +EXECUTE stmt; +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +DROP VIEW v1; +DROP TABLE t1, t2, t3; +# +# End of 10.10 tests +# +# # MDEV-19714: JOIN::pseudo_bits_cond is not visible in EXPLAIN FORMAT=JSON # CREATE TABLE t1 ( a INT ); diff --git a/mysql-test/main/subselect_nulls.result b/mysql-test/main/subselect_nulls.result index 08982371269..9d3b7b2cfd5 100644 --- a/mysql-test/main/subselect_nulls.result +++ b/mysql-test/main/subselect_nulls.result @@ -1,5 +1,3 @@ -drop table if exists x1; -drop table if exists x2; set @tmp_subselect_nulls=@@optimizer_switch; set optimizer_switch='semijoin=off'; create table x1(k int primary key, d1 int, d2 int); @@ -115,9 +113,44 @@ k d1 d2 set optimizer_switch= @tmp_subselect_nulls; drop table x1; drop table x2; +# +# MDEV-7339 Server crashes in Item_func_trig_cond::val_int +# select (select 1, 2) in (select 3, 4); (select 1, 2) in (select 3, 4) 0 select (select NULL, NULL) in (select 3, 4); (select NULL, NULL) in (select 3, 4) NULL +# +# End of 5.5 tests +# +# +# MDEV-32555 wrong result with an index and a partially null-rejecting condition +# +create table t1 (a int primary key); +insert t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 ( +b int not null, +c int default null, +d int not null, +e int not null, +unique key (d,b,c) +); +insert t2 values (1,null,1,1),(1,null,2,2),(1,null,3,3),(1,null,4,4),(2,null,1,2),(3,null,1,3),(4,null,2,2),(4,null,1,4); +select ( +select sum(t2_.e) from t2 t2_ where t2_.b = a and t2_.c <=> t2.c and t2_.d = 1 +) x from t2 left join t1 on a = b; +x +1 +2 +3 +4 +1 +4 +1 +1 +drop table t1, t2; +# +# End of 10.10 tests +# diff --git a/mysql-test/main/subselect_nulls.test b/mysql-test/main/subselect_nulls.test index 3e7b2189ed5..68575eca9e7 100644 --- a/mysql-test/main/subselect_nulls.test +++ b/mysql-test/main/subselect_nulls.test @@ -1,10 +1,3 @@ -# Initialize tables for the test - ---disable_warnings -drop table if exists x1; -drop table if exists x2; ---enable_warnings - set @tmp_subselect_nulls=@@optimizer_switch; set optimizer_switch='semijoin=off'; @@ -98,8 +91,39 @@ set optimizer_switch= @tmp_subselect_nulls; drop table x1; drop table x2; -# -# MDEV-7339 Server crashes in Item_func_trig_cond::val_int -# +--echo # +--echo # MDEV-7339 Server crashes in Item_func_trig_cond::val_int +--echo # select (select 1, 2) in (select 3, 4); select (select NULL, NULL) in (select 3, 4); + +--echo # +--echo # End of 5.5 tests +--echo # + +--echo # +--echo # MDEV-32555 wrong result with an index and a partially null-rejecting condition +--echo # + +create table t1 (a int primary key); +insert t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t2 ( + b int not null, + c int default null, + d int not null, + e int not null, + unique key (d,b,c) +); + +insert t2 values (1,null,1,1),(1,null,2,2),(1,null,3,3),(1,null,4,4),(2,null,1,2),(3,null,1,3),(4,null,2,2),(4,null,1,4); + +select ( + select sum(t2_.e) from t2 t2_ where t2_.b = a and t2_.c <=> t2.c and t2_.d = 1 +) x from t2 left join t1 on a = b; + +drop table t1, t2; + +--echo # +--echo # End of 10.10 tests +--echo # diff --git a/mysql-test/main/subselect_sj_mat.result b/mysql-test/main/subselect_sj_mat.result index d6582652729..e8d42228f67 100644 --- a/mysql-test/main/subselect_sj_mat.result +++ b/mysql-test/main/subselect_sj_mat.result @@ -2725,3 +2725,45 @@ i1 i2 1 4 2 6 DROP TABLE t1; +# +# MDEV-31983 jointable materialization subquery optimization ignoring errors, then failing ASSERT. +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +CREATE TABLE t3 (c DATETIME, d INT, KEY(c)); +INSERT INTO t3 VALUES ('2012-11-11',5),('2012-12-12',6); +UPDATE t1, t2 SET t1.a = 26 WHERE t2.b IN (SELECT MIN(d) FROM t3 WHERE c >= '2012-01'); +ERROR 22007: Truncated incorrect datetime value: '2012-01' +DROP TABLE t1, t2, t3; +# +# a followup fix: +# MDEV-32682: Assertion `range->rows >= s->found_records' failed in best_access_path +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b VARCHAR(10), pk INT, PRIMARY KEY (pk)) ENGINE=MyISAM; +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status Table is already up to date +SELECT STRAIGHT_JOIN t2.* FROM t1 JOIN t2 WHERE t2.b IS NULL AND t2.pk > 1; +b pk +DROP TABLE t1, t2; +# +# MDEV-32612 Assertion `tab->select->quick' failed in test_if_skip_sort_order +# +CREATE TABLE t1 (l_orderkey int, l_linenumber int, l_quantity double, +PRIMARY KEY (l_orderkey,l_linenumber), KEY (l_orderkey), +KEY (l_orderkey,l_quantity)) engine=MyISAM; +INSERT INTO t1 VALUES (290,1,35),(290,2,2); +SELECT * FROM t1 +WHERE l_quantity = 31 +AND (l_quantity = 50 OR l_orderkey = 41) +ORDER BY l_orderkey, l_linenumber; +l_orderkey l_linenumber l_quantity +DROP TABLE t1; +# end of 10.6 tests diff --git a/mysql-test/main/subselect_sj_mat.test b/mysql-test/main/subselect_sj_mat.test index 8bfafdcfbe7..a6262323991 100644 --- a/mysql-test/main/subselect_sj_mat.test +++ b/mysql-test/main/subselect_sj_mat.test @@ -2427,3 +2427,48 @@ WHERE alias1.i1 IN ( ); DROP TABLE t1; +--echo # +--echo # MDEV-31983 jointable materialization subquery optimization ignoring errors, then failing ASSERT. +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +CREATE TABLE t3 (c DATETIME, d INT, KEY(c)); +INSERT INTO t3 VALUES ('2012-11-11',5),('2012-12-12',6); + +--error ER_TRUNCATED_WRONG_VALUE +UPDATE t1, t2 SET t1.a = 26 WHERE t2.b IN (SELECT MIN(d) FROM t3 WHERE c >= '2012-01'); + +# Cleanup +DROP TABLE t1, t2, t3; + +--echo # +--echo # a followup fix: +--echo # MDEV-32682: Assertion `range->rows >= s->found_records' failed in best_access_path +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b VARCHAR(10), pk INT, PRIMARY KEY (pk)) ENGINE=MyISAM; + +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +SELECT STRAIGHT_JOIN t2.* FROM t1 JOIN t2 WHERE t2.b IS NULL AND t2.pk > 1; +DROP TABLE t1, t2; + +--echo # +--echo # MDEV-32612 Assertion `tab->select->quick' failed in test_if_skip_sort_order +--echo # + +CREATE TABLE t1 (l_orderkey int, l_linenumber int, l_quantity double, + PRIMARY KEY (l_orderkey,l_linenumber), KEY (l_orderkey), + KEY (l_orderkey,l_quantity)) engine=MyISAM; +INSERT INTO t1 VALUES (290,1,35),(290,2,2); +SELECT * FROM t1 +WHERE l_quantity = 31 +AND (l_quantity = 50 OR l_orderkey = 41) +ORDER BY l_orderkey, l_linenumber; +DROP TABLE t1; + +--echo # end of 10.6 tests diff --git a/mysql-test/main/sum_distinct-big.test b/mysql-test/main/sum_distinct-big.test index f808f79dfb1..8820c191ae9 100644 --- a/mysql-test/main/sum_distinct-big.test +++ b/mysql-test/main/sum_distinct-big.test @@ -82,6 +82,7 @@ SET @@max_heap_table_size=@save_max_heap_table_size; --echo # CREATE TABLE t2 (id INTEGER) ENGINE=InnoDB; +--disable_view_protocol BEGIN; INSERT INTO t2 SELECT b.seq FROM seq_1_to_128 a, seq_1_to_16384 b ORDER BY b.seq*rand(); @@ -106,5 +107,6 @@ SET @@max_heap_table_size=@save_max_heap_table_size; --echo # Back to default tmp_table_size / max_heap_table_size SELECT SQL_NO_CACHE count(DISTINCT id) sm FROM t2; COMMIT; +--enable_view_protocol DROP TABLE t2; diff --git a/mysql-test/main/temp.test b/mysql-test/main/temp.test new file mode 100644 index 00000000000..7e29df49b71 --- /dev/null +++ b/mysql-test/main/temp.test @@ -0,0 +1,7 @@ +CREATE TABLE t1 ( c1 longtext , c2 longtext ); + +INSERT INTO t1 VALUES('[1,2,3]', '[2, 3, 4]'), ('[1,2,3]', '[2, 3, 4]'); + +SELECT JSON_ARRAY_INTERSECT(c1, c2) FROM t1; + +DROP TABLE t1; diff --git a/mysql-test/main/type_bit.result b/mysql-test/main/type_bit.result index d075e883ac2..773ddf6d2c6 100644 --- a/mysql-test/main/type_bit.result +++ b/mysql-test/main/type_bit.result @@ -1859,6 +1859,26 @@ cc 18446744073709551615 cr 18446744073709551615 ct 18446744073709551615 # +# MDEV-32244 Wrong bit encoding using COALESCE +# +CREATE TABLE t1 (c1 BIT); +INSERT INTO t1 (c1) VALUES (0x01); +CREATE TABLE t2 AS SELECT +c1, +COALESCE(c1, c1) AS c2, +COALESCE(c1, null) AS c3, +COALESCE(null, c1) AS c4 FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c1` bit(1) DEFAULT NULL, + `c2` bit(1) DEFAULT NULL, + `c3` bit(1) DEFAULT NULL, + `c4` bit(1) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +DROP TABLE t1; +# # End of 10.4 tests # # diff --git a/mysql-test/main/type_bit.test b/mysql-test/main/type_bit.test index 8bab78adeaf..9b96b15a42f 100644 --- a/mysql-test/main/type_bit.test +++ b/mysql-test/main/type_bit.test @@ -543,6 +543,22 @@ DELIMITER ;$$ --horizontal_results +--echo # +--echo # MDEV-32244 Wrong bit encoding using COALESCE +--echo # + +CREATE TABLE t1 (c1 BIT); +INSERT INTO t1 (c1) VALUES (0x01); +CREATE TABLE t2 AS SELECT + c1, + COALESCE(c1, c1) AS c2, + COALESCE(c1, null) AS c3, + COALESCE(null, c1) AS c4 FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; + + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/type_date.result b/mysql-test/main/type_date.result index b5cd3bf3b61..2dee720e3e4 100644 --- a/mysql-test/main/type_date.result +++ b/mysql-test/main/type_date.result @@ -70,15 +70,15 @@ CREATE TABLE t1(AFIELD INT); INSERT INTO t1 VALUES(1); CREATE TABLE t2(GMT VARCHAR(32)); INSERT INTO t2 VALUES('GMT-0800'); -SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) +SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) as exp FROM t1, t2 GROUP BY t1.AFIELD; -DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) +exp Wed, 06 March 2002 10:11:12 GMT-0800 INSERT INTO t1 VALUES(1); -SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)), -DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) +SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) as e1, +DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) as e2 FROM t1,t2 GROUP BY t1.AFIELD; -DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) +e1 e2 Wed, 06 March 2002 10:11:12 GMT-0800 Wed, 06 March 2002 10:11:12 GMT-0800 drop table t1,t2; CREATE TABLE t1 (f1 time default NULL, f2 time default NULL); @@ -306,8 +306,8 @@ drop table t1; # # MDEV-4634 Crash in CONVERT_TZ # -SELECT CONVERT_TZ(GREATEST(DATE('2021-00-00'),DATE('2022-00-00')),'+00:00','+7:5'); -CONVERT_TZ(GREATEST(DATE('2021-00-00'),DATE('2022-00-00')),'+00:00','+7:5') +SELECT CONVERT_TZ(GREATEST(DATE('2021-00-00'),DATE('2022-00-00')),'+00:00','+7:5') as exp; +exp NULL Warnings: Warning 1292 Incorrect datetime value: '2022-00-00' diff --git a/mysql-test/main/type_date.test b/mysql-test/main/type_date.test index d4981183c10..ade138ca851 100644 --- a/mysql-test/main/type_date.test +++ b/mysql-test/main/type_date.test @@ -74,20 +74,17 @@ drop table t1; # Test problem with DATE_FORMAT # -#enable after fix MDEV-27871 ---disable_view_protocol CREATE TABLE t1(AFIELD INT); INSERT INTO t1 VALUES(1); CREATE TABLE t2(GMT VARCHAR(32)); INSERT INTO t2 VALUES('GMT-0800'); -SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) +SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) as exp FROM t1, t2 GROUP BY t1.AFIELD; INSERT INTO t1 VALUES(1); -SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)), - DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) +SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) as e1, + DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ', t2.GMT)) as e2 FROM t1,t2 GROUP BY t1.AFIELD; drop table t1,t2; ---enable_view_protocol # # Multiple SELECT DATE_FORMAT gave incorrect results (Bug #4036) @@ -287,10 +284,7 @@ drop table t1; --echo # --echo # MDEV-4634 Crash in CONVERT_TZ --echo # -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT CONVERT_TZ(GREATEST(DATE('2021-00-00'),DATE('2022-00-00')),'+00:00','+7:5'); ---enable_view_protocol +SELECT CONVERT_TZ(GREATEST(DATE('2021-00-00'),DATE('2022-00-00')),'+00:00','+7:5') as exp; --echo # --echo # MDEV-4804 Date comparing false result diff --git a/mysql-test/main/type_ranges.result b/mysql-test/main/type_ranges.result index 012d1fc67ce..c6ce8bd4cb9 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/main/type_set.result b/mysql-test/main/type_set.result index bd8a0e95eaa..e727c2cbf2f 100644 --- a/mysql-test/main/type_set.result +++ b/mysql-test/main/type_set.result @@ -390,6 +390,70 @@ a FLOOR(a) CEILING(a) TRUNCATE(a,0) ROUND(a) DROP TABLE t2; DROP TABLE t1; # +# MDEV-32226 UBSAN shift exponent X is too large for 64-bit type 'long long int' in sql/field.cc +# +SET sql_mode=''; +CREATE TABLE t (f SET('1','2','3','4','5','6','7','8','9','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1')); +Warnings: +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +Note 1291 Column 'f' has duplicated value '1' in SET +INSERT INTO t VALUES ('0'); +DROP TABLE t; +# # MDEV-32203 Raise notes when an index cannot be used on data type mismatch # SET note_verbosity=unusable_keys; diff --git a/mysql-test/main/type_set.test b/mysql-test/main/type_set.test index 95732681be4..77712c61654 100644 --- a/mysql-test/main/type_set.test +++ b/mysql-test/main/type_set.test @@ -262,6 +262,15 @@ SELECT * FROM t2; DROP TABLE t2; DROP TABLE t1; +--echo # +--echo # MDEV-32226 UBSAN shift exponent X is too large for 64-bit type 'long long int' in sql/field.cc +--echo # + +SET sql_mode=''; +CREATE TABLE t (f SET('1','2','3','4','5','6','7','8','9','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1')); +INSERT INTO t VALUES ('0'); +DROP TABLE t; + --echo # --echo # MDEV-32203 Raise notes when an index cannot be used on data type mismatch --echo # diff --git a/mysql-test/main/type_time.result b/mysql-test/main/type_time.result index 88a012b76d4..97f45e61743 100644 --- a/mysql-test/main/type_time.result +++ b/mysql-test/main/type_time.result @@ -194,8 +194,8 @@ drop table t1; # MDEV-4634 Crash in CONVERT_TZ # SET timestamp=unix_timestamp('2001-02-03 10:20:30'); -SELECT CONVERT_TZ(GREATEST(TIME('00:00:00'),TIME('00:00:00')),'+00:00','+7:5'); -CONVERT_TZ(GREATEST(TIME('00:00:00'),TIME('00:00:00')),'+00:00','+7:5') +SELECT CONVERT_TZ(GREATEST(TIME('00:00:00'),TIME('00:00:00')),'+00:00','+7:5') as exp; +exp 2001-02-03 07:05:00 SET timestamp=DEFAULT; # @@ -1408,8 +1408,8 @@ SET timestamp=UNIX_TIMESTAMP('2001-01-01 00:00:00'); SELECT TIME'10:20:30' IN (102030,TIME'10:20:31'); TIME'10:20:30' IN (102030,TIME'10:20:31') 1 -SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); -TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') as exp; +exp 1 CREATE TABLE t1 (a TIME); INSERT INTO t1 VALUES ('10:20:30'),('10:20:31'),('10:20:32'); diff --git a/mysql-test/main/type_time.test b/mysql-test/main/type_time.test index 6d33c96a637..ae44427b370 100644 --- a/mysql-test/main/type_time.test +++ b/mysql-test/main/type_time.test @@ -134,12 +134,9 @@ drop table t1; --echo # --echo # MDEV-4634 Crash in CONVERT_TZ --echo # -#enable after fix MDEV-27871 ---disable_view_protocol SET timestamp=unix_timestamp('2001-02-03 10:20:30'); -SELECT CONVERT_TZ(GREATEST(TIME('00:00:00'),TIME('00:00:00')),'+00:00','+7:5'); +SELECT CONVERT_TZ(GREATEST(TIME('00:00:00'),TIME('00:00:00')),'+00:00','+7:5') as exp; SET timestamp=DEFAULT; ---enable_view_protocol --echo # --echo # MDEV-4652 Wrong result for CONCAT(GREATEST(TIME('00:00:01'),TIME('00:00:00'))) @@ -854,10 +851,7 @@ DROP TABLE t1; --echo # SET timestamp=UNIX_TIMESTAMP('2001-01-01 00:00:00'); SELECT TIME'10:20:30' IN (102030,TIME'10:20:31'); -#enable after fix MDEV-27871 ---disable_view_protocol -SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); ---enable_view_protocol +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') as exp; CREATE TABLE t1 (a TIME); INSERT INTO t1 VALUES ('10:20:30'),('10:20:31'),('10:20:32'); SELECT a FROM t1 WHERE a IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') ORDER BY a; diff --git a/mysql-test/main/type_varchar.result b/mysql-test/main/type_varchar.result index bb752719caf..a4b99ad98d5 100644 --- a/mysql-test/main/type_varchar.result +++ b/mysql-test/main/type_varchar.result @@ -950,3 +950,232 @@ Note 1105 Cannot use key parts with `test`.`t1`.`indexed_col` in the rewritten c DROP TABLE t2; DROP TABLE t1; SET note_verbosity=DEFAULT; +# +# MDEV-32957 Unusable key notes report wrong predicates for > and >= +# +SET note_verbosity=unusable_keys; +CREATE TABLE t1 (a INT, i CHAR(32), KEY(i)); +FOR i IN 1..31 +DO +INSERT INTO t1 VALUES (i, 10+i); +END FOR; +$$ +EXPLAIN SELECT * FROM t1 WHERE i>30 ORDER BY i LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index i i 33 NULL 5 Using where +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` > "30" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` > "30" of type `int` +EXPLAIN SELECT * FROM t1 WHERE i>=30 ORDER BY i LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index i i 33 NULL 5 Using where +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "30" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "30" of type `int` +DROP TABLE t1; +SET note_verbosity=DEFAULT; +# +# MDEV-32958 Unusable key notes do not get reported for some operations +# +SET note_verbosity=unusable_keys; +CREATE TABLE t1 (c1 varchar(10), KEY(c1)) CHARACTER SET latin1; +INSERT INTO t1 VALUES ('a'); +INSERT INTO t1 VALUES ('b'); +INSERT INTO t1 VALUES ('c'); +INSERT INTO t1 VALUES ('d'); +INSERT INTO t1 VALUES ('e'); +INSERT INTO t1 VALUES ('f'); +INSERT INTO t1 VALUES ('g'); +INSERT INTO t1 VALUES ('h'); +INSERT INTO t1 VALUES ('i'); +INSERT INTO t1 VALUES ('j'); +EXPLAIN SELECT * FROM t1 WHERE c1=10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c1 c1 13 NULL 10 Using where; Using index +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` = "10" of type `int` +SELECT * FROM t1 WHERE c1=10; +c1 +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` = "10" of type `int` +Warning 1292 Truncated incorrect DECIMAL value: 'a' +Warning 1292 Truncated incorrect DECIMAL value: 'b' +Warning 1292 Truncated incorrect DECIMAL value: 'c' +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1292 Truncated incorrect DECIMAL value: 'g' +Warning 1292 Truncated incorrect DECIMAL value: 'h' +Warning 1292 Truncated incorrect DECIMAL value: 'i' +Warning 1292 Truncated incorrect DECIMAL value: 'j' +EXPLAIN SELECT * FROM t1 WHERE c1<10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c1 c1 13 NULL 10 Using where; Using index +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` < "10" of type `int` +SELECT * FROM t1 WHERE c1<10; +c1 +a +b +c +d +e +f +g +h +i +j +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` < "10" of type `int` +Warning 1292 Truncated incorrect DECIMAL value: 'a' +Warning 1292 Truncated incorrect DECIMAL value: 'b' +Warning 1292 Truncated incorrect DECIMAL value: 'c' +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1292 Truncated incorrect DECIMAL value: 'g' +Warning 1292 Truncated incorrect DECIMAL value: 'h' +Warning 1292 Truncated incorrect DECIMAL value: 'i' +Warning 1292 Truncated incorrect DECIMAL value: 'j' +EXPLAIN SELECT * FROM t1 WHERE c1 BETWEEN 10 AND 11; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c1 c1 13 NULL 10 Using where; Using index +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` >= "10" of type `int` +SELECT * FROM t1 WHERE c1 BETWEEN 10 AND 11; +c1 +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` >= "10" of type `int` +Warning 1292 Truncated incorrect DECIMAL value: 'a' +Warning 1292 Truncated incorrect DECIMAL value: 'b' +Warning 1292 Truncated incorrect DECIMAL value: 'c' +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1292 Truncated incorrect DECIMAL value: 'g' +Warning 1292 Truncated incorrect DECIMAL value: 'h' +Warning 1292 Truncated incorrect DECIMAL value: 'i' +Warning 1292 Truncated incorrect DECIMAL value: 'j' +EXPLAIN SELECT * FROM t1 WHERE c1 BETWEEN 10 AND '11'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c1 c1 13 NULL 10 Using where; Using index +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` >= "10" of type `int` +SELECT * FROM t1 WHERE c1 BETWEEN 10 AND '11'; +c1 +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` >= "10" of type `int` +Warning 1292 Truncated incorrect DOUBLE value: 'a' +Warning 1292 Truncated incorrect DOUBLE value: 'b' +Warning 1292 Truncated incorrect DOUBLE value: 'c' +Warning 1292 Truncated incorrect DOUBLE value: 'd' +Warning 1292 Truncated incorrect DOUBLE value: 'e' +Warning 1292 Truncated incorrect DOUBLE value: 'f' +Warning 1292 Truncated incorrect DOUBLE value: 'g' +Warning 1292 Truncated incorrect DOUBLE value: 'h' +Warning 1292 Truncated incorrect DOUBLE value: 'i' +Warning 1292 Truncated incorrect DOUBLE value: 'j' +EXPLAIN SELECT * FROM t1 WHERE c1 IN (10,20); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c1 c1 13 NULL 10 Using where; Using index +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` = "10" of type `int` +SELECT * FROM t1 WHERE c1 IN (10,20); +c1 +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of type `varchar` = "10" of type `int` +Warning 1292 Truncated incorrect DECIMAL value: 'a' +Warning 1292 Truncated incorrect DECIMAL value: 'b' +Warning 1292 Truncated incorrect DECIMAL value: 'c' +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1292 Truncated incorrect DECIMAL value: 'e' +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1292 Truncated incorrect DECIMAL value: 'g' +Warning 1292 Truncated incorrect DECIMAL value: 'h' +Warning 1292 Truncated incorrect DECIMAL value: 'i' +Warning 1292 Truncated incorrect DECIMAL value: 'j' +EXPLAIN SELECT * FROM t1 WHERE c1 IN (_latin1'a' COLLATE latin1_german2_ci,'b'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c1 c1 13 NULL 10 Using where; Using index +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of collation `latin1_swedish_ci` = "_latin1'a' collate latin1_german2_ci" of collation `latin1_german2_ci` +SELECT * FROM t1 WHERE c1 IN (_latin1'a' COLLATE latin1_german2_ci,'b'); +c1 +a +b +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of collation `latin1_swedish_ci` = "_latin1'a' collate latin1_german2_ci" of collation `latin1_german2_ci` +EXPLAIN SELECT * FROM t1 WHERE c1 IN ('a',_latin1'b' COLLATE latin1_german2_ci); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c1 c1 13 NULL 10 Using where; Using index +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of collation `latin1_swedish_ci` = "'a'" of collation `latin1_german2_ci` +SELECT * FROM t1 WHERE c1 IN ('a',_latin1'b' COLLATE latin1_german2_ci); +c1 +a +b +Warnings: +Note 1105 Cannot use key `c1` part[0] for lookup: `test`.`t1`.`c1` of collation `latin1_swedish_ci` = "'a'" of collation `latin1_german2_ci` +DROP TABLE t1; +CREATE TABLE t1(a INT, i CHAR(2), INDEX(i(1))); +INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), +(20),(21),(22),(23),(24),(25),(26),(27),(28),(29), +(30),(31),(32),(33),(34),(35); +EXPLAIN SELECT * FROM t1 WHERE i >= 10 ORDER BY i LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL i NULL NULL NULL 26 Using where; Using filesort +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +SELECT * FROM t1 WHERE i >= 10 ORDER BY i LIMIT 5; +a i +NULL 10 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` >= "10" of type `int` +EXPLAIN UPDATE t1 SET a = 1 WHERE i = 10 ORDER BY a, i LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where; Using filesort +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` = "10" of type `int` +EXPLAIN UPDATE t1 SET a = 1 WHERE i < 10 ORDER BY a, i LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where; Using filesort +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` < "10" of type `int` +EXPLAIN DELETE FROM t1 WHERE i = 10 ORDER BY a, i LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where; Using filesort +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` = "10" of type `int` +EXPLAIN DELETE FROM t1 WHERE i < 10 ORDER BY a, i LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where; Using filesort +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` < "10" of type `int` +EXPLAIN UPDATE t1 SET a = 1 WHERE i = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` = "10" of type `int` +EXPLAIN UPDATE t1 SET a = 1 WHERE i < 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` < "10" of type `int` +EXPLAIN DELETE FROM t1 WHERE i = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` = "10" of type `int` +EXPLAIN DELETE FROM t1 WHERE i < 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where +Warnings: +Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` < "10" of type `int` +DROP TABLE t1; +SET note_verbosity=DEFAULT; diff --git a/mysql-test/main/type_varchar.test b/mysql-test/main/type_varchar.test index 46b37554575..feb270272c1 100644 --- a/mysql-test/main/type_varchar.test +++ b/mysql-test/main/type_varchar.test @@ -415,3 +415,86 @@ DELIMITER ;$$ --source unusable_keys_joins.inc DROP TABLE t1; SET note_verbosity=DEFAULT; + + +--echo # +--echo # MDEV-32957 Unusable key notes report wrong predicates for > and >= +--echo # + +SET note_verbosity=unusable_keys; +CREATE TABLE t1 (a INT, i CHAR(32), KEY(i)); +DELIMITER $$; +FOR i IN 1..31 +DO + INSERT INTO t1 VALUES (i, 10+i); +END FOR; +$$ +DELIMITER ;$$ +EXPLAIN SELECT * FROM t1 WHERE i>30 ORDER BY i LIMIT 5; +EXPLAIN SELECT * FROM t1 WHERE i>=30 ORDER BY i LIMIT 5; +DROP TABLE t1; +SET note_verbosity=DEFAULT; + + +--echo # +--echo # MDEV-32958 Unusable key notes do not get reported for some operations +--echo # + +SET note_verbosity=unusable_keys; +CREATE TABLE t1 (c1 varchar(10), KEY(c1)) CHARACTER SET latin1; +INSERT INTO t1 VALUES ('a'); +INSERT INTO t1 VALUES ('b'); +INSERT INTO t1 VALUES ('c'); +INSERT INTO t1 VALUES ('d'); +INSERT INTO t1 VALUES ('e'); +INSERT INTO t1 VALUES ('f'); +INSERT INTO t1 VALUES ('g'); +INSERT INTO t1 VALUES ('h'); +INSERT INTO t1 VALUES ('i'); +INSERT INTO t1 VALUES ('j'); + +EXPLAIN SELECT * FROM t1 WHERE c1=10; +SELECT * FROM t1 WHERE c1=10; + +EXPLAIN SELECT * FROM t1 WHERE c1<10; +SELECT * FROM t1 WHERE c1<10; + +EXPLAIN SELECT * FROM t1 WHERE c1 BETWEEN 10 AND 11; +SELECT * FROM t1 WHERE c1 BETWEEN 10 AND 11; + +EXPLAIN SELECT * FROM t1 WHERE c1 BETWEEN 10 AND '11'; +SELECT * FROM t1 WHERE c1 BETWEEN 10 AND '11'; + +EXPLAIN SELECT * FROM t1 WHERE c1 IN (10,20); +SELECT * FROM t1 WHERE c1 IN (10,20); + +EXPLAIN SELECT * FROM t1 WHERE c1 IN (_latin1'a' COLLATE latin1_german2_ci,'b'); +SELECT * FROM t1 WHERE c1 IN (_latin1'a' COLLATE latin1_german2_ci,'b'); + +EXPLAIN SELECT * FROM t1 WHERE c1 IN ('a',_latin1'b' COLLATE latin1_german2_ci); +SELECT * FROM t1 WHERE c1 IN ('a',_latin1'b' COLLATE latin1_german2_ci); + +DROP TABLE t1; + + +CREATE TABLE t1(a INT, i CHAR(2), INDEX(i(1))); +INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), + (20),(21),(22),(23),(24),(25),(26),(27),(28),(29), + (30),(31),(32),(33),(34),(35); + +EXPLAIN SELECT * FROM t1 WHERE i >= 10 ORDER BY i LIMIT 5; +SELECT * FROM t1 WHERE i >= 10 ORDER BY i LIMIT 5; + +EXPLAIN UPDATE t1 SET a = 1 WHERE i = 10 ORDER BY a, i LIMIT 5; +EXPLAIN UPDATE t1 SET a = 1 WHERE i < 10 ORDER BY a, i LIMIT 5; +EXPLAIN DELETE FROM t1 WHERE i = 10 ORDER BY a, i LIMIT 5; +EXPLAIN DELETE FROM t1 WHERE i < 10 ORDER BY a, i LIMIT 5; + +EXPLAIN UPDATE t1 SET a = 1 WHERE i = 10; +EXPLAIN UPDATE t1 SET a = 1 WHERE i < 10; +EXPLAIN DELETE FROM t1 WHERE i = 10; +EXPLAIN DELETE FROM t1 WHERE i < 10; + +DROP TABLE t1; + +SET note_verbosity=DEFAULT; diff --git a/mysql-test/main/type_year.result b/mysql-test/main/type_year.result index 278a8887d6d..ce602c1482b 100644 --- a/mysql-test/main/type_year.result +++ b/mysql-test/main/type_year.result @@ -675,6 +675,26 @@ FLOOR(a) int(4) unsigned YES NULL CEILING(a) int(4) unsigned YES NULL DROP TABLE t2,t1; # +# MDEV-32244 Wrong bit encoding using COALESCE +# +CREATE TABLE t1 (c1 YEAR); +INSERT INTO t1 (c1) VALUES (0x01); +CREATE TABLE t2 AS SELECT +c1, +COALESCE(c1, c1) AS c2, +COALESCE(c1, null) AS c3, +COALESCE(null, c1) AS c4 FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c1` year(4) DEFAULT NULL, + `c2` year(4) DEFAULT NULL, + `c3` year(4) DEFAULT NULL, + `c4` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +DROP TABLE t1; +# # End of 10.4 tests # # diff --git a/mysql-test/main/type_year.test b/mysql-test/main/type_year.test index 2edb67a89eb..98f266587b1 100644 --- a/mysql-test/main/type_year.test +++ b/mysql-test/main/type_year.test @@ -356,6 +356,20 @@ CREATE TABLE t2 AS SELECT a, ROUND(a), TRUNCATE(a,0), FLOOR(a), CEILING(a) FROM DESC t2; DROP TABLE t2,t1; +--echo # +--echo # MDEV-32244 Wrong bit encoding using COALESCE +--echo # + +CREATE TABLE t1 (c1 YEAR); +INSERT INTO t1 (c1) VALUES (0x01); +CREATE TABLE t2 AS SELECT + c1, + COALESCE(c1, c1) AS c2, + COALESCE(c1, null) AS c3, + COALESCE(null, c1) AS c4 FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; --echo # --echo # End of 10.4 tests diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index 01b7b99b3fc..2bc26ca4334 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -4437,12 +4437,14 @@ SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV'; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index Warnings: +Note 1105 Cannot use key `a` part[0] for lookup: `test`.`t1`.`a` of type `varchar` < "0" of type `int` Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 'JJ' or `test`.`t1`.`a` = 'VV' and `test`.`t1`.`a` <> 0 EXPLAIN EXTENDED SELECT * FROM t1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV'; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index Warnings: +Note 1105 Cannot use key `a` part[0] for lookup: `test`.`t1`.`a` of type `varchar` < "0" of type `int` Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 'JJ' or `test`.`t1`.`a` = 'VV' and `test`.`t1`.`a` <> 0 # t1 and v1 should return the same result set SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV'; @@ -4463,12 +4465,14 @@ SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV'; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index Warnings: +Note 1105 Cannot use key `a` part[0] for lookup: `test`.`t1`.`a` of type `varchar` < "0" of type `int` Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 'JJ' or `test`.`t1`.`a` = 'VV' and `test`.`t1`.`a` <> 0 EXPLAIN EXTENDED SELECT * FROM t1 WHERE a > 'JJ' OR a AND a = 'VV'; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index Warnings: +Note 1105 Cannot use key `a` part[0] for lookup: `test`.`t1`.`a` of type `varchar` < "0" of type `int` Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 'JJ' or `test`.`t1`.`a` = 'VV' and `test`.`t1`.`a` <> 0 DROP VIEW v1; DROP TABLE t1; diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 3363e77ea6e..93652834a80 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -4535,5 +4535,18 @@ NULL DROP FUNCTION f; DROP TABLE t; # +# MDEV-31296: Crash in Item_func::fix_fields when prepared statement +# with subqueries and window function is executed with +# sql_mode = ONLY_FULL_GROUP_BY +# +CREATE TABLE t1 ( a INT, i INT) ; +CREATE TABLE t2 ( a INT); +INSERT INTO t2 VALUES (4000); +SET SESSION sql_mode = "ONLY_FULL_GROUP_BY"; +EXECUTE IMMEDIATE "SELECT SUM(i) OVER (ORDER BY i) FROM t1 NATURAL JOIN t2"; +SUM(i) OVER (ORDER BY i) +# Clean up +DROP TABLE t1, t2; +# # End of 10.6 tests # diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index 232565e2c93..51c91eb605d 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -2910,6 +2910,20 @@ EXECUTE IMMEDIATE "SELECT LEAD(c) OVER (ORDER BY c) FROM (SELECT 1 AS c) AS a NA DROP FUNCTION f; DROP TABLE t; +--echo # +--echo # MDEV-31296: Crash in Item_func::fix_fields when prepared statement +--echo # with subqueries and window function is executed with +--echo # sql_mode = ONLY_FULL_GROUP_BY +--echo # +CREATE TABLE t1 ( a INT, i INT) ; +CREATE TABLE t2 ( a INT); +INSERT INTO t2 VALUES (4000); +SET SESSION sql_mode = "ONLY_FULL_GROUP_BY"; +EXECUTE IMMEDIATE "SELECT SUM(i) OVER (ORDER BY i) FROM t1 NATURAL JOIN t2"; + +--echo # Clean up +DROP TABLE t1, t2; + --echo # --echo # End of 10.6 tests --echo # diff --git a/mysql-test/main/win_big-mdev-10092.result b/mysql-test/main/win_big-mdev-10092.result index dc8b7b9c3bd..b65a2cfad7a 100644 --- a/mysql-test/main/win_big-mdev-10092.result +++ b/mysql-test/main/win_big-mdev-10092.result @@ -79,8 +79,8 @@ call add_data(); call add_data(); set sort_buffer_size = 1024; flush status; -select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey ) from orders; -o_custkey Avg(o_custkey) OVER ( ORDER BY o_custkey ) +select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey ) as exp from orders; +o_custkey exp 593 593 593 593 892 742.5 @@ -196,14 +196,14 @@ o_custkey Avg(o_custkey) OVER ( ORDER BY o_custkey ) 14935 7440.456140350877 14935 7440.456140350877 select variable_name, -case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end as exp from information_schema.session_status where variable_name like 'Sort_merge_passes'; -variable_name case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +variable_name exp SORT_MERGE_PASSES WITH PASSES flush status; -select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey RANGE CURRENT ROW ) from orders; -o_custkey Avg(o_custkey) OVER ( ORDER BY o_custkey RANGE CURRENT ROW ) +select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey RANGE CURRENT ROW ) as exp from orders; +o_custkey exp 593 593 593 593 892 892 @@ -319,10 +319,10 @@ o_custkey Avg(o_custkey) OVER ( ORDER BY o_custkey RANGE CURRENT ROW ) 14935 14935 14935 14935 select variable_name, -case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end as exp from information_schema.session_status where variable_name like 'Sort_merge_passes'; -variable_name case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +variable_name exp SORT_MERGE_PASSES WITH PASSES drop table orders; drop procedure add_data; diff --git a/mysql-test/main/win_big-mdev-10092.test b/mysql-test/main/win_big-mdev-10092.test index c4bda66018b..036e24b77a6 100644 --- a/mysql-test/main/win_big-mdev-10092.test +++ b/mysql-test/main/win_big-mdev-10092.test @@ -85,24 +85,19 @@ call add_data(); call add_data(); set sort_buffer_size = 1024; -#enable after fix MDEV-27871 ---disable_view_protocol - flush status; -select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey ) from orders; +select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey ) as exp from orders; select variable_name, - case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end as exp from information_schema.session_status where variable_name like 'Sort_merge_passes'; flush status; -select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey RANGE CURRENT ROW ) from orders; +select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey RANGE CURRENT ROW ) as exp from orders; select variable_name, - case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end as exp from information_schema.session_status where variable_name like 'Sort_merge_passes'; ---enable_view_protocol - drop table orders; drop procedure add_data; diff --git a/mysql-test/main/win_big-mdev-11697.result b/mysql-test/main/win_big-mdev-11697.result index e8034e67aaf..fc8c0f18801 100644 --- a/mysql-test/main/win_big-mdev-11697.result +++ b/mysql-test/main/win_big-mdev-11697.result @@ -66,10 +66,10 @@ id next_id 9 10 10 11 select variable_name, -case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end as exp from information_schema.session_status where variable_name like 'Sort_merge_passes'; -variable_name case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +variable_name exp SORT_MERGE_PASSES WITH PASSES drop table test_table; set max_recursive_iterations=default; diff --git a/mysql-test/main/win_big-mdev-11697.test b/mysql-test/main/win_big-mdev-11697.test index b3ac2b41e89..ae0b283465d 100644 --- a/mysql-test/main/win_big-mdev-11697.test +++ b/mysql-test/main/win_big-mdev-11697.test @@ -42,16 +42,13 @@ commit; analyze table test_table; explain select * from (select id, lead(id) over(order by id) next_id from test_table order by id) a limit 10; -#enable after fix MDEV-27871 ---disable_view_protocol flush status; select * from (select id, lead(id) over(order by id) next_id from test_table order by id) a limit 10; select variable_name, - case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end as exp from information_schema.session_status where variable_name like 'Sort_merge_passes'; ---enable_view_protocol drop table test_table; set max_recursive_iterations=default; diff --git a/mysql-test/main/win_orderby.result b/mysql-test/main/win_orderby.result index 1a9860c1c76..f38bdd77992 100644 --- a/mysql-test/main/win_orderby.result +++ b/mysql-test/main/win_orderby.result @@ -13,12 +13,12 @@ A.a + B.a* 10 + C.a * 100, from t0 A, t0 B, t0 C; select pk, -count(a) over (order by pk rows between 2 preceding and 2 following) +count(a) over (order by pk rows between 2 preceding and 2 following) as exp from t1 where pk between 1 and 30 order by pk desc limit 4; -pk count(a) over (order by pk rows between 2 preceding and 2 following) +pk exp 30 3 29 4 28 5 @@ -65,21 +65,9 @@ WINDOW w2 AS (ORDER BY id) ) ) ) -) +) as exp FROM t1; -id IN (SELECT id -FROM t1 -WINDOW w AS (ORDER BY (SELECT 1 -FROM t1 -WHERE -EXISTS ( SELECT id -FROM t1 -GROUP BY id -WINDOW w2 AS (ORDER BY id) -) -) -) -) +exp 1 1 1 diff --git a/mysql-test/main/win_orderby.test b/mysql-test/main/win_orderby.test index 65421fc095c..d0bcddfece1 100644 --- a/mysql-test/main/win_orderby.test +++ b/mysql-test/main/win_orderby.test @@ -21,16 +21,13 @@ select 1 from t0 A, t0 B, t0 C; -#enable after fix MDEV-27871 ---disable_view_protocol select pk, - count(a) over (order by pk rows between 2 preceding and 2 following) + count(a) over (order by pk rows between 2 preceding and 2 following) as exp from t1 where pk between 1 and 30 order by pk desc limit 4; ---disable_view_protocol drop table t0,t1; @@ -80,7 +77,7 @@ SELECT ) ) ) - ) + ) as exp FROM t1; DROP TABLE t1; diff --git a/mysql-test/main/win_std.result b/mysql-test/main/win_std.result index 36d99eec425..dac8a2d58eb 100644 --- a/mysql-test/main/win_std.result +++ b/mysql-test/main/win_std.result @@ -27,90 +27,90 @@ std(c) over (order by a) 0 0 # Empty frame. -select std(b) over (order by a rows between 2 following and 1 following) +select std(b) over (order by a rows between 2 following and 1 following) as exp from t2; -std(b) over (order by a rows between 2 following and 1 following) +exp NULL NULL NULL NULL NULL NULL -select std(b) over (order by a range between 2 following and 1 following) +select std(b) over (order by a range between 2 following and 1 following) as exp from t2; -std(b) over (order by a range between 2 following and 1 following) +exp NULL NULL NULL NULL NULL NULL -select std(b) over (order by a rows between 1 preceding and 2 preceding) +select std(b) over (order by a rows between 1 preceding and 2 preceding) as exp from t2; -std(b) over (order by a rows between 1 preceding and 2 preceding) +exp NULL NULL NULL NULL NULL NULL -select std(b) over (order by a range between 1 preceding and 2 preceding) +select std(b) over (order by a range between 1 preceding and 2 preceding) as exp from t2; -std(b) over (order by a range between 1 preceding and 2 preceding) +exp NULL NULL NULL NULL NULL NULL -select std(b) over (order by a rows between 1 following and 0 following) +select std(b) over (order by a rows between 1 following and 0 following) as exp from t2; -std(b) over (order by a rows between 1 following and 0 following) +exp NULL NULL NULL NULL NULL NULL -select std(b) over (order by a range between 1 following and 0 following) +select std(b) over (order by a range between 1 following and 0 following) as exp from t2; -std(b) over (order by a range between 1 following and 0 following) +exp NULL NULL NULL NULL NULL NULL -select std(b) over (order by a rows between 1 following and 0 preceding) +select std(b) over (order by a rows between 1 following and 0 preceding) as exp from t2; -std(b) over (order by a rows between 1 following and 0 preceding) +exp NULL NULL NULL NULL NULL NULL -select std(b) over (order by a range between 1 following and 0 preceding) +select std(b) over (order by a range between 1 following and 0 preceding) as exp from t2; -std(b) over (order by a range between 1 following and 0 preceding) +exp NULL NULL NULL NULL NULL NULL -select std(b) over (order by a rows between 0 following and 1 preceding) +select std(b) over (order by a rows between 0 following and 1 preceding) as exp from t2; -std(b) over (order by a rows between 0 following and 1 preceding) +exp NULL NULL NULL NULL NULL NULL -select std(b) over (order by a range between 0 following and 1 preceding) +select std(b) over (order by a range between 0 following and 1 preceding) as exp from t2; -std(b) over (order by a range between 0 following and 1 preceding) +exp NULL NULL NULL @@ -118,57 +118,56 @@ NULL NULL NULL # 1 row frame. -select std(b) over (order by a rows between current row and current row) +select std(b) over (order by a rows between current row and current row) as exp from t2; -std(b) over (order by a rows between current row and current row) +exp 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 -select std(b) over (order by a rows between 0 preceding and current row) +select std(b) over (order by a rows between 0 preceding and current row) as exp from t2; -std(b) over (order by a rows between 0 preceding and current row) +exp 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 -select std(b) over (order by a rows between 0 preceding and 0 preceding) +select std(b) over (order by a rows between 0 preceding and 0 preceding) as exp from t2; -std(b) over (order by a rows between 0 preceding and 0 preceding) +exp 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 -select std(b) over (order by a rows between 0 preceding and 0 following) +select std(b) over (order by a rows between 0 preceding and 0 following) as exp from t2; -std(b) over (order by a rows between 0 preceding and 0 following) +exp 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 -select std(b) over (order by a rows between 0 following and 0 preceding) -from t2; -std(b) over (order by a rows between 0 following and 0 preceding) +select std(b) over (order by a rows between 0 following and 0 preceding) as exp from t2; +exp 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 -select std(b) over (order by a rows between 0 following and current row) +select std(b) over (order by a rows between 0 following and current row) as exp from t2; ERROR HY000: Unacceptable combination of window frame bound specifications -select std(b) over (order by a rows between current row and 0 following) +select std(b) over (order by a rows between current row and 0 following) as exp from t2; -std(b) over (order by a rows between current row and 0 following) +exp 0.0000 0.0000 0.0000 @@ -176,39 +175,39 @@ std(b) over (order by a rows between current row and 0 following) 0.0000 0.0000 # Only peers frame. -select a, b, std(b) over (order by a range between 0 preceding and 0 preceding) +select a, b, std(b) over (order by a range between 0 preceding and 0 preceding) as exp from t2; -a b std(b) over (order by a range between 0 preceding and 0 preceding) +a b exp 0 1 0.8165 0 2 0.8165 0 3 0.8165 1 1 0.4714 1 1 0.4714 1 2 0.4714 -select a, b, std(b) over (order by a range between 0 preceding and current row) +select a, b, std(b) over (order by a range between 0 preceding and current row) as exp from t2; -a b std(b) over (order by a range between 0 preceding and current row) +a b exp 0 1 0.8165 0 2 0.8165 0 3 0.8165 1 1 0.4714 1 1 0.4714 1 2 0.4714 -select a, b, std(b) over (order by a range between current row and 0 preceding) +select a, b, std(b) over (order by a range between current row and 0 preceding) as exp from t2; ERROR HY000: Unacceptable combination of window frame bound specifications -select a, b, std(b) over (order by a range between current row and 0 following) +select a, b, std(b) over (order by a range between current row and 0 following) as exp from t2; -a b std(b) over (order by a range between current row and 0 following) +a b exp 0 1 0.8165 0 2 0.8165 0 3 0.8165 1 1 0.4714 1 1 0.4714 1 2 0.4714 -select a, b, std(b) over (order by a range between 0 following and 0 following) +select a, b, std(b) over (order by a range between 0 following and 0 following) as exp from t2; -a b std(b) over (order by a range between 0 following and 0 following) +a b exp 0 1 0.8165 0 2 0.8165 0 3 0.8165 @@ -216,36 +215,36 @@ a b std(b) over (order by a range between 0 following and 0 following) 1 1 0.4714 1 2 0.4714 # 2 rows frame. -select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and current row) +select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and current row) as exp from t2; -pk a b std(b) over (order by a, b, pk rows between 1 preceding and current row) +pk a b exp 1 0 1 0.0000 2 0 2 0.5000 3 0 3 0.5000 4 1 1 1.0000 5 1 1 0.0000 6 1 2 0.5000 -select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and 0 preceding) +select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and 0 preceding) as exp from t2; -pk a b std(b) over (order by a, b, pk rows between 1 preceding and 0 preceding) +pk a b exp 1 0 1 0.0000 2 0 2 0.5000 3 0 3 0.5000 4 1 1 1.0000 5 1 1 0.0000 6 1 2 0.5000 -select pk, a, b, std(b) over (order by a, b, pk rows between current row and 1 following) +select pk, a, b, std(b) over (order by a, b, pk rows between current row and 1 following) as exp from t2; -pk a b std(b) over (order by a, b, pk rows between current row and 1 following) +pk a b exp 1 0 1 0.5000 2 0 2 0.5000 3 0 3 1.0000 4 1 1 0.0000 5 1 1 0.5000 6 1 2 0.0000 -select pk, a, b, std(b) over (order by a, b, pk rows between 0 following and 1 following) +select pk, a, b, std(b) over (order by a, b, pk rows between 0 following and 1 following) as exp from t2; -pk a b std(b) over (order by a, b, pk rows between 0 following and 1 following) +pk a b exp 1 0 1 0.5000 2 0 2 0.5000 3 0 3 1.0000 @@ -253,36 +252,36 @@ pk a b std(b) over (order by a, b, pk rows between 0 following and 1 following) 5 1 1 0.5000 6 1 2 0.0000 # 2 peers frame. -select pk, a, b, std(b) over (order by a range between 1 preceding and current row) +select pk, a, b, std(b) over (order by a range between 1 preceding and current row) as exp from t2; -pk a b std(b) over (order by a range between 1 preceding and current row) +pk a b exp 1 0 1 0.8165 2 0 2 0.8165 3 0 3 0.8165 4 1 1 0.7454 5 1 1 0.7454 6 1 2 0.7454 -select pk, a, b, std(b) over (order by a range between 1 preceding and 0 preceding) +select pk, a, b, std(b) over (order by a range between 1 preceding and 0 preceding) as exp from t2; -pk a b std(b) over (order by a range between 1 preceding and 0 preceding) +pk a b exp 1 0 1 0.8165 2 0 2 0.8165 3 0 3 0.8165 4 1 1 0.7454 5 1 1 0.7454 6 1 2 0.7454 -select pk, a, b, std(b) over (order by a range between current row and 1 following) +select pk, a, b, std(b) over (order by a range between current row and 1 following) as exp from t2; -pk a b std(b) over (order by a range between current row and 1 following) +pk a b exp 1 0 1 0.7454 2 0 2 0.7454 3 0 3 0.7454 4 1 1 0.4714 5 1 1 0.4714 6 1 2 0.4714 -select pk, a, b, std(b) over (order by a range between 0 following and 1 following) +select pk, a, b, std(b) over (order by a range between 0 following and 1 following) as exp from t2; -pk a b std(b) over (order by a range between 0 following and 1 following) +pk a b exp 1 0 1 0.7454 2 0 2 0.7454 3 0 3 0.7454 diff --git a/mysql-test/main/win_std.test b/mysql-test/main/win_std.test index e7986e2cf84..c2186747f42 100644 --- a/mysql-test/main/win_std.test +++ b/mysql-test/main/win_std.test @@ -25,120 +25,115 @@ select std(c) over (order by a) from t2; --enable_warnings -#enable after fix MDEV-27871 ---disable_view_protocol - --echo # Empty frame. -select std(b) over (order by a rows between 2 following and 1 following) +select std(b) over (order by a rows between 2 following and 1 following) as exp from t2; -select std(b) over (order by a range between 2 following and 1 following) +select std(b) over (order by a range between 2 following and 1 following) as exp from t2; -select std(b) over (order by a rows between 1 preceding and 2 preceding) +select std(b) over (order by a rows between 1 preceding and 2 preceding) as exp from t2; -select std(b) over (order by a range between 1 preceding and 2 preceding) +select std(b) over (order by a range between 1 preceding and 2 preceding) as exp from t2; -select std(b) over (order by a rows between 1 following and 0 following) +select std(b) over (order by a rows between 1 following and 0 following) as exp from t2; -select std(b) over (order by a range between 1 following and 0 following) +select std(b) over (order by a range between 1 following and 0 following) as exp from t2; -select std(b) over (order by a rows between 1 following and 0 preceding) +select std(b) over (order by a rows between 1 following and 0 preceding) as exp from t2; -select std(b) over (order by a range between 1 following and 0 preceding) +select std(b) over (order by a range between 1 following and 0 preceding) as exp from t2; -select std(b) over (order by a rows between 0 following and 1 preceding) +select std(b) over (order by a rows between 0 following and 1 preceding) as exp from t2; -select std(b) over (order by a range between 0 following and 1 preceding) +select std(b) over (order by a range between 0 following and 1 preceding) as exp from t2; --echo # 1 row frame. -select std(b) over (order by a rows between current row and current row) +select std(b) over (order by a rows between current row and current row) as exp from t2; -select std(b) over (order by a rows between 0 preceding and current row) +select std(b) over (order by a rows between 0 preceding and current row) as exp from t2; -select std(b) over (order by a rows between 0 preceding and 0 preceding) +select std(b) over (order by a rows between 0 preceding and 0 preceding) as exp from t2; -select std(b) over (order by a rows between 0 preceding and 0 following) +select std(b) over (order by a rows between 0 preceding and 0 following) as exp from t2; -select std(b) over (order by a rows between 0 following and 0 preceding) -from t2; +select std(b) over (order by a rows between 0 following and 0 preceding) as exp from t2; --error ER_BAD_COMBINATION_OF_WINDOW_FRAME_BOUND_SPECS -select std(b) over (order by a rows between 0 following and current row) +select std(b) over (order by a rows between 0 following and current row) as exp from t2; -select std(b) over (order by a rows between current row and 0 following) +select std(b) over (order by a rows between current row and 0 following) as exp from t2; --echo # Only peers frame. --sorted_result -select a, b, std(b) over (order by a range between 0 preceding and 0 preceding) +select a, b, std(b) over (order by a range between 0 preceding and 0 preceding) as exp from t2; --sorted_result -select a, b, std(b) over (order by a range between 0 preceding and current row) +select a, b, std(b) over (order by a range between 0 preceding and current row) as exp from t2; --error ER_BAD_COMBINATION_OF_WINDOW_FRAME_BOUND_SPECS -select a, b, std(b) over (order by a range between current row and 0 preceding) +select a, b, std(b) over (order by a range between current row and 0 preceding) as exp from t2; --sorted_result -select a, b, std(b) over (order by a range between current row and 0 following) +select a, b, std(b) over (order by a range between current row and 0 following) as exp from t2; --sorted_result -select a, b, std(b) over (order by a range between 0 following and 0 following) +select a, b, std(b) over (order by a range between 0 following and 0 following) as exp from t2; --echo # 2 rows frame. --sorted_result -select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and current row) +select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and current row) as exp from t2; --sorted_result -select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and 0 preceding) +select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and 0 preceding) as exp from t2; --sorted_result -select pk, a, b, std(b) over (order by a, b, pk rows between current row and 1 following) +select pk, a, b, std(b) over (order by a, b, pk rows between current row and 1 following) as exp from t2; --sorted_result -select pk, a, b, std(b) over (order by a, b, pk rows between 0 following and 1 following) +select pk, a, b, std(b) over (order by a, b, pk rows between 0 following and 1 following) as exp from t2; --echo # 2 peers frame. --sorted_result -select pk, a, b, std(b) over (order by a range between 1 preceding and current row) +select pk, a, b, std(b) over (order by a range between 1 preceding and current row) as exp from t2; --sorted_result -select pk, a, b, std(b) over (order by a range between 1 preceding and 0 preceding) +select pk, a, b, std(b) over (order by a range between 1 preceding and 0 preceding) as exp from t2; --sorted_result -select pk, a, b, std(b) over (order by a range between current row and 1 following) +select pk, a, b, std(b) over (order by a range between current row and 1 following) as exp from t2; --sorted_result -select pk, a, b, std(b) over (order by a range between 0 following and 1 following) +select pk, a, b, std(b) over (order by a range between 0 following and 1 following) as exp from t2; ---enable_view_protocol drop table t1; drop table t2; diff --git a/mysql-test/main/winservice.inc b/mysql-test/main/winservice.inc index d77856f6b5b..2e81c75d039 100644 --- a/mysql-test/main/winservice.inc +++ b/mysql-test/main/winservice.inc @@ -21,7 +21,7 @@ exec $sc_exe delete $service_name; source include/shutdown_mysqld.inc; echo # run mysql_install_db with --service parameter; --disable_result_log -exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --port=$MASTER_MYPORT --password=$password --service=$service_name -R; +exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --port=$MASTER_MYPORT --password=$password --service=$service_name --verbose-bootstrap -R; --enable_result_log echo # Start service; diff --git a/mysql-test/mariadb-test-run.pl b/mysql-test/mariadb-test-run.pl index 17c9496a158..9b5559dfc2a 100755 --- a/mysql-test/mariadb-test-run.pl +++ b/mysql-test/mariadb-test-run.pl @@ -267,6 +267,7 @@ sub using_extern { return (keys %opts_extern > 0);}; our $opt_fast= 0; our $opt_force= 0; +our $opt_skip_not_found= 0; our $opt_mem= $ENV{'MTR_MEM'}; our $opt_clean_vardir= $ENV{'MTR_CLEAN_VARDIR'}; @@ -1085,13 +1086,6 @@ sub run_worker ($) { } -sub ignore_option { - my ($opt, $value)= @_; - mtr_report("Ignoring option '$opt'"); -} - - - # Setup any paths that are $opt_vardir related sub set_vardir { ($opt_vardir)= @_; @@ -1181,6 +1175,7 @@ sub command_line_setup { # Control what test suites or cases to run 'force+' => \$opt_force, + 'skip-not-found' => \$opt_skip_not_found, 'suite|suites=s' => \$opt_suites, 'skip-rpl' => \&collect_option, 'skip-test=s' => \&collect_option, @@ -1189,8 +1184,6 @@ sub command_line_setup { 'big-test+' => \$opt_big_test, 'combination=s' => \@opt_combinations, 'experimental=s' => \@opt_experimentals, - # skip-im is deprecated and silently ignored - 'skip-im' => \&ignore_option, 'staging-run' => \$opt_staging_run, # Specify ports @@ -5892,6 +5885,8 @@ Options to control what test suites or cases to run the execution will continue from the next test file. When specified twice, execution will continue executing the failed test file from the next command. + skip-not-found It is not an error if a test was not found in a + specified test suite. Test will be marked as skipped. do-test=PREFIX or REGEX Run test cases which name are prefixed with PREFIX or fulfills REGEX diff --git a/mysql-test/std_data/mysql80/t2.cfg b/mysql-test/std_data/mysql80/t2.cfg new file mode 100644 index 00000000000..81f92978393 Binary files /dev/null and b/mysql-test/std_data/mysql80/t2.cfg differ diff --git a/mysql-test/std_data/mysql80/t2.ibd b/mysql-test/std_data/mysql80/t2.ibd new file mode 100644 index 00000000000..be2b46a7af1 Binary files /dev/null and b/mysql-test/std_data/mysql80/t2.ibd differ 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 d697788047f..87152e8242d 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result @@ -1,4 +1,5 @@ RESET MASTER; +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 d093a644397..e32d1e0eaba 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; RESET MASTER; 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 35b44be02cf..903704ac93d 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 @@ -68,7 +68,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 include/reset_slave.inc Warnings: Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos' 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 e05994f1943..97d81d2aed1 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 @@ -143,7 +143,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 --let $master_use_gtid_option= No --source include/reset_slave.inc 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_gtid_basic.result b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result index 0246a9e2900..e1186d65ec2 100644 --- a/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result +++ b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result @@ -188,6 +188,13 @@ BINLOG_GTID_POS('master-bin.000001',18446744073709551616) NULL Warnings: Warning 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated +SET sql_log_bin= 0; +CREATE TABLE t1 AS SELECT MASTER_POS_WAIT(@binlog_file, 4, 0); +SELECT BINLOG_GTID_POS(@binlog_file, 4); +BINLOG_GTID_POS(@binlog_file, 4) +NULL +DROP TABLE t1; +SET sql_log_bin= 1; *** Some tests of @@GLOBAL.gtid_binlog_state *** connection server_2; include/sync_with_master_gtid.inc 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 e94e097f41f..dbaceb65906 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 @@ -197,7 +197,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 b49bad93627..afbba204e1b 100644 --- a/mysql-test/suite/compat/oracle/r/func_decode.result +++ b/mysql-test/suite/compat/oracle/r/func_decode.result @@ -1,8 +1,8 @@ SET sql_mode=ORACLE; SELECT DECODE(10); -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 ')' at line 1 +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' SELECT DECODE(10,10); -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 ')' at line 1 +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' SELECT DECODE(10,10,'x10'); DECODE(10,10,'x10') x10 @@ -28,16 +28,16 @@ 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; # # MDEV-13863 sql_mode=ORACLE: DECODE does not treat two NULLs as equivalent # SELECT DECODE(10); -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 ')' at line 1 +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' SELECT DECODE(10,10); -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 ')' at line 1 +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' SELECT DECODE_ORACLE(10); ERROR 42000: Incorrect parameter count in the call to native function 'DECODE_ORACLE' SELECT DECODE_ORACLE(10,10); @@ -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_decode.test b/mysql-test/suite/compat/oracle/t/func_decode.test index 1d49cdd2102..b8be7178570 100644 --- a/mysql-test/suite/compat/oracle/t/func_decode.test +++ b/mysql-test/suite/compat/oracle/t/func_decode.test @@ -1,8 +1,8 @@ SET sql_mode=ORACLE; ---error ER_PARSE_ERROR +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT SELECT DECODE(10); ---error ER_PARSE_ERROR +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT SELECT DECODE(10,10); SELECT DECODE(10,10,'x10'); @@ -25,9 +25,9 @@ DROP TABLE decode; --echo # MDEV-13863 sql_mode=ORACLE: DECODE does not treat two NULLs as equivalent --echo # ---error ER_PARSE_ERROR +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT SELECT DECODE(10); ---error ER_PARSE_ERROR +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT SELECT DECODE(10,10); --error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT 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/encryption/r/innodb_encrypt_temporary_tables.result b/mysql-test/suite/encryption/r/innodb_encrypt_temporary_tables.result index 541680ae862..d86ca6f9c00 100644 --- a/mysql-test/suite/encryption/r/innodb_encrypt_temporary_tables.result +++ b/mysql-test/suite/encryption/r/innodb_encrypt_temporary_tables.result @@ -1,6 +1,8 @@ -SELECT variable_value into @old_encrypted FROM information_schema.global_status +SELECT CAST(variable_value AS INT) INTO @old_encrypted +FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_temp_blocks_encrypted'; -SELECT variable_value into @old_decrypted FROM information_schema.global_status +SELECT CAST(variable_value AS INT) INTO @old_decrypted +FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_temp_blocks_decrypted'; CREATE TEMPORARY TABLE t1(f1 CHAR(200), f2 CHAR(200)) ENGINE=InnoDB; INSERT INTO t1 (f1,f2) SELECT '', '' FROM seq_1_to_8192; @@ -12,11 +14,13 @@ COUNT(*) SELECT COUNT(*) FROM t2; COUNT(*) 8192 -SELECT variable_value > @old_encrypted FROM information_schema.global_status +SELECT CAST(variable_value AS INT) > @old_encrypted +FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_temp_blocks_encrypted'; -variable_value > @old_encrypted +CAST(variable_value AS INT) > @old_encrypted 1 -SELECT variable_value > @old_decrypted FROM information_schema.global_status +SELECT CAST(variable_value AS INT) > @old_decrypted +FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_temp_blocks_decrypted'; -variable_value > @old_decrypted +CAST(variable_value AS INT) > @old_decrypted 1 diff --git a/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result b/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result index 7ee30423fe7..18082027660 100644 --- a/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result +++ b/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result @@ -13,11 +13,13 @@ set current_num = current_num + 1; end while; end// commit; -set autocommit=0; -call innodb_insert_proc(10000); +begin; +set statement unique_checks=0, foreign_key_checks=0 for +call innodb_insert_proc(100); commit; -set autocommit=1; +DROP PROCEDURE innodb_insert_proc; # Wait max 10 min for key encryption threads to encrypt all spaces +FLUSH TABLES t1, t2, t3 FOR EXPORT; # tablespaces should be now encrypted # t1 yes on expecting NOT FOUND NOT FOUND /foobar/ in t1.ibd @@ -25,15 +27,16 @@ NOT FOUND /foobar/ in t1.ibd NOT FOUND /temp/ in t2.ibd # t3 ... on expecting NOT FOUND NOT FOUND /barfoo/ in t3.ibd -# restart db.opt +t1.cfg t1.frm t1.ibd +t2.cfg t2.frm t2.ibd +t3.cfg t3.frm t3.ibd -FLUSH TABLES t1, t2, t3 FOR EXPORT; backup: t1 backup: t2 backup: t3 @@ -55,17 +58,18 @@ restore: t1 .ibd and .cfg files restore: t2 .ibd and .cfg files restore: t3 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -SELECT COUNT(1) FROM t1; -COUNT(1) -10000 +SELECT COUNT(*) FROM t1; +COUNT(*) +100 ALTER TABLE t2 IMPORT TABLESPACE; -SELECT COUNT(1) FROM t2; -COUNT(1) -10000 +SELECT COUNT(*) FROM t2; +COUNT(*) +100 ALTER TABLE t3 IMPORT TABLESPACE; -SELECT COUNT(1) FROM t3; -COUNT(1) -10000 +SELECT COUNT(*) FROM t3; +COUNT(*) +100 +FLUSH TABLES t1, t2, t3 FOR EXPORT; # tablespaces should remain encrypted after import # t1 yes on expecting NOT FOUND NOT FOUND /foobar/ in t1.ibd @@ -73,8 +77,8 @@ NOT FOUND /foobar/ in t1.ibd NOT FOUND /temp/ in t2.ibd # t3 ... on expecting NOT FOUND NOT FOUND /barfoo/ in t3.ibd -# restart -ALTER TABLE t1 ENGINE InnoDB; +UNLOCK TABLES; +ALTER TABLE t1 FORCE; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -82,7 +86,7 @@ t1 CREATE TABLE `t1` ( `a` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes -ALTER TABLE t2 ENGINE InnoDB; +ALTER TABLE t2 FORCE; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( @@ -90,7 +94,7 @@ t2 CREATE TABLE `t2` ( `a` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci -ALTER TABLE t3 ENGINE InnoDB; +ALTER TABLE t3 FORCE; SHOW CREATE TABLE t3; Table Create Table t3 CREATE TABLE `t3` ( @@ -98,30 +102,17 @@ t3 CREATE TABLE `t3` ( `a` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED `encrypted`=yes -# Restarting server -# restart -# Done restarting server # Verify that tables are still usable -SELECT COUNT(1) FROM t1; -COUNT(1) -10000 -SELECT COUNT(1) FROM t2; -COUNT(1) -10000 -SELECT COUNT(1) FROM t3; -COUNT(1) -10000 -# Tablespaces should be encrypted after restart +CHECK TABLE t1, t2, t3 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t2 check status OK +test.t3 check status OK +FLUSH TABLES t1, t2, t3 FOR EXPORT; # t1 yes on expecting NOT FOUND NOT FOUND /foobar/ in t1.ibd # t2 ... on expecting NOT FOUND NOT FOUND /temp/ in t2.ibd # t3 ... on expecting NOT FOUND -NOT FOUND /barfoo/ in t3.ibd -# restart -# Wait max 10 min for key encryption threads to encrypt all spaces -# Success! -# Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 -# restart: --innodb_encrypt_tables=0 --innodb_encryption_threads=0 -DROP PROCEDURE innodb_insert_proc; +UNLOCK TABLES; DROP TABLE t1, t2, t3; diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index 39d10000717..3560672e509 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -4541,6 +4541,19 @@ NULL DROP FUNCTION f; DROP TABLE t; # +# MDEV-31296: Crash in Item_func::fix_fields when prepared statement +# with subqueries and window function is executed with +# sql_mode = ONLY_FULL_GROUP_BY +# +CREATE TABLE t1 ( a INT, i INT) ; +CREATE TABLE t2 ( a INT); +INSERT INTO t2 VALUES (4000); +SET SESSION sql_mode = "ONLY_FULL_GROUP_BY"; +EXECUTE IMMEDIATE "SELECT SUM(i) OVER (ORDER BY i) FROM t1 NATURAL JOIN t2"; +SUM(i) OVER (ORDER BY i) +# Clean up +DROP TABLE t1, t2; +# # End of 10.6 tests # # diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.opt b/mysql-test/suite/encryption/t/innodb-bad-key-change.opt index d3f298d3335..d14f3bcbe59 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change.opt +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.opt @@ -1,2 +1 @@ ---innodb-purge-rseg-truncate-frequency=1 --skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.opt b/mysql-test/suite/encryption/t/innodb-bad-key-change2.opt index d3f298d3335..d14f3bcbe59 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change2.opt +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.opt @@ -1,2 +1 @@ ---innodb-purge-rseg-truncate-frequency=1 --skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-compressed-blob.opt b/mysql-test/suite/encryption/t/innodb-compressed-blob.opt index 061212b3034..f44dcb1ef80 100644 --- a/mysql-test/suite/encryption/t/innodb-compressed-blob.opt +++ b/mysql-test/suite/encryption/t/innodb-compressed-blob.opt @@ -2,5 +2,4 @@ --innodb-tablespaces-encryption --innodb-encrypt-tables=on --innodb-encryption-threads=4 ---innodb-purge-rseg-truncate-frequency=1 --skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-encryption-disable.opt b/mysql-test/suite/encryption/t/innodb-encryption-disable.opt index d3f298d3335..d14f3bcbe59 100644 --- a/mysql-test/suite/encryption/t/innodb-encryption-disable.opt +++ b/mysql-test/suite/encryption/t/innodb-encryption-disable.opt @@ -1,2 +1 @@ ---innodb-purge-rseg-truncate-frequency=1 --skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-force-corrupt.opt b/mysql-test/suite/encryption/t/innodb-force-corrupt.opt index d3f298d3335..d14f3bcbe59 100644 --- a/mysql-test/suite/encryption/t/innodb-force-corrupt.opt +++ b/mysql-test/suite/encryption/t/innodb-force-corrupt.opt @@ -1,2 +1 @@ ---innodb-purge-rseg-truncate-frequency=1 --skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-missing-key.opt b/mysql-test/suite/encryption/t/innodb-missing-key.opt index 5e144bc2d3c..6a8ee144418 100644 --- a/mysql-test/suite/encryption/t/innodb-missing-key.opt +++ b/mysql-test/suite/encryption/t/innodb-missing-key.opt @@ -2,5 +2,4 @@ --innodb-encryption-rotate-key-age=15 --innodb-encryption-threads=4 --innodb-tablespaces-encryption ---innodb-purge-rseg-truncate-frequency=1 --skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.opt b/mysql-test/suite/encryption/t/innodb-redo-badkey.opt index 60d43648e00..a5182c766ad 100644 --- a/mysql-test/suite/encryption/t/innodb-redo-badkey.opt +++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.opt @@ -2,5 +2,4 @@ --innodb-tablespaces-encryption --innodb-encryption-threads=2 --innodb-default-encryption-key-id=4 ---innodb-purge-rseg-truncate-frequency=1 --skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.test b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.test index d99a55b9b44..83abb783c9e 100644 --- a/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.test +++ b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.test @@ -2,10 +2,12 @@ --source include/have_innodb.inc --source include/have_file_key_management_plugin.inc -SELECT variable_value into @old_encrypted FROM information_schema.global_status +SELECT CAST(variable_value AS INT) INTO @old_encrypted +FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_temp_blocks_encrypted'; -SELECT variable_value into @old_decrypted FROM information_schema.global_status +SELECT CAST(variable_value AS INT) INTO @old_decrypted +FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_temp_blocks_decrypted'; CREATE TEMPORARY TABLE t1(f1 CHAR(200), f2 CHAR(200)) ENGINE=InnoDB; @@ -17,8 +19,10 @@ INSERT INTO t2 (f1,f2,f3) SELECT '', '', '' FROM seq_1_to_8192; SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t2; -SELECT variable_value > @old_encrypted FROM information_schema.global_status +SELECT CAST(variable_value AS INT) > @old_encrypted +FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_temp_blocks_encrypted'; -SELECT variable_value > @old_decrypted FROM information_schema.global_status +SELECT CAST(variable_value AS INT) > @old_decrypted +FROM information_schema.global_status WHERE variable_name = 'innodb_encryption_n_temp_blocks_decrypted'; diff --git a/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test index 22755571618..5f02d966e7e 100644 --- a/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test +++ b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test @@ -6,7 +6,6 @@ let MYSQLD_DATADIR = `SELECT @@datadir`; --let SEARCH_RANGE = 10000000 ---let $id = `SELECT RAND()` --let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd --let t2_IBD = $MYSQLD_DATADIR/test/t2.ibd --let t3_IBD = $MYSQLD_DATADIR/test/t3.ibd @@ -30,19 +29,18 @@ end// delimiter ;// commit; -set autocommit=0; -call innodb_insert_proc(10000); +begin; +set statement unique_checks=0, foreign_key_checks=0 for +call innodb_insert_proc(100); commit; -set autocommit=1; +DROP PROCEDURE innodb_insert_proc; --echo # Wait max 10 min for key encryption threads to encrypt all spaces --let $wait_timeout= 600 --let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND ROTATING_OR_FLUSHING <> 0 --source include/wait_condition.inc -# shutdown so that grep is safe ---source include/shutdown_mysqld.inc - +FLUSH TABLES t1, t2, t3 FOR EXPORT; --echo # tablespaces should be now encrypted --let SEARCH_PATTERN=foobar --echo # t1 yes on expecting NOT FOUND @@ -57,11 +55,8 @@ set autocommit=1; -- let SEARCH_FILE=$t3_IBD -- source include/search_pattern_in_file.inc ---source include/start_mysqld.inc let MYSQLD_DATADIR =`SELECT @@datadir`; - --list_files $MYSQLD_DATADIR/test -FLUSH TABLES t1, t2, t3 FOR EXPORT; perl; do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; ib_backup_tablespaces("test", "t1","t2","t3"); @@ -80,14 +75,13 @@ ib_restore_tablespaces("test", "t1","t2","t3"); EOF ALTER TABLE t1 IMPORT TABLESPACE; -SELECT COUNT(1) FROM t1; +SELECT COUNT(*) FROM t1; ALTER TABLE t2 IMPORT TABLESPACE; -SELECT COUNT(1) FROM t2; +SELECT COUNT(*) FROM t2; ALTER TABLE t3 IMPORT TABLESPACE; -SELECT COUNT(1) FROM t3; +SELECT COUNT(*) FROM t3; -# shutdown so that grep is safe ---source include/shutdown_mysqld.inc +FLUSH TABLES t1, t2, t3 FOR EXPORT; --echo # tablespaces should remain encrypted after import --let SEARCH_PATTERN=foobar @@ -103,28 +97,18 @@ SELECT COUNT(1) FROM t3; -- let SEARCH_FILE=$t3_IBD -- source include/search_pattern_in_file.inc ---source include/start_mysqld.inc - -ALTER TABLE t1 ENGINE InnoDB; +UNLOCK TABLES; +ALTER TABLE t1 FORCE; SHOW CREATE TABLE t1; -ALTER TABLE t2 ENGINE InnoDB; +ALTER TABLE t2 FORCE; SHOW CREATE TABLE t2; -ALTER TABLE t3 ENGINE InnoDB; +ALTER TABLE t3 FORCE; SHOW CREATE TABLE t3; ---echo # Restarting server --- source include/restart_mysqld.inc ---echo # Done restarting server - --echo # Verify that tables are still usable -SELECT COUNT(1) FROM t1; -SELECT COUNT(1) FROM t2; -SELECT COUNT(1) FROM t3; +CHECK TABLE t1, t2, t3 EXTENDED; +FLUSH TABLES t1, t2, t3 FOR EXPORT; -# shutdown so that grep is safe ---source include/shutdown_mysqld.inc - ---echo # Tablespaces should be encrypted after restart --let SEARCH_PATTERN=foobar --echo # t1 yes on expecting NOT FOUND -- let SEARCH_FILE=$t1_IBD @@ -136,19 +120,7 @@ SELECT COUNT(1) FROM t3; --echo # t3 ... on expecting NOT FOUND --let SEARCH_PATTERN=barfoo -- let SEARCH_FILE=$t3_IBD --- source include/search_pattern_in_file.inc ---source include/start_mysqld.inc +UNLOCK TABLES; ---echo # Wait max 10 min for key encryption threads to encrypt all spaces ---let $wait_timeout= 600 ---let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND ROTATING_OR_FLUSHING <> 0 ---source include/wait_condition.inc - ---echo # Success! ---echo # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 --- let $restart_parameters=--innodb_encrypt_tables=0 --innodb_encryption_threads=0 --- source include/restart_mysqld.inc - -DROP PROCEDURE innodb_insert_proc; DROP TABLE t1, t2, t3; 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 8ef10bf47b5..b4e3704c62f 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 include/reset_slave.inc 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/events/events_1.result b/mysql-test/suite/events/events_1.result index 24f3aa35b56..2db478ad040 100644 --- a/mysql-test/suite/events/events_1.result +++ b/mysql-test/suite/events/events_1.result @@ -2,10 +2,6 @@ set sql_mode=""; call mtr.add_suppression("Column count of mysql.event is wrong. Expected .*, found .*\. The table is probably corrupted"); call mtr.add_suppression("Incorrect definition of table mysql.event:.*"); call mtr.add_suppression("Event Scheduler: .* DROP command denied to user"); -drop database if exists events_test; -drop database if exists db_x; -drop database if exists mysqltest_db2; -drop database if exists mysqltest_no_such_database; create database events_test; use events_test; CREATE USER pauline@localhost; diff --git a/mysql-test/suite/events/events_1.test b/mysql-test/suite/events/events_1.test index 63b0c50909f..cace9eb349d 100644 --- a/mysql-test/suite/events/events_1.test +++ b/mysql-test/suite/events/events_1.test @@ -11,12 +11,6 @@ call mtr.add_suppression("Column count of mysql.event is wrong. Expected .*, fou call mtr.add_suppression("Incorrect definition of table mysql.event:.*"); call mtr.add_suppression("Event Scheduler: .* DROP command denied to user"); ---disable_warnings -drop database if exists events_test; -drop database if exists db_x; -drop database if exists mysqltest_db2; -drop database if exists mysqltest_no_such_database; ---enable_warnings create database events_test; use events_test; @@ -44,6 +38,8 @@ DROP EVENT e_x1; DROP EVENT e_x2; disconnect priv_conn; connection default; +let $wait_condition= SELECT count(*)=1 from information_schema.processlist; +--source include/wait_condition.inc DROP DATABASE db_x; DROP USER pauline@localhost; USE events_test; @@ -103,6 +99,8 @@ delimiter ;| set global event_scheduler = on; let $wait_condition= SELECT count(*)>0 from mysql.event where name='e_43' and interval_value= 5; --source include/wait_condition.inc +let $wait_condition= SELECT count(*)=2 from information_schema.processlist; +--source include/wait_condition.inc select db, name, body, status, interval_field, interval_value from mysql.event; drop event e_43; drop table test_nested; diff --git a/mysql-test/suite/events/events_stress.test b/mysql-test/suite/events/events_stress.test index 080707f029f..92b084a35b4 100644 --- a/mysql-test/suite/events/events_stress.test +++ b/mysql-test/suite/events/events_stress.test @@ -45,10 +45,12 @@ CREATE EVENT ev_drop1 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1; CREATE EVENT ev_drop2 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1; CREATE EVENT ev_drop3 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1; USE events_test; +--disable_service_connection SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS; SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2'; DROP DATABASE events_conn1_test2; SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2'; +--enable_service_connection --echo "Now testing stability - dropping db -> events while they are running" CREATE DATABASE events_conn1_test2; diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result index eaf9bda6f38..231862f76ad 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.result +++ b/mysql-test/suite/federated/federatedx_create_handlers.result @@ -1140,6 +1140,111 @@ t3_myisam2 t3_myisam3 SELECT * FROM federated.t1 UNION SELECT * FROM t3 ORDER BY 2; ERROR 42S22: Unknown column '2' in 'order clause' +# +# MDEV-32382 FederatedX error on pushdown of statement having CTE +# +# Single SELECT with CTE +WITH cte AS (SELECT * FROM federated.t1) +SELECT * FROM cte; +a +bcd +abc +cde +explain extended WITH cte AS (SELECT * FROM federated.t1) +SELECT * FROM cte; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 with cte as (/* select#2 */ select `federated`.`t1`.`a` AS `a` from `federated`.`t1`)/* select#1 */ select `cte`.`a` AS `a` from `cte` +# Pushdown of a UNION having CTE's +WITH cte AS (SELECT * FROM federated.t1), +cte2 AS (SELECT * FROM federated.t2) +SELECT * FROM cte +UNION +SELECT * FROM cte2; +a +abc +bcd +cde +def +efg +explain extended WITH cte AS (SELECT * FROM federated.t1), +cte2 AS (SELECT * FROM federated.t2) +SELECT * FROM cte +UNION +SELECT * FROM cte2; +id select_type table type possible_keys key key_len ref rows filtered Extra +NULL PUSHED UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 with cte as (/* select#2 */ select `federated`.`t1`.`a` AS `a` from `federated`.`t1`), cte2 as (/* select#3 */ select `federated`.`t2`.`a` AS `a` from `federated`.`t2`)/* select#1 */ select `cte`.`a` AS `a` from `cte` union /* select#4 */ select `cte2`.`a` AS `a` from `cte2` +# Partial pushdown is not allowed for unions with CTE's, however a CTE +# may be pushed down a derived table +WITH cte AS (SELECT * FROM federated.t1) +SELECT * FROM cte +UNION ALL +SELECT * FROM t3; +a +abc +bcd +cde +t3_myisam1 +t3_myisam2 +t3_myisam3 +explain extended WITH cte AS (SELECT * FROM federated.t1) +SELECT * FROM cte +UNION ALL +SELECT * FROM t3; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 3 100.00 +2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL NULL +3 UNION t3 ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1003 with cte as (/* select#2 */ select `federated`.`t1`.`a` AS `a` from `federated`.`t1`)/* select#1 */ select `cte`.`a` AS `a` from `cte` union all /* select#3 */ select `federated`.`t3`.`a` AS `a` from `federated`.`t3` +WITH cte AS (SELECT * FROM federated.t1 UNION SELECT * FROM t3) +SELECT * FROM cte; +a +abc +bcd +cde +t3_myisam1 +t3_myisam2 +t3_myisam3 +explain extended WITH cte AS (SELECT * FROM federated.t1 UNION SELECT * FROM t3) +SELECT * FROM cte; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 6 100.00 +2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 +3 UNION t3 ALL NULL NULL NULL NULL 3 100.00 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 with cte as (/* select#2 */ select `federated`.`t1`.`a` AS `a` from `federated`.`t1` union /* select#3 */ select `federated`.`t3`.`a` AS `a` from `federated`.`t3`)/* select#1 */ select `cte`.`a` AS `a` from `cte` +# Two CTE's where one CTE refers to another +WITH cte AS (SELECT * FROM federated.t1), +cte2 AS (SELECT * FROM t3 +WHERE t3.a NOT IN (SELECT * FROM cte)) +SELECT * FROM cte JOIN cte2; +a a +abc t3_myisam1 +abc t3_myisam2 +abc t3_myisam3 +bcd t3_myisam1 +bcd t3_myisam2 +bcd t3_myisam3 +cde t3_myisam1 +cde t3_myisam2 +cde t3_myisam3 +explain extended WITH cte AS (SELECT * FROM federated.t1), +cte2 AS (SELECT * FROM t3 +WHERE t3.a NOT IN (SELECT * FROM cte)) +SELECT * FROM cte JOIN cte2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 3 100.00 +1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +5 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL NULL +4 MATERIALIZED ALL NULL NULL NULL NULL 3 100.00 +2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 with cte as (/* select#2 */ select `federated`.`t1`.`a` AS `a` from `federated`.`t1`), cte2 as (/* select#3 */ select `federated`.`t3`.`a` AS `a` from `federated`.`t3` where !<`federated`.`t3`.`a`>((`federated`.`t3`.`a`,`federated`.`t3`.`a` in ( (/* select#4 */ select `cte`.`a` from `cte` ), (`federated`.`t3`.`a` in on distinct_key where `federated`.`t3`.`a` = ``.`a`)))))/* select#1 */ select `cte`.`a` AS `a`,`federated`.`t3`.`a` AS `a` from `cte` join `federated`.`t3` where !<`federated`.`t3`.`a`>((`federated`.`t3`.`a`,`federated`.`t3`.`a` in ( (/* select#4 */ select `cte`.`a` from `cte` ), (`federated`.`t3`.`a` in on distinct_key where `federated`.`t3`.`a` = ``.`a`)))) connection master; DROP TABLES federated.t1, federated.t2, t3, t4, t5, t6, federated.t11, federated.t12, federated.t13, federated.t14; diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test index f0cf3662023..e65972635e0 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.test +++ b/mysql-test/suite/federated/federatedx_create_handlers.test @@ -740,6 +740,55 @@ SELECT * FROM federated.t1 UNION SELECT * FROM t3 ORDER BY a; SELECT * FROM federated.t1 UNION SELECT * FROM t3 ORDER BY 2; +--echo # +--echo # MDEV-32382 FederatedX error on pushdown of statement having CTE +--echo # + +--echo # Single SELECT with CTE +let $query= WITH cte AS (SELECT * FROM federated.t1) + SELECT * FROM cte; +eval $query; +eval explain extended $query; + +--echo # Pushdown of a UNION having CTE's +let $query= WITH cte AS (SELECT * FROM federated.t1), + cte2 AS (SELECT * FROM federated.t2) + SELECT * FROM cte + UNION + SELECT * FROM cte2; +--sorted_result +eval $query; +eval explain extended $query; + +# CREATE TABLE t3 (a int); +# INSERT INTO t3 VALUES (101),(102),(103); + +--echo # Partial pushdown is not allowed for unions with CTE's, however a CTE +--echo # may be pushed down a derived table +let $query= WITH cte AS (SELECT * FROM federated.t1) + SELECT * FROM cte + UNION ALL + SELECT * FROM t3; +--sorted_result +eval $query; +eval explain extended $query; + +let $query= WITH cte AS (SELECT * FROM federated.t1 UNION SELECT * FROM t3) + SELECT * FROM cte; +--sorted_result +eval $query; +eval explain extended $query; + +--echo # Two CTE's where one CTE refers to another +let $query= WITH cte AS (SELECT * FROM federated.t1), + cte2 AS (SELECT * FROM t3 + WHERE t3.a NOT IN (SELECT * FROM cte)) + SELECT * FROM cte JOIN cte2; +--sorted_result +eval $query; +eval explain extended $query; + + # Cleanup connection master; DROP TABLES federated.t1, federated.t2, t3, t4, t5, t6, federated.t11, 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 abe8f7c4e14..72de6653414 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -178,9 +178,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 @@ -305,7 +305,7 @@ def information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME 3 NULL NO varchar def information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA 2 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS DELETE_RULE 9 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS MATCH_OPTION 7 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL -def information_schema REFERENTIAL_CONSTRAINTS REFERENCED_TABLE_NAME 11 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL +def information_schema REFERENTIAL_CONSTRAINTS REFERENCED_TABLE_NAME 11 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS TABLE_NAME 10 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_CATALOG 4 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_NAME 6 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL @@ -354,9 +354,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 @@ -743,9 +743,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) @@ -919,9 +919,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 14599609e3a..5e59e1fe6e4 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 @@ -178,9 +178,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 @@ -305,7 +305,7 @@ def information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME 3 NULL NO varchar def information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA 2 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS DELETE_RULE 9 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS MATCH_OPTION 7 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL -def information_schema REFERENTIAL_CONSTRAINTS REFERENCED_TABLE_NAME 11 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL +def information_schema REFERENTIAL_CONSTRAINTS REFERENCED_TABLE_NAME 11 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS TABLE_NAME 10 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_CATALOG 4 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) NEVER NULL def information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_NAME 6 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL @@ -354,9 +354,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 @@ -743,9 +743,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) @@ -919,9 +919,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_statistics.result b/mysql-test/suite/funcs_1/r/is_statistics.result index b08f7202a3b..809c287d8d6 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics.result +++ b/mysql-test/suite/funcs_1/r/is_statistics.result @@ -263,8 +263,6 @@ ORDER BY table_schema,table_name,index_name,seq_in_index,column_name; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT IGNORED def db_datadict t1 1 db_datadict f2_ind 1 f2 NULL 0 NULL NULL YES HASH NO def db_datadict t1 0 db_datadict PRIMARY 1 f1 NULL 0 NULL NULL HASH NO -def db_datadict_2 t3 1 db_datadict_2 f2f1_ind 1 f2 NULL NULL NULL NULL YES HASH NO -def db_datadict_2 t3 1 db_datadict_2 f2f1_ind 2 f1 NULL 0 NULL NULL HASH NO def db_datadict_2 t3 0 db_datadict_2 f5 1 f5 NULL 0 NULL NULL YES HASH NO def db_datadict_2 t3 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH NO SHOW GRANTS FOR 'testuser1'@'localhost'; @@ -298,8 +296,6 @@ SELECT * FROM information_schema.statistics WHERE table_schema LIKE 'db_datadict%' ORDER BY table_schema,table_name,index_name,seq_in_index,column_name; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT IGNORED -def db_datadict_2 t3 1 db_datadict_2 f2f1_ind 1 f2 NULL NULL NULL NULL YES HASH NO -def db_datadict_2 t3 1 db_datadict_2 f2f1_ind 2 f1 NULL 0 NULL NULL HASH NO def db_datadict_2 t3 0 db_datadict_2 f5 1 f5 NULL 0 NULL NULL YES HASH NO def db_datadict_2 t3 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH NO SHOW GRANTS FOR 'testuser1'@'localhost'; diff --git a/mysql-test/suite/funcs_1/r/is_table_constraints.result b/mysql-test/suite/funcs_1/r/is_table_constraints.result index ce052821ec8..85e09cef9cd 100644 --- a/mysql-test/suite/funcs_1/r/is_table_constraints.result +++ b/mysql-test/suite/funcs_1/r/is_table_constraints.result @@ -95,7 +95,6 @@ def sys PRIMARY sys sys_config ######################################################################################### # Testcase 3.2.7.2 + 3.2.7.3: INFORMATION_SCHEMA.TABLE_CONSTRAINTS accessible information ######################################################################################### -DROP DATABASE IF EXISTS db_datadict; CREATE DATABASE db_datadict; CREATE TABLE db_datadict.t1 (f1 BIGINT, f2 BIGINT, f3 BIGINT, f4 BIGINT, f5 BIGINT, f6 BIGINT, PRIMARY KEY (f1,f2)) @@ -105,13 +104,12 @@ CREATE UNIQUE INDEX my_idx2 ON db_datadict.t1(f3); CREATE TABLE db_datadict.t2 (f1 BIGINT, f2 BIGINT, f3 BIGINT, f4 BIGINT, f5 BIGINT, f6 BIGINT, PRIMARY KEY (f1,f2)) ENGINE = ; -DROP USER 'testuser1'@'localhost'; CREATE USER 'testuser1'@'localhost'; -GRANT SELECT(f5) ON db_datadict.t1 TO 'testuser1'@'localhost'; +GRANT SELECT(f5), UPDATE(f6) ON db_datadict.t1 TO 'testuser1'@'localhost'; SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` -GRANT SELECT (`f5`) ON `db_datadict`.`t1` TO `testuser1`@`localhost` +GRANT SELECT (`f5`), UPDATE (`f6`) ON `db_datadict`.`t1` TO `testuser1`@`localhost` SELECT * FROM information_schema.table_constraints WHERE table_schema = 'db_datadict' ORDER BY table_schema,table_name, constraint_name; @@ -135,7 +133,7 @@ connect testuser1, localhost, testuser1, , db_datadict; SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` -GRANT SELECT (`f5`) ON `db_datadict`.`t1` TO `testuser1`@`localhost` +GRANT SELECT (`f5`), UPDATE (`f6`) ON `db_datadict`.`t1` TO `testuser1`@`localhost` SELECT * FROM information_schema.table_constraints WHERE table_schema = 'db_datadict' ORDER BY table_schema,table_name, constraint_name; @@ -145,11 +143,6 @@ def db_datadict my_idx2 db_datadict t1 UNIQUE def db_datadict PRIMARY db_datadict t1 PRIMARY KEY SHOW INDEXES FROM db_datadict.t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored -t1 0 PRIMARY 1 f1 ### ### ### ### ### ### ### NO -t1 0 PRIMARY 2 f2 ### ### ### ### ### ### ### NO -t1 0 my_idx1 1 f6 ### ### ### ### ### ### ### NO -t1 0 my_idx1 2 f1 ### ### ### ### ### ### ### NO -t1 0 my_idx2 1 f3 ### ### ### ### ### ### ### NO SHOW INDEXES FROM db_datadict.t2; ERROR 42000: SELECT command denied to user 'testuser1'@'localhost' for table `db_datadict`.`t2` connection default; @@ -159,8 +152,6 @@ DROP DATABASE db_datadict; ######################################################################################### # Testcase 3.2.1.13+3.2.1.14+3.2.1.15: INFORMATION_SCHEMA.TABLE_CONSTRAINTS modifications ######################################################################################### -DROP DATABASE IF EXISTS db_datadict; -DROP TABLE IF EXISTS test.t1_my_table; CREATE DATABASE db_datadict; SELECT table_name FROM information_schema.table_constraints WHERE table_name LIKE 't1_my_table%'; @@ -311,8 +302,6 @@ table_name # Testcases 3.2.1.3-3.2.1.5 + 3.2.1.8-3.2.1.12: INSERT/UPDATE/DELETE and # DDL on INFORMATION_SCHEMA tables are not supported ######################################################################## -DROP DATABASE IF EXISTS db_datadict; -DROP TABLE IF EXISTS db_datadict.t1; CREATE DATABASE db_datadict; CREATE TABLE db_datadict.t1 (f1 BIGINT, UNIQUE(f1)) ENGINE = ; diff --git a/mysql-test/suite/funcs_1/t/is_table_constraints.test b/mysql-test/suite/funcs_1/t/is_table_constraints.test index cf8d3fbf2d2..b4d550fc3b2 100644 --- a/mysql-test/suite/funcs_1/t/is_table_constraints.test +++ b/mysql-test/suite/funcs_1/t/is_table_constraints.test @@ -36,7 +36,6 @@ eval SHOW TABLES FROM information_schema LIKE '$is_table'; # --source suite/funcs_1/datadict/is_table_query.inc - --echo ######################################################################### --echo # Testcase 3.2.10.1: INFORMATION_SCHEMA.TABLE_CONSTRAINTS layout --echo ######################################################################### @@ -85,9 +84,6 @@ ORDER BY constraint_schema, table_name, constraint_name; # mysql is_table_constraints_mysql # information_schema is_table_constraints_is # ---disable_warnings -DROP DATABASE IF EXISTS db_datadict; ---enable_warnings CREATE DATABASE db_datadict; --replace_result $engine_type eval @@ -102,10 +98,8 @@ CREATE TABLE db_datadict.t2 (f1 BIGINT, f2 BIGINT, f3 BIGINT, f4 BIGINT, f5 BIGINT, f6 BIGINT, PRIMARY KEY (f1,f2)) ENGINE = $engine_type; ---error 0,ER_CANNOT_USER -DROP USER 'testuser1'@'localhost'; CREATE USER 'testuser1'@'localhost'; -GRANT SELECT(f5) ON db_datadict.t1 TO 'testuser1'@'localhost'; +GRANT SELECT(f5), UPDATE(f6) ON db_datadict.t1 TO 'testuser1'@'localhost'; SHOW GRANTS FOR 'testuser1'@'localhost'; let $my_select = SELECT * FROM information_schema.table_constraints @@ -161,10 +155,6 @@ DROP DATABASE db_datadict; # automatically deletes all relevant information on that object from # every appropriate INFORMATION_SCHEMA table. # ---disable_warnings -DROP DATABASE IF EXISTS db_datadict; -DROP TABLE IF EXISTS test.t1_my_table; ---enable_warnings CREATE DATABASE db_datadict; SELECT table_name FROM information_schema.table_constraints @@ -281,10 +271,6 @@ WHERE table_name = 't1_my_tablex'; # 3.2.1.12: Ensure that no user may directly add to, alter, or delete any data # in an INFORMATION_SCHEMA table. # ---disable_warnings -DROP DATABASE IF EXISTS db_datadict; -DROP TABLE IF EXISTS db_datadict.t1; ---enable_warnings CREATE DATABASE db_datadict; --replace_result $engine_type eval diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index b6e27070ba6..398584d3e9a 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -14,13 +14,18 @@ galera_as_slave_ctas : MDEV-28378 timeout galera_pc_recovery : MDEV-25199 cluster fails to start up galera_sst_encrypted : MDEV-29876 Galera test failure on galera_sst_encrypted galera_var_node_address : MDEV-20485 Galera test failure -MDEV-26575 : MDEV-29878 Galera test failure on MDEV-26575 -galera_bf_abort_shutdown : MDEV-29918 Assertion failure on galera_bf_abort_shutdown -galera_var_ignore_apply_errors : 28: "Server did not transition to READY state" galera_bf_kill_debug : timeout after 900 seconds galera_ssl_upgrade : [Warning] Failed to load slave replication state from table mysql.gtid_slave_pos: 130: Incorrect file format 'gtid_slave_pos' galera_parallel_simple : timeout related to wsrep_sync_wait galera_insert_bulk : MDEV-30536 no expected deadlock in galera_insert_bulk test -versioning_trx_id : MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch -MDEV-27713 : test is using get_lock(), which is now rejected in cluster -galera_bf_abort_group_commit : MDEV-30855 PR to remove the test exists +galera_sequences : MDEV-32561 WSREP FSM failure: no such a transition REPLICATING -> COMMITTED +galera_shutdown_nonprim : MDEV-32635 galera_shutdown_nonprim: mysql_shutdown failed +versioning_trx_id : MDEV-18590 : galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch +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_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-27806.result b/mysql-test/suite/galera/r/MDEV-27806.result new file mode 100644 index 00000000000..0f7ac79e4cd --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-27806.result @@ -0,0 +1,52 @@ +connection node_2; +connection node_1; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2),(3); +CREATE TABLE ts1 AS SELECT * FROM t1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-bin.000002 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000002 # Query # # use `test`; CREATE TABLE `ts1` ( + `f1` int(11) NOT NULL +) +mysqld-bin.000002 # Annotate_rows # # CREATE TABLE ts1 AS SELECT * FROM t1 +mysqld-bin.000002 # Table_map # # table_id: # (test.ts1) +mysqld-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F +mysqld-bin.000002 # Xid # # COMMIT /* XID */ +connection node_2; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-bin.000003 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000003 # Query # # use `test`; CREATE TABLE `ts1` ( + `f1` int(11) NOT NULL +) +mysqld-bin.000003 # Annotate_rows # # CREATE TABLE ts1 AS SELECT * FROM t1 +mysqld-bin.000003 # Table_map # # table_id: # (test.ts1) +mysqld-bin.000003 # Write_rows_v1 # # table_id: # flags: STMT_END_F +mysqld-bin.000003 # Xid # # COMMIT /* XID */ +BINLOG_POSITIONS_MATCH +1 +DROP TABLE t1,ts1; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +CREATE TABLE ts1 AS SELECT * FROM t1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-bin.000002 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000002 # Query # # use `test`; CREATE TABLE `ts1` ( + `f1` int(11) NOT NULL +) +mysqld-bin.000002 # Xid # # COMMIT /* XID */ +connection node_2; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-bin.000003 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000003 # Query # # use `test`; CREATE TABLE `ts1` ( + `f1` int(11) NOT NULL +) +mysqld-bin.000003 # Query # # COMMIT +BINLOG_POSITIONS_MATCH +1 +DROP TABLE t1,ts1; +CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); 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/create.result b/mysql-test/suite/galera/r/create.result index cd0380b206d..16ae684a1f2 100644 --- a/mysql-test/suite/galera/r/create.result +++ b/mysql-test/suite/galera/r/create.result @@ -18,6 +18,8 @@ USE test; CREATE TABLE t1(i INT) ENGINE=INNODB; INSERT INTO t1 VALUES(1); CREATE TEMPORARY TABLE `t1_temp` AS SELECT * FROM `t1` WHERE i = 1; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = STMT in CREATE TABLE AS SELECT SELECT * FROM t1; i 1 diff --git a/mysql-test/suite/galera/r/galera_as_master.result b/mysql-test/suite/galera/r/galera_as_master.result index 4aca328be56..dd3e017379c 100644 --- a/mysql-test/suite/galera/r/galera_as_master.result +++ b/mysql-test/suite/galera/r/galera_as_master.result @@ -52,6 +52,8 @@ DROP TABLE t1, t4; SET SQL_LOG_BIN=OFF; DROP TABLE t2, t3; connection node_3; +BINLOG_POSITIONS_MATCH +1 STOP SLAVE; RESET SLAVE ALL; CALL mtr.add_suppression('You need to use --log-bin to make --binlog-format work'); diff --git a/mysql-test/suite/galera/r/galera_as_slave_replay.result b/mysql-test/suite/galera/r/galera_as_slave_replay.result index 05bfeed8f01..0425bd2b97a 100644 --- a/mysql-test/suite/galera/r/galera_as_slave_replay.result +++ b/mysql-test/suite/galera/r/galera_as_slave_replay.result @@ -2,6 +2,7 @@ connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; connection node_2a; connection node_2; connection node_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; connection node_3; RESET MASTER; 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_cache_index.result b/mysql-test/suite/galera/r/galera_cache_index.result new file mode 100644 index 00000000000..d8172e6bd0d --- /dev/null +++ b/mysql-test/suite/galera/r/galera_cache_index.result @@ -0,0 +1,49 @@ +connection node_2; +connection node_1; +CREATE TABLE t1 (c1 int, UNIQUE INDEX (c1)) engine=innodb; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +CREATE TABLE t2 (c1 int); +INSERT INTO t2 VALUES (1),(2),(3),(4),(5); +CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2) INSERT_METHOD=LAST; +CACHE INDEX t1,t2 IN default; +Table Op Msg_type Msg_text +test.t1 assign_to_keycache Error Table 't1' is differently defined or of non-MyISAM type or doesn't exist +test.t1 assign_to_keycache error Corrupt +test.t2 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache +LOAD INDEX INTO CACHE t1,t2; +Table Op Msg_type Msg_text +test.t1 preload_keys Error Table 't1' is differently defined or of non-MyISAM type or doesn't exist +test.t1 preload_keys error Corrupt +test.t2 preload_keys note The storage engine for the table doesn't support preload_keys +DROP TEMPORARY TABLE t1; +DROP TABLE t1,t2; +CREATE TABLE t1 (c1 int, UNIQUE INDEX (c1)) engine=MyISAM; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +CREATE TABLE t2 (c1 int, UNIQUE INDEX (c1)) engine=MyISAM; +INSERT INTO t2 VALUES (1),(2),(3),(4),(5); +CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2) INSERT_METHOD=LAST; +CACHE INDEX t1,t2 IN default; +Table Op Msg_type Msg_text +test.t1 assign_to_keycache Error Table 't1' is differently defined or of non-MyISAM type or doesn't exist +test.t1 assign_to_keycache error Corrupt +test.t2 assign_to_keycache status OK +LOAD INDEX INTO CACHE t1,t2; +Table Op Msg_type Msg_text +test.t1 preload_keys Error Table 't1' is differently defined or of non-MyISAM type or doesn't exist +test.t1 preload_keys error Corrupt +test.t2 preload_keys status OK +DROP TEMPORARY TABLE t1; +DROP TABLE t1,t2; +CREATE TABLE t1 (c1 int, UNIQUE INDEX (c1)) engine=MyISAM; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +CREATE TABLE t2 (c1 int, UNIQUE INDEX (c1)) engine=MyISAM; +INSERT INTO t2 VALUES (1),(2),(3),(4),(5); +CACHE INDEX t1,t2 IN default; +Table Op Msg_type Msg_text +test.t1 assign_to_keycache status OK +test.t2 assign_to_keycache status OK +LOAD INDEX INTO CACHE t1,t2; +Table Op Msg_type Msg_text +test.t1 preload_keys status OK +test.t2 preload_keys status OK +DROP TABLE t1,t2; diff --git a/mysql-test/suite/galera/r/galera_concurrent_ctas.result b/mysql-test/suite/galera/r/galera_concurrent_ctas.result index 39c55277c52..933f1d2a98e 100644 --- a/mysql-test/suite/galera/r/galera_concurrent_ctas.result +++ b/mysql-test/suite/galera/r/galera_concurrent_ctas.result @@ -1,5 +1,30 @@ connection node_2; connection node_1; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connection node_1; +SET DEBUG_SYNC = 'wsrep_create_table_as_select WAIT_FOR continue'; +CREATE table t1 as SELECT SLEEP(0.1);; +connection node_1a; +# Wait until CTAS is on debug sync point +connection node_1b; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL debug_dbug = '+d,sync.wsrep_apply_cb'; +connection node_2; +CREATE table t1 as SELECT SLEEP(0.2);; +connection node_1b; +SET SESSION debug_sync = 'now WAIT_FOR sync.wsrep_apply_cb_reached'; +# Signal first CTAS to continue and wait until CTAS has executed +SET DEBUG_SYNC= 'now SIGNAL continue'; +SET GLOBAL debug_dbug= ''; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +connection node_2a; +connection node_1b; +SET DEBUG_SYNC= 'RESET'; +connection node_2; +connection node_1; +DROP TABLE t1; disconnect node_2; disconnect node_1; # End of test diff --git a/mysql-test/suite/galera/r/galera_forced_binlog_format_ctas.result b/mysql-test/suite/galera/r/galera_forced_binlog_format_ctas.result new file mode 100644 index 00000000000..cae5f723c51 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_forced_binlog_format_ctas.result @@ -0,0 +1,273 @@ +connection node_2; +connection node_1; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since.*"); +SET GLOBAL wsrep_forced_binlog_format=ROW; +connection node_1; +CREATE TABLE t1(a int not null primary key auto_increment, b int) ENGINE=InnoDB; +CREATE TABLE t2(a int not null primary key, b int) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL,1),(NULL,2); +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +CREATE TABLE t3 AS SELECT * FROM t1; +CREATE TABLE t4 AS SELECT * FROM t2; +CREATE TABLE t5 (a INT UNIQUE) AS SELECT 1 AS a; +CREATE TABLE t6 (a INT UNIQUE) REPLACE SELECT 1 AS a; +CREATE TABLE t7 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a, +3 AS c; +SELECT COUNT(*) AS EXPECT_32 FROM t1; +EXPECT_32 +32 +SELECT COUNT(*) AS EXPECT_0 FROM t2; +EXPECT_0 +0 +SELECT COUNT(*) AS EXPECT_32 FROM t3; +EXPECT_32 +32 +SELECT * FROM t4; +a b +SELECT * FROM t5; +a +1 +SELECT * FROM t6; +a +1 +SELECT * FROM t7; +a b +1 3 +connection node_2; +# Veryfy CTAS replication +SELECT COUNT(*) AS EXPECT_32 FROM t1; +EXPECT_32 +32 +SELECT COUNT(*) AS EXPECT_0 FROM t2; +EXPECT_0 +0 +SELECT COUNT(*) AS EXPECT_32 FROM t3; +EXPECT_32 +32 +SELECT * FROM t4; +a b +SELECT * FROM t5; +a +1 +SELECT * FROM t6; +a +1 +SELECT * FROM t7; +a b +1 3 +connection node_1; +DROP TABLE t1,t2,t3,t4,t5,t6,t7; +SET GLOBAL wsrep_forced_binlog_format=STATEMENT; +connection node_1; +CREATE TABLE t1(a int not null primary key auto_increment, b int) ENGINE=InnoDB; +CREATE TABLE t2(a int not null primary key, b int) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL,1),(NULL,2); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system variable that may have a different value on the slave +INSERT INTO t1(b) SELECT b+1 from t1; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system variable that may have a different value on the slave +INSERT INTO t1(b) SELECT b+1 from t1; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system variable that may have a different value on the slave +INSERT INTO t1(b) SELECT b+1 from t1; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system variable that may have a different value on the slave +INSERT INTO t1(b) SELECT b+1 from t1; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system variable that may have a different value on the slave +CREATE TABLE t3 AS SELECT * FROM t1; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = STMT in CREATE TABLE AS SELECT +CREATE TABLE t4 AS SELECT * FROM t2; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = STMT in CREATE TABLE AS SELECT +CREATE TABLE t5 (a INT UNIQUE) AS SELECT 1 AS a; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = STMT in CREATE TABLE AS SELECT +CREATE TABLE t6 (a INT UNIQUE) REPLACE SELECT 1 AS a; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = STMT in CREATE TABLE AS SELECT +CREATE TABLE t7 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a, +3 AS c; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = STMT in CREATE TABLE AS SELECT +SELECT COUNT(*) AS EXPECT_32 FROM t1; +EXPECT_32 +32 +SELECT COUNT(*) AS EXPECT_0 FROM t2; +EXPECT_0 +0 +SELECT COUNT(*) AS EXPECT_32 FROM t3; +EXPECT_32 +32 +SELECT * FROM t4; +a b +SELECT * FROM t5; +a +1 +SELECT * FROM t6; +a +1 +SELECT * FROM t7; +a b +1 3 +connection node_2; +# Veryfy CTAS replication +SELECT COUNT(*) AS EXPECT_32 FROM t1; +EXPECT_32 +32 +SELECT COUNT(*) AS EXPECT_0 FROM t2; +EXPECT_0 +0 +SELECT COUNT(*) AS EXPECT_32 FROM t3; +EXPECT_32 +32 +SELECT * FROM t4; +a b +SELECT * FROM t5; +a +1 +SELECT * FROM t6; +a +1 +SELECT * FROM t7; +a b +1 3 +connection node_1; +DROP TABLE t1,t2,t3,t4,t5,t6,t7; +SET GLOBAL wsrep_forced_binlog_format=MIXED; +connection node_1; +CREATE TABLE t1(a int not null primary key auto_increment, b int) ENGINE=InnoDB; +CREATE TABLE t2(a int not null primary key, b int) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL,1),(NULL,2); +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +CREATE TABLE t3 AS SELECT * FROM t1; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = MIXED in CREATE TABLE AS SELECT +CREATE TABLE t4 AS SELECT * FROM t2; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = MIXED in CREATE TABLE AS SELECT +CREATE TABLE t5 (a INT UNIQUE) AS SELECT 1 AS a; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = MIXED in CREATE TABLE AS SELECT +CREATE TABLE t6 (a INT UNIQUE) REPLACE SELECT 1 AS a; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = MIXED in CREATE TABLE AS SELECT +CREATE TABLE t7 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a, +3 AS c; +Warnings: +Warning 1105 Galera does not support wsrep_forced_binlog_format = MIXED in CREATE TABLE AS SELECT +SELECT COUNT(*) AS EXPECT_32 FROM t1; +EXPECT_32 +32 +SELECT COUNT(*) AS EXPECT_0 FROM t2; +EXPECT_0 +0 +SELECT COUNT(*) AS EXPECT_32 FROM t3; +EXPECT_32 +32 +SELECT * FROM t4; +a b +SELECT * FROM t5; +a +1 +SELECT * FROM t6; +a +1 +SELECT * FROM t7; +a b +1 3 +connection node_2; +# Veryfy CTAS replication +SELECT COUNT(*) AS EXPECT_32 FROM t1; +EXPECT_32 +32 +SELECT COUNT(*) AS EXPECT_0 FROM t2; +EXPECT_0 +0 +SELECT COUNT(*) AS EXPECT_32 FROM t3; +EXPECT_32 +32 +SELECT * FROM t4; +a b +SELECT * FROM t5; +a +1 +SELECT * FROM t6; +a +1 +SELECT * FROM t7; +a b +1 3 +connection node_1; +DROP TABLE t1,t2,t3,t4,t5,t6,t7; +SET GLOBAL wsrep_forced_binlog_format=NONE; +connection node_1; +CREATE TABLE t1(a int not null primary key auto_increment, b int) ENGINE=InnoDB; +CREATE TABLE t2(a int not null primary key, b int) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL,1),(NULL,2); +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +CREATE TABLE t3 AS SELECT * FROM t1; +CREATE TABLE t4 AS SELECT * FROM t2; +CREATE TABLE t5 (a INT UNIQUE) AS SELECT 1 AS a; +CREATE TABLE t6 (a INT UNIQUE) REPLACE SELECT 1 AS a; +CREATE TABLE t7 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a, +3 AS c; +SELECT COUNT(*) AS EXPECT_32 FROM t1; +EXPECT_32 +32 +SELECT COUNT(*) AS EXPECT_0 FROM t2; +EXPECT_0 +0 +SELECT COUNT(*) AS EXPECT_32 FROM t3; +EXPECT_32 +32 +SELECT * FROM t4; +a b +SELECT * FROM t5; +a +1 +SELECT * FROM t6; +a +1 +SELECT * FROM t7; +a b +1 3 +connection node_2; +# Veryfy CTAS replication +SELECT COUNT(*) AS EXPECT_32 FROM t1; +EXPECT_32 +32 +SELECT COUNT(*) AS EXPECT_0 FROM t2; +EXPECT_0 +0 +SELECT COUNT(*) AS EXPECT_32 FROM t3; +EXPECT_32 +32 +SELECT * FROM t4; +a b +SELECT * FROM t5; +a +1 +SELECT * FROM t6; +a +1 +SELECT * FROM t7; +a b +1 3 +connection node_1; +DROP TABLE t1,t2,t3,t4,t5,t6,t7; diff --git a/mysql-test/suite/galera/r/galera_ftwrl_concurrent.result b/mysql-test/suite/galera/r/galera_ftwrl_concurrent.result new file mode 100644 index 00000000000..d7b396bf6a5 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_ftwrl_concurrent.result @@ -0,0 +1,122 @@ +connection node_2; +connection node_1; +connect node_1_ctrl, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET SESSION wsrep_sync_wait=0; +# +# Case 1: FTWRL +# +connection node_1; +SET SESSION wsrep_sync_wait=0; +FLUSH TABLES WITH READ LOCK; +SHOW STATUS LIKE 'wsrep_local_state_comment'; +Variable_name Value +wsrep_local_state_comment Donor/Desynced +SET SESSION debug_sync = "wsrep_unlock_global_read_lock_after_resume_and_resync SIGNAL unlock_ready WAIT_FOR unlock_continue"; +UNLOCK TABLES; +connection node_1_ctrl; +SET debug_sync = "now WAIT_FOR unlock_ready"; +connect node_1_a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1_a; +SET SESSION debug_sync = "wsrep_global_read_lock_block_commit_after_pause SIGNAL lock_ready WAIT_FOR lock_continue"; +FLUSH TABLES WITH READ LOCK; +connection node_1_ctrl; +SET debug_sync = "now WAIT_FOR lock_ready"; +SET debug_sync = "now SIGNAL unlock_continue"; +connection node_1; +connection node_1_ctrl; +SET debug_sync = "now SIGNAL lock_continue"; +connection node_1_a; +UNLOCK TABLES; +CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; +DROP TABLE t1; +connection node_1_ctrl; +SET debug_sync = "RESET"; +# +# Case 2: BACKUP STAGE +# +connection node_1; +SET SESSION wsrep_sync_wait=0; +BACKUP STAGE START; +BACKUP STAGE BLOCK_DDL; +SHOW STATUS LIKE 'wsrep_local_state_comment'; +Variable_name Value +wsrep_local_state_comment Donor/Desynced +SET SESSION debug_sync = "wsrep_backup_stage_after_resume_and_resync SIGNAL resume_and_resync_ready WAIT_FOR resume_and_resync_continue"; +BACKUP STAGE END; +connection node_1_ctrl; +SET debug_sync = "now WAIT_FOR resume_and_resync_ready"; +connection node_1_a; +BACKUP STAGE START; +SET SESSION debug_sync = "wsrep_backup_stage_after_desync_and_pause SIGNAL desync_and_pause_ready WAIT_FOR desync_and_pause_continue"; +BACKUP STAGE BLOCK_DDL; +connection node_1_ctrl; +SET debug_sync = "now WAIT_FOR desync_and_pause_ready"; +SET debug_sync = "now SIGNAL resume_and_resync_continue"; +connection node_1; +connection node_1_ctrl; +SET debug_sync = "now SIGNAL desync_and_pause_continue"; +connection node_1_a; +BACKUP STAGE END; +CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; +DROP TABLE t1; +connection node_1_ctrl; +SET debug_sync = "RESET"; +# +# Case 3: FTWRL first, BACKUP STAGE second +# +connection node_1; +SET SESSION wsrep_sync_wait=0; +SET SESSION wsrep_sync_wait=0; +FLUSH TABLES WITH READ LOCK; +SHOW STATUS LIKE 'wsrep_local_state_comment'; +Variable_name Value +wsrep_local_state_comment Donor/Desynced +SET SESSION debug_sync = "wsrep_unlock_global_read_lock_after_resume_and_resync SIGNAL unlock_ready WAIT_FOR unlock_continue"; +UNLOCK TABLES; +connection node_1_ctrl; +SET debug_sync = "now WAIT_FOR unlock_ready"; +connection node_1_a; +BACKUP STAGE START; +SET SESSION debug_sync = "wsrep_backup_stage_after_desync_and_pause SIGNAL desync_and_pause_ready WAIT_FOR desync_and_pause_continue"; +BACKUP STAGE BLOCK_DDL; +connection node_1_ctrl; +SET debug_sync = "now WAIT_FOR desync_and_pause_ready"; +SET debug_sync = "now SIGNAL unlock_continue"; +connection node_1; +connection node_1_ctrl; +SET debug_sync = "now SIGNAL desync_and_pause_continue"; +connection node_1_a; +BACKUP STAGE END; +CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; +DROP TABLE t1; +connection node_1_ctrl; +SET debug_sync = "RESET"; +# +# Case 4: BACKUP STAGE first, then FTWRL +# +connection node_1; +SET SESSION wsrep_sync_wait=0; +BACKUP STAGE START; +BACKUP STAGE BLOCK_DDL; +SHOW STATUS LIKE 'wsrep_local_state_comment'; +Variable_name Value +wsrep_local_state_comment Donor/Desynced +SET SESSION debug_sync = "wsrep_backup_stage_after_resume_and_resync SIGNAL resume_and_resync_ready WAIT_FOR resume_and_resync_continue"; +BACKUP STAGE END; +connection node_1_ctrl; +SET debug_sync = "now WAIT_FOR resume_and_resync_ready"; +connection node_1_a; +SET SESSION debug_sync = "wsrep_global_read_lock_block_commit_after_pause SIGNAL lock_ready WAIT_FOR lock_continue"; +FLUSH TABLES WITH READ LOCK; +connection node_1_ctrl; +SET debug_sync = "now WAIT_FOR lock_ready"; +SET debug_sync = "now SIGNAL resume_and_resync_continue"; +connection node_1; +connection node_1_ctrl; +SET debug_sync = "now SIGNAL lock_continue"; +connection node_1_a; +UNLOCK TABLES; +CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; +DROP TABLE t1; +connection node_1_ctrl; +SET debug_sync = "RESET"; 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/r/galera_sequences.result b/mysql-test/suite/galera/r/galera_sequences.result index e696a707cdf..1a5219c2d45 100644 --- a/mysql-test/suite/galera/r/galera_sequences.result +++ b/mysql-test/suite/galera/r/galera_sequences.result @@ -31,7 +31,7 @@ select NEXT VALUE FOR Seq1_1; NEXT VALUE FOR Seq1_1 1 alter table Seq1_1 engine=myisam; -ERROR 42000: This version of MariaDB doesn't yet support 'Galera cluster does support only InnoDB sequences' +ERROR 42000: This version of MariaDB doesn't yet support 'non-InnoDB sequences in Galera cluster' select NEXT VALUE FOR Seq1_1; NEXT VALUE FOR Seq1_1 2 @@ -156,7 +156,53 @@ a b DROP TABLE t1; DROP SEQUENCE t; CREATE SEQUENCE t ENGINE=MYISAM; -ERROR 42000: This version of MariaDB doesn't yet support 'Galera cluster does support only InnoDB sequences' +ERROR 42000: This version of MariaDB doesn't yet support 'non-InnoDB sequences in Galera cluster' +SHOW CREATE SEQUENCE t; +ERROR 42S02: Table 'test.t' doesn't exist +SHOW CREATE TABLE t; +ERROR 42S02: Table 'test.t' doesn't exist +connection node_2; +SHOW CREATE SEQUENCE t; +ERROR 42S02: Table 'test.t' doesn't exist +SHOW CREATE TABLE t; +ERROR 42S02: Table 'test.t' doesn't exist +connection node_1; +CREATE SEQUENCE t NOCACHE ENGINE=InnoDB; +ALTER TABLE t ENGINE=MyISAM; +ERROR 42000: This version of MariaDB doesn't yet support 'non-InnoDB sequences in Galera cluster' +SHOW CREATE SEQUENCE t; +Table Create Table +t CREATE SEQUENCE `t` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=InnoDB +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `next_not_cached_value` bigint(21) NOT NULL, + `minimum_value` bigint(21) NOT NULL, + `maximum_value` bigint(21) NOT NULL, + `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used', + `increment` bigint(21) NOT NULL COMMENT 'increment value', + `cache_size` bigint(21) unsigned NOT NULL, + `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed', + `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done' +) ENGINE=InnoDB SEQUENCE=1 +connection node_2; +SHOW CREATE SEQUENCE t; +Table Create Table +t CREATE SEQUENCE `t` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=InnoDB +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `next_not_cached_value` bigint(21) NOT NULL, + `minimum_value` bigint(21) NOT NULL, + `maximum_value` bigint(21) NOT NULL, + `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used', + `increment` bigint(21) NOT NULL COMMENT 'increment value', + `cache_size` bigint(21) unsigned NOT NULL, + `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed', + `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done' +) ENGINE=InnoDB SEQUENCE=1 +connection node_1; +DROP SEQUENCE t; CREATE SEQUENCE t INCREMENT BY 1 NOCACHE ENGINE=INNODB; CREATE TABLE t1(a int not null primary key default nextval(t), b int) engine=innodb; connection node_2; @@ -185,7 +231,7 @@ DROP TABLE t1; CREATE SEQUENCE t INCREMENT BY 0 NOCACHE ENGINE=INNODB; DROP SEQUENCE t; CREATE SEQUENCE t INCREMENT BY 1 CACHE=20 ENGINE=INNODB; -ERROR 42000: This version of MariaDB doesn't yet support 'In Galera if you use CACHE you should set INCREMENT BY 0 to behave correctly in a cluster' +ERROR 42000: This version of MariaDB doesn't yet support 'CACHE without INCREMENT BY 0 in Galera cluster' CREATE SEQUENCE t INCREMENT BY 0 CACHE=20 ENGINE=INNODB; CREATE TABLE t1(a int not null primary key default nextval(t), b int) engine=innodb; connection node_2; @@ -201,9 +247,9 @@ DROP SEQUENCE t; DROP TABLE t1; CREATE SEQUENCE t INCREMENT BY 0 CACHE=20 ENGINE=INNODB; ALTER TABLE t ENGINE=MYISAM; -ERROR 42000: This version of MariaDB doesn't yet support 'Galera cluster does support only InnoDB sequences' +ERROR 42000: This version of MariaDB doesn't yet support 'non-InnoDB sequences in Galera cluster' ALTER SEQUENCE t INCREMENT BY 1 CACHE=10; -ERROR 42000: This version of MariaDB doesn't yet support 'In Galera if you use CACHE you should set INCREMENT BY 0 to behave correctly in a cluster' +ERROR 42000: This version of MariaDB doesn't yet support 'CACHE without INCREMENT BY 0 in Galera cluster' ALTER SEQUENCE t INCREMENT BY 1 NOCACHE; ALTER SEQUENCE t INCREMENT BY 0 NOCACHE; ALTER SEQUENCE t INCREMENT BY 0 CACHE=10; diff --git a/mysql-test/suite/galera/r/galera_slave_replay.result b/mysql-test/suite/galera/r/galera_slave_replay.result index 0b0199c4a02..8fb7e1ab099 100644 --- a/mysql-test/suite/galera/r/galera_slave_replay.result +++ b/mysql-test/suite/galera/r/galera_slave_replay.result @@ -2,6 +2,7 @@ connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; connection node_2a; connection node_2; connection node_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; connection node_3; RESET MASTER; diff --git a/mysql-test/suite/galera/r/mdev-31285.result b/mysql-test/suite/galera/r/mdev-31285.result new file mode 100644 index 00000000000..228f62fa305 --- /dev/null +++ b/mysql-test/suite/galera/r/mdev-31285.result @@ -0,0 +1,23 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connection node_1; +CREATE TABLE t ENGINE=InnoDB WITH SYSTEM VERSIONING AS SELECT 1 AS i; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `i` int(1) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING +SELECT * from t; +i +1 +DROP TABLE IF EXISTS t; +COMMIT; +connection node_2; +SET SESSION wsrep_sync_wait=0; +Killing server ... +Starting server ... +connection node_2; +call mtr.add_suppression("WSREP: Event .*Write_rows_v1 apply failed:.*"); +call mtr.add_suppression("SREP: Failed to apply write set: gtid:.*"); diff --git a/mysql-test/suite/galera/r/mdev-31651.result b/mysql-test/suite/galera/r/mdev-31651.result new file mode 100644 index 00000000000..f715aa895f8 --- /dev/null +++ b/mysql-test/suite/galera/r/mdev-31651.result @@ -0,0 +1,11 @@ +connection node_2; +connection node_1; +call mtr.add_suppression("BINLOG_BASE64_EVENT: Could not read field.*"); +call mtr.add_suppression("BINLOG_BASE64_EVENT: Could not execute Write_rows_v1 event on table.*"); +CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT, KEY(b)) engine=innodb; +BINLOG 'AMqaOw8BAAAAdAAAAHgAAAAAAAQANS42LjM0LTc5LjEtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAYVx w2w='; +BINLOG 'wlZOTxMBAAAAKgAAADwCAAAAACkAAAAAAAEABHRlc3QAAnQxAAIDAwAC wlZOTxcBAAAAJgAAAGICAAAAACkAAAAAAAEAAv/8AgAAAAgAAAA='; +ERROR HY000: Got error 171 "The event was corrupt, leading to illegal data being read" from storage engine InnoDB +SELECT * FROM t1; +a b +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-27806.opt b/mysql-test/suite/galera/t/MDEV-27806.opt new file mode 100644 index 00000000000..009e761eb2c --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-27806.opt @@ -0,0 +1 @@ +--log-bin --log-slave-updates --gtid-strict-mode --wsrep_gtid_mode=on diff --git a/mysql-test/suite/galera/t/MDEV-27806.test b/mysql-test/suite/galera/t/MDEV-27806.test new file mode 100644 index 00000000000..62a0ca483e0 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-27806.test @@ -0,0 +1,51 @@ +# +# MDEV-27806 GTIDs diverge after CTAS +# +--source include/galera_cluster.inc + +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2),(3); +CREATE TABLE ts1 AS SELECT * FROM t1; +--let binlog_pos= `SELECT @@gtid_binlog_pos` + +--let $MASTER_MYPORT=$NODE_MYPORT_1 +--let $binlog_file=LAST +--let $binlog_limit=8,20 +--source include/show_binlog_events.inc + +--connection node_2 +--let $binlog_limit=7,20 +--source include/show_binlog_events.inc + +--disable_query_log +--eval SELECT STRCMP(@@gtid_binlog_pos, "$binlog_pos") = 0 AS BINLOG_POSITIONS_MATCH; +--enable_query_log + +DROP TABLE t1,ts1; + + +# +# Same as above, with empty CREATE TABLE AS SELECT +# +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +CREATE TABLE ts1 AS SELECT * FROM t1; +--let binlog_pos= `SELECT @@gtid_binlog_pos` + +--let $MASTER_MYPORT=$NODE_MYPORT_1 +--let $binlog_file=LAST +--let $binlog_limit=18,20 +--source include/show_binlog_events.inc + +--connection node_2 +--let $binlog_limit=17,20 +--source include/show_binlog_events.inc + +--disable_query_log +--eval SELECT STRCMP(@@gtid_binlog_pos, "$binlog_pos") = 0 AS BINLOG_POSITIONS_MATCH; +--enable_query_log + +DROP TABLE t1,ts1; + +CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); 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_as_master.test b/mysql-test/suite/galera/t/galera_as_master.test index 1c439ffff63..a5554a735fe 100644 --- a/mysql-test/suite/galera/t/galera_as_master.test +++ b/mysql-test/suite/galera/t/galera_as_master.test @@ -52,12 +52,18 @@ DROP TABLE t1, t4; SET SQL_LOG_BIN=OFF; DROP TABLE t2, t3; +--let binlog_pos=`SELECT @@gtid_binlog_pos;` + --connection node_3 --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't4'; --source include/wait_condition.inc +--disable_query_log +--eval SELECT STRCMP(@@gtid_binlog_pos, "$binlog_pos") = 0 AS BINLOG_POSITIONS_MATCH; +--enable_query_log + STOP SLAVE; RESET SLAVE ALL; diff --git a/mysql-test/suite/galera/t/galera_as_slave_replay.test b/mysql-test/suite/galera/t/galera_as_slave_replay.test index 725d72c4144..73fd7b3ff29 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_replay.test +++ b/mysql-test/suite/galera/t/galera_as_slave_replay.test @@ -17,6 +17,8 @@ --source include/galera_cluster.inc #--source suite/galera/include/galera_have_debug_sync.inc +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; + # # node 3 is native MariaDB server operating as async replication master # 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_cache_index.test b/mysql-test/suite/galera/t/galera_cache_index.test new file mode 100644 index 00000000000..b373a173894 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_cache_index.test @@ -0,0 +1,29 @@ +--source include/galera_cluster.inc + +CREATE TABLE t1 (c1 int, UNIQUE INDEX (c1)) engine=innodb; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +CREATE TABLE t2 (c1 int); +INSERT INTO t2 VALUES (1),(2),(3),(4),(5); +CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2) INSERT_METHOD=LAST; +CACHE INDEX t1,t2 IN default; +LOAD INDEX INTO CACHE t1,t2; +DROP TEMPORARY TABLE t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (c1 int, UNIQUE INDEX (c1)) engine=MyISAM; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +CREATE TABLE t2 (c1 int, UNIQUE INDEX (c1)) engine=MyISAM; +INSERT INTO t2 VALUES (1),(2),(3),(4),(5); +CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2) INSERT_METHOD=LAST; +CACHE INDEX t1,t2 IN default; +LOAD INDEX INTO CACHE t1,t2; +DROP TEMPORARY TABLE t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (c1 int, UNIQUE INDEX (c1)) engine=MyISAM; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +CREATE TABLE t2 (c1 int, UNIQUE INDEX (c1)) engine=MyISAM; +INSERT INTO t2 VALUES (1),(2),(3),(4),(5); +CACHE INDEX t1,t2 IN default; +LOAD INDEX INTO CACHE t1,t2; +DROP TABLE t1,t2; diff --git a/mysql-test/suite/galera/t/galera_concurrent_ctas.test b/mysql-test/suite/galera/t/galera_concurrent_ctas.test index 61038664b21..e22ac811c8b 100644 --- a/mysql-test/suite/galera/t/galera_concurrent_ctas.test +++ b/mysql-test/suite/galera/t/galera_concurrent_ctas.test @@ -1,56 +1,85 @@ --source include/galera_cluster.inc --source include/big_test.inc +--source include/have_debug_sync.inc ---write_file $MYSQLTEST_VARDIR/tmp/galera_concurrent.sql -CREATE table t1 as SELECT SLEEP(0.1); -DROP table t1; -CREATE table t1 as SELECT SLEEP(0.1); -DROP table t1; -CREATE table t1 as SELECT SLEEP(0.1); -DROP table t1; -CREATE table t1 as SELECT SLEEP(0.1); -DROP table t1; -CREATE table t1 as SELECT SLEEP(0.1); -DROP table t1; -CREATE table t1 as SELECT SLEEP(0.1); -DROP table t1; -CREATE table t1 as SELECT SLEEP(0.1); -DROP table t1; -CREATE table t1 as SELECT SLEEP(0.1); -DROP table t1; -CREATE table t1 as SELECT SLEEP(0.2); -CREATE table t2 as SELECT SLEEP(0.2); -CREATE table t3 as SELECT SLEEP(0.2); -CREATE table t4 as SELECT SLEEP(0.2); -CREATE table t5 as SELECT SLEEP(0.2); -CREATE table t6 as SELECT SLEEP(0.2); -CREATE table t7 as SELECT SLEEP(0.2); -CREATE table t8 as SELECT SLEEP(0.2); -CREATE table t9 as SELECT SLEEP(0.2); -DROP table t1; -DROP table t2; -DROP table t3; -DROP table t4; -DROP table t5; -DROP table t6; -DROP table t7; -DROP table t8; -DROP table t9; -EOF +# +# To have real concurrent CTAS this test uses DEBUG_SYNC +# -let $run=10; +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 -while($run) -{ - --error 0,1 - exec $MYSQL --user=root --host=127.0.0.1 --port=$NODE_MYPORT_1 test \ - < $MYSQLTEST_VARDIR/tmp/galera_concurrent.sql & \ - $MYSQL --user=root --host=127.0.0.1 --port=$NODE_MYPORT_2 test \ - < $MYSQLTEST_VARDIR/tmp/galera_concurrent.sql; - dec $run; -} +--connection node_1 +# +# Send CTAS it will block before open_tables call +# +SET DEBUG_SYNC = 'wsrep_create_table_as_select WAIT_FOR continue'; +--send CREATE table t1 as SELECT SLEEP(0.1); + +--connection node_1a +# +# Wait for CTAS to block +# +--echo # Wait until CTAS is on debug sync point +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'debug sync point: wsrep_create_table_as_select' +--source include/wait_condition.inc + +--connection node_1b +# +# Block node_1 applier +# +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL debug_dbug = '+d,sync.wsrep_apply_cb'; + +# +# Send concurrent CTAS it will block on applier +# +--connection node_2 +--send CREATE table t1 as SELECT SLEEP(0.2); + +# +# Wait until second CTAS is blocked +# +--connection node_1b +SET SESSION debug_sync = 'now WAIT_FOR sync.wsrep_apply_cb_reached'; + +--echo # Signal first CTAS to continue and wait until CTAS has executed +SET DEBUG_SYNC= 'now SIGNAL continue'; +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'Creating table CREATE table t1 as SELECT SLEEP(0.1)' +--source include/wait_condition.inc +# +# Release second CTAS and cleanup +# +SET GLOBAL debug_dbug= ''; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +# +# Wait until second CTAS continues +# +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'debug sync point: now%' +--source include/wait_condition.inc +# +# Wait until second CTAS finishes +# +--connection node_2a +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'Creating table CREATE table t1 as SELECT SLEEP(0.2)' +--source include/wait_condition.inc +# +# Cleanup +# +--connection node_1b +SET DEBUG_SYNC= 'RESET'; +# +# Verify that at least one is successful +# +--connection node_2 +--reap + +--connection node_1 +--error 0,ER_TABLE_EXISTS_ERROR,ER_QUERY_INTERRUPTED +--reap +DROP TABLE t1; ---remove_file $MYSQLTEST_VARDIR/tmp/galera_concurrent.sql --source include/galera_end.inc --echo # End of test diff --git a/mysql-test/suite/galera/t/galera_forced_binlog_ctas_test.inc b/mysql-test/suite/galera/t/galera_forced_binlog_ctas_test.inc new file mode 100644 index 00000000000..f6d8f451d13 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_forced_binlog_ctas_test.inc @@ -0,0 +1,50 @@ +--connection node_1 +CREATE TABLE t1(a int not null primary key auto_increment, b int) ENGINE=InnoDB; +CREATE TABLE t2(a int not null primary key, b int) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL,1),(NULL,2); +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +INSERT INTO t1(b) SELECT b+1 from t1; +CREATE TABLE t3 AS SELECT * FROM t1; +CREATE TABLE t4 AS SELECT * FROM t2; +CREATE TABLE t5 (a INT UNIQUE) AS SELECT 1 AS a; +CREATE TABLE t6 (a INT UNIQUE) REPLACE SELECT 1 AS a; +CREATE TABLE t7 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a, +3 AS c; + +SELECT COUNT(*) AS EXPECT_32 FROM t1; +SELECT COUNT(*) AS EXPECT_0 FROM t2; +SELECT COUNT(*) AS EXPECT_32 FROM t3; +SELECT * FROM t4; +SELECT * FROM t5; +SELECT * FROM t6; +SELECT * FROM t7; + +--connection node_2 +--echo # Veryfy CTAS replication +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't3' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't4' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't5' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't6' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't7' +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_32 FROM t1; +SELECT COUNT(*) AS EXPECT_0 FROM t2; +SELECT COUNT(*) AS EXPECT_32 FROM t3; +SELECT * FROM t4; +SELECT * FROM t5; +SELECT * FROM t6; +SELECT * FROM t7; + +--connection node_1 +DROP TABLE t1,t2,t3,t4,t5,t6,t7; diff --git a/mysql-test/suite/galera/t/galera_forced_binlog_format_ctas.test b/mysql-test/suite/galera/t/galera_forced_binlog_format_ctas.test new file mode 100644 index 00000000000..bb9cb6a9403 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_forced_binlog_format_ctas.test @@ -0,0 +1,19 @@ +--source include/galera_cluster.inc + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since.*"); + +SET GLOBAL wsrep_forced_binlog_format=ROW; + +--source suite/galera/t/galera_forced_binlog_ctas_test.inc + +SET GLOBAL wsrep_forced_binlog_format=STATEMENT; + +--source suite/galera/t/galera_forced_binlog_ctas_test.inc + +SET GLOBAL wsrep_forced_binlog_format=MIXED; + +--source suite/galera/t/galera_forced_binlog_ctas_test.inc + +SET GLOBAL wsrep_forced_binlog_format=NONE; + +--source suite/galera/t/galera_forced_binlog_ctas_test.inc diff --git a/mysql-test/suite/galera/t/galera_ftwrl_concurrent.test b/mysql-test/suite/galera/t/galera_ftwrl_concurrent.test new file mode 100644 index 00000000000..724160835d8 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ftwrl_concurrent.test @@ -0,0 +1,193 @@ +# +# MDEV-32282 +# +# A node remains in paused state after two interleaving FTWRLs, +# and the following CREATE TABLE fails with +# +# ER_UNKNOWN_COM_ERROR (1047): Aborting TOI: Replication paused on +# node for FTWRL/BACKUP STAGE. +# +# node_1 node_1_a +# ---------------------------------------------------------------------- +# FTWRL +# UNLOCK TABLES wait after resume_and_resync() +# FTWRL wait after desync_and_pause() +# continue +# continue +# UNLOCK TABLES +# CREATE TABLE fails +# +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug_sync.inc + +# Connection to control sync points +--connect node_1_ctrl, 127.0.0.1, root, , test, $NODE_MYPORT_1 +SET SESSION wsrep_sync_wait=0; + +--echo # +--echo # Case 1: FTWRL +--echo # + +--connection node_1 +SET SESSION wsrep_sync_wait=0; +FLUSH TABLES WITH READ LOCK; +SHOW STATUS LIKE 'wsrep_local_state_comment'; +SET SESSION debug_sync = "wsrep_unlock_global_read_lock_after_resume_and_resync SIGNAL unlock_ready WAIT_FOR unlock_continue"; +--send UNLOCK TABLES + +--connection node_1_ctrl +SET debug_sync = "now WAIT_FOR unlock_ready"; + +--connect node_1_a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1_a +SET SESSION debug_sync = "wsrep_global_read_lock_block_commit_after_pause SIGNAL lock_ready WAIT_FOR lock_continue"; +--send FLUSH TABLES WITH READ LOCK + +--connection node_1_ctrl +SET debug_sync = "now WAIT_FOR lock_ready"; +SET debug_sync = "now SIGNAL unlock_continue"; + +--connection node_1 +--reap + +--connection node_1_ctrl +SET debug_sync = "now SIGNAL lock_continue"; + +--connection node_1_a +--reap + +UNLOCK TABLES; +--let $wait_condition = SELECT VARIABLE_VALUE = "Synced" FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = "wsrep_local_state_comment" +--source include/wait_condition.inc + +CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; +DROP TABLE t1; +--connection node_1_ctrl +SET debug_sync = "RESET"; + +--echo # +--echo # Case 2: BACKUP STAGE +--echo # +# Although BACKUP STAGE was not involved in MDEV-32282, add a testcase +# as it uses similar mechanism to pause and desync the node. +# + +--connection node_1 +SET SESSION wsrep_sync_wait=0; +BACKUP STAGE START; +BACKUP STAGE BLOCK_DDL; +SHOW STATUS LIKE 'wsrep_local_state_comment'; +SET SESSION debug_sync = "wsrep_backup_stage_after_resume_and_resync SIGNAL resume_and_resync_ready WAIT_FOR resume_and_resync_continue"; +--send BACKUP STAGE END + +--connection node_1_ctrl +SET debug_sync = "now WAIT_FOR resume_and_resync_ready"; + +--connection node_1_a +BACKUP STAGE START; +SET SESSION debug_sync = "wsrep_backup_stage_after_desync_and_pause SIGNAL desync_and_pause_ready WAIT_FOR desync_and_pause_continue"; +--send BACKUP STAGE BLOCK_DDL + +--connection node_1_ctrl +SET debug_sync = "now WAIT_FOR desync_and_pause_ready"; +SET debug_sync = "now SIGNAL resume_and_resync_continue"; + +--connection node_1 +--reap + +--connection node_1_ctrl +SET debug_sync = "now SIGNAL desync_and_pause_continue"; + +--connection node_1_a +--reap +BACKUP STAGE END; +--let $wait_condition = SELECT VARIABLE_VALUE = "Synced" FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = "wsrep_local_state_comment" +--source include/wait_condition.inc + +CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; +DROP TABLE t1; + +--connection node_1_ctrl +SET debug_sync = "RESET"; + +--echo # +--echo # Case 3: FTWRL first, BACKUP STAGE second +--echo # + +--connection node_1 +SET SESSION wsrep_sync_wait=0; +SET SESSION wsrep_sync_wait=0; +FLUSH TABLES WITH READ LOCK; +SHOW STATUS LIKE 'wsrep_local_state_comment'; +SET SESSION debug_sync = "wsrep_unlock_global_read_lock_after_resume_and_resync SIGNAL unlock_ready WAIT_FOR unlock_continue"; +--send UNLOCK TABLES + +--connection node_1_ctrl +SET debug_sync = "now WAIT_FOR unlock_ready"; + +--connection node_1_a +BACKUP STAGE START; +SET SESSION debug_sync = "wsrep_backup_stage_after_desync_and_pause SIGNAL desync_and_pause_ready WAIT_FOR desync_and_pause_continue"; +--send BACKUP STAGE BLOCK_DDL + +--connection node_1_ctrl +SET debug_sync = "now WAIT_FOR desync_and_pause_ready"; +SET debug_sync = "now SIGNAL unlock_continue"; + +--connection node_1 +--reap + +--connection node_1_ctrl +SET debug_sync = "now SIGNAL desync_and_pause_continue"; + +--connection node_1_a +--reap +BACKUP STAGE END; +--let $wait_condition = SELECT VARIABLE_VALUE = "Synced" FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = "wsrep_local_state_comment" +--source include/wait_condition.inc + +CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; +DROP TABLE t1; + +--connection node_1_ctrl +SET debug_sync = "RESET"; + +--echo # +--echo # Case 4: BACKUP STAGE first, then FTWRL +--echo # +--connection node_1 +SET SESSION wsrep_sync_wait=0; +BACKUP STAGE START; +BACKUP STAGE BLOCK_DDL; +SHOW STATUS LIKE 'wsrep_local_state_comment'; +SET SESSION debug_sync = "wsrep_backup_stage_after_resume_and_resync SIGNAL resume_and_resync_ready WAIT_FOR resume_and_resync_continue"; +--send BACKUP STAGE END + +--connection node_1_ctrl +SET debug_sync = "now WAIT_FOR resume_and_resync_ready"; +--connection node_1_a +SET SESSION debug_sync = "wsrep_global_read_lock_block_commit_after_pause SIGNAL lock_ready WAIT_FOR lock_continue"; +--send FLUSH TABLES WITH READ LOCK + +--connection node_1_ctrl +SET debug_sync = "now WAIT_FOR lock_ready"; +SET debug_sync = "now SIGNAL resume_and_resync_continue"; + +--connection node_1 +--reap + +--connection node_1_ctrl +SET debug_sync = "now SIGNAL lock_continue"; + +--connection node_1_a +--reap + +UNLOCK TABLES; +--let $wait_condition = SELECT VARIABLE_VALUE = "Synced" FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = "wsrep_local_state_comment" +--source include/wait_condition.inc + +CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; +DROP TABLE t1; +--connection node_1_ctrl +SET debug_sync = "RESET"; 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/t/galera_restart_replica.test b/mysql-test/suite/galera/t/galera_restart_replica.test index 2cc3a1dcff2..37cfd9bc0f9 100644 --- a/mysql-test/suite/galera/t/galera_restart_replica.test +++ b/mysql-test/suite/galera/t/galera_restart_replica.test @@ -3,9 +3,9 @@ # # The galera/galera_2node_slave.cnf describes the setup of the nodes # ---source include/big_test.inc --source include/force_restart.inc --source include/galera_cluster.inc +--source include/have_innodb.inc --source include/have_sequence.inc # As node #3 is not a Galera node, and galera_cluster.inc does not open connetion to it diff --git a/mysql-test/suite/galera/t/galera_sequences.test b/mysql-test/suite/galera/t/galera_sequences.test index 5c03ab973e0..53417055d7d 100644 --- a/mysql-test/suite/galera/t/galera_sequences.test +++ b/mysql-test/suite/galera/t/galera_sequences.test @@ -134,6 +134,31 @@ DROP SEQUENCE t; # --error ER_NOT_SUPPORTED_YET CREATE SEQUENCE t ENGINE=MYISAM; +--error ER_NO_SUCH_TABLE +SHOW CREATE SEQUENCE t; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE t; + +--connection node_2 +# Verify that above MyISAM sequence does not replicate +--error ER_NO_SUCH_TABLE +SHOW CREATE SEQUENCE t; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE t; + +--connection node_1 +CREATE SEQUENCE t NOCACHE ENGINE=InnoDB; +--error ER_NOT_SUPPORTED_YET +ALTER TABLE t ENGINE=MyISAM; +SHOW CREATE SEQUENCE t; +SHOW CREATE TABLE t; + +--connection node_2 +SHOW CREATE SEQUENCE t; +SHOW CREATE TABLE t; + +--connection node_1 +DROP SEQUENCE t; CREATE SEQUENCE t INCREMENT BY 1 NOCACHE ENGINE=INNODB; CREATE TABLE t1(a int not null primary key default nextval(t), b int) engine=innodb; @@ -164,15 +189,15 @@ SET SESSION wsrep_sync_wait=0; while ($count) { --connection node_1 ---error 0,ER_LOCK_WAIT_TIMEOUT +--error 0,ER_LOCK_WAIT_TIMEOUT,ER_LOCK_DEADLOCK INSERT INTO t1(b) values (1); --connection node_2 ---error 0,ER_LOCK_WAIT_TIMEOUT +--error 0,ER_LOCK_WAIT_TIMEOUT,ER_LOCK_DEADLOCK INSERT INTO t1(b) values (2); ---error 0,ER_LOCK_WAIT_TIMEOUT +--error 0,ER_LOCK_WAIT_TIMEOUT,ER_LOCK_DEADLOCK INSERT INTO t1(b) values (2); --connection node_1 ---error 0,ER_LOCK_WAIT_TIMEOUT +--error 0,ER_LOCK_WAIT_TIMEOUT,ER_LOCK_DEADLOCK INSERT INTO t1(b) values (1); --dec $count } @@ -222,15 +247,15 @@ SET SESSION wsrep_sync_wait=0; while ($count) { --connection node_1 ---error 0,ER_LOCK_WAIT_TIMEOUT +--error 0,ER_LOCK_WAIT_TIMEOUT,ER_LOCK_DEADLOCK INSERT INTO t1(b) values (1),(2),(3),(4),(5),(6),(7),(8),(9); --connection node_2 ---error 0,ER_LOCK_WAIT_TIMEOUT +--error 0,ER_LOCK_WAIT_TIMEOUT,ER_LOCK_DEADLOCK INSERT INTO t1(b) values (21),(22),(23),(24),(25),(26),(27),(28),(29); ---error 0,ER_LOCK_WAIT_TIMEOUT +--error 0,ER_LOCK_WAIT_TIMEOUT,ER_LOCK_DEADLOCK INSERT INTO t1(b) values (21),(22),(23),(24),(25),(26),(27),(28),(29); --connection node_1 ---error 0,ER_LOCK_WAIT_TIMEOUT +--error 0,ER_LOCK_WAIT_TIMEOUT,ER_LOCK_DEADLOCK INSERT INTO t1(b) values (1),(2),(3),(4),(5),(6),(7),(8),(9); --dec $count } diff --git a/mysql-test/suite/galera/t/galera_slave_replay.test b/mysql-test/suite/galera/t/galera_slave_replay.test index f1500eeaeaa..6680e66ffa1 100644 --- a/mysql-test/suite/galera/t/galera_slave_replay.test +++ b/mysql-test/suite/galera/t/galera_slave_replay.test @@ -17,6 +17,8 @@ --connection node_2a --source include/galera_cluster.inc +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; + # # node 3 is native MariaDB server operating as async replication master # diff --git a/mysql-test/suite/galera/t/mdev-31285.test b/mysql-test/suite/galera/t/mdev-31285.test new file mode 100644 index 00000000000..d2749165ef7 --- /dev/null +++ b/mysql-test/suite/galera/t/mdev-31285.test @@ -0,0 +1,34 @@ +--source include/galera_cluster.inc + +--let $node_1 = node_1 +--let $node_2 = node_2 +--source include/auto_increment_offset_save.inc + +--connection node_1 +CREATE TABLE t ENGINE=InnoDB WITH SYSTEM VERSIONING AS SELECT 1 AS i; +SHOW CREATE TABLE t; +SELECT * from t; +DROP TABLE IF EXISTS t; +COMMIT; + +# +# Restart node_2, force SST because database is inconsistent compared to node_1 +# +--connection node_2 +SET SESSION wsrep_sync_wait=0; +--source include/kill_galera.inc +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat +--echo Starting server ... +let $restart_noprint=2; +--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 + +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +--source include/wait_condition.inc + +--connection node_2 +call mtr.add_suppression("WSREP: Event .*Write_rows_v1 apply failed:.*"); +call mtr.add_suppression("SREP: Failed to apply write set: gtid:.*"); + +--source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/mdev-31651.test b/mysql-test/suite/galera/t/mdev-31651.test new file mode 100644 index 00000000000..3598057a53f --- /dev/null +++ b/mysql-test/suite/galera/t/mdev-31651.test @@ -0,0 +1,11 @@ +--source include/galera_cluster.inc + + +call mtr.add_suppression("BINLOG_BASE64_EVENT: Could not read field.*"); +call mtr.add_suppression("BINLOG_BASE64_EVENT: Could not execute Write_rows_v1 event on table.*"); +CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT, KEY(b)) engine=innodb; +BINLOG 'AMqaOw8BAAAAdAAAAHgAAAAAAAQANS42LjM0LTc5LjEtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAYVx w2w='; +--error ER_GET_ERRNO +BINLOG 'wlZOTxMBAAAAKgAAADwCAAAAACkAAAAAAAEABHRlc3QAAnQxAAIDAwAC wlZOTxcBAAAAJgAAAGICAAAAACkAAAAAAAEAAv/8AgAAAAgAAAA='; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index d0e682958ec..ac7ce8c8ee6 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -10,12 +10,15 @@ # ############################################################################## -galera_2_cluster : MDEV-29877 Galera test failure on galera_2_cluster -galera_gtid_2_cluster : MDEV-29877 Galera test failure on galera_2_cluster +galera_2_cluster : MDEV-32631 galera_2_cluster: before_rollback(): Assertion `0' failed +galera_gtid_2_cluster : MDEV-32633 galera_gtid_2_cluster: Assertion `thd->wsrep_next_trx_id() != (0x7fffffffffffffffLL * 2ULL + 1)' galera_ipv6_mariabackup : MDEV-24097 galera_ipv6_mariabackup_section : MDEV-24097, MDEV-22195 galera_vote_rejoin_mysqldump : MDEV-24481: galera_3nodes.galera_vote_rejoin_mysqldump MTR failed: mysql_shutdown failed -galera_ssl_reload : MDEV-30172 At line 50: 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/galera_3nodes_sr/disabled.def b/mysql-test/suite/galera_3nodes_sr/disabled.def index df2277fb8ad..4472d960d9f 100644 --- a/mysql-test/suite/galera_3nodes_sr/disabled.def +++ b/mysql-test/suite/galera_3nodes_sr/disabled.def @@ -10,4 +10,4 @@ # ############################################################################## -galera_sr_kill_slave_after_apply_rollback2 : MDEV-29892 Galera test failure on galera_sr_kill_slave_after_apply_rollback2 \ No newline at end of file +galera_sr_kill_slave_after_apply_rollback2 : MDEV-29892 Galera test failure on galera_sr_kill_slave_after_apply_rollback2 diff --git a/mysql-test/suite/galera_sr/disabled.def b/mysql-test/suite/galera_sr/disabled.def index 9cca05eb62c..c126cc8c703 100644 --- a/mysql-test/suite/galera_sr/disabled.def +++ b/mysql-test/suite/galera_sr/disabled.def @@ -10,8 +10,7 @@ # ############################################################################## -GCF-1060 : MDEV-26528 wrong usage of mutex LOCK_thd_kill and LOCK_thd_kill +GCF-1060 : MDEV-32160 GCF-1060 test failure due to wsrep MDL conflict galera_sr_cc_master : MDEV-29882 Galera test failure on galera_sr_cc_master -mysql-wsrep-features#138 : At line 25: query 'DROP TABLE t1' failed: 2013: Lost connection to MySQL server during query # Links to below failures in MDEV-30172 MDEV-25718 : timeout related to wsrep_sync_wait and DEBUG_SYNC diff --git a/mysql-test/suite/galera_sr/r/MDEV-28971.result b/mysql-test/suite/galera_sr/r/MDEV-28971.result new file mode 100644 index 00000000000..0826f5e6b66 --- /dev/null +++ b/mysql-test/suite/galera_sr/r/MDEV-28971.result @@ -0,0 +1,17 @@ +connection node_2; +connection node_1; +CREATE SEQUENCE SEQ NOCACHE ENGINE=InnoDB; +SET SESSION wsrep_trx_fragment_size=1; +SET collation_connection=utf16_thai_520_w2; +SET autocommit=0; +CREATE TABLE t1 (a BLOB UNIQUE); +INSERT INTO t1 VALUES ('AAF'); +SELECT SETVAL (SEQ, 100); +ERROR 42000: This version of MariaDB doesn't yet support 'SEQUENCEs with streaming replication in Galera cluster' +ALTER TABLE t1 ADD CONSTRAINT constraint_1 UNIQUE (a); +Warnings: +Note 1831 Duplicate index `constraint_1`. This is deprecated and will be disallowed in a future release +INSERT INTO t1 VALUES(); +ALTER TABLE t1 ADD KEY(b (50)); +ERROR 42000: Key column 'b' doesn't exist in table +DROP TABLE t1,SEQ; diff --git a/mysql-test/suite/galera_sr/t/MDEV-28971.test b/mysql-test/suite/galera_sr/t/MDEV-28971.test new file mode 100644 index 00000000000..d3dbf03b4df --- /dev/null +++ b/mysql-test/suite/galera_sr/t/MDEV-28971.test @@ -0,0 +1,20 @@ +# +# MDEV-28971 - Assertion `total_length + thd->wsrep_sr().log_position() == saved_pos' +# failed in int wsrep_write_cache_inc(THD*, IO_CACHE*, size_t*) +# + +--source include/galera_cluster.inc + +CREATE SEQUENCE SEQ NOCACHE ENGINE=InnoDB; +SET SESSION wsrep_trx_fragment_size=1; +SET collation_connection=utf16_thai_520_w2; +SET autocommit=0; +CREATE TABLE t1 (a BLOB UNIQUE); +INSERT INTO t1 VALUES ('AAF'); +--error ER_NOT_SUPPORTED_YET +SELECT SETVAL (SEQ, 100); +ALTER TABLE t1 ADD CONSTRAINT constraint_1 UNIQUE (a); +INSERT INTO t1 VALUES(); +--error ER_KEY_COLUMN_DOES_NOT_EXIST +ALTER TABLE t1 ADD KEY(b (50)); +DROP TABLE t1,SEQ; diff --git a/mysql-test/suite/gcol/r/gcol_bugfixes.result b/mysql-test/suite/gcol/r/gcol_bugfixes.result index 7b70f61df03..f26b0ad3795 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/gcol_partition_innodb.result b/mysql-test/suite/gcol/r/gcol_partition_innodb.result index e61c0a26417..e6252b3dea5 100644 --- a/mysql-test/suite/gcol/r/gcol_partition_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_partition_innodb.result @@ -1,6 +1,6 @@ -SET @@session.default_storage_engine = 'InnoDB'; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; +SET default_storage_engine = 'InnoDB'; drop table if exists t1; # Case 1. Partitioning by RANGE based on a non-stored generated column. CREATE TABLE t1 ( @@ -128,6 +128,7 @@ Warnings: Warning 1906 The value specified for generated column 'vd' in table 't1' has been ignored DROP TABLE t1; InnoDB 0 transactions not purged +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; @@ -135,4 +136,3 @@ DROP FUNCTION IF EXISTS f1; DROP TRIGGER IF EXISTS trg1; DROP TRIGGER IF EXISTS trg2; set sql_warnings = 0; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/gcol/r/gcol_purge.result b/mysql-test/suite/gcol/r/gcol_purge.result index a130485f219..19db34ac916 100644 --- a/mysql-test/suite/gcol/r/gcol_purge.result +++ b/mysql-test/suite/gcol/r/gcol_purge.result @@ -1,9 +1,7 @@ -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; SET @save_dbug=@@GLOBAL.debug_dbug; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; CREATE TABLE t1(f1 INT NOT NULL, f2 int not null, f3 int generated always as (f2 * 2) VIRTUAL, -primary key(f1), INDEX (f3))ENGINE=InnoDB; +primary key(f1), INDEX (f3))ENGINE=InnoDB STATS_PERSISTENT=0; connect con1,localhost,root,,,; InnoDB 0 transactions not purged START TRANSACTION WITH CONSISTENT SNAPSHOT; @@ -22,6 +20,5 @@ commit; disconnect con1; disconnect con2; connection default; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; SET GLOBAL debug_dbug=@save_dbug; DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/gcol_update.result b/mysql-test/suite/gcol/r/gcol_update.result index 720ff533bac..54974826ebb 100644 --- a/mysql-test/suite/gcol/r/gcol_update.result +++ b/mysql-test/suite/gcol/r/gcol_update.result @@ -1,5 +1,5 @@ -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; connect purge_control,localhost,root; START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; @@ -39,4 +39,4 @@ InnoDB 0 transactions not purged disconnect purge_control; connection default; drop table t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; 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/r/innodb_virtual_debug.result b/mysql-test/suite/gcol/r/innodb_virtual_debug.result index 882fbc6e6a9..1ca30b84a81 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_debug.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug.result @@ -1,4 +1,6 @@ set default_storage_engine=innodb; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; CREATE TABLE `t` ( `a` VARCHAR(100), `b` VARCHAR(100), @@ -145,3 +147,4 @@ DROP TABLE t1; disconnect con1; connection default; SET DEBUG_SYNC=RESET; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result index 89711a2d8bb..63ea5b1d418 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result @@ -1,7 +1,5 @@ set default_storage_engine=innodb; set @old_dbug=@@global.debug_dbug; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; SET GLOBAL innodb_stats_persistent = OFF; CREATE TABLE `t` ( @@ -204,5 +202,4 @@ disconnect truncate; connection default; DROP TABLE t1, t2; set debug_sync=reset; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_index.result b/mysql-test/suite/gcol/r/innodb_virtual_index.result index 52203c0610c..a26da4ae176 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_index.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_index.result @@ -1,6 +1,4 @@ SET default_storage_engine= innodb; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; # # Bug 21922176 - PREBUILT->SEARCH_TUPLE CREATED WITHOUT INCLUDING # THE NUMBER OF VIRTUAL COLUMNS @@ -194,7 +192,6 @@ ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col1 % col2) VIRTUAL, ADD UNIQUE index idx (col1), algorithm=inplace; ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; # # Bug 27122803 - BACKPORT FIX FOR BUG 25899959 TO MYSQL-5.7 # diff --git a/mysql-test/suite/gcol/r/innodb_virtual_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_purge.result index 1fcbd05f354..3f1c4413615 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_purge.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_purge.result @@ -1,5 +1,5 @@ -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; # # Bug#21869656 UNDO LOG DOES NOT CONTAIN ENOUGH INFORMATION # ON INDEXED VIRTUAL COLUMNS @@ -173,4 +173,4 @@ CHECK TABLE t EXTENDED; Table Op Msg_type Msg_text test.t check status OK DROP TABLE t; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; 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/gcol_partition_innodb.test b/mysql-test/suite/gcol/t/gcol_partition_innodb.test index 75e2f80af20..6bcd9d27118 100644 --- a/mysql-test/suite/gcol/t/gcol_partition_innodb.test +++ b/mysql-test/suite/gcol/t/gcol_partition_innodb.test @@ -29,9 +29,9 @@ ##### Storage engine to be tested # Set the session storage engine --source include/have_innodb.inc -eval SET @@session.default_storage_engine = 'InnoDB'; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; +SET default_storage_engine = 'InnoDB'; ##### Workarounds for known open engine specific bugs # none @@ -60,7 +60,9 @@ REPLACE INTO t1 SELECT * FROM t1; DROP TABLE t1; --source suite/innodb/include/wait_all_purged.inc + +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; + #------------------------------------------------------------------------------# # Cleanup --source suite/gcol/inc/gcol_cleanup.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/gcol/t/gcol_purge.test b/mysql-test/suite/gcol/t/gcol_purge.test index 8fff375cdc2..4ebb37ad3cc 100644 --- a/mysql-test/suite/gcol/t/gcol_purge.test +++ b/mysql-test/suite/gcol/t/gcol_purge.test @@ -1,12 +1,10 @@ --source include/have_innodb.inc --source include/have_debug.inc -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; SET @save_dbug=@@GLOBAL.debug_dbug; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; CREATE TABLE t1(f1 INT NOT NULL, f2 int not null, f3 int generated always as (f2 * 2) VIRTUAL, - primary key(f1), INDEX (f3))ENGINE=InnoDB; + primary key(f1), INDEX (f3))ENGINE=InnoDB STATS_PERSISTENT=0; connect(con1,localhost,root,,,); --source ../innodb/include/wait_all_purged.inc START TRANSACTION WITH CONSISTENT SNAPSHOT; @@ -31,6 +29,5 @@ commit; disconnect con1; disconnect con2; connection default; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; SET GLOBAL debug_dbug=@save_dbug; DROP TABLE t1; diff --git a/mysql-test/suite/gcol/t/gcol_update.test b/mysql-test/suite/gcol/t/gcol_update.test index 8652ce7a638..86474f86c2e 100644 --- a/mysql-test/suite/gcol/t/gcol_update.test +++ b/mysql-test/suite/gcol/t/gcol_update.test @@ -1,7 +1,7 @@ --source include/have_innodb.inc -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; connect (purge_control,localhost,root); START TRANSACTION WITH CONSISTENT SNAPSHOT; @@ -64,4 +64,4 @@ disconnect purge_control; connection default; drop table t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; 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/gcol/t/innodb_virtual_debug.test b/mysql-test/suite/gcol/t/innodb_virtual_debug.test index c1bd76342e5..337af3e5d95 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_debug.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug.test @@ -4,6 +4,10 @@ --source include/count_sessions.inc set default_storage_engine=innodb; +# Ensure that the history list length will actually be decremented by purge. +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; + CREATE TABLE `t` ( `a` VARCHAR(100), `b` VARCHAR(100), @@ -338,4 +342,6 @@ DROP TABLE t1; connection default; SET DEBUG_SYNC=RESET; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; + --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test index da49a5b6b43..09fba0285c7 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test @@ -6,8 +6,6 @@ set default_storage_engine=innodb; set @old_dbug=@@global.debug_dbug; # Ensure that the history list length will actually be decremented by purge. -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; SET GLOBAL innodb_stats_persistent = OFF; @@ -267,5 +265,4 @@ DROP TABLE t1, t2; --source include/wait_until_count_sessions.inc set debug_sync=reset; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_index.test b/mysql-test/suite/gcol/t/innodb_virtual_index.test index d0e1951842e..83d9a6bdae5 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_index.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_index.test @@ -3,10 +3,6 @@ SET default_storage_engine= innodb; -# Ensure that the history list length will actually be decremented by purge. -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; - --echo # --echo # Bug 21922176 - PREBUILT->SEARCH_TUPLE CREATED WITHOUT INCLUDING --echo # THE NUMBER OF VIRTUAL COLUMNS @@ -226,7 +222,6 @@ ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col1 % col2) VIRTUAL, ADD UNIQUE index idx (col1), algorithm=inplace; DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; --echo # --echo # Bug 27122803 - BACKPORT FIX FOR BUG 25899959 TO MYSQL-5.7 diff --git a/mysql-test/suite/gcol/t/innodb_virtual_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_purge.test index 3db1b8757ff..5f3cae34057 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_purge.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_purge.test @@ -1,9 +1,8 @@ --source include/have_innodb.inc --source include/count_sessions.inc -# Ensure that the history list length will actually be decremented by purge. -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; --echo # --echo # Bug#21869656 UNDO LOG DOES NOT CONTAIN ENOUGH INFORMATION @@ -186,5 +185,6 @@ SET GLOBAL innodb_max_purge_lag_wait=0; CHECK TABLE t EXTENDED; DROP TABLE t; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; + --source include/wait_until_count_sessions.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/innodb/disabled.def b/mysql-test/suite/innodb/disabled.def new file mode 100644 index 00000000000..e78d33745b2 --- /dev/null +++ b/mysql-test/suite/innodb/disabled.def @@ -0,0 +1 @@ +doublewrite_debug : MDEV-33098 occasionally fails to start up InnoDB 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/include/wait_all_purged.inc b/mysql-test/suite/innodb/include/wait_all_purged.inc index e3a506c7622..e374a7c09f3 100644 --- a/mysql-test/suite/innodb/include/wait_all_purged.inc +++ b/mysql-test/suite/innodb/include/wait_all_purged.inc @@ -1,5 +1,4 @@ # Wait for everything to be purged. -# The user should have set innodb_purge_rseg_truncate_frequency=1. --disable_query_log if (!$wait_all_purged) 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/alter_kill.result b/mysql-test/suite/innodb/r/alter_kill.result index 037b06fffbc..a0d95154ab9 100644 --- a/mysql-test/suite/innodb/r/alter_kill.result +++ b/mysql-test/suite/innodb/r/alter_kill.result @@ -1,7 +1,7 @@ # # Bug#16720368 INNODB CRASHES ON BROKEN #SQL*.IBD FILE AT STARTUP # -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET GLOBAL innodb_stats_persistent=0; CREATE TABLE bug16720368_1 (a INT PRIMARY KEY) ENGINE=InnoDB; connect con1,localhost,root; CREATE TABLE bug16720368 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb/r/alter_table.result b/mysql-test/suite/innodb/r/alter_table.result index d39edd3c826..a07780148ff 100644 --- a/mysql-test/suite/innodb/r/alter_table.result +++ b/mysql-test/suite/innodb/r/alter_table.result @@ -117,8 +117,25 @@ ERROR 42000: Incorrect column specifier for column 'c' CREATE TABLE t1 (c DATETIME AUTO_INCREMENT UNIQUE) ENGINE=InnoDB; ERROR 42000: Incorrect column specifier for column 'c' # -# End of 10.4 tests +# MDEV-31000 Assertion failed on ALTER TABLE...page_compressed=1 # +SET @save_file_per_table=@@GLOBAL.innodb_file_per_table; +SET GLOBAL innodb_file_per_table=0; +Warnings: +Warning 1287 '@@innodb_file_per_table' is deprecated and will be removed in a future release +CREATE TABLE t (c INT PRIMARY KEY) ENGINE=INNODB; +SET GLOBAL innodb_file_per_table=1; +Warnings: +Warning 1287 '@@innodb_file_per_table' is deprecated and will be removed in a future release +ALTER TABLE t page_compressed=1; +SET GLOBAL innodb_file_per_table=@save_file_per_table; +Warnings: +Warning 1287 '@@innodb_file_per_table' is deprecated and will be removed in a future release +SELECT space>0 FROM information_schema.innodb_sys_tables WHERE name='test/t'; +space>0 +1 +DROP TABLE t; +# End of 10.4 tests # # MDEV-21748 ASAN use-after-poison in PageBulk::insertPage() # @@ -136,3 +153,4 @@ CREATE TABLE t1 (id INT PRIMARY KEY, a YEAR, INDEX(id,a)) ENGINE=InnoDB; INSERT INTO t1 VALUES (1,NULL),(2,NULL); UPDATE t1 SET a=0; DROP TABLE t1; +# End of 10.5 tests 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/cursor-restore-locking.result b/mysql-test/suite/innodb/r/cursor-restore-locking.result index 6259cfd58ca..d834146e44e 100644 --- a/mysql-test/suite/innodb/r/cursor-restore-locking.result +++ b/mysql-test/suite/innodb/r/cursor-restore-locking.result @@ -1,5 +1,3 @@ -SET @save_freq=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB, STATS_PERSISTENT=0; InnoDB 0 transactions not purged connect prevent_purge,localhost,root,,; @@ -40,4 +38,3 @@ disconnect con_del_2; connection default; SET DEBUG_SYNC = 'RESET'; DROP TABLE t; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_freq; diff --git a/mysql-test/suite/innodb/r/dml_purge.result b/mysql-test/suite/innodb/r/dml_purge.result index 75a5f0fec6c..1ef8a5ea1b9 100644 --- a/mysql-test/suite/innodb/r/dml_purge.result +++ b/mysql-test/suite/innodb/r/dml_purge.result @@ -1,10 +1,9 @@ -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; # # MDEV-12288 Reset DB_TRX_ID when the history is removed, # to speed up MVCC # -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; CREATE TABLE t1(a INT PRIMARY KEY, b INT NOT NULL) ROW_FORMAT=REDUNDANT ENGINE=InnoDB; InnoDB 0 transactions not purged @@ -49,4 +48,4 @@ a b c 1 2 NULL 3 -3 NULL DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; 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 1e8914ffc49..c6fdc3231e0 100644 --- a/mysql-test/suite/innodb/r/fk_col_alter.result +++ b/mysql-test/suite/innodb/r/fk_col_alter.result @@ -91,4 +91,41 @@ CREATE TABLE t2 (b VARCHAR(8)) ENGINE=InnoDB; SET SESSION FOREIGN_KEY_CHECKS = ON; ALTER TABLE t2 MODIFY b VARCHAR(16), ADD KEY(b); DROP TABLE t1, t2; +# +# MDEV-32337 Assertion `pos < table->n_def' failed +# in dict_table_get_nth_col +# +CREATE TABLE t (a INT, va INT AS (a), b INT, vb INT AS (b), +c INT, vc INT AS (c), vf VARCHAR(16) AS (f), +f VARCHAR(4)) ENGINE=InnoDB; +ALTER TABLE t MODIFY f VARCHAR(8); +ALTER TABLE t MODIFY vf VARCHAR(18); +ERROR HY000: This is not yet supported for generated columns +DROP TABLE t; +# +# MDEV-32527 Server aborts during alter operation +# when table doesn't have foreign index +# +CREATE TABLE t1 (f1 INT NOT NULL, INDEX(f1)) ENGINE=InnoDB; +CREATE TABLE t2(f1 INT NOT NULL, f2 VARCHAR(100) DEFAULT NULL, +INDEX idx(f1, f2), +FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=INNODB; +SET SESSION FOREIGN_KEY_CHECKS = OFF; +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 a439f6d7981..808e2270e27 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -1,3 +1,4 @@ +SET GLOBAL innodb_stats_persistent = 0; # # Bug #19027905 ASSERT RET.SECOND DICT_CREATE_FOREIGN_CONSTRAINTS_LOW # DICT_CREATE_FOREIGN_CONSTR @@ -154,6 +155,8 @@ INSERT INTO parent SET a=0; FLUSH TABLES; # restart disconnect incomplete; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; INSERT INTO child SET a=0; INSERT INTO child SET a=1; ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) @@ -165,8 +168,6 @@ ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fail ALTER TABLE child FORCE; DELETE FROM parent; DROP TABLE child,parent; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; unique_constraint_name @@ -724,13 +725,14 @@ 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 test.t1 check status OK DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; # # MDEV-17187 table doesn't exist in engine after ALTER other tables # with CONSTRAINTs @@ -889,6 +891,42 @@ DROP INDEX fx ON t1; INSERT INTO t1 VALUES (2,11,11); DROP TABLE t1; SET FOREIGN_KEY_CHECKS=DEFAULT; +# +# MDEV-32018 Allow the setting of Auto_increment on FK referenced columns +# +CREATE TABLE t1 ( +id int unsigned NOT NULL PRIMARY KEY +); +CREATE TABLE t2 ( +id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, +t1_id int unsigned DEFAULT NULL, +CONSTRAINT FK_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) +); +ALTER TABLE t1 MODIFY id INT unsigned AUTO_INCREMENT; +DROP TABLE t1,t2; +# +# 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 @@ -1034,8 +1072,6 @@ DROP TABLE IF EXISTS t2, t1; # # MDEV-30531 Corrupt index(es) on busy table when using FOREIGN KEY # -SET @freq=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; CREATE TABLE collections ( id int(11) unsigned NOT NULL AUTO_INCREMENT, collectionhash varchar(255) NOT NULL DEFAULT '0', @@ -1061,7 +1097,7 @@ CHECK TABLE binaries, collections EXTENDED; Table Op Msg_type Msg_text test.binaries check status OK test.collections check status OK -SET GLOBAL innodb_purge_rseg_truncate_frequency=@freq; disconnect con1; DROP TABLE binaries, collections; # End of 10.6 tests +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/r/full_crc32_import.result b/mysql-test/suite/innodb/r/full_crc32_import.result index 32964be46d4..548e69c1c52 100644 --- a/mysql-test/suite/innodb/r/full_crc32_import.result +++ b/mysql-test/suite/innodb/r/full_crc32_import.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; FLUSH TABLES; # Treating compact format as dynamic format after import stmt CREATE TABLE t1 @@ -200,3 +202,4 @@ a 3 DROP TABLE t1; SET GLOBAL innodb_compression_algorithm=@save_algo; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/r/gap_lock_split.result b/mysql-test/suite/innodb/r/gap_lock_split.result index 7c10d8eed94..e607eda3dc9 100644 --- a/mysql-test/suite/innodb/r/gap_lock_split.result +++ b/mysql-test/suite/innodb/r/gap_lock_split.result @@ -1,5 +1,3 @@ -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023; @@ -29,4 +27,3 @@ disconnect con1; connection default; COMMIT; DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; 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..d30c5bddf30 --- /dev/null +++ b/mysql-test/suite/innodb/r/import_update_stats.result @@ -0,0 +1,66 @@ +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 1 NULL NULL YES BTREE NO +t1 1 idx2 1 col_2 A 1 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; 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/index_merge_threshold.result b/mysql-test/suite/innodb/r/index_merge_threshold.result index 989d31e90b1..83f7ab33f68 100644 --- a/mysql-test/suite/innodb/r/index_merge_threshold.result +++ b/mysql-test/suite/innodb/r/index_merge_threshold.result @@ -1,5 +1,5 @@ -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; CREATE TABLE tab(a BIGINT PRIMARY KEY,c1 TINYTEXT,c2 TEXT,c3 MEDIUMTEXT, c4 TINYBLOB,c5 BLOB,c6 MEDIUMBLOB,c7 LONGBLOB) ENGINE=InnoDB; CREATE INDEX index1 ON tab(c1(255)) COMMENT 'Check index level merge MERGE_THRESHOLD=51'; @@ -1309,4 +1309,4 @@ name count_reset index_page_merge_attempts 2 index_page_merge_successful 2 DROP TABLE tab1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/r/innodb-16k.result b/mysql-test/suite/innodb/r/innodb-16k.result index d46bea183c9..a7fbe8602e1 100644 --- a/mysql-test/suite/innodb/r/innodb-16k.result +++ b/mysql-test/suite/innodb/r/innodb-16k.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; call mtr.add_suppression("InnoDB: Cannot add field .* in table"); # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status @@ -9,9 +11,7 @@ variable_value # Each row format has its own amount of overhead that # varies depending on number of fields and other overhead. SET SESSION innodb_strict_mode = ON; -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; SET @save_level=@@GLOBAL.innodb_compression_level; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SET GLOBAL innodb_compression_level=1; CREATE TABLE t1 ( c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), @@ -506,8 +506,8 @@ ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); DROP TABLE t1; InnoDB 0 transactions not purged -SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; SET GLOBAL innodb_compression_level=@save_level; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; DROP TABLE tlong2; diff --git a/mysql-test/suite/innodb/r/innodb-32k.result b/mysql-test/suite/innodb/r/innodb-32k.result index 7dd1df8cfc5..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_purge_rseg_truncate_frequency=1; +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-tempfile.result b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result index 4475abab066..00a210b85d5 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result +++ b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result @@ -44,8 +44,6 @@ set DEBUG_SYNC="now WAIT_FOR default_signal"; # restart disconnect con1; SHOW KEYS 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 f1 1 f1 A # NULL NULL BTREE NO DROP TABLE t1; # # MDEV-25503 InnoDB hangs on startup during recovery diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result index 949bb9c8f24..353ad2b34dd 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-debug.result b/mysql-test/suite/innodb/r/innodb-index-debug.result index 426712631c0..d881f14034f 100644 --- a/mysql-test/suite/innodb/r/innodb-index-debug.result +++ b/mysql-test/suite/innodb/r/innodb-index-debug.result @@ -1,3 +1,7 @@ +SET GLOBAL innodb_max_purge_lag_wait=0; +connect stop_purge,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1)) Engine=InnoDB; SHOW CREATE TABLE t1; Table Create Table @@ -141,6 +145,7 @@ ERROR 23000: Duplicate entry '0' for key 'i' SET DEBUG_SYNC='now SIGNAL log2'; connection con1; disconnect con1; +disconnect stop_purge; connection default; SET DEBUG_SYNC='RESET'; 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-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 150f950d591..e4951d33681 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-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"); CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, c3 TEXT) ENGINE=InnoDB STATS_PERSISTENT=0; @@ -153,6 +155,7 @@ test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE size 1 NULL Number of pages in the connection con1; KILL QUERY @id; ERROR 70100: Query execution was interrupted +SET GLOBAL innodb_max_purge_lag_wait=0; SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2d_created WAIT_FOR kill_done'; CREATE INDEX c2d ON t1(c2); connection default; @@ -219,13 +222,13 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=1 connection default; 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; SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2e_created WAIT_FOR dml2_done'; @@ -272,13 +275,13 @@ name pos c2 0 c3 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)- @@ -318,16 +321,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'); connection con1; SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2f_created WAIT_FOR dml3_done'; @@ -403,16 +406,16 @@ ddl_sort_file_alter_table 0 ddl_log_file_alter_table 2 connection default; 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)- @@ -435,6 +438,7 @@ COUNT(c22f) CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK +SET GLOBAL innodb_max_purge_lag_wait=0; ALTER TABLE t1 ADD UNIQUE INDEX c3p5(c3(5)); ERROR 23000: Duplicate entry 'NULL' for key 'c3p5' UPDATE t1 SET c3 = NULL WHERE c3 = ''; 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..10995515eec --- /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 = @@transaction_isolation; +SET GLOBAL transaction_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 transaction_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 = @@transaction_isolation; +SET GLOBAL transaction_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 transaction_isolation = @old_tx_isolation; +SET GLOBAL innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_none.result b/mysql-test/suite/innodb/r/innodb-page_compression_none.result new file mode 100644 index 00000000000..58b2119e042 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-page_compression_none.result @@ -0,0 +1,18 @@ +# +# MDEV-30825 innodb_compression_algorithm=0 (none) increments Innodb_num_pages_page_compression_error +# +SET @save_compression_algorithm=@@GLOBAL.innodb_compression_algorithm; +SET GLOBAL innodb_compression_algorithm=0; +SELECT VARIABLE_VALUE INTO @compress_errors FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_num_pages_page_compression_error'; +CREATE TABLE t (c INT) page_compressed=1 page_compression_level=4 ENGINE=InnoDB; +INSERT INTO t VALUES (1); +FLUSH TABLES t FOR EXPORT; +UNLOCK TABLES; +SELECT VARIABLE_VALUE - @compress_errors AS NUMBER_OF_ERRORS FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_num_pages_page_compression_error'; +NUMBER_OF_ERRORS +0 +DROP TABLE t; +SET GLOBAL innodb_compression_algorithm=@save_compression_algorithm; +# +# End of 10.4 tests +# 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-system-table-view.result b/mysql-test/suite/innodb/r/innodb-system-table-view.result index dfe916bc6cd..ab1d6bc89db 100644 --- a/mysql-test/suite/innodb/r/innodb-system-table-view.result +++ b/mysql-test/suite/innodb/r/innodb-system-table-view.result @@ -1,5 +1,5 @@ -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; SELECT table_id INTO @table_stats_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/innodb_table_stats'; SELECT table_id INTO @index_stats_id FROM information_schema.innodb_sys_tables @@ -171,7 +171,6 @@ name num_rows ref_count test/parent 1 2 DROP TABLE child; DROP TABLE parent; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; # # MDEV-29479 I_S.INNODB_SYS_TABLESPACES doesn't have # temporary tablespace information @@ -179,3 +178,4 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; SELECT SPACE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE name like 'innodb_temporary'; SPACE 4294967294 +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result index e1b67edbd9a..6948038a76c 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"); @@ -171,13 +173,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; @@ -229,13 +231,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)- @@ -255,17 +257,18 @@ 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'; ALTER TABLE t1 ADD PRIMARY KEY(c22f), CHANGE c2 c22f INT; ERROR 42000: Multiple primary key defined @@ -311,16 +314,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-wl5522-1.result b/mysql-test/suite/innodb/r/innodb-wl5522-1.result index 204d6bc8b78..42c0631dd29 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-1.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-1.result @@ -808,6 +808,18 @@ call mtr.add_suppression("InnoDB: unsupported MySQL tablespace"); ALTER TABLE t1 IMPORT TABLESPACE; ERROR 42000: Table 't1' uses an extension that doesn't exist in this MariaDB version DROP TABLE t1; -# # End of 10.3 tests # +# MDEV-29972 crash after "Unsupported meta-data version number" +# +call mtr.add_suppression("Index for table 't2' is corrupt"); +CREATE TABLE t2 (i INT PRIMARY KEY) ENGINE=InnoDB; +ALTER TABLE t2 DISCARD TABLESPACE; +ALTER TABLE t2 IMPORT TABLESPACE; +ERROR 42000: This version of MariaDB doesn't yet support 'meta-data version' +ALTER TABLE t2 IMPORT TABLESPACE; +ERROR HY000: Index for table 't2' is corrupt; try to repair it +SELECT * FROM t2; +ERROR HY000: Tablespace has been discarded for table `t2` +DROP TABLE t2; +# End of 10.4 tests diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 6e24bce0844..f1cf23d6eaf 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -2486,7 +2486,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_buffer_pool_dump_pct.result b/mysql-test/suite/innodb/r/innodb_buffer_pool_dump_pct.result index fa17487df97..33adf9baebb 100644 --- a/mysql-test/suite/innodb/r/innodb_buffer_pool_dump_pct.result +++ b/mysql-test/suite/innodb/r/innodb_buffer_pool_dump_pct.result @@ -3,17 +3,8 @@ col2 VARCHAR(25), col3 varchar(25)) ENGINE=InnoDB; CREATE INDEX idx1 ON tab5(col2(10)); CREATE INDEX idx2 ON tab5(col3(10)); SET GLOBAL innodb_buffer_pool_dump_pct=100; -SELECT variable_value INTO @IBPDS -FROM information_schema.global_status -WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS'; SET GLOBAL innodb_buffer_pool_dump_now=ON; SET GLOBAL innodb_buffer_pool_dump_pct=1; -SELECT @@global.innodb_buffer_pool_dump_pct; -@@global.innodb_buffer_pool_dump_pct -1 -SELECT variable_value INTO @IBPDS -FROM information_schema.global_status -WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS'; SET GLOBAL innodb_buffer_pool_dump_now=ON; SET GLOBAL innodb_buffer_pool_dump_pct=DEFAULT; DROP TABLE tab5; 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_bug14147491.result b/mysql-test/suite/innodb/r/innodb_bug14147491.result index b33b7f0d587..77d53183d92 100644 --- a/mysql-test/suite/innodb/r/innodb_bug14147491.result +++ b/mysql-test/suite/innodb/r/innodb_bug14147491.result @@ -1,5 +1,4 @@ # Ensure that purge will not crash on the table after we corrupt it. -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SET GLOBAL innodb_fast_shutdown=0; # Create and populate the table to be corrupted CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb/r/innodb_bug84958.result b/mysql-test/suite/innodb/r/innodb_bug84958.result index 9a4129647b9..3375efb9184 100644 --- a/mysql-test/suite/innodb/r/innodb_bug84958.result +++ b/mysql-test/suite/innodb/r/innodb_bug84958.result @@ -4,8 +4,6 @@ # # Set up the test with a procedure and a function. # -SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency= 1; CREATE PROCEDURE insert_n(start int, end int) BEGIN DECLARE i INT DEFAULT start; @@ -84,7 +82,6 @@ test.t1 check status OK # disconnect con2; disconnect con3; -SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; DROP TABLE t1; DROP PROCEDURE insert_n; DROP FUNCTION num_pages_get; diff --git a/mysql-test/suite/innodb/r/innodb_ctype_utf8.result b/mysql-test/suite/innodb/r/innodb_ctype_utf8.result index 3ce1d3a1d53..d817af2735c 100644 --- a/mysql-test/suite/innodb/r/innodb_ctype_utf8.result +++ b/mysql-test/suite/innodb/r/innodb_ctype_utf8.result @@ -379,5 +379,101 @@ INSERT INTO t1 VALUES ('ss '); INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/; DROP TABLE t1; # +# MDEV-30048 Prefix keys for CHAR work differently for MyISAM vs InnoDB +# +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(2))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`(2)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(120) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(120) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`(100)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +# +# MDEV-30050 Inconsistent results of DISTINCT with NOPAD +# +CREATE TABLE t1 (c CHAR(100) COLLATE utf8mb3_unicode_nopad_ci); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +SET big_tables=0; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +SET big_tables=1; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +DROP TABLE t1; +SET big_tables=DEFAULT; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +# +# MDEV-30050 Inconsistent results of DISTINCT with NOPAD +# +CREATE OR REPLACE TABLE t1 (c CHAR(100) COLLATE utf8mb3_unicode_nopad_ci); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 VALUES ('ss'),('ß'); +SET big_tables=0; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +SET big_tables=1; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +DROP TABLE t1; +SET big_tables=DEFAULT; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +# # End 10.4 tests # diff --git a/mysql-test/suite/innodb/r/innodb_force_recovery.result b/mysql-test/suite/innodb/r/innodb_force_recovery.result index 05239950678..2f1169f4147 100644 --- a/mysql-test/suite/innodb/r/innodb_force_recovery.result +++ b/mysql-test/suite/innodb/r/innodb_force_recovery.result @@ -4,9 +4,18 @@ insert into t1 values(1, 2); insert into t2 values(1, 2); SET GLOBAL innodb_fast_shutdown = 0; # restart: --innodb-force-recovery=4 +SELECT CAST(variable_value AS INTEGER) INTO @read1 +FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME='innodb_buffer_pool_read_requests'; select * from t1; f1 f2 1 2 +SELECT CAST(variable_value AS INTEGER) INTO @read2 +FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME='innodb_buffer_pool_read_requests'; +SELECT @read1>0, @read2>@read1; +@read1>0 @read2>@read1 +1 1 begin; insert into t1 values(2, 3); rollback; 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_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 18814e26c82..697ed2e36ae 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2385,6 +2385,10 @@ key_len NULL ref NULL rows 6 Extra Using where +Warnings: +Level Note +Code 1105 +Message Cannot use key `PRIMARY` part[0] for lookup: `test`.`bar`.`c` of type `char` > "2" of type `int` EXPLAIN SELECT c FROM foo WHERE c>2;; id 1 select_type SIMPLE @@ -2396,6 +2400,10 @@ key_len NULL ref NULL rows 6 Extra Using where +Warnings: +Level Note +Code 1105 +Message Cannot use key `PRIMARY` part[0] for lookup: `test`.`foo`.`c` of type `char` > "2" of type `int` EXPLAIN SELECT c FROM foo2 WHERE c>2;; id 1 select_type SIMPLE @@ -2407,6 +2415,10 @@ key_len 5 ref NULL rows 6 Extra Using where; Using index +Warnings: +Level Note +Code 1105 +Message Cannot use key `PRIMARY` part[0] for lookup: `test`.`foo2`.`c` of type `char` > "2" of type `int` DROP TABLE foo, bar, foo2; # # Bug#41348: INSERT INTO tbl SELECT * FROM temp_tbl overwrites locking type of temp table diff --git a/mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result b/mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result index 1e97c21c253..1ccf79e4517 100644 --- a/mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result +++ b/mysql-test/suite/innodb/r/innodb_prefix_index_restart_server.result @@ -90,3 +90,19 @@ worklog5743; col_1_text = REPEAT("a", 3500) col_2_text = REPEAT("o", 3500) 1 1 DROP TABLE worklog5743; +# +# MDEV-21245 InnoDB: Using a partial-field key prefix in search +# +CREATE TABLE t1 (a VARCHAR(255), KEY k(a)) DEFAULT CHARSET=utf8mb3 +ENGINE=InnoDB; +INSERT INTO t1 set a=''; +alter table t1 change a a varchar(3000); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Note 1071 Specified key was too long; max key length is 3072 bytes +SELECT * FROM t1 WHERE a IN (''); +a + +DROP TABLE t1; +# End of 10.4 tests diff --git a/mysql-test/suite/innodb/r/innodb_scrub.result b/mysql-test/suite/innodb/r/innodb_scrub.result index f824a1d0858..eba4984fb83 100644 --- a/mysql-test/suite/innodb/r/innodb_scrub.result +++ b/mysql-test/suite/innodb/r/innodb_scrub.result @@ -1,6 +1,6 @@ CREATE TABLE t1(f1 int auto_increment primary key, f2 varchar(256), -f3 text) engine = innodb; +f3 text) engine = innodb stats_persistent=0; FLUSH TABLE t1 FOR EXPORT; UNLOCK TABLES; FOUND 500500 /unicycle|repairman/ in t1.ibd diff --git a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result index 8cc2a11545f..c53707d5997 100644 --- a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result +++ b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result @@ -48,7 +48,7 @@ lock_rec_locks lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 coun lock_table_lock_created lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of table locks created lock_table_lock_removed lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of table locks removed from the lock queue lock_table_locks lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Current number of table locks on tables -lock_row_lock_current_waits lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of row locks currently being waited for (innodb_row_lock_current_waits) +lock_row_lock_current_waits lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of row locks currently being waited for (innodb_row_lock_current_waits) lock_row_lock_time lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Time spent in acquiring row locks, in milliseconds (innodb_row_lock_time) lock_row_lock_time_max lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value The maximum time to acquire a row lock, in milliseconds (innodb_row_lock_time_max) lock_row_lock_waits lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of times a row lock had to be waited for (innodb_row_lock_waits) 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 6df1831db48..2a68bc4c070 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 e25ab2a8a24..4ce1b59e0ba 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_persistent.result +++ b/mysql-test/suite/innodb/r/innodb_stats_persistent.result @@ -1,5 +1,3 @@ -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SET @saved_include_delete_marked = @@GLOBAL.innodb_stats_include_delete_marked; SET GLOBAL innodb_stats_include_delete_marked = ON; SET @saved_traditional = @@GLOBAL.innodb_stats_traditional; @@ -10,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; @@ -59,7 +57,7 @@ connection con1; EXPLAIN SELECT * FROM t2 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref val val 4 const 1 Using index -InnoDB 0 transactions not purged +SET GLOBAL innodb_max_purge_lag_wait=0; # After COMMIT and purge, the DELETE must show up. EXPLAIN SELECT * FROM t1 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra @@ -91,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 @@ -105,4 +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; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +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/instant_alter,4k.rdiff b/mysql-test/suite/innodb/r/instant_alter,4k.rdiff index a885eb260d6..ab12a24663e 100644 --- a/mysql-test/suite/innodb/r/instant_alter,4k.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter,4k.rdiff @@ -312,12 +312,11 @@ connection default; InnoDB 0 transactions not purged DROP TABLE t1,t2,t3,t4,big; -@@ -2836,7 +2868,7 @@ +@@ -2836,6 +2868,6 @@ FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants -209 +211 - SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; SET GLOBAL innodb_instant_alter_column_allowed = @saved_allowance; # diff --git a/mysql-test/suite/innodb/r/instant_alter.result b/mysql-test/suite/innodb/r/instant_alter.result index 18680432c77..55bb921c27b 100644 --- a/mysql-test/suite/innodb/r/instant_alter.result +++ b/mysql-test/suite/innodb/r/instant_alter.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; # # MDEV-11369: Instant ADD COLUMN for InnoDB # @@ -52,8 +54,6 @@ connect analyze, localhost, root; connection default; SET timestamp = 42; SET time_zone='+03:00'; -SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SET @old_instant= (SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'); @@ -2873,7 +2873,6 @@ FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants 209 -SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; SET GLOBAL innodb_instant_alter_column_allowed = @saved_allowance; # # MDEV-18266: Changing an index comment unnecessarily rebuilds index @@ -2940,3 +2939,4 @@ index(id, msg) FLUSH TABLES; ALTER TABLE mdev28822_100427_innodb ADD i1 INTEGER, ALGORITHM=INSTANT; DROP TABLE mdev28822_100427_innodb; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/r/instant_alter_bugs.result b/mysql-test/suite/innodb/r/instant_alter_bugs.result index f56938550ac..1183618f992 100644 --- a/mysql-test/suite/innodb/r/instant_alter_bugs.result +++ b/mysql-test/suite/innodb/r/instant_alter_bugs.result @@ -1,5 +1,5 @@ -SET @save_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; # # MDEV-17821 Assertion `!page_rec_is_supremum(rec)' failed # in btr_pcur_store_position @@ -208,7 +208,6 @@ DROP TABLE t1; # MDEV-23801 Assertion index->table->instant... failed # in btr_pcur_store_position() # -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; CREATE TABLE t ( pk int auto_increment, c01 char(255) not null default repeat('a',255), @@ -232,7 +231,6 @@ INSERT INTO t () VALUES (),(); ROLLBACK; DELETE FROM t; InnoDB 0 transactions not purged -SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; CREATE TABLE tt ENGINE=InnoDB AS SELECT c FROM t; DROP TABLE t, tt; # End of 10.3 tests @@ -489,11 +487,36 @@ ALTER TABLE t1 ADD COLUMN(f2 INT NOT NULL, f3 INT NOT NULL, f4 INT NOT NULL, f5 INT NOT NULL), CHANGE COLUMN f1 f1 CHAR(10) DEFAULT NULL; DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; # # MDEV-26420 Buffer overflow on instant ADD/DROP of generated column # CREATE TABLE t1 (i int AS (0) STORED, j INT) ENGINE=InnoDB; ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS (1), DROP COLUMN i; DROP TABLE t1; +# +# MDEV-18322 Assertion "wrong_page_type" on instant ALTER +# +BEGIN NOT ATOMIC +DECLARE c TEXT +DEFAULT(SELECT CONCAT('CREATE TABLE t1 (c', +GROUP_CONCAT(seq SEPARATOR ' CHAR(200), c'), +' CHAR(211)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT') +FROM seq_1_to_40); +EXECUTE IMMEDIATE c; +END; +$$ +INSERT INTO t1 SET c1=NULL; +ALTER TABLE t1 ADD c41 INT FIRST; +ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8123. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs +ALTER TABLE t1 ADD c41 INT FIRST; +ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8123. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +DROP TABLE t1; # End of 10.4 tests +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; +# End of 10.6 tests diff --git a/mysql-test/suite/innodb/r/instant_alter_crash.result b/mysql-test/suite/innodb/r/instant_alter_crash.result index 7855aa24264..e423afe10a8 100644 --- a/mysql-test/suite/innodb/r/instant_alter_crash.result +++ b/mysql-test/suite/innodb/r/instant_alter_crash.result @@ -3,7 +3,7 @@ FLUSH TABLES; # MDEV-11369: Instant ADD COLUMN for InnoDB # CREATE TABLE t1(id INT PRIMARY KEY, c2 INT UNIQUE) -ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=REDUNDANT; CREATE TABLE t2 LIKE t1; INSERT INTO t1 VALUES(0,2); INSERT INTO t2 VALUES(2,1); @@ -20,7 +20,6 @@ COMMIT; # Kill the server disconnect ddl; # restart -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SELECT * FROM t1; id c2 0 2 @@ -46,8 +45,6 @@ COMMIT; # Kill the server disconnect ddl; # restart -SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SELECT * FROM t1; id c2 0 3 @@ -76,7 +73,6 @@ COMMIT; # Kill the server disconnect ddl; # restart -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; FOUND 3 /\[Note\] InnoDB: Rolled back recovered transaction / in mysqld.1.err SELECT * FROM t1; id c2 @@ -164,7 +160,7 @@ t1 CREATE TABLE `t1` ( `c2` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `c2` (`c2`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0 ROW_FORMAT=REDUNDANT SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( @@ -172,7 +168,7 @@ t2 CREATE TABLE `t2` ( `c2` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `c2` (`c2`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0 ROW_FORMAT=REDUNDANT SHOW CREATE TABLE t3; Table Create Table t3 CREATE TABLE `t3` ( diff --git a/mysql-test/suite/innodb/r/instant_alter_debug,redundant.rdiff b/mysql-test/suite/innodb/r/instant_alter_debug,redundant.rdiff index cff4ff18c70..f442e406ce4 100644 --- a/mysql-test/suite/innodb/r/instant_alter_debug,redundant.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_debug,redundant.rdiff @@ -1,6 +1,8 @@ -@@ -527,4 +527,4 @@ +@@ -527,6 +527,6 @@ FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants -35 +36 + SET GLOBAL innodb_stats_persistent = @save_stats_persistent; + # End of 10.6 tests diff --git a/mysql-test/suite/innodb/r/instant_alter_debug.result b/mysql-test/suite/innodb/r/instant_alter_debug.result index e7f956df13c..ca69cfadcfd 100644 --- a/mysql-test/suite/innodb/r/instant_alter_debug.result +++ b/mysql-test/suite/innodb/r/instant_alter_debug.result @@ -1,5 +1,5 @@ -SET @save_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; SET @old_instant= (SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'); @@ -515,9 +515,10 @@ test.t1 check status OK DROP TABLE t1; SET DEBUG_SYNC=RESET; # End of 10.5 tests -SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; SELECT variable_value-@old_instant instants FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants 35 +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; +# End of 10.6 tests diff --git a/mysql-test/suite/innodb/r/instant_alter_purge,release.rdiff b/mysql-test/suite/innodb/r/instant_alter_purge,release.rdiff index 8722b724c6e..23f6c9154ef 100644 --- a/mysql-test/suite/innodb/r/instant_alter_purge,release.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_purge,release.rdiff @@ -1,6 +1,6 @@ --- instant_alter_purge.result +++ instant_alter_purge,release.result -@@ -32,16 +32,11 @@ +@@ -32,15 +32,10 @@ START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; DELETE FROM t1; @@ -16,4 +16,3 @@ connection default; -SET DEBUG_SYNC=RESET; DROP TABLE t1; - SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/innodb/r/instant_alter_purge.result b/mysql-test/suite/innodb/r/instant_alter_purge.result index 261356bad12..4163bf3fdba 100644 --- a/mysql-test/suite/innodb/r/instant_alter_purge.result +++ b/mysql-test/suite/innodb/r/instant_alter_purge.result @@ -1,5 +1,3 @@ -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; InnoDB 0 transactions not purged # # MDEV-17793 Crash in purge after instant DROP and emptying the table @@ -7,7 +5,7 @@ InnoDB 0 transactions not purged connect prevent_purge,localhost,root; START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; -CREATE TABLE t1 (f1 INT, f2 INT) ENGINE=InnoDB; +CREATE TABLE t1 (f1 INT, f2 INT) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1 () VALUES (); ALTER TABLE t1 DROP f2, ADD COLUMN f2 INT; ALTER TABLE t1 DROP f1; @@ -22,4 +20,3 @@ ALTER TABLE t1 DROP extra; disconnect prevent_purge; InnoDB 0 transactions not purged DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/innodb/r/instant_alter_rollback.result b/mysql-test/suite/innodb/r/instant_alter_rollback.result index b51e067c647..6e84580c672 100644 --- a/mysql-test/suite/innodb/r/instant_alter_rollback.result +++ b/mysql-test/suite/innodb/r/instant_alter_rollback.result @@ -1,3 +1,4 @@ +SET GLOBAL innodb_stats_persistent = 0; FLUSH TABLES; # # MDEV-11369: Instant ADD COLUMN for InnoDB @@ -47,11 +48,8 @@ CREATE TABLE foo(a INT PRIMARY KEY) ENGINE=InnoDB; # Kill the server disconnect to_be_killed; # restart -SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; DROP TABLE foo; InnoDB 0 transactions not purged -SET GLOBAL innodb_purge_rseg_truncate_frequency=@saved_frequency; SELECT * FROM empty; id c2 d1 SELECT * FROM once; diff --git a/mysql-test/suite/innodb/r/mem_pressure.result b/mysql-test/suite/innodb/r/mem_pressure.result new file mode 100644 index 00000000000..b1127db8673 --- /dev/null +++ b/mysql-test/suite/innodb/r/mem_pressure.result @@ -0,0 +1,25 @@ +# +# MDEV-24670 avoid OOM by linux kernel co-operative memory management +# +set @save_dbug=@@debug_dbug; +set @save_limit=@@GLOBAL.innodb_limit_optimistic_insert_debug; +set GLOBAL innodb_max_purge_lag_wait=0; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +SET GLOBAL innodb_limit_optimistic_insert_debug=2; +SET STATEMENT unique_checks=0, foreign_key_checks=0 FOR +INSERT INTO t1 SELECT * FROM seq_1_to_1000; +SET GLOBAL innodb_limit_optimistic_insert_debug=@save_limit; +DROP TABLE t1; +SELECT CAST(VARIABLE_VALUE AS INTEGER) INTO @dirty_prev +FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty'; +set debug_dbug="d,trigger_garbage_collection"; +SET GLOBAL innodb_buffer_pool_size=@@innodb_buffer_pool_size; +SELECT CAST(VARIABLE_VALUE AS INTEGER) < @dirty_prev AS LESS_DIRTY_IS_GOOD +FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty'; +LESS_DIRTY_IS_GOOD +1 +FOUND 1 /InnoDB: Memory pressure event freed.*/ in mysqld.1.err +set debug_dbug=@save_dbug; +# End of 10.11 tests diff --git a/mysql-test/suite/innodb/r/mon_lock_wait_current_count.result b/mysql-test/suite/innodb/r/mon_lock_wait_current_count.result new file mode 100644 index 00000000000..442baeca3f5 --- /dev/null +++ b/mysql-test/suite/innodb/r/mon_lock_wait_current_count.result @@ -0,0 +1,54 @@ +connect prevent_purge,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +SET GLOBAL innodb_monitor_disable='lock_row_lock_time_avg'; +CREATE TABLE `t` (a INT PRIMARY KEY) engine=InnoDB STATS_PERSISTENT=0; +INSERT INTO t VALUES (5); +SELECT name, count FROM information_schema.innodb_metrics +WHERE name ='lock_row_lock_current_waits'; +name count +lock_row_lock_current_waits 0 +connect con1,localhost,root,,; +BEGIN; +SELECT * FROM t FOR UPDATE; +a +5 +connect con2,localhost,root,,; +SET DEBUG_SYNC="lock_wait_before_suspend SIGNAL blocked WAIT_FOR cont"; +BEGIN; +SELECT * FROM t FOR UPDATE; +connection default; +SET DEBUG_SYNC="now WAIT_FOR blocked"; +SELECT name, count FROM information_schema.innodb_metrics +WHERE name ='lock_row_lock_current_waits'; +name count +lock_row_lock_current_waits 1 +SET GLOBAL innodb_monitor_disable='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_reset_all='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_enable='lock_row_lock_current_waits'; +SELECT name, count FROM information_schema.innodb_metrics +WHERE name ='lock_row_lock_current_waits'; +name count +lock_row_lock_current_waits 1 +SET DEBUG_SYNC="now SIGNAL cont"; +disconnect con1; +connection con2; +a +5 +COMMIT; +disconnect con2; +connection default; +SET DEBUG_SYNC="reset"; +SELECT name, count FROM information_schema.innodb_metrics +WHERE name ='lock_row_lock_current_waits'; +name count +lock_row_lock_current_waits 0 +DROP TABLE `t`; +SET GLOBAL innodb_monitor_disable='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_reset_all='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_enable='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_enable='lock_row_lock_time_avg'; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; +SET GLOBAL innodb_monitor_enable=default; +disconnect prevent_purge; 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/page_id_innochecksum.result b/mysql-test/suite/innodb/r/page_id_innochecksum.result index 7a5f44b21e6..bde986c07ef 100644 --- a/mysql-test/suite/innodb/r/page_id_innochecksum.result +++ b/mysql-test/suite/innodb/r/page_id_innochecksum.result @@ -1,9 +1,8 @@ # Set the environmental variables -create table t1(f1 int not null)engine=innodb; +create table t1(f1 int not null)engine=innodb stats_persistent=0; insert into t1 values(1), (2), (3); # Change the page offset FOUND 1 /page id mismatch/ in result.log -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; InnoDB 0 transactions not purged drop table t1; call mtr.add_suppression("InnoDB: Failed to read page 3 from file '.*test/t1\\.ibd': Page read from tablespace is corrupted\\."); diff --git a/mysql-test/suite/innodb/r/purge.result b/mysql-test/suite/innodb/r/purge.result index a71d0afdcbe..9284fa18a7d 100644 --- a/mysql-test/suite/innodb/r/purge.result +++ b/mysql-test/suite/innodb/r/purge.result @@ -1,5 +1,5 @@ -SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; # Bug #12429576 - Test an assertion failure on purge. CREATE TABLE t1_purge ( A int, @@ -117,5 +117,5 @@ t12963823 CREATE TABLE `t12963823` ( KEY `ndx_p` (`p`(500)) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC InnoDB 0 transactions not purged +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge, t12637786, t12963823; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; diff --git a/mysql-test/suite/innodb/r/purge_secondary.result b/mysql-test/suite/innodb/r/purge_secondary.result index 6c0612c7cfe..70d16f1f505 100644 --- a/mysql-test/suite/innodb/r/purge_secondary.result +++ b/mysql-test/suite/innodb/r/purge_secondary.result @@ -1,5 +1,5 @@ -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; CREATE TABLE t1 ( a SERIAL, b CHAR(255) NOT NULL DEFAULT '', c BOOLEAN DEFAULT false, l LINESTRING NOT NULL DEFAULT ST_linefromtext('linestring(448 -689, @@ -169,4 +169,5 @@ page 5: N_RECS=0x0001 UNLOCK TABLES; DROP TABLE t1; # End of 10.3 tests -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; +# End of 10.6 tests 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 747fe91c966..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; -Got one of the listed errors -# restart -drop table t1; diff --git a/mysql-test/suite/innodb/r/read_only_recovery.result b/mysql-test/suite/innodb/r/read_only_recovery.result index add0da94cab..2cde58189d5 100644 --- a/mysql-test/suite/innodb/r/read_only_recovery.result +++ b/mysql-test/suite/innodb/r/read_only_recovery.result @@ -37,6 +37,8 @@ SELECT * FROM t; a 3 SET GLOBAL innodb_max_purge_lag_wait=0; +INSERT INTO mysql.innodb_index_stats +SELECT * FROM mysql.innodb_index_stats LIMIT 0; # restart SELECT * FROM t; a 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/row_format_redundant.result b/mysql-test/suite/innodb/r/row_format_redundant.result index f0286381809..04101ae98ec 100644 --- a/mysql-test/suite/innodb/r/row_format_redundant.result +++ b/mysql-test/suite/innodb/r/row_format_redundant.result @@ -41,14 +41,14 @@ TRUNCATE TABLE t2; ERROR HY000: Table 't2' is read only TRUNCATE TABLE t3; ERROR HY000: Table 't3' is read only -# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 +# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown TRUNCATE TABLE t1; TRUNCATE TABLE t2; TRUNCATE TABLE t3; corrupted SYS_TABLES.MIX_LEN for test/t1 corrupted SYS_TABLES.MIX_LEN for test/t2 corrupted SYS_TABLES.MIX_LEN for test/t3 -# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 +# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown TRUNCATE TABLE t1; ERROR 42S02: Table 'test.t1' doesn't exist in engine TRUNCATE TABLE t2; @@ -69,7 +69,6 @@ Warning 1932 Table 'test.t1' doesn't exist in engine DROP TABLE t2,t3; FOUND 1 /\[ERROR\] InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b.*/ in mysqld.1.err # restart -ib_buffer_pool ib_logfile0 ibdata1 db.opt diff --git a/mysql-test/suite/innodb/r/scrub.result b/mysql-test/suite/innodb/r/scrub.result index 4c14088f429..5b8dd17d871 100644 --- a/mysql-test/suite/innodb/r/scrub.result +++ b/mysql-test/suite/innodb/r/scrub.result @@ -1,6 +1,5 @@ SET GLOBAL innodb_file_per_table=OFF, -innodb_purge_rseg_truncate_frequency=1, innodb_immediate_scrub_data_uncompressed=ON; Warnings: Warning 1287 '@@innodb_file_per_table' is deprecated and will be removed in a future release diff --git a/mysql-test/suite/innodb/r/scrub_debug.result b/mysql-test/suite/innodb/r/scrub_debug.result index 5fbf1250b21..7b0a9fd501c 100644 --- a/mysql-test/suite/innodb/r/scrub_debug.result +++ b/mysql-test/suite/innodb/r/scrub_debug.result @@ -1,12 +1,10 @@ SET @save_debug=@@GLOBAL.INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG; SET @save_scrub=@@GLOBAL.INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED; -SET @save_freq=@@GLOBAL.INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY; -SET GLOBAL INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY=1; SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=1; SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=2; CREATE TABLE t1(f1 INT AUTO_INCREMENT PRIMARY KEY, f2 VARCHAR(256) GENERATED ALWAYS as('repairman'), -INDEX idx(f2))ENGINE= InnoDB; +INDEX idx(f2))ENGINE= InnoDB STATS_PERSISTENT=0; INSERT INTO t1(f1) SELECT seq FROM seq_1_to_50; FLUSH TABLE t1 FOR EXPORT; FOUND 108 /repairman/ in t1.ibd @@ -19,4 +17,3 @@ UNLOCK TABLES; DROP TABLE t1; SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=@save_debug; SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=@save_scrub; -SET GLOBAL INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY = @save_freq; diff --git a/mysql-test/suite/innodb/r/sys_truncate_shutdown.result b/mysql-test/suite/innodb/r/sys_truncate_shutdown.result new file mode 100644 index 00000000000..ee567a76fb1 --- /dev/null +++ b/mysql-test/suite/innodb/r/sys_truncate_shutdown.result @@ -0,0 +1,23 @@ +SET GLOBAL innodb_fast_shutdown=0; +# restart +SET GLOBAL INNODB_FILE_PER_TABLE= 0; +Warnings: +Warning 1287 '@@innodb_file_per_table' is deprecated and will be removed in a future release +SET UNIQUE_CHECKS=0, FOREIGN_KEY_CHECKS=0; +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, +f3 INT NOT NULL, INDEX(f1), +INDEX(f2), INDEX(f3))ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +COMMIT; +DROP TABLE t1; +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; +NAME FILE_SIZE +innodb_system 70254592 +SET GLOBAL innodb_fast_shutdown=0; +# restart +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; +NAME FILE_SIZE +innodb_system 3145728 diff --git a/mysql-test/suite/innodb/r/sys_truncate_shutdown_debug.result b/mysql-test/suite/innodb/r/sys_truncate_shutdown_debug.result new file mode 100644 index 00000000000..0aad5af9cb6 --- /dev/null +++ b/mysql-test/suite/innodb/r/sys_truncate_shutdown_debug.result @@ -0,0 +1,41 @@ +call mtr.add_suppression("InnoDB: Cannot shrink the system tablespace"); +call mtr.add_suppression("InnoDB: Plugin initialization aborted"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error"); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); +SET GLOBAL innodb_fast_shutdown=0; +# restart +SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=2; +SET GLOBAL INNODB_FILE_PER_TABLE= 0; +Warnings: +Warning 1287 '@@innodb_file_per_table' is deprecated and will be removed in a future release +SET UNIQUE_CHECKS=0, FOREIGN_KEY_CHECKS=0; +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, +f3 INT NOT NULL, INDEX(f1), +INDEX(f2), INDEX(f3))ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +COMMIT; +DROP TABLE t1; +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; +NAME FILE_SIZE +innodb_system 540016640 +SET GLOBAL INNODB_FAST_SHUTDOWN=0; +SET GLOBAL DEBUG_DBUG="+d,shrink_buffer_pool_full"; +# restart +FOUND 1 /\[Warning\] InnoDB: Cannot shrink the system tablespace/ in mysqld.1.err +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; +NAME FILE_SIZE +innodb_system 540016640 +SET GLOBAL INNODB_FAST_SHUTDOWN=0; +SET GLOBAL DEBUG_DBUG="+d,mtr_log_max_size"; +# restart +FOUND 1 /\[ERROR\] InnoDB: Cannot shrink the system tablespace/ in mysqld.1.err +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; +NAME FILE_SIZE +innodb_system 540016640 +SET GLOBAL INNODB_FAST_SHUTDOWN=0; +# restart: --debug_dbug=+d,crash_after_sys_truncate +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; +NAME FILE_SIZE +innodb_system 3145728 diff --git a/mysql-test/suite/innodb/r/table_flags.result b/mysql-test/suite/innodb/r/table_flags.result index e421126d2eb..e38eb93e781 100644 --- a/mysql-test/suite/innodb/r/table_flags.result +++ b/mysql-test/suite/innodb/r/table_flags.result @@ -100,13 +100,9 @@ ERROR 42S02: Table 'test.tc' doesn't exist in engine SELECT * FROM tc; ERROR 42S02: Table 'test.tc' doesn't exist in engine SHOW CREATE TABLE td; -Table Create Table -td CREATE TABLE `td` ( - `a` int(11) NOT NULL, - PRIMARY KEY (`a`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +ERROR HY000: Got error 194 "Tablespace is missing for a table" from storage engine InnoDB SELECT * FROM td; -a +ERROR HY000: Got error 194 "Tablespace is missing for a table" from storage engine InnoDB SHOW CREATE TABLE tz; Table Create Table tz CREATE TABLE `tz` ( @@ -121,8 +117,8 @@ a 42 SHOW CREATE TABLE tp; ERROR 42S02: Table 'test.tp' doesn't exist in engine -FOUND 5 /InnoDB: Table test/t[cp] in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649/ in mysqld.1.err -FOUND 2 /InnoDB: Table test/tr in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b/ in mysqld.1.err +FOUND 3 /InnoDB: Table test/t[cp] in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649/ in mysqld.1.err +FOUND 1 /InnoDB: Table test/tr in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b/ in mysqld.1.err Restoring SYS_TABLES clustered index root page (8) # restart: with restart_parameters SHOW CREATE TABLE tr; 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/r/truncate_crash.result b/mysql-test/suite/innodb/r/truncate_crash.result index ae3e6f6f4bf..7df461ec3a7 100644 --- a/mysql-test/suite/innodb/r/truncate_crash.result +++ b/mysql-test/suite/innodb/r/truncate_crash.result @@ -1,5 +1,5 @@ FLUSH TABLES; -CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1 VALUES (1),(2); connect wait,localhost,root,,test; SET DEBUG_SYNC='before_trx_state_committed_in_memory SIGNAL c WAIT_FOR ever'; @@ -8,10 +8,7 @@ connection default; SET DEBUG_SYNC='now WAIT_FOR c'; # restart disconnect wait; -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; InnoDB 0 transactions not purged -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; SELECT COUNT(*) FROM t1; COUNT(*) 0 diff --git a/mysql-test/suite/innodb/r/truncate_foreign.result b/mysql-test/suite/innodb/r/truncate_foreign.result index e587baa5288..e001e3ba507 100644 --- a/mysql-test/suite/innodb/r/truncate_foreign.result +++ b/mysql-test/suite/innodb/r/truncate_foreign.result @@ -77,25 +77,26 @@ DROP TABLE t1; call mtr.add_suppression("InnoDB: In ALTER TABLE `test`\\.`t1` has or is"); CREATE TABLE t1 (pk INT, a INT, PRIMARY KEY (pk), KEY (a)) ENGINE=InnoDB; SET FOREIGN_KEY_CHECKS=0; -ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (a), ALGORITHM=COPY; +ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (a), ALGORITHM=COPY; INSERT INTO t1 VALUES (1,1); +CREATE TABLE t2(f1 INT PRIMARY KEY)ENGINE=InnoDB; LOCK TABLES t1 WRITE; SET FOREIGN_KEY_CHECKS=1; TRUNCATE t1; ERROR HY000: Cannot add foreign key constraint for `t1` INSERT INTO t1 VALUES (2,2); -ERROR HY000: Table 't1' was not locked with LOCK TABLES +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t2` (`a`)) SELECT * FROM t1; pk a 1 1 UNLOCK TABLES; INSERT INTO t1 VALUES (2,2); -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t2` (`a`)) SET FOREIGN_KEY_CHECKS=0; INSERT INTO t1 VALUES (2,2); SELECT * FROM t1; pk a 1 1 2 2 -DROP TABLE t1; +DROP TABLE t2, t1; # End of 10.6 tests diff --git a/mysql-test/suite/innodb/r/trx_id_future.result b/mysql-test/suite/innodb/r/trx_id_future.result index 4f88b1d4783..487fa82c50c 100644 --- a/mysql-test/suite/innodb/r/trx_id_future.result +++ b/mysql-test/suite/innodb/r/trx_id_future.result @@ -2,8 +2,7 @@ # Bug #20445525 ADD A CONSISTENCY CHECK AGAINST DB_TRX_ID BEING # IN THE FUTURE # -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; -CREATE TABLE t1(a INT) row_format=redundant engine=innoDB; +CREATE TABLE t1(a INT) row_format=redundant engine=innoDB stats_persistent=0; INSERT INTO t1 VALUES(1); InnoDB 0 transactions not purged call mtr.add_suppression("\\[Warning\\] InnoDB: A transaction id in a record of table `test`\\.`t1` is newer than the system-wide maximum"); diff --git a/mysql-test/suite/innodb/r/undo_log.result b/mysql-test/suite/innodb/r/undo_log.result index cda3b190ede..014b1210ec0 100644 --- a/mysql-test/suite/innodb/r/undo_log.result +++ b/mysql-test/suite/innodb/r/undo_log.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; SET innodb_strict_mode=OFF; CREATE TABLE test_tab ( a_str_18 mediumtext, @@ -144,8 +146,6 @@ CHECK TABLE test_tab; Table Op Msg_type Msg_text test.test_tab check status OK DROP TABLE test_tab; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; CREATE TEMPORARY TABLE t2(i INT)ENGINE=InnoDB; CREATE TABLE t1(i TEXT NOT NULL) ENGINE=INNODB; BEGIN; @@ -156,4 +156,4 @@ ROLLBACK; InnoDB 0 transactions not purged DROP TABLE t1; DROP TABLE t2; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/r/undo_space_dblwr.result b/mysql-test/suite/innodb/r/undo_space_dblwr.result new file mode 100644 index 00000000000..d6822b20eb7 --- /dev/null +++ b/mysql-test/suite/innodb/r/undo_space_dblwr.result @@ -0,0 +1,20 @@ +call mtr.add_suppression("Checksum mismatch in the first page of file"); +show variables like 'innodb_doublewrite'; +Variable_name Value +innodb_doublewrite ON +create table t1(f1 int not null, f2 int not null)engine=innodb; +insert into t1 values (1, 1); +InnoDB 0 transactions not purged +set GLOBAL innodb_log_checkpoint_now=1; +# Make the first page dirty for undo tablespace +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 1; +SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0; +SET GLOBAL innodb_max_dirty_pages_pct=0.0; +# Kill the server +# restart +FOUND 1 /Checksum mismatch in the first page of file/ in mysqld.1.err +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; diff --git a/mysql-test/suite/innodb/r/undo_truncate.result b/mysql-test/suite/innodb/r/undo_truncate.result index c46dccfbba9..f90bef94415 100644 --- a/mysql-test/suite/innodb/r/undo_truncate.result +++ b/mysql-test/suite/innodb/r/undo_truncate.result @@ -1,7 +1,6 @@ SET GLOBAL innodb_fast_shutdown=0; # restart: --innodb_undo_tablespaces=2 SET GLOBAL innodb_undo_log_truncate = 0; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; === information_schema.innodb_sys_tablespaces and innodb_sys_datafiles === Space_Name Page_Size Zip_Size Path innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001 @@ -35,7 +34,6 @@ connection con2; commit; disconnect con2; connection default; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SET GLOBAL innodb_max_purge_lag_wait=0; set global innodb_fast_shutdown=0; # restart diff --git a/mysql-test/suite/innodb/r/undo_truncate_recover.result b/mysql-test/suite/innodb/r/undo_truncate_recover.result index 4d75712060a..777c9ce5899 100644 --- a/mysql-test/suite/innodb/r/undo_truncate_recover.result +++ b/mysql-test/suite/innodb/r/undo_truncate_recover.result @@ -1,7 +1,6 @@ SET GLOBAL innodb_fast_shutdown=0; # restart: --innodb_undo_tablespaces=2 SET GLOBAL innodb_undo_log_truncate = 1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; create table t1(keyc int primary key, c char(100)) engine = innodb; begin; commit; diff --git a/mysql-test/suite/innodb/r/undo_upgrade.result b/mysql-test/suite/innodb/r/undo_upgrade.result index 12d6f30e1d8..f2eca9e2a7c 100644 --- a/mysql-test/suite/innodb/r/undo_upgrade.result +++ b/mysql-test/suite/innodb/r/undo_upgrade.result @@ -8,29 +8,13 @@ call mtr.add_suppression("Plugin 'InnoDB' init function returned error"); call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); call mtr.add_suppression("InnoDB: Cannot change innodb_undo_tablespaces=\\d+ because previous shutdown was not with innodb_fast_shutdown=0"); CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; -connect con_purge,localhost,root,,,; -START TRANSACTION WITH CONSISTENT SNAPSHOT; -connection default; -INSERT INTO t1 VALUES(1); -UPDATE t1 SET f1=100; -# case 1: Undo log left to purge -# restart: --innodb_undo_tablespaces=2 -# Display 4 undo tablespaces -select @@global.innodb_undo_tablespaces; -@@global.innodb_undo_tablespaces -4 -# Should list 4 undo log tablespaces -undo001 -undo002 -undo003 -undo004 -# case 2: XA transaction alone left +# case 1: XA transaction alone left InnoDB 0 transactions not purged XA START 'zombie'; INSERT INTO t1 VALUES(2); XA END 'zombie'; XA PREPARE 'zombie'; -# restart: --innodb_undo_tablespaces=2 +# restart # Display 4 undo tablespaces select @@global.innodb_undo_tablespaces; @@global.innodb_undo_tablespaces @@ -41,7 +25,7 @@ undo002 undo003 undo004 XA COMMIT 'zombie'; -# case 3: Successful innodb_undo_tablespace upgrade +# case 2: Successful innodb_undo_tablespace upgrade SET GLOBAL innodb_fast_shutdown=0; # restart: --innodb_undo_tablespaces=2 # Display 2 undo tablespaces @@ -53,14 +37,14 @@ undo001 undo002 DROP TABLE t1; InnoDB 0 transactions not purged -# case 4: Reduce the innodb_undo_tablespace to 0 +# case 3: Reduce the innodb_undo_tablespace to 0 # restart: --innodb_undo_tablespaces=0 # Display 0 undo tablespace SELECT @@global.innodb_undo_tablespaces; @@global.innodb_undo_tablespaces 0 # Shouldn't list any undo log tablespaces -# case 5: Change undo tablespace when force_recovery < 5 +# case 4: Change undo tablespace when force_recovery < 5 # restart: --innodb_undo_tablespaces=2 --innodb_force_recovery=4 # Display 2 undo tablespace SELECT @@global.innodb_undo_tablespaces; @@ -69,7 +53,7 @@ SELECT @@global.innodb_undo_tablespaces; # Should list 2 undo log tablespaces undo001 undo002 -# case 6: Fail to change undo tablespace when force_recovery > 4 +# case 5: Fail to change undo tablespace when force_recovery > 4 # restart: --innodb_undo_tablespaces=4 --innodb_force_recovery=5 # Display 2 undo tablespace SELECT @@global.innodb_undo_tablespaces; 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/alter_kill.test b/mysql-test/suite/innodb/t/alter_kill.test index 4e42015a69b..57ca97f003d 100644 --- a/mysql-test/suite/innodb/t/alter_kill.test +++ b/mysql-test/suite/innodb/t/alter_kill.test @@ -25,7 +25,7 @@ call mtr.add_suppression("Table .*bug16720368.* is corrupted"); -- echo # Bug#16720368 INNODB CRASHES ON BROKEN #SQL*.IBD FILE AT STARTUP -- echo # -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET GLOBAL innodb_stats_persistent=0; CREATE TABLE bug16720368_1 (a INT PRIMARY KEY) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb/t/alter_table.test b/mysql-test/suite/innodb/t/alter_table.test index 67ada081d46..d293d3a40f4 100644 --- a/mysql-test/suite/innodb/t/alter_table.test +++ b/mysql-test/suite/innodb/t/alter_table.test @@ -121,9 +121,20 @@ CREATE TABLE t1 (c TIMESTAMP AUTO_INCREMENT UNIQUE) ENGINE=InnoDB; CREATE TABLE t1 (c DATETIME AUTO_INCREMENT UNIQUE) ENGINE=InnoDB; --echo # ---echo # End of 10.4 tests +--echo # MDEV-31000 Assertion failed on ALTER TABLE...page_compressed=1 --echo # +SET @save_file_per_table=@@GLOBAL.innodb_file_per_table; +SET GLOBAL innodb_file_per_table=0; +CREATE TABLE t (c INT PRIMARY KEY) ENGINE=INNODB; +SET GLOBAL innodb_file_per_table=1; +ALTER TABLE t page_compressed=1; +SET GLOBAL innodb_file_per_table=@save_file_per_table; +SELECT space>0 FROM information_schema.innodb_sys_tables WHERE name='test/t'; +DROP TABLE t; + +--echo # End of 10.4 tests + --echo # --echo # MDEV-21748 ASAN use-after-poison in PageBulk::insertPage() --echo # @@ -141,3 +152,5 @@ CREATE TABLE t1 (id INT PRIMARY KEY, a YEAR, INDEX(id,a)) ENGINE=InnoDB; INSERT INTO t1 VALUES (1,NULL),(2,NULL); UPDATE t1 SET a=0; DROP TABLE t1; + +--echo # End of 10.5 tests 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/cursor-restore-locking.test b/mysql-test/suite/innodb/t/cursor-restore-locking.test index b65d3773ba2..0f90055ff8b 100644 --- a/mysql-test/suite/innodb/t/cursor-restore-locking.test +++ b/mysql-test/suite/innodb/t/cursor-restore-locking.test @@ -3,8 +3,6 @@ source include/have_debug.inc; source include/have_debug_sync.inc; -SET @save_freq=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB, STATS_PERSISTENT=0; --source include/wait_all_purged.inc @@ -86,5 +84,4 @@ INSERT INTO t VALUES(30, 20); # trx_4 SET DEBUG_SYNC = 'RESET'; DROP TABLE t; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_freq; --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/dml_purge.test b/mysql-test/suite/innodb/t/dml_purge.test index c13ff22572b..78c6c50ae71 100644 --- a/mysql-test/suite/innodb/t/dml_purge.test +++ b/mysql-test/suite/innodb/t/dml_purge.test @@ -1,17 +1,16 @@ --source include/innodb_page_size.inc +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; + let INNODB_PAGE_SIZE=`select @@innodb_page_size`; let MYSQLD_DATADIR=`select @@datadir`; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; --echo # --echo # MDEV-12288 Reset DB_TRX_ID when the history is removed, --echo # to speed up MVCC --echo # -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; - CREATE TABLE t1(a INT PRIMARY KEY, b INT NOT NULL) ROW_FORMAT=REDUNDANT ENGINE=InnoDB; --source include/wait_all_purged.inc @@ -80,4 +79,5 @@ EOF UNLOCK TABLES; SELECT * FROM t1; DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; + +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; 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..797b7158778 --- /dev/null +++ b/mysql-test/suite/innodb/t/doublewrite_debug.combinations @@ -0,0 +1,9 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 +--innodb-use-atomic-writes=0 +--innodb-undo-tablespaces=0 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 +--innodb-use-atomic-writes=0 +--innodb-undo-tablespaces=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 5e8d96e0645..21fd470eaa8 100644 --- a/mysql-test/suite/innodb/t/fk_col_alter.test +++ b/mysql-test/suite/innodb/t/fk_col_alter.test @@ -122,4 +122,45 @@ CREATE TABLE t2 (b VARCHAR(8)) ENGINE=InnoDB; SET SESSION FOREIGN_KEY_CHECKS = ON; ALTER TABLE t2 MODIFY b VARCHAR(16), ADD KEY(b); DROP TABLE t1, t2; + +--echo # +--echo # MDEV-32337 Assertion `pos < table->n_def' failed +--echo # in dict_table_get_nth_col +--echo # +CREATE TABLE t (a INT, va INT AS (a), b INT, vb INT AS (b), + c INT, vc INT AS (c), vf VARCHAR(16) AS (f), + f VARCHAR(4)) ENGINE=InnoDB; +ALTER TABLE t MODIFY f VARCHAR(8); +# Altering the virtual column is not supported +--error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN +ALTER TABLE t MODIFY vf VARCHAR(18); +DROP TABLE t; + +--echo # +--echo # MDEV-32527 Server aborts during alter operation +--echo # when table doesn't have foreign index +--echo # +CREATE TABLE t1 (f1 INT NOT NULL, INDEX(f1)) ENGINE=InnoDB; +CREATE TABLE t2(f1 INT NOT NULL, f2 VARCHAR(100) DEFAULT NULL, + INDEX idx(f1, f2), + FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=INNODB; +SET SESSION FOREIGN_KEY_CHECKS = OFF; +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 31ab5168d06..0db3a7ca377 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -2,6 +2,8 @@ --source include/count_sessions.inc --source include/default_charset.inc +SET GLOBAL innodb_stats_persistent = 0; + --echo # --echo # Bug #19027905 ASSERT RET.SECOND DICT_CREATE_FOREIGN_CONSTRAINTS_LOW --echo # DICT_CREATE_FOREIGN_CONSTR @@ -126,6 +128,9 @@ FLUSH TABLES; --let $shutdown_timeout= disconnect incomplete; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; + INSERT INTO child SET a=0; --error ER_NO_REFERENCED_ROW_2 INSERT INTO child SET a=1; @@ -138,9 +143,6 @@ ALTER TABLE child FORCE; DELETE FROM parent; DROP TABLE child,parent; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; - SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; @@ -731,13 +733,14 @@ 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 CHECK TABLE t1; DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; --echo # --echo # MDEV-17187 table doesn't exist in engine after ALTER other tables @@ -934,7 +937,55 @@ INSERT INTO t1 VALUES (2,11,11); DROP TABLE t1; SET FOREIGN_KEY_CHECKS=DEFAULT; --- echo # End of 10.4 tests +--echo # +--echo # MDEV-32018 Allow the setting of Auto_increment on FK referenced columns +--echo # + +CREATE TABLE t1 ( + id int unsigned NOT NULL PRIMARY KEY +); + +CREATE TABLE t2 ( + id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, + t1_id int unsigned DEFAULT NULL, + CONSTRAINT FK_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) +); + +ALTER TABLE t1 MODIFY id INT unsigned AUTO_INCREMENT; + +DROP TABLE t1,t2; + +--echo # +--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 @@ -1080,9 +1131,6 @@ DROP TABLE IF EXISTS t2, t1; --echo # MDEV-30531 Corrupt index(es) on busy table when using FOREIGN KEY --echo # -SET @freq=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; - CREATE TABLE collections ( id int(11) unsigned NOT NULL AUTO_INCREMENT, collectionhash varchar(255) NOT NULL DEFAULT '0', @@ -1111,7 +1159,6 @@ REPLACE INTO binaries (id) VALUES (NULL); SET GLOBAL innodb_max_purge_lag_wait=0; CHECK TABLE binaries, collections EXTENDED; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@freq; --disconnect con1 @@ -1120,4 +1167,6 @@ DROP TABLE binaries, collections; --echo # End of 10.6 tests +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; + --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/full_crc32_import.test b/mysql-test/suite/innodb/t/full_crc32_import.test index b79fd95471b..0eb31f8d63f 100644 --- a/mysql-test/suite/innodb/t/full_crc32_import.test +++ b/mysql-test/suite/innodb/t/full_crc32_import.test @@ -2,6 +2,9 @@ # This test is slow on buildbot. --source include/big_test.inc +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; + FLUSH TABLES; let $MYSQLD_TMPDIR = `SELECT @@tmpdir`; @@ -222,3 +225,4 @@ SELECT * FROM t1; DROP TABLE t1; SET GLOBAL innodb_compression_algorithm=@save_algo; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/t/gap_lock_split.test b/mysql-test/suite/innodb/t/gap_lock_split.test index e8202615c3f..c67e693fc0b 100644 --- a/mysql-test/suite/innodb/t/gap_lock_split.test +++ b/mysql-test/suite/innodb/t/gap_lock_split.test @@ -3,9 +3,6 @@ --source include/have_debug.inc --source include/have_debug_sync.inc -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; - CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023; @@ -44,4 +41,3 @@ disconnect con1; connection default; COMMIT; DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; 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..30420f4d079 --- /dev/null +++ b/mysql-test/suite/innodb/t/import_update_stats.test @@ -0,0 +1,74 @@ +# +# BUG#20125349 - PERSISTANT STATS IS NOT UPDATED WHEN TTS IS IMPORTED. +# + +--source include/not_embedded.inc +--source include/have_innodb.inc + +let MYSQLD_DATADIR =`SELECT @@datadir`; + +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; + +--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/index_merge_threshold.test b/mysql-test/suite/innodb/t/index_merge_threshold.test index a587e10db6c..cb8e117d453 100644 --- a/mysql-test/suite/innodb/t/index_merge_threshold.test +++ b/mysql-test/suite/innodb/t/index_merge_threshold.test @@ -13,8 +13,8 @@ --source include/have_innodb_16k.inc --source include/have_partition.inc -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; # Check index merge threshold by create index on all datatypes @@ -189,4 +189,5 @@ CREATE INDEX index1 ON tab1(b(750)) COMMENT 'MERGE_THRESHOLD=45'; --source suite/innodb/include/innodb_merge_threshold_secondary.inc DROP TABLE tab1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; + +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/t/innodb-16k.test b/mysql-test/suite/innodb/t/innodb-16k.test index 56109543ee4..fd024047114 100644 --- a/mysql-test/suite/innodb/t/innodb-16k.test +++ b/mysql-test/suite/innodb/t/innodb-16k.test @@ -3,6 +3,9 @@ --source include/have_innodb.inc --source include/have_innodb_16k.inc +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; + call mtr.add_suppression("InnoDB: Cannot add field .* in table"); let $MYSQLD_DATADIR= `select @@datadir`; @@ -16,9 +19,7 @@ SELECT variable_value FROM information_schema.global_status --echo # varies depending on number of fields and other overhead. SET SESSION innodb_strict_mode = ON; -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; SET @save_level=@@GLOBAL.innodb_compression_level; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SET GLOBAL innodb_compression_level=1; # Compressed table: compressBound() for the s390x DFLTCC instruction @@ -458,8 +459,8 @@ DROP TABLE t1; --source include/wait_all_purged.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; SET GLOBAL innodb_compression_level=@save_level; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; diff --git a/mysql-test/suite/innodb/t/innodb-32k.test b/mysql-test/suite/innodb/t/innodb-32k.test index 07c6c10d013..a5fd78fdfc2 100644 --- a/mysql-test/suite/innodb/t/innodb-32k.test +++ b/mysql-test/suite/innodb/t/innodb-32k.test @@ -3,12 +3,24 @@ --source include/have_innodb.inc --source include/have_innodb_32k.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; - +SET GLOBAL innodb_stats_persistent = 0; 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-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test index 0ae116f58f0..2534f03dbec 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test +++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test @@ -65,8 +65,11 @@ set DEBUG_SYNC="now WAIT_FOR default_signal"; --let $shutdown_timeout=0 --source include/restart_mysqld.inc disconnect con1; ---replace_column 7 # +# This may occasionally display records for a corrupted index(f2). +# The original bug was about a crash during the execution of SHOW KEYS. +--disable_result_log SHOW KEYS FROM t1; +--enable_result_log DROP TABLE t1; remove_files_wildcard $datadir/test #sql-*.frm; diff --git a/mysql-test/suite/innodb/t/innodb-alter.test b/mysql-test/suite/innodb/t/innodb-alter.test index c6a76b66b3e..dd00c36130b 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-debug.test b/mysql-test/suite/innodb/t/innodb-index-debug.test index ae880274e02..cfe893f5b9d 100644 --- a/mysql-test/suite/innodb/t/innodb-index-debug.test +++ b/mysql-test/suite/innodb/t/innodb-index-debug.test @@ -6,6 +6,10 @@ --source include/big_test.inc let $MYSQLD_DATADIR= `select @@datadir`; +SET GLOBAL innodb_max_purge_lag_wait=0; +connect (stop_purge,localhost,root); +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; # # Test for BUG# 12739098, check whether trx->error_status is reset on error. @@ -155,6 +159,7 @@ SET DEBUG_SYNC='now SIGNAL log2'; --connection con1 reap; --disconnect con1 +--disconnect stop_purge --connection default SET DEBUG_SYNC='RESET'; DROP TABLE t1; 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 5423516c4b5..64cea29e7d9 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-index-online.test b/mysql-test/suite/innodb/t/innodb-index-online.test index 827941817f6..70a10391db2 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online.test +++ b/mysql-test/suite/innodb/t/innodb-index-online.test @@ -4,6 +4,10 @@ --source include/have_debug_sync.inc --source include/no_valgrind_without_big.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'; @@ -154,6 +158,7 @@ let $ID= `SELECT @id := CONNECTION_ID()`; --error ER_QUERY_INTERRUPTED KILL QUERY @id; +SET GLOBAL innodb_max_purge_lag_wait=0; SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2d_created WAIT_FOR kill_done'; --send CREATE INDEX c2d ON t1(c2); @@ -205,13 +210,13 @@ SHOW CREATE TABLE t1; connection default; 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; @@ -250,13 +255,13 @@ INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf ON si.index_id = sf.index_id WHERE si.name = '?c2e'; 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 @@ -293,16 +298,16 @@ ALTER TABLE t1 COMMENT 'testing if c2e will be dropped'; 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'); connection con1; @@ -339,16 +344,16 @@ eval $innodb_metrics_select; connection default; 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 @@ -365,6 +370,8 @@ SELECT connection con1; SELECT COUNT(c22f) FROM t1; CHECK TABLE t1; +# Avoid a strange DEBUG_SYNC timeout on c3p5_created. +SET GLOBAL innodb_max_purge_lag_wait=0; # Create a column prefix index. --error ER_DUP_ENTRY 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..0511e5f1fb1 --- /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 = @@transaction_isolation; +SET GLOBAL transaction_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 transaction_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-page_compression_none.test b/mysql-test/suite/innodb/t/innodb-page_compression_none.test new file mode 100644 index 00000000000..e4eaae8bcb2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-page_compression_none.test @@ -0,0 +1,26 @@ +-- source include/innodb_checksum_algorithm.inc + +--echo # +--echo # MDEV-30825 innodb_compression_algorithm=0 (none) increments Innodb_num_pages_page_compression_error +--echo # + +SET @save_compression_algorithm=@@GLOBAL.innodb_compression_algorithm; +SET GLOBAL innodb_compression_algorithm=0; +SELECT VARIABLE_VALUE INTO @compress_errors FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_num_pages_page_compression_error'; + + +CREATE TABLE t (c INT) page_compressed=1 page_compression_level=4 ENGINE=InnoDB; +INSERT INTO t VALUES (1); + +FLUSH TABLES t FOR EXPORT; +UNLOCK TABLES; + +SELECT VARIABLE_VALUE - @compress_errors AS NUMBER_OF_ERRORS FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_num_pages_page_compression_error'; + +DROP TABLE t; +SET GLOBAL innodb_compression_algorithm=@save_compression_algorithm; + +--echo # +--echo # End of 10.4 tests +--echo # + 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-system-table-view.test b/mysql-test/suite/innodb/t/innodb-system-table-view.test index ea620b398e5..663b76a1f18 100644 --- a/mysql-test/suite/innodb/t/innodb-system-table-view.test +++ b/mysql-test/suite/innodb/t/innodb-system-table-view.test @@ -4,8 +4,9 @@ --source include/innodb_page_size_small.inc -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; + LET $MYSQLD_DATADIR = `select @@datadir`; LET $INNODB_PAGE_SIZE = `select @@innodb_page_size`; @@ -140,10 +141,11 @@ WHERE name LIKE "%parent"; DROP TABLE child; DROP TABLE parent; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; --echo # --echo # MDEV-29479 I_S.INNODB_SYS_TABLESPACES doesn't have --echo # temporary tablespace information --echo # SELECT SPACE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE name like 'innodb_temporary'; + +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test index 93b70d8dde9..24e1843854c 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'; @@ -167,13 +171,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; @@ -211,13 +215,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 @@ -239,18 +243,19 @@ 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; # Accumulate and apply some modification log. SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt3 WAIT_FOR dml3_done'; --error ER_MULTIPLE_PRI_KEY @@ -282,16 +287,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-wl5522-1.test b/mysql-test/suite/innodb/t/innodb-wl5522-1.test index dbd58835ec6..9e5d606b894 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-1.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-1.test @@ -960,6 +960,25 @@ ALTER TABLE t1 IMPORT TABLESPACE; DROP TABLE t1; --remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd ---echo # --echo # End of 10.3 tests + --echo # +--echo # MDEV-29972 crash after "Unsupported meta-data version number" +--echo # + +call mtr.add_suppression("Index for table 't2' is corrupt"); + +CREATE TABLE t2 (i INT PRIMARY KEY) ENGINE=InnoDB; +ALTER TABLE t2 DISCARD TABLESPACE; +--copy_file std_data/mysql80/t2.cfg $MYSQLD_DATADIR/test/t2.cfg +--copy_file std_data/mysql80/t2.ibd $MYSQLD_DATADIR/test/t2.ibd +--error ER_NOT_SUPPORTED_YET +ALTER TABLE t2 IMPORT TABLESPACE; +--remove_file $MYSQLD_DATADIR/test/t2.cfg +--error ER_NOT_KEYFILE +ALTER TABLE t2 IMPORT TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t2; +DROP TABLE t2; + +--echo # End of 10.4 tests diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test index 381091165ef..b393ca70778 100644 --- a/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test +++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test @@ -35,49 +35,44 @@ SET GLOBAL innodb_buffer_pool_dump_pct=100; # - The granularity of the timestamp is one second. # - There could have been some dump caused by some previous test # just a few milliseconds before. -# In order to avoid conflict with previous tests, read the current value -# of INNODB_BUFFER_POOL_DUMP_STATUS -# and confirm that the timestamp is different after the dump #*********************************************************** -# Read the current value to compare with the new value. -SELECT variable_value INTO @IBPDS -FROM information_schema.global_status -WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS'; +--error 0,1 +--remove_file $MYSQLD_DATADIR/ib_buffer_pool + SET GLOBAL innodb_buffer_pool_dump_now=ON; - -# Sleep one second in order to ensure that the time stamp is -# different at next dump ---sleep 1 - +perl; +my $f="$ENV{MYSQLD_DATADIR}/ib_buffer_pool"; +my $count=300; +until (-e $f) +{ + select(undef, undef, undef, .1); + die "File $f was not created\n" if (0 > --$count); +} +EOF let $wait_condition = SELECT count(*) = 1 FROM information_schema.global_status WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS' -AND variable_value != @IBPDS AND variable_value like 'Buffer pool(s) dump completed at%'; --source include/wait_condition.inc --move_file $MYSQLD_DATADIR/ib_buffer_pool $MYSQLD_DATADIR/ib_buffer_pool100 SET GLOBAL innodb_buffer_pool_dump_pct=1; -SELECT @@global.innodb_buffer_pool_dump_pct; - -# Read the current value to compare with the new value. ---disable_warnings -SELECT variable_value INTO @IBPDS -FROM information_schema.global_status -WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS'; ---enable_warnings - SET GLOBAL innodb_buffer_pool_dump_now=ON; -# Sleep one second in order to ensure that the time stamp is -# different at next dump ---sleep 1 +perl; +my $f="$ENV{MYSQLD_DATADIR}/ib_buffer_pool"; +my $count=300; +until (-e $f) +{ + select(undef, undef, undef, .1); + die "File $f was not created\n" if (0 > --$count); +} +EOF let $wait_condition = SELECT count(*) = 1 FROM information_schema.global_status WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS' -AND variable_value != @IBPDS AND variable_value like 'Buffer pool(s) dump completed at%'; --source include/wait_condition.inc 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_bug14147491.test b/mysql-test/suite/innodb/t/innodb_bug14147491.test index 4f4810f84ae..6fe4b319e34 100644 --- a/mysql-test/suite/innodb/t/innodb_bug14147491.test +++ b/mysql-test/suite/innodb/t/innodb_bug14147491.test @@ -16,7 +16,6 @@ call mtr.add_suppression("InnoDB: File '.*test/t1\\.ibd' is corrupted"); --enable_query_log --echo # Ensure that purge will not crash on the table after we corrupt it. -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SET GLOBAL innodb_fast_shutdown=0; --echo # Create and populate the table to be corrupted diff --git a/mysql-test/suite/innodb/t/innodb_bug84958.test b/mysql-test/suite/innodb/t/innodb_bug84958.test index b42f7bd639e..d4159dcc485 100644 --- a/mysql-test/suite/innodb/t/innodb_bug84958.test +++ b/mysql-test/suite/innodb/t/innodb_bug84958.test @@ -6,8 +6,6 @@ --echo # --source include/have_innodb.inc -SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency= 1; DELIMITER ~~; CREATE PROCEDURE insert_n(start int, end int) @@ -90,7 +88,6 @@ CHECK TABLE t1; --echo # disconnect con2; disconnect con3; -SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; DROP TABLE t1; DROP PROCEDURE insert_n; DROP FUNCTION num_pages_get; diff --git a/mysql-test/suite/innodb/t/innodb_ctype_utf8.test b/mysql-test/suite/innodb/t/innodb_ctype_utf8.test index 99b79253215..2e916bafe35 100644 --- a/mysql-test/suite/innodb/t/innodb_ctype_utf8.test +++ b/mysql-test/suite/innodb/t/innodb_ctype_utf8.test @@ -32,6 +32,23 @@ let $coll_pad='utf8_bin'; SET NAMES utf8mb3 COLLATE utf8mb3_unicode_nopad_ci; --source include/ctype_nopad_prefix_unique.inc +--source include/ctype_utf8mb3_uca_char.inc + +--echo # +--echo # MDEV-30050 Inconsistent results of DISTINCT with NOPAD +--echo # + +CREATE OR REPLACE TABLE t1 (c CHAR(100) COLLATE utf8mb3_unicode_nopad_ci); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('ss'),('ß'); +SET big_tables=0; +SELECT DISTINCT c FROM t1; +SET big_tables=1; +SELECT DISTINCT c FROM t1; +DROP TABLE t1; +SET big_tables=DEFAULT; + + --echo # --echo # End 10.4 tests --echo # diff --git a/mysql-test/suite/innodb/t/innodb_force_recovery.test b/mysql-test/suite/innodb/t/innodb_force_recovery.test index 2368af76f09..30364c06bb3 100644 --- a/mysql-test/suite/innodb/t/innodb_force_recovery.test +++ b/mysql-test/suite/innodb/t/innodb_force_recovery.test @@ -21,8 +21,18 @@ SET GLOBAL innodb_fast_shutdown = 0; --source include/restart_mysqld.inc let $status=`SHOW ENGINE INNODB STATUS`; +SELECT CAST(variable_value AS INTEGER) INTO @read1 +FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME='innodb_buffer_pool_read_requests'; + select * from t1; +SELECT CAST(variable_value AS INTEGER) INTO @read2 +FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME='innodb_buffer_pool_read_requests'; + +SELECT @read1>0, @read2>@read1; + begin; insert into t1 values(2, 3); rollback; 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_prefix_index_restart_server.test b/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test index 1fb7c6d0f77..fa93e95c642 100644 --- a/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test +++ b/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test @@ -93,3 +93,17 @@ SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM worklog5743; DROP TABLE worklog5743; + +--echo # +--echo # MDEV-21245 InnoDB: Using a partial-field key prefix in search +--echo # +CREATE TABLE t1 (a VARCHAR(255), KEY k(a)) DEFAULT CHARSET=utf8mb3 +ENGINE=InnoDB; +INSERT INTO t1 set a=''; +--enable_info +alter table t1 change a a varchar(3000); +--disable_info +SELECT * FROM t1 WHERE a IN (''); +DROP TABLE t1; + +--echo # End of 10.4 tests diff --git a/mysql-test/suite/innodb/t/innodb_scrub.test b/mysql-test/suite/innodb/t/innodb_scrub.test index 8fe460da4d3..cf6b92e1a75 100644 --- a/mysql-test/suite/innodb/t/innodb_scrub.test +++ b/mysql-test/suite/innodb/t/innodb_scrub.test @@ -4,7 +4,7 @@ let $MYSQLD_DATADIR=`select @@datadir`; CREATE TABLE t1(f1 int auto_increment primary key, f2 varchar(256), - f3 text) engine = innodb; + f3 text) engine = innodb stats_persistent=0; let $numinserts = 500; --disable_query_log begin; 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 f79ae37e8de..294f283b259 100644 --- a/mysql-test/suite/innodb/t/innodb_stats_persistent.test +++ b/mysql-test/suite/innodb/t/innodb_stats_persistent.test @@ -1,8 +1,6 @@ --source include/have_innodb.inc --source include/have_sequence.inc -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SET @saved_include_delete_marked = @@GLOBAL.innodb_stats_include_delete_marked; SET GLOBAL innodb_stats_include_delete_marked = ON; SET @saved_traditional = @@GLOBAL.innodb_stats_traditional; @@ -15,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,,); @@ -51,7 +50,7 @@ SELECT COUNT(*) FROM t2; connection con1; EXPLAIN SELECT * FROM t2 WHERE val=4; ---source include/wait_all_purged.inc +SET GLOBAL innodb_max_purge_lag_wait=0; --echo # After COMMIT and purge, the DELETE must show up. EXPLAIN SELECT * FROM t1 WHERE val=4; @@ -84,4 +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; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; + +# +# 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/instant_alter.test b/mysql-test/suite/innodb/t/instant_alter.test index 8e333e3bb72..d6d7a988d96 100644 --- a/mysql-test/suite/innodb/t/instant_alter.test +++ b/mysql-test/suite/innodb/t/instant_alter.test @@ -3,6 +3,9 @@ let $datadir=`select @@datadir`; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; + --echo # --echo # MDEV-11369: Instant ADD COLUMN for InnoDB --echo # @@ -44,8 +47,6 @@ connect analyze, localhost, root; connection default; SET timestamp = 42; SET time_zone='+03:00'; -SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SET @old_instant= (SELECT variable_value FROM information_schema.global_status @@ -906,7 +907,6 @@ DROP TABLE t1; SELECT variable_value-@old_instant instants FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; -SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; SET GLOBAL innodb_instant_alter_column_allowed = @saved_allowance; --echo # @@ -967,3 +967,4 @@ remove_file $datadir/test/mdev28822_100427_innodb.frm; copy_file std_data/mysql_upgrade/mdev28822_100427_innodb.frm $datadir/test/mdev28822_100427_innodb.frm; ALTER TABLE mdev28822_100427_innodb ADD i1 INTEGER, ALGORITHM=INSTANT; DROP TABLE mdev28822_100427_innodb; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/t/instant_alter_bugs.test b/mysql-test/suite/innodb/t/instant_alter_bugs.test index 5c3c39d44e0..8a4299e52ff 100644 --- a/mysql-test/suite/innodb/t/instant_alter_bugs.test +++ b/mysql-test/suite/innodb/t/instant_alter_bugs.test @@ -1,7 +1,8 @@ --source include/have_innodb.inc +--source include/have_sequence.inc -SET @save_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; --echo # --echo # MDEV-17821 Assertion `!page_rec_is_supremum(rec)' failed @@ -217,8 +218,6 @@ DROP TABLE t1; --echo # in btr_pcur_store_position() --echo # -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; - CREATE TABLE t ( pk int auto_increment, c01 char(255) not null default repeat('a',255), @@ -245,7 +244,6 @@ ROLLBACK; DELETE FROM t; --source include/wait_all_purged.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; CREATE TABLE tt ENGINE=InnoDB AS SELECT c FROM t; DROP TABLE t, tt; @@ -524,7 +522,6 @@ ALTER TABLE t1 ADD COLUMN(f2 INT NOT NULL, f3 INT NOT NULL, f4 INT NOT NULL, f5 INT NOT NULL), CHANGE COLUMN f1 f1 CHAR(10) DEFAULT NULL; DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; --echo # --echo # MDEV-26420 Buffer overflow on instant ADD/DROP of generated column @@ -533,4 +530,32 @@ CREATE TABLE t1 (i int AS (0) STORED, j INT) ENGINE=InnoDB; ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS (1), DROP COLUMN i; DROP TABLE t1; +--echo # +--echo # MDEV-18322 Assertion "wrong_page_type" on instant ALTER +--echo # + +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE c TEXT + DEFAULT(SELECT CONCAT('CREATE TABLE t1 (c', + GROUP_CONCAT(seq SEPARATOR ' CHAR(200), c'), + ' CHAR(211)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT') + FROM seq_1_to_40); + EXECUTE IMMEDIATE c; +END; +$$ +DELIMITER ;$$ +INSERT INTO t1 SET c1=NULL; +--error ER_TOO_BIG_ROWSIZE +ALTER TABLE t1 ADD c41 INT FIRST; +--error ER_TOO_BIG_ROWSIZE +ALTER TABLE t1 ADD c41 INT FIRST; +CHECK TABLE t1; +SELECT COUNT(*) FROM t1; +DROP TABLE t1; + --echo # End of 10.4 tests + +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; + +--echo # End of 10.6 tests diff --git a/mysql-test/suite/innodb/t/instant_alter_crash.test b/mysql-test/suite/innodb/t/instant_alter_crash.test index 37cdb2862ad..f51f61e3c04 100644 --- a/mysql-test/suite/innodb/t/instant_alter_crash.test +++ b/mysql-test/suite/innodb/t/instant_alter_crash.test @@ -14,7 +14,7 @@ let MYSQLD_DATADIR=`select @@datadir`; --echo # CREATE TABLE t1(id INT PRIMARY KEY, c2 INT UNIQUE) -ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=REDUNDANT; CREATE TABLE t2 LIKE t1; INSERT INTO t1 VALUES(0,2); INSERT INTO t2 VALUES(2,1); @@ -36,7 +36,6 @@ COMMIT; disconnect ddl; --source include/start_mysqld.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SELECT * FROM t1; SELECT * FROM t2; BEGIN; @@ -64,9 +63,6 @@ COMMIT; disconnect ddl; --source include/start_mysqld.inc -SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; - SELECT * FROM t1; SELECT * FROM t2; BEGIN; @@ -94,8 +90,6 @@ COMMIT; disconnect ddl; --source include/start_mysqld.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; - let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; let SEARCH_PATTERN= \[Note\] InnoDB: Rolled back recovered transaction ; -- source include/search_pattern_in_file.inc diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.test b/mysql-test/suite/innodb/t/instant_alter_debug.test index e94583cd250..b4d6b279ad5 100644 --- a/mysql-test/suite/innodb/t/instant_alter_debug.test +++ b/mysql-test/suite/innodb/t/instant_alter_debug.test @@ -3,8 +3,8 @@ --source include/have_debug_sync.inc --source include/have_sequence.inc -SET @save_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; SET @old_instant= (SELECT variable_value FROM information_schema.global_status @@ -602,8 +602,10 @@ SET DEBUG_SYNC=RESET; --echo # End of 10.5 tests -SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; - SELECT variable_value-@old_instant instants FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; + +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; + +--echo # End of 10.6 tests diff --git a/mysql-test/suite/innodb/t/instant_alter_purge.test b/mysql-test/suite/innodb/t/instant_alter_purge.test index 88a56141a1f..5fbd4da8818 100644 --- a/mysql-test/suite/innodb/t/instant_alter_purge.test +++ b/mysql-test/suite/innodb/t/instant_alter_purge.test @@ -4,8 +4,6 @@ if ($have_debug) { --source include/have_debug_sync.inc } -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; --source include/wait_all_purged.inc --echo # @@ -16,7 +14,7 @@ connect (prevent_purge,localhost,root); START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; -CREATE TABLE t1 (f1 INT, f2 INT) ENGINE=InnoDB; +CREATE TABLE t1 (f1 INT, f2 INT) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1 () VALUES (); ALTER TABLE t1 DROP f2, ADD COLUMN f2 INT; ALTER TABLE t1 DROP f1; @@ -34,4 +32,3 @@ disconnect prevent_purge; let $wait_all_purged= 0; --source include/wait_all_purged.inc DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/innodb/t/instant_alter_rollback.test b/mysql-test/suite/innodb/t/instant_alter_rollback.test index cfece7e0738..491f63463c5 100644 --- a/mysql-test/suite/innodb/t/instant_alter_rollback.test +++ b/mysql-test/suite/innodb/t/instant_alter_rollback.test @@ -3,6 +3,8 @@ # The embedded server tests do not support restarting. --source include/not_embedded.inc +SET GLOBAL innodb_stats_persistent = 0; + # Flush any open myisam tables from previous tests FLUSH TABLES; @@ -60,11 +62,8 @@ CREATE TABLE foo(a INT PRIMARY KEY) ENGINE=InnoDB; disconnect to_be_killed; --source include/start_mysqld.inc -SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; DROP TABLE foo; --source include/wait_all_purged.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency=@saved_frequency; SELECT * FROM empty; SELECT * FROM once; diff --git a/mysql-test/suite/innodb/t/log_file_name.test b/mysql-test/suite/innodb/t/log_file_name.test index 1945be89599..f95a56c7e8b 100644 --- a/mysql-test/suite/innodb/t/log_file_name.test +++ b/mysql-test/suite/innodb/t/log_file_name.test @@ -170,6 +170,8 @@ call mtr.add_suppression("InnoDB: Plugin initialization aborted"); call mtr.add_suppression("Plugin 'InnoDB' \(init function returned error\|registration as a STORAGE ENGINE failed\)"); call mtr.add_suppression("InnoDB: Table test/u[123] in the InnoDB data dictionary has tablespace id [1-9][0-9]*, but tablespace with that id or name does not exist\\. Have you deleted or moved \\.ibd files\\?"); call mtr.add_suppression("InnoDB: Cannot replay rename of tablespace.*"); +call mtr.add_suppression("InnoDB: Attempted to open a previously opened tablespace"); +call mtr.add_suppression("InnoDB: Recovery cannot access file"); FLUSH TABLES; --enable_query_log diff --git a/mysql-test/suite/innodb/t/mdev-14846.test b/mysql-test/suite/innodb/t/mdev-14846.test index a576d244007..5c101eaa4e6 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/mem_pressure.test b/mysql-test/suite/innodb/t/mem_pressure.test new file mode 100644 index 00000000000..91f75e65795 --- /dev/null +++ b/mysql-test/suite/innodb/t/mem_pressure.test @@ -0,0 +1,44 @@ +--source include/have_debug.inc +--source include/linux.inc +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-24670 avoid OOM by linux kernel co-operative memory management +--echo # + +set @save_dbug=@@debug_dbug; + +set @save_limit=@@GLOBAL.innodb_limit_optimistic_insert_debug; +# Wait for the undo logs to be empty from previous tests. +# This is not an actual parameter, so there is no need to restore it. +set GLOBAL innodb_max_purge_lag_wait=0; + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +SET GLOBAL innodb_limit_optimistic_insert_debug=2; +SET STATEMENT unique_checks=0, foreign_key_checks=0 FOR +INSERT INTO t1 SELECT * FROM seq_1_to_1000; + +SET GLOBAL innodb_limit_optimistic_insert_debug=@save_limit; + +DROP TABLE t1; + +SELECT CAST(VARIABLE_VALUE AS INTEGER) INTO @dirty_prev +FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty'; + +set debug_dbug="d,trigger_garbage_collection"; +SET GLOBAL innodb_buffer_pool_size=@@innodb_buffer_pool_size; + +SELECT CAST(VARIABLE_VALUE AS INTEGER) < @dirty_prev AS LESS_DIRTY_IS_GOOD +FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty'; + +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_PATTERN= InnoDB: Memory pressure event freed.*; +--source include/search_pattern_in_file.inc + +set debug_dbug=@save_dbug; + +--echo # End of 10.11 tests diff --git a/mysql-test/suite/innodb/t/mon_lock_wait_current_count.test b/mysql-test/suite/innodb/t/mon_lock_wait_current_count.test new file mode 100644 index 00000000000..9255d608a83 --- /dev/null +++ b/mysql-test/suite/innodb/t/mon_lock_wait_current_count.test @@ -0,0 +1,97 @@ +# Check if lock_row_lock_current_waits counter in +# information_schema.innodb_metrics does not become negative after disabling, +# resetting and enabling. + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/count_sessions.inc + +--connect (prevent_purge,localhost,root,,) +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +--connection default +# lock_row_lock_time_avg is filled under lock_sys.wait_mutex lock, which +# will be held by connection 2, that is why the following SELECT +# from information_schema.innodb_metrics will be blocked. +# +# And setting innodb_monitor_disable=all causes innodb monitor enabling +# status changing. The status will not be restored to default value even +# after +# ----------------------- +# SET GLOBAL innodb_monitor_reset_all=default; +# SET GLOBAL innodb_monitor_enable=default; +# ----------------------- +# execution. See MDEV-32553 for details. +# +# All monitors disabling, i.e. "innodb_monitor_disable=all" causes +# innodb.monitor test failure due to MDEV-32553. 10.5 is not affected, as +# innodb.monitor differs there. +# +# Disable not all monitors at the beggining of the test, +# but only the monitor, which causes hanging, i.e. lock_row_lock_time_avg. +SET GLOBAL innodb_monitor_disable='lock_row_lock_time_avg'; +# 'lock_row_lock_current_waits' should be enabled by default; +CREATE TABLE `t` (a INT PRIMARY KEY) engine=InnoDB STATS_PERSISTENT=0; +INSERT INTO t VALUES (5); +SELECT name, count FROM information_schema.innodb_metrics + WHERE name ='lock_row_lock_current_waits'; + +--connect (con1,localhost,root,,) +BEGIN; +SELECT * FROM t FOR UPDATE; + +--connect (con2,localhost,root,,) +SET DEBUG_SYNC="lock_wait_before_suspend SIGNAL blocked WAIT_FOR cont"; +BEGIN; +--send SELECT * FROM t FOR UPDATE + +--connection default +SET DEBUG_SYNC="now WAIT_FOR blocked"; +SELECT name, count FROM information_schema.innodb_metrics + WHERE name ='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_disable='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_reset_all='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_enable='lock_row_lock_current_waits'; +###################################### +# Equals to zero if the bug is not fixed, as MONITOR_DISPLAY_CURRENT is not +# set for this counter and its value is reset during previous +# "SET GLOBAL innodb_monitor_reset_all='lock_row_lock_current_waits'" execution. +##### +SELECT name, count FROM information_schema.innodb_metrics + WHERE name ='lock_row_lock_current_waits'; +SET DEBUG_SYNC="now SIGNAL cont"; + +--disconnect con1 + +--connection con2 +--reap +COMMIT; +--disconnect con2 + +--connection default +SET DEBUG_SYNC="reset"; +###################################### +# Equals to -1 if the bug is not fixed. I.e. +# innodb_counter_value[MONITOR_OVLD_ROW_LOCK_CURRENT_WAIT].mon_start_value is +# set to 1 during +# "set global innodb_monitor_disable='lock_row_lock_current_waits'" execution, +# and the value is counted as +# (value = 0) - (mon_value_reset = 0) - (mon_start_value = 1) + +# (mon_last_value = 0) = -1. See MONITOR_SET_DIFF() macro in +# srv_mon_process_existing_counter() for details. +##### +SELECT name, count FROM information_schema.innodb_metrics + WHERE name ='lock_row_lock_current_waits'; +DROP TABLE `t`; +SET GLOBAL innodb_monitor_disable='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_reset_all='lock_row_lock_current_waits'; +SET GLOBAL innodb_monitor_enable='lock_row_lock_current_waits'; +# TODO: remove it when MDEV-32553 is fixed +SET GLOBAL innodb_monitor_enable='lock_row_lock_time_avg'; +--disable_warnings +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; +SET GLOBAL innodb_monitor_enable=default; +--enable_warnings +--disconnect prevent_purge +--source include/wait_until_count_sessions.inc 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/page_id_innochecksum.test b/mysql-test/suite/innodb/t/page_id_innochecksum.test index 2a2c14844fa..9d8114d1720 100644 --- a/mysql-test/suite/innodb/t/page_id_innochecksum.test +++ b/mysql-test/suite/innodb/t/page_id_innochecksum.test @@ -6,7 +6,7 @@ let MYSQLD_BASEDIR= `SELECT @@basedir`; let MYSQLD_DATADIR= `SELECT @@datadir`; let INNODB_PAGE_SIZE=`select @@innodb_page_size`; -create table t1(f1 int not null)engine=innodb; +create table t1(f1 int not null)engine=innodb stats_persistent=0; insert into t1 values(1), (2), (3); let $resultlog=$MYSQLTEST_VARDIR/tmp/result.log; @@ -63,7 +63,6 @@ let SEARCH_PATTERN=page id mismatch; --remove_file $resultlog let $restart_parameters=--innodb-force-recovery=1; --source include/start_mysqld.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; --source include/wait_all_purged.inc drop table t1; call mtr.add_suppression("InnoDB: Failed to read page 3 from file '.*test/t1\\.ibd': Page read from tablespace is corrupted\\."); diff --git a/mysql-test/suite/innodb/t/purge.test b/mysql-test/suite/innodb/t/purge.test index 63312e50fd8..1dc2b1175dc 100644 --- a/mysql-test/suite/innodb/t/purge.test +++ b/mysql-test/suite/innodb/t/purge.test @@ -1,8 +1,8 @@ --source include/have_innodb.inc --source include/have_innodb_16k.inc -SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; --echo # Bug #12429576 - Test an assertion failure on purge. CREATE TABLE t1_purge ( @@ -113,5 +113,6 @@ SHOW CREATE TABLE t12963823; # We need to activate the purge thread before DROP TABLE. -- source include/wait_all_purged.inc + +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge, t12637786, t12963823; -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; diff --git a/mysql-test/suite/innodb/t/purge_secondary.test b/mysql-test/suite/innodb/t/purge_secondary.test index a7f75f56b53..8a38a418877 100644 --- a/mysql-test/suite/innodb/t/purge_secondary.test +++ b/mysql-test/suite/innodb/t/purge_secondary.test @@ -1,14 +1,13 @@ --source include/have_innodb.inc --source include/have_sequence.inc +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; + --disable_query_log call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool"); --enable_query_log -# Ensure that the history list length will actually be decremented by purge. -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; - CREATE TABLE t1 ( a SERIAL, b CHAR(255) NOT NULL DEFAULT '', c BOOLEAN DEFAULT false, l LINESTRING NOT NULL DEFAULT ST_linefromtext('linestring(448 -689, @@ -175,4 +174,6 @@ DROP TABLE t1; --echo # End of 10.3 tests -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; + +--echo # End of 10.6 tests 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 53b375b80fd..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, 2026; -eval kill $me; - -source include/start_mysqld.inc; -drop table t1; diff --git a/mysql-test/suite/innodb/t/read_only_recovery.test b/mysql-test/suite/innodb/t/read_only_recovery.test index 47146213090..d011b3aa5e3 100644 --- a/mysql-test/suite/innodb/t/read_only_recovery.test +++ b/mysql-test/suite/innodb/t/read_only_recovery.test @@ -39,6 +39,8 @@ SELECT * FROM t; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT * FROM t; SET GLOBAL innodb_max_purge_lag_wait=0; +INSERT INTO mysql.innodb_index_stats +SELECT * FROM mysql.innodb_index_stats LIMIT 0; --let $restart_parameters= --source include/restart_mysqld.inc SELECT * FROM t; 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/row_format_redundant.opt b/mysql-test/suite/innodb/t/row_format_redundant.opt index 3147bad4713..349b00fe111 100644 --- a/mysql-test/suite/innodb/t/row_format_redundant.opt +++ b/mysql-test/suite/innodb/t/row_format_redundant.opt @@ -1,2 +1,4 @@ --innodb-checksum-algorithm=crc32 --innodb-undo-tablespaces=0 +--skip-innodb-fast-shutdown +--skip-innodb-buffer-pool-dump-at-shutdown diff --git a/mysql-test/suite/innodb/t/row_format_redundant.test b/mysql-test/suite/innodb/t/row_format_redundant.test index 6b5a559fc18..b11347766b5 100644 --- a/mysql-test/suite/innodb/t/row_format_redundant.test +++ b/mysql-test/suite/innodb/t/row_format_redundant.test @@ -72,7 +72,7 @@ TRUNCATE TABLE t2; --error ER_OPEN_AS_READONLY TRUNCATE TABLE t3; ---let $restart_parameters= $d +--let $restart_parameters= $d --skip-innodb-fast-shutdown --source include/restart_mysqld.inc TRUNCATE TABLE t1; diff --git a/mysql-test/suite/innodb/t/scrub.test b/mysql-test/suite/innodb/t/scrub.test index a2f4e5757f5..1c38637984a 100644 --- a/mysql-test/suite/innodb/t/scrub.test +++ b/mysql-test/suite/innodb/t/scrub.test @@ -4,7 +4,6 @@ SET GLOBAL innodb_file_per_table=OFF, - innodb_purge_rseg_truncate_frequency=1, innodb_immediate_scrub_data_uncompressed=ON; CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, f3 INT NOT NULL, INDEX(f1), diff --git a/mysql-test/suite/innodb/t/scrub_debug.test b/mysql-test/suite/innodb/t/scrub_debug.test index 141b0f0c5ba..8cebfca6106 100644 --- a/mysql-test/suite/innodb/t/scrub_debug.test +++ b/mysql-test/suite/innodb/t/scrub_debug.test @@ -4,15 +4,13 @@ SET @save_debug=@@GLOBAL.INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG; SET @save_scrub=@@GLOBAL.INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED; -SET @save_freq=@@GLOBAL.INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY; -SET GLOBAL INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY=1; SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=1; SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=2; let $MYSQLD_DATADIR=`select @@datadir`; CREATE TABLE t1(f1 INT AUTO_INCREMENT PRIMARY KEY, f2 VARCHAR(256) GENERATED ALWAYS as('repairman'), - INDEX idx(f2))ENGINE= InnoDB; + INDEX idx(f2))ENGINE= InnoDB STATS_PERSISTENT=0; INSERT INTO t1(f1) SELECT seq FROM seq_1_to_50; FLUSH TABLE t1 FOR EXPORT; let SEARCH_PATTERN= repairman; @@ -28,4 +26,3 @@ UNLOCK TABLES; DROP TABLE t1; SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=@save_debug; SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=@save_scrub; -SET GLOBAL INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY = @save_freq; diff --git a/mysql-test/suite/innodb/t/sys_truncate_shutdown.opt b/mysql-test/suite/innodb/t/sys_truncate_shutdown.opt new file mode 100644 index 00000000000..001feac38fb --- /dev/null +++ b/mysql-test/suite/innodb/t/sys_truncate_shutdown.opt @@ -0,0 +1,3 @@ +--innodb_data_file_path=ibdata1:1M:autoextend +--innodb_sys_tablespaces +--innodb_page_size=4k diff --git a/mysql-test/suite/innodb/t/sys_truncate_shutdown.test b/mysql-test/suite/innodb/t/sys_truncate_shutdown.test new file mode 100644 index 00000000000..0f61049ba5e --- /dev/null +++ b/mysql-test/suite/innodb/t/sys_truncate_shutdown.test @@ -0,0 +1,20 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +SET GLOBAL innodb_fast_shutdown=0; +--source include/restart_mysqld.inc +SET GLOBAL INNODB_FILE_PER_TABLE= 0; +SET UNIQUE_CHECKS=0, FOREIGN_KEY_CHECKS=0; +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, + f3 INT NOT NULL, INDEX(f1), + INDEX(f2), INDEX(f3))ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +COMMIT; +DROP TABLE t1; +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; + +SET GLOBAL innodb_fast_shutdown=0; +--source include/restart_mysqld.inc +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; diff --git a/mysql-test/suite/innodb/t/sys_truncate_shutdown_debug.opt b/mysql-test/suite/innodb/t/sys_truncate_shutdown_debug.opt new file mode 100644 index 00000000000..001feac38fb --- /dev/null +++ b/mysql-test/suite/innodb/t/sys_truncate_shutdown_debug.opt @@ -0,0 +1,3 @@ +--innodb_data_file_path=ibdata1:1M:autoextend +--innodb_sys_tablespaces +--innodb_page_size=4k diff --git a/mysql-test/suite/innodb/t/sys_truncate_shutdown_debug.test b/mysql-test/suite/innodb/t/sys_truncate_shutdown_debug.test new file mode 100644 index 00000000000..8e8c91e7b47 --- /dev/null +++ b/mysql-test/suite/innodb/t/sys_truncate_shutdown_debug.test @@ -0,0 +1,51 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/not_embedded.inc +--source include/have_debug.inc + +call mtr.add_suppression("InnoDB: Cannot shrink the system tablespace"); +call mtr.add_suppression("InnoDB: Plugin initialization aborted"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error"); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); + +SET GLOBAL innodb_fast_shutdown=0; +--source include/restart_mysqld.inc +SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=2; +SET GLOBAL INNODB_FILE_PER_TABLE= 0; +SET UNIQUE_CHECKS=0, FOREIGN_KEY_CHECKS=0; +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, + f3 INT NOT NULL, INDEX(f1), + INDEX(f2), INDEX(f3))ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +INSERT INTO t1 SELECT seq, seq, seq FROM seq_1_to_16384; +COMMIT; +DROP TABLE t1; +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; + +SET GLOBAL INNODB_FAST_SHUTDOWN=0; +SET GLOBAL DEBUG_DBUG="+d,shrink_buffer_pool_full"; +--source include/restart_mysqld.inc + +--let SEARCH_PATTERN= \\[Warning\\] InnoDB: Cannot shrink the system tablespace +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +--source include/search_pattern_in_file.inc + +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; + +SET GLOBAL INNODB_FAST_SHUTDOWN=0; +SET GLOBAL DEBUG_DBUG="+d,mtr_log_max_size"; +--source include/restart_mysqld.inc + +--let SEARCH_PATTERN= \\[ERROR\\] InnoDB: Cannot shrink the system tablespace +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +--source include/search_pattern_in_file.inc + +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; + +SET GLOBAL INNODB_FAST_SHUTDOWN=0; +# Crash after shrinking the system tablespace +let $restart_parameters=--debug_dbug="+d,crash_after_sys_truncate"; +--source include/restart_mysqld.inc + +SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; diff --git a/mysql-test/suite/innodb/t/table_flags.opt b/mysql-test/suite/innodb/t/table_flags.opt index 3147bad4713..22cc64896fc 100644 --- a/mysql-test/suite/innodb/t/table_flags.opt +++ b/mysql-test/suite/innodb/t/table_flags.opt @@ -1,2 +1,3 @@ --innodb-checksum-algorithm=crc32 --innodb-undo-tablespaces=0 +--skip-innodb-buffer-pool-dump-at-shutdown diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test index 1c3efa1fbba..a17b8dc32b6 100644 --- a/mysql-test/suite/innodb/t/table_flags.test +++ b/mysql-test/suite/innodb/t/table_flags.test @@ -34,7 +34,6 @@ let bugdir= $MYSQLTEST_VARDIR/tmp/table_flags; --let $d=--innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir --let $d=$d --innodb-data-file-path=ibdata1:1M:autoextend --let $d=$d --innodb-undo-tablespaces=0 ---let $d=$d --innodb-purge-rseg-truncate-frequency=1 --let $d=$d --skip-innodb-fast-shutdown --let $restart_noprint=1 --let $restart_parameters=$d --innodb-stats-persistent=0 @@ -157,7 +156,9 @@ SHOW CREATE TABLE tr; SHOW CREATE TABLE tc; --error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM tc; +--error ER_GET_ERRNO SHOW CREATE TABLE td; +--error ER_GET_ERRNO SELECT * FROM td; # This table was converted to NO_ROLLBACK due to the SYS_TABLES.TYPE change. SHOW CREATE TABLE tz; 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/t/truncate_crash.test b/mysql-test/suite/innodb/t/truncate_crash.test index 27b8feea8a4..8a11b1ed531 100644 --- a/mysql-test/suite/innodb/t/truncate_crash.test +++ b/mysql-test/suite/innodb/t/truncate_crash.test @@ -4,7 +4,7 @@ --source include/not_embedded.inc FLUSH TABLES; -CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1 VALUES (1),(2); connect (wait,localhost,root,,test); @@ -17,10 +17,7 @@ SET DEBUG_SYNC='now WAIT_FOR c'; --source include/restart_mysqld.inc disconnect wait; -SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; --source include/wait_all_purged.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; --replace_result 2 0 SELECT COUNT(*) FROM t1; diff --git a/mysql-test/suite/innodb/t/truncate_foreign.test b/mysql-test/suite/innodb/t/truncate_foreign.test index abbe1b3df87..c29c141015a 100644 --- a/mysql-test/suite/innodb/t/truncate_foreign.test +++ b/mysql-test/suite/innodb/t/truncate_foreign.test @@ -89,16 +89,14 @@ call mtr.add_suppression("InnoDB: In ALTER TABLE `test`\\.`t1` has or is"); CREATE TABLE t1 (pk INT, a INT, PRIMARY KEY (pk), KEY (a)) ENGINE=InnoDB; SET FOREIGN_KEY_CHECKS=0; -ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (a), ALGORITHM=COPY; +ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (a), ALGORITHM=COPY; INSERT INTO t1 VALUES (1,1); +CREATE TABLE t2(f1 INT PRIMARY KEY)ENGINE=InnoDB; LOCK TABLES t1 WRITE; SET FOREIGN_KEY_CHECKS=1; --error ER_CANNOT_ADD_FOREIGN TRUNCATE t1; -# Whether TRUNCATE succeeds or fails, it will reload FOREIGN KEY constraints. -# As a result, ha_innobase::referenced_by_foreign_key() will retun TRUE -# (for the self-referential key), and the statement will fail. ---error ER_TABLE_NOT_LOCKED +--error ER_NO_REFERENCED_ROW_2 INSERT INTO t1 VALUES (2,2); SELECT * FROM t1; UNLOCK TABLES; @@ -107,6 +105,6 @@ INSERT INTO t1 VALUES (2,2); SET FOREIGN_KEY_CHECKS=0; INSERT INTO t1 VALUES (2,2); SELECT * FROM t1; -DROP TABLE t1; +DROP TABLE t2, t1; --echo # End of 10.6 tests diff --git a/mysql-test/suite/innodb/t/trx_id_future.test b/mysql-test/suite/innodb/t/trx_id_future.test index 18077549cf6..049e8f2c6f3 100644 --- a/mysql-test/suite/innodb/t/trx_id_future.test +++ b/mysql-test/suite/innodb/t/trx_id_future.test @@ -6,10 +6,9 @@ --source include/have_innodb.inc --source include/not_embedded.inc -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; let PAGE_SIZE=`select @@innodb_page_size`; -CREATE TABLE t1(a INT) row_format=redundant engine=innoDB; +CREATE TABLE t1(a INT) row_format=redundant engine=innoDB stats_persistent=0; INSERT INTO t1 VALUES(1); let MYSQLD_DATADIR=`select @@datadir`; diff --git a/mysql-test/suite/innodb/t/undo_log.test b/mysql-test/suite/innodb/t/undo_log.test index 150d50c2e75..60da94c39eb 100644 --- a/mysql-test/suite/innodb/t/undo_log.test +++ b/mysql-test/suite/innodb/t/undo_log.test @@ -1,5 +1,8 @@ --source include/have_innodb.inc +SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = 0; + SET innodb_strict_mode=OFF; CREATE TABLE test_tab ( a_str_18 mediumtext, @@ -141,8 +144,6 @@ SELECT COUNT(*) FROM test_tab; CHECK TABLE test_tab; DROP TABLE test_tab; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; CREATE TEMPORARY TABLE t2(i INT)ENGINE=InnoDB; CREATE TABLE t1(i TEXT NOT NULL) ENGINE=INNODB; BEGIN; @@ -153,4 +154,5 @@ ROLLBACK; --source include/wait_all_purged.inc DROP TABLE t1; DROP TABLE t2; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; + +SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/t/undo_space_dblwr.opt b/mysql-test/suite/innodb/t/undo_space_dblwr.opt new file mode 100644 index 00000000000..f498dd1fc93 --- /dev/null +++ b/mysql-test/suite/innodb/t/undo_space_dblwr.opt @@ -0,0 +1,3 @@ +--innodb_undo_tablespaces=3 +--innodb_sys_tablespaces +--innodb-stats-persistent=0 diff --git a/mysql-test/suite/innodb/t/undo_space_dblwr.test b/mysql-test/suite/innodb/t/undo_space_dblwr.test new file mode 100644 index 00000000000..b6fd6738a1c --- /dev/null +++ b/mysql-test/suite/innodb/t/undo_space_dblwr.test @@ -0,0 +1,46 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/not_embedded.inc +call mtr.add_suppression("Checksum mismatch in the first page of file"); +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; + +show variables like 'innodb_doublewrite'; +create table t1(f1 int not null, f2 int not null)engine=innodb; +insert into t1 values (1, 1); + +--source include/wait_all_purged.inc + +set GLOBAL innodb_log_checkpoint_now=1; +--source ../include/no_checkpoint_start.inc + +--echo # Make the first page dirty for undo tablespace +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 1; + +SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0; +SET GLOBAL innodb_max_dirty_pages_pct=0.0; + +sleep 1; +--let CLEANUP_IF_CHECKPOINT=drop table t1; +--source ../include/no_checkpoint_end.inc + +perl; +use IO::Handle; +my $fname= "$ENV{'MYSQLD_DATADIR'}/undo001"; +my $page_size = $ENV{INNODB_PAGE_SIZE}; +die unless open(FILE, "+<", $fname); +sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n"; +substr($page, 49, 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 +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_PATTERN= Checksum mismatch in the first page of file; +--source include/search_pattern_in_file.inc + +check table t1; +drop table t1; diff --git a/mysql-test/suite/innodb/t/undo_truncate.test b/mysql-test/suite/innodb/t/undo_truncate.test index eeffb6622c1..18cc4f36896 100644 --- a/mysql-test/suite/innodb/t/undo_truncate.test +++ b/mysql-test/suite/innodb/t/undo_truncate.test @@ -17,7 +17,6 @@ let $restart_parameters="--innodb_undo_tablespaces=2"; --source include/restart_mysqld.inc SET GLOBAL innodb_undo_log_truncate = 0; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; LET $MYSQLD_DATADIR = `select @@datadir`; LET $INNODB_PAGE_SIZE = `select @@innodb_page_size`; @@ -57,7 +56,6 @@ connection default; let $trx_before= `SHOW ENGINE INNODB STATUS`; let $trx_before= `select substr('$trx_before',9)+2`; -SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SET GLOBAL innodb_max_purge_lag_wait=0; set global innodb_fast_shutdown=0; let $restart_parameters=; diff --git a/mysql-test/suite/innodb/t/undo_truncate_recover.test b/mysql-test/suite/innodb/t/undo_truncate_recover.test index 1b27b0fe6e4..148c3f939d0 100644 --- a/mysql-test/suite/innodb/t/undo_truncate_recover.test +++ b/mysql-test/suite/innodb/t/undo_truncate_recover.test @@ -17,7 +17,6 @@ let $restart_parameters="--innodb_undo_tablespaces=2"; --source include/restart_mysqld.inc SET GLOBAL innodb_undo_log_truncate = 1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err; diff --git a/mysql-test/suite/innodb/t/undo_upgrade.test b/mysql-test/suite/innodb/t/undo_upgrade.test index 952d8b72b69..9c0da017fa7 100644 --- a/mysql-test/suite/innodb/t/undo_upgrade.test +++ b/mysql-test/suite/innodb/t/undo_upgrade.test @@ -15,23 +15,7 @@ call mtr.add_suppression("InnoDB: Cannot change innodb_undo_tablespaces=\\d+ bec let $MYSQLD_DATADIR= `select @@datadir`; CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; -connect(con_purge,localhost,root,,,); -START TRANSACTION WITH CONSISTENT SNAPSHOT; - -connection default; -INSERT INTO t1 VALUES(1); -UPDATE t1 SET f1=100; - -let $restart_parameters=--innodb_undo_tablespaces=2; ---echo # case 1: Undo log left to purge ---source include/restart_mysqld.inc ---echo # Display 4 undo tablespaces -select @@global.innodb_undo_tablespaces; - ---echo # Should list 4 undo log tablespaces -list_files $MYSQLD_DATADIR undo*; - ---echo # case 2: XA transaction alone left +--echo # case 1: XA transaction alone left --source include/wait_all_purged.inc XA START 'zombie'; INSERT INTO t1 VALUES(2); @@ -48,7 +32,7 @@ list_files $MYSQLD_DATADIR undo*; XA COMMIT 'zombie'; ---echo # case 3: Successful innodb_undo_tablespace upgrade +--echo # case 2: Successful innodb_undo_tablespace upgrade SET GLOBAL innodb_fast_shutdown=0; let $restart_parameters=--innodb_undo_tablespaces=2; @@ -63,7 +47,7 @@ list_files $MYSQLD_DATADIR undo*; DROP TABLE t1; --source include/wait_all_purged.inc ---echo # case 4: Reduce the innodb_undo_tablespace to 0 +--echo # case 3: Reduce the innodb_undo_tablespace to 0 let $restart_parameters=--innodb_undo_tablespaces=0; --source include/restart_mysqld.inc @@ -73,7 +57,7 @@ SELECT @@global.innodb_undo_tablespaces; --echo # Shouldn't list any undo log tablespaces list_files $MYSQLD_DATADIR undo*; ---echo # case 5: Change undo tablespace when force_recovery < 5 +--echo # case 4: Change undo tablespace when force_recovery < 5 let $restart_parameters=--innodb_undo_tablespaces=2 --innodb_force_recovery=4; --source include/restart_mysqld.inc @@ -83,7 +67,7 @@ SELECT @@global.innodb_undo_tablespaces; --echo # Should list 2 undo log tablespaces list_files $MYSQLD_DATADIR undo*; ---echo # case 6: Fail to change undo tablespace when force_recovery > 4 +--echo # case 5: Fail to change undo tablespace when force_recovery > 4 let $restart_parameters=--innodb_undo_tablespaces=4 --innodb_force_recovery=5; --source include/restart_mysqld.inc diff --git a/mysql-test/suite/innodb_fts/r/crash_recovery.result b/mysql-test/suite/innodb_fts/r/crash_recovery.result index 52a58c7034d..d7a8ef85646 100644 --- a/mysql-test/suite/innodb_fts/r/crash_recovery.result +++ b/mysql-test/suite/innodb_fts/r/crash_recovery.result @@ -33,10 +33,7 @@ connection default; disconnect ddl1; disconnect ddl2; disconnect ddl3; -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; -InnoDB 0 transactions not purged -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_max_purge_lag_wait=0; CHECK TABLE t1,t2,t3; Table Op Msg_type Msg_text test.t1 check status OK 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-ddl.result b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result index 18be4423398..05b9fa4053b 100644 --- a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result +++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result @@ -318,3 +318,16 @@ DROP TABLE t1; disconnect con1; SET GLOBAL innodb_optimize_fulltext_only=OFF; SET GLOBAL innodb_ft_aux_table = default; +# +# MDEV-32017 Auto-increment no longer works for +# explicit FTS_DOC_ID +# +CREATE TABLE t ( +FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, +f1 char(255), f2 char(255), f3 char(255), fulltext key (f3) +) ENGINE=InnoDB; +INSERT INTO t (f1,f2,f3) VALUES ('foo','bar','baz'); +ALTER TABLE t ADD FULLTEXT INDEX ft1(f1); +ALTER TABLE t ADD FULLTEXT INDEX ft2(f2); +INSERT INTO t (f1,f2,f3) VALUES ('bar','baz','qux'); +DROP TABLE t; 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 0cbe1090e89..32bb1c80010 100644 --- a/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result +++ b/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result @@ -132,6 +132,7 @@ AGAINST ('"xyz blob"@3' IN BOOLEAN MODE); count(*) 2 DROP TABLE t1; +set names utf8; CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, a TEXT, @@ -158,7 +159,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); @@ -173,7 +174,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..1087f25b2cd --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/misc_1.result @@ -0,0 +1,920 @@ +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; +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; +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..c050a4da60a --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/opt.result @@ -0,0 +1,1657 @@ +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 fulltext PRIMARY,FTS_DOC_ID_INDEX,ft_idx ft_idx 0 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, + "cost": 0.00009287, + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "fulltext", + "possible_keys": ["f1"], + "key": "f1", + "key_length": "0", + "used_key_parts": ["f1"], + "loops": 1, + "rows": 1, + "cost": 0.00009287, + "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..21f2505467d --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/misc_1.test @@ -0,0 +1,888 @@ +--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 +#------------------------------------------------------------------------------ + +# 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; + +#------------------------------------------------------------------------------ +# 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/innodb_zip/r/blob.result b/mysql-test/suite/innodb_zip/r/blob.result index bfe96b8a869..5671e81aafe 100644 --- a/mysql-test/suite/innodb_zip/r/blob.result +++ b/mysql-test/suite/innodb_zip/r/blob.result @@ -2,10 +2,8 @@ # MDEV-21259 Assertion 'w != NORMAL || mach_read_from_4(ptr) != val' # failed in mtr_t::write(), btr_free_externally_stored_field() # -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; CREATE TABLE t1 (c TEXT, f2 INT PRIMARY KEY, f3 INT UNIQUE) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET @level= @@GLOBAL.innodb_compression_level; SET GLOBAL innodb_compression_level=0; connect prevent_purge,localhost,root; @@ -18,4 +16,3 @@ disconnect prevent_purge; InnoDB 0 transactions not purged DROP TABLE t1; SET GLOBAL innodb_compression_level = @level; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/innodb_zip/r/restart.result b/mysql-test/suite/innodb_zip/r/restart.result index 133cf020d55..27316d6c619 100644 --- a/mysql-test/suite/innodb_zip/r/restart.result +++ b/mysql-test/suite/innodb_zip/r/restart.result @@ -532,15 +532,6 @@ Space_Name Page_Size Zip_Size Path innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001 innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002 innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003 -test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd -test/t6_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd -test/t6_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd -test/t7_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd -test/t7_restart#p#p0#sp#s1 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd -test/t5_restart DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd -test/t6_restart#p#p2 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd -test/t7_restart#p#p1#sp#s2 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd -test/t7_restart#p#p1#sp#s3 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1 SELECT count(*) FROM t5_restart; count(*) @@ -637,7 +628,6 @@ Space_Name Page_Size Zip_Size Path innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001 innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002 innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003 -test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd test/t77_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd @@ -736,15 +726,6 @@ Space_Name Page_Size Zip_Size Path innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001 innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002 innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003 -test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd -test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd -test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd -test/t77_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd -test/t77_restart#p#p0#sp#s1 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd -test/t55_restart DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd -test/t66_restart#p#p2 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p2.ibd -test/t77_restart#p#p1#sp#s2 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd -test/t77_restart#p#p1#sp#s3 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1 INSERT INTO t55_restart (SELECT 0, c2, c3, c4, c5 FROM t55_restart); SELECT count(*) FROM t55_restart; @@ -874,15 +855,6 @@ Space_Name Page_Size Zip_Size Path innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001 innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002 innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003 -test/t4_restart DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd -test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p0.ibd -test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p1.ibd -test/t77_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s0.ibd -test/t77_restart#p#p0#sp#s1 DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s1.ibd -test/t55_restart DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t55_restart.ibd -test/t66_restart#p#p2 DEFAULT 2048 MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p2.ibd -test/t77_restart#p#p1#sp#s2 DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s2.ibd -test/t77_restart#p#p1#sp#s3 DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s3.ibd innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1 INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart); SELECT count(*) FROM t4_restart; @@ -1016,15 +988,6 @@ Space_Name Page_Size Zip_Size Path innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001 innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002 innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003 -test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd -test/t66_restart#p#p0 DEFAULT 2048 MYSQLD_DATADIR/test/t66_restart#p#p0.ibd -test/t66_restart#p#p1 DEFAULT 2048 MYSQLD_DATADIR/test/t66_restart#p#p1.ibd -test/t77_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s0.ibd -test/t77_restart#p#p0#sp#s1 DEFAULT DEFAULT MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s1.ibd -test/t55_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t55_restart.ibd -test/t66_restart#p#p2 DEFAULT 2048 MYSQLD_DATADIR/test/t66_restart#p#p2.ibd -test/t77_restart#p#p1#sp#s2 DEFAULT DEFAULT MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s2.ibd -test/t77_restart#p#p1#sp#s3 DEFAULT DEFAULT MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s3.ibd innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1 INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart); SELECT count(*) FROM t4_restart; diff --git a/mysql-test/suite/innodb_zip/t/blob.test b/mysql-test/suite/innodb_zip/t/blob.test index b85cf7313d0..461b451fdec 100644 --- a/mysql-test/suite/innodb_zip/t/blob.test +++ b/mysql-test/suite/innodb_zip/t/blob.test @@ -5,11 +5,8 @@ --echo # failed in mtr_t::write(), btr_free_externally_stored_field() --echo # -SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; - CREATE TABLE t1 (c TEXT, f2 INT PRIMARY KEY, f3 INT UNIQUE) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET @level= @@GLOBAL.innodb_compression_level; SET GLOBAL innodb_compression_level=0; @@ -26,4 +23,3 @@ REPLACE INTO t1 SELECT * FROM t1; DROP TABLE t1; SET GLOBAL innodb_compression_level = @level; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/innodb_zip/t/restart.opt b/mysql-test/suite/innodb_zip/t/restart.opt index d7564300c09..03fb84e94a6 100644 --- a/mysql-test/suite/innodb_zip/t/restart.opt +++ b/mysql-test/suite/innodb_zip/t/restart.opt @@ -1,2 +1,5 @@ ---loose-innodb-sys-tables ---loose-innodb-sys-tablespaces +--innodb-sys-tables +--innodb-sys-tablespaces +--skip-innodb-stats-persistent +--skip-innodb-buffer-pool-dump-at-shutdown +--skip-innodb-fast-shutdown diff --git a/mysql-test/suite/maria/ctype_utf8mb3_uca.result b/mysql-test/suite/maria/ctype_utf8mb3_uca.result new file mode 100644 index 00000000000..70fff258316 --- /dev/null +++ b/mysql-test/suite/maria/ctype_utf8mb3_uca.result @@ -0,0 +1,75 @@ +# +# Start of 10.4 tests +# +SET default_storage_engine=Aria; +# +# MDEV-30048 Prefix keys for CHAR work differently for MyISAM vs InnoDB +# +SET NAMES utf8mb3; +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(10) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(2))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`(2)) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(120) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(120) COLLATE utf8mb3_unicode_nopad_ci, UNIQUE KEY(a(100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(120) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL, + UNIQUE KEY `a` (`a`(100)) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +INSERT INTO t1 VALUES ('ss'),('ß'); +DROP TABLE t1; +# +# MDEV-30050 Inconsistent results of DISTINCT with NOPAD +# +CREATE TABLE t1 (c CHAR(100) COLLATE utf8mb3_unicode_nopad_ci); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +INSERT INTO t1 VALUES ('ss'),('ß'); +SET big_tables=0; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +SET big_tables=1; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +SELECT DISTINCT c FROM t1; +c +ss +ß +DROP TABLE t1; +SET big_tables=DEFAULT; +Warnings: +Warning 1287 '@@big_tables' is deprecated and will be removed in a future release +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/maria/ctype_utf8mb3_uca.test b/mysql-test/suite/maria/ctype_utf8mb3_uca.test new file mode 100644 index 00000000000..21cec59008b --- /dev/null +++ b/mysql-test/suite/maria/ctype_utf8mb3_uca.test @@ -0,0 +1,12 @@ +--source include/have_maria.inc + +--echo # +--echo # Start of 10.4 tests +--echo # + +SET default_storage_engine=Aria; +--source include/ctype_utf8mb3_uca_char.inc + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/suite/maria/icp.result b/mysql-test/suite/maria/icp.result index a421ba6d3ea..ea546b5c7ef 100644 --- a/mysql-test/suite/maria/icp.result +++ b/mysql-test/suite/maria/icp.result @@ -151,7 +151,7 @@ INSERT INTO t1 VALUES # Execute select with invalid timestamp, desc ordering SELECT * -FROM t1 +FROM t1 FORCE INDEX(PRIMARY) WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; @@ -162,7 +162,7 @@ ts c # Should use index condition EXPLAIN SELECT * -FROM t1 +FROM t1 FORCE INDEX(PRIMARY) WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; @@ -424,6 +424,12 @@ CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL); INSERT INTO t2 VALUES (11,1); INSERT INTO t2 VALUES (12,2); INSERT INTO t2 VALUES (15,4); +analyze table t1,t2 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK set @save_optimizer_switch= @@optimizer_switch; set optimizer_switch='semijoin=off'; EXPLAIN @@ -693,6 +699,12 @@ CREATE TABLE t2 (a varchar(1024), KEY (a(512))); INSERT INTO t2 VALUES ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w'); insert into t2 select seq from seq_1_to_100; +analyze table t1,t2 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK SET SESSION optimizer_switch='index_condition_pushdown=off'; EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) 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/full_backup.result b/mysql-test/suite/mariabackup/full_backup.result index 1d0dffd528d..71525c22080 100644 --- a/mysql-test/suite/mariabackup/full_backup.result +++ b/mysql-test/suite/mariabackup/full_backup.result @@ -18,6 +18,12 @@ DROP TABLE t; # call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces"); call mtr.add_suppression("InnoDB: Cannot change innodb_undo_tablespaces=0 because previous shutdown was not with innodb_fast_shutdown=0"); +call mtr.add_suppression("Found 1 prepared XA transactions"); +CREATE TABLE t(f1 INT NOT NULL)ENGINE=InnoDB; +XA START 'zombie'; +INSERT INTO t VALUES(1); +XA END 'zombie'; +XA PREPARE 'zombie'; # restart: --innodb_undo_tablespaces=0 # xtrabackup backup # xtrabackup prepare @@ -28,3 +34,5 @@ call mtr.add_suppression("InnoDB: Cannot change innodb_undo_tablespaces=0 becaus # Display undo log files from target directory undo001 undo002 +XA COMMIT 'zombie'; +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/full_backup.test b/mysql-test/suite/mariabackup/full_backup.test index fb043f63be0..c6a21112b60 100644 --- a/mysql-test/suite/mariabackup/full_backup.test +++ b/mysql-test/suite/mariabackup/full_backup.test @@ -35,6 +35,13 @@ rmdir $targetdir; --echo # call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces"); call mtr.add_suppression("InnoDB: Cannot change innodb_undo_tablespaces=0 because previous shutdown was not with innodb_fast_shutdown=0"); +call mtr.add_suppression("Found 1 prepared XA transactions"); + +CREATE TABLE t(f1 INT NOT NULL)ENGINE=InnoDB; +XA START 'zombie'; +INSERT INTO t VALUES(1); +XA END 'zombie'; +XA PREPARE 'zombie'; let $restart_parameters=--innodb_undo_tablespaces=0; --source include/restart_mysqld.inc @@ -53,4 +60,6 @@ exec $XTRABACKUP --prepare --target-dir=$targetdir; --echo # Display undo log files from target directory list_files $targetdir undo*; +XA COMMIT 'zombie'; +DROP TABLE t; rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/log_page_corruption.result b/mysql-test/suite/mariabackup/log_page_corruption.result index f2a88ea4bdf..3772a6c0003 100644 --- a/mysql-test/suite/mariabackup/log_page_corruption.result +++ b/mysql-test/suite/mariabackup/log_page_corruption.result @@ -26,6 +26,17 @@ INSERT INTO t7_corrupted_to_alter VALUES (3), (4), (5), (6), (7), (8), (9); # Backup must fail due to page corruption FOUND 1 /Database page corruption detected.*/ in backup.log # "innodb_corrupted_pages" file must not exist +# Backup must not fail, but "innodb_corrupted_pages" file must be created due to --log-innodb-page-corruption option, and the file must contain all corrupted pages info, including those, which are supposed to be absent in the next test due to "DROP TABLE" execution during backup +--- "innodb_corrupted_pages" file content: --- +test/t1_corrupted +4 6 7 +test/t2_corrupted +5 6 8 +test/t5_corrupted_to_rename +4 +test/t6_corrupted_to_drop +4 +------ # Backup must not fail, but "innodb_corrupted_pages" file must be created due to --log-innodb-page-corruption option FOUND 1 /Database page corruption detected.*/ in backup.log FOUND 1 /completed OK!/ in backup.log @@ -45,6 +56,23 @@ INSERT INTO t1_inc_corrupted VALUES (3), (4), (5), (6), (7), (8), (9); INSERT INTO t2_inc_corrupted VALUES (3), (4), (5), (6), (7), (8), (9); INSERT INTO t3_inc VALUES (3), (4), (5), (6), (7), (8), (9); # restart +# Backup must not fail, but "innodb_corrupted_pages" file must be created due to --log-innodb-page-corruption option, and the file must contain all corrupted pages info, including those, which are supposed to be absent in the next test due to "DROP TABLE" execution during backup +--- "innodb_corrupted_pages" file content: --- +test/t1_corrupted +4 6 7 +test/t1_inc_corrupted +4 6 7 +test/t2_corrupted +5 6 8 +test/t2_inc_corrupted +5 6 8 +test/t5_corrupted_to_rename_renamed +4 +test/t5_inc_corrupted_to_rename +4 +test/t6_inc_corrupted_to_drop +4 +------ # Backup must not fail, but "innodb_corrupted_pages" file must be created due to --log-innodb-page-corruption option --- "innodb_corrupted_pages" file content: --- test/t1_corrupted diff --git a/mysql-test/suite/mariabackup/log_page_corruption.test b/mysql-test/suite/mariabackup/log_page_corruption.test index 2b101529039..18d773bd480 100644 --- a/mysql-test/suite/mariabackup/log_page_corruption.test +++ b/mysql-test/suite/mariabackup/log_page_corruption.test @@ -50,7 +50,7 @@ corrupt_space_page_id("$schema/t2_corrupted.ibd", $last_page_no = extend_space("$schema/t5_corrupted_to_rename.ibd", 1); corrupt_space_page_id("$schema/t5_corrupted_to_rename.ibd", $last_page_no); -$last_page_no = extend_space("$schema/t6_corrupted_to_drop.ibd", ); +$last_page_no = extend_space("$schema/t6_corrupted_to_drop.ibd", 1); corrupt_space_page_id("$schema/t6_corrupted_to_drop.ibd", $last_page_no); EOF --source include/start_mysqld.inc @@ -75,6 +75,21 @@ exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir= --file_exists $corrupted_pages_file --rmdir $targetdir +--echo # Backup must not fail, but "innodb_corrupted_pages" file must be created due to --log-innodb-page-corruption option, and the file must contain all corrupted pages info, including those, which are supposed to be absent in the next test due to "DROP TABLE" execution during backup +--disable_result_log +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --log-innodb-page-corruption --target-dir=$targetdir +--enable_result_log + +--echo --- "innodb_corrupted_pages" file content: --- +perl; +do "$ENV{MTR_SUITE_DIR}/include/corrupt-page.pl"; +print_corrupted_pages_file($ENV{corrupted_pages_file}, + $ENV{corrupted_pages_file_filt}); +EOF +--cat_file $corrupted_pages_file_filt +--echo ------ +--rmdir $targetdir + --let after_load_tablespaces=CREATE TABLE test.t4_corrupted_new ENGINE=INNODB SELECT UUID() from test.seq_1_to_10 --let add_corrupted_page_for_test_t4_corrupted_new=1 --let after_copy_test_t5_corrupted_to_rename=RENAME TABLE test.t5_corrupted_to_rename TO test.t5_corrupted_to_rename_renamed @@ -135,7 +150,7 @@ $last_page_no = extend_space("$schema/t5_inc_corrupted_to_rename.ibd", 1); corrupt_space_page_id("$schema/t5_inc_corrupted_to_rename.ibd", $last_page_no); print $fh "$last_page_no\n"; -$last_page_no = extend_space("$schema/t6_inc_corrupted_to_drop.ibd", ); +$last_page_no = extend_space("$schema/t6_inc_corrupted_to_drop.ibd", 1); corrupt_space_page_id("$schema/t6_inc_corrupted_to_drop.ibd", $last_page_no); close $fh; @@ -144,6 +159,23 @@ EOF --let incdir=$MYSQLTEST_VARDIR/tmp/backup_inc +--echo # Backup must not fail, but "innodb_corrupted_pages" file must be created due to --log-innodb-page-corruption option, and the file must contain all corrupted pages info, including those, which are supposed to be absent in the next test due to "DROP TABLE" execution during backup +--disable_result_log +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --log-innodb-page-corruption --target-dir=$incdir --incremental-basedir=$targetdir --dbug=+d,mariabackup_events,mariabackup_inject_code +--disable_result_log + +--let corrupted_pages_file = $incdir/innodb_corrupted_pages +--echo --- "innodb_corrupted_pages" file content: --- +perl; +do "$ENV{MTR_SUITE_DIR}/include/corrupt-page.pl"; +print_corrupted_pages_file($ENV{corrupted_pages_file}, + $ENV{corrupted_pages_file_filt}); +EOF +--cat_file $corrupted_pages_file_filt +--echo ------ +--remove_file $corrupted_pages_file_filt +--rmdir $incdir + --let after_load_tablespaces=CREATE TABLE test.t4_inc_corrupted_new ENGINE=INNODB SELECT UUID() from test.seq_1_to_10 --let add_corrupted_page_for_test_t4_inc_corrupted_new=1 --let after_copy_test_t5_inc_corrupted_to_rename=RENAME TABLE test.t5_inc_corrupted_to_rename TO test.t5_inc_corrupted_to_rename_renamed 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..445a98019b0 --- /dev/null +++ b/mysql-test/suite/mariabackup/slave_provision_nolock.result @@ -0,0 +1,48 @@ +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; +Warnings: +Note 4190 CHANGE MASTER TO is implicitly changing the value of 'Using_Gtid' from 'Slave_Pos' to 'No' +START SLAVE; +connection default; +connection server2; +connection server2; +STOP SLAVE; +RESET SLAVE ALL; +Warnings: +Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos' +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/mariabackup/unencrypted_page_compressed.result b/mysql-test/suite/mariabackup/unencrypted_page_compressed.result index 7edf66b027a..dfcf19b6c2b 100644 --- a/mysql-test/suite/mariabackup/unencrypted_page_compressed.result +++ b/mysql-test/suite/mariabackup/unencrypted_page_compressed.result @@ -1,6 +1,6 @@ call mtr.add_suppression("InnoDB: Table `test`.`t1` has an unreadable root page"); -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; -CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) ENGINE=InnoDB page_compressed=yes; +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) +ENGINE=InnoDB PAGE_COMPRESSED=YES STATS_PERSISTENT=0; insert into t1(b, c) values("mariadb", "mariabackup"); InnoDB 0 transactions not purged # Corrupt the table diff --git a/mysql-test/suite/mariabackup/unencrypted_page_compressed.test b/mysql-test/suite/mariabackup/unencrypted_page_compressed.test index ce5c94a1c57..700c4dd2034 100644 --- a/mysql-test/suite/mariabackup/unencrypted_page_compressed.test +++ b/mysql-test/suite/mariabackup/unencrypted_page_compressed.test @@ -1,6 +1,6 @@ call mtr.add_suppression("InnoDB: Table `test`.`t1` has an unreadable root page"); -SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; -CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) ENGINE=InnoDB page_compressed=yes; +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) +ENGINE=InnoDB PAGE_COMPRESSED=YES STATS_PERSISTENT=0; insert into t1(b, c) values("mariadb", "mariabackup"); --source ../innodb/include/wait_all_purged.inc 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/parts/r/partition_alter_innodb.result b/mysql-test/suite/parts/r/partition_alter_innodb.result index f040f266ce0..03e7d078d51 100644 --- a/mysql-test/suite/parts/r/partition_alter_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter_innodb.result @@ -71,7 +71,8 @@ DROP TABLE t1; # # MDEV-28079 Shutdown hangs after altering innodb partition fts table # -CREATE TABLE t1(f1 INT, f2 CHAR(100))ENGINE=InnoDB PARTITION BY HASH(f1) PARTITIONS 2; +CREATE TABLE t1(f1 INT, f2 CHAR(100))ENGINE=InnoDB STATS_PERSISTENT=0 +PARTITION BY HASH(f1) PARTITIONS 2; ALTER TABLE t1 ADD FULLTEXT(f2); InnoDB 0 transactions not purged DROP TABLE t1; diff --git a/mysql-test/suite/parts/r/partition_purge.result b/mysql-test/suite/parts/r/partition_purge.result index 072b141cd8d..a58e095db04 100644 --- a/mysql-test/suite/parts/r/partition_purge.result +++ b/mysql-test/suite/parts/r/partition_purge.result @@ -1,4 +1,4 @@ -CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB +CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB STATS_PERSISTENT=0 PARTITION BY LIST(f1) ( PARTITION p1 VALUES in (1, 2, 3), PARTITION p2 VALUES in (4, 5, 6)); diff --git a/mysql-test/suite/parts/r/partition_special_innodb.result b/mysql-test/suite/parts/r/partition_special_innodb.result index 2f056de2b7a..504989e25a1 100644 --- a/mysql-test/suite/parts/r/partition_special_innodb.result +++ b/mysql-test/suite/parts/r/partition_special_innodb.result @@ -269,6 +269,7 @@ Table Op Msg_type Msg_text test.t1 check status OK connection default; UNLOCK TABLES; +SET GLOBAL innodb_max_purge_lag_wait=0; connection con2; DROP TABLE t1; connection default; @@ -348,6 +349,7 @@ SELECT * FROM t1; ERROR HY000: Lock wait timeout exceeded; try restarting transaction connection default; UNLOCK TABLES; +SET GLOBAL innodb_max_purge_lag_wait=0; connection con2; DROP TABLE t1; disconnect con2; diff --git a/mysql-test/suite/parts/t/partition_alter_innodb.test b/mysql-test/suite/parts/t/partition_alter_innodb.test index 844b2084531..dcc448631dc 100644 --- a/mysql-test/suite/parts/t/partition_alter_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter_innodb.test @@ -12,7 +12,8 @@ SET GLOBAL innodb_read_only_compressed=@save_innodb_read_only_compressed; --echo # --echo # MDEV-28079 Shutdown hangs after altering innodb partition fts table --echo # -CREATE TABLE t1(f1 INT, f2 CHAR(100))ENGINE=InnoDB PARTITION BY HASH(f1) PARTITIONS 2; +CREATE TABLE t1(f1 INT, f2 CHAR(100))ENGINE=InnoDB STATS_PERSISTENT=0 +PARTITION BY HASH(f1) PARTITIONS 2; ALTER TABLE t1 ADD FULLTEXT(f2); --source ../innodb/include/wait_all_purged.inc DROP TABLE t1; diff --git a/mysql-test/suite/parts/t/partition_purge.test b/mysql-test/suite/parts/t/partition_purge.test index 2df81b0eb77..054ecf479aa 100644 --- a/mysql-test/suite/parts/t/partition_purge.test +++ b/mysql-test/suite/parts/t/partition_purge.test @@ -3,7 +3,7 @@ --source include/have_debug.inc --source include/have_debug_sync.inc -CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB +CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB STATS_PERSISTENT=0 PARTITION BY LIST(f1) ( PARTITION p1 VALUES in (1, 2, 3), PARTITION p2 VALUES in (4, 5, 6)); diff --git a/mysql-test/suite/parts/t/partition_special_innodb.test b/mysql-test/suite/parts/t/partition_special_innodb.test index 6273cc5cb2a..836b7048ccf 100644 --- a/mysql-test/suite/parts/t/partition_special_innodb.test +++ b/mysql-test/suite/parts/t/partition_special_innodb.test @@ -114,6 +114,8 @@ CHECK TABLE t1; --connection default UNLOCK TABLES; +# Avoid a MDL conflict between purge and the DROP TABLE below +SET GLOBAL innodb_max_purge_lag_wait=0; --connection con2 DROP TABLE t1; @@ -222,6 +224,8 @@ SELECT * FROM t1; --connection default UNLOCK TABLES; +# Avoid a MDL conflict between purge and the DROP TABLE below +SET GLOBAL innodb_max_purge_lag_wait=0; --connection con2 DROP TABLE t1; 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/perfschema/include/wait_for_pfs_thread_count.inc b/mysql-test/suite/perfschema/include/wait_for_pfs_thread_count.inc index 2375bdf1cac..49489b495e5 100644 --- a/mysql-test/suite/perfschema/include/wait_for_pfs_thread_count.inc +++ b/mysql-test/suite/perfschema/include/wait_for_pfs_thread_count.inc @@ -4,17 +4,6 @@ # Wait until there is only one session left, this one. -let $wait_condition= - select count(*) = 1 from information_schema.processlist; ---source include/wait_condition.inc - -# Threads are removed from information_schema.processlist -# very soon, but continue to execute in the server, -# before finally be removed from performance_schema.threads. -# Because instrumentation is optional, we use "<=" here. - -let $wait_condition= - select count(*) <= 2 from performance_schema.threads - where `TYPE`='FOREGROUND'; +let $wait_condition= select count(*) = 1 from performance_schema.threads where `type`='foreground'; --source include/wait_condition.inc diff --git a/mysql-test/suite/perfschema/r/events_waits_current_MDEV-29091.result b/mysql-test/suite/perfschema/r/events_waits_current_MDEV-29091.result deleted file mode 100644 index 8f3a17a0fc5..00000000000 --- a/mysql-test/suite/perfschema/r/events_waits_current_MDEV-29091.result +++ /dev/null @@ -1,41 +0,0 @@ -SET default_storage_engine=InnoDB; -SELECT @save_instrument_enabled := ENABLED -, @save_instrument_timed := TIMED -FROM performance_schema.setup_instruments -WHERE NAME = 'wait/lock/table/sql/handler'; -@save_instrument_enabled := ENABLED @save_instrument_timed := TIMED -YES YES -SELECT @save_consumer_enabled := ENABLED -FROM performance_schema.setup_consumers -WHERE NAME = 'events_waits_current'; -@save_consumer_enabled := ENABLED -YES -UPDATE performance_schema.setup_instruments -SET ENABLED = 'YES', TIMED = 'YES' -WHERE NAME = 'wait/lock/table/sql/handler'; -UPDATE performance_schema.setup_consumers -SET ENABLED = 'YES' -WHERE NAME = 'events_waits_current'; -CREATE TABLE t1 (id1 INT(11), col1 VARCHAR (200)); -INSERT INTO t1 VALUES (1, 'aa'); -INSERT INTO t1 VALUES (2, 'bb'); -connect con1,localhost,root,,test; -connect con2,localhost,root,,test; -connection con1; -START TRANSACTION; -connection con2; -START TRANSACTION; -SELECT id1 FROM t1 WHERE id1=1 FOR UPDATE; -connection default; -SELECT event_name FROM performance_schema.events_waits_current -WHERE event_name LIKE '%wait/lock/table/sql/handler%'; -event_name -UPDATE performance_schema.setup_instruments -SET ENABLED = @save_instrument_enabled, TIMED = @save_instrument_timed -WHERE NAME = 'wait/lock/table/sql/handler'; -UPDATE performance_schema.setup_consumers -SET ENABLED = @save_consumer_enabled -WHERE NAME = 'events_waits_current'; -disconnect con1; -disconnect con2; -DROP TABLE t1; diff --git a/mysql-test/suite/perfschema/r/mdl_func.result b/mysql-test/suite/perfschema/r/mdl_func.result index 4887b15efa5..f3fc0d10a96 100644 --- a/mysql-test/suite/perfschema/r/mdl_func.result +++ b/mysql-test/suite/perfschema/r/mdl_func.result @@ -1,3 +1,4 @@ +# restart UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name in ('wait/io/table/sql/handler', diff --git a/mysql-test/suite/perfschema/r/show_aggregate.result b/mysql-test/suite/perfschema/r/show_aggregate.result index 69861fa42c9..3facb3c5f04 100644 --- a/mysql-test/suite/perfschema/r/show_aggregate.result +++ b/mysql-test/suite/perfschema/r/show_aggregate.result @@ -7,6 +7,7 @@ SET @@session.sql_log_bin=OFF; # CREATE 3 CLIENTS, 3 CONNECTIONS, RESULTS TABLE connection default; USE test; +flush status; # # Create results table CREATE TABLE test.status_results @@ -82,9 +83,9 @@ ROLLBACK; connection default; # Get thread ids for each connection. USE performance_schema; -SELECT thread_id INTO @con1_id FROM threads WHERE processlist_user IN ('user1'); -SELECT thread_id INTO @con2_id FROM threads WHERE processlist_user IN ('user2'); -SELECT thread_id INTO @con3_id FROM threads WHERE processlist_user IN ('user3'); +SELECT thread_id INTO @con1_id FROM threads WHERE processlist_user IN ('user1') and processlist_id; +SELECT thread_id INTO @con2_id FROM threads WHERE processlist_user IN ('user2') and processlist_id; +SELECT thread_id INTO @con3_id FROM threads WHERE processlist_user IN ('user3') and processlist_id; #================= # Global results #================= @@ -204,100 +205,99 @@ USE performance_schema; # # Verify expected counts for 'handler_delete' per thread # -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_thread WHERE thread_id = @con1_id AND variable_name IN ('handler_delete', 'handler_rollback'); +SELECT *, IF (variable_value = 1,'OK1','ERROR1') AS Expected FROM status_by_thread WHERE thread_id = @con1_id AND variable_name IN ('handler_delete', 'handler_rollback'); THREAD_ID VARIABLE_NAME VARIABLE_VALUE Expected -con_1 Handler_delete 1 OK -con_1 Handler_rollback 1 OK +con_1 Handler_delete 1 OK1 +con_1 Handler_rollback 1 OK1 # -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_thread WHERE thread_id = @con2_id AND variable_name IN ('handler_delete', 'handler_rollback'); +SELECT *, IF (variable_value = 2,'OK2','ERROR2') AS Expected FROM status_by_thread WHERE thread_id = @con2_id AND variable_name IN ('handler_delete', 'handler_rollback'); THREAD_ID VARIABLE_NAME VARIABLE_VALUE Expected -con_2 Handler_delete 2 OK -con_2 Handler_rollback 2 OK +con_2 Handler_delete 2 OK2 +con_2 Handler_rollback 2 OK2 # -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_thread WHERE thread_id = @con3_id AND variable_name IN ('handler_delete', 'handler_rollback'); +SELECT *, IF (variable_value = 3,'OK3','ERROR3') AS Expected FROM status_by_thread WHERE thread_id = @con3_id AND variable_name IN ('handler_delete', 'handler_rollback'); THREAD_ID VARIABLE_NAME VARIABLE_VALUE Expected -con_3 Handler_delete 3 OK -con_3 Handler_rollback 3 OK +con_3 Handler_delete 3 OK3 +con_3 Handler_rollback 3 OK3 # # STATUS_BY_THREAD vs. GLOBAL_STATUS # -SELECT variable_name, t1, t2, t3, delta, thread, IF(thread=delta,'OK','ERROR') Expected +SELECT variable_name, t1, t2, t3, delta, thread, IF(thread=delta,'OK4','ERROR4') Expected FROM test.status_results ORDER BY variable_name; variable_name t1 t2 t3 delta thread Expected -Handler_delete 1 2 3 6 6 OK -Handler_rollback 1 2 3 6 6 OK +Handler_delete 1 2 3 6 6 OK4 +Handler_rollback 1 2 3 6 6 OK4 # # ================================================================================ # TEST 2: STATUS_BY_USER: Verify expected status counts per user (1,2,3) # ================================================================================ -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user1') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 1,'OK5','ERROR5') AS Expected FROM status_by_user WHERE user IN ('user1') AND variable_name IN ('handler_delete'); USER VARIABLE_NAME VARIABLE_VALUE Expected -user1 Handler_delete 1 OK +user1 Handler_delete 1 OK5 # -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user2') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 2,'OK6','ERROR6') AS Expected FROM status_by_user WHERE user IN ('user2') AND variable_name IN ('handler_delete'); USER VARIABLE_NAME VARIABLE_VALUE Expected -user2 Handler_delete 2 OK +user2 Handler_delete 2 OK6 # -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user3') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 3,'OK7','ERROR7') AS Expected FROM status_by_user WHERE user IN ('user3') AND variable_name IN ('handler_delete'); USER VARIABLE_NAME VARIABLE_VALUE Expected -user3 Handler_delete 3 OK +user3 Handler_delete 3 OK7 # # STATUS_BY_USER vs. GLOBAL_STATUS # -SELECT variable_name, u1, u2, u3, delta, user, IF(user=delta,'OK','ERROR') Expected +SELECT variable_name, u1, u2, u3, delta, user, IF(user=delta,'OK8','ERROR8') Expected FROM test.status_results ORDER BY variable_name; variable_name u1 u2 u3 delta user Expected -Handler_delete 1 2 3 6 6 OK -Handler_rollback 1 2 3 6 6 OK +Handler_delete 1 2 3 6 6 OK8 +Handler_rollback 1 2 3 6 6 OK8 # # ================================================================================ # TEST 3: STATUS_BY_ACCOUNT: Verify expected status counts per user, host (1,2,3) # ================================================================================ -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user1') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 1,'OK9','ERROR9') AS Expected FROM status_by_account WHERE user IN ('user1') AND variable_name IN ('handler_delete'); USER HOST VARIABLE_NAME VARIABLE_VALUE Expected -user1 localhost Handler_delete 1 OK +user1 localhost Handler_delete 1 OK9 # -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user2') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 2,'OKa','ERRORa') AS Expected FROM status_by_account WHERE user IN ('user2') AND variable_name IN ('handler_delete'); USER HOST VARIABLE_NAME VARIABLE_VALUE Expected -user2 localhost Handler_delete 2 OK +user2 localhost Handler_delete 2 OKa # -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user3') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 3,'OKb','ERRORb') AS Expected FROM status_by_account WHERE user IN ('user3') AND variable_name IN ('handler_delete'); USER HOST VARIABLE_NAME VARIABLE_VALUE Expected -user3 localhost Handler_delete 3 OK +user3 localhost Handler_delete 3 OKb # # STATUS_BY_ACCOUNT vs. GLOBAL_STATUS # -SELECT variable_name, a1, a2, a3, delta, acct, IF(acct=delta,'OK','ERROR') Expected +SELECT variable_name, a1, a2, a3, delta, acct, IF(acct=delta,'OKc','ERRORc') Expected FROM test.status_results ORDER BY variable_name; variable_name a1 a2 a3 delta acct Expected -Handler_delete 1 2 3 6 6 OK -Handler_rollback 1 2 3 6 6 OK +Handler_delete 1 2 3 6 6 OKc +Handler_rollback 1 2 3 6 6 OKc # ================================================================================ # TEST 4: STATUS_BY_HOST: Verify expected status counts per host (6) # ================================================================================ -SELECT *, IF (variable_value = 6,'OK','ERROR') AS Expected FROM status_by_host WHERE host IN ('localhost') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 6,'OKd','ERRORd') AS Expected FROM status_by_host WHERE host IN ('localhost') AND variable_name IN ('handler_delete'); HOST VARIABLE_NAME VARIABLE_VALUE Expected -localhost Handler_delete 6 OK +localhost Handler_delete 6 OKd # # STATUS_BY_HOST vs. GLOBAL_STATUS # # Special case: No way to isolate pre-existing 'localhost' activity, so # just check global totals = sum(status_by_host). # -SELECT variable_name, h1, h2, h3, delta, host, IF(host=delta,'OK','ERROR') Expected +SELECT variable_name, h1, h2, h3, delta, host, IF(host=delta,'OKe','ERRORe') Expected FROM test.status_results ORDER BY variable_name; variable_name h1 h2 h3 delta host Expected -Handler_delete 6 0 0 6 6 OK -Handler_rollback 6 0 0 6 6 OK +Handler_delete 6 0 0 6 6 OKe +Handler_rollback 6 0 0 6 6 OKe # # ================================================================================ # DISCONNECT ALL USERS AND RUN THE TESTS AGAIN. RESULTS SHOULD NOT CHANGE. # ================================================================================ -connection default; disconnect con1; disconnect con2; disconnect con3; @@ -429,68 +429,68 @@ USE performance_schema; # ================================================================================ # TEST 5: STATUS_BY_USER: Verify expected status counts per user (1,2,3) # ================================================================================ -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user1') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 1,'OKf','ERRORf') AS Expected FROM status_by_user WHERE user IN ('user1') AND variable_name IN ('handler_delete'); USER VARIABLE_NAME VARIABLE_VALUE Expected -user1 Handler_delete 1 OK +user1 Handler_delete 1 OKf # -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user2') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 2,'OKg','ERRORg') AS Expected FROM status_by_user WHERE user IN ('user2') AND variable_name IN ('handler_delete'); USER VARIABLE_NAME VARIABLE_VALUE Expected -user2 Handler_delete 2 OK +user2 Handler_delete 2 OKg # -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user3') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 3,'OKh','ERRORh') AS Expected FROM status_by_user WHERE user IN ('user3') AND variable_name IN ('handler_delete'); USER VARIABLE_NAME VARIABLE_VALUE Expected -user3 Handler_delete 3 OK +user3 Handler_delete 3 OKh # # STATUS_BY_USER vs. GLOBAL_STATUS # -SELECT variable_name, u1, u2, u3, delta, user, IF(user=delta,'OK','ERROR') Expected +SELECT variable_name, u1, u2, u3, delta, user, IF(user=delta,'OKi','ERRORi') Expected FROM test.status_results ORDER BY variable_name; variable_name u1 u2 u3 delta user Expected -Handler_delete 1 2 3 6 6 OK -Handler_rollback 1 2 3 6 6 OK +Handler_delete 1 2 3 6 6 OKi +Handler_rollback 1 2 3 6 6 OKi # # ================================================================================ # TEST 6: STATUS_BY_ACCOUNT: Verify expected status counts per user:host (1,2,3) # ================================================================================ -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user1') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 1,'OKj','ERRORj') AS Expected FROM status_by_account WHERE user IN ('user1') AND variable_name IN ('handler_delete'); USER HOST VARIABLE_NAME VARIABLE_VALUE Expected -user1 localhost Handler_delete 1 OK +user1 localhost Handler_delete 1 OKj # -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user2') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 2,'OKk','ERRORk') AS Expected FROM status_by_account WHERE user IN ('user2') AND variable_name IN ('handler_delete'); USER HOST VARIABLE_NAME VARIABLE_VALUE Expected -user2 localhost Handler_delete 2 OK +user2 localhost Handler_delete 2 OKk # -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user3') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 3,'OKl','ERRORl') AS Expected FROM status_by_account WHERE user IN ('user3') AND variable_name IN ('handler_delete'); USER HOST VARIABLE_NAME VARIABLE_VALUE Expected -user3 localhost Handler_delete 3 OK +user3 localhost Handler_delete 3 OKl # # STATUS_BY_ACCOUNT vs. GLOBAL_STATUS # -SELECT variable_name, a1, a2, a3, delta, acct, IF(acct=delta,'OK','ERROR') Expected +SELECT variable_name, a1, a2, a3, delta, acct, IF(acct=delta,'OKn','ERRORn') Expected FROM test.status_results ORDER BY variable_name; variable_name a1 a2 a3 delta acct Expected -Handler_delete 1 2 3 6 6 OK -Handler_rollback 1 2 3 6 6 OK +Handler_delete 1 2 3 6 6 OKn +Handler_rollback 1 2 3 6 6 OKn # ================================================================================ # TEST 7: STATUS_BY_HOST: Verify expected status counts per host (6) # ================================================================================ -SELECT *, IF (variable_value = 6,'OK','ERROR') AS Expected FROM status_by_host WHERE host IN ('localhost') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 6,'OKo','ERRORo') AS Expected FROM status_by_host WHERE host IN ('localhost') AND variable_name IN ('handler_delete'); HOST VARIABLE_NAME VARIABLE_VALUE Expected -localhost Handler_delete 6 OK +localhost Handler_delete 6 OKo # # STATUS_BY_HOST vs. GLOBAL_STATUS # # Special case: No way to isolate pre-existing 'localhost' activity, so # just check global totals = sum(status_by_host). # -SELECT variable_name, h1, h2, h3, delta, host, IF(host=delta,'OK','ERROR') Expected +SELECT variable_name, h1, h2, h3, delta, host, IF(host=delta,'OKp','ERRORp') Expected FROM test.status_results ORDER BY variable_name; variable_name h1 h2 h3 delta host Expected -Handler_delete 6 0 0 6 6 OK -Handler_rollback 6 0 0 6 6 OK +Handler_delete 6 0 0 6 6 OKp +Handler_rollback 6 0 0 6 6 OKp # ================================================================================ # TEST 8: FLUSH STATUS should clear account, host and user status # ================================================================================ diff --git a/mysql-test/suite/perfschema/r/sxlock_func,debug.rdiff b/mysql-test/suite/perfschema/r/sxlock_func,debug.rdiff new file mode 100644 index 00000000000..0596810e553 --- /dev/null +++ b/mysql-test/suite/perfschema/r/sxlock_func,debug.rdiff @@ -0,0 +1,22 @@ +@@ -7,7 +7,6 @@ + WHERE name LIKE 'wait/synch/rwlock/innodb/%' + AND name!='wait/synch/rwlock/innodb/btr_search_latch' ORDER BY name; + name +-wait/synch/rwlock/innodb/dict_operation_lock + wait/synch/rwlock/innodb/fil_space_latch + wait/synch/rwlock/innodb/lock_latch + wait/synch/rwlock/innodb/trx_i_s_cache_lock +@@ -19,11 +18,13 @@ + select name from performance_schema.setup_instruments + where name like "wait/synch/sxlock/%" order by name; + name ++wait/synch/sxlock/innodb/dict_operation_lock + wait/synch/sxlock/innodb/index_tree_rw_lock + SELECT DISTINCT name FROM performance_schema.rwlock_instances + WHERE name LIKE 'wait/synch/sxlock/innodb/%' + ORDER BY name; + name ++wait/synch/sxlock/innodb/dict_operation_lock + wait/synch/sxlock/innodb/index_tree_rw_lock + create table t1(a int) engine=innodb; + begin; diff --git a/mysql-test/suite/perfschema/r/table_aggregate_hist_2u_2t.result b/mysql-test/suite/perfschema/r/table_aggregate_hist_2u_2t.result index 47f4d7ba346..52ece6d289d 100644 --- a/mysql-test/suite/perfschema/r/table_aggregate_hist_2u_2t.result +++ b/mysql-test/suite/perfschema/r/table_aggregate_hist_2u_2t.result @@ -202,8 +202,10 @@ wait/io/table/sql/handler 23 wait/lock/table/sql/handler 24 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -260,8 +262,10 @@ wait/io/table/sql/handler 23 wait/lock/table/sql/handler 24 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -324,8 +328,10 @@ wait/io/table/sql/handler 23 wait/lock/table/sql/handler 24 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -423,8 +429,10 @@ wait/io/table/sql/handler 23 wait/lock/table/sql/handler 24 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -492,8 +500,10 @@ wait/io/table/sql/handler 23 wait/lock/table/sql/handler 24 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -603,8 +613,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 48 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 41 TABLE test t1 -wait/lock/table/sql/handler 78 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -677,8 +689,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 48 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 41 TABLE test t1 -wait/lock/table/sql/handler 78 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -800,8 +814,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 48 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 41 TABLE test t1 -wait/lock/table/sql/handler 78 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -875,8 +891,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -947,8 +965,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1019,8 +1039,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1088,8 +1110,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1156,8 +1180,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1223,8 +1249,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1289,8 +1317,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1357,8 +1387,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1424,8 +1456,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1491,8 +1525,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1558,8 +1594,10 @@ wait/io/table/sql/handler 71 wait/lock/table/sql/handler 56 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1625,8 +1663,10 @@ wait/io/table/sql/handler 0 wait/lock/table/sql/handler 0 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 0 0 0 0 0 0 0 diff --git a/mysql-test/suite/perfschema/r/table_aggregate_hist_2u_3t.result b/mysql-test/suite/perfschema/r/table_aggregate_hist_2u_3t.result index 9810d104ed9..b0ea06f4254 100644 --- a/mysql-test/suite/perfschema/r/table_aggregate_hist_2u_3t.result +++ b/mysql-test/suite/perfschema/r/table_aggregate_hist_2u_3t.result @@ -211,9 +211,12 @@ wait/io/table/sql/handler 33 wait/lock/table/sql/handler 36 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 22 TABLE test t2 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 10 TABLE test t2 +wait/lock/table/sql/handler 12 TABLE test t2 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -276,9 +279,12 @@ wait/io/table/sql/handler 33 wait/lock/table/sql/handler 36 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 22 TABLE test t2 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 10 TABLE test t2 +wait/lock/table/sql/handler 12 TABLE test t2 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -347,9 +353,12 @@ wait/io/table/sql/handler 33 wait/lock/table/sql/handler 36 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 22 TABLE test t2 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 10 TABLE test t2 +wait/lock/table/sql/handler 12 TABLE test t2 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -453,9 +462,12 @@ wait/io/table/sql/handler 33 wait/lock/table/sql/handler 36 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 22 TABLE test t2 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 10 TABLE test t2 +wait/lock/table/sql/handler 12 TABLE test t2 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -529,9 +541,12 @@ wait/io/table/sql/handler 33 wait/lock/table/sql/handler 36 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 22 TABLE test t2 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 10 TABLE test t2 +wait/lock/table/sql/handler 12 TABLE test t2 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -647,9 +662,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 72 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 41 TABLE test t1 -wait/lock/table/sql/handler 56 TABLE test t2 -wait/lock/table/sql/handler 78 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 24 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -728,9 +746,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 72 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 41 TABLE test t1 -wait/lock/table/sql/handler 56 TABLE test t2 -wait/lock/table/sql/handler 78 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 24 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -858,9 +879,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 72 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 41 TABLE test t1 -wait/lock/table/sql/handler 56 TABLE test t2 -wait/lock/table/sql/handler 78 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 24 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -940,9 +964,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1019,9 +1046,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1098,9 +1128,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1174,9 +1207,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1249,9 +1285,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1323,9 +1362,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1396,9 +1438,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1471,9 +1516,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1545,9 +1593,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1619,9 +1670,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1693,9 +1747,12 @@ wait/io/table/sql/handler 103 wait/lock/table/sql/handler 84 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 17 11 6 11 2 4 0 @@ -1767,9 +1824,12 @@ wait/io/table/sql/handler 0 wait/lock/table/sql/handler 0 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 45 TABLE test t1 -wait/lock/table/sql/handler 60 TABLE test t2 -wait/lock/table/sql/handler 82 TABLE test t3 +wait/io/table/sql/handler 21 TABLE test t1 +wait/lock/table/sql/handler 24 TABLE test t1 +wait/io/table/sql/handler 32 TABLE test t2 +wait/lock/table/sql/handler 28 TABLE test t2 +wait/io/table/sql/handler 50 TABLE test t3 +wait/lock/table/sql/handler 32 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 0 0 0 0 0 0 0 diff --git a/mysql-test/suite/perfschema/r/table_aggregate_hist_4u_2t.result b/mysql-test/suite/perfschema/r/table_aggregate_hist_4u_2t.result index 367a8a089eb..0a6dea739e4 100644 --- a/mysql-test/suite/perfschema/r/table_aggregate_hist_4u_2t.result +++ b/mysql-test/suite/perfschema/r/table_aggregate_hist_4u_2t.result @@ -202,8 +202,10 @@ wait/io/table/sql/handler 23 wait/lock/table/sql/handler 24 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -260,8 +262,10 @@ wait/io/table/sql/handler 23 wait/lock/table/sql/handler 24 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -324,8 +328,10 @@ wait/io/table/sql/handler 23 wait/lock/table/sql/handler 24 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -423,8 +429,10 @@ wait/io/table/sql/handler 58 wait/lock/table/sql/handler 48 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 38 TABLE test t1 -wait/lock/table/sql/handler 68 TABLE test t3 +wait/io/table/sql/handler 18 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 40 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 14 9 5 9 2 3 0 @@ -492,8 +500,10 @@ wait/io/table/sql/handler 58 wait/lock/table/sql/handler 48 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 38 TABLE test t1 -wait/lock/table/sql/handler 68 TABLE test t3 +wait/io/table/sql/handler 18 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 40 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 14 9 5 9 2 3 0 @@ -603,8 +613,10 @@ wait/io/table/sql/handler 106 wait/lock/table/sql/handler 72 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 61 TABLE test t1 -wait/lock/table/sql/handler 117 TABLE test t3 +wait/io/table/sql/handler 31 TABLE test t1 +wait/lock/table/sql/handler 30 TABLE test t1 +wait/io/table/sql/handler 75 TABLE test t3 +wait/lock/table/sql/handler 42 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 25 16 9 16 3 6 0 @@ -677,8 +689,10 @@ wait/io/table/sql/handler 106 wait/lock/table/sql/handler 72 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 61 TABLE test t1 -wait/lock/table/sql/handler 117 TABLE test t3 +wait/io/table/sql/handler 31 TABLE test t1 +wait/lock/table/sql/handler 30 TABLE test t1 +wait/io/table/sql/handler 75 TABLE test t3 +wait/lock/table/sql/handler 42 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 25 16 9 16 3 6 0 @@ -800,8 +814,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 96 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 87 TABLE test t1 -wait/lock/table/sql/handler 176 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 40 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 56 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -875,8 +891,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -947,8 +965,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1019,8 +1039,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1088,8 +1110,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1156,8 +1180,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1223,8 +1249,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1289,8 +1317,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1357,8 +1387,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1424,8 +1456,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1491,8 +1525,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1558,8 +1594,10 @@ wait/io/table/sql/handler 167 wait/lock/table/sql/handler 104 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1625,8 +1663,10 @@ wait/io/table/sql/handler 0 wait/lock/table/sql/handler 0 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 0 0 0 0 0 0 0 diff --git a/mysql-test/suite/perfschema/r/table_aggregate_hist_4u_3t.result b/mysql-test/suite/perfschema/r/table_aggregate_hist_4u_3t.result index ed1ac9d979b..c2eda2b8f23 100644 --- a/mysql-test/suite/perfschema/r/table_aggregate_hist_4u_3t.result +++ b/mysql-test/suite/perfschema/r/table_aggregate_hist_4u_3t.result @@ -211,9 +211,12 @@ wait/io/table/sql/handler 33 wait/lock/table/sql/handler 36 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 22 TABLE test t2 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 10 TABLE test t2 +wait/lock/table/sql/handler 12 TABLE test t2 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -276,9 +279,12 @@ wait/io/table/sql/handler 33 wait/lock/table/sql/handler 36 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 22 TABLE test t2 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 10 TABLE test t2 +wait/lock/table/sql/handler 12 TABLE test t2 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -347,9 +353,12 @@ wait/io/table/sql/handler 33 wait/lock/table/sql/handler 36 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 18 TABLE test t1 -wait/lock/table/sql/handler 22 TABLE test t2 -wait/lock/table/sql/handler 29 TABLE test t3 +wait/io/table/sql/handler 8 TABLE test t1 +wait/lock/table/sql/handler 10 TABLE test t1 +wait/io/table/sql/handler 10 TABLE test t2 +wait/lock/table/sql/handler 12 TABLE test t2 +wait/io/table/sql/handler 15 TABLE test t3 +wait/lock/table/sql/handler 14 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 6 4 2 4 1 1 0 @@ -453,9 +462,12 @@ wait/io/table/sql/handler 84 wait/lock/table/sql/handler 72 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 38 TABLE test t1 -wait/lock/table/sql/handler 50 TABLE test t2 -wait/lock/table/sql/handler 68 TABLE test t3 +wait/io/table/sql/handler 18 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 26 TABLE test t2 +wait/lock/table/sql/handler 24 TABLE test t2 +wait/io/table/sql/handler 40 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 14 9 5 9 2 3 0 @@ -529,9 +541,12 @@ wait/io/table/sql/handler 84 wait/lock/table/sql/handler 72 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 38 TABLE test t1 -wait/lock/table/sql/handler 50 TABLE test t2 -wait/lock/table/sql/handler 68 TABLE test t3 +wait/io/table/sql/handler 18 TABLE test t1 +wait/lock/table/sql/handler 20 TABLE test t1 +wait/io/table/sql/handler 26 TABLE test t2 +wait/lock/table/sql/handler 24 TABLE test t2 +wait/io/table/sql/handler 40 TABLE test t3 +wait/lock/table/sql/handler 28 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 14 9 5 9 2 3 0 @@ -647,9 +662,12 @@ wait/io/table/sql/handler 154 wait/lock/table/sql/handler 108 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 61 TABLE test t1 -wait/lock/table/sql/handler 84 TABLE test t2 -wait/lock/table/sql/handler 117 TABLE test t3 +wait/io/table/sql/handler 31 TABLE test t1 +wait/lock/table/sql/handler 30 TABLE test t1 +wait/io/table/sql/handler 48 TABLE test t2 +wait/lock/table/sql/handler 36 TABLE test t2 +wait/io/table/sql/handler 75 TABLE test t3 +wait/lock/table/sql/handler 42 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 25 16 9 16 3 6 0 @@ -728,9 +746,12 @@ wait/io/table/sql/handler 154 wait/lock/table/sql/handler 108 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 61 TABLE test t1 -wait/lock/table/sql/handler 84 TABLE test t2 -wait/lock/table/sql/handler 117 TABLE test t3 +wait/io/table/sql/handler 31 TABLE test t1 +wait/lock/table/sql/handler 30 TABLE test t1 +wait/io/table/sql/handler 48 TABLE test t2 +wait/lock/table/sql/handler 36 TABLE test t2 +wait/io/table/sql/handler 75 TABLE test t3 +wait/lock/table/sql/handler 42 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 25 16 9 16 3 6 0 @@ -858,9 +879,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 144 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 87 TABLE test t1 -wait/lock/table/sql/handler 124 TABLE test t2 -wait/lock/table/sql/handler 176 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 40 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 48 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 56 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -940,9 +964,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1019,9 +1046,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1098,9 +1128,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1174,9 +1207,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1249,9 +1285,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1323,9 +1362,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1396,9 +1438,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1471,9 +1516,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1545,9 +1593,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1619,9 +1670,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1693,9 +1747,12 @@ wait/io/table/sql/handler 243 wait/lock/table/sql/handler 156 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 39 25 14 25 4 10 0 @@ -1767,9 +1824,12 @@ wait/io/table/sql/handler 0 wait/lock/table/sql/handler 0 execute dump_waits_history; event_name count(event_name) object_type object_schema object_name -wait/lock/table/sql/handler 91 TABLE test t1 -wait/lock/table/sql/handler 128 TABLE test t2 -wait/lock/table/sql/handler 180 TABLE test t3 +wait/io/table/sql/handler 47 TABLE test t1 +wait/lock/table/sql/handler 44 TABLE test t1 +wait/io/table/sql/handler 76 TABLE test t2 +wait/lock/table/sql/handler 52 TABLE test t2 +wait/io/table/sql/handler 120 TABLE test t3 +wait/lock/table/sql/handler 60 TABLE test t3 execute dump_waits_index_io; object_type object_schema object_name index_name count_star count_read count_write count_fetch count_insert count_update count_delete TABLE test t1 NULL 0 0 0 0 0 0 0 diff --git a/mysql-test/suite/perfschema/t/events_waits_current_MDEV-29091.test b/mysql-test/suite/perfschema/t/events_waits_current_MDEV-29091.test deleted file mode 100644 index d9330ee5a9d..00000000000 --- a/mysql-test/suite/perfschema/t/events_waits_current_MDEV-29091.test +++ /dev/null @@ -1,62 +0,0 @@ -# -# proper event name wait/lock/table/sql/handler recorded in -# PERFORMANCE_SCHEMA.EVENTS_WAITS_CURRENT. Before this fix, it was -# labeled as wait/io/table/sql/handler. -# - ---source include/have_innodb.inc ---source include/have_perfschema.inc ---source include/not_embedded.inc - -SET default_storage_engine=InnoDB; - -SELECT @save_instrument_enabled := ENABLED -, @save_instrument_timed := TIMED -FROM performance_schema.setup_instruments -WHERE NAME = 'wait/lock/table/sql/handler'; - -SELECT @save_consumer_enabled := ENABLED -FROM performance_schema.setup_consumers -WHERE NAME = 'events_waits_current'; - -UPDATE performance_schema.setup_instruments -SET ENABLED = 'YES', TIMED = 'YES' -WHERE NAME = 'wait/lock/table/sql/handler'; - -UPDATE performance_schema.setup_consumers -SET ENABLED = 'YES' -WHERE NAME = 'events_waits_current'; - -CREATE TABLE t1 (id1 INT(11), col1 VARCHAR (200)); -INSERT INTO t1 VALUES (1, 'aa'); -INSERT INTO t1 VALUES (2, 'bb'); - -connect (con1,localhost,root,,test); -connect (con2,localhost,root,,test); - -connection con1; -START TRANSACTION; -let $wait_condition= - SELECT id1 FROM t1 WHERE id1=1 FOR UPDATE; ---source include/wait_condition.inc - -connection con2; -START TRANSACTION; -send SELECT id1 FROM t1 WHERE id1=1 FOR UPDATE; - -connection default; -SELECT event_name FROM performance_schema.events_waits_current -WHERE event_name LIKE '%wait/lock/table/sql/handler%'; - -# clean up -UPDATE performance_schema.setup_instruments -SET ENABLED = @save_instrument_enabled, TIMED = @save_instrument_timed -WHERE NAME = 'wait/lock/table/sql/handler'; - -UPDATE performance_schema.setup_consumers -SET ENABLED = @save_consumer_enabled -WHERE NAME = 'events_waits_current'; - -disconnect con1; -disconnect con2; -DROP TABLE t1; diff --git a/mysql-test/suite/perfschema/t/mdl_func.test b/mysql-test/suite/perfschema/t/mdl_func.test index fc12bdacf8c..209c2f112af 100644 --- a/mysql-test/suite/perfschema/t/mdl_func.test +++ b/mysql-test/suite/perfschema/t/mdl_func.test @@ -1,7 +1,11 @@ --source include/not_embedded.inc --source include/have_perfschema.inc -# This test fails very frequently on a Windows builder. ---source include/not_windows.inc +# This test needs a fresh restart. The table performance_schema.table_handles +# can otherwise contain extra rows left from previous testcases. +# For example the test case main.long_unique_delayed, which uses +# INSERT DELAYED, will leave extra rows in this table if run just before this +# test, causing .result diff failure. +--source include/restart_mysqld.inc UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; diff --git a/mysql-test/suite/perfschema/t/show_aggregate.test b/mysql-test/suite/perfschema/t/show_aggregate.test index a15dea45268..c84e99f6efc 100644 --- a/mysql-test/suite/perfschema/t/show_aggregate.test +++ b/mysql-test/suite/perfschema/t/show_aggregate.test @@ -13,8 +13,7 @@ --source include/not_embedded.inc --source include/no_protocol.inc --source include/maybe_pool_of_threads.inc - ---enable_connect_log +--source include/wait_for_pfs_thread_count.inc --echo # --echo # ================================================================================ @@ -26,10 +25,7 @@ SET @@session.sql_log_bin=OFF; connection default; USE test; -# Clear user, host and account status accumulated from preliminary checks by mtr. ---disable_query_log flush status; ---enable_query_log --echo # --echo # Create results table @@ -112,9 +108,9 @@ ROLLBACK; connection default; --echo # Get thread ids for each connection. USE performance_schema; -SELECT thread_id INTO @con1_id FROM threads WHERE processlist_user IN ('user1'); -SELECT thread_id INTO @con2_id FROM threads WHERE processlist_user IN ('user2'); -SELECT thread_id INTO @con3_id FROM threads WHERE processlist_user IN ('user3'); +SELECT thread_id INTO @con1_id FROM threads WHERE processlist_user IN ('user1') and processlist_id; +SELECT thread_id INTO @con2_id FROM threads WHERE processlist_user IN ('user2') and processlist_id; +SELECT thread_id INTO @con3_id FROM threads WHERE processlist_user IN ('user3') and processlist_id; --source ../include/show_aggregate.inc @@ -135,18 +131,18 @@ USE performance_schema; --echo # Verify expected counts for 'handler_delete' per thread --echo # --replace_column 1 con_1 -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_thread WHERE thread_id = @con1_id AND variable_name IN ('handler_delete', 'handler_rollback'); +SELECT *, IF (variable_value = 1,'OK1','ERROR1') AS Expected FROM status_by_thread WHERE thread_id = @con1_id AND variable_name IN ('handler_delete', 'handler_rollback'); --echo # --replace_column 1 con_2 -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_thread WHERE thread_id = @con2_id AND variable_name IN ('handler_delete', 'handler_rollback'); +SELECT *, IF (variable_value = 2,'OK2','ERROR2') AS Expected FROM status_by_thread WHERE thread_id = @con2_id AND variable_name IN ('handler_delete', 'handler_rollback'); --echo # --replace_column 1 con_3 -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_thread WHERE thread_id = @con3_id AND variable_name IN ('handler_delete', 'handler_rollback'); +SELECT *, IF (variable_value = 3,'OK3','ERROR3') AS Expected FROM status_by_thread WHERE thread_id = @con3_id AND variable_name IN ('handler_delete', 'handler_rollback'); --echo # --echo # STATUS_BY_THREAD vs. GLOBAL_STATUS --echo # -SELECT variable_name, t1, t2, t3, delta, thread, IF(thread=delta,'OK','ERROR') Expected +SELECT variable_name, t1, t2, t3, delta, thread, IF(thread=delta,'OK4','ERROR4') Expected FROM test.status_results ORDER BY variable_name; @@ -154,16 +150,16 @@ ORDER BY variable_name; --echo # ================================================================================ --echo # TEST 2: STATUS_BY_USER: Verify expected status counts per user (1,2,3) --echo # ================================================================================ -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user1') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 1,'OK5','ERROR5') AS Expected FROM status_by_user WHERE user IN ('user1') AND variable_name IN ('handler_delete'); --echo # -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user2') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 2,'OK6','ERROR6') AS Expected FROM status_by_user WHERE user IN ('user2') AND variable_name IN ('handler_delete'); --echo # -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user3') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 3,'OK7','ERROR7') AS Expected FROM status_by_user WHERE user IN ('user3') AND variable_name IN ('handler_delete'); --echo # --echo # STATUS_BY_USER vs. GLOBAL_STATUS --echo # -SELECT variable_name, u1, u2, u3, delta, user, IF(user=delta,'OK','ERROR') Expected +SELECT variable_name, u1, u2, u3, delta, user, IF(user=delta,'OK8','ERROR8') Expected FROM test.status_results ORDER BY variable_name; @@ -171,23 +167,23 @@ ORDER BY variable_name; --echo # ================================================================================ --echo # TEST 3: STATUS_BY_ACCOUNT: Verify expected status counts per user, host (1,2,3) --echo # ================================================================================ -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user1') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 1,'OK9','ERROR9') AS Expected FROM status_by_account WHERE user IN ('user1') AND variable_name IN ('handler_delete'); --echo # -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user2') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 2,'OKa','ERRORa') AS Expected FROM status_by_account WHERE user IN ('user2') AND variable_name IN ('handler_delete'); --echo # -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user3') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 3,'OKb','ERRORb') AS Expected FROM status_by_account WHERE user IN ('user3') AND variable_name IN ('handler_delete'); --echo # --echo # STATUS_BY_ACCOUNT vs. GLOBAL_STATUS --echo # -SELECT variable_name, a1, a2, a3, delta, acct, IF(acct=delta,'OK','ERROR') Expected +SELECT variable_name, a1, a2, a3, delta, acct, IF(acct=delta,'OKc','ERRORc') Expected FROM test.status_results ORDER BY variable_name; --echo # ================================================================================ --echo # TEST 4: STATUS_BY_HOST: Verify expected status counts per host (6) --echo # ================================================================================ -SELECT *, IF (variable_value = 6,'OK','ERROR') AS Expected FROM status_by_host WHERE host IN ('localhost') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 6,'OKd','ERRORd') AS Expected FROM status_by_host WHERE host IN ('localhost') AND variable_name IN ('handler_delete'); --echo # --echo # STATUS_BY_HOST vs. GLOBAL_STATUS @@ -195,7 +191,7 @@ SELECT *, IF (variable_value = 6,'OK','ERROR') AS Expected FROM status_by_host W --echo # Special case: No way to isolate pre-existing 'localhost' activity, so --echo # just check global totals = sum(status_by_host). --echo # -SELECT variable_name, h1, h2, h3, delta, host, IF(host=delta,'OK','ERROR') Expected +SELECT variable_name, h1, h2, h3, delta, host, IF(host=delta,'OKe','ERRORe') Expected FROM test.status_results ORDER BY variable_name; @@ -203,10 +199,10 @@ ORDER BY variable_name; --echo # ================================================================================ --echo # DISCONNECT ALL USERS AND RUN THE TESTS AGAIN. RESULTS SHOULD NOT CHANGE. --echo # ================================================================================ -connection default; disconnect con1; disconnect con2; disconnect con3; + --echo # USE test; --echo # @@ -218,6 +214,9 @@ UPDATE test.status_results h1=0, h2=0, h3=0, host=0, a1=0, a2=0, a3=0, acct=0; +let $wait_condition= select count(*) = 0 from performance_schema.threads where processlist_user like 'user%' and processlist_id; +--source include/wait_condition.inc + #--echo DEBUG #SELECT * FROM test.status_results; --echo # @@ -232,16 +231,16 @@ USE performance_schema; --echo # ================================================================================ --echo # TEST 5: STATUS_BY_USER: Verify expected status counts per user (1,2,3) --echo # ================================================================================ -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user1') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 1,'OKf','ERRORf') AS Expected FROM status_by_user WHERE user IN ('user1') AND variable_name IN ('handler_delete'); --echo # -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user2') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 2,'OKg','ERRORg') AS Expected FROM status_by_user WHERE user IN ('user2') AND variable_name IN ('handler_delete'); --echo # -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_user WHERE user IN ('user3') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 3,'OKh','ERRORh') AS Expected FROM status_by_user WHERE user IN ('user3') AND variable_name IN ('handler_delete'); --echo # --echo # STATUS_BY_USER vs. GLOBAL_STATUS --echo # -SELECT variable_name, u1, u2, u3, delta, user, IF(user=delta,'OK','ERROR') Expected +SELECT variable_name, u1, u2, u3, delta, user, IF(user=delta,'OKi','ERRORi') Expected FROM test.status_results ORDER BY variable_name; @@ -249,23 +248,23 @@ ORDER BY variable_name; --echo # ================================================================================ --echo # TEST 6: STATUS_BY_ACCOUNT: Verify expected status counts per user:host (1,2,3) --echo # ================================================================================ -SELECT *, IF (variable_value = 1,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user1') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 1,'OKj','ERRORj') AS Expected FROM status_by_account WHERE user IN ('user1') AND variable_name IN ('handler_delete'); --echo # -SELECT *, IF (variable_value = 2,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user2') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 2,'OKk','ERRORk') AS Expected FROM status_by_account WHERE user IN ('user2') AND variable_name IN ('handler_delete'); --echo # -SELECT *, IF (variable_value = 3,'OK','ERROR') AS Expected FROM status_by_account WHERE user IN ('user3') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 3,'OKl','ERRORl') AS Expected FROM status_by_account WHERE user IN ('user3') AND variable_name IN ('handler_delete'); --echo # --echo # STATUS_BY_ACCOUNT vs. GLOBAL_STATUS --echo # -SELECT variable_name, a1, a2, a3, delta, acct, IF(acct=delta,'OK','ERROR') Expected +SELECT variable_name, a1, a2, a3, delta, acct, IF(acct=delta,'OKn','ERRORn') Expected FROM test.status_results ORDER BY variable_name; --echo # ================================================================================ --echo # TEST 7: STATUS_BY_HOST: Verify expected status counts per host (6) --echo # ================================================================================ -SELECT *, IF (variable_value = 6,'OK','ERROR') AS Expected FROM status_by_host WHERE host IN ('localhost') AND variable_name IN ('handler_delete'); +SELECT *, IF (variable_value = 6,'OKo','ERRORo') AS Expected FROM status_by_host WHERE host IN ('localhost') AND variable_name IN ('handler_delete'); --echo # --echo # STATUS_BY_HOST vs. GLOBAL_STATUS @@ -273,11 +272,10 @@ SELECT *, IF (variable_value = 6,'OK','ERROR') AS Expected FROM status_by_host W --echo # Special case: No way to isolate pre-existing 'localhost' activity, so --echo # just check global totals = sum(status_by_host). --echo # -SELECT variable_name, h1, h2, h3, delta, host, IF(host=delta,'OK','ERROR') Expected +SELECT variable_name, h1, h2, h3, delta, host, IF(host=delta,'OKp','ERRORp') Expected FROM test.status_results ORDER BY variable_name; - --echo # ================================================================================ --echo # TEST 8: FLUSH STATUS should clear account, host and user status --echo # ================================================================================ @@ -290,7 +288,6 @@ SELECT * FROM status_by_host WHERE host IN ('localhost') AND variable_name IN (' --echo # SELECT * FROM status_by_user WHERE user IN ('user1', 'user2', 'user3') AND variable_name IN ('handler_delete'); - --echo # ================================================================================ --echo # CLEANUP --echo # ================================================================================ diff --git a/mysql-test/suite/perfschema/t/sxlock_func.test b/mysql-test/suite/perfschema/t/sxlock_func.test index c43adc849d2..24d0e07ca41 100644 --- a/mysql-test/suite/perfschema/t/sxlock_func.test +++ b/mysql-test/suite/perfschema/t/sxlock_func.test @@ -5,6 +5,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc --source include/have_innodb.inc +--source include/maybe_debug.inc UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; diff --git a/mysql-test/suite/plugins/r/compression,innodb-lz4.rdiff b/mysql-test/suite/plugins/r/compression,innodb-lz4.rdiff index 06fdb0bd4f0..791aecda080 100644 --- a/mysql-test/suite/plugins/r/compression,innodb-lz4.rdiff +++ b/mysql-test/suite/plugins/r/compression,innodb-lz4.rdiff @@ -10,15 +10,19 @@ +set global innodb_compression_algorithm = lz4; call mtr.add_suppression("Background Page read failed to read, uncompress, or decrypt"); call mtr.add_suppression("Table is compressed or encrypted but uncompress or decrypt failed"); - call mtr.add_suppression("Table .*t1.* is compressed with (\\w+), which is not currently loaded. Please load the \\1 provider plugin to open the table"); -@@ -15,8 +15,8 @@ + call mtr.add_suppression("Table `test`.`t1` is corrupted. Please drop the table and recreate"); +@@ -16,12 +16,12 @@ 0 abcabcabc 300 1 defdefdef 3000 2 ghighighi 30000 -# restart: --disable-provider-bzip2 +# restart: --disable-provider-lz4 select a, left(b, 9), length(b) from t1; --ERROR HY000: Table test/t1 is compressed with bzip2, which is not currently loaded. Please load the bzip2 provider plugin to open the table -+ERROR HY000: Table test/t1 is compressed with lz4, which is not currently loaded. Please load the lz4 provider plugin to open the table + ERROR 42S02: Table 'test.t1' doesn't exist in engine + show warnings; + Level Code Message +-Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded ++Warning 4185 MariaDB tried to use the LZ4 compression, but its provider plugin is not loaded + Error 1932 Table 'test.t1' doesn't exist in engine drop table t1; # restart diff --git a/mysql-test/suite/plugins/r/compression,innodb-lzma.rdiff b/mysql-test/suite/plugins/r/compression,innodb-lzma.rdiff index ee348934a54..13c42f82b43 100644 --- a/mysql-test/suite/plugins/r/compression,innodb-lzma.rdiff +++ b/mysql-test/suite/plugins/r/compression,innodb-lzma.rdiff @@ -10,15 +10,19 @@ +set global innodb_compression_algorithm = lzma; call mtr.add_suppression("Background Page read failed to read, uncompress, or decrypt"); call mtr.add_suppression("Table is compressed or encrypted but uncompress or decrypt failed"); - call mtr.add_suppression("Table .*t1.* is compressed with (\\w+), which is not currently loaded. Please load the \\1 provider plugin to open the table"); -@@ -15,8 +15,8 @@ + call mtr.add_suppression("Table `test`.`t1` is corrupted. Please drop the table and recreate"); +@@ -16,12 +16,12 @@ 0 abcabcabc 300 1 defdefdef 3000 2 ghighighi 30000 -# restart: --disable-provider-bzip2 +# restart: --disable-provider-lzma select a, left(b, 9), length(b) from t1; --ERROR HY000: Table test/t1 is compressed with bzip2, which is not currently loaded. Please load the bzip2 provider plugin to open the table -+ERROR HY000: Table test/t1 is compressed with lzma, which is not currently loaded. Please load the lzma provider plugin to open the table + ERROR 42S02: Table 'test.t1' doesn't exist in engine + show warnings; + Level Code Message +-Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded ++Warning 4185 MariaDB tried to use the LZMA compression, but its provider plugin is not loaded + Error 1932 Table 'test.t1' doesn't exist in engine drop table t1; # restart diff --git a/mysql-test/suite/plugins/r/compression,innodb-lzo.rdiff b/mysql-test/suite/plugins/r/compression,innodb-lzo.rdiff index d7cdc41092a..cc7783cc4f8 100644 --- a/mysql-test/suite/plugins/r/compression,innodb-lzo.rdiff +++ b/mysql-test/suite/plugins/r/compression,innodb-lzo.rdiff @@ -10,15 +10,19 @@ +set global innodb_compression_algorithm = lzo; call mtr.add_suppression("Background Page read failed to read, uncompress, or decrypt"); call mtr.add_suppression("Table is compressed or encrypted but uncompress or decrypt failed"); - call mtr.add_suppression("Table .*t1.* is compressed with (\\w+), which is not currently loaded. Please load the \\1 provider plugin to open the table"); -@@ -15,8 +15,8 @@ + call mtr.add_suppression("Table `test`.`t1` is corrupted. Please drop the table and recreate"); +@@ -16,12 +16,12 @@ 0 abcabcabc 300 1 defdefdef 3000 2 ghighighi 30000 -# restart: --disable-provider-bzip2 +# restart: --disable-provider-lzo select a, left(b, 9), length(b) from t1; --ERROR HY000: Table test/t1 is compressed with bzip2, which is not currently loaded. Please load the bzip2 provider plugin to open the table -+ERROR HY000: Table test/t1 is compressed with lzo, which is not currently loaded. Please load the lzo provider plugin to open the table + ERROR 42S02: Table 'test.t1' doesn't exist in engine + show warnings; + Level Code Message +-Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded ++Warning 4185 MariaDB tried to use the LZO compression, but its provider plugin is not loaded + Error 1932 Table 'test.t1' doesn't exist in engine drop table t1; # restart diff --git a/mysql-test/suite/plugins/r/compression,innodb-snappy.rdiff b/mysql-test/suite/plugins/r/compression,innodb-snappy.rdiff index e9c7485d118..98c4427a758 100644 --- a/mysql-test/suite/plugins/r/compression,innodb-snappy.rdiff +++ b/mysql-test/suite/plugins/r/compression,innodb-snappy.rdiff @@ -10,15 +10,19 @@ +set global innodb_compression_algorithm = snappy; call mtr.add_suppression("Background Page read failed to read, uncompress, or decrypt"); call mtr.add_suppression("Table is compressed or encrypted but uncompress or decrypt failed"); - call mtr.add_suppression("Table .*t1.* is compressed with (\\w+), which is not currently loaded. Please load the \\1 provider plugin to open the table"); -@@ -15,8 +15,8 @@ + call mtr.add_suppression("Table `test`.`t1` is corrupted. Please drop the table and recreate"); +@@ -16,12 +16,12 @@ 0 abcabcabc 300 1 defdefdef 3000 2 ghighighi 30000 -# restart: --disable-provider-bzip2 +# restart: --disable-provider-snappy select a, left(b, 9), length(b) from t1; --ERROR HY000: Table test/t1 is compressed with bzip2, which is not currently loaded. Please load the bzip2 provider plugin to open the table -+ERROR HY000: Table test/t1 is compressed with snappy, which is not currently loaded. Please load the snappy provider plugin to open the table + ERROR 42S02: Table 'test.t1' doesn't exist in engine + show warnings; + Level Code Message +-Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded ++Warning 4185 MariaDB tried to use the Snappy compression, but its provider plugin is not loaded + Error 1932 Table 'test.t1' doesn't exist in engine drop table t1; # restart diff --git a/mysql-test/suite/plugins/r/compression,mroonga-lz4.rdiff b/mysql-test/suite/plugins/r/compression,mroonga-lz4.rdiff index 9b155ff3a1d..ac186d3c566 100644 --- a/mysql-test/suite/plugins/r/compression,mroonga-lz4.rdiff +++ b/mysql-test/suite/plugins/r/compression,mroonga-lz4.rdiff @@ -1,6 +1,6 @@ --- suite/plugins/r/compression.result +++ suite/plugins/r/compression.reject -@@ -1,12 +1,8 @@ +@@ -1,13 +1,8 @@ # -# Testing bzip2 compression provider with innodb +# Testing lz4 compression provider with mroonga @@ -9,20 +9,25 @@ -set global innodb_compression_algorithm = bzip2; -call mtr.add_suppression("Background Page read failed to read, uncompress, or decrypt"); -call mtr.add_suppression("Table is compressed or encrypted but uncompress or decrypt failed"); +-call mtr.add_suppression("Table `test`.`t1` is corrupted. Please drop the table and recreate"); -call mtr.add_suppression("Table .*t1.* is compressed with (\\w+), which is not currently loaded. Please load the \\1 provider plugin to open the table"); -create table t1 (a int, b text ) engine = innodb page_compressed = 1; +create table t1 (a int, b text COMMENT 'FLAGS "COLUMN_SCALAR|COMPRESS_LZ4"') engine = mroonga charset = utf8; insert t1 (a, b) values (0, repeat("abc", 100)); insert t1 (a, b) values (1, repeat("def", 1000)); insert t1 (a, b) values (2, repeat("ghi", 10000)); -@@ -14,8 +11,20 @@ +@@ -16,12 +11,20 @@ 0 abcabcabc 300 1 defdefdef 3000 2 ghighighi 30000 -# restart: --disable-provider-bzip2 +# restart: --disable-provider-lz4 select a, left(b, 9), length(b) from t1; --ERROR HY000: Table test/t1 is compressed with bzip2, which is not currently loaded. Please load the bzip2 provider plugin to open the table +-ERROR 42S02: Table 'test.t1' doesn't exist in engine +-show warnings; +-Level Code Message +-Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded +-Error 1932 Table 'test.t1' doesn't exist in engine +a left(b, 9) length(b) +0 0 +1 0 diff --git a/mysql-test/suite/plugins/r/compression.result b/mysql-test/suite/plugins/r/compression.result index dd267f282c5..d7c11abc95b 100644 --- a/mysql-test/suite/plugins/r/compression.result +++ b/mysql-test/suite/plugins/r/compression.result @@ -5,6 +5,7 @@ call mtr.add_suppression("MariaDB tried to use the .+ compression, but its provi set global innodb_compression_algorithm = bzip2; call mtr.add_suppression("Background Page read failed to read, uncompress, or decrypt"); call mtr.add_suppression("Table is compressed or encrypted but uncompress or decrypt failed"); +call mtr.add_suppression("Table `test`.`t1` is corrupted. Please drop the table and recreate"); call mtr.add_suppression("Table .*t1.* is compressed with (\\w+), which is not currently loaded. Please load the \\1 provider plugin to open the table"); create table t1 (a int, b text ) engine = innodb page_compressed = 1; insert t1 (a, b) values (0, repeat("abc", 100)); @@ -17,6 +18,10 @@ a left(b, 9) length(b) 2 ghighighi 30000 # restart: --disable-provider-bzip2 select a, left(b, 9), length(b) from t1; -ERROR HY000: Table test/t1 is compressed with bzip2, which is not currently loaded. Please load the bzip2 provider plugin to open the table +ERROR 42S02: Table 'test.t1' doesn't exist in engine +show warnings; +Level Code Message +Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded +Error 1932 Table 'test.t1' doesn't exist in engine drop table t1; # restart diff --git a/mysql-test/suite/plugins/r/simple_password_check.result b/mysql-test/suite/plugins/r/simple_password_check.result index 30f68ba8193..0826b7f6637 100644 --- a/mysql-test/suite/plugins/r/simple_password_check.result +++ b/mysql-test/suite/plugins/r/simple_password_check.result @@ -254,3 +254,13 @@ Grants for foo1@localhost GRANT USAGE ON *.* TO `foo1`@`localhost` IDENTIFIED BY PASSWORD '*1D62FA326F98258451ED56A404F15452423DCC1D' drop user foo1@localhost; uninstall plugin simple_password_check; +# +# MDEV-22418 mysqladmin wrong error with simple_password_check +# +install soname "simple_password_check"; +MARIADB-ADMIN: unable to change password; error: 'The MariaDB server is running with the --strict-password-validation option so it cannot execute this statement' +# All done +uninstall plugin simple_password_check; +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/plugins/r/test_sql_service.result b/mysql-test/suite/plugins/r/test_sql_service.result index 2983da28cc9..bb0b536acd2 100644 --- a/mysql-test/suite/plugins/r/test_sql_service.result +++ b/mysql-test/suite/plugins/r/test_sql_service.result @@ -1,8 +1,8 @@ -reset master; install plugin test_sql_service soname 'test_sql_service'; show status like 'test_sql_service_passed'; Variable_name Value 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'; diff --git a/mysql-test/suite/plugins/t/compression.combinations b/mysql-test/suite/plugins/t/compression.combinations index 645ca60e5f0..17ea9e8244f 100644 --- a/mysql-test/suite/plugins/t/compression.combinations +++ b/mysql-test/suite/plugins/t/compression.combinations @@ -1,25 +1,30 @@ [innodb-bzip2] innodb +innodb-fast-shutdown=0 plugin-load-add=$PROVIDER_BZIP2_SO loose-provider-bzip2 [innodb-lz4] innodb +innodb-fast-shutdown=0 plugin-load-add=$PROVIDER_LZ4_SO loose-provider-lz4 [innodb-lzma] innodb +innodb-fast-shutdown=0 plugin-load-add=$PROVIDER_LZMA_SO loose-provider-lzma [innodb-lzo] innodb +innodb-fast-shutdown=0 plugin-load-add=$PROVIDER_LZO_SO loose-provider-lzo [innodb-snappy] innodb +innodb-fast-shutdown=0 plugin-load-add=$PROVIDER_SNAPPY_SO loose-provider-snappy diff --git a/mysql-test/suite/plugins/t/compression.test b/mysql-test/suite/plugins/t/compression.test index c97c5725e1d..df892acfdc4 100644 --- a/mysql-test/suite/plugins/t/compression.test +++ b/mysql-test/suite/plugins/t/compression.test @@ -21,6 +21,7 @@ if ($engine == "innodb") { let $table_params = page_compressed = 1; call mtr.add_suppression("Background Page read failed to read, uncompress, or decrypt"); call mtr.add_suppression("Table is compressed or encrypted but uncompress or decrypt failed"); + call mtr.add_suppression("Table `test`.`t1` is corrupted. Please drop the table and recreate"); call mtr.add_suppression("Table .*t1.* is compressed with (\\w+), which is not currently loaded. Please load the \\1 provider plugin to open the table"); } if ($engine == "mroonga") { @@ -39,8 +40,9 @@ let $restart_parameters = --disable-provider-$alg; source include/restart_mysqld.inc; if ($engine == "innodb") { - error ER_PROVIDER_NOT_LOADED; + error ER_NO_SUCH_TABLE_IN_ENGINE; select a, left(b, 9), length(b) from t1; + show warnings; } if ($engine == "mroonga"){ select a, left(b, 9), length(b) from t1; diff --git a/mysql-test/suite/plugins/t/simple_password_check.test b/mysql-test/suite/plugins/t/simple_password_check.test index 3ce2d86cd68..442585e89d4 100644 --- a/mysql-test/suite/plugins/t/simple_password_check.test +++ b/mysql-test/suite/plugins/t/simple_password_check.test @@ -150,3 +150,21 @@ flush privileges; show grants for foo1@localhost; drop user foo1@localhost; uninstall plugin simple_password_check; + + +--echo # +--echo # MDEV-22418 mysqladmin wrong error with simple_password_check +--echo # + +install soname "simple_password_check"; + +--replace_regex /.*[\/\\]// /(mysqladmin|mariadb-admin)(\.exe)?/MARIADB-ADMIN/ +--error 1 +--exec $MYSQLADMIN -uroot password foo 2>&1 + +--echo # All done +uninstall plugin simple_password_check; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/suite/plugins/t/test_sql_service.test b/mysql-test/suite/plugins/t/test_sql_service.test index 2f53c1d5b3e..ee611ef9e86 100644 --- a/mysql-test/suite/plugins/t/test_sql_service.test +++ b/mysql-test/suite/plugins/t/test_sql_service.test @@ -1,8 +1,6 @@ --source include/not_embedded.inc --source include/have_log_bin.inc -reset master; # clear binlogs - if (!$TEST_SQL_SERVICE_SO) { skip No TEST_SQL_SERVICE plugin; } @@ -13,6 +11,7 @@ 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'; @@ -76,8 +75,7 @@ drop table t1; uninstall plugin test_sql_service; # Check that statements were executed/binlogged in correct order. -source include/show_binlog_events.inc; +--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,100; - +# SHOW BINLOG EVENTS LIMIT 3,5; diff --git a/mysql-test/suite/roles/set_default_role_for.result b/mysql-test/suite/roles/set_default_role_for.result index 57a1471126c..1b133b1baae 100644 --- a/mysql-test/suite/roles/set_default_role_for.result +++ b/mysql-test/suite/roles/set_default_role_for.result @@ -14,7 +14,7 @@ set default role role_a for user_a@localhost; set default role invalid_role for user_a@localhost; ERROR OP000: Invalid role specification `invalid_role` set default role role_b for user_a@localhost; -ERROR OP000: User `root`@`localhost` has not been granted role `role_b` +ERROR OP000: User `user_a`@`localhost` has not been granted role `role_b` set default role role_b for user_b@localhost; show grants; Grants for user_a@localhost diff --git a/mysql-test/suite/roles/set_default_role_invalid.result b/mysql-test/suite/roles/set_default_role_invalid.result index 12e2c035a7d..2cd84cf2ff0 100644 --- a/mysql-test/suite/roles/set_default_role_invalid.result +++ b/mysql-test/suite/roles/set_default_role_invalid.result @@ -48,7 +48,7 @@ CREATE USER b; CREATE ROLE r1; CREATE ROLE r2; SET DEFAULT ROLE r1 FOR a; -ERROR OP000: User `root`@`localhost` has not been granted role `r1` +ERROR OP000: User `a`@`%` has not been granted role `r1` GRANT r1 TO b; GRANT r2 TO b; SET DEFAULT ROLE r1 FOR b; @@ -100,7 +100,7 @@ GRANT USAGE ON *.* TO `b`@`%` GRANT SELECT, UPDATE ON `mysql`.* TO `b`@`%` SET DEFAULT ROLE `r2` FOR `b`@`%` SET DEFAULT ROLE r1 FOR a; -ERROR OP000: User `b`@`%` has not been granted role `r1` +ERROR OP000: User `a`@`%` has not been granted role `r1` SET DEFAULT ROLE invalid_role; ERROR OP000: Invalid role specification `invalid_role` SET DEFAULT ROLE invalid_role FOR a; @@ -117,7 +117,7 @@ SET DEFAULT ROLE None; # Change user b (session 3: role granted to user a) SET DEFAULT ROLE r1 FOR a; SET DEFAULT ROLE r2 FOR a; -ERROR OP000: User `b`@`%` has not been granted role `r2` +ERROR OP000: User `a`@`%` has not been granted role `r2` SET DEFAULT ROLE invalid_role; ERROR OP000: Invalid role specification `invalid_role` SET DEFAULT ROLE invalid_role FOR a; diff --git a/mysql-test/suite/roles/set_default_role_invalid.test b/mysql-test/suite/roles/set_default_role_invalid.test index 02fca1107e2..d2ef01b8f88 100644 --- a/mysql-test/suite/roles/set_default_role_invalid.test +++ b/mysql-test/suite/roles/set_default_role_invalid.test @@ -70,7 +70,6 @@ CREATE USER a; CREATE USER b; CREATE ROLE r1; CREATE ROLE r2; -# Role has not been granted to user a, but the role is visible to current_user --error ER_INVALID_ROLE SET DEFAULT ROLE r1 FOR a; # Granting roles to user b diff --git a/mysql-test/suite/roles/set_default_role_invalid_skip_name_resolve-master.opt b/mysql-test/suite/roles/set_default_role_invalid_skip_name_resolve-master.opt new file mode 100644 index 00000000000..ec008a812ce --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_invalid_skip_name_resolve-master.opt @@ -0,0 +1 @@ +--skip-name-resolve \ No newline at end of file diff --git a/mysql-test/suite/roles/set_default_role_invalid_skip_name_resolve.result b/mysql-test/suite/roles/set_default_role_invalid_skip_name_resolve.result new file mode 100644 index 00000000000..a267e114012 --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_invalid_skip_name_resolve.result @@ -0,0 +1,85 @@ +# +# MDEV-26875: Wrong user in SET DEFAULT ROLE error +# +create user test_user; +create role test_role; +show grants for test_user; +Grants for test_user@% +GRANT USAGE ON *.* TO `test_user`@`%` +set default role test_role for test_user; +ERROR OP000: User `test_user`@`%` has not been granted role `test_role` +grant test_role to test_user; +set default role test_role for test_user; +show grants for test_user; +Grants for test_user@% +GRANT `test_role` TO `test_user`@`%` +GRANT USAGE ON *.* TO `test_user`@`%` +SET DEFAULT ROLE `test_role` FOR `test_user`@`%` +set default role none for test_user; +# +# Try to set default role to role(`test_role`). +-------------------------------------------------------------- +show grants for test_role; +Grants for test_role +GRANT USAGE ON *.* TO `test_role` +create role new_role; +grant new_role to test_role; +show grants for test_role; +Grants for test_role +GRANT `new_role` TO `test_role` +GRANT USAGE ON *.* TO `test_role` +GRANT USAGE ON *.* TO `new_role` +set default role new_role for test_role; +ERROR OP000: User `test_role`@`%` has not been granted role `new_role` +# +# Test of errors, where hostname cannot be resolved `test_user` +-------------------------------------------------------------- +grant test_role to test_user@'%'; +set default role test_role for test_user@'%'; +connect con_test_user,127.0.0.1,test_user,,,$MASTER_MYPORT; +show grants; +Grants for test_user@% +GRANT `test_role` TO `test_user`@`%` +GRANT USAGE ON *.* TO `test_user`@`%` +GRANT `new_role` TO `test_role` +GRANT USAGE ON *.* TO `test_role` +GRANT USAGE ON *.* TO `new_role` +SET DEFAULT ROLE `test_role` FOR `test_user`@`%` +select current_role; +current_role +test_role +set role `new_role`; +ERROR OP000: User `test_user`@`%` has not been granted role `new_role` +connection default; +set default role none for test_user; +disconnect con_test_user; +connect con_test_user,127.0.0.1,test_user,,,$MASTER_MYPORT; +select current_role; +current_role +NULL +set role `new_role`; +ERROR OP000: User `test_user`@`%` has not been granted role `new_role` +connection default; +disconnect con_test_user; +# +# Test of anonymous user connection +-------------------------------------------------------------- +grant test_role to ''@localhost; +connect con1,localhost,'',,,$MASTER_MYPORT; +SELECT CURRENT_ROLE; +CURRENT_ROLE +NULL +SET role test_role; +SELECT CURRENT_ROLE; +CURRENT_ROLE +test_role +SET role new_role; +ERROR OP000: User ``@`localhost` has not been granted role `new_role` +set default role test_role for ''@localhost; +ERROR 42000: You are using MariaDB as an anonymous user and anonymous users are not allowed to modify user settings +connection default; +disconnect con1; +REVOKE all privileges, grant option from ''@localhost; +drop role new_role; +drop role test_role; +drop user test_user; diff --git a/mysql-test/suite/roles/set_default_role_invalid_skip_name_resolve.test b/mysql-test/suite/roles/set_default_role_invalid_skip_name_resolve.test new file mode 100644 index 00000000000..5b4b14d3377 --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_invalid_skip_name_resolve.test @@ -0,0 +1,78 @@ +source include/not_embedded.inc; + +--echo # +--echo # MDEV-26875: Wrong user in SET DEFAULT ROLE error +--echo # +create user test_user; +create role test_role; +show grants for test_user; +--error ER_INVALID_ROLE +set default role test_role for test_user; +grant test_role to test_user; +set default role test_role for test_user; +show grants for test_user; +set default role none for test_user; + +--echo # +--echo # Try to set default role to role(`test_role`). +--echo -------------------------------------------------------------- +show grants for test_role; +create role new_role; +grant new_role to test_role; +show grants for test_role; +# One can not set role to a role +--error ER_INVALID_ROLE +set default role new_role for test_role; + +--echo # +--echo # Test of errors, where hostname cannot be resolved `test_user` +--echo -------------------------------------------------------------- +# `new_role` is granted to `test_role` +grant test_role to test_user@'%'; +set default role test_role for test_user@'%'; + +connect con_test_user,127.0.0.1,test_user,,,$MASTER_MYPORT; +show grants; +select current_role; +# `test_user` indirectly granted `new_role` +--error ER_INVALID_ROLE +set role `new_role`; + +connection default; +set default role none for test_user; +disconnect con_test_user; + +connect con_test_user,127.0.0.1,test_user,,,$MASTER_MYPORT; +select current_role; +--error ER_INVALID_ROLE +set role `new_role`; + +connection default; +disconnect con_test_user; + +--echo # +--echo # Test of anonymous user connection +--echo -------------------------------------------------------------- +--source include/add_anonymous_users.inc +# Skip windows, since it uses current user `Administrator` in buildbot. +--source include/not_windows.inc +grant test_role to ''@localhost; + +connect(con1,localhost,'',,,$MASTER_MYPORT); +SELECT CURRENT_ROLE; +SET role test_role; +SELECT CURRENT_ROLE; +# user cannot set subset role, since it is not granted explicitly +--error ER_INVALID_ROLE +SET role new_role; +--error ER_PASSWORD_ANONYMOUS_USER +set default role test_role for ''@localhost; + +connection default; +disconnect con1; +REVOKE all privileges, grant option from ''@localhost; +--source include/delete_anonymous_users.inc + +drop role new_role; +drop role test_role; +drop user test_user; 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/mysqlbinlog_slave_consistency.inc b/mysql-test/suite/rpl/include/mysqlbinlog_slave_consistency.inc index 48e4399d162..b571c24e9dc 100644 --- a/mysql-test/suite/rpl/include/mysqlbinlog_slave_consistency.inc +++ b/mysql-test/suite/rpl/include/mysqlbinlog_slave_consistency.inc @@ -128,6 +128,7 @@ if (!$slave_sql_errno) } --echo # Stop $con2 so it stops receiving $con1 events. +--let $rpl_allow_error= 1 --source include/stop_slave.inc --connection $con1 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 2634a6027a3..77b969fc05b 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 @@ -418,6 +418,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'`) { @@ -437,7 +439,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 96d75f33fb0..a8b729d0cb5 100644 --- a/mysql-test/suite/rpl/include/rpl_parallel_29322.inc +++ b/mysql-test/suite/rpl/include/rpl_parallel_29322.inc @@ -67,6 +67,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 ae5f83613fe..56b04494a7c 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_deadlock_show_slave_status.result b/mysql-test/suite/rpl/r/rpl_deadlock_show_slave_status.result new file mode 100644 index 00000000000..12ad5870d4a --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_deadlock_show_slave_status.result @@ -0,0 +1,66 @@ +include/master-slave.inc +[connection master] +# +# Initialize test data +connection master; +create table t1 (a int) engine=innodb; +insert into t1 values (1); +include/save_master_gtid.inc +connection slave; +include/sync_with_master_gtid.inc +include/stop_slave.inc +call mtr.add_suppression("Connection was killed"); +call mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +set @save_parallel_threads= @@global.slave_parallel_threads; +set @save_parallel_mode= @@global.slave_parallel_mode; +set @save_transaction_retries= @@global.slave_transaction_retries; +set @save_innodb_lock_wait_timeout= @@global.innodb_lock_wait_timeout; +set @@global.slave_parallel_threads= 2; +set @@global.slave_parallel_mode= CONSERVATIVE; +set @@global.slave_transaction_retries= 0; +set @@global.innodb_lock_wait_timeout= 10; +# Grabbing lock on innodb row to force future replication transaction to wait (and eventually timeout) +BEGIN; +select * from t1 where a=1 for update; +a +1 +connection master; +set @old_dbug= @@session.debug_dbug; +set @@session.debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10000; +update t1 set a=2 where a=1; +SET @commit_id= 10001; +insert into t1 values (3); +set @@session.debug_dbug= @old_dbug; +connection slave; +start slave; +# Waiting for first transaction to start (and be held at innodb row lock).. +# Waiting for next transaction to start and hold at do_gco_wait().. +connection slave1; +set @@session.debug_dbug="+d,hold_sss_with_err_lock"; +show slave status; +connection slave; +set debug_sync="now wait_for sss_got_err_lock"; +kill ; +set debug_sync="now signal sss_continue"; +connection slave1; +# Waiting for SHOW SLAVE STATUS to complete.. +# ..done +connection slave; +ROLLBACK; +include/wait_for_slave_sql_error.inc [errno=1927] +# +# Cleanup +connection master; +drop table t1; +include/save_master_gtid.inc +connection slave; +set debug_sync= "RESET"; +set @@global.slave_parallel_threads= @save_parallel_threads; +set @@global.slave_parallel_mode= @save_parallel_mode; +set @@global.slave_transaction_retries= @save_transaction_retries; +set @@global.innodb_lock_wait_timeout= @save_innodb_lock_wait_timeout; +start slave sql_thread; +include/sync_with_master_gtid.inc +include/rpl_end.inc +# End of rpl_deadlock_show_slave_status.test 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_basic.result b/mysql-test/suite/rpl/r/rpl_gtid_basic.result index 51ca4c62433..b2997cdfa3a 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_basic.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_basic.result @@ -188,6 +188,13 @@ BINLOG_GTID_POS('master-bin.000001',18446744073709551616) NULL Warnings: Warning 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated +SET sql_log_bin= 0; +CREATE TABLE t1 AS SELECT MASTER_POS_WAIT(@binlog_file, 4, 0); +SELECT BINLOG_GTID_POS(@binlog_file, 4); +BINLOG_GTID_POS(@binlog_file, 4) +NULL +DROP TABLE t1; +SET sql_log_bin= 1; *** Some tests of @@GLOBAL.gtid_binlog_state *** connection server_2; include/sync_with_master_gtid.inc 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_slave_filtering.result b/mysql-test/suite/rpl/r/rpl_gtid_slave_filtering.result new file mode 100644 index 00000000000..84080b94de8 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_gtid_slave_filtering.result @@ -0,0 +1,78 @@ +include/rpl_init.inc [topology=1->2->3] +*** Test GTID master switch in a topology with filtered events. +*** With --gtid-ignore-duplicate and --gtid-strict-mode, should allow +*** GTID connect at a GTID position that is filtered on the new master. +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1); +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1,1); +INSERT INTO t1 VALUES (2,1); +INSERT INTO t3 VALUES (2,1); +include/save_master_gtid.inc +connection server_2; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,2); +include/sync_with_master_gtid.inc +include/save_master_gtid.inc +connection server_3; +include/sync_with_master_gtid.inc +*** Promote 3 as new master, demote 2 as slave of 3. +*** GTID position of 2 in domain 0 is filtered on 3. +connection server_2; +include/stop_slave.inc +connection server_3; +include/stop_slave.inc +CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_1, +MASTER_USE_GTID=SLAVE_POS; +connection server_2; +CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_3, +MASTER_USE_GTID=SLAVE_POS; +include/start_slave.inc +connection server_3; +include/start_slave.inc +connection server_1; +INSERT INTO t1 VALUES (3,1); +INSERT INTO t3 VALUES (3,1); +include/save_master_gtid.inc +connection server_3; +INSERT INTO t2 VALUES (2,2); +include/sync_with_master_gtid.inc +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +a b +1 1 +2 1 +3 1 +SELECT * FROM t3 ORDER BY a; +ERROR 42S02: Table 'test.t3' doesn't exist +SELECT * FROM t2 ORDER BY a; +a b +1 2 +2 2 +*** Restore original topology. +connection server_3; +include/stop_slave.inc +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_1, +MASTER_USE_GTID=SLAVE_POS; +include/start_slave.inc +connection server_3; +CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_2, +MASTER_USE_GTID=SLAVE_POS; +include/start_slave.inc +connection server_1; +DROP TABLE t1; +DROP TABLE t3; +include/save_master_gtid.inc +connection server_2; +DROP TABLE t2; +include/sync_with_master_gtid.inc +include/save_master_gtid.inc +connection server_3; +include/sync_with_master_gtid.inc +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_gtid_startpos.result b/mysql-test/suite/rpl/r/rpl_gtid_startpos.result index e38eddcc97a..f271e730921 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=SLAVE_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, MASTER_USE_GTID=NO; 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 88e0214150b..a9bd16cc85a 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result @@ -228,7 +228,7 @@ call mtr.add_suppression("Slave SQL.*Duplicate entry .1. for key .PRIMARY.. on q 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"); set sql_log_bin= 1; Heartbeat events are received while sql thread stopped (1 means 'yes'): 1 -include/stop_slave.inc +include/stop_slave_io.inc set sql_log_bin= 0; DROP TABLE t1; set sql_log_bin= 1; diff --git a/mysql-test/suite/rpl/r/rpl_invoked_features.result b/mysql-test/suite/rpl/r/rpl_invoked_features.result index 3cfd40d5a0e..c8acf49cdf7 100644 --- a/mysql-test/suite/rpl/r/rpl_invoked_features.result +++ b/mysql-test/suite/rpl/r/rpl_invoked_features.result @@ -1,15 +1,8 @@ include/master-slave.inc [connection master] -USE test; -DROP VIEW IF EXISTS v1,v11; -DROP TABLE IF EXISTS t1,t2,t3,t11,t12,t13; -DROP PROCEDURE IF EXISTS p1; -DROP PROCEDURE IF EXISTS p11; -DROP FUNCTION IF EXISTS f1; -DROP FUNCTION IF EXISTS f2; -DROP EVENT IF EXISTS e1; -DROP EVENT IF EXISTS e11; - +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +call mtr.add_suppression("Event Scheduler: .* Duplicate entry '10' for key 'a'"); +# Create tables CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, c VARCHAR(64)) ENGINE=myisam; INSERT INTO t1 VALUES (1,1,'1'); INSERT INTO t1 VALUES (2,2,UUID()); @@ -22,7 +15,7 @@ INSERT INTO t11 VALUES (2,2,UUID()); CREATE TABLE t12 (a INT UNIQUE, b INT, c VARCHAR(64)) ENGINE=innodb; INSERT INTO t12 VALUES (1,1,'1'); INSERT INTO t12 VALUES (2,2,UUID()); - +# Create invoked features CREATE VIEW v1 AS SELECT * FROM t1; CREATE VIEW v11 AS SELECT * FROM t11; CREATE TRIGGER t1_tr1 BEFORE INSERT ON t1 FOR EACH ROW @@ -45,7 +38,7 @@ BEGIN UPDATE t12 SET c = ''; UPDATE t13 SET c = ''; END| -CREATE EVENT e1 ON SCHEDULE EVERY 10 SECOND DISABLE DO +CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DISABLE DO BEGIN ALTER EVENT e1 DISABLE; CALL p1(10, ''); @@ -78,7 +71,7 @@ CREATE PROCEDURE p11 (IN x INT, IN y VARCHAR(64)) BEGIN INSERT IGNORE INTO t11 VALUES (x,x,y); END| - +# Do some actions for non-transactional tables CREATE TABLE t3 SELECT * FROM v1; INSERT INTO t1 VALUES (3,3,''); UPDATE t1 SET c='2' WHERE a = 1; @@ -90,7 +83,7 @@ INSERT INTO t1 VALUES(6,6,f1(6)); INSERT INTO t1 VALUES (102,102,''); INSERT INTO t1 VALUES(7,7,f2(7)); INSERT INTO t1 VALUES (103,103,''); - +# Do some actions for transactional tables CREATE TABLE t13 SELECT * FROM v11; INSERT INTO t11 VALUES (3,3,''); UPDATE t11 SET c='2' WHERE a = 1; @@ -102,12 +95,12 @@ INSERT INTO t11 VALUES(6,6,f1(6)); INSERT INTO t11 VALUES (102,102,''); INSERT INTO t11 VALUES(7,7,f2(7)); INSERT INTO t11 VALUES (103,103,''); - +# Scheduler is on SET GLOBAL EVENT_SCHEDULER = on; ALTER EVENT e1 ENABLE; ALTER EVENT e11 ENABLE; SET GLOBAL EVENT_SCHEDULER = off; - +# Check original objects SHOW TABLES LIKE 't%'; Tables_in_test (t%) t1 @@ -268,7 +261,7 @@ a b 102 102 103 103 connection slave; - +# Check replicated objects SHOW TABLES LIKE 't%'; Tables_in_test (t%) t1 @@ -297,7 +290,7 @@ SELECT event_name, status FROM information_schema.events WHERE event_schema='tes event_name status e1 SLAVESIDE_DISABLED e11 SLAVESIDE_DISABLED - +# Check replicated data SELECT COUNT(*) FROM t1; COUNT(*) 12 @@ -429,7 +422,7 @@ a b 102 102 103 103 connection master; - +# Remove UUID() before comparing and sort tables UPDATE t1 SET c=''; UPDATE t2 SET c=''; UPDATE t3 SET c=''; @@ -439,10 +432,8 @@ UPDATE t13 SET c=''; ALTER TABLE t3 ORDER BY a; ALTER TABLE t13 ORDER BY a; connection slave; - - +# Compare a data from master and slave connection master; - DROP VIEW IF EXISTS v1,v11; DROP TABLE IF EXISTS t1,t2,t3,t11,t12,t13; DROP PROCEDURE IF EXISTS p1; diff --git a/mysql-test/suite/rpl/r/rpl_mdev_17614.result b/mysql-test/suite/rpl/r/rpl_mdev_17614.result index 0cc924749c8..7e2e8727b45 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 include/reset_slave.inc 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 include/reset_slave.inc 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 e94e097f41f..dbaceb65906 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 @@ -197,7 +197,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_parallel_sbm.result b/mysql-test/suite/rpl/r/rpl_parallel_sbm.result index f3cc8454510..7990a663f04 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_sbm.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_sbm.result @@ -15,9 +15,6 @@ create table t2 (a int); include/sync_slave_sql_with_master.inc # # Pt 1) Ensure SBM is updated immediately upon arrival of the next event -# Lock t1 on slave so the first received transaction does not complete/commit -connection slave; -LOCK TABLES t1 WRITE; connection master; # Sleep 2 to allow a buffer between events for SBM check insert into t1 values (0); @@ -26,8 +23,16 @@ connection slave; # Waiting for transaction to arrive on slave and begin SQL Delay.. # Validating SBM is updated on event arrival.. # ..done +# MDEV-32265. At time of STOP SLAVE, if the SQL Thread is currently +# delaying a transaction; then when the reciprocal START SLAVE occurs, +# if the event is still to be delayed, SBM should resume accordingly +include/stop_slave.inc +include/start_slave.inc connection slave; -UNLOCK TABLES; +# Waiting for replica to resume the delay for the transaction +# Sleeping 1s to increment SBM +# Ensuring Seconds_Behind_Master increases after sleeping.. +# ..done include/sync_with_master_gtid.inc # # Pt 2) If the worker threads have not entered an idle state, ensure diff --git a/mysql-test/suite/rpl/r/rpl_parallel_seq.result b/mysql-test/suite/rpl/r/rpl_parallel_seq.result index 8b1bb7c81c6..8f55f52e54c 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_seq.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_seq.result @@ -82,6 +82,37 @@ SELECT @@global.gtid_binlog_state, @@global.gtid_slave_pos as "all through 101 h @@global.gtid_binlog_state all through 101 have been committed 0-1-101 0-1-101 connection slave; +flush tables with read lock; +connection master; +CREATE OR REPLACE SEQUENCE s3 ENGINE=innodb; +SELECT NEXT VALUE FOR s3 into @tmpvar; +include/save_master_gtid.inc +connection slave; +unlock tables; +include/sync_with_master_gtid.inc +connection slave; +flush tables with read lock; +connection master; +CREATE OR REPLACE SEQUENCE s3 ENGINE=innodb; +SELECT NEXT VALUE FOR s3 into @tmpvar; +include/save_master_gtid.inc +connection slave; +unlock tables; +include/sync_with_master_gtid.inc +connection slave; +BEGIN /* slave local Trx */; +select count(*) from s3; +count(*) +1 +connection master; +CREATE OR REPLACE SEQUENCE s3 ENGINE=innodb; +SELECT NEXT VALUE FOR s3 into @tmpvar; +include/save_master_gtid.inc +connection slave; +connection slave; +rollback /* Trx */; +include/sync_with_master_gtid.inc +connection slave; include/stop_slave.inc SET debug_sync = RESET; SET @@global.slave_parallel_threads= 0; @@ -90,7 +121,10 @@ SET @@global.debug_dbug = ""; SET @@global.gtid_strict_mode=0; include/start_slave.inc connection master; -DROP SEQUENCE s2; +BEGIN; +INSERT INTO ti SET a=32593; +CREATE SEQUENCE s4; +DROP SEQUENCE s2,s3,s4; DROP TABLE ti; connection slave; include/rpl_end.inc 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 8ef10bf47b5..b4e3704c62f 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 include/reset_slave.inc include/start_slave.inc include/rpl_reset.inc diff --git a/mysql-test/suite/rpl/r/rpl_row_utf32.result b/mysql-test/suite/rpl/r/rpl_row_utf32.result index 6d177b7cda0..d167b0c747f 100644 --- a/mysql-test/suite/rpl/r/rpl_row_utf32.result +++ b/mysql-test/suite/rpl/r/rpl_row_utf32.result @@ -19,6 +19,64 @@ connection master; INSERT INTO t1(c1) VALUES ('insert into t1'); DROP TABLE t1; connection slave; +# +# MDEV-32249 strings/ctype-ucs2.c:2336: my_vsnprintf_utf32: Assertion `(n +# +# +# Testing with VARCHAR +# +connection slave; +include/stop_slave.inc +SET GLOBAL SLAVE_TYPE_CONVERSIONS= ''; +include/start_slave.inc +connection master; +CREATE TABLE t1 (a INT); +connection slave; +ALTER TABLE t1 MODIFY a VARCHAR(1) CHARACTER SET utf32; +connection master; +INSERT INTO t1 VALUES (1); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(1) CHARACTER SET utf32 COLLATE utf32_general_ci DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM t1 ORDER BY a; +a +SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; +START SLAVE; +connection master; +DROP TABLE t1; +connection slave; +# +# Testing with CHAR +# +connection slave; +include/stop_slave.inc +SET GLOBAL SLAVE_TYPE_CONVERSIONS= ''; +include/start_slave.inc +connection master; +CREATE TABLE t1 (a INT); +connection slave; +ALTER TABLE t1 MODIFY a CHAR(1) CHARACTER SET utf32; +connection master; +INSERT INTO t1 VALUES (1); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(1) CHARACTER SET utf32 COLLATE utf32_general_ci DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM t1 ORDER BY a; +a +SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; +START SLAVE; +connection master; +DROP TABLE t1; +connection slave; +connection slave; SET GLOBAL SLAVE_TYPE_CONVERSIONS= @saved_slave_type_conversions; include/stop_slave.inc include/start_slave.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_shutdown_await_ack.result b/mysql-test/suite/rpl/r/rpl_semi_sync_shutdown_await_ack.result index 719b61b796b..394a7acad41 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_shutdown_await_ack.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_shutdown_await_ack.result @@ -8,6 +8,7 @@ connection server_1; # Slaves which simulate an error will produce a timeout on the primary call mtr.add_suppression("Timeout waiting"); call mtr.add_suppression("did not exit"); +call mtr.add_suppression("Got an error reading communication packets"); # Suppress slave errors related to the simulated error connection server_2; call mtr.add_suppression("reply failed"); 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 3a30381d7c4..bc2cba4a06a 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 @@ -31,6 +31,13 @@ connection slave; # Compare the tables on master and 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_dbug; +SET GLOBAL debug_dbug="+d,semisync_corrupt_magic"; +insert into t1 values (11); +connection slave; +connection master; +SET GLOBAL debug_dbug= @save_debug_master; drop table t1; connection slave; set global rpl_semi_sync_slave_enabled = OFF; 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_start_alter_1.result b/mysql-test/suite/rpl/r/rpl_start_alter_1.result index 9edb23216fe..de7c0875344 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_1.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_1.result @@ -1,6 +1,7 @@ include/master-slave.inc [connection master] connection master; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_2.result b/mysql-test/suite/rpl/r/rpl_start_alter_2.result index a862fc5556a..49af973fb61 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_2.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_2.result @@ -1,6 +1,7 @@ include/master-slave.inc [connection master] connection master; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_3.result b/mysql-test/suite/rpl/r/rpl_start_alter_3.result index 97754401471..31d0023bb46 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_3.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_3.result @@ -1,6 +1,7 @@ include/master-slave.inc [connection master] connection master; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_4.result b/mysql-test/suite/rpl/r/rpl_start_alter_4.result index 9d7d6376bba..819bcda0c00 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_4.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_4.result @@ -1,6 +1,7 @@ include/master-slave.inc [connection master] connection master; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_5.result b/mysql-test/suite/rpl/r/rpl_start_alter_5.result index 4e592c1931f..ef19cd8f380 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_5.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_5.result @@ -1,6 +1,7 @@ include/master-slave.inc [connection master] connection master; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_6.result b/mysql-test/suite/rpl/r/rpl_start_alter_6.result index 6c26d511ee2..59a8363165f 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_6.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_6.result @@ -1,6 +1,7 @@ include/master-slave.inc [connection master] connection master; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_7.result b/mysql-test/suite/rpl/r/rpl_start_alter_7.result index cfe31497179..df7664d4aa2 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_7.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_7.result @@ -10,6 +10,10 @@ Warnings: Note 1255 Slave already has been stopped set global binlog_alter_two_phase=true; connection server_3; +SET STATEMENT sql_log_bin=0 FOR +CALL mtr.add_suppression("The table mysql.gtid_slave_pos was removed. This change will not take full effect until all SQL threads have been restarted"); +SET STATEMENT sql_log_bin=0 FOR +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; SET GLOBAL slave_parallel_threads=8; set global slave_parallel_mode=optimistic; set global gtid_strict_mode=1; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_8.result b/mysql-test/suite/rpl/r/rpl_start_alter_8.result index 8002f295f5c..406f2d1f6fc 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_8.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_8.result @@ -10,6 +10,10 @@ Warnings: Note 1255 Slave already has been stopped set global binlog_alter_two_phase=true; connection server_3; +SET STATEMENT sql_log_bin=0 FOR +CALL mtr.add_suppression("The table mysql.gtid_slave_pos was removed. This change will not take full effect until all SQL threads have been restarted"); +SET STATEMENT sql_log_bin=0 FOR +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; SET GLOBAL slave_parallel_threads=20; set global slave_parallel_mode=optimistic; set global gtid_strict_mode=1; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_mysqlbinlog_1.result b/mysql-test/suite/rpl/r/rpl_start_alter_mysqlbinlog_1.result index bf9d9be0ec6..b11804ed1c7 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_mysqlbinlog_1.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_mysqlbinlog_1.result @@ -4,6 +4,8 @@ connection master; set global binlog_alter_two_phase=true; connection slave; include/stop_slave.inc +SET STATEMENT sql_log_bin=0 FOR +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; set global gtid_strict_mode=1; # Legacy Master Slave connect master_node,127.0.0.1,root,,$db_name, $M_port; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_mysqlbinlog_2.result b/mysql-test/suite/rpl/r/rpl_start_alter_mysqlbinlog_2.result index 2c1ae667fd6..55bec7d3998 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_mysqlbinlog_2.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_mysqlbinlog_2.result @@ -49,6 +49,10 @@ connection server_2; SET @save_binlog_alter_two_phase= @@GLOBAL.binlog_alter_two_phase; SET GLOBAL binlog_alter_two_phase = ON; connection server_3; +SET STATEMENT sql_log_bin=0 FOR +CALL mtr.add_suppression("The table mysql.gtid_slave_pos was removed. This change will not take full effect until all SQL threads have been restarted"); +SET STATEMENT sql_log_bin=0 FOR +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; SET @save_gtid_strict_mode= @@GLOBAL.gtid_strict_mode; SET @slave_parallel_threads= @@GLOBAL.slave_parallel_threads; SET @slave_parallel_mode= @@GLOBAL.slave_parallel_mode; 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 e94e097f41f..dbaceb65906 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 @@ -197,7 +197,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 40910b8c1f2..9575ea89892 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; Warnings: Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos' 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 80414ac1f8d..8287b8feab5 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 include/reset_slave.inc Warnings: Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos' 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 fc765744b3f..bea325b251f 100644 --- a/mysql-test/suite/rpl/t/rpl_checksum.test +++ b/mysql-test/suite/rpl/t/rpl_checksum.test @@ -95,6 +95,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_deadlock_show_slave_status.test b/mysql-test/suite/rpl/t/rpl_deadlock_show_slave_status.test new file mode 100644 index 00000000000..4c41011e7b6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_deadlock_show_slave_status.test @@ -0,0 +1,121 @@ +# +# Verify that SHOW SLAVE STATUS will not cause deadlocks on the replica. +# A deadlock has been seen in do_gco_wait if the thread is killed, as it will +# hold the LOCK_parallel_entry, and during error reporting, try to grab the +# err_lock. Prior to MDEV-10653, SHOW SLAVE STATUS would grab these locks in +# the reverse order, as calling workers_idle() used to grab LOCK_parallel_entry +# with the err_lock already grabbed (though the MDEV-10653 patch changed the +# workles_idle() implementation to remove the need for locking the +# parallel_entry). +# +# References: +# MDEV-10653: SHOW SLAVE STATUS Can Deadlock an Errored Slave +# + +--source include/master-slave.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_binlog_format_row.inc + +--echo # +--echo # Initialize test data +--connection master +create table t1 (a int) engine=innodb; +insert into t1 values (1); +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc + +call mtr.add_suppression("Connection was killed"); +call mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); + +set @save_parallel_threads= @@global.slave_parallel_threads; +set @save_parallel_mode= @@global.slave_parallel_mode; +set @save_transaction_retries= @@global.slave_transaction_retries; +set @save_innodb_lock_wait_timeout= @@global.innodb_lock_wait_timeout; + +set @@global.slave_parallel_threads= 2; +set @@global.slave_parallel_mode= CONSERVATIVE; +set @@global.slave_transaction_retries= 0; +set @@global.innodb_lock_wait_timeout= 10; + +--echo # Grabbing lock on innodb row to force future replication transaction to wait (and eventually timeout) +BEGIN; +select * from t1 where a=1 for update; + +--connection master + +set @old_dbug= @@session.debug_dbug; +set @@session.debug_dbug="+d,binlog_force_commit_id"; + + +# GCO 1 +SET @commit_id= 10000; +# T1 +update t1 set a=2 where a=1; + +# GCO 2 +SET @commit_id= 10001; +# T2 +insert into t1 values (3); + +set @@session.debug_dbug= @old_dbug; + +--connection slave +start slave; + +--echo # Waiting for first transaction to start (and be held at innodb row lock).. +--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 # Waiting for next transaction to start and hold at do_gco_wait().. +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to start commit%' and command LIKE 'Slave_worker'; +--source include/wait_condition.inc + +--connection slave1 +set @@session.debug_dbug="+d,hold_sss_with_err_lock"; +--send show slave status + +--connection slave +set debug_sync="now wait_for sss_got_err_lock"; + +--let $t2_tid= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Waiting for prior transaction to start commit%'` +--replace_result $t2_tid "" +--eval kill $t2_tid +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE command LIKE 'Killed'; +--source include/wait_condition.inc + +set debug_sync="now signal sss_continue"; + +--connection slave1 +--echo # Waiting for SHOW SLAVE STATUS to complete.. +--disable_result_log +--reap +--enable_result_log +--echo # ..done + +--connection slave +ROLLBACK; +--let $slave_sql_errno= 1927 +--source include/wait_for_slave_sql_error.inc + + +--echo # +--echo # Cleanup +--connection master +drop table t1; +--source include/save_master_gtid.inc + +--connection slave +set debug_sync= "RESET"; +set @@global.slave_parallel_threads= @save_parallel_threads; +set @@global.slave_parallel_mode= @save_parallel_mode; +set @@global.slave_transaction_retries= @save_transaction_retries; +set @@global.innodb_lock_wait_timeout= @save_innodb_lock_wait_timeout; +start slave sql_thread; +--source include/sync_with_master_gtid.inc + +--source include/rpl_end.inc +--echo # End of rpl_deadlock_show_slave_status.test 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_basic.test b/mysql-test/suite/rpl/t/rpl_gtid_basic.test index 70bd0087f7a..a7af234d47e 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_basic.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_basic.test @@ -162,6 +162,13 @@ eval SELECT BINLOG_GTID_POS('$valid_binlog_name',0); eval SELECT BINLOG_GTID_POS('$valid_binlog_name',18446744073709551615); eval SELECT BINLOG_GTID_POS('$valid_binlog_name',18446744073709551616); +# MDEV-33045: Server crashes in Item_func_binlog_gtid_pos::val_str / Binary_string::c_ptr_safe +SET sql_log_bin= 0; +CREATE TABLE t1 AS SELECT MASTER_POS_WAIT(@binlog_file, 4, 0); +SELECT BINLOG_GTID_POS(@binlog_file, 4); +DROP TABLE t1; +SET sql_log_bin= 1; + --echo *** Some tests of @@GLOBAL.gtid_binlog_state *** --connection server_2 diff --git a/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test index 412489b3ee3..c9c4d6503a9 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test @@ -20,7 +20,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_slave_filtering.cnf b/mysql-test/suite/rpl/t/rpl_gtid_slave_filtering.cnf new file mode 100644 index 00000000000..a57dbbf3f56 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_slave_filtering.cnf @@ -0,0 +1,28 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb +gtid-domain-id=1 +gtid-strict-mode=0 +gtid-ignore-duplicates=1 + +[mysqld.2] +log-slave-updates +loose-innodb +gtid-domain-id=0 +replicate-ignore-table=test.t3 +gtid-strict-mode=0 +gtid-ignore-duplicates=1 + +[mysqld.3] +log-slave-updates +loose-innodb +gtid-domain-id=0 +replicate-ignore-table=test.t3 +gtid-strict-mode=0 +gtid-ignore-duplicates=1 + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_gtid_slave_filtering.test b/mysql-test/suite/rpl/t/rpl_gtid_slave_filtering.test new file mode 100644 index 00000000000..842bae8234c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_slave_filtering.test @@ -0,0 +1,109 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_mixed.inc + +--let $rpl_topology=1->2->3 +--source include/rpl_init.inc + +--echo *** Test GTID master switch in a topology with filtered events. +--echo *** With --gtid-ignore-duplicate and --gtid-strict-mode, should allow +--echo *** GTID connect at a GTID position that is filtered on the new master. + +--connection server_1 + +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1); +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1,1); +INSERT INTO t1 VALUES (2,1); +INSERT INTO t3 VALUES (2,1); +--source include/save_master_gtid.inc + +--connection server_2 +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,2); + +--let $slave_timeout= 10 +--source include/sync_with_master_gtid.inc +--source include/save_master_gtid.inc + +--connection server_3 +--source include/sync_with_master_gtid.inc + +--echo *** Promote 3 as new master, demote 2 as slave of 3. +--echo *** GTID position of 2 in domain 0 is filtered on 3. + +--connection server_2 +--source include/stop_slave.inc + +--connection server_3 +--source include/stop_slave.inc +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1, + MASTER_USE_GTID=SLAVE_POS; + +--connection server_2 +--replace_result $SERVER_MYPORT_3 SERVER_MYPORT_3 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_3, + MASTER_USE_GTID=SLAVE_POS; +--source include/start_slave.inc + +--connection server_3 +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (3,1); +INSERT INTO t3 VALUES (3,1); +--source include/save_master_gtid.inc + +--connection server_3 +INSERT INTO t2 VALUES (2,2); + +--source include/sync_with_master_gtid.inc +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 ORDER BY a; +# Verify that table t3 is being filtered. +--error 1146 +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + + +--echo *** Restore original topology. + +--connection server_3 +--source include/stop_slave.inc + +--connection server_2 +--source include/stop_slave.inc +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1, + MASTER_USE_GTID=SLAVE_POS; +--source include/start_slave.inc + +--connection server_3 +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_2, + MASTER_USE_GTID=SLAVE_POS; +--source include/start_slave.inc + + +# Cleanup + +--connection server_1 +DROP TABLE t1; +DROP TABLE t3; +--source include/save_master_gtid.inc + +--connection server_2 +DROP TABLE t2; +--source include/sync_with_master_gtid.inc +--source include/save_master_gtid.inc + +--connection server_3 +--source include/sync_with_master_gtid.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_startpos.test b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test index c7bcc1bb97e..d0885ab8912 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 9760d4df00c..b5ff294908b 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test @@ -210,7 +210,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 d6d14e0278d..b6133625c02 100644 --- a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test @@ -331,7 +331,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 set sql_log_bin= 0; DROP TABLE t1; set sql_log_bin= 1; diff --git a/mysql-test/suite/rpl/t/rpl_invoked_features.test b/mysql-test/suite/rpl/t/rpl_invoked_features.test index cd2b770c419..0467a243de8 100644 --- a/mysql-test/suite/rpl/t/rpl_invoked_features.test +++ b/mysql-test/suite/rpl/t/rpl_invoked_features.test @@ -8,9 +8,8 @@ --source include/have_innodb.inc --source include/master-slave.inc -disable_query_log; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); -enable_query_log; +call mtr.add_suppression("Event Scheduler: .* Duplicate entry '10' for key 'a'"); # --disable_warnings/--enable_warnings added before/after query # if one uses UUID() function because we need to avoid warnings @@ -22,60 +21,35 @@ enable_query_log; # Transactional engine --let $engine_type2= innodb - -# -# Clean up -# - -USE test; ---disable_warnings -DROP VIEW IF EXISTS v1,v11; -DROP TABLE IF EXISTS t1,t2,t3,t11,t12,t13; -DROP PROCEDURE IF EXISTS p1; -DROP PROCEDURE IF EXISTS p11; -DROP FUNCTION IF EXISTS f1; -DROP FUNCTION IF EXISTS f2; -DROP EVENT IF EXISTS e1; -DROP EVENT IF EXISTS e11; ---enable_warnings - - # # Prepare objects (tables etc) # -# Create tables +--echo # Create tables ---echo eval CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, c VARCHAR(64)) ENGINE=$engine_type; INSERT INTO t1 VALUES (1,1,'1'); ---disable_warnings +--disable_warnings ONCE INSERT INTO t1 VALUES (2,2,UUID()); ---enable_warnings eval CREATE TABLE t2 (a INT UNIQUE, b INT, c VARCHAR(64)) ENGINE=$engine_type; INSERT INTO t2 VALUES (1,1,'1'); ---disable_warnings +--disable_warnings ONCE INSERT INTO t2 VALUES (2,2,UUID()); ---enable_warnings eval CREATE TABLE t11 (a INT NOT NULL PRIMARY KEY, b INT, c VARCHAR(64)) ENGINE=$engine_type2; INSERT INTO t11 VALUES (1,1,'1'); ---disable_warnings +--disable_warnings ONCE INSERT INTO t11 VALUES (2,2,UUID()); ---enable_warnings eval CREATE TABLE t12 (a INT UNIQUE, b INT, c VARCHAR(64)) ENGINE=$engine_type2; INSERT INTO t12 VALUES (1,1,'1'); ---disable_warnings +--disable_warnings ONCE INSERT INTO t12 VALUES (2,2,UUID()); ---enable_warnings -# Create invoked features ---echo -# Create view for tables t1,t11 +--echo # Create invoked features + CREATE VIEW v1 AS SELECT * FROM t1; CREATE VIEW v11 AS SELECT * FROM t11; -# Create triggers for t1,t11 DELIMITER |; CREATE TRIGGER t1_tr1 BEFORE INSERT ON t1 FOR EACH ROW @@ -102,11 +76,7 @@ BEGIN UPDATE t13 SET c = ''; END| -# 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 +CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DISABLE DO BEGIN ALTER EVENT e1 DISABLE; CALL p1(10, ''); @@ -118,7 +88,6 @@ BEGIN CALL p11(10, ''); END| -# Create functions and procedures used for events CREATE FUNCTION f1 (x INT) RETURNS VARCHAR(64) BEGIN IF x > 5 THEN @@ -149,46 +118,39 @@ DELIMITER ;| # Start test case # -# Do some actions for non-transactional tables ---echo +--echo # Do some actions for non-transactional tables CREATE TABLE t3 SELECT * FROM v1; INSERT INTO t1 VALUES (3,3,''); UPDATE t1 SET c='2' WHERE a = 1; ---disable_warnings +--disable_warnings ONCE INSERT INTO t1 VALUES(4,4,f1(4)); ---enable_warnings INSERT INTO t1 VALUES (100,100,''); ---disable_warnings CALL p1(5, UUID()); ---enable_warnings INSERT INTO t1 VALUES (101,101,''); ---disable_warnings +--disable_warnings ONCE INSERT INTO t1 VALUES(6,6,f1(6)); ---enable_warnings INSERT INTO t1 VALUES (102,102,''); ---disable_warnings +--disable_warnings ONCE INSERT INTO t1 VALUES(7,7,f2(7)); ---enable_warnings INSERT INTO t1 VALUES (103,103,''); -# Do some actions for transactional tables ---echo ---disable_warnings +--echo # Do some actions for transactional tables CREATE TABLE t13 SELECT * FROM v11; INSERT INTO t11 VALUES (3,3,''); UPDATE t11 SET c='2' WHERE a = 1; +--disable_warnings ONCE INSERT INTO t11 VALUES(4,4,f1(4)); INSERT INTO t11 VALUES (100,100,''); CALL p11(5, UUID()); INSERT INTO t11 VALUES (101,101,''); +--disable_warnings ONCE INSERT INTO t11 VALUES(6,6,f1(6)); INSERT INTO t11 VALUES (102,102,''); +--disable_warnings ONCE INSERT INTO t11 VALUES(7,7,f2(7)); INSERT INTO t11 VALUES (103,103,''); ---enable_warnings -# Scheduler is on ---echo +--echo # Scheduler is on # Temporally events fire sequentally due Bug#29020. SET GLOBAL EVENT_SCHEDULER = on; # Wait while events will executed @@ -200,8 +162,7 @@ let $wait_condition= SELECT COUNT(*) = 1 FROM t11 WHERE t11.a = 10; --source include/wait_condition.inc SET GLOBAL EVENT_SCHEDULER = off; -# Check original objects ---echo +--echo # Check original objects --sorted_result SHOW TABLES LIKE 't%'; --sorted_result @@ -232,8 +193,7 @@ SELECT a,b FROM v11 ORDER BY a; --sync_slave_with_master slave -# Check replicated objects ---echo +--echo # Check replicated objects --sorted_result SHOW TABLES LIKE 't%'; --sorted_result @@ -245,8 +205,7 @@ SELECT routine_type, routine_name FROM information_schema.routines WHERE routine --sorted_result SELECT event_name, status FROM information_schema.events WHERE event_schema='test'; -# Check replicated data ---echo +--echo # Check replicated data SELECT COUNT(*) FROM t1; SELECT a,b FROM t1 ORDER BY a; SELECT COUNT(*) FROM t2; @@ -262,10 +221,8 @@ SELECT COUNT(*) FROM t13; SELECT a,b FROM t13 ORDER BY a; SELECT a,b FROM v11 ORDER BY a; -# Remove UUID() before comparing and sort tables - --connection master ---echo +--echo # Remove UUID() before comparing and sort tables UPDATE t1 SET c=''; UPDATE t2 SET c=''; UPDATE t3 SET c=''; @@ -280,25 +237,19 @@ ALTER TABLE t13 ORDER BY a; --sync_slave_with_master slave -# Compare a data from master and slave ---echo +--echo # Compare a data from master and slave --exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_master.sql --exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_slave.sql --diff_files $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_master.sql $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_slave.sql - # # Clean up # -# Remove dumps ---echo --remove_file $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_master.sql --remove_file $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_slave.sql -# Remove tables,views,procedures,functions --connection master ---echo DROP VIEW IF EXISTS v1,v11; DROP TABLE IF EXISTS t1,t2,t3,t11,t12,t13; DROP PROCEDURE IF EXISTS p1; 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 d49851cc8ce..2ad9124d886 100644 --- a/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test +++ b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test @@ -26,6 +26,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 8d91944a8eb..e9a41c95ff0 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 --source include/reset_slave.inc 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 --source include/reset_slave.inc 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_parallel_sbm.test b/mysql-test/suite/rpl/t/rpl_parallel_sbm.test index e738f55e7ec..58c0db15e47 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_sbm.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_sbm.test @@ -36,10 +36,6 @@ create table t2 (a int); --echo # --echo # Pt 1) Ensure SBM is updated immediately upon arrival of the next event ---echo # Lock t1 on slave so the first received transaction does not complete/commit ---connection slave -LOCK TABLES t1 WRITE; - --connection master --echo # Sleep 2 to allow a buffer between events for SBM check sleep 2; @@ -65,8 +61,31 @@ if (`SELECT $sbm_trx1_arrive > ($seconds_since_idling + 1)`) } --echo # ..done + +--echo # MDEV-32265. At time of STOP SLAVE, if the SQL Thread is currently +--echo # delaying a transaction; then when the reciprocal START SLAVE occurs, +--echo # if the event is still to be delayed, SBM should resume accordingly + +--source include/stop_slave.inc +--source include/start_slave.inc + --connection slave -UNLOCK TABLES; +--echo # Waiting for replica to resume the delay for the transaction +--let $wait_condition= SELECT count(*) FROM information_schema.processlist WHERE state LIKE 'Waiting until MASTER_DELAY seconds after master executed event'; +--source include/wait_condition.inc + +--echo # Sleeping 1s to increment SBM +sleep 1; + +--echo # Ensuring Seconds_Behind_Master increases after sleeping.. +--let $sbm_trx1_after_1s_sleep= query_get_value(SHOW SLAVE STATUS, Seconds_Behind_Master, 1) +if (`SELECT $sbm_trx1_after_1s_sleep <= $sbm_trx1_arrive`) +{ + --echo # ..failed + --die Seconds_Behind_Master did not increase after sleeping, but should have +} +--echo # ..done + --source include/sync_with_master_gtid.inc --echo # diff --git a/mysql-test/suite/rpl/t/rpl_parallel_seq.test b/mysql-test/suite/rpl/t/rpl_parallel_seq.test index 55113798d85..b1b15412b16 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_seq.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_seq.test @@ -128,8 +128,51 @@ SET DEBUG_SYNC = 'now SIGNAL continue_worker'; SELECT @@global.gtid_binlog_state, @@global.gtid_slave_pos as "all through 101 have been committed"; +# MDEV-31792 Assertion in MDL_context::acquire_lock upon parallel replication of CREATE SEQUENCE + +--let $iter = 3 +while ($iter) +{ +--connection slave +if (`select $iter > 1`) +{ + flush tables with read lock; +} +if (`select $iter = 1`) +{ + BEGIN /* slave local Trx */; + select count(*) from s3; +} + +--connection master +CREATE OR REPLACE SEQUENCE s3 ENGINE=innodb; +# select may return non-deterministically, don't print its result +SELECT NEXT VALUE FOR s3 into @tmpvar; +--source include/save_master_gtid.inc + +--connection slave +--let $wait_condition= SELECT count(*) = 1 FROM information_schema.processlist WHERE state LIKE "Waiting for prior transaction to start commit%" +--source include/wait_condition.inc + +if (`select $iter > 1`) +{ + unlock tables; +} +if (`select $iter = 1`) +{ +--connection slave +rollback /* Trx */; +} + + +--source include/sync_with_master_gtid.inc + +--dec $iter +} + + # -# MDEV-29621/MDEV-31077 clean up. +# MDEV-29621/MDEV-31077/MDEV-31792 clean up. # --connection slave --source include/stop_slave.inc @@ -142,7 +185,12 @@ SET debug_sync = RESET; --source include/start_slave.inc --connection master -DROP SEQUENCE s2; +# MDEV-32593 Assertion failure upon CREATE SEQUENCE +BEGIN; +INSERT INTO ti SET a=32593; +CREATE SEQUENCE s4; + +DROP SEQUENCE s2,s3,s4; DROP TABLE ti; --sync_slave_with_master 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 44df3ca4ea7..794a0c631d7 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_rewrite_db_sys_vars.test b/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test index b06899bb12e..27710063792 100644 --- a/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test +++ b/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test @@ -108,6 +108,7 @@ select * from my_table; --source include/save_master_gtid.inc connection slave; +--let $rpl_only_running_threads=1 --source include/stop_slave.inc --source include/reset_slave.inc --source include/start_slave.inc 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 d318e0d7d26..aa43831b2b6 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 --source include/reset_slave.inc --source include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_utf32.test b/mysql-test/suite/rpl/t/rpl_row_utf32.test index c82cd4e5c2f..546cf07adfd 100644 --- a/mysql-test/suite/rpl/t/rpl_row_utf32.test +++ b/mysql-test/suite/rpl/t/rpl_row_utf32.test @@ -34,10 +34,78 @@ DROP TABLE t1; --sync_slave_with_master +--echo # +--echo # MDEV-32249 strings/ctype-ucs2.c:2336: my_vsnprintf_utf32: Assertion `(n +--echo # + +--echo # +--echo # Testing with VARCHAR +--echo # + +-- connection slave +-- source include/stop_slave.inc +SET GLOBAL SLAVE_TYPE_CONVERSIONS= ''; +-- source include/start_slave.inc + +--connection master +CREATE TABLE t1 (a INT); + +--sync_slave_with_master +ALTER TABLE t1 MODIFY a VARCHAR(1) CHARACTER SET utf32; + +--connection master +INSERT INTO t1 VALUES (1); + +--connection slave +# ER_SLAVE_CONVERSION_FAILED +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc +SHOW CREATE TABLE t1; +SELECT * FROM t1 ORDER BY a; +SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; +START SLAVE; + +--connection master +DROP TABLE t1; +--sync_slave_with_master + +--echo # +--echo # Testing with CHAR +--echo # + +-- connection slave +-- source include/stop_slave.inc +SET GLOBAL SLAVE_TYPE_CONVERSIONS= ''; +-- source include/start_slave.inc + +--connection master +CREATE TABLE t1 (a INT); + +--sync_slave_with_master +ALTER TABLE t1 MODIFY a CHAR(1) CHARACTER SET utf32; + +--connection master +INSERT INTO t1 VALUES (1); + +--connection slave +# ER_SLAVE_CONVERSION_FAILED +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc +SHOW CREATE TABLE t1; +SELECT * FROM t1 ORDER BY a; +SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; +START SLAVE; + +--connection master +DROP TABLE t1; +--sync_slave_with_master + + # assertion: the slave woul hit an/several assertions: # before and during slave conversion procedure # Now that is fixed, it wont. +-- connection slave SET GLOBAL SLAVE_TYPE_CONVERSIONS= @saved_slave_type_conversions; -- source include/stop_slave.inc -- 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_shutdown_await_ack.test b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.test index 2ee7d0aa052..6c088c571f2 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.test @@ -67,6 +67,7 @@ --echo # Slaves which simulate an error will produce a timeout on the primary call mtr.add_suppression("Timeout waiting"); call mtr.add_suppression("did not exit"); +call mtr.add_suppression("Got an error reading communication packets"); --let $sav_master_timeout= `SELECT @@global.rpl_semi_sync_master_timeout` --let $sav_enabled_master= `SELECT @@GLOBAL.rpl_semi_sync_master_enabled` 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 384a357c96f..a467a38ddb0 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 @@ -77,6 +77,16 @@ insert into t1 values (10); --source include/diff_tables.inc --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_dbug; +SET GLOBAL debug_dbug="+d,semisync_corrupt_magic"; +insert into t1 values (11); + +--sync_slave_with_master + +--connection master +SET GLOBAL debug_dbug= @save_debug_master; + drop table t1; --sync_slave_with_master set global rpl_semi_sync_slave_enabled = OFF; 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_start_alter_1.test b/mysql-test/suite/rpl/t/rpl_start_alter_1.test index 9ce061f1031..b16f6a53393 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_1.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_1.test @@ -6,6 +6,7 @@ --source include/master-slave.inc --connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --let $binlog_alter_two_phase= `select @@binlog_alter_two_phase` set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; diff --git a/mysql-test/suite/rpl/t/rpl_start_alter_2.test b/mysql-test/suite/rpl/t/rpl_start_alter_2.test index 457409c51a6..a5cef2e51e5 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_2.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_2.test @@ -8,9 +8,11 @@ --source include/have_debug.inc --source include/master-slave.inc --connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --let $binlog_alter_two_phase= `select @@binlog_alter_two_phase` set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; + --connection slave --let $gtid_strict_mode= `select @@gtid_strict_mode` --let $slave_parallel_threads= `select @@slave_parallel_threads` diff --git a/mysql-test/suite/rpl/t/rpl_start_alter_3.test b/mysql-test/suite/rpl/t/rpl_start_alter_3.test index b280aeb9e5e..8207dcbbc25 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_3.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_3.test @@ -9,9 +9,11 @@ --source include/master-slave.inc --source include/have_debug.inc --connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --let $binlog_alter_two_phase= `select @@binlog_alter_two_phase` set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; + --connection slave --let $gtid_strict_mode= `select @@gtid_strict_mode` --let $slave_parallel_threads= `select @@slave_parallel_threads` diff --git a/mysql-test/suite/rpl/t/rpl_start_alter_4.test b/mysql-test/suite/rpl/t/rpl_start_alter_4.test index 8c67b50a7bf..f4edc4b928c 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_4.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_4.test @@ -9,6 +9,7 @@ --source include/master-slave.inc --source include/have_debug.inc --connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --let $binlog_alter_two_phase= `select @@binlog_alter_two_phase` set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; diff --git a/mysql-test/suite/rpl/t/rpl_start_alter_5.test b/mysql-test/suite/rpl/t/rpl_start_alter_5.test index 10d0d523a68..b2d31f21039 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_5.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_5.test @@ -9,6 +9,7 @@ --source include/master-slave.inc --source include/have_debug.inc --connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --let $binlog_alter_two_phase= `select @@binlog_alter_two_phase` set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; diff --git a/mysql-test/suite/rpl/t/rpl_start_alter_6.test b/mysql-test/suite/rpl/t/rpl_start_alter_6.test index fc49ea4a406..6c2b50156d0 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_6.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_6.test @@ -10,6 +10,7 @@ --source include/master-slave.inc --source include/have_debug.inc --connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --let $binlog_alter_two_phase= `select @@binlog_alter_two_phase` set global binlog_alter_two_phase = ON; set binlog_alter_two_phase = ON; diff --git a/mysql-test/suite/rpl/t/rpl_start_alter_7.test b/mysql-test/suite/rpl/t/rpl_start_alter_7.test index 7225c075ea7..21c21c85c59 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_7.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_7.test @@ -21,6 +21,10 @@ stop slave; set global binlog_alter_two_phase=true; --connection server_3 +SET STATEMENT sql_log_bin=0 FOR + CALL mtr.add_suppression("The table mysql.gtid_slave_pos was removed. This change will not take full effect until all SQL threads have been restarted"); +SET STATEMENT sql_log_bin=0 FOR + ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --let $gtid_strict_mode= `select @@gtid_strict_mode` --let $slave_parallel_threads= `select @@slave_parallel_threads` --let $slave_parallel_mode= `select @@slave_parallel_mode` diff --git a/mysql-test/suite/rpl/t/rpl_start_alter_8.test b/mysql-test/suite/rpl/t/rpl_start_alter_8.test index 4ab8e2b01e5..c8c5ac74404 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_8.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_8.test @@ -21,6 +21,10 @@ stop slave; set global binlog_alter_two_phase=true; --connection server_3 +SET STATEMENT sql_log_bin=0 FOR + CALL mtr.add_suppression("The table mysql.gtid_slave_pos was removed. This change will not take full effect until all SQL threads have been restarted"); +SET STATEMENT sql_log_bin=0 FOR + ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --let $gtid_strict_mode= `select @@gtid_strict_mode` --let $slave_parallel_threads= `select @@slave_parallel_threads` --let $slave_parallel_mode= `select @@slave_parallel_mode` diff --git a/mysql-test/suite/rpl/t/rpl_start_alter_mysqlbinlog_1.test b/mysql-test/suite/rpl/t/rpl_start_alter_mysqlbinlog_1.test index f655d3c10ba..a2f6adcc554 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_mysqlbinlog_1.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_mysqlbinlog_1.test @@ -10,6 +10,8 @@ set global binlog_alter_two_phase=true; --connection slave --source include/stop_slave.inc +SET STATEMENT sql_log_bin=0 FOR + ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; set global gtid_strict_mode=1; --echo # Legacy Master Slave diff --git a/mysql-test/suite/rpl/t/rpl_start_alter_mysqlbinlog_2.test b/mysql-test/suite/rpl/t/rpl_start_alter_mysqlbinlog_2.test index c7d5bd66e2b..9d9675c6487 100644 --- a/mysql-test/suite/rpl/t/rpl_start_alter_mysqlbinlog_2.test +++ b/mysql-test/suite/rpl/t/rpl_start_alter_mysqlbinlog_2.test @@ -57,6 +57,10 @@ SET @save_binlog_alter_two_phase= @@GLOBAL.binlog_alter_two_phase; SET GLOBAL binlog_alter_two_phase = ON; --connection server_3 +SET STATEMENT sql_log_bin=0 FOR + CALL mtr.add_suppression("The table mysql.gtid_slave_pos was removed. This change will not take full effect until all SQL threads have been restarted"); +SET STATEMENT sql_log_bin=0 FOR + ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; SET @save_gtid_strict_mode= @@GLOBAL.gtid_strict_mode; SET @slave_parallel_threads= @@GLOBAL.slave_parallel_threads; SET @slave_parallel_mode= @@GLOBAL.slave_parallel_mode; 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 793d8bccc18..ce01e41f8dc 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 --let $master_use_gtid_option= No --source include/reset_slave.inc --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/s3/amazon.result b/mysql-test/suite/s3/amazon.result index 29075118a63..b24969ab921 100644 --- a/mysql-test/suite/s3/amazon.result +++ b/mysql-test/suite/s3/amazon.result @@ -4,4 +4,14 @@ create table t1 (pk int primary key, a int); insert into t1 values (1,1),(2,2),(3,3),(4,4); alter table t1 engine=S3; drop table t1; +set @@global.s3_protocol_version="Amazon"; +create table t1 (pk int primary key, a int); +insert into t1 values (1,1),(2,2),(3,3),(4,4); +alter table t1 engine=S3; +drop table t1; +set @@global.s3_protocol_version="Domain"; +create table t1 (pk int primary key, a int); +insert into t1 values (1,1),(2,2),(3,3),(4,4); +alter table t1 engine=S3; +drop table t1; set @@global.s3_protocol_version=@save_s3_protocol_version; diff --git a/mysql-test/suite/s3/amazon.test b/mysql-test/suite/s3/amazon.test index 3c64cc2841b..bc9439ab2cc 100644 --- a/mysql-test/suite/s3/amazon.test +++ b/mysql-test/suite/s3/amazon.test @@ -1,6 +1,6 @@ --source include/have_s3.inc -if (`SELECT @@s3_host_name <> "s3.amazonaws.com"`) +if (`SELECT @@s3_host_name NOT LIKE "%.amazonaws.com"`) { skip Not connected to AWS; } @@ -20,6 +20,22 @@ insert into t1 values (1,1),(2,2),(3,3),(4,4); alter table t1 engine=S3; drop table t1; +set @@global.s3_protocol_version="Amazon"; + +create table t1 (pk int primary key, a int); +insert into t1 values (1,1),(2,2),(3,3),(4,4); +--replace_result $database database +alter table t1 engine=S3; +drop table t1; + +set @@global.s3_protocol_version="Domain"; + +create table t1 (pk int primary key, a int); +insert into t1 values (1,1),(2,2),(3,3),(4,4); +--replace_result $database database +alter table t1 engine=S3; +drop table t1; + # # clean up # diff --git a/mysql-test/suite/s3/debug.result b/mysql-test/suite/s3/debug.result new file mode 100644 index 00000000000..2dffcff86ee --- /dev/null +++ b/mysql-test/suite/s3/debug.result @@ -0,0 +1,32 @@ +drop table if exists t1; +# +# MDEV-32884 Make s3_debug dynamic +# +create or replace table t1 (a int, b int, c varchar(1000), key (a), key(c)) engine=aria; +insert into t1 select seq, seq+10, repeat(char(65+ mod(seq, 20)),mod(seq,1000)) from seq_1_to_100; +alter table t1 engine=s3; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` varchar(1000) DEFAULT NULL, + KEY `a` (`a`), + KEY `c` (`c`) +) ENGINE=S3 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +select count(*) from t1; +count(*) +100 +flush table t1; +NOT FOUND /s3_test_/ in mysqld.1.err +set @@global.s3_debug=1; +select count(*) from t1; +count(*) +100 +set @@global.s3_debug=0; +FOUND 6 /s3_test_/ in mysqld.1.err +select count(*) from t1; +count(*) +100 +drop table t1; +FOUND 6 /s3_test_/ in mysqld.1.err diff --git a/mysql-test/suite/s3/debug.test b/mysql-test/suite/s3/debug.test new file mode 100644 index 00000000000..67787d729ee --- /dev/null +++ b/mysql-test/suite/s3/debug.test @@ -0,0 +1,34 @@ +--source include/have_s3.inc +--source include/have_sequence.inc + +# +# Create unique database for running the tests +# +--source create_database.inc +--disable_warnings +drop table if exists t1; +--enable_warnings + +--echo # +--echo # MDEV-32884 Make s3_debug dynamic +--echo # + +create or replace table t1 (a int, b int, c varchar(1000), key (a), key(c)) engine=aria; +insert into t1 select seq, seq+10, repeat(char(65+ mod(seq, 20)),mod(seq,1000)) from seq_1_to_100; +alter table t1 engine=s3; +show create table t1; +select count(*) from t1; +flush table t1; + +--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_PATTERN=s3_test_ +--source include/search_pattern_in_file.inc +set @@global.s3_debug=1; +select count(*) from t1; +set @@global.s3_debug=0; +--source include/search_pattern_in_file.inc +select count(*) from t1; +drop table t1; +--source include/search_pattern_in_file.inc + +--source drop_database.inc diff --git a/mysql-test/suite/sql_sequence/alter.result b/mysql-test/suite/sql_sequence/alter.result index 6d29876a8eb..ae95bfb9cc1 100644 --- a/mysql-test/suite/sql_sequence/alter.result +++ b/mysql-test/suite/sql_sequence/alter.result @@ -210,8 +210,12 @@ create table t1 (a int); alter sequence t1 minvalue=100; ERROR 42S02: 'test.t1' is not a SEQUENCE drop table t1; +# +# MDEV-32795: ALTER SEQUENCE IF NOT EXISTS non_existing_seq Errors rather than note +# alter sequence if exists t1 minvalue=100; -ERROR 42S02: Unknown SEQUENCE: 't1' +Warnings: +Note 4091 Unknown SEQUENCE: 'test.t1' alter sequence t1 minvalue=100; ERROR 42S02: Unknown SEQUENCE: 't1' create sequence t1; diff --git a/mysql-test/suite/sql_sequence/alter.test b/mysql-test/suite/sql_sequence/alter.test index dab0e665950..20ac6b2cb92 100644 --- a/mysql-test/suite/sql_sequence/alter.test +++ b/mysql-test/suite/sql_sequence/alter.test @@ -120,8 +120,12 @@ create table t1 (a int); alter sequence t1 minvalue=100; drop table t1; ---error ER_UNKNOWN_SEQUENCES +--echo # +--echo # MDEV-32795: ALTER SEQUENCE IF NOT EXISTS non_existing_seq Errors rather than note +--echo # + alter sequence if exists t1 minvalue=100; + --error ER_UNKNOWN_SEQUENCES alter sequence t1 minvalue=100; diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result index 9326d7016c9..9d601a9e551 100644 --- a/mysql-test/suite/sql_sequence/create.result +++ b/mysql-test/suite/sql_sequence/create.result @@ -715,4 +715,12 @@ CREATE SEQUENCE seq1 START WITH 2; CREATE TRIGGER s1 BEFORE UPDATE ON seq1 FOR EACH ROW SET @a= 5; ERROR HY000: Trigger's 'seq1' is a view, temporary table or sequence DROP SEQUENCE seq1; +# +# MDEV-29771: Server crashes in check_sequence_fields upon +# CREATE TABLE .. SEQUENCE=1 AS SELECT .. +# +create table s sequence=1 as select 1; +ERROR HY000: Sequence 'test.s' table structure is invalid (Wrong number of columns) +# # End of 10.4 test +# diff --git a/mysql-test/suite/sql_sequence/create.test b/mysql-test/suite/sql_sequence/create.test index f2ea1d69cc1..4cece26de8e 100644 --- a/mysql-test/suite/sql_sequence/create.test +++ b/mysql-test/suite/sql_sequence/create.test @@ -554,4 +554,14 @@ CREATE SEQUENCE seq1 START WITH 2; CREATE TRIGGER s1 BEFORE UPDATE ON seq1 FOR EACH ROW SET @a= 5; DROP SEQUENCE seq1; +--echo # +--echo # MDEV-29771: Server crashes in check_sequence_fields upon +--echo # CREATE TABLE .. SEQUENCE=1 AS SELECT .. +--echo # + +--error ER_SEQUENCE_INVALID_TABLE_STRUCTURE +create table s sequence=1 as select 1; + +--echo # --echo # End of 10.4 test +--echo # diff --git a/mysql-test/suite/sql_sequence/other.result b/mysql-test/suite/sql_sequence/other.result index d237be635f7..b950a7d8b13 100644 --- a/mysql-test/suite/sql_sequence/other.result +++ b/mysql-test/suite/sql_sequence/other.result @@ -358,4 +358,34 @@ Note 4092 Unknown VIEW: 'test.s' DROP VIEW v1; DROP SEQUENCE s; DROP TABLE t; +# # End of 10.3 tests +# +# +# MDEV-32541 Assertion `!(thd->server_status & (1U | 8192U))' failed in MDL_context::release_transactional_locks +# +create sequence s1; +create sequence s2; +connect con1,localhost,root,,; +set session transaction read only; +start transaction; +connection default; +start transaction; +insert into s2 values (1, 1, 10000, 100, 1, 1000, 0, 0); +connection con1; +select lastval(s1); +lastval(s1) +NULL +select lastval(s2);; +connection default; +set lock_wait_timeout= 1; +insert into s1 values (1, 1, 10000, 100, 1, 1000, 0, 0); +connection con1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +disconnect con1; +connection default; +drop sequence s1; +drop sequence s2; +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/sql_sequence/other.test b/mysql-test/suite/sql_sequence/other.test index eaf54de455a..9761e4268a8 100644 --- a/mysql-test/suite/sql_sequence/other.test +++ b/mysql-test/suite/sql_sequence/other.test @@ -385,4 +385,39 @@ DROP VIEW IF EXISTS s; DROP VIEW v1; DROP SEQUENCE s; DROP TABLE t; +--echo # --echo # End of 10.3 tests +--echo # + +--echo # +--echo # MDEV-32541 Assertion `!(thd->server_status & (1U | 8192U))' failed in MDL_context::release_transactional_locks +--echo # +create sequence s1; +create sequence s2; +--connect (con1,localhost,root,,) +set session transaction read only; +start transaction; + +--connection default +start transaction; +insert into s2 values (1, 1, 10000, 100, 1, 1000, 0, 0); + +--connection con1 +select lastval(s1); +--send select lastval(s2); + +--connection default +set lock_wait_timeout= 1; +insert into s1 values (1, 1, 10000, 100, 1, 1000, 0, 0); + +--connection con1 +--error ER_LOCK_DEADLOCK +--reap +--disconnect con1 +--connection default +drop sequence s1; +drop sequence s2; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/suite/sys_vars/r/innodb_purge_batch_size_basic.result b/mysql-test/suite/sys_vars/r/innodb_purge_batch_size_basic.result index 6279cd143cf..442d44e7fb2 100644 --- a/mysql-test/suite/sys_vars/r/innodb_purge_batch_size_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_purge_batch_size_basic.result @@ -1,19 +1,19 @@ SET @global_start_value = @@global.innodb_purge_batch_size; SELECT @global_start_value; @global_start_value -300 +1000 '#--------------------FN_DYNVARS_046_01------------------------#' SET @@global.innodb_purge_batch_size = 1; SET @@global.innodb_purge_batch_size = DEFAULT; SELECT @@global.innodb_purge_batch_size; @@global.innodb_purge_batch_size -300 +1000 '#---------------------FN_DYNVARS_046_02-------------------------#' SET innodb_purge_batch_size = 1; ERROR HY000: Variable 'innodb_purge_batch_size' is a GLOBAL variable and should be set with SET GLOBAL SELECT @@innodb_purge_batch_size; @@innodb_purge_batch_size -300 +1000 SELECT local.innodb_purge_batch_size; ERROR 42S02: Unknown table 'local' in field list SET global innodb_purge_batch_size = 1; @@ -112,4 +112,4 @@ SELECT @@global.innodb_purge_batch_size; SET @@global.innodb_purge_batch_size = @global_start_value; SELECT @@global.innodb_purge_batch_size; @@global.innodb_purge_batch_size -300 +1000 diff --git a/mysql-test/suite/sys_vars/r/innodb_purge_rseg_truncate_frequency_basic.result b/mysql-test/suite/sys_vars/r/innodb_purge_rseg_truncate_frequency_basic.result index 65387032dc6..8b5ae0fae3e 100644 --- a/mysql-test/suite/sys_vars/r/innodb_purge_rseg_truncate_frequency_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_purge_rseg_truncate_frequency_basic.result @@ -4,7 +4,11 @@ SELECT @global_start_value; 128 '#--------------------FN_DYNVARS_046_01------------------------#' SET @@global.innodb_purge_rseg_truncate_frequency = 1; +Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release SET @@global.innodb_purge_rseg_truncate_frequency = DEFAULT; +Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency 128 @@ -17,31 +21,41 @@ SELECT @@innodb_purge_rseg_truncate_frequency; SELECT local.innodb_purge_rseg_truncate_frequency; ERROR 42S02: Unknown table 'local' in field list SET global innodb_purge_rseg_truncate_frequency = 1; +Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency 1 '#--------------------FN_DYNVARS_046_03------------------------#' SET @@global.innodb_purge_rseg_truncate_frequency = 1; +Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency 1 SET @@global.innodb_purge_rseg_truncate_frequency = 1; +Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency 1 SET @@global.innodb_purge_rseg_truncate_frequency = 128; +Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency 128 '#--------------------FN_DYNVARS_046_05-------------------------#' SET @@global.innodb_purge_rseg_truncate_frequency = -1; Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release Warning 1292 Truncated incorrect innodb_purge_rseg_truncate_fr... value: '-1' SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency 1 SET @@global.innodb_purge_rseg_truncate_frequency = -1024; Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release Warning 1292 Truncated incorrect innodb_purge_rseg_truncate_fr... value: '-1024' SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency @@ -98,16 +112,21 @@ SELECT @@global.innodb_purge_rseg_truncate_frequency; 1 '#---------------------FN_DYNVARS_046_08----------------------#' SET @@global.innodb_purge_rseg_truncate_frequency = TRUE; +Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency 1 SET @@global.innodb_purge_rseg_truncate_frequency = FALSE; Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release Warning 1292 Truncated incorrect innodb_purge_rseg_truncate_fr... value: '0' SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency 1 SET @@global.innodb_purge_rseg_truncate_frequency = @global_start_value; +Warnings: +Warning 1287 '@@innodb_purge_rseg_truncate_frequency' is deprecated and will be removed in a future release SELECT @@global.innodb_purge_rseg_truncate_frequency; @@global.innodb_purge_rseg_truncate_frequency 128 diff --git a/mysql-test/suite/sys_vars/r/old_mode_basic.result b/mysql-test/suite/sys_vars/r/old_mode_basic.result index 7701bc6bbfa..3032a82581b 100644 --- a/mysql-test/suite/sys_vars/r/old_mode_basic.result +++ b/mysql-test/suite/sys_vars/r/old_mode_basic.result @@ -132,8 +132,8 @@ Warning 1287 'ZERO_DATE_TIME_CAST' is deprecated and will be removed in a future SELECT @@global.old_mode; @@global.old_mode ZERO_DATE_TIME_CAST -SET @@global.old_mode = 128; -ERROR 42000: Variable 'old_mode' can't be set to the value of '128' +SET @@global.old_mode = 256; +ERROR 42000: Variable 'old_mode' can't be set to the value of '256' SELECT @@global.old_mode; @@global.old_mode ZERO_DATE_TIME_CAST diff --git a/mysql-test/suite/sys_vars/r/old_passwords_func.result b/mysql-test/suite/sys_vars/r/old_passwords_func.result index 6bd060932a8..fb250eeb669 100644 --- a/mysql-test/suite/sys_vars/r/old_passwords_func.result +++ b/mysql-test/suite/sys_vars/r/old_passwords_func.result @@ -9,6 +9,8 @@ SET GLOBAL old_passwords = TRUE; SET SESSION old_passwords = TRUE; CREATE USER 'userOldPass'@'localhost' IDENTIFIED BY 'pass3'; SET GLOBAL secure_auth = FALSE; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release connect con1,localhost,userNewPass1,pass1,; SELECT CURRENT_USER(); CURRENT_USER() @@ -30,6 +32,8 @@ disconnect con2; disconnect con3; '#------------------------FN_DYNVARS_115_02---------------------------#' SET GLOBAL secure_auth = TRUE; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release connect con1,localhost,userNewPass1,pass1,; SELECT CURRENT_USER(); CURRENT_USER() @@ -55,3 +59,5 @@ DROP USER 'userOldPass'@'localhost'; SET @@GLOBAL.old_passwords = @global_old_passwords; SET @@SESSION.old_passwords = @session_old_passwords; SET @@GLOBAL.secure_auth = @global_secure_auth; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result index 54a9b6dde7b..c0755278a28 100644 --- a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result +++ b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result @@ -1,58 +1,58 @@ set @@global.optimizer_switch=@@optimizer_switch; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,sargable_casefold=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=off,sargable_casefold=on select @@session.optimizer_switch; @@session.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,sargable_casefold=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=off,sargable_casefold=on show global variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,sargable_casefold=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=off,sargable_casefold=on show session variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,sargable_casefold=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=off,sargable_casefold=on select * from information_schema.global_variables where variable_name='optimizer_switch'; VARIABLE_NAME VARIABLE_VALUE -OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,sargable_casefold=on +OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=off,sargable_casefold=on select * from information_schema.session_variables where variable_name='optimizer_switch'; VARIABLE_NAME VARIABLE_VALUE -OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,sargable_casefold=on +OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=off,sargable_casefold=on set global optimizer_switch=2053; set session optimizer_switch=1034; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,sargable_casefold=off +index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off,sargable_casefold=off select @@session.optimizer_switch; @@session.optimizer_switch -index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,sargable_casefold=off +index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off,sargable_casefold=off set global optimizer_switch="index_merge_sort_union=on"; set session optimizer_switch="index_merge=off"; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,sargable_casefold=off +index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off,sargable_casefold=off select @@session.optimizer_switch; @@session.optimizer_switch -index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,sargable_casefold=off +index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off,sargable_casefold=off show global variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,sargable_casefold=off +optimizer_switch index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off,sargable_casefold=off show session variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,sargable_casefold=off +optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off,sargable_casefold=off select * from information_schema.global_variables where variable_name='optimizer_switch'; VARIABLE_NAME VARIABLE_VALUE -OPTIMIZER_SWITCH index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,sargable_casefold=off +OPTIMIZER_SWITCH index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off,sargable_casefold=off select * from information_schema.session_variables where variable_name='optimizer_switch'; VARIABLE_NAME VARIABLE_VALUE -OPTIMIZER_SWITCH index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,sargable_casefold=off +OPTIMIZER_SWITCH index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off,sargable_casefold=off set session optimizer_switch="default"; select @@session.optimizer_switch; @@session.optimizer_switch -index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,sargable_casefold=off +index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off,sargable_casefold=off set optimizer_switch = replace(@@optimizer_switch, '=off', '=on'); select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=on,hash_join_cardinality=on,sargable_casefold=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=on,hash_join_cardinality=on,cset_narrowing=on,sargable_casefold=on set global optimizer_switch=1.1; ERROR 42000: Incorrect argument type to variable 'optimizer_switch' set global optimizer_switch=1e1; 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/secure_auth_basic.result b/mysql-test/suite/sys_vars/r/secure_auth_basic.result index 35f283de278..66763fc5f8d 100644 --- a/mysql-test/suite/sys_vars/r/secure_auth_basic.result +++ b/mysql-test/suite/sys_vars/r/secure_auth_basic.result @@ -4,7 +4,11 @@ SELECT @global_start_value; 1 '#--------------------FN_DYNVARS_143_01------------------------#' SET @@global.secure_auth = 1; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SET @@global.secure_auth = DEFAULT; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SELECT @@global.secure_auth; @@global.secure_auth 1 @@ -17,15 +21,21 @@ SELECT @@secure_auth; SELECT global.secure_auth; ERROR 42S02: Unknown table 'global' in field list SET global secure_auth = 1; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SELECT @@global.secure_auth; @@global.secure_auth 1 '#--------------------FN_DYNVARS_143_03------------------------#' SET @@global.secure_auth = 0; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SELECT @@global.secure_auth; @@global.secure_auth 0 SET @@global.secure_auth = 1; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SELECT @@global.secure_auth; @@global.secure_auth 1 @@ -83,23 +93,33 @@ VARIABLE_VALUE ON '#---------------------FN_DYNVARS_143_08-------------------------#' SET @@global.secure_auth = OFF; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SELECT @@global.secure_auth; @@global.secure_auth 0 SET @@global.secure_auth = ON; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SELECT @@global.secure_auth; @@global.secure_auth 1 '#---------------------FN_DYNVARS_143_09----------------------#' SET @@global.secure_auth = TRUE; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SELECT @@global.secure_auth; @@global.secure_auth 1 SET @@global.secure_auth = FALSE; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SELECT @@global.secure_auth; @@global.secure_auth 0 SET @@global.secure_auth = @global_start_value; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SELECT @@global.secure_auth; @@global.secure_auth 1 diff --git a/mysql-test/suite/sys_vars/r/secure_auth_func.result b/mysql-test/suite/sys_vars/r/secure_auth_func.result index 97d22facd9d..ee0d6146225 100644 --- a/mysql-test/suite/sys_vars/r/secure_auth_func.result +++ b/mysql-test/suite/sys_vars/r/secure_auth_func.result @@ -8,6 +8,8 @@ SELECT @@GLOBAL.secure_auth; 1 / ON Expected '#--------------------FN_DYNVARS_144_02-------------------------#' SET GLOBAL secure_auth = OFF; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release CREATE USER 'testUser'@'localhost' IDENTIFIED BY 'newpass'; connect con_user1,localhost,testUser,newpass,; connection default; @@ -16,6 +18,8 @@ connect con_user2,localhost,testUser,newpass,; connection default; '#--------------------FN_DYNVARS_144_03-------------------------#' SET GLOBAL secure_auth = ON; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SET PASSWORD FOR 'testUser'@'localhost' = PASSWORD('newpass'); connect con_user3,localhost,testUser,newpass,; connection default; @@ -27,6 +31,8 @@ SET PASSWORD FOR 'testUser'@'localhost' = PASSWORD('newpass'); connect con_user4,localhost,testUser,newpass,; connection default; SET GLOBAL secure_auth = @old_secure_auth; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release disconnect con_user1; disconnect con_user2; disconnect con_user3; diff --git a/mysql-test/suite/sys_vars/r/secure_auth_grant.result b/mysql-test/suite/sys_vars/r/secure_auth_grant.result index 69e001ad77d..18174d77a19 100644 --- a/mysql-test/suite/sys_vars/r/secure_auth_grant.result +++ b/mysql-test/suite/sys_vars/r/secure_auth_grant.result @@ -23,6 +23,8 @@ GRANT CONNECTION ADMIN ON *.* TO user1@localhost; connect user1,localhost,user1,,; connection user1; SET GLOBAL secure_auth=1; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release SET secure_auth=1; ERROR HY000: Variable 'secure_auth' is a GLOBAL variable and should be set with SET GLOBAL SET SESSION secure_auth=1; @@ -31,3 +33,5 @@ disconnect user1; connection default; DROP USER user1@localhost; SET @@global.secure_auth=@global; +Warnings: +Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release diff --git a/mysql-test/suite/sys_vars/r/sysvars_debug.result b/mysql-test/suite/sys_vars/r/sysvars_debug.result index a705b1faef6..37f03aee1e3 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_debug.result +++ b/mysql-test/suite/sys_vars/r/sysvars_debug.result @@ -1,6 +1,21 @@ select * from information_schema.system_variables where variable_name like 'debug%' order by variable_name; +VARIABLE_NAME DEBUG +SESSION_VALUE +GLOBAL_VALUE +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE +VARIABLE_SCOPE SESSION +VARIABLE_TYPE VARCHAR +VARIABLE_COMMENT Built-in DBUG debugger +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT OPTIONAL +GLOBAL_VALUE_PATH NULL VARIABLE_NAME DEBUG_BINLOG_FSYNC_SLEEP SESSION_VALUE NULL GLOBAL_VALUE 314 @@ -23,7 +38,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE VARIABLE_SCOPE SESSION VARIABLE_TYPE VARCHAR -VARIABLE_COMMENT Built-in DBUG debugger +VARIABLE_COMMENT Built-in DBUG debugger. Alias for --debug NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff index 3c6f2c3b8d9..9ae5049be2d 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff @@ -298,7 +298,7 @@ NUMERIC_MAX_VALUE 65536 @@ -1285,7 +1285,7 @@ SESSION_VALUE NULL - DEFAULT_VALUE 300 + DEFAULT_VALUE 1000 VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED @@ -311,7 +311,7 @@ VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT Dictates rate at which UNDO records are purged. Value N means purge rollback segment(s) on every Nth iteration of purge invocation + VARIABLE_COMMENT Deprecated parameter with no effect NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 128 @@ -1333,7 +1333,7 @@ diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index b5f88162daf..8f4201e9f80 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -1197,7 +1197,7 @@ READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_PURGE_BATCH_SIZE SESSION_VALUE NULL -DEFAULT_VALUE 300 +DEFAULT_VALUE 1000 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Number of UNDO log pages to purge in one batch from the history list. @@ -1212,7 +1212,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 128 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED -VARIABLE_COMMENT Dictates rate at which UNDO records are purged. Value N means purge rollback segment(s) on every Nth iteration of purge invocation +VARIABLE_COMMENT Deprecated parameter with no effect NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 128 NUMERIC_BLOCK_SIZE 0 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 88eeac3491d..c88967c1db3 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,4 +1,6 @@ -@@ -44,7 +44,7 @@ +--- sysvars_server_embedded.result ++++ sysvars_server_embedded.result +@@ -34,7 +34,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE VARIABLE_SCOPE GLOBAL @@ -429,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 @@ -1834,7 +1834,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 f2fd688be13..866e567f65f 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -1785,7 +1785,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 @@ -2279,7 +2279,7 @@ VARIABLE_COMMENT Used to emulate old behavior from earlier MariaDB or MySQL vers NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO,ZERO_DATE_TIME_CAST,UTF8_IS_UTF8MB3,IGNORE_INDEX_ONLY_FOR_JOIN,COMPAT_5_1_CHECKSUM,LOCK_ALTER_TABLE_COPY +ENUM_VALUE_LIST NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO,ZERO_DATE_TIME_CAST,UTF8_IS_UTF8MB3,IGNORE_INDEX_ONLY_FOR_JOIN,COMPAT_5_1_CHECKSUM,NO_NULL_COLLATION_IDS,LOCK_ALTER_TABLE_COPY READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OLD_PASSWORDS @@ -2499,7 +2499,7 @@ VARIABLE_COMMENT Fine-tune the optimizer behavior NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,rowid_filter,condition_pushdown_from_having,not_null_range_scan,hash_join_cardinality,sargable_casefold,default +ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,rowid_filter,condition_pushdown_from_having,not_null_range_scan,hash_join_cardinality,cset_narrowing,sargable_casefold,default READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_TRACE 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 6f7978ef2cc..07dd2a3b1d0 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,4 +1,6 @@ -@@ -44,7 +44,7 @@ +--- sysvars_server_notembedded.result ++++ sysvars_server_notembedded.result +@@ -34,7 +34,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE VARIABLE_SCOPE GLOBAL @@ -438,7 +440,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 @@ -2024,7 +2024,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 3a4b2b0f18e..f668d078723 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -1975,7 +1975,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 @@ -2489,7 +2489,7 @@ VARIABLE_COMMENT Used to emulate old behavior from earlier MariaDB or MySQL vers NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO,ZERO_DATE_TIME_CAST,UTF8_IS_UTF8MB3,IGNORE_INDEX_ONLY_FOR_JOIN,COMPAT_5_1_CHECKSUM,LOCK_ALTER_TABLE_COPY +ENUM_VALUE_LIST NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO,ZERO_DATE_TIME_CAST,UTF8_IS_UTF8MB3,IGNORE_INDEX_ONLY_FOR_JOIN,COMPAT_5_1_CHECKSUM,NO_NULL_COLLATION_IDS,LOCK_ALTER_TABLE_COPY READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OLD_PASSWORDS @@ -2709,7 +2709,7 @@ VARIABLE_COMMENT Fine-tune the optimizer behavior NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,rowid_filter,condition_pushdown_from_having,not_null_range_scan,hash_join_cardinality,sargable_casefold,default +ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,rowid_filter,condition_pushdown_from_having,not_null_range_scan,hash_join_cardinality,cset_narrowing,sargable_casefold,default READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_TRACE diff --git a/mysql-test/suite/sys_vars/t/old_mode_basic.test b/mysql-test/suite/sys_vars/t/old_mode_basic.test index cb18796729e..c3fc4c57189 100644 --- a/mysql-test/suite/sys_vars/t/old_mode_basic.test +++ b/mysql-test/suite/sys_vars/t/old_mode_basic.test @@ -172,7 +172,7 @@ SET @@global.old_mode = 4; SELECT @@global.old_mode; --Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = 128; +SET @@global.old_mode = 256; SELECT @@global.old_mode; # use of decimal values 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/r/optimizer_switch.result b/mysql-test/suite/sysschema/r/optimizer_switch.result index 2d99669b06d..6336051db0d 100644 --- a/mysql-test/suite/sysschema/r/optimizer_switch.result +++ b/mysql-test/suite/sysschema/r/optimizer_switch.result @@ -34,6 +34,7 @@ subquery_cache on table_elimination on call sys.optimizer_switch_off(); option opt +cset_narrowing off index_merge_sort_intersection off mrr off mrr_cost_based off 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_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result index 3f7f73d3264..710bd105473 100644 --- a/mysql-test/suite/vcol/r/vcol_misc.result +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -566,3 +566,14 @@ drop table t1; # # End of 10.3 tests # +# +# MDEV-31112 vcol circular references lead to stack overflow +# +create table t (a int, c int as (a)); +alter table t alter column c drop default; +alter table t modify column a int as (c) stored; +ERROR 01000: Expression for field `a` is referring to uninitialized field `c` +drop table t; +# +# End of 10.4 tests +# 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_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index 44c3d9e59d0..d788f502b6a 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -528,3 +528,16 @@ drop table t1; --echo # --echo # End of 10.3 tests --echo # + +--echo # +--echo # MDEV-31112 vcol circular references lead to stack overflow +--echo # +create table t (a int, c int as (a)); +alter table t alter column c drop default; +--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD +alter table t modify column a int as (c) stored; +drop table t; + +--echo # +--echo # End of 10.4 tests +--echo # 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 7f7323ba47f..fed410f0157 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -785,6 +785,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; @@ -807,4 +869,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/delete_history.result b/mysql-test/suite/versioning/r/delete_history.result index a49ec025dff..04483a864c1 100644 --- a/mysql-test/suite/versioning/r/delete_history.result +++ b/mysql-test/suite/versioning/r/delete_history.result @@ -1,5 +1,3 @@ -set @saved_frequency= @@global.innodb_purge_rseg_truncate_frequency; -set global innodb_purge_rseg_truncate_frequency= 1; call mtr.add_suppression("need more HISTORY partitions"); create table t (a int); delete history from t before system_time now(); @@ -195,7 +193,7 @@ drop table t1; # MDEV-25004 Missing row in FTS_DOC_ID_INDEX during DELETE HISTORY # create table t1 (a integer, c0 varchar(255), fulltext key (c0)) -with system versioning engine innodb; +with system versioning engine innodb stats_persistent=0; set system_versioning_alter_history= keep; alter table t1 drop system versioning; alter table t1 add system versioning; @@ -205,12 +203,11 @@ InnoDB 0 transactions not purged delete history from t1; drop table t1; create table t1 (id int primary key, ftx varchar(255)) -with system versioning engine innodb; +with system versioning engine innodb stats_persistent=0; insert into t1 values (1, 'c'); delete from t1; alter table t1 add fulltext key(ftx); drop table t1; -set global innodb_purge_rseg_truncate_frequency= @saved_frequency; # # MDEV-28201 Server crashes upon SHOW ANALYZE/EXPLAIN FORMAT=JSON # diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 9841b4dedbb..36ea54bb08e 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -439,7 +439,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); @@ -700,3 +700,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/r/update.result b/mysql-test/suite/versioning/r/update.result index c439f5cf8f5..25cb515cc18 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -339,6 +339,7 @@ drop table t1; # MDEV-21342 Assertion in set_ok_status() upon spatial field error on system-versioned table # create or replace table t1 (f point, key(f)) with system versioning engine=myisam; +insert t1 values (null); update t1 set f = null where f = 'foo'; ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field drop table t1; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 61653550389..44f52ddf747 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/delete_history.test b/mysql-test/suite/versioning/t/delete_history.test index c653405a61a..66c28568b22 100644 --- a/mysql-test/suite/versioning/t/delete_history.test +++ b/mysql-test/suite/versioning/t/delete_history.test @@ -2,9 +2,6 @@ --source include/have_partition.inc --source suite/versioning/engines.inc -set @saved_frequency= @@global.innodb_purge_rseg_truncate_frequency; -set global innodb_purge_rseg_truncate_frequency= 1; - call mtr.add_suppression("need more HISTORY partitions"); create table t (a int); @@ -198,7 +195,7 @@ drop table t1; --echo # MDEV-25004 Missing row in FTS_DOC_ID_INDEX during DELETE HISTORY --echo # create table t1 (a integer, c0 varchar(255), fulltext key (c0)) -with system versioning engine innodb; +with system versioning engine innodb stats_persistent=0; set system_versioning_alter_history= keep; alter table t1 drop system versioning; alter table t1 add system versioning; @@ -209,14 +206,12 @@ delete history from t1; drop table t1; create table t1 (id int primary key, ftx varchar(255)) -with system versioning engine innodb; +with system versioning engine innodb stats_persistent=0; insert into t1 values (1, 'c'); delete from t1; alter table t1 add fulltext key(ftx); drop table t1; -set global innodb_purge_rseg_truncate_frequency= @saved_frequency; - --echo # --echo # MDEV-28201 Server crashes upon SHOW ANALYZE/EXPLAIN FORMAT=JSON --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/suite/versioning/t/trx_id.opt b/mysql-test/suite/versioning/t/trx_id.opt new file mode 100644 index 00000000000..f900254f5d0 --- /dev/null +++ b/mysql-test/suite/versioning/t/trx_id.opt @@ -0,0 +1,2 @@ +--log_bin +--binlog_do_db=foo diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index 6930fecce40..50bf331b1fe 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -257,6 +257,7 @@ drop table t1; --echo # MDEV-21342 Assertion in set_ok_status() upon spatial field error on system-versioned table --echo # create or replace table t1 (f point, key(f)) with system versioning engine=myisam; +insert t1 values (null); --error ER_CANT_CREATE_GEOMETRY_OBJECT update t1 set f = null where f = 'foo'; diff --git a/mysql-test/suite/wsrep/include/check_galera_version.inc b/mysql-test/suite/wsrep/include/check_galera_version.inc index 7a58e657f40..40cd157ca80 100644 --- a/mysql-test/suite/wsrep/include/check_galera_version.inc +++ b/mysql-test/suite/wsrep/include/check_galera_version.inc @@ -34,13 +34,13 @@ SELECT CAST(REGEXP_REPLACE(@ACTUAL_GALERA_VERSION,'^[\\d\\.]*\\.(\\d+).*','\\1') #SELECT @ACTUAL_GALERA_MINOR_VERSION; #SELECT @ACTUAL_GALERA_RELEASE_VERSION; -if (!`SELECT (@ACTUAL_GALERA_MAJOR_VERSION >= @GALERA_MAJOR_VERSION AND @ACTUAL_GALERA_MINOR_VERSION > @GALERA_MINOR_VERSION) OR - (@ACTUAL_GALERA_MAJOR_VERSION = @GALERA_MAJOR_VERSION AND - @ACTUAL_GALERA_MINOR_VERSION = @GALERA_MINOR_VERSION AND +if (!`SELECT (@ACTUAL_GALERA_MINOR_VERSION > @GALERA_MINOR_VERSION) OR + (@ACTUAL_GALERA_MINOR_VERSION = @GALERA_MINOR_VERSION AND @ACTUAL_GALERA_RELEASE_VERSION >= @GALERA_RELEASE_VERSION) `) { - skip Test requires Galera library version >= $galera_version; + let actual_galera_version=`select @ACTUAL_GALERA_VERSION`; + skip needs galera >= $galera_version, got $actual_galera_version; } --echo # Correct Galera library found diff --git a/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result b/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result index 8e2bf85d632..ce164f66a22 100644 --- a/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result +++ b/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result @@ -10,7 +10,7 @@ SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIK 'wsrep_provider_signal', 'wsrep_provider_gmcast_listen_addr'); COUNT(*) -84 +83 SELECT * FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_provider_%' AND VARIABLE_NAME NOT IN ( 'wsrep_provider', @@ -998,21 +998,6 @@ ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED GLOBAL_VALUE_PATH NULL -VARIABLE_NAME WSREP_PROVIDER_PROTONET_BACKEND -SESSION_VALUE NULL -GLOBAL_VALUE asio -GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE asio -VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE VARCHAR -VARIABLE_COMMENT Wsrep provider option -NUMERIC_MIN_VALUE NULL -NUMERIC_MAX_VALUE NULL -NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NULL -READ_ONLY YES -COMMAND_LINE_ARGUMENT REQUIRED -GLOBAL_VALUE_PATH NULL VARIABLE_NAME WSREP_PROVIDER_PROTONET_VERSION SESSION_VALUE NULL GLOBAL_VALUE 0 diff --git a/mysql-test/suite/wsrep/r/wsrep_variables_sst_method.result b/mysql-test/suite/wsrep/r/wsrep_variables_sst_method.result new file mode 100644 index 00000000000..1c830d412f9 --- /dev/null +++ b/mysql-test/suite/wsrep/r/wsrep_variables_sst_method.result @@ -0,0 +1,61 @@ +SELECT @@wsrep_on; +@@wsrep_on +1 +SET @wsrep_sst_method_saved = @@global.wsrep_sst_method; +/* test currently supported methods */ +SET GLOBAL wsrep_sst_method=DEFAULT; +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +rsync +SET GLOBAL wsrep_sst_method='rsync'; +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +rsync +SET GLOBAL wsrep_sst_method='mysqldump'; +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +mysqldump +SET GLOBAL wsrep_sst_method='mariabackup'; +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +mariabackup +SET GLOBAL wsrep_sst_method='backup'; +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +backup +SET GLOBAL wsrep_sst_method='backup1.sh'; +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +backup1.sh +SET GLOBAL wsrep_sst_method='my method'; +ERROR 42000: Variable 'wsrep_sst_method' can't be set to the value of 'my method' +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +backup1.sh +SHOW WARNINGS; +Level Code Message +Error 1231 Variable 'wsrep_sst_method' can't be set to the value of 'my method' +SET GLOBAL wsrep_sst_method='/method'; +ERROR 42000: Variable 'wsrep_sst_method' can't be set to the value of '/method' +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +backup1.sh +SHOW WARNINGS; +Level Code Message +Error 1231 Variable 'wsrep_sst_method' can't be set to the value of '/method' +SET GLOBAL wsrep_sst_method='method!'; +ERROR 42000: Variable 'wsrep_sst_method' can't be set to the value of 'method!' +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +backup1.sh +SHOW WARNINGS; +Level Code Message +Error 1231 Variable 'wsrep_sst_method' can't be set to the value of 'method!' +SET GLOBAL wsrep_sst_method='method;'; +ERROR 42000: Variable 'wsrep_sst_method' can't be set to the value of 'method;' +SELECT @@global.wsrep_sst_method; +@@global.wsrep_sst_method +backup1.sh +SHOW WARNINGS; +Level Code Message +Error 1231 Variable 'wsrep_sst_method' can't be set to the value of 'method;' diff --git a/mysql-test/suite/wsrep/t/wsrep_variables_sst_method.cnf b/mysql-test/suite/wsrep/t/wsrep_variables_sst_method.cnf new file mode 100644 index 00000000000..b1c96d2614d --- /dev/null +++ b/mysql-test/suite/wsrep/t/wsrep_variables_sst_method.cnf @@ -0,0 +1,7 @@ +!include ../my.cnf + +[mysqld.1] +wsrep-on=ON +wsrep-cluster-address=gcomm:// +wsrep-provider=@ENV.WSREP_PROVIDER +binlog-format=ROW diff --git a/mysql-test/suite/wsrep/t/wsrep_variables_sst_method.test b/mysql-test/suite/wsrep/t/wsrep_variables_sst_method.test new file mode 100644 index 00000000000..b41718792a2 --- /dev/null +++ b/mysql-test/suite/wsrep/t/wsrep_variables_sst_method.test @@ -0,0 +1,50 @@ +--source include/have_wsrep.inc +--source include/have_innodb.inc + +SELECT @@wsrep_on; + +SET @wsrep_sst_method_saved = @@global.wsrep_sst_method; + +/* test currently supported methods */ +SET GLOBAL wsrep_sst_method=DEFAULT; +SELECT @@global.wsrep_sst_method; + +SET GLOBAL wsrep_sst_method='rsync'; +SELECT @@global.wsrep_sst_method; + +SET GLOBAL wsrep_sst_method='mysqldump'; +SELECT @@global.wsrep_sst_method; + +SET GLOBAL wsrep_sst_method='mariabackup'; +SELECT @@global.wsrep_sst_method; + +SET GLOBAL wsrep_sst_method='backup'; +SELECT @@global.wsrep_sst_method; + +SET GLOBAL wsrep_sst_method='backup1.sh'; +SELECT @@global.wsrep_sst_method; + +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL wsrep_sst_method='my method'; +SELECT @@global.wsrep_sst_method; +SHOW WARNINGS; + +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL wsrep_sst_method='/method'; +SELECT @@global.wsrep_sst_method; +SHOW WARNINGS; + +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL wsrep_sst_method='method!'; +SELECT @@global.wsrep_sst_method; +SHOW WARNINGS; + +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL wsrep_sst_method='method;'; +SELECT @@global.wsrep_sst_method; +SHOW WARNINGS; + + +--disable_query_log +SET @@global.wsrep_sst_method = @wsrep_sst_method_saved; +--enable_query_log 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/ma_dyncol.c b/mysys/ma_dyncol.c index 16373602805..35060b17665 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -2877,6 +2877,13 @@ dynamic_column_update_move_left(DYNAMIC_COLUMN *str, PLAN *plan, write= (uchar *)str->str + FIXED_HEADER_SIZE; set_fixed_header(str, (uint)new_offset_size, new_column_count); + if (!new_column_count) + { + // No records left + DBUG_ASSERT(new_header_size == 0); + str->length= FIXED_HEADER_SIZE; + return ER_DYNCOL_OK; + } /* Move headers first. diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index c7663d04b4f..39c113650da 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -28,21 +28,16 @@ #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_MPROTECT 2 +#define ROOT_FLAG_READ_ONLY 4 /* data packed in MEM_ROOT -> min_malloc */ /* Don't allocate too small blocks */ #define ROOT_MIN_BLOCK_SIZE 256 -/* bits in MEM_ROOT->flags */ -#define ROOT_FLAG_THREAD_SPECIFIC 1 -#define ROOT_FLAG_MPROTECT 2 - -#define MALLOC_FLAG(R) MYF((R)->flags & ROOT_FLAG_THREAD_SPECIFIC ? 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) @@ -69,8 +64,7 @@ static void *root_alloc(MEM_ROOT *root, size_t size, size_t *alloced_size, #endif /* HAVE_MMAP */ return my_malloc(root->psi_key, size, - my_flags | MYF(root->flags & ROOT_FLAG_THREAD_SPECIFIC ? - MY_THREAD_SPECIFIC : 0)); + my_flags | MALLOC_FLAG(root)); } static void root_free(MEM_ROOT *root, void *ptr, size_t size) @@ -172,9 +166,6 @@ void init_alloc_root(PSI_memory_key key, MEM_ROOT *mem_root, size_t block_size, mem_root->block_num= 4; /* We shift this with >>2 */ mem_root->first_block_usage= 0; mem_root->psi_key= key; -#ifdef PROTECT_STATEMENT_MEMROOT - mem_root->read_only= 0; -#endif #if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) if (pre_alloc_size) @@ -281,10 +272,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", { @@ -300,9 +288,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->psi_key, length, MYF(MY_WME | ME_FATAL | - (mem_root->flags & - ROOT_FLAG_THREAD_SPECIFIC ? - MY_THREAD_SPECIFIC : 0))))) + MALLOC_FLAG(mem_root))))) { if (mem_root->error_handler) (*mem_root->error_handler)(); @@ -410,7 +396,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 } @@ -426,7 +412,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 @@ -560,6 +546,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; +} + + /* Remember last MEM_ROOT block. diff --git a/mysys/my_compare.c b/mysys/my_compare.c index d4ecfd7b4aa..d1326dc9d04 100644 --- a/mysys/my_compare.c +++ b/mysys/my_compare.c @@ -20,16 +20,6 @@ #include #include -int ha_compare_text(CHARSET_INFO *charset_info, const uchar *a, size_t a_length, - const uchar *b, size_t b_length, my_bool part_key) -{ - if (!part_key) - return my_ci_strnncollsp(charset_info, a, a_length, - b, b_length); - return my_ci_strnncoll(charset_info, a, a_length, - b, b_length, part_key); -} - static int compare_bin(const uchar *a, uint a_length, const uchar *b, uint b_length, @@ -183,9 +173,12 @@ int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a, next_key_length=key_length-b_length-pack_length; if (piks && - (flag=ha_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && - next_key_length <= 0)))) + (flag= ha_compare_char_fixed(keyseg->charset, + a, a_length, + b, b_length, + keyseg->length / keyseg->charset->mbmaxlen, + (my_bool) ((nextflag & SEARCH_PREFIX) && + next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a+=a_length; b+=b_length; @@ -195,9 +188,12 @@ int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a, { uint length=(uint) (end-a), a_length=length, b_length=length; if (piks && - (flag= ha_compare_text(keyseg->charset, a, a_length, b, b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && - next_key_length <= 0)))) + (flag= ha_compare_char_fixed(keyseg->charset, + a, a_length, + b, b_length, + keyseg->length / keyseg->charset->mbmaxlen, + (my_bool) ((nextflag & SEARCH_PREFIX) && + next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a=end; b+=length; @@ -242,7 +238,9 @@ int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a, next_key_length=key_length-b_length-pack_length; if (piks && - (flag= ha_compare_text(keyseg->charset,a,a_length,b,b_length, + (flag= ha_compare_char_varying(keyseg->charset, + a, a_length, + b, b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); @@ -260,7 +258,7 @@ int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a, next_key_length=key_length-b_length-pack_length; if (piks && - (flag=compare_bin(a,a_length,b,b_length, + (flag=compare_bin(a,a_length,b,b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0), 0))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); 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/CMakeLists.txt b/plugin/auth_pam/CMakeLists.txt index 49e02b339c7..f2cce80f800 100644 --- a/plugin/auth_pam/CMakeLists.txt +++ b/plugin/auth_pam/CMakeLists.txt @@ -42,8 +42,8 @@ IF(HAVE_PAM_APPL_H AND HAVE_GETGROUPLIST) IF (TARGET auth_pam) MYSQL_ADD_EXECUTABLE(auth_pam_tool auth_pam_tool.c DESTINATION ${INSTALL_PLUGINDIR}/auth_pam_tool_dir COMPONENT Server) TARGET_LINK_LIBRARIES(auth_pam_tool pam) - IF (CMAKE_MAJOR_VERSION EQUAL 2) - # 2.8.12 bug (in CentOS 7) + IF (CMAKE_VERSION VERSION_LESS 3.10.0) + # cmake bug #14362 SET(user mysql) ELSE() SET(user "%{mysqld_user}") diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index ffcfa019294..86220f48183 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "auth_pam_tool.h" diff --git a/plugin/cracklib_password_check/CMakeLists.txt b/plugin/cracklib_password_check/CMakeLists.txt index 4a6337310f9..79b3b80fbef 100644 --- a/plugin/cracklib_password_check/CMakeLists.txt +++ b/plugin/cracklib_password_check/CMakeLists.txt @@ -1,3 +1,9 @@ + +IF(PLUGIN_CRACKLIB_PASSWORD_CHECK STREQUAL "NO") + ADD_FEATURE_INFO(CRACKLIB_PASSWORD_CHECK "OFF" "CrackLib Password Validation Plugin") + RETURN() +ENDIF() + INCLUDE (CheckIncludeFiles) INCLUDE (CheckLibraryExists) 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/disks/mysql-test/disks/disks.result b/plugin/disks/mysql-test/disks/disks.result index 888f2df64f7..e46390c7516 100644 --- a/plugin/disks/mysql-test/disks/disks.result +++ b/plugin/disks/mysql-test/disks/disks.result @@ -7,6 +7,6 @@ DISKS CREATE TEMPORARY TABLE `DISKS` ( `Used` bigint(32) NOT NULL, `Available` bigint(32) NOT NULL ) ENGINE=MEMORY DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci -select sum(Total) > sum(Available), sum(Total)>sum(Used) from information_schema.disks; -sum(Total) > sum(Available) sum(Total)>sum(Used) +select sum(Total) >= sum(Available), sum(Total)>=sum(Used) from information_schema.disks; +sum(Total) >= sum(Available) sum(Total)>=sum(Used) 1 1 diff --git a/plugin/disks/mysql-test/disks/disks.test b/plugin/disks/mysql-test/disks/disks.test index 7189c548342..9adc3f01ebc 100644 --- a/plugin/disks/mysql-test/disks/disks.test +++ b/plugin/disks/mysql-test/disks/disks.test @@ -1,3 +1,3 @@ --replace_regex /varchar\([0-9]+\)/varchar(pathlen)/ show create table information_schema.disks; -select sum(Total) > sum(Available), sum(Total)>sum(Used) from information_schema.disks; +select sum(Total) >= sum(Available), sum(Total)>=sum(Used) from information_schema.disks; diff --git a/plugin/disks/mysql-test/disks/disks_notembedded.result b/plugin/disks/mysql-test/disks/disks_notembedded.result index 974294744cc..ea2ccc85bfb 100644 --- a/plugin/disks/mysql-test/disks/disks_notembedded.result +++ b/plugin/disks/mysql-test/disks/disks_notembedded.result @@ -6,16 +6,16 @@ CREATE USER user1@localhost; GRANT SELECT ON *.* TO user1@localhost; connect con1,localhost,user1,,; connection con1; -select sum(Total) > sum(Available), sum(Total)>sum(Used) from information_schema.disks; -sum(Total) > sum(Available) sum(Total)>sum(Used) +select sum(Total) >= sum(Available), sum(Total) >= sum(Used) from information_schema.disks; +sum(Total) >= sum(Available) sum(Total) >= sum(Used) NULL NULL disconnect con1; connection default; GRANT FILE ON *.* TO user1@localhost; connect con1,localhost,user1,,; connection con1; -select sum(Total) > sum(Available), sum(Total)>sum(Used) from information_schema.disks; -sum(Total) > sum(Available) sum(Total)>sum(Used) +select sum(Total) >= sum(Available), sum(Total) >= sum(Used) from information_schema.disks; +sum(Total) >= sum(Available) sum(Total) >= sum(Used) 1 1 connection default; DROP USER user1@localhost; diff --git a/plugin/disks/mysql-test/disks/disks_notembedded.test b/plugin/disks/mysql-test/disks/disks_notembedded.test index a0f6c2e5887..4481da9f176 100644 --- a/plugin/disks/mysql-test/disks/disks_notembedded.test +++ b/plugin/disks/mysql-test/disks/disks_notembedded.test @@ -10,7 +10,7 @@ GRANT SELECT ON *.* TO user1@localhost; connect (con1,localhost,user1,,); connection con1; -select sum(Total) > sum(Available), sum(Total)>sum(Used) from information_schema.disks; +select sum(Total) >= sum(Available), sum(Total) >= sum(Used) from information_schema.disks; disconnect con1; connection default; @@ -18,7 +18,7 @@ GRANT FILE ON *.* TO user1@localhost; connect (con1,localhost,user1,,); connection con1; -select sum(Total) > sum(Available), sum(Total)>sum(Used) from information_schema.disks; +select sum(Total) >= sum(Available), sum(Total) >= sum(Used) from information_schema.disks; connection default; DROP USER user1@localhost; diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index 6b5be475e97..cc29e57fcfe 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/hashicorp_key_management/hashicorp_key_management_plugin.cc b/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc index 7c72af688e4..bdc2f7345f1 100644 --- a/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc +++ b/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc @@ -593,32 +593,16 @@ int HCData::curl_run (const char *url, std::string *response, { const char *res = response->c_str(); /* - Error 404 requires special handling - in case the server - returned an empty array of error strings (the value of the - "error" object in JSON is equal to an empty array), we should - ignore this error at this level, since this means the missing - key (this problem is handled at a higher level), but if the - error object contains anything other than empty array, then - we need to print the error message to the log: + Error 404 requires special handling - we should ignore this + error at this level, since this means the missing key (this + problem is handled at a higher level) */ if (http_code == 404) { - const char *err; - int err_len; - if (json_get_object_key(res, res + response->size(), - "errors", &err, &err_len) == JSV_ARRAY) - { - const char *ev; - int ev_len; - if (json_get_array_item(err, err + err_len, 0, &ev, &ev_len) == - JSV_NOTHING) - { - *response = std::string(""); - is_error = false; - } - } + *response = std::string(""); + is_error = false; } - if (is_error) + else if (is_error) { my_printf_error(ER_UNKNOWN_ERROR, PLUGIN_ERROR_HEADER "Hashicorp server error: %d, response: %s", diff --git a/plugin/test_sql_service/CMakeLists.txt b/plugin/test_sql_service/CMakeLists.txt index 615508bdc4e..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) +MYSQL_ADD_PLUGIN(test_sql_service ${SOURCES} MODULE_ONLY COMPONENT Test) diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet4_myisam.result b/plugin/type_inet/mysql-test/type_inet/type_inet4_myisam.result index b6fd55e1df7..aaf66b34524 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet4_myisam.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet4_myisam.result @@ -98,6 +98,8 @@ c EXPLAIN SELECT * FROM t1 WHERE c>CAST('0.0.0.1' AS INET4); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index c c 67 NULL 3 Using where; Using index +Warnings: +Note 1105 Cannot use key `c` part[0] for lookup: `test`.`t1`.`c` of type `varchar` > "cast('0.0.0.1' as inet4)" of type `inet4` SELECT * FROM t1 WHERE c=CAST('0.0.0.1' AS INET4); c 0.0.0.1 diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.result b/plugin/type_inet/mysql-test/type_inet/type_inet6.result index 1d0f77ecbf5..a576a7e163f 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.result @@ -2284,6 +2284,81 @@ Warnings: Warning 1292 Incorrect inet6 value: '' DROP TABLE t1; # +# MDEV-32879 Server crash in my_decimal::operator= or unexpected ER_DUP_ENTRY upon comparison with INET6 and similar types +# +CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f, GROUP_CONCAT(c) FROM t1 GROUP BY f; +f GROUP_CONCAT(c) +NULL 2000-01-01 00:00:00.000000,1900-01-01 00:00:00.000000 +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f, COUNT(c) FROM t1 GROUP BY f; +f COUNT(c) +NULL 2 +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f FROM t1 ORDER BY f; +f +NULL +NULL +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL); +INSERT INTO t1 VALUES ('','::'),('','::'); +SELECT 1.00 + (b = a) AS f FROM t1 ORDER BY f; +f +NULL +NULL +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +SELECT 1.00 + (b BETWEEN a AND '') AS f FROM t1 ORDER BY f; +f +NULL +NULL +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +SELECT 1.00 + (b IN (a,'')) AS f FROM t1 ORDER BY f; +f +NULL +NULL +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +DROP TABLE t1; +# # MDEV-22256 Assertion `length == pack_length()' failed in Field_timestamp_with_dec::sort_string # SET sql_mode=''; diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.test b/plugin/type_inet/mysql-test/type_inet/type_inet6.test index 99f75312f3c..0c56ecfe4bb 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.test +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.test @@ -1675,6 +1675,32 @@ INSERT INTO t1 VALUES ('::'); SELECT * FROM t1 WHERE a IN ('','::1'); DROP TABLE t1; +--echo # +--echo # MDEV-32879 Server crash in my_decimal::operator= or unexpected ER_DUP_ENTRY upon comparison with INET6 and similar types +--echo # + +CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f, GROUP_CONCAT(c) FROM t1 GROUP BY f; +DROP TABLE t1; + +CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f, COUNT(c) FROM t1 GROUP BY f; +DROP TABLE t1; + +CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f FROM t1 ORDER BY f; +DROP TABLE t1; + +CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL); +INSERT INTO t1 VALUES ('','::'),('','::'); +SELECT 1.00 + (b = a) AS f FROM t1 ORDER BY f; +SELECT 1.00 + (b BETWEEN a AND '') AS f FROM t1 ORDER BY f; +SELECT 1.00 + (b IN (a,'')) AS f FROM t1 ORDER BY f; +DROP TABLE t1; + --echo # --echo # MDEV-22256 Assertion `length == pack_length()' failed in Field_timestamp_with_dec::sort_string --echo # diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.result b/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.result index da67e05a163..0f20e16db9c 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.result @@ -98,6 +98,8 @@ c EXPLAIN SELECT * FROM t1 WHERE c>CAST('::1' AS INET6); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index c c 67 NULL 3 Using where; Using index +Warnings: +Note 1105 Cannot use key `c` part[0] for lookup: `test`.`t1`.`c` of type `varchar` > "cast('::1' as inet6)" of type `inet6` SELECT * FROM t1 WHERE c=CAST('::1' AS INET6); c 0::1 diff --git a/plugin/type_test/mysql-test/type_test/type_test_double.result b/plugin/type_test/mysql-test/type_test/type_test_double.result index 6241ff95b8a..edcfdc0eff8 100644 --- a/plugin/type_test/mysql-test/type_test/type_test_double.result +++ b/plugin/type_test/mysql-test/type_test/type_test_double.result @@ -290,7 +290,7 @@ DATA_TYPE test_double CHARACTER_MAXIMUM_LENGTH NULL CHARACTER_OCTET_LENGTH NULL NUMERIC_PRECISION 22 -NUMERIC_SCALE 31 +NUMERIC_SCALE NULL DATETIME_PRECISION NULL CHARACTER_SET_NAME NULL COLLATION_NAME NULL diff --git a/plugin/type_uuid/mysql-test/type_uuid/order.result b/plugin/type_uuid/mysql-test/type_uuid/order.result index 2f6ae3ed47c..3dd799b6ae2 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/order.result +++ b/plugin/type_uuid/mysql-test/type_uuid/order.result @@ -1,80 +1,81 @@ create table t1 (a uuid, b int not null, index (a)); -insert t1 select sformat('11223344-5566-{:x}777-{}888-99aabbccddee', seq div 4, elt(1+(seq % 4),0,8,'c','e')),seq from seq_0_to_63; +insert t1 select sformat('{:03}01234-5566-{:x}777-{}888-99aabbccddee', +(seq % 2)*100 + seq, seq div 4, elt(1+(seq % 4),0,8,'c','e')),seq from seq_0_to_63; Warnings: -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 33 -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 37 -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 41 -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 45 -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 49 -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 53 -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 57 -Warning 1292 Incorrect uuid value: '11223344-5566-f777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 61 -select * from t1; +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 33 +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 37 +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 41 +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 45 +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 49 +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 53 +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 57 +Warning 1292 Incorrect uuid value: '06001234-5566-f777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 61 +select * from t1 order by b; a b -11223344-5566-0777-0888-99aabbccddee 0 -11223344-5566-0777-8888-99aabbccddee 1 -11223344-5566-0777-c888-99aabbccddee 2 -11223344-5566-0777-e888-99aabbccddee 3 -11223344-5566-1777-0888-99aabbccddee 4 -11223344-5566-1777-8888-99aabbccddee 5 -11223344-5566-1777-c888-99aabbccddee 6 -11223344-5566-1777-e888-99aabbccddee 7 -11223344-5566-2777-0888-99aabbccddee 8 -11223344-5566-2777-8888-99aabbccddee 9 -11223344-5566-2777-c888-99aabbccddee 10 -11223344-5566-2777-e888-99aabbccddee 11 -11223344-5566-3777-0888-99aabbccddee 12 -11223344-5566-3777-8888-99aabbccddee 13 -11223344-5566-3777-c888-99aabbccddee 14 -11223344-5566-3777-e888-99aabbccddee 15 -11223344-5566-4777-0888-99aabbccddee 16 -11223344-5566-4777-8888-99aabbccddee 17 -11223344-5566-4777-c888-99aabbccddee 18 -11223344-5566-4777-e888-99aabbccddee 19 -11223344-5566-5777-0888-99aabbccddee 20 -11223344-5566-5777-8888-99aabbccddee 21 -11223344-5566-5777-c888-99aabbccddee 22 -11223344-5566-5777-e888-99aabbccddee 23 -11223344-5566-6777-0888-99aabbccddee 24 -11223344-5566-6777-8888-99aabbccddee 25 -11223344-5566-6777-c888-99aabbccddee 26 -11223344-5566-6777-e888-99aabbccddee 27 -11223344-5566-7777-0888-99aabbccddee 28 -11223344-5566-7777-8888-99aabbccddee 29 -11223344-5566-7777-c888-99aabbccddee 30 -11223344-5566-7777-e888-99aabbccddee 31 +00001234-5566-0777-0888-99aabbccddee 0 +10101234-5566-0777-8888-99aabbccddee 1 +00201234-5566-0777-c888-99aabbccddee 2 +10301234-5566-0777-e888-99aabbccddee 3 +00401234-5566-1777-0888-99aabbccddee 4 +10501234-5566-1777-8888-99aabbccddee 5 +00601234-5566-1777-c888-99aabbccddee 6 +10701234-5566-1777-e888-99aabbccddee 7 +00801234-5566-2777-0888-99aabbccddee 8 +10901234-5566-2777-8888-99aabbccddee 9 +01001234-5566-2777-c888-99aabbccddee 10 +11101234-5566-2777-e888-99aabbccddee 11 +01201234-5566-3777-0888-99aabbccddee 12 +11301234-5566-3777-8888-99aabbccddee 13 +01401234-5566-3777-c888-99aabbccddee 14 +11501234-5566-3777-e888-99aabbccddee 15 +01601234-5566-4777-0888-99aabbccddee 16 +11701234-5566-4777-8888-99aabbccddee 17 +01801234-5566-4777-c888-99aabbccddee 18 +11901234-5566-4777-e888-99aabbccddee 19 +02001234-5566-5777-0888-99aabbccddee 20 +12101234-5566-5777-8888-99aabbccddee 21 +02201234-5566-5777-c888-99aabbccddee 22 +12301234-5566-5777-e888-99aabbccddee 23 +02401234-5566-6777-0888-99aabbccddee 24 +12501234-5566-6777-8888-99aabbccddee 25 +02601234-5566-6777-c888-99aabbccddee 26 +12701234-5566-6777-e888-99aabbccddee 27 +02801234-5566-7777-0888-99aabbccddee 28 +12901234-5566-7777-8888-99aabbccddee 29 +03001234-5566-7777-c888-99aabbccddee 30 +13101234-5566-7777-e888-99aabbccddee 31 NULL 32 -11223344-5566-8777-8888-99aabbccddee 33 -11223344-5566-8777-c888-99aabbccddee 34 -11223344-5566-8777-e888-99aabbccddee 35 +13301234-5566-8777-8888-99aabbccddee 33 +03401234-5566-8777-c888-99aabbccddee 34 +13501234-5566-8777-e888-99aabbccddee 35 NULL 36 -11223344-5566-9777-8888-99aabbccddee 37 -11223344-5566-9777-c888-99aabbccddee 38 -11223344-5566-9777-e888-99aabbccddee 39 +13701234-5566-9777-8888-99aabbccddee 37 +03801234-5566-9777-c888-99aabbccddee 38 +13901234-5566-9777-e888-99aabbccddee 39 NULL 40 -11223344-5566-a777-8888-99aabbccddee 41 -11223344-5566-a777-c888-99aabbccddee 42 -11223344-5566-a777-e888-99aabbccddee 43 +14101234-5566-a777-8888-99aabbccddee 41 +04201234-5566-a777-c888-99aabbccddee 42 +14301234-5566-a777-e888-99aabbccddee 43 NULL 44 -11223344-5566-b777-8888-99aabbccddee 45 -11223344-5566-b777-c888-99aabbccddee 46 -11223344-5566-b777-e888-99aabbccddee 47 +14501234-5566-b777-8888-99aabbccddee 45 +04601234-5566-b777-c888-99aabbccddee 46 +14701234-5566-b777-e888-99aabbccddee 47 NULL 48 -11223344-5566-c777-8888-99aabbccddee 49 -11223344-5566-c777-c888-99aabbccddee 50 -11223344-5566-c777-e888-99aabbccddee 51 +14901234-5566-c777-8888-99aabbccddee 49 +05001234-5566-c777-c888-99aabbccddee 50 +15101234-5566-c777-e888-99aabbccddee 51 NULL 52 -11223344-5566-d777-8888-99aabbccddee 53 -11223344-5566-d777-c888-99aabbccddee 54 -11223344-5566-d777-e888-99aabbccddee 55 +15301234-5566-d777-8888-99aabbccddee 53 +05401234-5566-d777-c888-99aabbccddee 54 +15501234-5566-d777-e888-99aabbccddee 55 NULL 56 -11223344-5566-e777-8888-99aabbccddee 57 -11223344-5566-e777-c888-99aabbccddee 58 -11223344-5566-e777-e888-99aabbccddee 59 +15701234-5566-e777-8888-99aabbccddee 57 +05801234-5566-e777-c888-99aabbccddee 58 +15901234-5566-e777-e888-99aabbccddee 59 NULL 60 -11223344-5566-f777-8888-99aabbccddee 61 -11223344-5566-f777-c888-99aabbccddee 62 -11223344-5566-f777-e888-99aabbccddee 63 +16101234-5566-f777-8888-99aabbccddee 61 +06201234-5566-f777-c888-99aabbccddee 62 +16301234-5566-f777-e888-99aabbccddee 63 select * from t1 order by a; a b NULL 40 @@ -85,62 +86,62 @@ NULL 48 NULL 52 NULL 56 NULL 60 -11223344-5566-0777-0888-99aabbccddee 0 -11223344-5566-1777-0888-99aabbccddee 4 -11223344-5566-2777-0888-99aabbccddee 8 -11223344-5566-3777-0888-99aabbccddee 12 -11223344-5566-4777-0888-99aabbccddee 16 -11223344-5566-5777-0888-99aabbccddee 20 -11223344-5566-6777-0888-99aabbccddee 24 -11223344-5566-6777-8888-99aabbccddee 25 -11223344-5566-6777-c888-99aabbccddee 26 -11223344-5566-6777-e888-99aabbccddee 27 -11223344-5566-7777-0888-99aabbccddee 28 -11223344-5566-7777-8888-99aabbccddee 29 -11223344-5566-7777-c888-99aabbccddee 30 -11223344-5566-7777-e888-99aabbccddee 31 -11223344-5566-8777-8888-99aabbccddee 33 -11223344-5566-8777-c888-99aabbccddee 34 -11223344-5566-8777-e888-99aabbccddee 35 -11223344-5566-9777-8888-99aabbccddee 37 -11223344-5566-9777-c888-99aabbccddee 38 -11223344-5566-9777-e888-99aabbccddee 39 -11223344-5566-a777-8888-99aabbccddee 41 -11223344-5566-a777-c888-99aabbccddee 42 -11223344-5566-a777-e888-99aabbccddee 43 -11223344-5566-b777-8888-99aabbccddee 45 -11223344-5566-b777-c888-99aabbccddee 46 -11223344-5566-b777-e888-99aabbccddee 47 -11223344-5566-c777-8888-99aabbccddee 49 -11223344-5566-c777-c888-99aabbccddee 50 -11223344-5566-c777-e888-99aabbccddee 51 -11223344-5566-d777-8888-99aabbccddee 53 -11223344-5566-d777-c888-99aabbccddee 54 -11223344-5566-d777-e888-99aabbccddee 55 -11223344-5566-e777-8888-99aabbccddee 57 -11223344-5566-e777-c888-99aabbccddee 58 -11223344-5566-e777-e888-99aabbccddee 59 -11223344-5566-f777-8888-99aabbccddee 61 -11223344-5566-f777-c888-99aabbccddee 62 -11223344-5566-f777-e888-99aabbccddee 63 -11223344-5566-0777-8888-99aabbccddee 1 -11223344-5566-1777-8888-99aabbccddee 5 -11223344-5566-2777-8888-99aabbccddee 9 -11223344-5566-3777-8888-99aabbccddee 13 -11223344-5566-4777-8888-99aabbccddee 17 -11223344-5566-5777-8888-99aabbccddee 21 -11223344-5566-0777-c888-99aabbccddee 2 -11223344-5566-1777-c888-99aabbccddee 6 -11223344-5566-2777-c888-99aabbccddee 10 -11223344-5566-3777-c888-99aabbccddee 14 -11223344-5566-4777-c888-99aabbccddee 18 -11223344-5566-5777-c888-99aabbccddee 22 -11223344-5566-0777-e888-99aabbccddee 3 -11223344-5566-1777-e888-99aabbccddee 7 -11223344-5566-2777-e888-99aabbccddee 11 -11223344-5566-3777-e888-99aabbccddee 15 -11223344-5566-4777-e888-99aabbccddee 19 -11223344-5566-5777-e888-99aabbccddee 23 +00001234-5566-0777-0888-99aabbccddee 0 +00401234-5566-1777-0888-99aabbccddee 4 +00801234-5566-2777-0888-99aabbccddee 8 +01201234-5566-3777-0888-99aabbccddee 12 +01601234-5566-4777-0888-99aabbccddee 16 +02001234-5566-5777-0888-99aabbccddee 20 +02401234-5566-6777-0888-99aabbccddee 24 +02601234-5566-6777-c888-99aabbccddee 26 +02801234-5566-7777-0888-99aabbccddee 28 +03001234-5566-7777-c888-99aabbccddee 30 +03401234-5566-8777-c888-99aabbccddee 34 +03801234-5566-9777-c888-99aabbccddee 38 +04201234-5566-a777-c888-99aabbccddee 42 +04601234-5566-b777-c888-99aabbccddee 46 +05001234-5566-c777-c888-99aabbccddee 50 +05401234-5566-d777-c888-99aabbccddee 54 +05801234-5566-e777-c888-99aabbccddee 58 +06201234-5566-f777-c888-99aabbccddee 62 +12501234-5566-6777-8888-99aabbccddee 25 +12701234-5566-6777-e888-99aabbccddee 27 +12901234-5566-7777-8888-99aabbccddee 29 +13101234-5566-7777-e888-99aabbccddee 31 +13301234-5566-8777-8888-99aabbccddee 33 +13501234-5566-8777-e888-99aabbccddee 35 +13701234-5566-9777-8888-99aabbccddee 37 +13901234-5566-9777-e888-99aabbccddee 39 +14101234-5566-a777-8888-99aabbccddee 41 +14301234-5566-a777-e888-99aabbccddee 43 +14501234-5566-b777-8888-99aabbccddee 45 +14701234-5566-b777-e888-99aabbccddee 47 +14901234-5566-c777-8888-99aabbccddee 49 +15101234-5566-c777-e888-99aabbccddee 51 +15301234-5566-d777-8888-99aabbccddee 53 +15501234-5566-d777-e888-99aabbccddee 55 +15701234-5566-e777-8888-99aabbccddee 57 +15901234-5566-e777-e888-99aabbccddee 59 +16101234-5566-f777-8888-99aabbccddee 61 +16301234-5566-f777-e888-99aabbccddee 63 +10101234-5566-0777-8888-99aabbccddee 1 +10501234-5566-1777-8888-99aabbccddee 5 +10901234-5566-2777-8888-99aabbccddee 9 +11301234-5566-3777-8888-99aabbccddee 13 +11701234-5566-4777-8888-99aabbccddee 17 +12101234-5566-5777-8888-99aabbccddee 21 +00201234-5566-0777-c888-99aabbccddee 2 +00601234-5566-1777-c888-99aabbccddee 6 +01001234-5566-2777-c888-99aabbccddee 10 +01401234-5566-3777-c888-99aabbccddee 14 +01801234-5566-4777-c888-99aabbccddee 18 +02201234-5566-5777-c888-99aabbccddee 22 +10301234-5566-0777-e888-99aabbccddee 3 +10701234-5566-1777-e888-99aabbccddee 7 +11101234-5566-2777-e888-99aabbccddee 11 +11501234-5566-3777-e888-99aabbccddee 15 +11901234-5566-4777-e888-99aabbccddee 19 +12301234-5566-5777-e888-99aabbccddee 23 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -149,138 +150,138 @@ t1 CREATE TABLE `t1` ( KEY `a` (`a`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci # now let's use the table as above, but created in 10.11.4 -select * from t2; +select * from t2 order by b; a b -11223344-5566-0777-0888-99aabbccddee 0 -11223344-5566-0777-8888-99aabbccddee 1 -11223344-5566-0777-c888-99aabbccddee 2 -11223344-5566-0777-e888-99aabbccddee 3 -11223344-5566-1777-0888-99aabbccddee 4 -11223344-5566-1777-8888-99aabbccddee 5 -11223344-5566-1777-c888-99aabbccddee 6 -11223344-5566-1777-e888-99aabbccddee 7 -11223344-5566-2777-0888-99aabbccddee 8 -11223344-5566-2777-8888-99aabbccddee 9 -11223344-5566-2777-c888-99aabbccddee 10 -11223344-5566-2777-e888-99aabbccddee 11 -11223344-5566-3777-0888-99aabbccddee 12 -11223344-5566-3777-8888-99aabbccddee 13 -11223344-5566-3777-c888-99aabbccddee 14 -11223344-5566-3777-e888-99aabbccddee 15 -11223344-5566-4777-0888-99aabbccddee 16 -11223344-5566-4777-8888-99aabbccddee 17 -11223344-5566-4777-c888-99aabbccddee 18 -11223344-5566-4777-e888-99aabbccddee 19 -11223344-5566-5777-0888-99aabbccddee 20 -11223344-5566-5777-8888-99aabbccddee 21 -11223344-5566-5777-c888-99aabbccddee 22 -11223344-5566-5777-e888-99aabbccddee 23 -11223344-5566-6777-0888-99aabbccddee 24 -11223344-5566-6777-8888-99aabbccddee 25 -11223344-5566-6777-c888-99aabbccddee 26 -11223344-5566-6777-e888-99aabbccddee 27 -11223344-5566-7777-0888-99aabbccddee 28 -11223344-5566-7777-8888-99aabbccddee 29 -11223344-5566-7777-c888-99aabbccddee 30 -11223344-5566-7777-e888-99aabbccddee 31 -11223344-5566-8777-0888-99aabbccddee 32 -11223344-5566-8777-8888-99aabbccddee 33 -11223344-5566-8777-c888-99aabbccddee 34 -11223344-5566-8777-e888-99aabbccddee 35 -11223344-5566-9777-0888-99aabbccddee 36 -11223344-5566-9777-8888-99aabbccddee 37 -11223344-5566-9777-c888-99aabbccddee 38 -11223344-5566-9777-e888-99aabbccddee 39 -11223344-5566-a777-0888-99aabbccddee 40 -11223344-5566-a777-8888-99aabbccddee 41 -11223344-5566-a777-c888-99aabbccddee 42 -11223344-5566-a777-e888-99aabbccddee 43 -11223344-5566-b777-0888-99aabbccddee 44 -11223344-5566-b777-8888-99aabbccddee 45 -11223344-5566-b777-c888-99aabbccddee 46 -11223344-5566-b777-e888-99aabbccddee 47 -11223344-5566-c777-0888-99aabbccddee 48 -11223344-5566-c777-8888-99aabbccddee 49 -11223344-5566-c777-c888-99aabbccddee 50 -11223344-5566-c777-e888-99aabbccddee 51 -11223344-5566-d777-0888-99aabbccddee 52 -11223344-5566-d777-8888-99aabbccddee 53 -11223344-5566-d777-c888-99aabbccddee 54 -11223344-5566-d777-e888-99aabbccddee 55 -11223344-5566-e777-0888-99aabbccddee 56 -11223344-5566-e777-8888-99aabbccddee 57 -11223344-5566-e777-c888-99aabbccddee 58 -11223344-5566-e777-e888-99aabbccddee 59 -11223344-5566-f777-0888-99aabbccddee 60 -11223344-5566-f777-8888-99aabbccddee 61 -11223344-5566-f777-c888-99aabbccddee 62 -11223344-5566-f777-e888-99aabbccddee 63 +00001234-5566-0777-0888-99aabbccddee 0 +10101234-5566-0777-8888-99aabbccddee 1 +00201234-5566-0777-c888-99aabbccddee 2 +10301234-5566-0777-e888-99aabbccddee 3 +00401234-5566-1777-0888-99aabbccddee 4 +10501234-5566-1777-8888-99aabbccddee 5 +00601234-5566-1777-c888-99aabbccddee 6 +10701234-5566-1777-e888-99aabbccddee 7 +00801234-5566-2777-0888-99aabbccddee 8 +10901234-5566-2777-8888-99aabbccddee 9 +01001234-5566-2777-c888-99aabbccddee 10 +11101234-5566-2777-e888-99aabbccddee 11 +01201234-5566-3777-0888-99aabbccddee 12 +11301234-5566-3777-8888-99aabbccddee 13 +01401234-5566-3777-c888-99aabbccddee 14 +11501234-5566-3777-e888-99aabbccddee 15 +01601234-5566-4777-0888-99aabbccddee 16 +11701234-5566-4777-8888-99aabbccddee 17 +01801234-5566-4777-c888-99aabbccddee 18 +11901234-5566-4777-e888-99aabbccddee 19 +02001234-5566-5777-0888-99aabbccddee 20 +12101234-5566-5777-8888-99aabbccddee 21 +02201234-5566-5777-c888-99aabbccddee 22 +12301234-5566-5777-e888-99aabbccddee 23 +02401234-5566-6777-0888-99aabbccddee 24 +12501234-5566-6777-8888-99aabbccddee 25 +02601234-5566-6777-c888-99aabbccddee 26 +12701234-5566-6777-e888-99aabbccddee 27 +02801234-5566-7777-0888-99aabbccddee 28 +12901234-5566-7777-8888-99aabbccddee 29 +03001234-5566-7777-c888-99aabbccddee 30 +13101234-5566-7777-e888-99aabbccddee 31 +03201234-5566-8777-0888-99aabbccddee 32 +13301234-5566-8777-8888-99aabbccddee 33 +03401234-5566-8777-c888-99aabbccddee 34 +13501234-5566-8777-e888-99aabbccddee 35 +03601234-5566-9777-0888-99aabbccddee 36 +13701234-5566-9777-8888-99aabbccddee 37 +03801234-5566-9777-c888-99aabbccddee 38 +13901234-5566-9777-e888-99aabbccddee 39 +04001234-5566-a777-0888-99aabbccddee 40 +14101234-5566-a777-8888-99aabbccddee 41 +04201234-5566-a777-c888-99aabbccddee 42 +14301234-5566-a777-e888-99aabbccddee 43 +04401234-5566-b777-0888-99aabbccddee 44 +14501234-5566-b777-8888-99aabbccddee 45 +04601234-5566-b777-c888-99aabbccddee 46 +14701234-5566-b777-e888-99aabbccddee 47 +04801234-5566-c777-0888-99aabbccddee 48 +14901234-5566-c777-8888-99aabbccddee 49 +05001234-5566-c777-c888-99aabbccddee 50 +15101234-5566-c777-e888-99aabbccddee 51 +05201234-5566-d777-0888-99aabbccddee 52 +15301234-5566-d777-8888-99aabbccddee 53 +05401234-5566-d777-c888-99aabbccddee 54 +15501234-5566-d777-e888-99aabbccddee 55 +05601234-5566-e777-0888-99aabbccddee 56 +15701234-5566-e777-8888-99aabbccddee 57 +05801234-5566-e777-c888-99aabbccddee 58 +15901234-5566-e777-e888-99aabbccddee 59 +06001234-5566-f777-0888-99aabbccddee 60 +16101234-5566-f777-8888-99aabbccddee 61 +06201234-5566-f777-c888-99aabbccddee 62 +16301234-5566-f777-e888-99aabbccddee 63 select * from t2 order by a; a b -11223344-5566-0777-0888-99aabbccddee 0 -11223344-5566-1777-0888-99aabbccddee 4 -11223344-5566-2777-0888-99aabbccddee 8 -11223344-5566-3777-0888-99aabbccddee 12 -11223344-5566-4777-0888-99aabbccddee 16 -11223344-5566-5777-0888-99aabbccddee 20 -11223344-5566-6777-0888-99aabbccddee 24 -11223344-5566-7777-0888-99aabbccddee 28 -11223344-5566-8777-0888-99aabbccddee 32 -11223344-5566-9777-0888-99aabbccddee 36 -11223344-5566-a777-0888-99aabbccddee 40 -11223344-5566-b777-0888-99aabbccddee 44 -11223344-5566-c777-0888-99aabbccddee 48 -11223344-5566-d777-0888-99aabbccddee 52 -11223344-5566-e777-0888-99aabbccddee 56 -11223344-5566-f777-0888-99aabbccddee 60 -11223344-5566-0777-8888-99aabbccddee 1 -11223344-5566-1777-8888-99aabbccddee 5 -11223344-5566-2777-8888-99aabbccddee 9 -11223344-5566-3777-8888-99aabbccddee 13 -11223344-5566-4777-8888-99aabbccddee 17 -11223344-5566-5777-8888-99aabbccddee 21 -11223344-5566-6777-8888-99aabbccddee 25 -11223344-5566-7777-8888-99aabbccddee 29 -11223344-5566-8777-8888-99aabbccddee 33 -11223344-5566-9777-8888-99aabbccddee 37 -11223344-5566-a777-8888-99aabbccddee 41 -11223344-5566-b777-8888-99aabbccddee 45 -11223344-5566-c777-8888-99aabbccddee 49 -11223344-5566-d777-8888-99aabbccddee 53 -11223344-5566-e777-8888-99aabbccddee 57 -11223344-5566-f777-8888-99aabbccddee 61 -11223344-5566-0777-c888-99aabbccddee 2 -11223344-5566-1777-c888-99aabbccddee 6 -11223344-5566-2777-c888-99aabbccddee 10 -11223344-5566-3777-c888-99aabbccddee 14 -11223344-5566-4777-c888-99aabbccddee 18 -11223344-5566-5777-c888-99aabbccddee 22 -11223344-5566-6777-c888-99aabbccddee 26 -11223344-5566-7777-c888-99aabbccddee 30 -11223344-5566-8777-c888-99aabbccddee 34 -11223344-5566-9777-c888-99aabbccddee 38 -11223344-5566-a777-c888-99aabbccddee 42 -11223344-5566-b777-c888-99aabbccddee 46 -11223344-5566-c777-c888-99aabbccddee 50 -11223344-5566-d777-c888-99aabbccddee 54 -11223344-5566-e777-c888-99aabbccddee 58 -11223344-5566-f777-c888-99aabbccddee 62 -11223344-5566-0777-e888-99aabbccddee 3 -11223344-5566-1777-e888-99aabbccddee 7 -11223344-5566-2777-e888-99aabbccddee 11 -11223344-5566-3777-e888-99aabbccddee 15 -11223344-5566-4777-e888-99aabbccddee 19 -11223344-5566-5777-e888-99aabbccddee 23 -11223344-5566-6777-e888-99aabbccddee 27 -11223344-5566-7777-e888-99aabbccddee 31 -11223344-5566-8777-e888-99aabbccddee 35 -11223344-5566-9777-e888-99aabbccddee 39 -11223344-5566-a777-e888-99aabbccddee 43 -11223344-5566-b777-e888-99aabbccddee 47 -11223344-5566-c777-e888-99aabbccddee 51 -11223344-5566-d777-e888-99aabbccddee 55 -11223344-5566-e777-e888-99aabbccddee 59 -11223344-5566-f777-e888-99aabbccddee 63 +00001234-5566-0777-0888-99aabbccddee 0 +00401234-5566-1777-0888-99aabbccddee 4 +00801234-5566-2777-0888-99aabbccddee 8 +01201234-5566-3777-0888-99aabbccddee 12 +01601234-5566-4777-0888-99aabbccddee 16 +02001234-5566-5777-0888-99aabbccddee 20 +02401234-5566-6777-0888-99aabbccddee 24 +02801234-5566-7777-0888-99aabbccddee 28 +03201234-5566-8777-0888-99aabbccddee 32 +03601234-5566-9777-0888-99aabbccddee 36 +04001234-5566-a777-0888-99aabbccddee 40 +04401234-5566-b777-0888-99aabbccddee 44 +04801234-5566-c777-0888-99aabbccddee 48 +05201234-5566-d777-0888-99aabbccddee 52 +05601234-5566-e777-0888-99aabbccddee 56 +06001234-5566-f777-0888-99aabbccddee 60 +10101234-5566-0777-8888-99aabbccddee 1 +10501234-5566-1777-8888-99aabbccddee 5 +10901234-5566-2777-8888-99aabbccddee 9 +11301234-5566-3777-8888-99aabbccddee 13 +11701234-5566-4777-8888-99aabbccddee 17 +12101234-5566-5777-8888-99aabbccddee 21 +12501234-5566-6777-8888-99aabbccddee 25 +12901234-5566-7777-8888-99aabbccddee 29 +13301234-5566-8777-8888-99aabbccddee 33 +13701234-5566-9777-8888-99aabbccddee 37 +14101234-5566-a777-8888-99aabbccddee 41 +14501234-5566-b777-8888-99aabbccddee 45 +14901234-5566-c777-8888-99aabbccddee 49 +15301234-5566-d777-8888-99aabbccddee 53 +15701234-5566-e777-8888-99aabbccddee 57 +16101234-5566-f777-8888-99aabbccddee 61 +00201234-5566-0777-c888-99aabbccddee 2 +00601234-5566-1777-c888-99aabbccddee 6 +01001234-5566-2777-c888-99aabbccddee 10 +01401234-5566-3777-c888-99aabbccddee 14 +01801234-5566-4777-c888-99aabbccddee 18 +02201234-5566-5777-c888-99aabbccddee 22 +02601234-5566-6777-c888-99aabbccddee 26 +03001234-5566-7777-c888-99aabbccddee 30 +03401234-5566-8777-c888-99aabbccddee 34 +03801234-5566-9777-c888-99aabbccddee 38 +04201234-5566-a777-c888-99aabbccddee 42 +04601234-5566-b777-c888-99aabbccddee 46 +05001234-5566-c777-c888-99aabbccddee 50 +05401234-5566-d777-c888-99aabbccddee 54 +05801234-5566-e777-c888-99aabbccddee 58 +06201234-5566-f777-c888-99aabbccddee 62 +10301234-5566-0777-e888-99aabbccddee 3 +10701234-5566-1777-e888-99aabbccddee 7 +11101234-5566-2777-e888-99aabbccddee 11 +11501234-5566-3777-e888-99aabbccddee 15 +11901234-5566-4777-e888-99aabbccddee 19 +12301234-5566-5777-e888-99aabbccddee 23 +12701234-5566-6777-e888-99aabbccddee 27 +13101234-5566-7777-e888-99aabbccddee 31 +13501234-5566-8777-e888-99aabbccddee 35 +13901234-5566-9777-e888-99aabbccddee 39 +14301234-5566-a777-e888-99aabbccddee 43 +14701234-5566-b777-e888-99aabbccddee 47 +15101234-5566-c777-e888-99aabbccddee 51 +15501234-5566-d777-e888-99aabbccddee 55 +15901234-5566-e777-e888-99aabbccddee 59 +16301234-5566-f777-e888-99aabbccddee 63 show create table t2; Table Create Table t2 CREATE TABLE `t2` ( @@ -294,62 +295,62 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref a a 17 test.t1.a 1 Using where select * from t1 left join t2 on (t1.a=t2.a); a b a b -11223344-5566-0777-0888-99aabbccddee 0 11223344-5566-0777-0888-99aabbccddee 0 -11223344-5566-0777-8888-99aabbccddee 1 11223344-5566-0777-8888-99aabbccddee 1 -11223344-5566-0777-c888-99aabbccddee 2 11223344-5566-0777-c888-99aabbccddee 2 -11223344-5566-0777-e888-99aabbccddee 3 11223344-5566-0777-e888-99aabbccddee 3 -11223344-5566-1777-0888-99aabbccddee 4 11223344-5566-1777-0888-99aabbccddee 4 -11223344-5566-1777-8888-99aabbccddee 5 11223344-5566-1777-8888-99aabbccddee 5 -11223344-5566-1777-c888-99aabbccddee 6 11223344-5566-1777-c888-99aabbccddee 6 -11223344-5566-1777-e888-99aabbccddee 7 11223344-5566-1777-e888-99aabbccddee 7 -11223344-5566-2777-0888-99aabbccddee 8 11223344-5566-2777-0888-99aabbccddee 8 -11223344-5566-2777-8888-99aabbccddee 9 11223344-5566-2777-8888-99aabbccddee 9 -11223344-5566-2777-c888-99aabbccddee 10 11223344-5566-2777-c888-99aabbccddee 10 -11223344-5566-2777-e888-99aabbccddee 11 11223344-5566-2777-e888-99aabbccddee 11 -11223344-5566-3777-0888-99aabbccddee 12 11223344-5566-3777-0888-99aabbccddee 12 -11223344-5566-3777-8888-99aabbccddee 13 11223344-5566-3777-8888-99aabbccddee 13 -11223344-5566-3777-c888-99aabbccddee 14 11223344-5566-3777-c888-99aabbccddee 14 -11223344-5566-3777-e888-99aabbccddee 15 11223344-5566-3777-e888-99aabbccddee 15 -11223344-5566-4777-0888-99aabbccddee 16 11223344-5566-4777-0888-99aabbccddee 16 -11223344-5566-4777-8888-99aabbccddee 17 11223344-5566-4777-8888-99aabbccddee 17 -11223344-5566-4777-c888-99aabbccddee 18 11223344-5566-4777-c888-99aabbccddee 18 -11223344-5566-4777-e888-99aabbccddee 19 11223344-5566-4777-e888-99aabbccddee 19 -11223344-5566-5777-0888-99aabbccddee 20 11223344-5566-5777-0888-99aabbccddee 20 -11223344-5566-5777-8888-99aabbccddee 21 11223344-5566-5777-8888-99aabbccddee 21 -11223344-5566-5777-c888-99aabbccddee 22 11223344-5566-5777-c888-99aabbccddee 22 -11223344-5566-5777-e888-99aabbccddee 23 11223344-5566-5777-e888-99aabbccddee 23 -11223344-5566-6777-0888-99aabbccddee 24 11223344-5566-6777-0888-99aabbccddee 24 -11223344-5566-6777-8888-99aabbccddee 25 11223344-5566-6777-8888-99aabbccddee 25 -11223344-5566-6777-c888-99aabbccddee 26 11223344-5566-6777-c888-99aabbccddee 26 -11223344-5566-6777-e888-99aabbccddee 27 11223344-5566-6777-e888-99aabbccddee 27 -11223344-5566-7777-0888-99aabbccddee 28 11223344-5566-7777-0888-99aabbccddee 28 -11223344-5566-7777-8888-99aabbccddee 29 11223344-5566-7777-8888-99aabbccddee 29 -11223344-5566-7777-c888-99aabbccddee 30 11223344-5566-7777-c888-99aabbccddee 30 -11223344-5566-7777-e888-99aabbccddee 31 11223344-5566-7777-e888-99aabbccddee 31 -11223344-5566-8777-8888-99aabbccddee 33 11223344-5566-8777-8888-99aabbccddee 33 -11223344-5566-8777-c888-99aabbccddee 34 11223344-5566-8777-c888-99aabbccddee 34 -11223344-5566-8777-e888-99aabbccddee 35 11223344-5566-8777-e888-99aabbccddee 35 -11223344-5566-9777-8888-99aabbccddee 37 11223344-5566-9777-8888-99aabbccddee 37 -11223344-5566-9777-c888-99aabbccddee 38 11223344-5566-9777-c888-99aabbccddee 38 -11223344-5566-9777-e888-99aabbccddee 39 11223344-5566-9777-e888-99aabbccddee 39 -11223344-5566-a777-8888-99aabbccddee 41 11223344-5566-a777-8888-99aabbccddee 41 -11223344-5566-a777-c888-99aabbccddee 42 11223344-5566-a777-c888-99aabbccddee 42 -11223344-5566-a777-e888-99aabbccddee 43 11223344-5566-a777-e888-99aabbccddee 43 -11223344-5566-b777-8888-99aabbccddee 45 11223344-5566-b777-8888-99aabbccddee 45 -11223344-5566-b777-c888-99aabbccddee 46 11223344-5566-b777-c888-99aabbccddee 46 -11223344-5566-b777-e888-99aabbccddee 47 11223344-5566-b777-e888-99aabbccddee 47 -11223344-5566-c777-8888-99aabbccddee 49 11223344-5566-c777-8888-99aabbccddee 49 -11223344-5566-c777-c888-99aabbccddee 50 11223344-5566-c777-c888-99aabbccddee 50 -11223344-5566-c777-e888-99aabbccddee 51 11223344-5566-c777-e888-99aabbccddee 51 -11223344-5566-d777-8888-99aabbccddee 53 11223344-5566-d777-8888-99aabbccddee 53 -11223344-5566-d777-c888-99aabbccddee 54 11223344-5566-d777-c888-99aabbccddee 54 -11223344-5566-d777-e888-99aabbccddee 55 11223344-5566-d777-e888-99aabbccddee 55 -11223344-5566-e777-8888-99aabbccddee 57 11223344-5566-e777-8888-99aabbccddee 57 -11223344-5566-e777-c888-99aabbccddee 58 11223344-5566-e777-c888-99aabbccddee 58 -11223344-5566-e777-e888-99aabbccddee 59 11223344-5566-e777-e888-99aabbccddee 59 -11223344-5566-f777-8888-99aabbccddee 61 11223344-5566-f777-8888-99aabbccddee 61 -11223344-5566-f777-c888-99aabbccddee 62 11223344-5566-f777-c888-99aabbccddee 62 -11223344-5566-f777-e888-99aabbccddee 63 11223344-5566-f777-e888-99aabbccddee 63 +00001234-5566-0777-0888-99aabbccddee 0 00001234-5566-0777-0888-99aabbccddee 0 +00201234-5566-0777-c888-99aabbccddee 2 00201234-5566-0777-c888-99aabbccddee 2 +00401234-5566-1777-0888-99aabbccddee 4 00401234-5566-1777-0888-99aabbccddee 4 +00601234-5566-1777-c888-99aabbccddee 6 00601234-5566-1777-c888-99aabbccddee 6 +00801234-5566-2777-0888-99aabbccddee 8 00801234-5566-2777-0888-99aabbccddee 8 +01001234-5566-2777-c888-99aabbccddee 10 01001234-5566-2777-c888-99aabbccddee 10 +01201234-5566-3777-0888-99aabbccddee 12 01201234-5566-3777-0888-99aabbccddee 12 +01401234-5566-3777-c888-99aabbccddee 14 01401234-5566-3777-c888-99aabbccddee 14 +01601234-5566-4777-0888-99aabbccddee 16 01601234-5566-4777-0888-99aabbccddee 16 +01801234-5566-4777-c888-99aabbccddee 18 01801234-5566-4777-c888-99aabbccddee 18 +02001234-5566-5777-0888-99aabbccddee 20 02001234-5566-5777-0888-99aabbccddee 20 +02201234-5566-5777-c888-99aabbccddee 22 02201234-5566-5777-c888-99aabbccddee 22 +02401234-5566-6777-0888-99aabbccddee 24 02401234-5566-6777-0888-99aabbccddee 24 +02601234-5566-6777-c888-99aabbccddee 26 02601234-5566-6777-c888-99aabbccddee 26 +02801234-5566-7777-0888-99aabbccddee 28 02801234-5566-7777-0888-99aabbccddee 28 +03001234-5566-7777-c888-99aabbccddee 30 03001234-5566-7777-c888-99aabbccddee 30 +03401234-5566-8777-c888-99aabbccddee 34 03401234-5566-8777-c888-99aabbccddee 34 +03801234-5566-9777-c888-99aabbccddee 38 03801234-5566-9777-c888-99aabbccddee 38 +04201234-5566-a777-c888-99aabbccddee 42 04201234-5566-a777-c888-99aabbccddee 42 +04601234-5566-b777-c888-99aabbccddee 46 04601234-5566-b777-c888-99aabbccddee 46 +05001234-5566-c777-c888-99aabbccddee 50 05001234-5566-c777-c888-99aabbccddee 50 +05401234-5566-d777-c888-99aabbccddee 54 05401234-5566-d777-c888-99aabbccddee 54 +05801234-5566-e777-c888-99aabbccddee 58 05801234-5566-e777-c888-99aabbccddee 58 +06201234-5566-f777-c888-99aabbccddee 62 06201234-5566-f777-c888-99aabbccddee 62 +10101234-5566-0777-8888-99aabbccddee 1 10101234-5566-0777-8888-99aabbccddee 1 +10301234-5566-0777-e888-99aabbccddee 3 10301234-5566-0777-e888-99aabbccddee 3 +10501234-5566-1777-8888-99aabbccddee 5 10501234-5566-1777-8888-99aabbccddee 5 +10701234-5566-1777-e888-99aabbccddee 7 10701234-5566-1777-e888-99aabbccddee 7 +10901234-5566-2777-8888-99aabbccddee 9 10901234-5566-2777-8888-99aabbccddee 9 +11101234-5566-2777-e888-99aabbccddee 11 11101234-5566-2777-e888-99aabbccddee 11 +11301234-5566-3777-8888-99aabbccddee 13 11301234-5566-3777-8888-99aabbccddee 13 +11501234-5566-3777-e888-99aabbccddee 15 11501234-5566-3777-e888-99aabbccddee 15 +11701234-5566-4777-8888-99aabbccddee 17 11701234-5566-4777-8888-99aabbccddee 17 +11901234-5566-4777-e888-99aabbccddee 19 11901234-5566-4777-e888-99aabbccddee 19 +12101234-5566-5777-8888-99aabbccddee 21 12101234-5566-5777-8888-99aabbccddee 21 +12301234-5566-5777-e888-99aabbccddee 23 12301234-5566-5777-e888-99aabbccddee 23 +12501234-5566-6777-8888-99aabbccddee 25 12501234-5566-6777-8888-99aabbccddee 25 +12701234-5566-6777-e888-99aabbccddee 27 12701234-5566-6777-e888-99aabbccddee 27 +12901234-5566-7777-8888-99aabbccddee 29 12901234-5566-7777-8888-99aabbccddee 29 +13101234-5566-7777-e888-99aabbccddee 31 13101234-5566-7777-e888-99aabbccddee 31 +13301234-5566-8777-8888-99aabbccddee 33 13301234-5566-8777-8888-99aabbccddee 33 +13501234-5566-8777-e888-99aabbccddee 35 13501234-5566-8777-e888-99aabbccddee 35 +13701234-5566-9777-8888-99aabbccddee 37 13701234-5566-9777-8888-99aabbccddee 37 +13901234-5566-9777-e888-99aabbccddee 39 13901234-5566-9777-e888-99aabbccddee 39 +14101234-5566-a777-8888-99aabbccddee 41 14101234-5566-a777-8888-99aabbccddee 41 +14301234-5566-a777-e888-99aabbccddee 43 14301234-5566-a777-e888-99aabbccddee 43 +14501234-5566-b777-8888-99aabbccddee 45 14501234-5566-b777-8888-99aabbccddee 45 +14701234-5566-b777-e888-99aabbccddee 47 14701234-5566-b777-e888-99aabbccddee 47 +14901234-5566-c777-8888-99aabbccddee 49 14901234-5566-c777-8888-99aabbccddee 49 +15101234-5566-c777-e888-99aabbccddee 51 15101234-5566-c777-e888-99aabbccddee 51 +15301234-5566-d777-8888-99aabbccddee 53 15301234-5566-d777-8888-99aabbccddee 53 +15501234-5566-d777-e888-99aabbccddee 55 15501234-5566-d777-e888-99aabbccddee 55 +15701234-5566-e777-8888-99aabbccddee 57 15701234-5566-e777-8888-99aabbccddee 57 +15901234-5566-e777-e888-99aabbccddee 59 15901234-5566-e777-e888-99aabbccddee 59 +16101234-5566-f777-8888-99aabbccddee 61 16101234-5566-f777-8888-99aabbccddee 61 +16301234-5566-f777-e888-99aabbccddee 63 16301234-5566-f777-e888-99aabbccddee 63 NULL 32 NULL NULL NULL 36 NULL NULL NULL 40 NULL NULL @@ -364,62 +365,62 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref a a 17 test.t1.a 1 Using where select * from t1 left join t2 on (t1.a<=>t2.a); a b a b -11223344-5566-0777-0888-99aabbccddee 0 11223344-5566-0777-0888-99aabbccddee 0 -11223344-5566-0777-8888-99aabbccddee 1 11223344-5566-0777-8888-99aabbccddee 1 -11223344-5566-0777-c888-99aabbccddee 2 11223344-5566-0777-c888-99aabbccddee 2 -11223344-5566-0777-e888-99aabbccddee 3 11223344-5566-0777-e888-99aabbccddee 3 -11223344-5566-1777-0888-99aabbccddee 4 11223344-5566-1777-0888-99aabbccddee 4 -11223344-5566-1777-8888-99aabbccddee 5 11223344-5566-1777-8888-99aabbccddee 5 -11223344-5566-1777-c888-99aabbccddee 6 11223344-5566-1777-c888-99aabbccddee 6 -11223344-5566-1777-e888-99aabbccddee 7 11223344-5566-1777-e888-99aabbccddee 7 -11223344-5566-2777-0888-99aabbccddee 8 11223344-5566-2777-0888-99aabbccddee 8 -11223344-5566-2777-8888-99aabbccddee 9 11223344-5566-2777-8888-99aabbccddee 9 -11223344-5566-2777-c888-99aabbccddee 10 11223344-5566-2777-c888-99aabbccddee 10 -11223344-5566-2777-e888-99aabbccddee 11 11223344-5566-2777-e888-99aabbccddee 11 -11223344-5566-3777-0888-99aabbccddee 12 11223344-5566-3777-0888-99aabbccddee 12 -11223344-5566-3777-8888-99aabbccddee 13 11223344-5566-3777-8888-99aabbccddee 13 -11223344-5566-3777-c888-99aabbccddee 14 11223344-5566-3777-c888-99aabbccddee 14 -11223344-5566-3777-e888-99aabbccddee 15 11223344-5566-3777-e888-99aabbccddee 15 -11223344-5566-4777-0888-99aabbccddee 16 11223344-5566-4777-0888-99aabbccddee 16 -11223344-5566-4777-8888-99aabbccddee 17 11223344-5566-4777-8888-99aabbccddee 17 -11223344-5566-4777-c888-99aabbccddee 18 11223344-5566-4777-c888-99aabbccddee 18 -11223344-5566-4777-e888-99aabbccddee 19 11223344-5566-4777-e888-99aabbccddee 19 -11223344-5566-5777-0888-99aabbccddee 20 11223344-5566-5777-0888-99aabbccddee 20 -11223344-5566-5777-8888-99aabbccddee 21 11223344-5566-5777-8888-99aabbccddee 21 -11223344-5566-5777-c888-99aabbccddee 22 11223344-5566-5777-c888-99aabbccddee 22 -11223344-5566-5777-e888-99aabbccddee 23 11223344-5566-5777-e888-99aabbccddee 23 -11223344-5566-6777-0888-99aabbccddee 24 11223344-5566-6777-0888-99aabbccddee 24 -11223344-5566-6777-8888-99aabbccddee 25 11223344-5566-6777-8888-99aabbccddee 25 -11223344-5566-6777-c888-99aabbccddee 26 11223344-5566-6777-c888-99aabbccddee 26 -11223344-5566-6777-e888-99aabbccddee 27 11223344-5566-6777-e888-99aabbccddee 27 -11223344-5566-7777-0888-99aabbccddee 28 11223344-5566-7777-0888-99aabbccddee 28 -11223344-5566-7777-8888-99aabbccddee 29 11223344-5566-7777-8888-99aabbccddee 29 -11223344-5566-7777-c888-99aabbccddee 30 11223344-5566-7777-c888-99aabbccddee 30 -11223344-5566-7777-e888-99aabbccddee 31 11223344-5566-7777-e888-99aabbccddee 31 -11223344-5566-8777-8888-99aabbccddee 33 11223344-5566-8777-8888-99aabbccddee 33 -11223344-5566-8777-c888-99aabbccddee 34 11223344-5566-8777-c888-99aabbccddee 34 -11223344-5566-8777-e888-99aabbccddee 35 11223344-5566-8777-e888-99aabbccddee 35 -11223344-5566-9777-8888-99aabbccddee 37 11223344-5566-9777-8888-99aabbccddee 37 -11223344-5566-9777-c888-99aabbccddee 38 11223344-5566-9777-c888-99aabbccddee 38 -11223344-5566-9777-e888-99aabbccddee 39 11223344-5566-9777-e888-99aabbccddee 39 -11223344-5566-a777-8888-99aabbccddee 41 11223344-5566-a777-8888-99aabbccddee 41 -11223344-5566-a777-c888-99aabbccddee 42 11223344-5566-a777-c888-99aabbccddee 42 -11223344-5566-a777-e888-99aabbccddee 43 11223344-5566-a777-e888-99aabbccddee 43 -11223344-5566-b777-8888-99aabbccddee 45 11223344-5566-b777-8888-99aabbccddee 45 -11223344-5566-b777-c888-99aabbccddee 46 11223344-5566-b777-c888-99aabbccddee 46 -11223344-5566-b777-e888-99aabbccddee 47 11223344-5566-b777-e888-99aabbccddee 47 -11223344-5566-c777-8888-99aabbccddee 49 11223344-5566-c777-8888-99aabbccddee 49 -11223344-5566-c777-c888-99aabbccddee 50 11223344-5566-c777-c888-99aabbccddee 50 -11223344-5566-c777-e888-99aabbccddee 51 11223344-5566-c777-e888-99aabbccddee 51 -11223344-5566-d777-8888-99aabbccddee 53 11223344-5566-d777-8888-99aabbccddee 53 -11223344-5566-d777-c888-99aabbccddee 54 11223344-5566-d777-c888-99aabbccddee 54 -11223344-5566-d777-e888-99aabbccddee 55 11223344-5566-d777-e888-99aabbccddee 55 -11223344-5566-e777-8888-99aabbccddee 57 11223344-5566-e777-8888-99aabbccddee 57 -11223344-5566-e777-c888-99aabbccddee 58 11223344-5566-e777-c888-99aabbccddee 58 -11223344-5566-e777-e888-99aabbccddee 59 11223344-5566-e777-e888-99aabbccddee 59 -11223344-5566-f777-8888-99aabbccddee 61 11223344-5566-f777-8888-99aabbccddee 61 -11223344-5566-f777-c888-99aabbccddee 62 11223344-5566-f777-c888-99aabbccddee 62 -11223344-5566-f777-e888-99aabbccddee 63 11223344-5566-f777-e888-99aabbccddee 63 +00001234-5566-0777-0888-99aabbccddee 0 00001234-5566-0777-0888-99aabbccddee 0 +00201234-5566-0777-c888-99aabbccddee 2 00201234-5566-0777-c888-99aabbccddee 2 +00401234-5566-1777-0888-99aabbccddee 4 00401234-5566-1777-0888-99aabbccddee 4 +00601234-5566-1777-c888-99aabbccddee 6 00601234-5566-1777-c888-99aabbccddee 6 +00801234-5566-2777-0888-99aabbccddee 8 00801234-5566-2777-0888-99aabbccddee 8 +01001234-5566-2777-c888-99aabbccddee 10 01001234-5566-2777-c888-99aabbccddee 10 +01201234-5566-3777-0888-99aabbccddee 12 01201234-5566-3777-0888-99aabbccddee 12 +01401234-5566-3777-c888-99aabbccddee 14 01401234-5566-3777-c888-99aabbccddee 14 +01601234-5566-4777-0888-99aabbccddee 16 01601234-5566-4777-0888-99aabbccddee 16 +01801234-5566-4777-c888-99aabbccddee 18 01801234-5566-4777-c888-99aabbccddee 18 +02001234-5566-5777-0888-99aabbccddee 20 02001234-5566-5777-0888-99aabbccddee 20 +02201234-5566-5777-c888-99aabbccddee 22 02201234-5566-5777-c888-99aabbccddee 22 +02401234-5566-6777-0888-99aabbccddee 24 02401234-5566-6777-0888-99aabbccddee 24 +02601234-5566-6777-c888-99aabbccddee 26 02601234-5566-6777-c888-99aabbccddee 26 +02801234-5566-7777-0888-99aabbccddee 28 02801234-5566-7777-0888-99aabbccddee 28 +03001234-5566-7777-c888-99aabbccddee 30 03001234-5566-7777-c888-99aabbccddee 30 +03401234-5566-8777-c888-99aabbccddee 34 03401234-5566-8777-c888-99aabbccddee 34 +03801234-5566-9777-c888-99aabbccddee 38 03801234-5566-9777-c888-99aabbccddee 38 +04201234-5566-a777-c888-99aabbccddee 42 04201234-5566-a777-c888-99aabbccddee 42 +04601234-5566-b777-c888-99aabbccddee 46 04601234-5566-b777-c888-99aabbccddee 46 +05001234-5566-c777-c888-99aabbccddee 50 05001234-5566-c777-c888-99aabbccddee 50 +05401234-5566-d777-c888-99aabbccddee 54 05401234-5566-d777-c888-99aabbccddee 54 +05801234-5566-e777-c888-99aabbccddee 58 05801234-5566-e777-c888-99aabbccddee 58 +06201234-5566-f777-c888-99aabbccddee 62 06201234-5566-f777-c888-99aabbccddee 62 +10101234-5566-0777-8888-99aabbccddee 1 10101234-5566-0777-8888-99aabbccddee 1 +10301234-5566-0777-e888-99aabbccddee 3 10301234-5566-0777-e888-99aabbccddee 3 +10501234-5566-1777-8888-99aabbccddee 5 10501234-5566-1777-8888-99aabbccddee 5 +10701234-5566-1777-e888-99aabbccddee 7 10701234-5566-1777-e888-99aabbccddee 7 +10901234-5566-2777-8888-99aabbccddee 9 10901234-5566-2777-8888-99aabbccddee 9 +11101234-5566-2777-e888-99aabbccddee 11 11101234-5566-2777-e888-99aabbccddee 11 +11301234-5566-3777-8888-99aabbccddee 13 11301234-5566-3777-8888-99aabbccddee 13 +11501234-5566-3777-e888-99aabbccddee 15 11501234-5566-3777-e888-99aabbccddee 15 +11701234-5566-4777-8888-99aabbccddee 17 11701234-5566-4777-8888-99aabbccddee 17 +11901234-5566-4777-e888-99aabbccddee 19 11901234-5566-4777-e888-99aabbccddee 19 +12101234-5566-5777-8888-99aabbccddee 21 12101234-5566-5777-8888-99aabbccddee 21 +12301234-5566-5777-e888-99aabbccddee 23 12301234-5566-5777-e888-99aabbccddee 23 +12501234-5566-6777-8888-99aabbccddee 25 12501234-5566-6777-8888-99aabbccddee 25 +12701234-5566-6777-e888-99aabbccddee 27 12701234-5566-6777-e888-99aabbccddee 27 +12901234-5566-7777-8888-99aabbccddee 29 12901234-5566-7777-8888-99aabbccddee 29 +13101234-5566-7777-e888-99aabbccddee 31 13101234-5566-7777-e888-99aabbccddee 31 +13301234-5566-8777-8888-99aabbccddee 33 13301234-5566-8777-8888-99aabbccddee 33 +13501234-5566-8777-e888-99aabbccddee 35 13501234-5566-8777-e888-99aabbccddee 35 +13701234-5566-9777-8888-99aabbccddee 37 13701234-5566-9777-8888-99aabbccddee 37 +13901234-5566-9777-e888-99aabbccddee 39 13901234-5566-9777-e888-99aabbccddee 39 +14101234-5566-a777-8888-99aabbccddee 41 14101234-5566-a777-8888-99aabbccddee 41 +14301234-5566-a777-e888-99aabbccddee 43 14301234-5566-a777-e888-99aabbccddee 43 +14501234-5566-b777-8888-99aabbccddee 45 14501234-5566-b777-8888-99aabbccddee 45 +14701234-5566-b777-e888-99aabbccddee 47 14701234-5566-b777-e888-99aabbccddee 47 +14901234-5566-c777-8888-99aabbccddee 49 14901234-5566-c777-8888-99aabbccddee 49 +15101234-5566-c777-e888-99aabbccddee 51 15101234-5566-c777-e888-99aabbccddee 51 +15301234-5566-d777-8888-99aabbccddee 53 15301234-5566-d777-8888-99aabbccddee 53 +15501234-5566-d777-e888-99aabbccddee 55 15501234-5566-d777-e888-99aabbccddee 55 +15701234-5566-e777-8888-99aabbccddee 57 15701234-5566-e777-8888-99aabbccddee 57 +15901234-5566-e777-e888-99aabbccddee 59 15901234-5566-e777-e888-99aabbccddee 59 +16101234-5566-f777-8888-99aabbccddee 61 16101234-5566-f777-8888-99aabbccddee 61 +16301234-5566-f777-e888-99aabbccddee 63 16301234-5566-f777-e888-99aabbccddee 63 NULL 32 NULL NULL NULL 36 NULL NULL NULL 40 NULL NULL @@ -434,319 +435,319 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a a 17 test.t2.a 1 Using where select * from t2 left join t1 on (t1.a=t2.a); a b a b -11223344-5566-0777-0888-99aabbccddee 0 11223344-5566-0777-0888-99aabbccddee 0 -11223344-5566-0777-8888-99aabbccddee 1 11223344-5566-0777-8888-99aabbccddee 1 -11223344-5566-0777-c888-99aabbccddee 2 11223344-5566-0777-c888-99aabbccddee 2 -11223344-5566-0777-e888-99aabbccddee 3 11223344-5566-0777-e888-99aabbccddee 3 -11223344-5566-1777-0888-99aabbccddee 4 11223344-5566-1777-0888-99aabbccddee 4 -11223344-5566-1777-8888-99aabbccddee 5 11223344-5566-1777-8888-99aabbccddee 5 -11223344-5566-1777-c888-99aabbccddee 6 11223344-5566-1777-c888-99aabbccddee 6 -11223344-5566-1777-e888-99aabbccddee 7 11223344-5566-1777-e888-99aabbccddee 7 -11223344-5566-2777-0888-99aabbccddee 8 11223344-5566-2777-0888-99aabbccddee 8 -11223344-5566-2777-8888-99aabbccddee 9 11223344-5566-2777-8888-99aabbccddee 9 -11223344-5566-2777-c888-99aabbccddee 10 11223344-5566-2777-c888-99aabbccddee 10 -11223344-5566-2777-e888-99aabbccddee 11 11223344-5566-2777-e888-99aabbccddee 11 -11223344-5566-3777-0888-99aabbccddee 12 11223344-5566-3777-0888-99aabbccddee 12 -11223344-5566-3777-8888-99aabbccddee 13 11223344-5566-3777-8888-99aabbccddee 13 -11223344-5566-3777-c888-99aabbccddee 14 11223344-5566-3777-c888-99aabbccddee 14 -11223344-5566-3777-e888-99aabbccddee 15 11223344-5566-3777-e888-99aabbccddee 15 -11223344-5566-4777-0888-99aabbccddee 16 11223344-5566-4777-0888-99aabbccddee 16 -11223344-5566-4777-8888-99aabbccddee 17 11223344-5566-4777-8888-99aabbccddee 17 -11223344-5566-4777-c888-99aabbccddee 18 11223344-5566-4777-c888-99aabbccddee 18 -11223344-5566-4777-e888-99aabbccddee 19 11223344-5566-4777-e888-99aabbccddee 19 -11223344-5566-5777-0888-99aabbccddee 20 11223344-5566-5777-0888-99aabbccddee 20 -11223344-5566-5777-8888-99aabbccddee 21 11223344-5566-5777-8888-99aabbccddee 21 -11223344-5566-5777-c888-99aabbccddee 22 11223344-5566-5777-c888-99aabbccddee 22 -11223344-5566-5777-e888-99aabbccddee 23 11223344-5566-5777-e888-99aabbccddee 23 -11223344-5566-6777-0888-99aabbccddee 24 11223344-5566-6777-0888-99aabbccddee 24 -11223344-5566-6777-8888-99aabbccddee 25 11223344-5566-6777-8888-99aabbccddee 25 -11223344-5566-6777-c888-99aabbccddee 26 11223344-5566-6777-c888-99aabbccddee 26 -11223344-5566-6777-e888-99aabbccddee 27 11223344-5566-6777-e888-99aabbccddee 27 -11223344-5566-7777-0888-99aabbccddee 28 11223344-5566-7777-0888-99aabbccddee 28 -11223344-5566-7777-8888-99aabbccddee 29 11223344-5566-7777-8888-99aabbccddee 29 -11223344-5566-7777-c888-99aabbccddee 30 11223344-5566-7777-c888-99aabbccddee 30 -11223344-5566-7777-e888-99aabbccddee 31 11223344-5566-7777-e888-99aabbccddee 31 -11223344-5566-8777-0888-99aabbccddee 32 NULL NULL -11223344-5566-8777-8888-99aabbccddee 33 11223344-5566-8777-8888-99aabbccddee 33 -11223344-5566-8777-c888-99aabbccddee 34 11223344-5566-8777-c888-99aabbccddee 34 -11223344-5566-8777-e888-99aabbccddee 35 11223344-5566-8777-e888-99aabbccddee 35 -11223344-5566-9777-0888-99aabbccddee 36 NULL NULL -11223344-5566-9777-8888-99aabbccddee 37 11223344-5566-9777-8888-99aabbccddee 37 -11223344-5566-9777-c888-99aabbccddee 38 11223344-5566-9777-c888-99aabbccddee 38 -11223344-5566-9777-e888-99aabbccddee 39 11223344-5566-9777-e888-99aabbccddee 39 -11223344-5566-a777-0888-99aabbccddee 40 NULL NULL -11223344-5566-a777-8888-99aabbccddee 41 11223344-5566-a777-8888-99aabbccddee 41 -11223344-5566-a777-c888-99aabbccddee 42 11223344-5566-a777-c888-99aabbccddee 42 -11223344-5566-a777-e888-99aabbccddee 43 11223344-5566-a777-e888-99aabbccddee 43 -11223344-5566-b777-0888-99aabbccddee 44 NULL NULL -11223344-5566-b777-8888-99aabbccddee 45 11223344-5566-b777-8888-99aabbccddee 45 -11223344-5566-b777-c888-99aabbccddee 46 11223344-5566-b777-c888-99aabbccddee 46 -11223344-5566-b777-e888-99aabbccddee 47 11223344-5566-b777-e888-99aabbccddee 47 -11223344-5566-c777-0888-99aabbccddee 48 NULL NULL -11223344-5566-c777-8888-99aabbccddee 49 11223344-5566-c777-8888-99aabbccddee 49 -11223344-5566-c777-c888-99aabbccddee 50 11223344-5566-c777-c888-99aabbccddee 50 -11223344-5566-c777-e888-99aabbccddee 51 11223344-5566-c777-e888-99aabbccddee 51 -11223344-5566-d777-0888-99aabbccddee 52 NULL NULL -11223344-5566-d777-8888-99aabbccddee 53 11223344-5566-d777-8888-99aabbccddee 53 -11223344-5566-d777-c888-99aabbccddee 54 11223344-5566-d777-c888-99aabbccddee 54 -11223344-5566-d777-e888-99aabbccddee 55 11223344-5566-d777-e888-99aabbccddee 55 -11223344-5566-e777-0888-99aabbccddee 56 NULL NULL -11223344-5566-e777-8888-99aabbccddee 57 11223344-5566-e777-8888-99aabbccddee 57 -11223344-5566-e777-c888-99aabbccddee 58 11223344-5566-e777-c888-99aabbccddee 58 -11223344-5566-e777-e888-99aabbccddee 59 11223344-5566-e777-e888-99aabbccddee 59 -11223344-5566-f777-0888-99aabbccddee 60 NULL NULL -11223344-5566-f777-8888-99aabbccddee 61 11223344-5566-f777-8888-99aabbccddee 61 -11223344-5566-f777-c888-99aabbccddee 62 11223344-5566-f777-c888-99aabbccddee 62 -11223344-5566-f777-e888-99aabbccddee 63 11223344-5566-f777-e888-99aabbccddee 63 +00001234-5566-0777-0888-99aabbccddee 0 00001234-5566-0777-0888-99aabbccddee 0 +00201234-5566-0777-c888-99aabbccddee 2 00201234-5566-0777-c888-99aabbccddee 2 +00401234-5566-1777-0888-99aabbccddee 4 00401234-5566-1777-0888-99aabbccddee 4 +00601234-5566-1777-c888-99aabbccddee 6 00601234-5566-1777-c888-99aabbccddee 6 +00801234-5566-2777-0888-99aabbccddee 8 00801234-5566-2777-0888-99aabbccddee 8 +01001234-5566-2777-c888-99aabbccddee 10 01001234-5566-2777-c888-99aabbccddee 10 +01201234-5566-3777-0888-99aabbccddee 12 01201234-5566-3777-0888-99aabbccddee 12 +01401234-5566-3777-c888-99aabbccddee 14 01401234-5566-3777-c888-99aabbccddee 14 +01601234-5566-4777-0888-99aabbccddee 16 01601234-5566-4777-0888-99aabbccddee 16 +01801234-5566-4777-c888-99aabbccddee 18 01801234-5566-4777-c888-99aabbccddee 18 +02001234-5566-5777-0888-99aabbccddee 20 02001234-5566-5777-0888-99aabbccddee 20 +02201234-5566-5777-c888-99aabbccddee 22 02201234-5566-5777-c888-99aabbccddee 22 +02401234-5566-6777-0888-99aabbccddee 24 02401234-5566-6777-0888-99aabbccddee 24 +02601234-5566-6777-c888-99aabbccddee 26 02601234-5566-6777-c888-99aabbccddee 26 +02801234-5566-7777-0888-99aabbccddee 28 02801234-5566-7777-0888-99aabbccddee 28 +03001234-5566-7777-c888-99aabbccddee 30 03001234-5566-7777-c888-99aabbccddee 30 +03201234-5566-8777-0888-99aabbccddee 32 NULL NULL +03401234-5566-8777-c888-99aabbccddee 34 03401234-5566-8777-c888-99aabbccddee 34 +03601234-5566-9777-0888-99aabbccddee 36 NULL NULL +03801234-5566-9777-c888-99aabbccddee 38 03801234-5566-9777-c888-99aabbccddee 38 +04001234-5566-a777-0888-99aabbccddee 40 NULL NULL +04201234-5566-a777-c888-99aabbccddee 42 04201234-5566-a777-c888-99aabbccddee 42 +04401234-5566-b777-0888-99aabbccddee 44 NULL NULL +04601234-5566-b777-c888-99aabbccddee 46 04601234-5566-b777-c888-99aabbccddee 46 +04801234-5566-c777-0888-99aabbccddee 48 NULL NULL +05001234-5566-c777-c888-99aabbccddee 50 05001234-5566-c777-c888-99aabbccddee 50 +05201234-5566-d777-0888-99aabbccddee 52 NULL NULL +05401234-5566-d777-c888-99aabbccddee 54 05401234-5566-d777-c888-99aabbccddee 54 +05601234-5566-e777-0888-99aabbccddee 56 NULL NULL +05801234-5566-e777-c888-99aabbccddee 58 05801234-5566-e777-c888-99aabbccddee 58 +06001234-5566-f777-0888-99aabbccddee 60 NULL NULL +06201234-5566-f777-c888-99aabbccddee 62 06201234-5566-f777-c888-99aabbccddee 62 +10101234-5566-0777-8888-99aabbccddee 1 10101234-5566-0777-8888-99aabbccddee 1 +10301234-5566-0777-e888-99aabbccddee 3 10301234-5566-0777-e888-99aabbccddee 3 +10501234-5566-1777-8888-99aabbccddee 5 10501234-5566-1777-8888-99aabbccddee 5 +10701234-5566-1777-e888-99aabbccddee 7 10701234-5566-1777-e888-99aabbccddee 7 +10901234-5566-2777-8888-99aabbccddee 9 10901234-5566-2777-8888-99aabbccddee 9 +11101234-5566-2777-e888-99aabbccddee 11 11101234-5566-2777-e888-99aabbccddee 11 +11301234-5566-3777-8888-99aabbccddee 13 11301234-5566-3777-8888-99aabbccddee 13 +11501234-5566-3777-e888-99aabbccddee 15 11501234-5566-3777-e888-99aabbccddee 15 +11701234-5566-4777-8888-99aabbccddee 17 11701234-5566-4777-8888-99aabbccddee 17 +11901234-5566-4777-e888-99aabbccddee 19 11901234-5566-4777-e888-99aabbccddee 19 +12101234-5566-5777-8888-99aabbccddee 21 12101234-5566-5777-8888-99aabbccddee 21 +12301234-5566-5777-e888-99aabbccddee 23 12301234-5566-5777-e888-99aabbccddee 23 +12501234-5566-6777-8888-99aabbccddee 25 12501234-5566-6777-8888-99aabbccddee 25 +12701234-5566-6777-e888-99aabbccddee 27 12701234-5566-6777-e888-99aabbccddee 27 +12901234-5566-7777-8888-99aabbccddee 29 12901234-5566-7777-8888-99aabbccddee 29 +13101234-5566-7777-e888-99aabbccddee 31 13101234-5566-7777-e888-99aabbccddee 31 +13301234-5566-8777-8888-99aabbccddee 33 13301234-5566-8777-8888-99aabbccddee 33 +13501234-5566-8777-e888-99aabbccddee 35 13501234-5566-8777-e888-99aabbccddee 35 +13701234-5566-9777-8888-99aabbccddee 37 13701234-5566-9777-8888-99aabbccddee 37 +13901234-5566-9777-e888-99aabbccddee 39 13901234-5566-9777-e888-99aabbccddee 39 +14101234-5566-a777-8888-99aabbccddee 41 14101234-5566-a777-8888-99aabbccddee 41 +14301234-5566-a777-e888-99aabbccddee 43 14301234-5566-a777-e888-99aabbccddee 43 +14501234-5566-b777-8888-99aabbccddee 45 14501234-5566-b777-8888-99aabbccddee 45 +14701234-5566-b777-e888-99aabbccddee 47 14701234-5566-b777-e888-99aabbccddee 47 +14901234-5566-c777-8888-99aabbccddee 49 14901234-5566-c777-8888-99aabbccddee 49 +15101234-5566-c777-e888-99aabbccddee 51 15101234-5566-c777-e888-99aabbccddee 51 +15301234-5566-d777-8888-99aabbccddee 53 15301234-5566-d777-8888-99aabbccddee 53 +15501234-5566-d777-e888-99aabbccddee 55 15501234-5566-d777-e888-99aabbccddee 55 +15701234-5566-e777-8888-99aabbccddee 57 15701234-5566-e777-8888-99aabbccddee 57 +15901234-5566-e777-e888-99aabbccddee 59 15901234-5566-e777-e888-99aabbccddee 59 +16101234-5566-f777-8888-99aabbccddee 61 16101234-5566-f777-8888-99aabbccddee 61 +16301234-5566-f777-e888-99aabbccddee 63 16301234-5566-f777-e888-99aabbccddee 63 explain select * from t2 left join t1 on (t1.a<=>t2.a); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 64 1 SIMPLE t1 ref a a 17 test.t2.a 1 Using where select * from t2 left join t1 on (t1.a<=>t2.a); a b a b -11223344-5566-0777-0888-99aabbccddee 0 11223344-5566-0777-0888-99aabbccddee 0 -11223344-5566-0777-8888-99aabbccddee 1 11223344-5566-0777-8888-99aabbccddee 1 -11223344-5566-0777-c888-99aabbccddee 2 11223344-5566-0777-c888-99aabbccddee 2 -11223344-5566-0777-e888-99aabbccddee 3 11223344-5566-0777-e888-99aabbccddee 3 -11223344-5566-1777-0888-99aabbccddee 4 11223344-5566-1777-0888-99aabbccddee 4 -11223344-5566-1777-8888-99aabbccddee 5 11223344-5566-1777-8888-99aabbccddee 5 -11223344-5566-1777-c888-99aabbccddee 6 11223344-5566-1777-c888-99aabbccddee 6 -11223344-5566-1777-e888-99aabbccddee 7 11223344-5566-1777-e888-99aabbccddee 7 -11223344-5566-2777-0888-99aabbccddee 8 11223344-5566-2777-0888-99aabbccddee 8 -11223344-5566-2777-8888-99aabbccddee 9 11223344-5566-2777-8888-99aabbccddee 9 -11223344-5566-2777-c888-99aabbccddee 10 11223344-5566-2777-c888-99aabbccddee 10 -11223344-5566-2777-e888-99aabbccddee 11 11223344-5566-2777-e888-99aabbccddee 11 -11223344-5566-3777-0888-99aabbccddee 12 11223344-5566-3777-0888-99aabbccddee 12 -11223344-5566-3777-8888-99aabbccddee 13 11223344-5566-3777-8888-99aabbccddee 13 -11223344-5566-3777-c888-99aabbccddee 14 11223344-5566-3777-c888-99aabbccddee 14 -11223344-5566-3777-e888-99aabbccddee 15 11223344-5566-3777-e888-99aabbccddee 15 -11223344-5566-4777-0888-99aabbccddee 16 11223344-5566-4777-0888-99aabbccddee 16 -11223344-5566-4777-8888-99aabbccddee 17 11223344-5566-4777-8888-99aabbccddee 17 -11223344-5566-4777-c888-99aabbccddee 18 11223344-5566-4777-c888-99aabbccddee 18 -11223344-5566-4777-e888-99aabbccddee 19 11223344-5566-4777-e888-99aabbccddee 19 -11223344-5566-5777-0888-99aabbccddee 20 11223344-5566-5777-0888-99aabbccddee 20 -11223344-5566-5777-8888-99aabbccddee 21 11223344-5566-5777-8888-99aabbccddee 21 -11223344-5566-5777-c888-99aabbccddee 22 11223344-5566-5777-c888-99aabbccddee 22 -11223344-5566-5777-e888-99aabbccddee 23 11223344-5566-5777-e888-99aabbccddee 23 -11223344-5566-6777-0888-99aabbccddee 24 11223344-5566-6777-0888-99aabbccddee 24 -11223344-5566-6777-8888-99aabbccddee 25 11223344-5566-6777-8888-99aabbccddee 25 -11223344-5566-6777-c888-99aabbccddee 26 11223344-5566-6777-c888-99aabbccddee 26 -11223344-5566-6777-e888-99aabbccddee 27 11223344-5566-6777-e888-99aabbccddee 27 -11223344-5566-7777-0888-99aabbccddee 28 11223344-5566-7777-0888-99aabbccddee 28 -11223344-5566-7777-8888-99aabbccddee 29 11223344-5566-7777-8888-99aabbccddee 29 -11223344-5566-7777-c888-99aabbccddee 30 11223344-5566-7777-c888-99aabbccddee 30 -11223344-5566-7777-e888-99aabbccddee 31 11223344-5566-7777-e888-99aabbccddee 31 -11223344-5566-8777-0888-99aabbccddee 32 NULL 32 -11223344-5566-8777-0888-99aabbccddee 32 NULL 36 -11223344-5566-8777-0888-99aabbccddee 32 NULL 40 -11223344-5566-8777-0888-99aabbccddee 32 NULL 44 -11223344-5566-8777-0888-99aabbccddee 32 NULL 48 -11223344-5566-8777-0888-99aabbccddee 32 NULL 52 -11223344-5566-8777-0888-99aabbccddee 32 NULL 56 -11223344-5566-8777-0888-99aabbccddee 32 NULL 60 -11223344-5566-8777-8888-99aabbccddee 33 11223344-5566-8777-8888-99aabbccddee 33 -11223344-5566-8777-c888-99aabbccddee 34 11223344-5566-8777-c888-99aabbccddee 34 -11223344-5566-8777-e888-99aabbccddee 35 11223344-5566-8777-e888-99aabbccddee 35 -11223344-5566-9777-0888-99aabbccddee 36 NULL 32 -11223344-5566-9777-0888-99aabbccddee 36 NULL 36 -11223344-5566-9777-0888-99aabbccddee 36 NULL 40 -11223344-5566-9777-0888-99aabbccddee 36 NULL 44 -11223344-5566-9777-0888-99aabbccddee 36 NULL 48 -11223344-5566-9777-0888-99aabbccddee 36 NULL 52 -11223344-5566-9777-0888-99aabbccddee 36 NULL 56 -11223344-5566-9777-0888-99aabbccddee 36 NULL 60 -11223344-5566-9777-8888-99aabbccddee 37 11223344-5566-9777-8888-99aabbccddee 37 -11223344-5566-9777-c888-99aabbccddee 38 11223344-5566-9777-c888-99aabbccddee 38 -11223344-5566-9777-e888-99aabbccddee 39 11223344-5566-9777-e888-99aabbccddee 39 -11223344-5566-a777-0888-99aabbccddee 40 NULL 32 -11223344-5566-a777-0888-99aabbccddee 40 NULL 36 -11223344-5566-a777-0888-99aabbccddee 40 NULL 40 -11223344-5566-a777-0888-99aabbccddee 40 NULL 44 -11223344-5566-a777-0888-99aabbccddee 40 NULL 48 -11223344-5566-a777-0888-99aabbccddee 40 NULL 52 -11223344-5566-a777-0888-99aabbccddee 40 NULL 56 -11223344-5566-a777-0888-99aabbccddee 40 NULL 60 -11223344-5566-a777-8888-99aabbccddee 41 11223344-5566-a777-8888-99aabbccddee 41 -11223344-5566-a777-c888-99aabbccddee 42 11223344-5566-a777-c888-99aabbccddee 42 -11223344-5566-a777-e888-99aabbccddee 43 11223344-5566-a777-e888-99aabbccddee 43 -11223344-5566-b777-0888-99aabbccddee 44 NULL 32 -11223344-5566-b777-0888-99aabbccddee 44 NULL 36 -11223344-5566-b777-0888-99aabbccddee 44 NULL 40 -11223344-5566-b777-0888-99aabbccddee 44 NULL 44 -11223344-5566-b777-0888-99aabbccddee 44 NULL 48 -11223344-5566-b777-0888-99aabbccddee 44 NULL 52 -11223344-5566-b777-0888-99aabbccddee 44 NULL 56 -11223344-5566-b777-0888-99aabbccddee 44 NULL 60 -11223344-5566-b777-8888-99aabbccddee 45 11223344-5566-b777-8888-99aabbccddee 45 -11223344-5566-b777-c888-99aabbccddee 46 11223344-5566-b777-c888-99aabbccddee 46 -11223344-5566-b777-e888-99aabbccddee 47 11223344-5566-b777-e888-99aabbccddee 47 -11223344-5566-c777-0888-99aabbccddee 48 NULL 32 -11223344-5566-c777-0888-99aabbccddee 48 NULL 36 -11223344-5566-c777-0888-99aabbccddee 48 NULL 40 -11223344-5566-c777-0888-99aabbccddee 48 NULL 44 -11223344-5566-c777-0888-99aabbccddee 48 NULL 48 -11223344-5566-c777-0888-99aabbccddee 48 NULL 52 -11223344-5566-c777-0888-99aabbccddee 48 NULL 56 -11223344-5566-c777-0888-99aabbccddee 48 NULL 60 -11223344-5566-c777-8888-99aabbccddee 49 11223344-5566-c777-8888-99aabbccddee 49 -11223344-5566-c777-c888-99aabbccddee 50 11223344-5566-c777-c888-99aabbccddee 50 -11223344-5566-c777-e888-99aabbccddee 51 11223344-5566-c777-e888-99aabbccddee 51 -11223344-5566-d777-0888-99aabbccddee 52 NULL 32 -11223344-5566-d777-0888-99aabbccddee 52 NULL 36 -11223344-5566-d777-0888-99aabbccddee 52 NULL 40 -11223344-5566-d777-0888-99aabbccddee 52 NULL 44 -11223344-5566-d777-0888-99aabbccddee 52 NULL 48 -11223344-5566-d777-0888-99aabbccddee 52 NULL 52 -11223344-5566-d777-0888-99aabbccddee 52 NULL 56 -11223344-5566-d777-0888-99aabbccddee 52 NULL 60 -11223344-5566-d777-8888-99aabbccddee 53 11223344-5566-d777-8888-99aabbccddee 53 -11223344-5566-d777-c888-99aabbccddee 54 11223344-5566-d777-c888-99aabbccddee 54 -11223344-5566-d777-e888-99aabbccddee 55 11223344-5566-d777-e888-99aabbccddee 55 -11223344-5566-e777-0888-99aabbccddee 56 NULL 32 -11223344-5566-e777-0888-99aabbccddee 56 NULL 36 -11223344-5566-e777-0888-99aabbccddee 56 NULL 40 -11223344-5566-e777-0888-99aabbccddee 56 NULL 44 -11223344-5566-e777-0888-99aabbccddee 56 NULL 48 -11223344-5566-e777-0888-99aabbccddee 56 NULL 52 -11223344-5566-e777-0888-99aabbccddee 56 NULL 56 -11223344-5566-e777-0888-99aabbccddee 56 NULL 60 -11223344-5566-e777-8888-99aabbccddee 57 11223344-5566-e777-8888-99aabbccddee 57 -11223344-5566-e777-c888-99aabbccddee 58 11223344-5566-e777-c888-99aabbccddee 58 -11223344-5566-e777-e888-99aabbccddee 59 11223344-5566-e777-e888-99aabbccddee 59 -11223344-5566-f777-0888-99aabbccddee 60 NULL 32 -11223344-5566-f777-0888-99aabbccddee 60 NULL 36 -11223344-5566-f777-0888-99aabbccddee 60 NULL 40 -11223344-5566-f777-0888-99aabbccddee 60 NULL 44 -11223344-5566-f777-0888-99aabbccddee 60 NULL 48 -11223344-5566-f777-0888-99aabbccddee 60 NULL 52 -11223344-5566-f777-0888-99aabbccddee 60 NULL 56 -11223344-5566-f777-0888-99aabbccddee 60 NULL 60 -11223344-5566-f777-8888-99aabbccddee 61 11223344-5566-f777-8888-99aabbccddee 61 -11223344-5566-f777-c888-99aabbccddee 62 11223344-5566-f777-c888-99aabbccddee 62 -11223344-5566-f777-e888-99aabbccddee 63 11223344-5566-f777-e888-99aabbccddee 63 -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' -Warning 1292 Incorrect uuid value: '11223344-5566-f777-0888-99aabbccddee' +00001234-5566-0777-0888-99aabbccddee 0 00001234-5566-0777-0888-99aabbccddee 0 +00201234-5566-0777-c888-99aabbccddee 2 00201234-5566-0777-c888-99aabbccddee 2 +00401234-5566-1777-0888-99aabbccddee 4 00401234-5566-1777-0888-99aabbccddee 4 +00601234-5566-1777-c888-99aabbccddee 6 00601234-5566-1777-c888-99aabbccddee 6 +00801234-5566-2777-0888-99aabbccddee 8 00801234-5566-2777-0888-99aabbccddee 8 +01001234-5566-2777-c888-99aabbccddee 10 01001234-5566-2777-c888-99aabbccddee 10 +01201234-5566-3777-0888-99aabbccddee 12 01201234-5566-3777-0888-99aabbccddee 12 +01401234-5566-3777-c888-99aabbccddee 14 01401234-5566-3777-c888-99aabbccddee 14 +01601234-5566-4777-0888-99aabbccddee 16 01601234-5566-4777-0888-99aabbccddee 16 +01801234-5566-4777-c888-99aabbccddee 18 01801234-5566-4777-c888-99aabbccddee 18 +02001234-5566-5777-0888-99aabbccddee 20 02001234-5566-5777-0888-99aabbccddee 20 +02201234-5566-5777-c888-99aabbccddee 22 02201234-5566-5777-c888-99aabbccddee 22 +02401234-5566-6777-0888-99aabbccddee 24 02401234-5566-6777-0888-99aabbccddee 24 +02601234-5566-6777-c888-99aabbccddee 26 02601234-5566-6777-c888-99aabbccddee 26 +02801234-5566-7777-0888-99aabbccddee 28 02801234-5566-7777-0888-99aabbccddee 28 +03001234-5566-7777-c888-99aabbccddee 30 03001234-5566-7777-c888-99aabbccddee 30 +03201234-5566-8777-0888-99aabbccddee 32 NULL 32 +03201234-5566-8777-0888-99aabbccddee 32 NULL 36 +03201234-5566-8777-0888-99aabbccddee 32 NULL 40 +03201234-5566-8777-0888-99aabbccddee 32 NULL 44 +03201234-5566-8777-0888-99aabbccddee 32 NULL 48 +03201234-5566-8777-0888-99aabbccddee 32 NULL 52 +03201234-5566-8777-0888-99aabbccddee 32 NULL 56 +03201234-5566-8777-0888-99aabbccddee 32 NULL 60 +03401234-5566-8777-c888-99aabbccddee 34 03401234-5566-8777-c888-99aabbccddee 34 +03601234-5566-9777-0888-99aabbccddee 36 NULL 32 +03601234-5566-9777-0888-99aabbccddee 36 NULL 36 +03601234-5566-9777-0888-99aabbccddee 36 NULL 40 +03601234-5566-9777-0888-99aabbccddee 36 NULL 44 +03601234-5566-9777-0888-99aabbccddee 36 NULL 48 +03601234-5566-9777-0888-99aabbccddee 36 NULL 52 +03601234-5566-9777-0888-99aabbccddee 36 NULL 56 +03601234-5566-9777-0888-99aabbccddee 36 NULL 60 +03801234-5566-9777-c888-99aabbccddee 38 03801234-5566-9777-c888-99aabbccddee 38 +04001234-5566-a777-0888-99aabbccddee 40 NULL 32 +04001234-5566-a777-0888-99aabbccddee 40 NULL 36 +04001234-5566-a777-0888-99aabbccddee 40 NULL 40 +04001234-5566-a777-0888-99aabbccddee 40 NULL 44 +04001234-5566-a777-0888-99aabbccddee 40 NULL 48 +04001234-5566-a777-0888-99aabbccddee 40 NULL 52 +04001234-5566-a777-0888-99aabbccddee 40 NULL 56 +04001234-5566-a777-0888-99aabbccddee 40 NULL 60 +04201234-5566-a777-c888-99aabbccddee 42 04201234-5566-a777-c888-99aabbccddee 42 +04401234-5566-b777-0888-99aabbccddee 44 NULL 32 +04401234-5566-b777-0888-99aabbccddee 44 NULL 36 +04401234-5566-b777-0888-99aabbccddee 44 NULL 40 +04401234-5566-b777-0888-99aabbccddee 44 NULL 44 +04401234-5566-b777-0888-99aabbccddee 44 NULL 48 +04401234-5566-b777-0888-99aabbccddee 44 NULL 52 +04401234-5566-b777-0888-99aabbccddee 44 NULL 56 +04401234-5566-b777-0888-99aabbccddee 44 NULL 60 +04601234-5566-b777-c888-99aabbccddee 46 04601234-5566-b777-c888-99aabbccddee 46 +04801234-5566-c777-0888-99aabbccddee 48 NULL 32 +04801234-5566-c777-0888-99aabbccddee 48 NULL 36 +04801234-5566-c777-0888-99aabbccddee 48 NULL 40 +04801234-5566-c777-0888-99aabbccddee 48 NULL 44 +04801234-5566-c777-0888-99aabbccddee 48 NULL 48 +04801234-5566-c777-0888-99aabbccddee 48 NULL 52 +04801234-5566-c777-0888-99aabbccddee 48 NULL 56 +04801234-5566-c777-0888-99aabbccddee 48 NULL 60 +05001234-5566-c777-c888-99aabbccddee 50 05001234-5566-c777-c888-99aabbccddee 50 +05201234-5566-d777-0888-99aabbccddee 52 NULL 32 +05201234-5566-d777-0888-99aabbccddee 52 NULL 36 +05201234-5566-d777-0888-99aabbccddee 52 NULL 40 +05201234-5566-d777-0888-99aabbccddee 52 NULL 44 +05201234-5566-d777-0888-99aabbccddee 52 NULL 48 +05201234-5566-d777-0888-99aabbccddee 52 NULL 52 +05201234-5566-d777-0888-99aabbccddee 52 NULL 56 +05201234-5566-d777-0888-99aabbccddee 52 NULL 60 +05401234-5566-d777-c888-99aabbccddee 54 05401234-5566-d777-c888-99aabbccddee 54 +05601234-5566-e777-0888-99aabbccddee 56 NULL 32 +05601234-5566-e777-0888-99aabbccddee 56 NULL 36 +05601234-5566-e777-0888-99aabbccddee 56 NULL 40 +05601234-5566-e777-0888-99aabbccddee 56 NULL 44 +05601234-5566-e777-0888-99aabbccddee 56 NULL 48 +05601234-5566-e777-0888-99aabbccddee 56 NULL 52 +05601234-5566-e777-0888-99aabbccddee 56 NULL 56 +05601234-5566-e777-0888-99aabbccddee 56 NULL 60 +05801234-5566-e777-c888-99aabbccddee 58 05801234-5566-e777-c888-99aabbccddee 58 +06001234-5566-f777-0888-99aabbccddee 60 NULL 32 +06001234-5566-f777-0888-99aabbccddee 60 NULL 36 +06001234-5566-f777-0888-99aabbccddee 60 NULL 40 +06001234-5566-f777-0888-99aabbccddee 60 NULL 44 +06001234-5566-f777-0888-99aabbccddee 60 NULL 48 +06001234-5566-f777-0888-99aabbccddee 60 NULL 52 +06001234-5566-f777-0888-99aabbccddee 60 NULL 56 +06001234-5566-f777-0888-99aabbccddee 60 NULL 60 +06201234-5566-f777-c888-99aabbccddee 62 06201234-5566-f777-c888-99aabbccddee 62 +10101234-5566-0777-8888-99aabbccddee 1 10101234-5566-0777-8888-99aabbccddee 1 +10301234-5566-0777-e888-99aabbccddee 3 10301234-5566-0777-e888-99aabbccddee 3 +10501234-5566-1777-8888-99aabbccddee 5 10501234-5566-1777-8888-99aabbccddee 5 +10701234-5566-1777-e888-99aabbccddee 7 10701234-5566-1777-e888-99aabbccddee 7 +10901234-5566-2777-8888-99aabbccddee 9 10901234-5566-2777-8888-99aabbccddee 9 +11101234-5566-2777-e888-99aabbccddee 11 11101234-5566-2777-e888-99aabbccddee 11 +11301234-5566-3777-8888-99aabbccddee 13 11301234-5566-3777-8888-99aabbccddee 13 +11501234-5566-3777-e888-99aabbccddee 15 11501234-5566-3777-e888-99aabbccddee 15 +11701234-5566-4777-8888-99aabbccddee 17 11701234-5566-4777-8888-99aabbccddee 17 +11901234-5566-4777-e888-99aabbccddee 19 11901234-5566-4777-e888-99aabbccddee 19 +12101234-5566-5777-8888-99aabbccddee 21 12101234-5566-5777-8888-99aabbccddee 21 +12301234-5566-5777-e888-99aabbccddee 23 12301234-5566-5777-e888-99aabbccddee 23 +12501234-5566-6777-8888-99aabbccddee 25 12501234-5566-6777-8888-99aabbccddee 25 +12701234-5566-6777-e888-99aabbccddee 27 12701234-5566-6777-e888-99aabbccddee 27 +12901234-5566-7777-8888-99aabbccddee 29 12901234-5566-7777-8888-99aabbccddee 29 +13101234-5566-7777-e888-99aabbccddee 31 13101234-5566-7777-e888-99aabbccddee 31 +13301234-5566-8777-8888-99aabbccddee 33 13301234-5566-8777-8888-99aabbccddee 33 +13501234-5566-8777-e888-99aabbccddee 35 13501234-5566-8777-e888-99aabbccddee 35 +13701234-5566-9777-8888-99aabbccddee 37 13701234-5566-9777-8888-99aabbccddee 37 +13901234-5566-9777-e888-99aabbccddee 39 13901234-5566-9777-e888-99aabbccddee 39 +14101234-5566-a777-8888-99aabbccddee 41 14101234-5566-a777-8888-99aabbccddee 41 +14301234-5566-a777-e888-99aabbccddee 43 14301234-5566-a777-e888-99aabbccddee 43 +14501234-5566-b777-8888-99aabbccddee 45 14501234-5566-b777-8888-99aabbccddee 45 +14701234-5566-b777-e888-99aabbccddee 47 14701234-5566-b777-e888-99aabbccddee 47 +14901234-5566-c777-8888-99aabbccddee 49 14901234-5566-c777-8888-99aabbccddee 49 +15101234-5566-c777-e888-99aabbccddee 51 15101234-5566-c777-e888-99aabbccddee 51 +15301234-5566-d777-8888-99aabbccddee 53 15301234-5566-d777-8888-99aabbccddee 53 +15501234-5566-d777-e888-99aabbccddee 55 15501234-5566-d777-e888-99aabbccddee 55 +15701234-5566-e777-8888-99aabbccddee 57 15701234-5566-e777-8888-99aabbccddee 57 +15901234-5566-e777-e888-99aabbccddee 59 15901234-5566-e777-e888-99aabbccddee 59 +16101234-5566-f777-8888-99aabbccddee 61 16101234-5566-f777-8888-99aabbccddee 61 +16301234-5566-f777-e888-99aabbccddee 63 16301234-5566-f777-e888-99aabbccddee 63 +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '06001234-5566-f777-0888-99aabbccddee' Warnings: select * from t1 union select * from t2; a b -11223344-5566-0777-0888-99aabbccddee 0 -11223344-5566-0777-8888-99aabbccddee 1 -11223344-5566-0777-c888-99aabbccddee 2 -11223344-5566-0777-e888-99aabbccddee 3 -11223344-5566-1777-0888-99aabbccddee 4 -11223344-5566-1777-8888-99aabbccddee 5 -11223344-5566-1777-c888-99aabbccddee 6 -11223344-5566-1777-e888-99aabbccddee 7 -11223344-5566-2777-0888-99aabbccddee 8 -11223344-5566-2777-8888-99aabbccddee 9 -11223344-5566-2777-c888-99aabbccddee 10 -11223344-5566-2777-e888-99aabbccddee 11 -11223344-5566-3777-0888-99aabbccddee 12 -11223344-5566-3777-8888-99aabbccddee 13 -11223344-5566-3777-c888-99aabbccddee 14 -11223344-5566-3777-e888-99aabbccddee 15 -11223344-5566-4777-0888-99aabbccddee 16 -11223344-5566-4777-8888-99aabbccddee 17 -11223344-5566-4777-c888-99aabbccddee 18 -11223344-5566-4777-e888-99aabbccddee 19 -11223344-5566-5777-0888-99aabbccddee 20 -11223344-5566-5777-8888-99aabbccddee 21 -11223344-5566-5777-c888-99aabbccddee 22 -11223344-5566-5777-e888-99aabbccddee 23 -11223344-5566-6777-0888-99aabbccddee 24 -11223344-5566-6777-8888-99aabbccddee 25 -11223344-5566-6777-c888-99aabbccddee 26 -11223344-5566-6777-e888-99aabbccddee 27 -11223344-5566-7777-0888-99aabbccddee 28 -11223344-5566-7777-8888-99aabbccddee 29 -11223344-5566-7777-c888-99aabbccddee 30 -11223344-5566-7777-e888-99aabbccddee 31 -11223344-5566-8777-8888-99aabbccddee 33 -11223344-5566-8777-c888-99aabbccddee 34 -11223344-5566-8777-e888-99aabbccddee 35 -11223344-5566-9777-8888-99aabbccddee 37 -11223344-5566-9777-c888-99aabbccddee 38 -11223344-5566-9777-e888-99aabbccddee 39 -11223344-5566-a777-8888-99aabbccddee 41 -11223344-5566-a777-c888-99aabbccddee 42 -11223344-5566-a777-e888-99aabbccddee 43 -11223344-5566-b777-8888-99aabbccddee 45 -11223344-5566-b777-c888-99aabbccddee 46 -11223344-5566-b777-e888-99aabbccddee 47 -11223344-5566-c777-8888-99aabbccddee 49 -11223344-5566-c777-c888-99aabbccddee 50 -11223344-5566-c777-e888-99aabbccddee 51 -11223344-5566-d777-8888-99aabbccddee 53 -11223344-5566-d777-c888-99aabbccddee 54 -11223344-5566-d777-e888-99aabbccddee 55 -11223344-5566-e777-8888-99aabbccddee 57 -11223344-5566-e777-c888-99aabbccddee 58 -11223344-5566-e777-e888-99aabbccddee 59 -11223344-5566-f777-8888-99aabbccddee 61 -11223344-5566-f777-c888-99aabbccddee 62 -11223344-5566-f777-e888-99aabbccddee 63 +00001234-5566-0777-0888-99aabbccddee 0 +00201234-5566-0777-c888-99aabbccddee 2 +00401234-5566-1777-0888-99aabbccddee 4 +00601234-5566-1777-c888-99aabbccddee 6 +00801234-5566-2777-0888-99aabbccddee 8 +01001234-5566-2777-c888-99aabbccddee 10 +01201234-5566-3777-0888-99aabbccddee 12 +01401234-5566-3777-c888-99aabbccddee 14 +01601234-5566-4777-0888-99aabbccddee 16 +01801234-5566-4777-c888-99aabbccddee 18 +02001234-5566-5777-0888-99aabbccddee 20 +02201234-5566-5777-c888-99aabbccddee 22 +02401234-5566-6777-0888-99aabbccddee 24 +02601234-5566-6777-c888-99aabbccddee 26 +02801234-5566-7777-0888-99aabbccddee 28 +03001234-5566-7777-c888-99aabbccddee 30 +03401234-5566-8777-c888-99aabbccddee 34 +03801234-5566-9777-c888-99aabbccddee 38 +04201234-5566-a777-c888-99aabbccddee 42 +04601234-5566-b777-c888-99aabbccddee 46 +05001234-5566-c777-c888-99aabbccddee 50 +05401234-5566-d777-c888-99aabbccddee 54 +05801234-5566-e777-c888-99aabbccddee 58 +06201234-5566-f777-c888-99aabbccddee 62 +10101234-5566-0777-8888-99aabbccddee 1 +10301234-5566-0777-e888-99aabbccddee 3 +10501234-5566-1777-8888-99aabbccddee 5 +10701234-5566-1777-e888-99aabbccddee 7 +10901234-5566-2777-8888-99aabbccddee 9 +11101234-5566-2777-e888-99aabbccddee 11 +11301234-5566-3777-8888-99aabbccddee 13 +11501234-5566-3777-e888-99aabbccddee 15 +11701234-5566-4777-8888-99aabbccddee 17 +11901234-5566-4777-e888-99aabbccddee 19 +12101234-5566-5777-8888-99aabbccddee 21 +12301234-5566-5777-e888-99aabbccddee 23 +12501234-5566-6777-8888-99aabbccddee 25 +12701234-5566-6777-e888-99aabbccddee 27 +12901234-5566-7777-8888-99aabbccddee 29 +13101234-5566-7777-e888-99aabbccddee 31 +13301234-5566-8777-8888-99aabbccddee 33 +13501234-5566-8777-e888-99aabbccddee 35 +13701234-5566-9777-8888-99aabbccddee 37 +13901234-5566-9777-e888-99aabbccddee 39 +14101234-5566-a777-8888-99aabbccddee 41 +14301234-5566-a777-e888-99aabbccddee 43 +14501234-5566-b777-8888-99aabbccddee 45 +14701234-5566-b777-e888-99aabbccddee 47 +14901234-5566-c777-8888-99aabbccddee 49 +15101234-5566-c777-e888-99aabbccddee 51 +15301234-5566-d777-8888-99aabbccddee 53 +15501234-5566-d777-e888-99aabbccddee 55 +15701234-5566-e777-8888-99aabbccddee 57 +15901234-5566-e777-e888-99aabbccddee 59 +16101234-5566-f777-8888-99aabbccddee 61 +16301234-5566-f777-e888-99aabbccddee 63 NULL 32 NULL 36 NULL 40 @@ -755,14 +756,78 @@ NULL 48 NULL 52 NULL 56 NULL 60 +select * from t1, t1 t where t1.b div 4 in (6,7) and t.b div 4 in (6,7) and t1.a > t.a; +a b a b +02601234-5566-6777-c888-99aabbccddee 26 02401234-5566-6777-0888-99aabbccddee 24 +02801234-5566-7777-0888-99aabbccddee 28 02401234-5566-6777-0888-99aabbccddee 24 +02801234-5566-7777-0888-99aabbccddee 28 02601234-5566-6777-c888-99aabbccddee 26 +03001234-5566-7777-c888-99aabbccddee 30 02401234-5566-6777-0888-99aabbccddee 24 +03001234-5566-7777-c888-99aabbccddee 30 02601234-5566-6777-c888-99aabbccddee 26 +03001234-5566-7777-c888-99aabbccddee 30 02801234-5566-7777-0888-99aabbccddee 28 +12501234-5566-6777-8888-99aabbccddee 25 02401234-5566-6777-0888-99aabbccddee 24 +12501234-5566-6777-8888-99aabbccddee 25 02601234-5566-6777-c888-99aabbccddee 26 +12501234-5566-6777-8888-99aabbccddee 25 02801234-5566-7777-0888-99aabbccddee 28 +12501234-5566-6777-8888-99aabbccddee 25 03001234-5566-7777-c888-99aabbccddee 30 +12701234-5566-6777-e888-99aabbccddee 27 02401234-5566-6777-0888-99aabbccddee 24 +12701234-5566-6777-e888-99aabbccddee 27 02601234-5566-6777-c888-99aabbccddee 26 +12701234-5566-6777-e888-99aabbccddee 27 02801234-5566-7777-0888-99aabbccddee 28 +12701234-5566-6777-e888-99aabbccddee 27 03001234-5566-7777-c888-99aabbccddee 30 +12701234-5566-6777-e888-99aabbccddee 27 12501234-5566-6777-8888-99aabbccddee 25 +12901234-5566-7777-8888-99aabbccddee 29 02401234-5566-6777-0888-99aabbccddee 24 +12901234-5566-7777-8888-99aabbccddee 29 02601234-5566-6777-c888-99aabbccddee 26 +12901234-5566-7777-8888-99aabbccddee 29 02801234-5566-7777-0888-99aabbccddee 28 +12901234-5566-7777-8888-99aabbccddee 29 03001234-5566-7777-c888-99aabbccddee 30 +12901234-5566-7777-8888-99aabbccddee 29 12501234-5566-6777-8888-99aabbccddee 25 +12901234-5566-7777-8888-99aabbccddee 29 12701234-5566-6777-e888-99aabbccddee 27 +13101234-5566-7777-e888-99aabbccddee 31 02401234-5566-6777-0888-99aabbccddee 24 +13101234-5566-7777-e888-99aabbccddee 31 02601234-5566-6777-c888-99aabbccddee 26 +13101234-5566-7777-e888-99aabbccddee 31 02801234-5566-7777-0888-99aabbccddee 28 +13101234-5566-7777-e888-99aabbccddee 31 03001234-5566-7777-c888-99aabbccddee 30 +13101234-5566-7777-e888-99aabbccddee 31 12501234-5566-6777-8888-99aabbccddee 25 +13101234-5566-7777-e888-99aabbccddee 31 12701234-5566-6777-e888-99aabbccddee 27 +13101234-5566-7777-e888-99aabbccddee 31 12901234-5566-7777-8888-99aabbccddee 29 alter ignore table t2 force; Warnings: -Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 33 -Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 37 -Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 41 -Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 45 -Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 49 -Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 53 -Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 57 -Warning 1292 Incorrect uuid value: '11223344-5566-f777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 61 -drop table t1, t2; +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 33 +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 37 +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 41 +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 45 +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 49 +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 53 +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 57 +Warning 1292 Incorrect uuid value: '06001234-5566-f777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 61 +drop table t2; +# +# MDEV-31926 UUID v7 are compared incorrectly +# +select * from t1, t1 t where t1.b div 4 in (6,7) and t.b div 4 in (6,7) and concat(t1.a) > concat(t.a); +a b a b +02601234-5566-6777-c888-99aabbccddee 26 02401234-5566-6777-0888-99aabbccddee 24 +02801234-5566-7777-0888-99aabbccddee 28 02401234-5566-6777-0888-99aabbccddee 24 +02801234-5566-7777-0888-99aabbccddee 28 02601234-5566-6777-c888-99aabbccddee 26 +03001234-5566-7777-c888-99aabbccddee 30 02401234-5566-6777-0888-99aabbccddee 24 +03001234-5566-7777-c888-99aabbccddee 30 02601234-5566-6777-c888-99aabbccddee 26 +03001234-5566-7777-c888-99aabbccddee 30 02801234-5566-7777-0888-99aabbccddee 28 +12501234-5566-6777-8888-99aabbccddee 25 02401234-5566-6777-0888-99aabbccddee 24 +12501234-5566-6777-8888-99aabbccddee 25 02601234-5566-6777-c888-99aabbccddee 26 +12501234-5566-6777-8888-99aabbccddee 25 02801234-5566-7777-0888-99aabbccddee 28 +12501234-5566-6777-8888-99aabbccddee 25 03001234-5566-7777-c888-99aabbccddee 30 +12701234-5566-6777-e888-99aabbccddee 27 02401234-5566-6777-0888-99aabbccddee 24 +12701234-5566-6777-e888-99aabbccddee 27 02601234-5566-6777-c888-99aabbccddee 26 +12701234-5566-6777-e888-99aabbccddee 27 02801234-5566-7777-0888-99aabbccddee 28 +12701234-5566-6777-e888-99aabbccddee 27 03001234-5566-7777-c888-99aabbccddee 30 +12701234-5566-6777-e888-99aabbccddee 27 12501234-5566-6777-8888-99aabbccddee 25 +12901234-5566-7777-8888-99aabbccddee 29 02401234-5566-6777-0888-99aabbccddee 24 +12901234-5566-7777-8888-99aabbccddee 29 02601234-5566-6777-c888-99aabbccddee 26 +12901234-5566-7777-8888-99aabbccddee 29 02801234-5566-7777-0888-99aabbccddee 28 +12901234-5566-7777-8888-99aabbccddee 29 03001234-5566-7777-c888-99aabbccddee 30 +12901234-5566-7777-8888-99aabbccddee 29 12501234-5566-6777-8888-99aabbccddee 25 +12901234-5566-7777-8888-99aabbccddee 29 12701234-5566-6777-e888-99aabbccddee 27 +13101234-5566-7777-e888-99aabbccddee 31 02401234-5566-6777-0888-99aabbccddee 24 +13101234-5566-7777-e888-99aabbccddee 31 02601234-5566-6777-c888-99aabbccddee 26 +13101234-5566-7777-e888-99aabbccddee 31 02801234-5566-7777-0888-99aabbccddee 28 +13101234-5566-7777-e888-99aabbccddee 31 03001234-5566-7777-c888-99aabbccddee 30 +13101234-5566-7777-e888-99aabbccddee 31 12501234-5566-6777-8888-99aabbccddee 25 +13101234-5566-7777-e888-99aabbccddee 31 12701234-5566-6777-e888-99aabbccddee 27 +13101234-5566-7777-e888-99aabbccddee 31 12901234-5566-7777-8888-99aabbccddee 29 +drop table t1; diff --git a/plugin/type_uuid/mysql-test/type_uuid/order.test b/plugin/type_uuid/mysql-test/type_uuid/order.test index 46f76da98e3..18854e85fbf 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/order.test +++ b/plugin/type_uuid/mysql-test/type_uuid/order.test @@ -2,8 +2,9 @@ source include/have_sequence.inc; create table t1 (a uuid, b int not null, index (a)); -insert t1 select sformat('11223344-5566-{:x}777-{}888-99aabbccddee', seq div 4, elt(1+(seq % 4),0,8,'c','e')),seq from seq_0_to_63; -select * from t1; +insert t1 select sformat('{:03}01234-5566-{:x}777-{}888-99aabbccddee', + (seq % 2)*100 + seq, seq div 4, elt(1+(seq % 4),0,8,'c','e')),seq from seq_0_to_63; +select * from t1 order by b; select * from t1 order by a; show create table t1; @@ -12,7 +13,7 @@ let $datadir= `select @@datadir`; --copy_file $MTR_SUITE_DIR/std_data/mdev-29959.frm $datadir/test/t2.frm --copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYI $datadir/test/t2.MYI --copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYD $datadir/test/t2.MYD -select * from t2; +select * from t2 order by b; select * from t2 order by a; show create table t2; @@ -35,6 +36,27 @@ select * from t2 left join t1 on (t1.a<=>t2.a); --sorted_result select * from t1 union select * from t2; +--sorted_result +select * from t1, t1 t where t1.b div 4 in (6,7) and t.b div 4 in (6,7) and t1.a > t.a; + alter ignore table t2 force; -drop table t1, t2; +drop table t2; + +--echo # +--echo # MDEV-31926 UUID v7 are compared incorrectly +--echo # + +# for v6 and v7 string comparison should produce the same result. +# Quoting the standard draft: +# +# 6.11. Sorting +# +# UUIDv6 and UUIDv7 are designed so that implementations that require +# sorting (e.g., database indexes) sort as opaque raw bytes, without +# need for parsing or introspection. +# +--sorted_result +select * from t1, t1 t where t1.b div 4 in (6,7) and t.b div 4 in (6,7) and concat(t1.a) > concat(t.a); + +drop table t1; diff --git a/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYD b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYD index 138a08deeb7..1e0594674f5 100644 Binary files a/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYD and b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYD differ diff --git a/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYI b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYI index 6dde55b27da..b85c5d61dd6 100644 Binary files a/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYI and b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYI differ diff --git a/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.frm b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.frm index d03c730aff7..ebefe982d95 100644 Binary files a/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.frm and b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.frm differ diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result index 84b2b7e46f7..4d6baeaff53 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result @@ -3182,10 +3182,10 @@ d 11111111-0000-0000-0000-000000000000 SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1); d -11111111-0000-0000-0000-000000000000 +00000000-0000-0000-0000-111111111111 SELECT * FROM t1 WHERE d >= ALL (SELECT * FROM t1); d -00000000-0000-0000-0000-111111111111 +11111111-0000-0000-0000-000000000000 DROP TABLE t1; # # MDEV-31719 Wrong result of: WHERE inet6_column IN ('','::1') diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_innodb.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_innodb.result index d769f1a1374..37710ab1008 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_innodb.result +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_innodb.result @@ -195,6 +195,8 @@ EXPLAIN SELECT * FROM t2 JOIN t1 ON ( t1.pk > t2.d); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system NULL NULL NULL NULL 1 1 SIMPLE t2 ALL d NULL NULL NULL 1 Using where +Warnings: +Note 1105 Cannot use key `d` part[0] for lookup: `test`.`t2`.`d` of type `blob` < "'00000000-0000-0000-0000-000000000000'" of type `uuid` UPDATE t2 JOIN t1 ON ( t1.pk > t2.d) SET t1.c = 1; ERROR 22007: Incorrect uuid value: '2' DROP TABLE t1, t2; diff --git a/plugin/type_uuid/sql_type_uuid.h b/plugin/type_uuid/sql_type_uuid.h index 939c6047731..3ca310ff0b6 100644 --- a/plugin/type_uuid/sql_type_uuid.h +++ b/plugin/type_uuid/sql_type_uuid.h @@ -142,11 +142,11 @@ public: constexpr Segment(size_t memory_pos, size_t record_pos, size_t length) :m_memory_pos(memory_pos), m_record_pos(record_pos), m_length(length) { } - void memory_to_record(char *to, const char *from) const + void mem2rec(char *to, const char *from) const { memcpy(to + m_record_pos, from + m_memory_pos, m_length); } - void record_to_memory(char *to, const char * from) const + void rec2mem(char *to, const char * from) const { memcpy(to + m_memory_pos, from + m_record_pos, m_length); } @@ -173,16 +173,24 @@ public: return segments[i]; } + // version > 0 && version < 6 && variant != 0 + static bool mem_need_swap(const char *s) + { return s[6] > 0 && s[6] < 0x60 && s[8] & 0x80; } + + // s[6] & 0x80 && s[8] > 0: this means a swapped uuid + static bool rec_need_swap(const char *s) + { return s[6] & -s[8] & 0x80; } + // Convert the in-memory representation to the in-record representation static void memory_to_record(char *to, const char *from) { - if (force_swap || (from[6] > 0 && from[6] < 0x60 && from[8] & 0x80)) + if (force_swap || mem_need_swap(from)) { - segment(0).memory_to_record(to, from); - segment(1).memory_to_record(to, from); - segment(2).memory_to_record(to, from); - segment(3).memory_to_record(to, from); - segment(4).memory_to_record(to, from); + segment(0).mem2rec(to, from); + segment(1).mem2rec(to, from); + segment(2).mem2rec(to, from); + segment(3).mem2rec(to, from); + segment(4).mem2rec(to, from); } else memcpy(to, from, binary_length()); @@ -191,13 +199,13 @@ public: // Convert the in-record representation to the in-memory representation static void record_to_memory(char *to, const char *from) { - if (force_swap || (from[6] & -from[8] & 0x80)) + if (force_swap || rec_need_swap(from)) { - segment(0).record_to_memory(to, from); - segment(1).record_to_memory(to, from); - segment(2).record_to_memory(to, from); - segment(3).record_to_memory(to, from); - segment(4).record_to_memory(to, from); + segment(0).rec2mem(to, from); + segment(1).rec2mem(to, from); + segment(2).rec2mem(to, from); + segment(3).rec2mem(to, from); + segment(4).rec2mem(to, from); } else memcpy(to, from, binary_length()); @@ -233,14 +241,20 @@ public: { DBUG_ASSERT(a.length == binary_length()); DBUG_ASSERT(b.length == binary_length()); - int res; - if ((res= segment(4).cmp_memory(a.str, b.str)) || - (res= segment(3).cmp_memory(a.str, b.str)) || - (res= segment(2).cmp_memory(a.str, b.str)) || - (res= segment(1).cmp_memory(a.str, b.str)) || - (res= segment(0).cmp_memory(a.str, b.str))) - return res; - return 0; + bool swap_a= force_swap || mem_need_swap(a.str); + bool swap_b= force_swap || mem_need_swap(b.str); + if (swap_a && swap_b) + { + int res; + if ((res= segment(4).cmp_memory(a.str, b.str)) || + (res= segment(3).cmp_memory(a.str, b.str)) || + (res= segment(2).cmp_memory(a.str, b.str)) || + (res= segment(1).cmp_memory(a.str, b.str)) || + (res= segment(0).cmp_memory(a.str, b.str))) + return res; + return 0; + } + return memcmp(a.str, b.str, binary_length()); } static ulong KEY_pack_flags(uint column_nr) diff --git a/scripts/mariadb_system_tables_fix.sql b/scripts/mariadb_system_tables_fix.sql index b5a065bc9bf..7d0fd0f5644 100644 --- a/scripts/mariadb_system_tables_fix.sql +++ b/scripts/mariadb_system_tables_fix.sql @@ -25,6 +25,7 @@ # adding a 'SHOW WARNINGS' after the statement. set sql_mode=''; +set sql_safe_updates='OFF'; set default_storage_engine=Aria; set enforce_storage_engine=NULL; set alter_algorithm='DEFAULT'; @@ -229,6 +230,11 @@ UPDATE user SET plugin='unix_socket' WHERE plugin='auth_socket'; DELETE FROM plugin WHERE name='auth_socket'; +# Delete plugins that are now inbuilt but might not have been before (MDEV-32043) +DELETE plugin + FROM information_schema.PLUGINS is_p + JOIN plugin ON plugin.name = is_p.PLUGIN_NAME + WHERE is_p.PLUGIN_LIBRARY IS NULL; ALTER TABLE user MODIFY Password char(41) character set latin1 collate latin1_bin NOT NULL default '', diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index e9a141af0d6..55d59f315ac 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -511,7 +511,7 @@ done if test -n "$user" then - if test -z "$srcdir" -a "$in_rpm" -eq 0 + if test -z "$srcdir" -a "$in_rpm" -eq 0 -a -d "$pamtooldir/auth_pam_tool_dir" then chown 0 "$pamtooldir/auth_pam_tool_dir/auth_pam_tool" && \ chmod 04755 "$pamtooldir/auth_pam_tool_dir/auth_pam_tool" diff --git a/scripts/mysql_setpermission.sh b/scripts/mysql_setpermission.sh index 76c07b6816b..9af895ff8b8 100644 --- a/scripts/mysql_setpermission.sh +++ b/scripts/mysql_setpermission.sh @@ -71,7 +71,7 @@ usage() if ($opt_help); # the help function if ($opt_host =~ s/:(\d+)$//) { - $opt_port = $1; + $opt_port = $1; } if ($opt_host eq '') @@ -101,7 +101,7 @@ my $prefix= 'mysql'; if (eval {DBI->install_driver("MariaDB")}) { $dsn ="DBI:MariaDB:;"; $prefix= 'mariadb'; -} +} else { $dsn = "DBI:mysql:;"; } @@ -229,11 +229,11 @@ sub setpwd { $pass = "PASSWORD(". $dbh->quote($pass) . ")"; } - my $uh= "$user@$host"; + my $uh= $user."@".$host; my $sth = $dbh->prepare("set password for $uh =$pass") || die $dbh->errstr; $sth->execute || die $dbh->errstr; $sth->finish; - print "The password is set for user $user.\n\n"; + print "The password is set for user $uh.\n\n"; } diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 45205204c93..248cdbbd52a 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='mariadb_backup_galera_info' IST_FILE='xtrabackup_ist' MAGIC_FILE="$DATA/$INFO_FILE" @@ -439,7 +440,7 @@ get_transfer() get_footprint() { cd "$DATA_DIR" - local payload_data=$(find . \ + local payload_data=$(find $findopt . \ -regex '.*undo[0-9]+$\|.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' \ -type f -print0 | du --files0-from=- --block-size=1 -c -s | \ awk 'END { print $1 }') @@ -798,10 +799,20 @@ recv_joiner() local ltcmd="$tcmd" if [ $tmt -gt 0 ]; then if [ -n "$(commandex timeout)" ]; then - if timeout --help | grep -qw -F -- '-k'; then + local koption=0 + if [ "$OS" = 'FreeBSD' ]; then + if timeout 2>&1 | grep -qw -F -- '-k'; then + koption=1 + fi + else + if timeout --help | grep -qw -F -- '-k'; then + koption=1 + fi + fi + if [ $koption -ne 0 ]; then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" else - ltcmd="timeout -s9 $tmt $tcmd" + ltcmd="timeout -s 9 $tmt $tcmd" fi fi fi @@ -1032,9 +1043,29 @@ 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 +findopt='-L' +[ "$OS" = 'FreeBSD' ] && findopt="$findopt -E" + if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]; then trap cleanup_at_exit EXIT @@ -1086,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" @@ -1189,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 @@ -1297,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 @@ -1428,26 +1445,18 @@ else # joiner wsrep_log_info \ "Cleaning the existing datadir and innodb-data/log directories" - if [ "$OS" = 'FreeBSD' ]; then - find -E ${ib_home_dir:+"$ib_home_dir"} \ - ${ib_undo_dir:+"$ib_undo_dir"} \ - ${ib_log_dir:+"$ib_log_dir"} \ - ${ar_log_dir:+"$ar_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" \ - -o -exec rm -rf {} >&2 \+ - else - find ${ib_home_dir:+"$ib_home_dir"} \ - ${ib_undo_dir:+"$ib_undo_dir"} \ - ${ib_log_dir:+"$ib_log_dir"} \ - ${ar_log_dir:+"$ar_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" \ - -o -exec rm -rf {} >&2 \+ - fi + + find $findopt ${ib_home_dir:+"$ib_home_dir"} \ + ${ib_undo_dir:+"$ib_undo_dir"} \ + ${ib_log_dir:+"$ib_log_dir"} \ + ${ar_log_dir:+"$ar_log_dir"} \ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rf {} >&2 \+ TDATA="$DATA" DATA="$DATA/.sst" - MAGIC_FILE="$DATA/$INFO_FILE" + wsrep_log_info "Waiting for SST streaming to complete!" monitor_process $jpid @@ -1464,7 +1473,7 @@ else # joiner exit 2 fi - qpfiles=$(find "$DATA" -maxdepth 1 -type f -name '*.qp' -print -quit) + qpfiles=$(find $findopt "$DATA" -maxdepth 1 -type f -name '*.qp' -print -quit) if [ -n "$qpfiles" ]; then wsrep_log_info "Compressed qpress files found" @@ -1480,7 +1489,7 @@ else # joiner if [ -n "$progress" -a "$progress" != 'none' ] && \ pv --help | grep -qw -F -- '--line-mode' then - count=$(find "$DATA" -maxdepth 1 -type f -name '*.qp' | wc -l) + count=$(find $findopt "$DATA" -maxdepth 1 -type f -name '*.qp' | wc -l) count=$(( count*2 )) pvopts='-f -l -N Decompression' pvformat="-F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'" @@ -1492,13 +1501,13 @@ else # joiner # Decompress the qpress files wsrep_log_info "Decompression with $nproc threads" timeit 'Joiner-Decompression' \ - "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | \ + "find $findopt '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | \ $dcmd" extcode=$? if [ $extcode -eq 0 ]; then wsrep_log_info "Removing qpress files after decompression" - find "$DATA" -type f -name '*.qp' -delete + find $findopt "$DATA" -type f -name '*.qp' -delete if [ $? -ne 0 ]; then wsrep_log_error \ "Something went wrong with deletion of qpress files." \ diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index a7c2688df76..4e0151a2cd0 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" @@ -564,6 +565,7 @@ FILTER="-f '- /lost+found' -f '- /.Trashes' -f '- /.pid' -f '- /.conf' + -f '- /.snapshot/' -f '+ /wsrep_sst_binlog.tar' -f '- $ib_home_dir/ib_lru_dump' -f '- $ib_home_dir/ibdata*' @@ -579,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 @@ -672,8 +674,12 @@ FILTER="-f '- /lost+found' cd "$DATA" - find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \ - -not -name '.zfs' -print0 | xargs -I{} -0 -P $backup_threads \ + findopt='-L' + [ "$OS" = 'FreeBSD' ] && findopt="$findopt -E" + + find $findopt . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \ + -not -name '.zfs' -not -name .snapshot -print0 \ + | xargs -I{} -0 -P $backup_threads \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \ --owner --group --perms --links --specials --ignore-times \ --inplace --recursive --delete --quiet $WHOLE_FILE_OPT \ @@ -683,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" @@ -765,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/CMakeLists.txt b/sql/CMakeLists.txt index 2717858716c..466ec320b25 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -95,7 +95,9 @@ ENDIF() SET (SQL_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/yy_mariadb.cc ${CMAKE_CURRENT_BINARY_DIR}/yy_oracle.cc - ../sql-common/client.c compat56.cc derror.cc des_key_file.cc + ../sql-common/client.c + cset_narrowing.cc + compat56.cc derror.cc des_key_file.cc discover.cc ../sql-common/errmsg.c field.cc field_conv.cc field_comp.cc filesort_utils.cc @@ -219,6 +221,9 @@ MYSQL_ADD_PLUGIN(partition ha_partition.cc STORAGE_ENGINE DEFAULT STATIC_ONLY RECOMPILE_FOR_EMBEDDED) MYSQL_ADD_PLUGIN(sql_sequence ha_sequence.cc STORAGE_ENGINE MANDATORY STATIC_ONLY RECOMPILE_FOR_EMBEDDED) +MYSQL_ADD_PLUGIN(online_alter_log online_alter.cc STORAGE_ENGINE MANDATORY +STATIC_ONLY NOT_EMBEDDED) + ADD_LIBRARY(sql STATIC ${SQL_SOURCE}) MAYBE_DISABLE_IPO(sql) @@ -226,6 +231,7 @@ DTRACE_INSTRUMENT(sql) TARGET_LINK_LIBRARIES(sql mysys mysys_ssl dbug strings vio pcre2-8 tpool + online_alter_log ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${SSL_LIBRARIES} ${LIBSYSTEMD}) diff --git a/sql/backup.cc b/sql/backup.cc index 49c26552bbe..5ce770c3c4c 100644 --- a/sql/backup.cc +++ b/sql/backup.cc @@ -311,6 +311,7 @@ static bool backup_block_ddl(THD *thd) if (server_state.desync_and_pause().is_undefined()) { DBUG_RETURN(1); } + DEBUG_SYNC(thd, "wsrep_backup_stage_after_desync_and_pause"); thd->wsrep_desynced_backup_stage= true; } else @@ -433,6 +434,7 @@ bool backup_end(THD *thd) wsrep_thd_query(thd)); server_state.resume_and_resync(); thd->wsrep_desynced_backup_stage= false; + DEBUG_SYNC(thd, "wsrep_backup_stage_after_resume_and_resync"); } #endif /* WITH_WSREP */ } diff --git a/sql/cset_narrowing.cc b/sql/cset_narrowing.cc new file mode 100644 index 00000000000..abdaec16416 --- /dev/null +++ b/sql/cset_narrowing.cc @@ -0,0 +1,35 @@ +/* + Copyright (c) 2023, 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 02110-1335 USA */ + +#ifdef USE_PRAGMA_IMPLEMENTATION +#pragma implementation // gcc: Class implementation +#endif + +#include "mariadb.h" +#include "sql_priv.h" +#include "sql_select.h" + +Charset_utf8narrow utf8mb3_from_mb4; + +bool Utf8_narrow::should_do_narrowing(const THD *thd, + CHARSET_INFO *field_cset, + CHARSET_INFO *value_cset) +{ + return optimizer_flag(thd, OPTIMIZER_SWITCH_CSET_NARROWING) && + field_cset == &my_charset_utf8mb3_general_ci && + value_cset == &my_charset_utf8mb4_general_ci; +} + diff --git a/sql/cset_narrowing.h b/sql/cset_narrowing.h new file mode 100644 index 00000000000..bb0a3960b8e --- /dev/null +++ b/sql/cset_narrowing.h @@ -0,0 +1,143 @@ +/* + Copyright (c) 2023, 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 02110-1335 USA */ + +#ifndef CSET_NARROWING_H_INCLUDED +#define CSET_NARROWING_H_INCLUDED + +/* + A singleton class to provide "utf8mb3_from_mb4.charset()". + + This is a variant of utf8mb3_general_ci that one can use when they have data + in MB4 and want to make index lookup keys in MB3. +*/ +extern +class Charset_utf8narrow +{ + struct my_charset_handler_st cset_handler; + struct charset_info_st cset; +public: + Charset_utf8narrow() : + cset_handler(*my_charset_utf8mb3_general_ci.cset), + cset(my_charset_utf8mb3_general_ci) /* Copy the CHARSET_INFO structure */ + { + /* Insert our function wc_mb */ + cset_handler.wc_mb= my_wc_mb_utf8mb4_bmp_only; + cset.cset=&cset_handler; + + /* Charsets are compared by their name, so assign a different name */ + LEX_CSTRING tmp= {STRING_WITH_LEN("utf8_mb4_to_mb3")}; + cset.cs_name= tmp; + } + + CHARSET_INFO *charset() { return &cset; } + +} utf8mb3_from_mb4; + + +/* + A class to temporary change a field that uses utf8mb3_general_ci to enable + correct lookup key construction from string value in utf8mb4_general_ci + + Intended usage: + + // can do this in advance: + bool do_narrowing= Utf8_narrow::should_do_narrowing(field, value_cset); + ... + + // This sets the field to do narrowing if necessary: + Utf8_narrow narrow(field, do_narrowing); + + // write to 'field' here + // item->save_in_field(field) or something else + + // Stop doing narrowing + narrow.stop(); +*/ + +class Utf8_narrow +{ + Field *field; + DTCollation save_collation; + +public: + static bool should_do_narrowing(const THD *thd, CHARSET_INFO *field_cset, + CHARSET_INFO *value_cset); + + static bool should_do_narrowing(const Field *field, CHARSET_INFO *value_cset) + { + CHARSET_INFO *field_cset= field->charset(); + THD *thd= field->table->in_use; + return should_do_narrowing(thd, field_cset, value_cset); + } + + Utf8_narrow(Field *field_arg, bool is_applicable) + { + field= NULL; + if (is_applicable) + { + DTCollation mb3_from_mb4= utf8mb3_from_mb4.charset(); + field= field_arg; + save_collation= field->dtcollation(); + field->change_charset(mb3_from_mb4); + } + } + + void stop() + { + if (field) + field->change_charset(save_collation); +#ifndef NDEBUG + field= NULL; +#endif + } + + ~Utf8_narrow() + { + DBUG_ASSERT(!field); + } +}; + + +/* + @brief + Check if two fields can participate in a multiple equality using charset + narrowing. + + @detail + Normally, check_simple_equality() checks this by calling: + + left_field->eq_def(right_field) + + This function does the same but takes into account we might use charset + narrowing: + - collations are not the same but rather an utf8mb{3,4}_general_ci pair + - for field lengths, should compare # characters, not #bytes. +*/ + +inline +bool fields_equal_using_narrowing(const THD *thd, const Field *left, const Field *right) +{ + return + dynamic_cast(left) && + dynamic_cast(right) && + left->real_type() == right->real_type() && + (Utf8_narrow::should_do_narrowing(left, right->charset()) || + Utf8_narrow::should_do_narrowing(right, left->charset())) && + left->char_length() == right->char_length(); +}; + + +#endif /* CSET_NARROWING_H_INCLUDED */ diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc index 61c8f50d1e3..0a284011c41 100644 --- a/sql/ddl_log.cc +++ b/sql/ddl_log.cc @@ -181,6 +181,8 @@ static constexpr unsigned DDL_LOG_BACKUP_OFFSET_POS= 8; /* Sum of the above variables */ static constexpr unsigned DDL_LOG_HEADER_SIZE= 4+2+2+1; +static void ddl_log_free_lists(); + /** Sync the ddl log file. @@ -734,6 +736,7 @@ static bool create_ddl_log() char file_name[FN_REFLEN]; DBUG_ENTER("create_ddl_log"); + ddl_log_free_lists(); global_ddl_log.open= 0; global_ddl_log.created= 1; global_ddl_log.num_entries= 0; @@ -2828,24 +2831,11 @@ int ddl_log_execute_recovery() } -/** - Release all memory allocated to the ddl log and delete the ddl log -*/ - -void ddl_log_release() +static void ddl_log_free_lists() { - char file_name[FN_REFLEN]; - DDL_LOG_MEMORY_ENTRY *free_list; - DDL_LOG_MEMORY_ENTRY *used_list; - DBUG_ENTER("ddl_log_release"); + DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free; + DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used; - if (!global_ddl_log.initialized) - DBUG_VOID_RETURN; - - global_ddl_log.initialized= 0; - - free_list= global_ddl_log.first_free; - used_list= global_ddl_log.first_used; while (used_list) { DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry; @@ -2858,6 +2848,25 @@ void ddl_log_release() my_free(free_list); free_list= tmp; } + global_ddl_log.first_free= global_ddl_log.first_used= 0; +} + + +/** + Release all memory allocated to the ddl log and delete the ddl log +*/ + +void ddl_log_release() +{ + char file_name[FN_REFLEN]; + DBUG_ENTER("ddl_log_release"); + + if (!global_ddl_log.initialized) + DBUG_VOID_RETURN; + + global_ddl_log.initialized= 0; + ddl_log_free_lists(); + my_free(global_ddl_log.file_entry_buf); global_ddl_log.file_entry_buf= 0; close_ddl_log(); diff --git a/sql/deprecation.h b/sql/deprecation.h index 428b13f62c7..67c453685b0 100644 --- a/sql/deprecation.h +++ b/sql/deprecation.h @@ -36,6 +36,10 @@ template static inline void check_deprecated_version(void) ); } +/* + V is the 2-component 4-digit version where something was deprecated. + For example, if deprecated in 11.2: warn_deprecated<1102>(thd, "something") +*/ template static inline void warn_deprecated(THD *thd, const char *what, const char *to= NULL) { @@ -47,6 +51,16 @@ template static inline void warn_deprecated(THD *thd, what, to); } +template static inline void warn_deprecated(const char *what, + const char *to= NULL) +{ + check_deprecated_version(); + sql_print_warning(to && *to + ? "'%s' is deprecated and will be removed in a future release. Please use %s instead" + : "'%s' is deprecated and will be removed in a future release", + what, to); +} + /* Prevent direct usage of the error that bypasses the template */ #undef ER_WARN_DEPRECATED_SYNTAX #undef ER_WARN_DEPRECATED_SYNTAX_WITH_VER diff --git a/sql/field.cc b/sql/field.cc index 0765e7b5dbd..55d7597254c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5046,7 +5046,7 @@ Converter_double_to_longlong::push_warning(THD *thd, } -int Field_real::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) +int Field_real::store_time_dec(const MYSQL_TIME *ltime, uint) { return store(TIME_to_double(ltime)); } @@ -6591,7 +6591,7 @@ int Field_year::store(longlong nr, bool unsigned_val) } -int Field_year::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) +int Field_year::store_time_dec(const MYSQL_TIME *ltime, uint) { ErrConvTime str(ltime); if (Field_year::store(ltime->year, 0)) @@ -7502,7 +7502,8 @@ Field_longstr::cmp_to_string_with_stricter_collation(const Item_bool_func *cond, return !cmp_is_done_using_type_handler_of_this(cond, item) ? Data_type_compatibility::INCOMPATIBLE_DATA_TYPE : (charset() != cond->compare_collation() && - !(cond->compare_collation()->state & MY_CS_BINSORT)) ? + !(cond->compare_collation()->state & MY_CS_BINSORT) && + !Utf8_narrow::should_do_narrowing(this, cond->compare_collation())) ? Data_type_compatibility::INCOMPATIBLE_COLLATION : Data_type_compatibility::OK; } @@ -7513,6 +7514,18 @@ Field_longstr::can_optimize_keypart_ref(const Item_bool_func *cond, const Item *item) const { DBUG_ASSERT(cmp_type() == STRING_RESULT); + /* + So, we have an equality: tbl.string_key = 'abc' + + The comparison is the string comparison. Can we use index lookups to + find matching rows? We can do that when: + - The comparison uses the same collation as tbl.string_key + - the comparison uses binary collation, while tbl.string_key + uses some other collation. + In this case, we will find matches in some collation. For example, for + 'abc' we may find 'abc', 'ABC', and 'äbc'. + But we're certain that will find the row with the identical binary, 'abc'. + */ return cmp_to_string_with_stricter_collation(cond, item); } @@ -7718,9 +7731,10 @@ void Field_string::sql_type(String &res) const */ void Field_string::sql_rpl_type(String *res) const { - CHARSET_INFO *cs=charset(); if (Field_string::has_charset()) { + CHARSET_INFO *cs= res->charset(); + DBUG_ASSERT(cs->mbminlen == 1); size_t length= cs->cset->snprintf(cs, (char*) res->ptr(), res->alloced_length(), "char(%u octets) character set %s", @@ -8187,9 +8201,10 @@ void Field_varstring::sql_type(String &res) const */ void Field_varstring::sql_rpl_type(String *res) const { - CHARSET_INFO *cs=charset(); if (Field_varstring::has_charset()) { + CHARSET_INFO *cs= res->charset(); + DBUG_ASSERT(cs->mbminlen == 1); size_t length= cs->cset->snprintf(cs, (char*) res->ptr(), res->alloced_length(), "varchar(%u octets) character set %s", @@ -9502,14 +9517,14 @@ int Field_set::store(const char *from,size_t length,CHARSET_INFO *cs) { /* This is for reading numbers with LOAD DATA INFILE */ char *end; - tmp= cs->strntoull(from,length,10,&end,&err); - if (err || end != from+length || - tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1)) + tmp= cs->strntoull(from, length, 10, &end, &err); + if (err || end != from + length) { - tmp=0; set_warning(WARN_DATA_TRUNCATED, 1); - err= 1; + store_type(0); + return 1; } + return Field_set::store((longlong) tmp, true/*unsigned*/); } else if (got_warning) set_warning(WARN_DATA_TRUNCATED, 1); @@ -11320,6 +11335,7 @@ void Field::set_warning_truncated_wrong_value(const char *type_arg, void Field::raise_note_cannot_use_key_part(THD *thd, uint keynr, uint part, const LEX_CSTRING &op, + CHARSET_INFO *op_collation, Item *value, Data_type_compatibility reason) const @@ -11340,7 +11356,7 @@ void Field::raise_note_cannot_use_key_part(THD *thd, case Data_type_compatibility::INCOMPATIBLE_COLLATION: { const LEX_CSTRING colf(charset()->coll_name); - const LEX_CSTRING colv(value->collation.collation->coll_name); + const LEX_CSTRING colv(op_collation->coll_name); push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_UNKNOWN_ERROR, "Cannot use key %`.*s part[%u] for lookup: " diff --git a/sql/field.h b/sql/field.h index 6620ed28c8d..2bd82d0e675 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1662,6 +1662,7 @@ public: void print_key_value_binary(String *out, const uchar* key, uint32 length); void raise_note_cannot_use_key_part(THD *thd, uint keynr, uint part, const LEX_CSTRING &op, + CHARSET_INFO *op_collation, Item *value, const Data_type_compatibility reason) const; @@ -1841,6 +1842,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; @@ -2142,7 +2153,7 @@ public: const LEX_CSTRING *field_name_arg, const DTCollation &collation); decimal_digits_t decimals() const override - { return is_created_from_null_item ? 0 : NOT_FIXED_DEC; } + { return is_created_from_null_item ? 0 : DECIMAL_NOT_SPECIFIED; } int save_in_field(Field *to) override { return save_in_field_str(to); } bool memcpy_field_possible(const Field *from) const override { @@ -2312,7 +2323,7 @@ public: Information_schema_numeric_attributes information_schema_numeric_attributes() const override { - return dec == NOT_FIXED_DEC ? + return dec == DECIMAL_NOT_SPECIFIED ? Information_schema_numeric_attributes(field_length) : Information_schema_numeric_attributes(field_length, dec); } @@ -2884,6 +2895,8 @@ public: integers. But in all other cases we treat it as TIME_RESULT! */ }; +static inline decimal_digits_t fix_dec_arg(decimal_digits_t dec_arg) +{ return dec_arg >= FLOATING_POINT_DECIMALS ? DECIMAL_NOT_SPECIFIED : dec_arg; } class Field_float final :public Field_real { public: @@ -2893,19 +2906,13 @@ public: decimal_digits_t dec_arg,bool zero_arg,bool unsigned_arg) :Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, - dec_arg, zero_arg, unsigned_arg) - { - if (dec_arg >= FLOATING_POINT_DECIMALS) - dec_arg= NOT_FIXED_DEC; - } + fix_dec_arg(dec_arg), zero_arg, unsigned_arg) + { } Field_float(uint32 len_arg, bool maybe_null_arg, const LEX_CSTRING *field_name_arg, decimal_digits_t dec_arg) :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0, - NONE, field_name_arg, dec_arg, 0, 0) - { - if (dec_arg >= FLOATING_POINT_DECIMALS) - dec_arg= NOT_FIXED_DEC; - } + NONE, field_name_arg, fix_dec_arg(dec_arg), 0, 0) + { } const Type_handler *type_handler() const override { return &type_handler_float; } enum ha_base_keytype key_type() const override { return HA_KEYTYPE_FLOAT; } @@ -2941,28 +2948,20 @@ public: decimal_digits_t dec_arg,bool zero_arg,bool unsigned_arg) :Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, - dec_arg, zero_arg, unsigned_arg) - { - if (dec_arg >= FLOATING_POINT_DECIMALS) - dec_arg= NOT_FIXED_DEC; - } + fix_dec_arg(dec_arg), zero_arg, unsigned_arg) + { } Field_double(uint32 len_arg, bool maybe_null_arg, const LEX_CSTRING *field_name_arg, decimal_digits_t dec_arg) :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0, - NONE, field_name_arg, dec_arg, 0, 0) - { - if (dec_arg >= FLOATING_POINT_DECIMALS) - dec_arg= NOT_FIXED_DEC; - } + NONE, field_name_arg, fix_dec_arg(dec_arg), 0, 0) + { } Field_double(uint32 len_arg, bool maybe_null_arg, const LEX_CSTRING *field_name_arg, decimal_digits_t dec_arg, bool not_fixed_arg) :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0, - NONE, field_name_arg, dec_arg, 0, 0) + NONE, field_name_arg, fix_dec_arg(dec_arg), 0, 0) { not_fixed= not_fixed_arg; - if (dec_arg >= FLOATING_POINT_DECIMALS) - dec_arg= NOT_FIXED_DEC; } void init_for_tmp_table(Field *org_field, TABLE *new_table) override { diff --git a/sql/filesort.h b/sql/filesort.h index 3c37ebb4045..f2da3b84e1b 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 a615d26b9a9..f7b84ff3be8 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -75,8 +75,7 @@ HA_REC_NOT_IN_SEQ | \ HA_CAN_REPAIR | \ HA_REUSES_FILE_NAMES) -#define PARTITION_DISABLED_TABLE_FLAGS (HA_CAN_GEOMETRY | \ - HA_DUPLICATE_POS | \ +#define PARTITION_DISABLED_TABLE_FLAGS (HA_DUPLICATE_POS | \ HA_CAN_INSERT_DELAYED | \ HA_READ_BEFORE_WRITE_REMOVAL |\ HA_CAN_TABLES_WITHOUT_ROLLBACK) @@ -4315,9 +4314,12 @@ int ha_partition::external_lock(THD *thd, int lock_type) (void) (*file)->ha_external_lock(thd, lock_type); } while (*(++file)); } - if (lock_type == F_WRLCK && m_part_info->part_expr) - m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0); - + if (lock_type == F_WRLCK) + { + if (m_part_info->part_expr) + m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0); + need_info_for_auto_inc(); + } DBUG_RETURN(0); err_handler: @@ -4631,33 +4633,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); @@ -6150,6 +6127,9 @@ int ha_partition::common_first_last(uchar *buf) { int error; + if (table->all_partitions_pruned_away) + return HA_ERR_END_OF_FILE; // No rows matching WHERE + if (unlikely((error= partition_scan_set_up(buf, FALSE)))) return error; if (!m_ordered_scan_ongoing && @@ -11043,10 +11023,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 856583f423f..d450f96f4f9 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1406,9 +1406,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/ha_sequence.cc b/sql/ha_sequence.cc index 1ba57875d52..a3b5c209530 100644 --- a/sql/ha_sequence.cc +++ b/sql/ha_sequence.cc @@ -271,13 +271,26 @@ int ha_sequence::write_row(const uchar *buf) } #ifdef WITH_WSREP - /* We need to start Galera transaction for select NEXT VALUE FOR - sequence if it is not yet started. Note that ALTER is handled - as TOI. */ - if (WSREP_ON && WSREP(thd) && - !thd->wsrep_trx().active() && - wsrep_thd_is_local(thd)) - wsrep_start_transaction(thd, thd->wsrep_next_trx_id()); + if (WSREP_ON && WSREP(thd) && wsrep_thd_is_local(thd)) + { + if (sequence_locked && + (wsrep_thd_is_SR(thd) || wsrep_streaming_enabled(thd))) + { + my_error(ER_NOT_SUPPORTED_YET, MYF(0), + "SEQUENCEs with streaming replication in Galera cluster"); + DBUG_RETURN(HA_ERR_UNSUPPORTED); + } + + /* + We need to start Galera transaction for select NEXT VALUE FOR + sequence if it is not yet started. Note that ALTER is handled + as TOI. + */ + if (!thd->wsrep_trx().active()) + { + wsrep_start_transaction(thd, thd->wsrep_next_trx_id()); + } + } #endif if (likely(!(error= file->update_first_row(buf)))) diff --git a/sql/handler.cc b/sql/handler.cc index a977054d0da..50a8ab37bfb 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -659,6 +659,7 @@ static bool update_optimizer_costs(handlerton *hton) } const char *hton_no_exts[]= { 0 }; +static bool ddl_recovery_done= false; int ha_initialize_handlerton(st_plugin_int *plugin) { @@ -812,6 +813,9 @@ int ha_initialize_handlerton(st_plugin_int *plugin) resolve_sysvar_table_options(hton); update_discovery_counters(hton, 1); + if (ddl_recovery_done && hton->signal_ddl_recovery_done) + hton->signal_ddl_recovery_done(hton); + DBUG_RETURN(ret); err_deinit: @@ -1008,6 +1012,7 @@ void ha_signal_ddl_recovery_done() DBUG_ENTER("ha_signal_ddl_recovery_done"); plugin_foreach(NULL, signal_ddl_recovery_done, MYSQL_STORAGE_ENGINE_PLUGIN, NULL); + ddl_recovery_done= true; DBUG_VOID_RETURN; } @@ -1764,8 +1769,7 @@ int ha_commit_trans(THD *thd, bool all) uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all); /* rw_trans is TRUE when we in a transaction changing data */ - bool rw_trans= is_real_trans && - (rw_ha_count > (thd->is_current_stmt_binlog_disabled()?0U:1U)); + bool rw_trans= is_real_trans && rw_ha_count > 0; MDL_request mdl_backup; DBUG_PRINT("info", ("is_real_trans: %d rw_trans: %d rw_ha_count: %d", is_real_trans, rw_trans, rw_ha_count)); @@ -2597,7 +2601,7 @@ static bool xarecover_decide_to_commit(xid_recovery_member* member, static void xarecover_do_commit_or_rollback(handlerton *hton, xarecover_complete_arg *arg) { - xid_t x; + XA_data x; my_bool rc; xid_recovery_member *member= arg->member; Binlog_offset *ptr_commit_max= arg->binlog_coord; @@ -7314,8 +7318,8 @@ int handler::binlog_log_row(const uchar *before_record, #ifdef HAVE_REPLICATION if (unlikely(!error && table->s->online_alter_binlog && is_root_handler())) - error= binlog_log_row_online_alter(table, before_record, after_record, - log_func); + error= online_alter_log_row(table, before_record, after_record, + log_func); #endif // HAVE_REPLICATION DBUG_RETURN(error); @@ -7853,7 +7857,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/handler.h b/sql/handler.h index 6e887100bee..fe272d841d9 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -557,6 +557,7 @@ enum legacy_db_type DB_TYPE_BLACKHOLE_DB=19, DB_TYPE_PARTITION_DB=20, DB_TYPE_BINLOG=21, + DB_TYPE_ONLINE_ALTER=22, DB_TYPE_PBXT=23, DB_TYPE_PERFORMANCE_SCHEMA=28, DB_TYPE_S3=41, @@ -889,6 +890,7 @@ typedef ulonglong my_xid; // this line is the same as in log_event.h #define COMPATIBLE_DATA_YES 0 #define COMPATIBLE_DATA_NO 1 + /** struct xid_t is binary compatible with the XID structure as in the X/Open CAE Specification, Distributed Transaction Processing: @@ -972,6 +974,13 @@ struct xid_t { }; typedef struct xid_t XID; +struct Online_alter_cache_list; +struct XA_data: XID +{ + Online_alter_cache_list *online_alter_cache= NULL; + XA_data &operator=(const XID &x) { XID::operator=(x); return *this; } +}; + /* Enumerates a sequence in the order of their creation that is in the top-down order of the index file. @@ -1096,6 +1105,7 @@ enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX }; extern MYSQL_PLUGIN_IMPORT st_plugin_int *hton2plugin[MAX_HA]; struct handlerton; + #define view_pseudo_hton ((handlerton *)1) /* @@ -1917,7 +1927,6 @@ struct THD_TRANS }; - /** Either statement transaction or normal transaction - related thread-specific storage engine data. diff --git a/sql/item.cc b/sql/item.cc index 5c4f1704ebe..a385cb67f30 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -941,14 +941,15 @@ bool Item_field::register_field_in_write_map(void *arg) This is used by fix_vcol_expr() when a table is opened - We don't have to check fields that are marked as NO_DEFAULT_VALUE - as the upper level will ensure that all these will be given a value. + We don't have to check non-virtual fields that are marked as + NO_DEFAULT_VALUE as the upper level will ensure that all these + will be given a value. */ bool Item_field::check_field_expression_processor(void *arg) { Field *org_field= (Field*) arg; - if (field->flags & NO_DEFAULT_VALUE_FLAG) + if (field->flags & NO_DEFAULT_VALUE_FLAG && !field->vcol_info) return 0; if ((field->default_value && field->default_value->flags) || field->vcol_info) { @@ -2520,7 +2521,8 @@ bool DTCollation::aggregate(const DTCollation &dt, uint flags) /******************************/ static -void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +void my_coll_agg_error(const DTCollation &c1, const DTCollation &c2, + const char *fname) { my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), c1.collation->coll_name.str, c1.derivation_name(), @@ -2603,10 +2605,17 @@ bool Type_std_attributes::agg_item_collations(DTCollation &c, } +/* + @param single_err When nargs==1, use *single_err as the second aggregated + collation when producing error message. +*/ + bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, const LEX_CSTRING &fname, Item **args, uint nargs, - uint flags, int item_sep) + uint flags, int item_sep, + const Single_coll_err + *single_err) { THD *thd= current_thd; if (thd->lex->is_ps_or_view_context_analysis()) @@ -2644,26 +2653,42 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, args[0]= safe_args[0]; args[item_sep]= safe_args[1]; } - my_coll_agg_error(args, nargs, fname.str, item_sep); + if (nargs == 1 && single_err) + { + /* + Use *single_err to produce an error message mentioning two + collations. + */ + if (single_err->first) + my_coll_agg_error(args[0]->collation, single_err->coll, fname.str); + else + my_coll_agg_error(single_err->coll, args[0]->collation, fname.str); + } + else + my_coll_agg_error(args, nargs, fname.str, item_sep); return TRUE; } if (conv->fix_fields_if_needed(thd, arg)) return TRUE; - Query_arena *arena, backup; - arena= thd->activate_stmt_arena_if_needed(&backup); - if (arena) + 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); + Item_direct_ref_to_item *ref= new (thd->mem_root) Item_direct_ref_to_item(thd, *arg); if ((ref == NULL) || ref->fix_fields(thd, (Item **)&ref)) { - thd->restore_active_arena(arena, &backup); + if (arena) + thd->restore_active_arena(arena, &backup); return TRUE; } *arg= ref; - thd->restore_active_arena(arena, &backup); + if (arena) + thd->restore_active_arena(arena, &backup); ref->change_item(thd, conv); } else @@ -9546,6 +9571,11 @@ bool Item_default_value::eq(const Item *item, bool binary_cmp) const bool Item_default_value::check_field_expression_processor(void *) +{ + return Item_default_value::update_func_default_processor(0); +} + +bool Item_default_value::update_func_default_processor(void *) { field->default_value= ((Item_field *)(arg->real_item()))->field->default_value; return 0; diff --git a/sql/item.h b/sql/item.h index 827300050bb..16ba4514421 100644 --- a/sql/item.h +++ b/sql/item.h @@ -28,8 +28,11 @@ #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" + C_MODE_START #include @@ -1984,7 +1987,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); @@ -2334,6 +2338,7 @@ public: virtual bool check_handler_func_processor(void *arg) { return 0; } virtual bool check_field_expression_processor(void *arg) { return 0; } virtual bool check_func_default_processor(void *arg) { return 0; } + virtual bool update_func_default_processor(void *arg) { return 0; } /* Check if an expression value has allowed arguments, like DATE/DATETIME for date functions. Also used by partitioning code to reject @@ -5410,8 +5415,10 @@ protected: public: // This method is used by Arg_comparator - bool agg_arg_charsets_for_comparison(CHARSET_INFO **cs, Item **a, Item **b) + bool agg_arg_charsets_for_comparison(CHARSET_INFO **cs, Item **a, Item **b, + bool allow_narrowing) { + THD *thd= current_thd; DTCollation tmp; if (tmp.set((*a)->collation, (*b)->collation, MY_COLL_CMP_CONV) || tmp.derivation == DERIVATION_NONE) @@ -5424,11 +5431,40 @@ public: func_name()); return true; } + + if (allow_narrowing && + (*a)->collation.derivation == (*b)->collation.derivation) + { + // allow_narrowing==true only for = and <=> comparisons. + if (Utf8_narrow::should_do_narrowing(thd, (*a)->collation.collation, + (*b)->collation.collation)) + { + // a is a subset, b is a superset (e.g. utf8mb3 vs utf8mb4) + *cs= (*b)->collation.collation; // Compare using the wider cset + return false; + } + else + if (Utf8_narrow::should_do_narrowing(thd, (*b)->collation.collation, + (*a)->collation.collation)) + { + // a is a superset, b is a subset (e.g. utf8mb4 vs utf8mb3) + *cs= (*a)->collation.collation; // Compare using the wider cset + return false; + } + } + /* + If necessary, convert both *a and *b to the collation in tmp: + */ + Single_coll_err error_for_a= {(*b)->collation, true}; + Single_coll_err error_for_b= {(*a)->collation, false}; + if (agg_item_set_converter(tmp, func_name_cstring(), - a, 1, MY_COLL_CMP_CONV, 1) || + a, 1, MY_COLL_CMP_CONV, 1, + /*just for error message*/ &error_for_a) || agg_item_set_converter(tmp, func_name_cstring(), - b, 1, MY_COLL_CMP_CONV, 1)) - return true; + b, 1, MY_COLL_CMP_CONV, 1, + /*just for error message*/ &error_for_b)) + return true; *cs= tmp.collation; return false; } @@ -5455,6 +5491,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 @@ -6702,6 +6746,7 @@ public: bool update_vcol_processor(void *) override { return false; } bool check_field_expression_processor(void *arg) override; bool check_func_default_processor(void *) override { return true; } + bool update_func_default_processor(void *arg) override; bool register_field_in_read_map(void *arg) override; bool walk(Item_processor processor, bool walk_subquery, void *args) override { diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 58ef471bf8c..43ab0e4c23c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -333,6 +333,7 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, !(*item)->with_sum_func()) { TABLE *table= field->table; + Use_relaxed_field_copy urfc(thd); MY_BITMAP *old_maps[2] = { NULL, NULL }; ulonglong UNINIT_VAR(orig_field_val); /* original field value if valid */ bool save_field_value; @@ -351,7 +352,7 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, !(field->table->status & STATUS_NO_RECORD)); if (save_field_value) orig_field_val= field->val_int(); - if (!(*item)->save_in_field_no_warnings(field, 1) && !field->is_null()) + if (!(*item)->save_in_field(field, 1) && !field->is_null()) { int field_cmp= 0; // If item is a decimal value, we must reject it if it was truncated. @@ -456,26 +457,6 @@ void Item_bool_func::raise_note_if_key_become_unused(THD *thd, const Item_args & } -bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp) -{ - DBUG_ASSERT(arg_count >= 2); // Item_func_nullif has arg_count == 3 - - if (args[0]->cmp_type() == STRING_RESULT && - args[1]->cmp_type() == STRING_RESULT) - { - DTCollation tmp; - if (agg_arg_charsets_for_comparison(tmp, args, 2)) - return true; - cmp->m_compare_collation= tmp.collation; - } - // Convert constants when compared to int/year field - DBUG_ASSERT(functype() != LIKE_FUNC); - convert_const_compared_to_int_field(thd); - - return cmp->set_cmp_func(thd, this, &args[0], &args[1], true); -} - - /* Comparison operators remove arguments' dependency on PAD_CHAR_TO_FULL_LENGTH in case of PAD SPACE comparison collations: trailing spaces do not affect @@ -504,8 +485,15 @@ bool Item_bool_rowready_func2::fix_length_and_dec(THD *thd) if (!args[0] || !args[1]) return FALSE; Item_args old_args(args[0], args[1]); - if (setup_args_and_comparator(thd, &cmp)) + convert_const_compared_to_int_field(thd); + Type_handler_hybrid_field_type tmp; + if (tmp.aggregate_for_comparison(func_name_cstring(), args, 2, false) || + tmp.type_handler()->Item_bool_rowready_func2_fix_length_and_dec(thd, + this)) + { + DBUG_ASSERT(thd->is_error()); return true; + } raise_note_if_key_become_unused(thd, old_args); return false; } @@ -525,21 +513,14 @@ bool Item_bool_rowready_func2::fix_length_and_dec(THD *thd) */ int Arg_comparator::set_cmp_func(THD *thd, Item_func_or_sum *owner_arg, + const Type_handler *compare_handler, Item **a1, Item **a2) { owner= owner_arg; set_null= set_null && owner_arg; a= a1; b= a2; - Item *tmp_args[2]= {*a1, *a2}; - Type_handler_hybrid_field_type tmp; - if (tmp.aggregate_for_comparison(owner_arg->func_name_cstring(), tmp_args, 2, - false)) - { - DBUG_ASSERT(thd->is_error()); - return 1; - } - m_compare_handler= tmp.type_handler(); + m_compare_handler= compare_handler; return m_compare_handler->set_comparator_func(thd, this); } @@ -588,9 +569,27 @@ bool Arg_comparator::set_cmp_func_string(THD *thd) { /* We must set cmp_collation here as we may be called from for an automatic - generated item, like in natural join + generated item, like in natural join. + Allow reinterpted superset as subset. + Use charset narrowing only for equalities, as that would allow + to construct ref access. + Non-equality comparisons with constants work without charset narrowing, + the constant gets converted. + Non-equality comparisons with non-constants would need narrowing to + enable range optimizer to handle e.g. + t1.mb3key_col <= const_table.mb4_col + But this doesn't look important. */ - if (owner->agg_arg_charsets_for_comparison(&m_compare_collation, a, b)) + bool allow_narrowing= false; + if (owner->type() == Item::FUNC_ITEM) + { + Item_func::Functype ftype= ((Item_func*)owner)->functype(); + if (ftype == Item_func::EQUAL_FUNC || ftype==Item_func::EQ_FUNC) + allow_narrowing= true; + } + + if (owner->agg_arg_charsets_for_comparison(&m_compare_collation, a, b, + allow_narrowing)) return true; if ((*a)->type() == Item::FUNC_ITEM && @@ -2787,8 +2786,9 @@ Item_func_nullif::fix_length_and_dec(THD *thd) fix_char_length(args[2]->max_char_length()); set_maybe_null(); m_arg0= args[0]; - if (setup_args_and_comparator(thd, &cmp)) - return TRUE; + convert_const_compared_to_int_field(thd); + if (cmp.set_cmp_func(thd, this, &args[0], &args[1], true/*set_null*/)) + return true; /* A special code for EXECUTE..PREPARE. @@ -3459,7 +3459,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 dfb928f90ca..b60a60eef3c 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -58,6 +58,7 @@ class Arg_comparator: public Sql_alloc // when one of arguments is NULL. int set_cmp_func(THD *thd, Item_func_or_sum *owner_arg, + const Type_handler *compare_handler, Item **a1, Item **a2); int compare_not_null_values(longlong val1, longlong val2) @@ -96,11 +97,24 @@ public: bool set_cmp_func_decimal(THD *thd); inline int set_cmp_func(THD *thd, Item_func_or_sum *owner_arg, - Item **a1, Item **a2, bool set_null_arg) + const Type_handler *compare_handler, + Item **a1, Item **a2, bool set_null_arg) { set_null= set_null_arg; - return set_cmp_func(thd, owner_arg, a1, a2); + return set_cmp_func(thd, owner_arg, compare_handler, a1, a2); } + int set_cmp_func(THD *thd, Item_func_or_sum *owner_arg, + Item **a1, Item **a2, bool set_null_arg) + { + Item *tmp_args[2]= { *a1, *a2 }; + Type_handler_hybrid_field_type tmp; + if (tmp.aggregate_for_comparison(owner_arg->func_name_cstring(), + tmp_args, 2, false)) + return 1; + return set_cmp_func(thd, owner_arg, tmp.type_handler(), + a1, a2, set_null_arg); + } + inline int compare() { return (this->*func)(); } int compare_string(); // compare args[0] & args[1] @@ -562,9 +576,17 @@ public: return this; } bool fix_length_and_dec(THD *thd) override; + bool fix_length_and_dec_generic(THD *thd, + const Type_handler *compare_handler) + { + DBUG_ASSERT(args == tmp_arg); + return cmp.set_cmp_func(thd, this, compare_handler, + tmp_arg, tmp_arg + 1, true/*set_null*/); + } int set_cmp_func(THD *thd) { - return cmp.set_cmp_func(thd, this, tmp_arg, tmp_arg + 1, true); + DBUG_ASSERT(args == tmp_arg); + return cmp.set_cmp_func(thd, this, tmp_arg, tmp_arg + 1, true/*set_null*/); } CHARSET_INFO *compare_collation() const override { return cmp.compare_collation(); } @@ -2451,9 +2473,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 4f0df8f732d..b79a30b5d0d 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -419,7 +419,15 @@ class Create_func_decode_oracle : public Create_native_func { public: virtual Item *create_native(THD *thd, const LEX_CSTRING *name, - List *item_list); + List *item_list) + { + if (unlikely(!item_list || item_list->elements < 3)) + { + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); + return NULL; + } + return new (thd->mem_root) Item_func_decode_oracle(thd, *item_list); + } static Create_func_decode_oracle s_singleton; @@ -429,6 +437,30 @@ protected: }; +class Create_func_decode : public Create_native_func +{ +public: + virtual Item *create_native(THD *thd, const LEX_CSTRING *name, + List *item_list) + { + if (unlikely(!item_list || item_list->elements != 2)) + { + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); + return NULL; + } + Item_args args(thd, *item_list); + return new (thd->mem_root) Item_func_decode(thd, args.arguments()[0], + args.arguments()[1]); + } + + static Create_func_decode s_singleton; + +protected: + Create_func_decode() {} + virtual ~Create_func_decode() {} +}; + + class Create_func_concat_ws : public Create_native_func { public: @@ -1609,9 +1641,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; @@ -2030,9 +2060,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; @@ -3214,9 +3242,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 @@ -3248,20 +3274,9 @@ Create_func_decode_histogram::create_2_arg(THD *thd, Item *arg1, Item *arg2) return new (thd->mem_root) Item_func_decode_histogram(thd, arg1, arg2); } -Create_func_decode_oracle Create_func_decode_oracle::s_singleton; +Create_func_decode Create_func_decode::s_singleton; -Item* -Create_func_decode_oracle::create_native(THD *thd, const LEX_CSTRING *name, - List *item_list) -{ - uint arg_count= item_list ? item_list->elements : 0; - if (unlikely(arg_count < 3)) - { - my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); - return NULL; - } - return new (thd->mem_root) Item_func_decode_oracle(thd, *item_list); -} +Create_func_decode_oracle Create_func_decode_oracle::s_singleton; Create_func_concat_ws Create_func_concat_ws::s_singleton; @@ -4609,10 +4624,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; @@ -4830,7 +4842,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); } @@ -5345,7 +5357,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); } @@ -5916,6 +5928,7 @@ const Native_func_registry func_array[] = { { STRING_WITH_LEN("DAYOFMONTH") }, BUILDER(Create_func_dayofmonth)}, { { STRING_WITH_LEN("DAYOFWEEK") }, BUILDER(Create_func_dayofweek)}, { { STRING_WITH_LEN("DAYOFYEAR") }, BUILDER(Create_func_dayofyear)}, + { { STRING_WITH_LEN("DECODE") }, BUILDER(Create_func_decode)}, { { STRING_WITH_LEN("DEGREES") }, BUILDER(Create_func_degrees)}, { { STRING_WITH_LEN("DECODE_HISTOGRAM") }, BUILDER(Create_func_decode_histogram)}, { { STRING_WITH_LEN("DECODE_ORACLE") }, BUILDER(Create_func_decode_oracle)}, @@ -6088,9 +6101,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. @@ -6219,13 +6248,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 803959604c6..ea32d6616f2 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 d95a4da85e2..d0683607d4f 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++) { @@ -1814,7 +1823,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 && @@ -2793,8 +2802,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 @@ -6226,7 +6244,8 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) table= 0; for (uint i=1 ; i < arg_count ; i++) { - item= args[i]= args[i]->real_item(); + + item= args[i]->real_item(); /* When running in PS mode, some Item_field's can already be replaced to Item_func_conv_charset during PREPARE time. This is possible @@ -6315,9 +6334,10 @@ bool Item_func_match::fix_index() for (i=1; i < arg_count; i++) { - if (args[i]->type() != FIELD_ITEM) + Item *real_item= args[i]->real_item(); + if (real_item->type() != FIELD_ITEM) goto err; - item=(Item_field*)args[i]; + item=(Item_field*)real_item; for (keynr=0 ; keynr < fts ; keynr++) { KEY *ft_key=&table->key_info[ft_to_key[keynr]]; diff --git a/sql/item_func.h b/sql/item_func.h index 211d96ccadf..e1d67a73134 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, @@ -80,6 +112,38 @@ public: CASE_SIMPLE_FUNC, // Used by ColumnStore/spider, DATE_FUNC, YEAR_FUNC }; + + /* + A function bitmap. Useful when some operation needs to be applied only + to certain functions. For now we only need to distinguish some + comparison predicates. + */ + enum Bitmap : ulonglong + { + BITMAP_NONE= 0, + BITMAP_EQ= 1ULL << EQ_FUNC, + BITMAP_EQUAL= 1ULL << EQUAL_FUNC, + BITMAP_NE= 1ULL << NE_FUNC, + BITMAP_LT= 1ULL << LT_FUNC, + BITMAP_LE= 1ULL << LE_FUNC, + BITMAP_GE= 1ULL << GE_FUNC, + BITMAP_GT= 1ULL << GT_FUNC, + BITMAP_LIKE= 1ULL << LIKE_FUNC, + BITMAP_BETWEEN= 1ULL << BETWEEN, + BITMAP_IN= 1ULL << IN_FUNC, + BITMAP_MULT_EQUAL= 1ULL << MULT_EQUAL_FUNC, + BITMAP_OTHER= 1ULL << 63, + BITMAP_ALL= 0xFFFFFFFFFFFFFFFFULL, + BITMAP_ANY_EQUALITY= BITMAP_EQ | BITMAP_EQUAL | BITMAP_MULT_EQUAL, + BITMAP_EXCEPT_ANY_EQUALITY= BITMAP_ALL & ~BITMAP_ANY_EQUALITY, + }; + + ulonglong bitmap_bit() const + { + Functype type= functype(); + return 1ULL << (type > 63 ? 63 : type); + } + static scalar_comparison_op functype_to_scalar_comparison_op(Functype type) { switch (type) { @@ -171,9 +235,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; } @@ -389,15 +459,6 @@ public: } } void convert_const_compared_to_int_field(THD *thd); - /** - Prepare arguments and setup a comparator. - Used in Item_func_xxx with two arguments and a comparator, - e.g. Item_bool_func2 and Item_func_nullif. - args[0] or args[1] can be modified: - - converted to character set and collation of the operation - - or replaced to an Item_int_with_ref - */ - bool setup_args_and_comparator(THD *thd, Arg_comparator *cmp); Item_func *get_item_func() override { return this; } bool is_simplified_cond_processor(void *arg) override { return const_item() && !val_int(); } diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 508ea9f644e..f2f76846341 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -909,7 +909,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); @@ -941,21 +941,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); } @@ -1496,10 +1522,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); } @@ -1512,8 +1547,7 @@ bool Item_func_json_contains_path::fix_length_and_dec(THD *thd) return Item_bool_func::fix_length_and_dec(thd); } - -void Item_func_json_contains_path::cleanup() +Item_func_json_contains_path::~Item_func_json_contains_path() { if (tmp_paths) { @@ -1521,7 +1555,6 @@ void Item_func_json_contains_path::cleanup() tmp_paths[i-1].free(); tmp_paths= 0; } - Item_int_func::cleanup(); } @@ -2081,7 +2114,7 @@ return_null: String *Item_func_json_array_insert::val_str(String *str) { json_engine_t je; - String *js= args[0]->val_json(&tmp_js); + String *js= args[0]->val_str(&tmp_js); uint n_arg, n_path; THD *thd= current_thd; @@ -4086,6 +4119,13 @@ int Arg_comparator::compare_e_json_str_basic(Item *j, Item *s) return MY_TEST(sortcmp(res1, res2, compare_collation()) == 0); } +bool Item_func_json_arrayagg::fix_fields(THD *thd, Item **ref) +{ + bool res= Item_func_group_concat::fix_fields(thd, ref); + m_tmp_json.set_charset(collation.collation); + return res; +} + String *Item_func_json_arrayagg::get_str_from_item(Item *i, String *tmp) { @@ -4812,11 +4852,21 @@ If any of them fails, return false, else return true. bool Item_func_json_schema_valid::fix_length_and_dec(THD *thd) { json_engine_t je; - bool res= 0; + bool res= 0, is_schema_constant= args[0]->const_item(); - String *js= args[0]->val_json(&tmp_js); + String *js= NULL; - if ((null_value= args[0]->null_value)) + if (!is_schema_constant) + { + + my_error(ER_JSON_NO_VARIABLE_SCHEMA, MYF(0)); + null_value= 1; + return 0; + } + null_value= args[0]->null_value; + js= args[0]->val_json(&tmp_js); + + if (!js) { null_value= 1; return 0; @@ -5155,8 +5205,21 @@ String* Item_func_json_array_intersect::val_str(String *str) { DBUG_ASSERT(fixed()); - json_engine_t je2, res_je; - String *js2= args[1]->val_json(&tmp_js2); + json_engine_t je2, res_je, je1; + String *js2= args[1]->val_json(&tmp_js2), *js1= args[0]->val_json(&tmp_js1); + + if (parse_for_each_row) + { + if (args[0]->null_value) + goto null_return; + if (hash_inited) + my_hash_free(&items); + if (root_inited) + free_root(&hash_root, MYF(0)); + root_inited= false; + hash_inited= false; + prepare_json_and_create_hash(&je1, js1); + } if (null_value || args[1]->null_value) goto null_return; @@ -5197,18 +5260,10 @@ null_return: return NULL; } -bool Item_func_json_array_intersect::fix_length_and_dec(THD *thd) +void Item_func_json_array_intersect::prepare_json_and_create_hash(json_engine_t *je1, String *js) { - json_engine_t je1; - String *js1= args[0]->val_json(&tmp_js1); - - if (args[0]->null_value) - { - null_value= true; - return FALSE; - } - json_scan_start(&je1, js1->charset(), (const uchar *) js1->ptr(), - (const uchar *) js1->ptr() + js1->length()); + json_scan_start(je1, js->charset(), (const uchar *) js->ptr(), + (const uchar *) js->ptr() + js->length()); /* Scan value uses the hash table to get the intersection of two arrays. */ @@ -5217,18 +5272,40 @@ bool Item_func_json_array_intersect::fix_length_and_dec(THD *thd) init_alloc_root(PSI_NOT_INSTRUMENTED, &hash_root, 1024, 0, MYF(0)); root_inited= true; - if (json_read_value(&je1) || je1.value_type != JSON_VALUE_ARRAY || - create_hash(&je1, &items, hash_inited, &hash_root)) + if (json_read_value(je1) || je1->value_type != JSON_VALUE_ARRAY || + create_hash(je1, &items, hash_inited, &hash_root)) + { + if (je1->s.error) + report_json_error(js, je1, 0); + null_value= 1; + } + + max_length= (args[0]->max_length < args[1]->max_length) ? + args[0]->max_length : args[1]->max_length; +} + +bool Item_func_json_array_intersect::fix_length_and_dec(THD *thd) +{ + json_engine_t je1; + String *js1; + + if (!args[0]->const_item()) { - if (je1.s.error) - report_json_error(js1, &je1, 0); - null_value= 1; - return FALSE; + if (args[1]->const_item()) + { + std::swap(args[0], args[1]); + } + else + { + parse_for_each_row= true; + goto end; + } } - max_length= (args[0]->max_length < args[1]->max_length) ? - args[0]->max_length : args[1]->max_length; + js1= args[0]->val_json(&tmp_js1); + prepare_json_and_create_hash(&je1, js1); +end: set_maybe_null(); return FALSE; } diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index 42255d8d6f6..eb8b723e843 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -266,11 +266,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; }; @@ -337,6 +352,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") }; @@ -344,7 +360,6 @@ public: } bool fix_fields(THD *thd, Item **ref) override; bool fix_length_and_dec(THD *thd) override; - void cleanup() override; longlong val_int() override; Item *get_copy(THD *thd) override { return get_item_copy(thd, this); } @@ -726,6 +741,7 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("json_arrayagg(") }; return name; } + bool fix_fields(THD *thd, Item **ref) override; enum Sumfunctype sum_func() const override { return JSON_ARRAYAGG_FUNC; } String* val_str(String *str) override; @@ -869,9 +885,10 @@ protected: bool hash_inited, root_inited; HASH items; MEM_ROOT hash_root; + bool parse_for_each_row; public: Item_func_json_array_intersect(THD *thd, Item *a, Item *b): - Item_str_func(thd, a, b) { hash_inited= root_inited= false; } + Item_str_func(thd, a, b) { hash_inited= root_inited= parse_for_each_row= false; } String *val_str(String *) override; bool fix_length_and_dec(THD *thd) override; LEX_CSTRING func_name_cstring() const override @@ -889,6 +906,7 @@ public: if (root_inited) free_root(&hash_root, MYF(0)); } + void prepare_json_and_create_hash(json_engine_t *je1, String *js); }; class Item_func_json_object_filter_keys: public Item_str_func diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index b18e4684060..9bf98948487 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2580,13 +2580,31 @@ bool Item_func_trim::fix_length_and_dec(THD *thd) 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(' '); @@ -3626,12 +3644,12 @@ String *Item_func_binlog_gtid_pos::val_str(String *str) String name_str, *name; longlong pos; - if (args[0]->null_value || args[1]->null_value) - goto err; - name= args[0]->val_str(&name_str); pos= args[1]->val_int(); + if (args[0]->null_value || args[1]->null_value) + goto err; + if (pos < 0 || pos > UINT_MAX32) goto err; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index fdae00ae56a..470165d691f 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -362,6 +362,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(THD *thd) override; LEX_CSTRING func_name_cstring() const override @@ -388,10 +394,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 { @@ -490,6 +503,12 @@ public: String *val_str(String *to) override { return val_str_internal(to, NULL); }; bool fix_length_and_dec(THD *thd) 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") }; @@ -508,10 +527,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); } @@ -675,8 +701,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(THD *thd) 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") }; @@ -715,16 +749,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(THD *thd) override { bool res= Item_func_substr::fix_length_and_dec(thd); 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); } @@ -772,17 +815,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(THD *thd) override; + const Schema *schema() const override { return &mariadb_schema; } LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("trim") }; @@ -800,20 +839,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(THD *thd) override { bool res= Item_func_trim::fix_length_and_dec(thd); @@ -835,6 +865,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") }; @@ -852,20 +883,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(THD *thd) override { bool res= Item_func_ltrim::fix_length_and_dec(thd); @@ -883,6 +905,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") }; @@ -900,20 +923,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(THD *thd) override { bool res= Item_func_rtrim::fix_length_and_dec(thd); @@ -1086,6 +1100,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") }; @@ -1456,6 +1476,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(THD *thd) override; }; @@ -1467,7 +1489,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") }; @@ -1488,16 +1518,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(THD *thd) override { bool res= Item_func_rpad::fix_length_and_dec(thd); 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); } @@ -1511,7 +1550,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") }; @@ -1531,16 +1578,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(THD *thd) override { bool res= Item_func_lpad::fix_length_and_dec(thd); 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 aeae52bc8b1..308bcb6e1ae 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1320,18 +1320,10 @@ bool Item_singlerow_subselect::fix_length_and_dec() } unsigned_flag= value->unsigned_flag; /* - If the subquery has no tables (1) and is not a UNION (2), like: - - (SELECT subq_value) - + If the subquery always returns a row, like "(SELECT subq_value)" then its NULLability is the same as subq_value's NULLability. - - (1): A subquery that uses a table will return NULL when the table is empty. - (2): A UNION subquery will return NULL if it produces a "Subquery returns - more than one row" error. */ - if (engine->no_tables() && - engine->engine_type() != subselect_engine::UNION_ENGINE) + if (engine->always_returns_one_row()) set_maybe_null(engine->may_be_null()); else { @@ -1342,6 +1334,32 @@ bool Item_singlerow_subselect::fix_length_and_dec() } + +/* + @brief + Check if we can guarantee that this engine will always produce exactly one + row. + + @detail + Check if the subquery is just + + (SELECT value) + + Then we can guarantee we always return one row. + Selecting from tables may produce more than one row. + HAVING, WHERE or ORDER BY/LIMIT clauses may cause no rows to be produced. +*/ + +bool subselect_single_select_engine::always_returns_one_row() const +{ + st_select_lex *params= select_lex->master_unit()->global_parameters(); + return no_tables() && + !params->limit_params.select_limit && + !params->limit_params.offset_limit && + !select_lex->where && + !select_lex->having; +} + /** Add an expression cache for this subquery if it is needed @@ -2618,10 +2636,6 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, (select_lex->ref_pointer_array[i]->type() == REF_ITEM && ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() == Item_ref::OUTER_REF)); - if (select_lex->ref_pointer_array[i]-> - check_cols(left_expr->element_index(i)->cols())) - DBUG_RETURN(true); - Item *item_eq= new (thd->mem_root) Item_func_eq(thd, new (thd->mem_root) @@ -2688,9 +2702,6 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, (select_lex->ref_pointer_array[i]->type() == REF_ITEM && ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() == Item_ref::OUTER_REF)); - if (select_lex->ref_pointer_array[i]-> - check_cols(left_expr->element_index(i)->cols())) - DBUG_RETURN(true); item= new (thd->mem_root) Item_func_eq(thd, new (thd->mem_root) @@ -3317,8 +3328,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; } } @@ -4033,14 +4048,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; } @@ -4854,7 +4869,7 @@ subselect_uniquesubquery_engine::change_result(Item_subselect *si, @retval FALSE there are some tables in subquery */ -bool subselect_single_select_engine::no_tables() +bool subselect_single_select_engine::no_tables() const { return(select_lex->table_list.elements == 0); } @@ -4884,7 +4899,7 @@ bool subselect_single_select_engine::may_be_null() @retval FALSE there are some tables in subquery */ -bool subselect_union_engine::no_tables() +bool subselect_union_engine::no_tables() const { for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) { @@ -4904,7 +4919,7 @@ bool subselect_union_engine::no_tables() FALSE there are some tables in subquery */ -bool subselect_uniquesubquery_engine::no_tables() +bool subselect_uniquesubquery_engine::no_tables() const { /* returning value is correct, but this method should never be called */ DBUG_ASSERT(FALSE); @@ -5906,7 +5921,7 @@ void subselect_hash_sj_engine::exclude() DBUG_ASSERT(FALSE); } -bool subselect_hash_sj_engine::no_tables() +bool subselect_hash_sj_engine::no_tables() const { DBUG_ASSERT(FALSE); return FALSE; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 8d58e16bb28..f838c0d4c8f 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -874,7 +874,11 @@ public: virtual bool change_result(Item_subselect *si, select_result_interceptor *result, bool temp= FALSE)= 0; - virtual bool no_tables()= 0; + virtual bool no_tables() const = 0; + /* + Return true we can guarantee that the subquery will always return one row. + */ + virtual bool always_returns_one_row() const { return false; } virtual bool is_executed() const { return FALSE; } /* Check if subquery produced any rows during last query execution */ virtual bool no_rows() = 0; @@ -895,25 +899,26 @@ public: subselect_single_select_engine(st_select_lex *select, select_result_interceptor *result, Item_subselect *item); - void cleanup(); - int prepare(THD *thd); - bool fix_length_and_dec(Item_cache** row); - int exec(); - uint cols() const; - uint8 uncacheable(); - void exclude(); - table_map upper_select_const_tables(); - void print (String *str, enum_query_type query_type); + void cleanup() override; + int prepare(THD *thd) override; + bool fix_length_and_dec(Item_cache** row) override; + int exec() override; + uint cols() const override; + uint8 uncacheable() override; + void exclude() override; + table_map upper_select_const_tables() override; + void print(String *str, enum_query_type query_type) override; bool change_result(Item_subselect *si, select_result_interceptor *result, - bool temp); - bool no_tables(); - bool may_be_null(); - bool is_executed() const { return executed; } - bool no_rows(); - virtual enum_engine_type engine_type() { return SINGLE_SELECT_ENGINE; } - int get_identifier(); - void force_reexecution(); + bool temp) override; + bool no_tables() const override; + bool always_returns_one_row() const override; + bool may_be_null() override; + bool is_executed() const override { return executed; } + bool no_rows() override; + enum_engine_type engine_type() override { return SINGLE_SELECT_ENGINE; } + int get_identifier() override; + void force_reexecution() override; void change_select(st_select_lex *new_select) { select_lex= new_select; } friend class subselect_hash_sj_engine; @@ -932,23 +937,23 @@ public: subselect_union_engine(st_select_lex_unit *u, select_result_interceptor *result, Item_subselect *item); - void cleanup(); - int prepare(THD *); - bool fix_length_and_dec(Item_cache** row); - int exec(); - uint cols() const; - uint8 uncacheable(); - void exclude(); - table_map upper_select_const_tables(); - void print (String *str, enum_query_type query_type); + void cleanup() override; + int prepare(THD *) override; + bool fix_length_and_dec(Item_cache** row) override; + int exec() override; + uint cols() const override; + uint8 uncacheable() override; + void exclude() override; + table_map upper_select_const_tables() override; + void print(String *str, enum_query_type query_type) override; bool change_result(Item_subselect *si, select_result_interceptor *result, - bool temp= FALSE); - bool no_tables(); - bool is_executed() const; - void force_reexecution(); - bool no_rows(); - virtual enum_engine_type engine_type() { return UNION_ENGINE; } + bool temp= FALSE) override; + bool no_tables() const override; + bool is_executed() const override; + void force_reexecution() override; + bool no_rows() override; + enum_engine_type engine_type() override { return UNION_ENGINE; } }; @@ -993,24 +998,24 @@ public: DBUG_ASSERT(subs); } ~subselect_uniquesubquery_engine(); - void cleanup(); - int prepare(THD *); - bool fix_length_and_dec(Item_cache** row); - int exec(); - uint cols() const { return 1; } - uint8 uncacheable() { return UNCACHEABLE_DEPENDENT_INJECTED; } - void exclude(); - table_map upper_select_const_tables() { return 0; } - void print (String *str, enum_query_type query_type); + void cleanup() override; + int prepare(THD *) override; + bool fix_length_and_dec(Item_cache** row) override; + int exec() override; + uint cols() const override { return 1; } + uint8 uncacheable() override { return UNCACHEABLE_DEPENDENT_INJECTED; } + void exclude() override; + table_map upper_select_const_tables() override { return 0; } + void print(String *str, enum_query_type query_type) override; bool change_result(Item_subselect *si, select_result_interceptor *result, - bool temp= FALSE); - bool no_tables(); + bool temp= FALSE) override; + bool no_tables() const override; int index_lookup(); /* TIMOUR: this method needs refactoring. */ int scan_table(); bool copy_ref_key(bool skip_constants); - bool no_rows() { return empty_result_set; } - virtual enum_engine_type engine_type() { return UNIQUESUBQUERY_ENGINE; } + bool no_rows() override { return empty_result_set; } + enum_engine_type engine_type() override { return UNIQUESUBQUERY_ENGINE; } }; @@ -1131,26 +1136,26 @@ public: ~subselect_hash_sj_engine(); bool init(List *tmp_columns, uint subquery_id); - void cleanup(); - int prepare(THD *); - int exec(); - void print(String *str, enum_query_type query_type); - uint cols() const { return materialize_engine->cols(); } - uint8 uncacheable() { return materialize_engine->uncacheable(); } - table_map upper_select_const_tables() { return 0; } - bool no_rows() { return !tmp_table->file->stats.records; } - virtual enum_engine_type engine_type() { return HASH_SJ_ENGINE; } + void cleanup() override; + int prepare(THD *) override; + int exec() override; + void print(String *str, enum_query_type query_type) override; + uint cols() const override { return materialize_engine->cols(); } + uint8 uncacheable() override { return materialize_engine->uncacheable(); } + table_map upper_select_const_tables() override { return 0; } + bool no_rows() override { return !tmp_table->file->stats.records; } + enum_engine_type engine_type() override { return HASH_SJ_ENGINE; } /* TODO: factor out all these methods in a base subselect_index_engine class because all of them have dummy implementations and should never be called. */ - bool fix_length_and_dec(Item_cache** row);//=>base class - void exclude(); //=>base class + bool fix_length_and_dec(Item_cache** row) override;//=>base class + void exclude() override; //=>base class //=>base class bool change_result(Item_subselect *si, select_result_interceptor *result, - bool temp= FALSE); - bool no_tables();//=>base class + bool temp= FALSE) override; + bool no_tables() const override;//=>base class protected: /* The engine used to compute the IN predicate. */ @@ -1416,19 +1421,20 @@ public: bool has_covering_null_row_arg, bool has_covering_null_columns_arg, uint count_columns_with_nulls_arg); - int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; } - int exec(); - bool fix_length_and_dec(Item_cache**) { return FALSE; } - uint cols() const { /* TODO: what is the correct value? */ return 1; } - uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; } - void exclude() {} - table_map upper_select_const_tables() { return 0; } + int prepare(THD *thd_arg) override { set_thd(thd_arg); return 0; } + int exec() override; + bool fix_length_and_dec(Item_cache**) override { return FALSE; } + uint cols() const override + { /* TODO: what is the correct value? */ return 1; } + uint8 uncacheable() override { return UNCACHEABLE_DEPENDENT; } + void exclude() override {} + table_map upper_select_const_tables() override { return 0; } bool change_result(Item_subselect*, select_result_interceptor*, - bool temp= FALSE) + bool temp= FALSE) override { DBUG_ASSERT(FALSE); return false; } - bool no_tables() { return false; } - bool no_rows() + bool no_tables() const override { return false; } + bool no_rows() override { /* TODO: It is completely unclear what is the semantics of this @@ -1438,7 +1444,7 @@ public: */ return !(item->get_IN_subquery()->null_value); } - void print(String*, enum_query_type); + void print(String*, enum_query_type) override; friend void subselect_hash_sj_engine::cleanup(); }; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index bbd09a59267..bcaf229dd15 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1296,9 +1296,14 @@ void Item_sum_min_max::setup_hybrid(THD *thd, Item *item, Item *value_arg) /* Don't cache value, as it will change */ if (!item->const_item()) arg_cache->set_used_tables(RAND_TABLE_BIT); + DBUG_ASSERT(item->type_handler_for_comparison() == + value->type_handler_for_comparison()); + DBUG_ASSERT(item->type_handler_for_comparison() == + arg_cache->type_handler_for_comparison()); cmp= new (thd->mem_root) Arg_comparator(); if (cmp) - cmp->set_cmp_func(thd, this, (Item**)&arg_cache, (Item**)&value, FALSE); + cmp->set_cmp_func(thd, this, item->type_handler_for_comparison(), + (Item**)&arg_cache, (Item**)&value, FALSE); DBUG_VOID_RETURN; } @@ -4287,8 +4292,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_stmt_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 165a28abe6a..2026c6edc0f 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -481,23 +481,35 @@ static bool make_date_time(THD *thd, const String *format, uint hours_i; uint weekday; ulong length; - const char *ptr, *end; + const uchar *ptr, *end; struct my_tz curr_tz; Time_zone* curr_timezone= 0; str->length(0); if (l_time->neg) - str->append('-'); - - end= (ptr= format->ptr()) + format->length(); - for (; ptr != end ; ptr++) + str->append_wc('-'); + + end= (ptr= (const uchar *) format->ptr()) + format->length(); + + for ( ; ; ) { - if (*ptr != '%' || ptr+1 == end) - str->append(*ptr); + my_wc_t wc; + int mblen= format->charset()->cset->mb_wc(format->charset(), &wc, ptr, end); + if (mblen < 1) + return false; + ptr+= mblen; + + if (wc != '%' || ptr >= end) + str->append_wc(wc); else { - switch (*++ptr) { + mblen= format->charset()->cset->mb_wc(format->charset(), &wc, ptr, end); + if (mblen < 1) + return false; + ptr+= mblen; + + switch (wc) { case 'M': if (type == MYSQL_TIMESTAMP_TIME || !l_time->month) return 1; @@ -533,8 +545,7 @@ static bool make_date_time(THD *thd, const String *format, case 'D': if (type == MYSQL_TIMESTAMP_TIME) return 1; - length= (uint) (int10_to_str(l_time->day, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 1, '0'); + str->append_zerofill(l_time->day, 1); if (l_time->day >= 10 && l_time->day <= 19) str->append(STRING_WITH_LEN("th")); else @@ -558,73 +569,62 @@ static bool make_date_time(THD *thd, const String *format, case 'Y': if (type == MYSQL_TIMESTAMP_TIME) return 1; - length= (uint) (int10_to_str(l_time->year, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 4, '0'); + str->append_zerofill(l_time->year, 4); break; case 'y': if (type == MYSQL_TIMESTAMP_TIME) return 1; - length= (uint) (int10_to_str(l_time->year%100, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 2, '0'); + str->append_zerofill(l_time->year % 100, 2); break; case 'm': if (type == MYSQL_TIMESTAMP_TIME) return 1; - length= (uint) (int10_to_str(l_time->month, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 2, '0'); + str->append_zerofill(l_time->month, 2); break; case 'c': if (type == MYSQL_TIMESTAMP_TIME) return 1; - length= (uint) (int10_to_str(l_time->month, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 1, '0'); + str->append_zerofill(l_time->month, 1); break; case 'd': if (type == MYSQL_TIMESTAMP_TIME) return 1; - length= (uint) (int10_to_str(l_time->day, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 2, '0'); + str->append_zerofill(l_time->day, 2); break; case 'e': if (type == MYSQL_TIMESTAMP_TIME) return 1; - length= (uint) (int10_to_str(l_time->day, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 1, '0'); + str->append_zerofill(l_time->day, 1); break; case 'f': - length= (uint) (int10_to_str(l_time->second_part, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 6, '0'); + str->append_zerofill((uint) l_time->second_part, 6); break; case 'H': - length= (uint) (int10_to_str(l_time->hour, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 2, '0'); + str->append_zerofill(l_time->hour, 2); break; case 'h': case 'I': hours_i= (l_time->hour%24 + 11)%12+1; - length= (uint) (int10_to_str(hours_i, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 2, '0'); + str->append_zerofill(hours_i, 2); break; case 'i': /* minutes */ - length= (uint) (int10_to_str(l_time->minute, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 2, '0'); + str->append_zerofill(l_time->minute, 2); break; case 'j': + { if (type == MYSQL_TIMESTAMP_TIME || !l_time->month || !l_time->year) return 1; - length= (uint) (int10_to_str(calc_daynr(l_time->year,l_time->month, - l_time->day) - - calc_daynr(l_time->year,1,1) + 1, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 3, '0'); + long value= calc_daynr(l_time->year,l_time->month, l_time->day) - + calc_daynr(l_time->year,1,1) + 1; + str->append_zerofill((uint) value, 3); break; + } case 'k': - length= (uint) (int10_to_str(l_time->hour, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 1, '0'); + str->append_zerofill(l_time->hour, 1); break; case 'l': hours_i= (l_time->hour%24 + 11)%12+1; - length= (uint) (int10_to_str(hours_i, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 1, '0'); + str->append_zerofill(hours_i, 1); break; case 'p': hours_i= l_time->hour%24; @@ -640,8 +640,7 @@ static bool make_date_time(THD *thd, const String *format, break; case 'S': case 's': - length= (uint) (int10_to_str(l_time->second, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 2, '0'); + str->append_zerofill(l_time->second, 2); break; case 'T': length= sprintf(intbuff, "%02d:%02d:%02d", @@ -654,42 +653,39 @@ static bool make_date_time(THD *thd, const String *format, uint year; if (type == MYSQL_TIMESTAMP_TIME) return 1; - length= (uint) (int10_to_str(calc_week(l_time, - (*ptr) == 'U' ? - WEEK_FIRST_WEEKDAY : WEEK_MONDAY_FIRST, - &year), - intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 2, '0'); + + uint value= calc_week(l_time, + wc == 'U' ? WEEK_FIRST_WEEKDAY : + WEEK_MONDAY_FIRST, + &year); + str->append_zerofill(value, 2); } break; case 'v': case 'V': { - uint year; - if (type == MYSQL_TIMESTAMP_TIME) - return 1; - length= (uint) (int10_to_str(calc_week(l_time, - ((*ptr) == 'V' ? - (WEEK_YEAR | WEEK_FIRST_WEEKDAY) : - (WEEK_YEAR | WEEK_MONDAY_FIRST)), - &year), - intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 2, '0'); + uint year; + if (type == MYSQL_TIMESTAMP_TIME) + return 1; + uint value= calc_week(l_time, wc == 'V' ? + (WEEK_YEAR | WEEK_FIRST_WEEKDAY) : + (WEEK_YEAR | WEEK_MONDAY_FIRST), + &year); + str->append_zerofill(value, 2); } break; case 'x': case 'X': { - uint year; - if (type == MYSQL_TIMESTAMP_TIME) - return 1; - (void) calc_week(l_time, - ((*ptr) == 'X' ? - WEEK_YEAR | WEEK_FIRST_WEEKDAY : - WEEK_YEAR | WEEK_MONDAY_FIRST), - &year); - length= (uint) (int10_to_str(year, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 4, '0'); + uint year; + if (type == MYSQL_TIMESTAMP_TIME) + return 1; + (void) calc_week(l_time, + (wc == 'X' ? + WEEK_YEAR | WEEK_FIRST_WEEKDAY : + WEEK_YEAR | WEEK_MONDAY_FIRST), + &year); + str->append_zerofill(year, 4); } break; case 'w': @@ -697,8 +693,7 @@ static bool make_date_time(THD *thd, const String *format, return 1; weekday=calc_weekday(calc_daynr(l_time->year,l_time->month, l_time->day),1); - length= (uint) (int10_to_str(weekday, intbuff, 10) - intbuff); - str->append_with_prefill(intbuff, length, 1, '0'); + str->append_zerofill(weekday, 1); break; case 'z': @@ -728,7 +723,7 @@ static bool make_date_time(THD *thd, const String *format, str->append(curr_tz.abbreviation, strlen(curr_tz.abbreviation)); break; default: - str->append(*ptr); + str->append_wc(wc); break; } } @@ -2436,11 +2431,7 @@ error: static inline bool append_val(int val, int size, String *str) { - ulong len= 0; - char intbuff[15]; - - len= (ulong) (int10_to_str(val, intbuff, 10) - intbuff); - return str->append_with_prefill(intbuff, len, size, '0'); + return str->append_zerofill(val, size); } @@ -3121,6 +3112,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/lex.h b/sql/lex.h index 4900ef59625..fb267326562 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -767,7 +767,6 @@ SYMBOL sql_functions[] = { { "DATE_ADD", SYM(DATE_ADD_INTERVAL)}, { "DATE_SUB", SYM(DATE_SUB_INTERVAL)}, { "DATE_FORMAT", SYM(DATE_FORMAT_SYM)}, - { "DECODE", SYM(DECODE_MARIADB_SYM)}, { "DENSE_RANK", SYM(DENSE_RANK_SYM)}, { "EXTRACT", SYM(EXTRACT_SYM)}, { "FIRST_VALUE", SYM(FIRST_VALUE_SYM)}, diff --git a/sql/lock.cc b/sql/lock.cc index f5bca86693d..a9c866a7641 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -1141,7 +1141,7 @@ void Global_read_lock::unlock_global_read_lock(THD *thd) #ifdef WITH_WSREP if (m_state == GRL_ACQUIRED_AND_BLOCKS_COMMIT && - wsrep_locked_seqno != WSREP_SEQNO_UNDEFINED) + thd->wsrep_desynced_backup_stage) { Wsrep_server_state& server_state= Wsrep_server_state::instance(); if (server_state.state() == Wsrep_server_state::s_donor || @@ -1158,8 +1158,10 @@ void Global_read_lock::unlock_global_read_lock(THD *thd) WSREP_DEBUG("unlock_global_read_lock: waiting for flow control for %s", wsrep_thd_query(thd)); server_state.resume_and_resync(); + DEBUG_SYNC(thd, "wsrep_unlock_global_read_lock_after_resume_and_resync"); wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED; } + thd->wsrep_desynced_backup_stage= false; } #endif /* WITH_WSREP */ @@ -1216,11 +1218,13 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd) server_state.state() != Wsrep_server_state::s_synced)) { paused_seqno= server_state.pause(); + thd->wsrep_desynced_backup_stage= true; } else if (WSREP_NNULL(thd) && server_state.state() == Wsrep_server_state::s_synced) { paused_seqno= server_state.desync_and_pause(); + thd->wsrep_desynced_backup_stage= true; } else { @@ -1231,6 +1235,7 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd) { wsrep_locked_seqno= paused_seqno.get(); } + DEBUG_SYNC(thd, "wsrep_global_read_lock_block_commit_after_pause"); #endif /* WITH_WSREP */ DBUG_RETURN(FALSE); } diff --git a/sql/log.cc b/sql/log.cc index 2f7efda0b4d..f63c6b4b5c4 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -59,6 +59,7 @@ #include "sp_rcontext.h" #include "sp_head.h" #include "sql_table.h" +#include "log_cache.h" #include "wsrep_mysqld.h" #ifdef WITH_WSREP @@ -75,9 +76,6 @@ /* max size of the log message */ #define MAX_LOG_BUFFER_SIZE 1024 #define MAX_TIME_SIZE 32 -#define MY_OFF_T_UNDEF (~(my_off_t)0UL) -/* Truncate cache log files bigger than this */ -#define CACHE_FILE_TRUNC_SIZE 65536 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"") @@ -104,8 +102,6 @@ static int binlog_flush_cache(THD *thd, binlog_cache_mngr *cache_mngr, Log_event *end_ev, bool all, bool using_stmt, bool using_trx, bool is_ro_1pc); -static int binlog_online_alter_end_trans(THD *thd, bool all, bool commit); - static const LEX_CSTRING write_error_msg= { STRING_WITH_LEN("error writing to the binary log") }; @@ -285,272 +281,6 @@ void make_default_log_name(char **out, const char* log_ext, bool once) Helper classes to store non-transactional and transactional data before copying it to the binary log. */ -class binlog_cache_data -{ -public: - binlog_cache_data(bool precompute_checksums_): - before_stmt_pos(MY_OFF_T_UNDEF), m_pending(0), status(0), - incident(FALSE), precompute_checksums(precompute_checksums_), - saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0), - ptr_binlog_cache_disk_use(0) - { - /* - Read the current checksum setting. We will use this setting to decide - whether to pre-compute checksums in the cache. Then when writing the cache - to the actual binlog, another check will be made and checksums recomputed - in the unlikely case that the setting changed meanwhile. - */ - checksum_opt= !precompute_checksums_ ? BINLOG_CHECKSUM_ALG_OFF : - (enum_binlog_checksum_alg)binlog_checksum_options; - } - - ~binlog_cache_data() - { - DBUG_ASSERT(empty()); - close_cached_file(&cache_log); - } - - /* - Return 1 if there is no relevant entries in the cache - - This is: - - Cache is empty - - There are row or critical (DDL?) events in the cache - - The status test is needed to avoid writing entries with only - a table map entry, which would crash in do_apply_event() on the slave - as it assumes that there is always a row entry after a table map. - */ - bool empty() const - { - return (pending() == NULL && - (my_b_write_tell(&cache_log) == 0 || - ((status & (LOGGED_ROW_EVENT | LOGGED_CRITICAL)) == 0))); - } - - Rows_log_event *pending() const - { - return m_pending; - } - - void set_pending(Rows_log_event *const pending_arg) - { - m_pending= pending_arg; - } - - void set_incident(void) - { - incident= TRUE; - } - - bool has_incident(void) - { - return(incident); - } - - void reset() - { - bool cache_was_empty= empty(); - bool truncate_file= (cache_log.file != -1 && - my_b_write_tell(&cache_log) > CACHE_FILE_TRUNC_SIZE); - truncate(0,1); // Forget what's in cache - checksum_opt= !precompute_checksums ? BINLOG_CHECKSUM_ALG_OFF : - (enum_binlog_checksum_alg)binlog_checksum_options; - if (!cache_was_empty) - compute_statistics(); - if (truncate_file) - my_chsize(cache_log.file, 0, 0, MYF(MY_WME)); - - status= 0; - incident= FALSE; - before_stmt_pos= MY_OFF_T_UNDEF; - DBUG_ASSERT(empty()); - } - - my_off_t get_byte_position() const - { - return my_b_tell(&cache_log); - } - - my_off_t get_prev_position() - { - return(before_stmt_pos); - } - - void set_prev_position(my_off_t pos) - { - before_stmt_pos= pos; - } - - void restore_prev_position() - { - truncate(before_stmt_pos); - } - - void restore_savepoint(my_off_t pos) - { - truncate(pos); - if (pos < before_stmt_pos) - before_stmt_pos= MY_OFF_T_UNDEF; - } - - void set_binlog_cache_info(my_off_t param_max_binlog_cache_size, - ulong *param_ptr_binlog_cache_use, - ulong *param_ptr_binlog_cache_disk_use) - { - /* - The assertions guarantee that the set_binlog_cache_info is - called just once and information passed as parameters are - never zero. - - This is done while calling the constructor binlog_cache_mngr. - We cannot set information in the constructor binlog_cache_data - because the space for binlog_cache_mngr is allocated through - a placement new. - - In the future, we can refactor this and change it to avoid - the set_binlog_info. - */ - DBUG_ASSERT(saved_max_binlog_cache_size == 0); - DBUG_ASSERT(param_max_binlog_cache_size != 0); - DBUG_ASSERT(ptr_binlog_cache_use == 0); - DBUG_ASSERT(param_ptr_binlog_cache_use != 0); - DBUG_ASSERT(ptr_binlog_cache_disk_use == 0); - DBUG_ASSERT(param_ptr_binlog_cache_disk_use != 0); - - saved_max_binlog_cache_size= param_max_binlog_cache_size; - ptr_binlog_cache_use= param_ptr_binlog_cache_use; - ptr_binlog_cache_disk_use= param_ptr_binlog_cache_disk_use; - cache_log.end_of_file= saved_max_binlog_cache_size; - } - - void add_status(enum_logged_status status_arg) - { - status|= status_arg; - } - - /* - Cache to store data before copying it to the binary log. - */ - IO_CACHE cache_log; - -protected: - /* - Binlog position before the start of the current statement. - */ - my_off_t before_stmt_pos; - -private: - /* - Pending binrows event. This event is the event where the rows are currently - written. - */ - Rows_log_event *m_pending; - - /* - Bit flags for what has been writing to cache. Used to - discard logs without any data changes. - see enum_logged_status; - */ - uint32 status; - -public: - /* - The algorithm (if any) used to pre-compute checksums in the cache. - Initialized from binlog_checksum_options when the cache is reset. - */ - enum_binlog_checksum_alg checksum_opt; - -private: - /* - This indicates that some events did not get into the cache and most likely - it is corrupted. - */ - bool incident; - - /* Whether the caller requested precomputing checksums. */ - bool precompute_checksums; - - /** - This function computes binlog cache and disk usage. - */ - void compute_statistics() - { - statistic_increment(*ptr_binlog_cache_use, &LOCK_status); - if (cache_log.disk_writes != 0) - { -#ifdef REAL_STATISTICS - statistic_add(*ptr_binlog_cache_disk_use, - cache_log.disk_writes, &LOCK_status); -#else - statistic_increment(*ptr_binlog_cache_disk_use, &LOCK_status); -#endif - cache_log.disk_writes= 0; - } - } - - /* - Stores the values of maximum size of the cache allowed when this cache - is configured. This corresponds to either - . max_binlog_cache_size or max_binlog_stmt_cache_size. - */ - my_off_t saved_max_binlog_cache_size; - - /* - Stores a pointer to the status variable that keeps track of the in-memory - cache usage. This corresponds to either - . binlog_cache_use or binlog_stmt_cache_use. - */ - ulong *ptr_binlog_cache_use; - - /* - Stores a pointer to the status variable that keeps track of the disk - cache usage. This corresponds to either - . binlog_cache_disk_use or binlog_stmt_cache_disk_use. - */ - ulong *ptr_binlog_cache_disk_use; - - /* - It truncates the cache to a certain position. This includes deleting the - pending event. - */ - void truncate(my_off_t pos, bool reset_cache=0) - { - DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos)); - cache_log.error=0; - if (pending()) - { - delete pending(); - set_pending(0); - } -#ifndef DBUG_OFF - my_bool res= -#endif - reinit_io_cache(&cache_log, WRITE_CACHE, pos, 0, reset_cache); - DBUG_ASSERT(res == 0); - cache_log.end_of_file= saved_max_binlog_cache_size; - } - - binlog_cache_data& operator=(const binlog_cache_data& info); - binlog_cache_data(const binlog_cache_data& info); -}; - - -class online_alter_cache_data: public Sql_alloc, public ilist_node<>, - public binlog_cache_data -{ -public: - online_alter_cache_data() : binlog_cache_data(false), - hton(nullptr), sink_log(nullptr), sv_list(nullptr) { } - void store_prev_position() - { - before_stmt_pos= my_b_write_tell(&cache_log); - } - - handlerton *hton; - Cache_flip_event_log *sink_log; - SAVEPOINT *sv_list; -}; void Log_event_writer::add_status(enum_logged_status status) { @@ -2258,7 +1988,6 @@ int binlog_rollback_by_xid(handlerton *hton, XID *xid) DBUG_ASSERT(thd->lex->sql_command == SQLCOM_XA_ROLLBACK || (thd->transaction->xid_state.get_state_code() == XA_ROLLBACK_ONLY)); - rc= binlog_rollback(hton, thd, TRUE); thd->ha_data[hton->slot].ha_info[1].reset(); @@ -2286,15 +2015,16 @@ inline bool is_prepared_xa(THD *thd) static bool trans_cannot_safely_rollback(THD *thd, bool all) { DBUG_ASSERT(ending_trans(thd, all)); + ulong binlog_format= thd->wsrep_binlog_format(thd->variables.binlog_format); return ((thd->variables.option_bits & OPTION_BINLOG_THIS_TRX) || (trans_has_updated_non_trans_table(thd) && - thd->wsrep_binlog_format() == BINLOG_FORMAT_STMT) || + binlog_format == BINLOG_FORMAT_STMT) || (thd->transaction->all.has_modified_non_trans_temp_table() && - thd->wsrep_binlog_format() == BINLOG_FORMAT_MIXED) || + binlog_format == BINLOG_FORMAT_MIXED) || (trans_has_updated_non_trans_table(thd) && ending_single_stmt_trans(thd,all) && - thd->wsrep_binlog_format() == BINLOG_FORMAT_MIXED) || + binlog_format == BINLOG_FORMAT_MIXED) || is_prepared_xa(thd)); } @@ -2340,61 +2070,6 @@ static int binlog_commit_flush_xa_prepare(THD *thd, bool all, return (binlog_flush_cache(thd, cache_mngr, &end_evt, all, TRUE, TRUE)); } -#ifdef HAVE_REPLICATION -int binlog_log_row_online_alter(TABLE* table, const uchar *before_record, - const uchar *after_record, Log_func *log_func) -{ - THD *thd= table->in_use; - - if (!table->online_alter_cache) - { - table->online_alter_cache= online_alter_binlog_get_cache_data(thd, table); - trans_register_ha(thd, false, binlog_hton, 0); - if (thd->in_multi_stmt_transaction_mode()) - trans_register_ha(thd, true, binlog_hton, 0); - } - - // We need to log all columns for the case if alter table changes primary key - DBUG_ASSERT(!before_record || bitmap_is_set_all(table->read_set)); - MY_BITMAP *old_rpl_write_set= table->rpl_write_set; - table->rpl_write_set= &table->s->all_set; - - table->online_alter_cache->store_prev_position(); - int error= (*log_func)(thd, table, table->s->online_alter_binlog, - table->online_alter_cache, - table->file->has_transactions_and_rollback(), - BINLOG_ROW_IMAGE_FULL, - before_record, after_record); - - table->rpl_write_set= old_rpl_write_set; - - if (unlikely(error)) - { - table->online_alter_cache->restore_prev_position(); - return HA_ERR_RBR_LOGGING_FAILED; - } - - return 0; -} - -static void -binlog_online_alter_cleanup(ilist &list, bool ending_trans) -{ - if (ending_trans) - { - auto it= list.begin(); - while (it != list.end()) - { - auto &cache= *it++; - cache.sink_log->release(); - cache.reset(); - delete &cache; - } - list.clear(); - DBUG_ASSERT(list.empty()); - } -} -#endif // HAVE_REPLICATION /** This function is called once after each statement. @@ -2412,12 +2087,7 @@ int binlog_commit(THD *thd, bool all, bool ro_1pc) PSI_stage_info org_stage; DBUG_ENTER("binlog_commit"); - IF_DBUG(bool commit_online= !thd->online_alter_cache_list.empty(),); - bool is_ending_transaction= ending_trans(thd, all); - error= binlog_online_alter_end_trans(thd, all, true); - if (error) - DBUG_RETURN(error); binlog_cache_mngr *const cache_mngr= thd->binlog_get_cache_mngr(); /* @@ -2425,7 +2095,7 @@ int binlog_commit(THD *thd, bool all, bool ro_1pc) */ if (!cache_mngr) { - DBUG_ASSERT(WSREP(thd) || commit_online || + DBUG_ASSERT(WSREP(thd) || (thd->lex->sql_command != SQLCOM_XA_PREPARE && !(thd->lex->sql_command == SQLCOM_XA_COMMIT && thd->lex->xa_opt == XA_ONE_PHASE))); @@ -2523,17 +2193,13 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) DBUG_ENTER("binlog_rollback"); bool is_ending_trans= ending_trans(thd, all); - - bool rollback_online= !thd->online_alter_cache_list.empty(); - if (rollback_online) - binlog_online_alter_end_trans(thd, all, 0); int error= 0; binlog_cache_mngr *const cache_mngr= thd->binlog_get_cache_mngr(); if (!cache_mngr) { - DBUG_ASSERT(WSREP(thd) || rollback_online); - DBUG_ASSERT(thd->lex->sql_command != SQLCOM_XA_ROLLBACK || rollback_online); + DBUG_ASSERT(WSREP(thd)); + DBUG_ASSERT(thd->lex->sql_command != SQLCOM_XA_ROLLBACK); DBUG_RETURN(0); } @@ -2586,6 +2252,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) } else if (likely(!error)) { + ulong binlog_format= thd->wsrep_binlog_format(thd->variables.binlog_format); if (is_ending_trans && trans_cannot_safely_rollback(thd, all)) error= binlog_rollback_flush_trx_cache(thd, all, cache_mngr); /* @@ -2602,9 +2269,9 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) (!(thd->transaction->stmt.has_created_dropped_temp_table() && !thd->is_current_stmt_binlog_format_row()) && (!stmt_has_updated_non_trans_table(thd) || - thd->wsrep_binlog_format() != BINLOG_FORMAT_STMT) && + binlog_format != BINLOG_FORMAT_STMT) && (!thd->transaction->stmt.has_modified_non_trans_temp_table() || - thd->wsrep_binlog_format() != BINLOG_FORMAT_MIXED))) + binlog_format != BINLOG_FORMAT_MIXED))) error= binlog_truncate_trx_cache(thd, cache_mngr, all); } @@ -2697,6 +2364,23 @@ bool Event_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 +Event_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: @@ -2726,9 +2410,6 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) int error= 1; DBUG_ENTER("binlog_savepoint_set"); - if (!mysql_bin_log.is_open() && !thd->online_alter_cache_list.empty()) - DBUG_RETURN(0); - char buf[1024]; String log_query(buf, sizeof(buf), &my_charset_bin); @@ -2761,9 +2442,6 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) { DBUG_ENTER("binlog_savepoint_rollback"); - if (!mysql_bin_log.is_open() && !thd->online_alter_cache_list.empty()) - DBUG_RETURN(0); - /* Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some non-transactional table. Otherwise, truncate the binlog cache starting @@ -6529,7 +6207,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 (check_write_error(thd) && cache_data && + if (check_cache_error(thd, cache_data) && thd->lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) && table->current_lock == F_WRLCK) cache_data->set_incident(); @@ -6537,54 +6215,6 @@ write_err: } -#ifdef HAVE_REPLICATION -static online_alter_cache_data * -online_alter_binlog_setup_cache_data(MEM_ROOT *root, TABLE_SHARE *share) -{ - static ulong online_alter_cache_use= 0, online_alter_cache_disk_use= 0; - - auto cache= new (root) online_alter_cache_data(); - if (!cache || open_cached_file(&cache->cache_log, mysql_tmpdir, - LOG_PREFIX, (size_t)binlog_cache_size, MYF(MY_WME))) - { - delete cache; - return NULL; - } - - share->online_alter_binlog->acquire(); - cache->hton= share->db_type(); - cache->sink_log= share->online_alter_binlog; - - my_off_t binlog_max_size= SIZE_T_MAX; // maximum possible cache size - DBUG_EXECUTE_IF("online_alter_small_cache", binlog_max_size= 4096;); - - cache->set_binlog_cache_info(binlog_max_size, - &online_alter_cache_use, - &online_alter_cache_disk_use); - cache->store_prev_position(); - return cache; -} - - -online_alter_cache_data *online_alter_binlog_get_cache_data(THD *thd, TABLE *table) -{ - ilist &list= thd->online_alter_cache_list; - - /* we assume it's very rare to have more than one online ALTER running */ - for (auto &cache: list) - { - if (cache.sink_log == table->s->online_alter_binlog) - return &cache; - } - - MEM_ROOT *root= &thd->transaction->mem_root; - auto *new_cache_data= online_alter_binlog_setup_cache_data(root, table->s); - list.push_back(*new_cache_data); - - return new_cache_data; -} -#endif - binlog_cache_mngr *THD::binlog_get_cache_mngr() const { return (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton); @@ -6680,7 +6310,7 @@ Event_log::flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event, binlog_cache_data *cache_data, bool is_transactional) { - DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)"); + DBUG_ENTER("Event_log::flush_and_set_pending_rows_event(event)"); DBUG_ASSERT(WSREP_EMULATE_BINLOG(thd) || is_open()); DBUG_PRINT("enter", ("event: %p", event)); @@ -6694,20 +6324,37 @@ Event_log::flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event, /* 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; } @@ -7382,7 +7029,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(); } @@ -7810,129 +7457,6 @@ uint MYSQL_BIN_LOG::next_file_id() return res; } -static int binlog_online_alter_end_trans(THD *thd, bool all, bool commit) -{ - DBUG_ENTER("binlog_online_alter_end_trans"); - int error= 0; -#ifdef HAVE_REPLICATION - if (thd->online_alter_cache_list.empty()) - DBUG_RETURN(0); - - bool is_ending_transaction= ending_trans(thd, all); - - for (auto &cache: thd->online_alter_cache_list) - { - auto *binlog= cache.sink_log; - DBUG_ASSERT(binlog); - bool non_trans= cache.hton->flags & HTON_NO_ROLLBACK // Aria - || !cache.hton->rollback; - bool do_commit= (commit && is_ending_transaction) || non_trans; - - if (commit || non_trans) - { - // Do not set STMT_END for last event to leave table open in altering thd - error= binlog_flush_pending_rows_event(thd, false, true, binlog, &cache); - } - - if (do_commit) - { - /* - If the cache wasn't reinited to write, then it remains empty after - the last write. - */ - if (my_b_bytes_in_cache(&cache.cache_log) && likely(!error)) - { - DBUG_ASSERT(cache.cache_log.type != READ_CACHE); - mysql_mutex_lock(binlog->get_log_lock()); - error= binlog->write_cache_raw(thd, &cache.cache_log); - mysql_mutex_unlock(binlog->get_log_lock()); - } - } - else if (!commit) // rollback - { - DBUG_ASSERT(!non_trans); - cache.restore_prev_position(); - } - else - { - DBUG_ASSERT(!is_ending_transaction); - cache.store_prev_position(); - } - - - if (error) - { - my_error(ER_ERROR_ON_WRITE, MYF(ME_ERROR_LOG), - binlog->get_name(), errno); - binlog_online_alter_cleanup(thd->online_alter_cache_list, - is_ending_transaction); - DBUG_RETURN(error); - } - } - - binlog_online_alter_cleanup(thd->online_alter_cache_list, - is_ending_transaction); - - for (TABLE *table= thd->open_tables; table; table= table->next) - table->online_alter_cache= NULL; -#endif // HAVE_REPLICATION - DBUG_RETURN(error); -} - -SAVEPOINT** find_savepoint_in_list(THD *thd, LEX_CSTRING name, - SAVEPOINT ** const list); - -SAVEPOINT* savepoint_add(THD *thd, LEX_CSTRING name, SAVEPOINT **list, - int (*release_old)(THD*, SAVEPOINT*)); - -int online_alter_savepoint_set(THD *thd, LEX_CSTRING name) -{ - - DBUG_ENTER("binlog_online_alter_savepoint"); -#ifdef HAVE_REPLICATION - if (thd->online_alter_cache_list.empty()) - DBUG_RETURN(0); - - if (savepoint_alloc_size < sizeof (SAVEPOINT) + sizeof(my_off_t)) - savepoint_alloc_size= sizeof (SAVEPOINT) + sizeof(my_off_t); - - for (auto &cache: thd->online_alter_cache_list) - { - if (cache.hton->savepoint_set == NULL) - continue; - - SAVEPOINT *sv= savepoint_add(thd, name, &cache.sv_list, NULL); - if(unlikely(sv == NULL)) - DBUG_RETURN(1); - my_off_t *pos= (my_off_t*)(sv+1); - *pos= cache.get_byte_position(); - - sv->prev= cache.sv_list; - cache.sv_list= sv; - } -#endif - DBUG_RETURN(0); -} - -int online_alter_savepoint_rollback(THD *thd, LEX_CSTRING name) -{ - DBUG_ENTER("online_alter_savepoint_rollback"); -#ifdef HAVE_REPLICATION - for (auto &cache: thd->online_alter_cache_list) - { - if (cache.hton->savepoint_set == NULL) - continue; - - SAVEPOINT **sv= find_savepoint_in_list(thd, name, &cache.sv_list); - // sv is null if savepoint was set up before online table was modified - my_off_t pos= *sv ? *(my_off_t*)(*sv+1) : 0; - - cache.restore_savepoint(pos); - } - -#endif - DBUG_RETURN(0); -} int Event_log::write_cache_raw(THD *thd, IO_CACHE *cache) { @@ -9158,13 +8682,10 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) DEBUG_SYNC(leader->thd, "commit_loop_entry_commit_ordered"); ++num_commits; + set_current_thd(current->thd); if (current->cache_mngr->using_xa && likely(!current->error) && !DBUG_IF("skip_commit_ordered")) - { - mysql_mutex_lock(¤t->thd->LOCK_thd_data); run_commit_ordered(current->thd, current->all); - mysql_mutex_unlock(¤t->thd->LOCK_thd_data); - } current->thd->wakeup_subsequent_commits(current->error); /* @@ -9181,6 +8702,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) } current= next; } + set_current_thd(leader->thd); DEBUG_SYNC(leader->thd, "commit_after_group_run_commit_ordered"); mysql_mutex_unlock(&LOCK_commit_ordered); DEBUG_SYNC(leader->thd, "commit_after_group_release_commit_ordered"); @@ -9201,6 +8723,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 2ba6ffa2b79..f1da71643c4 100644 --- a/sql/log.h +++ b/sql/log.h @@ -402,6 +402,7 @@ public: bool is_transactional); void set_write_error(THD *thd, bool is_transactional); static bool check_write_error(THD *thd); + static bool check_cache_error(THD *thd, binlog_cache_data *cache_data); int write_cache(THD *thd, binlog_cache_data *cache_data); int write_cache_raw(THD *thd, IO_CACHE *cache); char* get_name() { return name; } @@ -989,6 +990,7 @@ public: bool write_incident(THD *thd); void write_binlog_checkpoint_event_already_locked(const char *name, uint len); bool write_table_map(THD *thd, TABLE *table, bool with_annotate); + void start_union_events(THD *thd, query_id_t query_id_param); void stop_union_events(THD *thd); bool is_query_in_union(THD *thd, query_id_t query_id_param); @@ -1349,9 +1351,8 @@ int binlog_flush_pending_rows_event(THD *thd, bool stmt_end, binlog_cache_data *cache_data); Rows_log_event* binlog_get_pending_rows_event(binlog_cache_mngr *cache_mngr, bool use_trans_cache); -int binlog_log_row_online_alter(TABLE* table, const uchar *before_record, - const uchar *after_record, Log_func *log_func); -online_alter_cache_data *online_alter_binlog_get_cache_data(THD *thd, TABLE *table); +int online_alter_log_row(TABLE* table, const uchar *before_record, + const uchar *after_record, Log_func *log_func); binlog_cache_data* binlog_get_cache_data(binlog_cache_mngr *cache_mngr, bool use_trans_cache); @@ -1445,8 +1446,4 @@ int binlog_commit_by_xid(handlerton *hton, XID *xid); int binlog_rollback_by_xid(handlerton *hton, XID *xid); bool write_bin_log_start_alter(THD *thd, bool& partial_alter, uint64 start_alter_id, bool log_if_exists); - -int online_alter_savepoint_set(THD *thd, LEX_CSTRING name); -int online_alter_savepoint_rollback(THD *thd, LEX_CSTRING name); - #endif /* LOG_H */ diff --git a/sql/log_cache.h b/sql/log_cache.h new file mode 100644 index 00000000000..cdff752b806 --- /dev/null +++ b/sql/log_cache.h @@ -0,0 +1,272 @@ +/* + Copyright (c) 2023, MariaDB plc + + 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-1335 USA +*/ + +#include "log_event.h" + +static constexpr my_off_t MY_OFF_T_UNDEF= ~0ULL; +/** Truncate cache log files bigger than this */ +static constexpr my_off_t CACHE_FILE_TRUNC_SIZE = 65536; + + +class binlog_cache_data +{ +public: + binlog_cache_data(bool precompute_checksums): + before_stmt_pos(MY_OFF_T_UNDEF), m_pending(0), status(0), + incident(FALSE), precompute_checksums(precompute_checksums), + saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0), + ptr_binlog_cache_disk_use(0) + { + /* + Read the current checksum setting. We will use this setting to decide + whether to pre-compute checksums in the cache. Then when writing the cache + to the actual binlog, another check will be made and checksums recomputed + in the unlikely case that the setting changed meanwhile. + */ + checksum_opt= !precompute_checksums ? BINLOG_CHECKSUM_ALG_OFF : + (enum_binlog_checksum_alg)binlog_checksum_options; + } + + ~binlog_cache_data() + { + DBUG_ASSERT(empty()); + close_cached_file(&cache_log); + } + + /* + Return 1 if there is no relevant entries in the cache + + This is: + - Cache is empty + - There are row or critical (DDL?) events in the cache + + The status test is needed to avoid writing entries with only + a table map entry, which would crash in do_apply_event() on the slave + as it assumes that there is always a row entry after a table map. + */ + bool empty() const + { + return (pending() == NULL && + (my_b_write_tell(&cache_log) == 0 || + ((status & (LOGGED_ROW_EVENT | LOGGED_CRITICAL)) == 0))); + } + + Rows_log_event *pending() const + { + return m_pending; + } + + void set_pending(Rows_log_event *const pending_arg) + { + m_pending= pending_arg; + } + + void set_incident(void) + { + incident= TRUE; + } + + bool has_incident(void) const + { + return(incident); + } + + void reset() + { + bool cache_was_empty= empty(); + bool truncate_file= (cache_log.file != -1 && + my_b_write_tell(&cache_log) > CACHE_FILE_TRUNC_SIZE); + truncate(0,1); // Forget what's in cache + checksum_opt= !precompute_checksums ? BINLOG_CHECKSUM_ALG_OFF : + (enum_binlog_checksum_alg)binlog_checksum_options; + if (!cache_was_empty) + compute_statistics(); + if (truncate_file) + my_chsize(cache_log.file, 0, 0, MYF(MY_WME)); + + status= 0; + incident= FALSE; + before_stmt_pos= MY_OFF_T_UNDEF; + DBUG_ASSERT(empty()); + } + + my_off_t get_byte_position() const + { + return my_b_tell(&cache_log); + } + + my_off_t get_prev_position() const + { + return(before_stmt_pos); + } + + void set_prev_position(my_off_t pos) + { + before_stmt_pos= pos; + } + + void restore_prev_position() + { + truncate(before_stmt_pos); + } + + void restore_savepoint(my_off_t pos) + { + truncate(pos); + if (pos < before_stmt_pos) + before_stmt_pos= MY_OFF_T_UNDEF; + } + + void set_binlog_cache_info(my_off_t param_max_binlog_cache_size, + ulong *param_ptr_binlog_cache_use, + ulong *param_ptr_binlog_cache_disk_use) + { + /* + The assertions guarantee that the set_binlog_cache_info is + called just once and information passed as parameters are + never zero. + + This is done while calling the constructor binlog_cache_mngr. + We cannot set information in the constructor binlog_cache_data + because the space for binlog_cache_mngr is allocated through + a placement new. + + In the future, we can refactor this and change it to avoid + the set_binlog_info. + */ + DBUG_ASSERT(saved_max_binlog_cache_size == 0); + DBUG_ASSERT(param_max_binlog_cache_size != 0); + DBUG_ASSERT(ptr_binlog_cache_use == 0); + DBUG_ASSERT(param_ptr_binlog_cache_use != 0); + DBUG_ASSERT(ptr_binlog_cache_disk_use == 0); + DBUG_ASSERT(param_ptr_binlog_cache_disk_use != 0); + + saved_max_binlog_cache_size= param_max_binlog_cache_size; + ptr_binlog_cache_use= param_ptr_binlog_cache_use; + ptr_binlog_cache_disk_use= param_ptr_binlog_cache_disk_use; + cache_log.end_of_file= saved_max_binlog_cache_size; + } + + void add_status(enum_logged_status status_arg) + { + status|= status_arg; + } + + /* + Cache to store data before copying it to the binary log. + */ + IO_CACHE cache_log; + +protected: + /* + Binlog position before the start of the current statement. + */ + my_off_t before_stmt_pos; + +private: + /* + Pending binrows event. This event is the event where the rows are currently + written. + */ + Rows_log_event *m_pending; + + /* + Bit flags for what has been writing to cache. Used to + discard logs without any data changes. + see enum_logged_status; + */ + uint32 status; + +public: + /* + The algorithm (if any) used to pre-compute checksums in the cache. + Initialized from binlog_checksum_options when the cache is reset. + */ + enum_binlog_checksum_alg checksum_opt; + +private: + /* + This indicates that some events did not get into the cache and most likely + it is corrupted. + */ + bool incident; + + /* Whether the caller requested precomputing checksums. */ + bool precompute_checksums; + + /** + This function computes binlog cache and disk usage. + */ + void compute_statistics() + { + statistic_increment(*ptr_binlog_cache_use, &LOCK_status); + if (cache_log.disk_writes != 0) + { +#ifdef REAL_STATISTICS + statistic_add(*ptr_binlog_cache_disk_use, + cache_log.disk_writes, &LOCK_status); +#else + statistic_increment(*ptr_binlog_cache_disk_use, &LOCK_status); +#endif + cache_log.disk_writes= 0; + } + } + + /* + Stores the values of maximum size of the cache allowed when this cache + is configured. This corresponds to either + . max_binlog_cache_size or max_binlog_stmt_cache_size. + */ + my_off_t saved_max_binlog_cache_size; + + /* + Stores a pointer to the status variable that keeps track of the in-memory + cache usage. This corresponds to either + . binlog_cache_use or binlog_stmt_cache_use. + */ + ulong *ptr_binlog_cache_use; + + /* + Stores a pointer to the status variable that keeps track of the disk + cache usage. This corresponds to either + . binlog_cache_disk_use or binlog_stmt_cache_disk_use. + */ + ulong *ptr_binlog_cache_disk_use; + + /* + It truncates the cache to a certain position. This includes deleting the + pending event. + */ + void truncate(my_off_t pos, bool reset_cache=0) + { + DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos)); + cache_log.error=0; + if (pending()) + { + delete pending(); + set_pending(0); + } + my_bool res __attribute__((unused))= + reinit_io_cache(&cache_log, WRITE_CACHE, pos, 0, reset_cache); + DBUG_ASSERT(res == 0); + cache_log.end_of_file= saved_max_binlog_cache_size; + } + + binlog_cache_data& operator=(const binlog_cache_data& info); + binlog_cache_data(const binlog_cache_data& info); +}; diff --git a/sql/log_event.cc b/sql/log_event.cc index d7439fc0a67..41ddc038594 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -880,7 +880,7 @@ 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, size_t max_allowed_packet) { DBUG_ENTER("Log_event::read_log_event(IO_CACHE*,Format_description_log_event*...)"); @@ -921,8 +921,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: @@ -933,13 +937,7 @@ err: if (force_opt) DBUG_RETURN(new Unknown_log_event()); #endif - if (event.length() >= LOG_EVENT_MINIMAL_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 @@ -949,6 +947,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() >= LOG_EVENT_MINIMAL_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); } @@ -962,7 +973,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_binlog_checksum_alg alg; @@ -1031,7 +1043,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 16f16e50169..d53d5204cbb 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1404,14 +1404,15 @@ 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, size_t max_allowed_packet); 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) { - return read_log_event(file, description_event, crc_check, get_max_packet()); + return read_log_event(file, description_event, crc_check, print_errors, + get_max_packet()); } /** @@ -1557,7 +1558,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/log_event_server.cc b/sql/log_event_server.cc index 6030202adc7..ae715e870c9 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -2881,6 +2881,9 @@ Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg, sa_seq_no= thd->get_binlog_start_alter_seq_no(); flags2|= FL_DDL; } + + DBUG_ASSERT(thd_arg->lex->sql_command != SQLCOM_CREATE_SEQUENCE || + (flags2 & FL_DDL) || thd_arg->in_multi_stmt_transaction_mode()); } diff --git a/sql/mdl.cc b/sql/mdl.cc index 6cb27efba12..32374415a2e 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -262,6 +262,12 @@ const char *dbug_print_mdl(MDL_ticket *mdl_ticket) } +const char *dbug_print(MDL_ticket *mdl_ticket) +{ + return dbug_print_mdl(mdl_ticket); +} + + static int mdl_dbug_print_lock(MDL_ticket *mdl_ticket, void *arg, bool granted) { String *tmp= (String*) arg; @@ -276,6 +282,7 @@ static int mdl_dbug_print_lock(MDL_ticket *mdl_ticket, void *arg, bool granted) const char *mdl_dbug_print_locks() { thread_local String tmp; + tmp.length(0); mdl_iterate(mdl_dbug_print_lock, (void*) &tmp); return tmp.c_ptr(); } diff --git a/sql/mdl.h b/sql/mdl.h index 06cfdf224d1..384878a1bc9 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -945,7 +945,8 @@ public: already has received some signal or closed signal slot. */ - void init(MDL_context_owner *arg) { m_owner= arg; } + void init(MDL_context_owner *arg) { m_owner= arg; reset(); } + void reset() { m_deadlock_overweight= 0; } void set_needs_thr_lock_abort(bool needs_thr_lock_abort) { @@ -1054,7 +1055,7 @@ private: */ MDL_wait_for_subgraph *m_waiting_for; LF_PINS *m_pins; - uint m_deadlock_overweight= 0; + uint m_deadlock_overweight; private: MDL_ticket *find_ticket(MDL_request *mdl_req, enum_mdl_duration *duration); @@ -1102,6 +1103,26 @@ private: /* metadata_lock_info plugin */ friend int i_s_metadata_lock_info_fill_row(MDL_ticket*, void*); +#ifndef DBUG_OFF +public: + /** + This is for the case when the thread opening the table does not acquire + the lock itself, but utilizes a lock guarantee from another MDL context. + + For example, in InnoDB, MDL is acquired by the purge_coordinator_task, + but the table may be opened and used in a purge_worker_task. + The coordinator thread holds the lock for the duration of worker's purge + job, or longer, possibly reusing shared MDL for different workers and jobs. + */ + MDL_context *lock_warrant= NULL; + + inline bool is_lock_warrantee(MDL_key::enum_mdl_namespace ns, + const char *db, const char *name, + enum_mdl_type mdl_type) const + { + return lock_warrant && lock_warrant->is_lock_owner(ns, db, name, mdl_type); + } +#endif }; diff --git a/sql/my_apc.cc b/sql/my_apc.cc index 9777deb399a..50e88abf88e 100644 --- a/sql/my_apc.cc +++ b/sql/my_apc.cc @@ -201,13 +201,16 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call, This should be called periodically by the APC target thread. */ -void Apc_target::process_apc_requests() +void Apc_target::process_apc_requests(bool force) { while (1) { Call_request *request; - - mysql_mutex_lock(LOCK_thd_kill_ptr); + + if (force) + mysql_mutex_lock(LOCK_thd_kill_ptr); + else if (mysql_mutex_trylock(LOCK_thd_kill_ptr)) + break; // Mutex is blocked, try again later if (!(request= get_first_in_queue())) { /* No requests in the queue */ diff --git a/sql/my_apc.h b/sql/my_apc.h index 2c0a9ade314..29fa3172a12 100644 --- a/sql/my_apc.h +++ b/sql/my_apc.h @@ -70,10 +70,10 @@ public: bool process= !--enabled && have_apc_requests(); mysql_mutex_unlock(LOCK_thd_kill_ptr); if (unlikely(process)) - process_apc_requests(); + process_apc_requests(true); } - void process_apc_requests(); + void process_apc_requests(bool force); /* A lightweight function, intended to be used in frequent checks like this: diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fb897d0326e..9526773ad78 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5322,7 +5322,6 @@ static int init_server_components() MARIADB_REMOVED_OPTION("innodb-change-buffering"), /* removed in 11.3 */ - MARIADB_REMOVED_OPTION("debug"), MARIADB_REMOVED_OPTION("date-format"), MARIADB_REMOVED_OPTION("datetime-format"), MARIADB_REMOVED_OPTION("time-format"), @@ -8106,6 +8105,9 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument, test_flags= argument ? ((uint) atoi(argument) & ~TEST_BLOCKING) : 0; opt_endinfo=1; break; + case OPT_SECURE_AUTH: + warn_deprecated<1006>("--secure-auth"); + break; case (int) OPT_ISAM_LOG: opt_myisam_log=1; break; diff --git a/sql/mysqld.h b/sql/mysqld.h index bdaab87eaf3..11e1ee1c8da 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -850,7 +850,7 @@ enum options_mysqld OPT_SSL_KEY, OPT_WANT_CORE, OPT_MYSQL_COMPATIBILITY, - OPT_TLS_VERSION, + OPT_TLS_VERSION, OPT_SECURE_AUTH, OPT_MYSQL_TO_BE_IMPLEMENTED, OPT_SEQURE_FILE_PRIV, OPT_which_is_always_the_last @@ -892,6 +892,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 | @@ -912,15 +917,15 @@ 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), + // Print only the SELECT part, even for INSERT...SELECT - QT_SELECT_ONLY = (1 << 13) + QT_SELECT_ONLY = (1 << 14) }; diff --git a/sql/online_alter.cc b/sql/online_alter.cc new file mode 100644 index 00000000000..da18b6f9466 --- /dev/null +++ b/sql/online_alter.cc @@ -0,0 +1,455 @@ +/* + Copyright (c) 2023, MariaDB plc + + 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-1335 USA +*/ + +#include "my_global.h" +#include "handler.h" +#include "sql_class.h" +#include "log_cache.h" + + +static handlerton *online_alter_hton; + +typedef void *sv_id_t; + +struct Online_alter_cache_list: ilist +{ + sv_id_t savepoint_id= 0; +}; + +struct table_savepoint: ilist_node<> +{ + sv_id_t id; + my_off_t log_prev_pos; + table_savepoint(sv_id_t id, my_off_t pos): id(id), log_prev_pos(pos){} +}; + +class online_alter_cache_data: public ilist_node<>, + public binlog_cache_data +{ +public: + online_alter_cache_data() : binlog_cache_data(false), + hton(nullptr), sink_log(nullptr) { } + void store_prev_position() + { + before_stmt_pos= my_b_write_tell(&cache_log); + } + + handlerton *hton; + Cache_flip_event_log *sink_log; + ilist sv_list; + /** + Finds savepoint with specified id and returns its associated data. + Cleans up all the savepoints up to the found one. + */ + my_off_t pop_sv_until(sv_id_t id) + { + my_off_t pos= 0; + auto it= sv_list.begin(); + auto sentinel= it->prev; + while (pos == 0 && it != sv_list.end()) + { + table_savepoint &sv= *it; + ++it; + if (sv.id == id) + pos= sv.log_prev_pos; + delete &sv; + } + sentinel->next= &*it; // drop the range from the list + it->prev= sentinel; + return pos; + } + void cleanup_sv() + { + pop_sv_until((sv_id_t)1); // Erase the whole list + } +}; + + +static +online_alter_cache_data *setup_cache_data(MEM_ROOT *root, TABLE_SHARE *share) +{ + static ulong online_alter_cache_use= 0, online_alter_cache_disk_use= 0; + + auto cache= new online_alter_cache_data(); + if (!cache || open_cached_file(&cache->cache_log, mysql_tmpdir, LOG_PREFIX, + (size_t)binlog_cache_size, MYF(MY_WME))) + { + delete cache; + return NULL; + } + + share->online_alter_binlog->acquire(); + cache->hton= share->db_type(); + cache->sink_log= share->online_alter_binlog; + + my_off_t binlog_max_size= SIZE_T_MAX; // maximum possible cache size + DBUG_EXECUTE_IF("online_alter_small_cache", binlog_max_size= 4096;); + + cache->set_binlog_cache_info(binlog_max_size, + &online_alter_cache_use, + &online_alter_cache_disk_use); + cache->store_prev_position(); + return cache; +} + + +static Online_alter_cache_list &get_cache_list(handlerton *ht, THD *thd) +{ + void *data= thd_get_ha_data(thd, ht); + DBUG_ASSERT(data); + return *(Online_alter_cache_list*)data; +} + + +static Online_alter_cache_list &get_or_create_cache_list(THD *thd) +{ + void *data= thd_get_ha_data(thd, online_alter_hton); + if (!data) + { + data= new Online_alter_cache_list(); + thd_set_ha_data(thd, online_alter_hton, data); + } + return *(Online_alter_cache_list*)data; +} + + +static online_alter_cache_data* get_cache_data(THD *thd, TABLE *table) +{ + auto &cache_list= get_or_create_cache_list(thd); + /* we assume it's very rare to have more than one online ALTER running */ + for (auto &cache: cache_list) + { + if (cache.sink_log == table->s->online_alter_binlog) + return &cache; + } + + MEM_ROOT *root= &thd->transaction->mem_root; + auto *new_cache_data= setup_cache_data(root, table->s); + cache_list.push_back(*new_cache_data); + + return new_cache_data; +} + + +int online_alter_log_row(TABLE* table, const uchar *before_record, + const uchar *after_record, Log_func *log_func) +{ + THD *thd= table->in_use; + + if (!table->online_alter_cache) + { + table->online_alter_cache= get_cache_data(thd, table); + trans_register_ha(thd, false, online_alter_hton, 0); + if (thd->in_multi_stmt_transaction_mode()) + trans_register_ha(thd, true, online_alter_hton, 0); + } + + // We need to log all columns for the case if alter table changes primary key + DBUG_ASSERT(!before_record || bitmap_is_set_all(table->read_set)); + MY_BITMAP *old_rpl_write_set= table->rpl_write_set; + table->rpl_write_set= &table->s->all_set; + + table->online_alter_cache->store_prev_position(); + int error= (*log_func)(thd, table, table->s->online_alter_binlog, + table->online_alter_cache, + table->file->has_transactions_and_rollback(), + BINLOG_ROW_IMAGE_FULL, + before_record, after_record); + + table->rpl_write_set= old_rpl_write_set; + + if (unlikely(error)) + { + table->online_alter_cache->restore_prev_position(); + return HA_ERR_RBR_LOGGING_FAILED; + } + + return 0; +} + + +static void +cleanup_cache_list(ilist &list, bool ending_trans) +{ + if (ending_trans) + { + auto it= list.begin(); + while (it != list.end()) + { + auto &cache= *it++; + cache.sink_log->release(); + cache.reset(); + cache.cleanup_sv(); + delete &cache; + } + list.clear(); + DBUG_ASSERT(list.empty()); + } +} + + +static +int online_alter_end_trans(Online_alter_cache_list &cache_list, THD *thd, + bool is_ending_transaction, bool commit) +{ + DBUG_ENTER("online_alter_end_trans"); + int error= 0; + + if (cache_list.empty()) + DBUG_RETURN(0); + + for (auto &cache: cache_list) + { + auto *binlog= cache.sink_log; + DBUG_ASSERT(binlog); + bool non_trans= cache.hton->flags & HTON_NO_ROLLBACK // Aria + || !cache.hton->rollback; + bool do_commit= (commit && is_ending_transaction) || non_trans; + + if (commit || non_trans) + { + // Do not set STMT_END for last event to leave table open in altering thd + error= binlog_flush_pending_rows_event(thd, false, true, binlog, &cache); + } + + if (do_commit) + { + /* + If the cache wasn't reinited to write, then it remains empty after + the last write. + */ + if (my_b_bytes_in_cache(&cache.cache_log) && likely(!error)) + { + DBUG_ASSERT(cache.cache_log.type != READ_CACHE); + mysql_mutex_lock(binlog->get_log_lock()); + error= binlog->write_cache_raw(thd, &cache.cache_log); + mysql_mutex_unlock(binlog->get_log_lock()); + } + } + else if (!commit) // rollback + { + DBUG_ASSERT(!non_trans); + cache.restore_prev_position(); + } + else + { + DBUG_ASSERT(!is_ending_transaction); + cache.store_prev_position(); + } + + + if (error) + { + my_error(ER_ERROR_ON_WRITE, MYF(ME_ERROR_LOG), + binlog->get_name(), errno); + cleanup_cache_list(cache_list, is_ending_transaction); + DBUG_RETURN(error); + } + } + + cleanup_cache_list(cache_list, is_ending_transaction); + + DBUG_RETURN(error); +} + +void cleanup_tables(THD *thd) +{ + for (TABLE *table= thd->open_tables; table; table= table->next) + table->online_alter_cache= NULL; +} + +static +int online_alter_savepoint_set(handlerton *hton, THD *thd, sv_id_t sv_id) +{ + DBUG_ENTER("binlog_online_alter_savepoint"); + auto &cache_list= get_cache_list(hton, thd); + if (cache_list.empty()) + DBUG_RETURN(0); + + for (auto &cache: cache_list) + { + if (cache.hton->savepoint_set == NULL) + continue; + + auto *sv= new table_savepoint(sv_id, cache.get_byte_position()); + if(unlikely(sv == NULL)) + DBUG_RETURN(1); + cache.sv_list.push_front(*sv); + } + DBUG_RETURN(0); +} + +static +int online_alter_savepoint_rollback(handlerton *hton, THD *thd, sv_id_t sv_id) +{ + DBUG_ENTER("online_alter_savepoint_rollback"); + + auto &cache_list= get_cache_list(hton, thd); + for (auto &cache: cache_list) + { + if (cache.hton->savepoint_set == NULL) + continue; + + // There's no savepoint if it was set up before online table was modified. + // In that case, restore to 0. + my_off_t pos= cache.pop_sv_until(sv_id); + + cache.restore_savepoint(pos); + } + + DBUG_RETURN(0); +} + +static int online_alter_commit(handlerton *hton, THD *thd, bool all) +{ + int res; + bool is_ending_transaction= ending_trans(thd, all); + if (is_ending_transaction + && thd->transaction->xid_state.get_state_code() == XA_PREPARED) + { + res= hton->commit_by_xid(hton, thd->transaction->xid_state.get_xid()); + // cleanup was already done by prepare() + } + else + { + res= online_alter_end_trans(get_cache_list(hton, thd), thd, + is_ending_transaction, true); + cleanup_tables(thd); + } + return res; +}; + +static int online_alter_rollback(handlerton *hton, THD *thd, bool all) +{ + int res; + bool is_ending_transaction= ending_trans(thd, all); + if (is_ending_transaction + && thd->transaction->xid_state.get_state_code() == XA_PREPARED) + { + res= hton->rollback_by_xid(hton, thd->transaction->xid_state.get_xid()); + // cleanup was already done by prepare() + } + else + { + res= online_alter_end_trans(get_cache_list(hton, thd), thd, + is_ending_transaction, false); + cleanup_tables(thd); + } + return res; +}; + +static int online_alter_prepare(handlerton *hton, THD *thd, bool all) +{ + auto &cache_list= get_cache_list(hton, thd); + int res= 0; + if (ending_trans(thd, all)) + { + thd->transaction->xid_state.set_online_alter_cache(&cache_list); + thd_set_ha_data(thd, hton, NULL); + } + else + { + res= online_alter_end_trans(cache_list, thd, false, true); + } + + cleanup_tables(thd); + return res; +}; + +static int online_alter_commit_by_xid(handlerton *hton, XID *x) +{ + auto *xid= static_cast(x); + if (likely(xid->online_alter_cache == NULL)) + return 1; + int res= online_alter_end_trans(*xid->online_alter_cache, current_thd, + true, true); + delete xid->online_alter_cache; + xid->online_alter_cache= NULL; + return res; +}; + +static int online_alter_rollback_by_xid(handlerton *hton, XID *x) +{ + auto *xid= static_cast(x); + if (likely(xid->online_alter_cache == NULL)) + return 1; + int res= online_alter_end_trans(*xid->online_alter_cache, current_thd, + true, false); + delete xid->online_alter_cache; + xid->online_alter_cache= NULL; + return res; +}; + +static int online_alter_close_connection(handlerton *hton, THD *thd) +{ + auto *cache_list= (Online_alter_cache_list*)thd_get_ha_data(thd, hton); + + DBUG_ASSERT(!cache_list || cache_list->empty()); + delete cache_list; + thd_set_ha_data(thd, hton, NULL); + return 0; +} + + +static int online_alter_log_init(void *p) +{ + online_alter_hton= (handlerton *)p; + online_alter_hton->db_type= DB_TYPE_ONLINE_ALTER; + online_alter_hton->savepoint_offset= 0; + online_alter_hton->close_connection= online_alter_close_connection; + + online_alter_hton->savepoint_set= online_alter_savepoint_set; + online_alter_hton->savepoint_rollback= online_alter_savepoint_rollback; + online_alter_hton->savepoint_rollback_can_release_mdl= + [](handlerton *hton, THD *thd){ return true; }; + + online_alter_hton->commit= online_alter_commit; + online_alter_hton->rollback= online_alter_rollback; + + + online_alter_hton->recover= [](handlerton*, XID*, uint){ return 0; }; + online_alter_hton->prepare= online_alter_prepare; + online_alter_hton->commit_by_xid= online_alter_commit_by_xid; + online_alter_hton->rollback_by_xid= online_alter_rollback_by_xid; + + online_alter_hton->drop_table= [](handlerton *, const char*) { return -1; }; + online_alter_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN + | HTON_NO_ROLLBACK; + return 0; +} + +struct st_mysql_storage_engine online_alter_storage_engine= +{ MYSQL_HANDLERTON_INTERFACE_VERSION }; + +maria_declare_plugin(online_alter_log) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &online_alter_storage_engine, + "online_alter_log", + "MariaDB PLC", + "A pseudo storage engine for the online alter log", + PLUGIN_LICENSE_GPL, + online_alter_log_init, + NULL, + 0x0100, // 1.0 + NULL, // no status vars + NULL, // no sysvars + "1.0", + MariaDB_PLUGIN_MATURITY_STABLE +} +maria_declare_plugin_end; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index cd8c249c331..387d39e293c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2705,18 +2705,26 @@ static int fill_used_fields_bitmap(PARAM *param) force_quick_range is really needed. RETURN - -1 if error or impossible select (i.e. certainly no rows will be selected) - 0 if can't use quick_select - 1 if found usable ranges and quick select has been successfully created. + SQL_SELECT:: + IMPOSSIBLE_RANGE, + impossible select (i.e. certainly no rows will be selected) + ERROR, + an error occurred, either memory or in evaluating conditions + OK = 1, + either + found usable ranges and quick select has been successfully created. + or can't use quick_select */ -int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, - table_map prev_tables, - ha_rows limit, bool force_quick_range, - bool ordered_output, - bool remove_false_parts_of_where, - bool only_single_index_range_scan, - bool suppress_unusable_key_notes) +quick_select_return +SQL_SELECT::test_quick_select(THD *thd, + key_map keys_to_use, + table_map prev_tables, + ha_rows limit, bool force_quick_range, + bool ordered_output, + bool remove_false_parts_of_where, + bool only_single_index_range_scan, + Item_func::Bitmap note_unusable_keys) { uint idx; Item *notnull_cond= NULL; @@ -2724,7 +2732,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, SEL_ARG **backup_keys= 0; ha_rows table_records= head->stat_records(); handler *file= head->file; - bool impossible_range= 0; + quick_select_return returnval= OK; + DBUG_ENTER("SQL_SELECT::test_quick_select"); DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu", (ulong) keys_to_use.to_ulonglong(), (ulong) prev_tables, @@ -2739,7 +2748,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, head->with_impossible_ranges.clear_all(); DBUG_ASSERT(!head->is_filled_at_execution()); if (keys_to_use.is_clear_all() || head->is_filled_at_execution()) - DBUG_RETURN(0); + DBUG_RETURN(OK); records= table_records; notnull_cond= head->notnull_cond; if (file->ha_table_flags() & HA_NON_COMPARABLE_ROWID) @@ -2781,7 +2790,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, bool force_group_by= false, group_by_optimization_used= false; if (check_stack_overrun(thd, 2*STACK_MIN_SIZE + sizeof(PARAM), buff)) - DBUG_RETURN(0); // Fatal error flag is set + DBUG_RETURN(ERROR); // Fatal error flag is set /* set up parameter that is passed to all functions */ bzero((void*) ¶m, sizeof(param)); @@ -2801,9 +2810,9 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, param.max_key_parts= 0; param.remove_false_where_parts= remove_false_parts_of_where; param.force_default_mrr= ordered_output; - param.note_unusable_keys= (!suppress_unusable_key_notes && - thd->give_notes_for_unusable_keys()); - + param.note_unusable_keys= thd->give_notes_for_unusable_keys() ? + note_unusable_keys : + Item_func::BITMAP_NONE; param.possible_keys.clear_all(); thd->no_errors=1; // Don't warn about NULL @@ -2818,7 +2827,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, { thd->no_errors=0; free_root(&alloc,MYF(0)); // Return memory & allocator - DBUG_RETURN(-1); // Error + DBUG_RETURN(ERROR); } key_parts= param.key_parts; @@ -2888,7 +2897,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, { thd->no_errors=0; free_root(&alloc,MYF(0)); // Return memory & allocator - DBUG_RETURN(-1); // Error + DBUG_RETURN(ERROR); } thd->mem_root= &alloc; @@ -2947,8 +2956,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, { if (tree->type == SEL_TREE::IMPOSSIBLE) { - records= 0; - impossible_range= 1; /* Return -1 from this function. */ + records=0L; + returnval= IMPOSSIBLE_RANGE; read_time= (double) HA_POS_ERROR; trace_range.add("impossible_range", true); goto free_mem; @@ -2968,7 +2977,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, thd->no_errors=0; thd->mem_root= param.old_root; free_root(&alloc, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(ERROR); } } @@ -3144,7 +3153,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if (best_trp) { records= best_trp->records; - impossible_range= records == 0; // No matching rows + if (records == 0) + returnval= IMPOSSIBLE_RANGE; if (!(quick= best_trp->make_quick(¶m, TRUE)) || quick->init()) { delete quick; @@ -3182,7 +3192,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, limit rows if we are using a key */ set_if_smaller(records, table_records); - DBUG_RETURN(impossible_range ? -1 : MY_TEST(quick)); + DBUG_RETURN(returnval); } /**************************************************************************** @@ -3651,6 +3661,7 @@ end_of_range_loop: init_sql_alloc(key_memory_quick_range_select_root, &alloc, thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); + bzero((void*) ¶m, sizeof(param)); param.thd= thd; param.mem_root= &alloc; param.old_root= thd->mem_root; @@ -4106,7 +4117,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) range_par->remove_jump_scans= FALSE; range_par->real_keynr[0]= 0; range_par->alloced_sel_args= 0; - range_par->note_unusable_keys= 0; + range_par->note_unusable_keys= Item_func::BITMAP_NONE; thd->no_errors=1; // Don't warn about NULL thd->mem_root=&alloc; @@ -9025,9 +9036,11 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param, if (field->result_type() == STRING_RESULT && field->charset() != compare_collation()) { - if (param->note_unusable_keys) + if (param->note_unusable_keys & BITMAP_LIKE) field->raise_note_cannot_use_key_part(param->thd, keynr, key_part->part, - func_name_cstring(), value, + func_name_cstring(), + compare_collation(), + value, Data_type_compatibility:: INCOMPATIBLE_COLLATION); DBUG_RETURN(0); @@ -9043,9 +9056,11 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param, field->type_handler() == &type_handler_enum || field->type_handler() == &type_handler_set) { - if (param->note_unusable_keys) + if (param->note_unusable_keys & BITMAP_LIKE) field->raise_note_cannot_use_key_part(param->thd, keynr, key_part->part, - func_name_cstring(), value, + func_name_cstring(), + compare_collation(), + value, Data_type_compatibility:: INCOMPATIBLE_DATA_TYPE); DBUG_RETURN(0); @@ -9150,7 +9165,8 @@ Field::can_optimize_scalar_range(const RANGE_OPT_PARAM *param, TODO: Perhaps we also need to raise a similar note when a partition could not be used (when using_real_indexes==false). */ - if (param->using_real_indexes && param->note_unusable_keys) + if (param->using_real_indexes && param->note_unusable_keys && + (param->note_unusable_keys & cond->bitmap_bit())) { DBUG_ASSERT(keynr < table->s->keys); /* @@ -9164,6 +9180,7 @@ Field::can_optimize_scalar_range(const RANGE_OPT_PARAM *param, */ raise_note_cannot_use_key_part(param->thd, keynr, key_part->part, scalar_comparison_op_to_lex_cstring(op), + cond->compare_collation(), value, compat); } return compat; @@ -9284,11 +9301,28 @@ SEL_ARG *Field_str::get_mm_leaf(RANGE_OPT_PARAM *prm, KEY_PART *key_part, const Item_bool_func *cond, scalar_comparison_op op, Item *value) { + int err; DBUG_ENTER("Field_str::get_mm_leaf"); if (can_optimize_scalar_range(prm, key_part, cond, op, value) != Data_type_compatibility::OK) DBUG_RETURN(0); - int err= value->save_in_field_no_warnings(this, 1); + + { + /* + Do CharsetNarrowing if necessary + This means that we are temporary changing the character set of the + current key field to make key lookups possible. + This is needed when comparing an utf8mb3 key field with an utf8mb4 value. + See cset_narrowing.h for more details. + */ + bool do_narrowing= + Utf8_narrow::should_do_narrowing(this, value->collation.collation); + Utf8_narrow narrow(this, do_narrowing); + + err= value->save_in_field_no_warnings(this, 1); + narrow.stop(); + } + if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0) DBUG_RETURN(&null_element); if (err > 0) @@ -15595,13 +15629,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. @@ -15858,8 +15885,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 @@ -15882,12 +15908,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); } @@ -15933,34 +15953,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(); @@ -15989,8 +15995,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 69f556334b8..59a01e5bb8d 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -891,7 +891,10 @@ public: */ bool remove_false_where_parts; - bool note_unusable_keys; // Give SQL notes for unusable keys + /* + Which functions should give SQL notes for unusable keys. + */ + Item_func::Bitmap note_unusable_keys; /* used_key_no -> table_key_no translation table. Only makes sense if @@ -1777,7 +1780,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 ...). */ @@ -1898,13 +1900,22 @@ class SQL_SELECT :public Sql_alloc { ~SQL_SELECT(); void cleanup(); void set_quick(QUICK_SELECT_I *new_quick) { delete quick; quick= new_quick; } - bool check_quick(THD *thd, bool force_quick_range, ha_rows limit) + + /* + @return + true - for ERROR and IMPOSSIBLE_RANGE + false - Ok + */ + bool check_quick(THD *thd, bool force_quick_range, ha_rows limit, + Item_func::Bitmap note_unusable_keys) { key_map tmp; tmp.set_all(); return test_quick_select(thd, tmp, 0, limit, force_quick_range, - FALSE, FALSE, FALSE) < 0; + FALSE, FALSE, FALSE, + note_unusable_keys) != OK; } + /* RETURN 0 if record must be skipped <-> (cond && cond->val_int() == 0) @@ -1918,13 +1929,25 @@ class SQL_SELECT :public Sql_alloc { rc= -1; return rc; } - int test_quick_select(THD *thd, key_map keys, table_map prev_tables, - ha_rows limit, bool force_quick_range, - bool ordered_output, bool remove_false_parts_of_where, - bool only_single_index_range_scan, - bool suppress_unusable_key_notes = 0); + + enum quick_select_return_type { + IMPOSSIBLE_RANGE = -1, + ERROR, + OK + }; + + enum quick_select_return_type + test_quick_select(THD *thd, key_map keys, table_map prev_tables, + ha_rows limit, + bool force_quick_range, + bool ordered_output, + bool remove_false_parts_of_where, + bool only_single_index_range_scan, + Item_func::Bitmap note_unusable_keys); }; +typedef enum SQL_SELECT::quick_select_return_type quick_select_return; + class SQL_SELECT_auto { diff --git a/sql/opt_split.cc b/sql/opt_split.cc index e45cbada5e8..aa6054b1244 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -1000,7 +1000,8 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(uint idx, table_map needed_in_prefix= 0; do { - if (keyuse_ext->needed_in_prefix & remaining_tables) + if (keyuse_ext->needed_in_prefix & + (remaining_tables | this->join->sjm_lookup_tables)) { keyuse_ext++; continue; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index c880168e201..6d9b40cc063 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -709,6 +709,14 @@ int check_and_do_in_subquery_rewrites(JOIN *join) my_error(ER_OPERAND_COLUMNS, MYF(0), ncols); DBUG_RETURN(-1); } + + uint cols_num= in_subs->left_exp()->cols(); + for (uint i= 0; i < cols_num; i++) + { + if (select_lex->ref_pointer_array[i]-> + check_cols(in_subs->left_exp()->element_index(i)->cols())) + DBUG_RETURN(-1); + } } DBUG_PRINT("info", ("Checking if subq can be converted to semi-join")); diff --git a/sql/protocol.cc b/sql/protocol.cc index 6667129d8bb..d2ef52e0887 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 4fdfde3e007..09dbdfbde2b 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -229,9 +229,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/rowid_filter.cc b/sql/rowid_filter.cc index dbd02c5c196..d4fb958fb26 100644 --- a/sql/rowid_filter.cc +++ b/sql/rowid_filter.cc @@ -560,8 +560,11 @@ TABLE::best_range_rowid_filter(uint access_key_no, double records, range filter and place into the filter the rowids / primary keys read from key tuples when doing this scan. @retval - false on success - true otherwise + Rowid_filter::SUCCESS on success + Rowid_filter::NON_FATAL_ERROR the error which does not require transaction + rollback + Rowid_filter::FATAL_ERROR the error which does require transaction + rollback @note The function assumes that the quick select object to perform @@ -574,9 +577,9 @@ TABLE::best_range_rowid_filter(uint access_key_no, double records, purposes to facilitate a lazy building of the filter. */ -bool Range_rowid_filter::fill() +Rowid_filter::build_return_code Range_rowid_filter::build() { - int rc= 0; + build_return_code rc= SUCCESS; handler *file= table->file; THD *thd= table->in_use; QUICK_RANGE_SELECT* quick= (QUICK_RANGE_SELECT*) select->quick; @@ -598,19 +601,37 @@ bool Range_rowid_filter::fill() file->ha_start_keyread(quick->index); if (quick->init() || quick->reset()) - goto end; - - while (!(rc= quick->get_next())) + rc= FATAL_ERROR; + else { - file->position(quick->record); - if (container->add(NULL, (char*) file->ref) || thd->killed) + for (;;) { - rc= 1; - break; + int quick_get_next_result= quick->get_next(); + if (thd->check_killed()) + { + rc= FATAL_ERROR; + break; + } + if (quick_get_next_result != 0) + { + rc= (quick_get_next_result == HA_ERR_END_OF_FILE ? SUCCESS + : FATAL_ERROR); + /* + The error state has been set by file->print_error(res, MYF(0)) call + inside quick->get_next() call, in Mrr_simple_index_reader::get_next() + */ + DBUG_ASSERT(rc == SUCCESS || thd->is_error()); + break; + } + file->position(quick->record); + if (container->add(NULL, (char *) file->ref)) + { + rc= NON_FATAL_ERROR; + break; + } } } -end: quick->range_end(); file->ha_end_keyread(); file->ha_restart_keyread(org_keyread); @@ -623,11 +644,12 @@ end: tracker->set_container_elements_count(container->elements()); tracker->report_container_buff_size(file->ref_length); - if (rc != HA_ERR_END_OF_FILE) - return 1; + if (rc != SUCCESS) + return rc; + container->sort(refpos_order_cmp, (void *) file); - file->rowid_filter_is_active= container->elements() != 0; - return 0; + table->file->rowid_filter_is_active= true; + return rc; } diff --git a/sql/rowid_filter.h b/sql/rowid_filter.h index 8f3f3a10925..286d3b50b48 100644 --- a/sql/rowid_filter.h +++ b/sql/rowid_filter.h @@ -213,6 +213,11 @@ protected: Rowid_filter_tracker *tracker; public: + enum build_return_code { + SUCCESS, + NON_FATAL_ERROR, + FATAL_ERROR, + }; Rowid_filter(Rowid_filter_container *container_arg) : container(container_arg) {} @@ -220,7 +225,7 @@ public: Build the filter : fill it with info on the set of elements placed there */ - virtual bool build() = 0; + virtual build_return_code build() = 0; /* Check whether an element is in the filter. @@ -265,7 +270,7 @@ public: ~Range_rowid_filter(); - bool build() override { return fill(); } + build_return_code build() override; bool check(char *elem) override { @@ -276,8 +281,6 @@ public: return was_checked; } - bool fill(); - SQL_SELECT *get_select() { return select; } }; diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index 1162905925a..20188d6c11d 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -721,6 +721,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, if (WSREP_ON_ && wsrep_thd_is_local(thd)) { thd->wsrep_ignore_table= false; + table->file->row_logging= 1; // replication requires binary logging wsrep_start_trx_if_not_started(thd); } else diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 27390bdc953..6a6d7fcb170 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/rpl_parallel.cc b/sql/rpl_parallel.cc index 95a1234ec9a..333a3960360 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -895,8 +895,7 @@ do_retry: thd->wait_for_commit_ptr->unregister_wait_for_prior_commit(); DBUG_EXECUTE_IF("inject_mdev8031", { /* Simulate that we get deadlock killed at this exact point. */ - rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED; - thd->set_killed(KILL_CONNECTION); + slave_background_kill_request(thd); }); #ifdef ENABLED_DEBUG_SYNC DBUG_EXECUTE_IF("rpl_parallel_simulate_wait_at_retry", { @@ -2877,23 +2876,12 @@ rpl_parallel::stop_during_until() bool -rpl_parallel::workers_idle() +rpl_parallel::workers_idle(Relay_log_info *rli) { - struct rpl_parallel_entry *e; - uint32 i, max_i; - - max_i= domain_hash.records; - for (i= 0; i < max_i; ++i) - { - bool active; - e= (struct rpl_parallel_entry *)my_hash_element(&domain_hash, i); - mysql_mutex_lock(&e->LOCK_parallel_entry); - active= e->current_sub_id > e->last_committed_sub_id; - mysql_mutex_unlock(&e->LOCK_parallel_entry); - if (active) - break; - } - return (i == max_i); + mysql_mutex_assert_owner(&rli->data_lock); + return !rli->last_inuse_relaylog || + rli->last_inuse_relaylog->queued_count == + rli->last_inuse_relaylog->dequeued_count; } diff --git a/sql/rpl_parallel.h b/sql/rpl_parallel.h index a9cfefcb02e..307d0e3bada 100644 --- a/sql/rpl_parallel.h +++ b/sql/rpl_parallel.h @@ -460,9 +460,10 @@ struct rpl_parallel { rpl_parallel_entry *find(uint32 domain_id, Relay_log_info *rli); void wait_for_done(THD *thd, Relay_log_info *rli); void stop_during_until(); - bool workers_idle(); int wait_for_workers_idle(THD *thd); int do_event(rpl_group_info *serial_rgi, Log_event *ev, ulonglong event_size); + + static bool workers_idle(Relay_log_info *rli); }; diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index bc1f0ebbff5..cc6def9b8f3 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -2384,7 +2384,17 @@ void rpl_group_info::slave_close_thread_tables(THD *thd) { DBUG_ENTER("rpl_group_info::slave_close_thread_tables(THD *thd)"); thd->get_stmt_da()->set_overwrite_status(true); - thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd); +#ifdef WITH_WSREP + // This can happen e.g. when table_def::compatible_with fails and sets a error + // but thd->is_error() is false then. However, we do not want to commit + // statement on Galera instead we want to rollback it as later in + // apply_write_set we rollback transaction and that can't be done + // after wsrep transaction state is s_committed. + if (WSREP(thd)) + (thd->is_error() || thd->is_slave_error) ? trans_rollback_stmt(thd) : trans_commit_stmt(thd); + else +#endif + thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd); thd->get_stmt_da()->set_overwrite_status(false); close_thread_tables(thd); diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 6ccddbc623a..464baaced08 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -625,7 +625,7 @@ struct inuse_relaylog { rpl_gtid *relay_log_state; uint32 relay_log_state_count; /* Number of events in this relay log queued for worker threads. */ - int64 queued_count; + Atomic_counter queued_count; /* Number of events completed by worker threads. */ Atomic_counter dequeued_count; /* Set when all events have been read from a relaylog. */ diff --git a/sql/select_handler.cc b/sql/select_handler.cc index e80e2548d5b..ab2a6850a6e 100644 --- a/sql/select_handler.cc +++ b/sql/select_handler.cc @@ -200,3 +200,18 @@ void select_handler::print_error(int error, myf errflag) { my_error(ER_GET_ERRNO, MYF(0), error, hton_name(ht)->str); } + +select_pushdown_type select_handler::get_pushdown_type() +{ + /* + In the case of single SELECT select_lex is initialized and lex_unit==NULL, + in the case of whole UNIT select_lex == NULL and lex_unit is initialized, + in the case of partial pushdown both select_lex and lex_unit + are initialized + */ + if(!lex_unit) + return select_pushdown_type::SINGLE_SELECT; + + return select_lex ? select_pushdown_type::PART_OF_UNIT : + select_pushdown_type::WHOLE_UNIT; +} diff --git a/sql/select_handler.h b/sql/select_handler.h index ea59eab4250..207af43f56c 100644 --- a/sql/select_handler.h +++ b/sql/select_handler.h @@ -20,6 +20,12 @@ #include "mariadb.h" #include "sql_priv.h" +enum class select_pushdown_type { + SINGLE_SELECT, + PART_OF_UNIT, + WHOLE_UNIT +}; + /** @class select_handler @@ -50,7 +56,7 @@ class select_handler virtual bool prepare(); /* - Select_handler processes one of + Select_handler processes these cases: - single SELECT - whole unit (multiple SELECTs combined with UNION/EXCEPT/INTERSECT) - single SELECT that is part of a unit (partial pushdown) @@ -60,7 +66,7 @@ class select_handler in the case of partial pushdown both select_lex and lex_unit are initialized */ - SELECT_LEX *select_lex; // Single select to be executed + SELECT_LEX *select_lex; // Single select/part of a unit to be executed SELECT_LEX_UNIT *lex_unit; // Unit to be executed /* @@ -99,6 +105,8 @@ protected: TABLE *create_tmp_table(THD *thd); + select_pushdown_type get_pushdown_type(); + THD *thd; handlerton *ht; diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc index 17adeed86e7..670a6d8d9ed 100644 --- a/sql/semisync_master.cc +++ b/sql/semisync_master.cc @@ -18,6 +18,8 @@ #include #include "semisync_master.h" +#include +#include #define TIME_THOUSAND 1000 #define TIME_MILLION 1000000 @@ -562,6 +564,8 @@ int Repl_semi_sync_master::report_reply_packet(uint32 server_id, DBUG_ENTER("Repl_semi_sync_master::report_reply_packet"); + DBUG_EXECUTE_IF("semisync_corrupt_magic", + const_cast(packet)[REPLY_MAGIC_NUM_OFFSET]= 0;); if (unlikely(packet[REPLY_MAGIC_NUM_OFFSET] != Repl_semi_sync_master::k_packet_magic_num)) { @@ -593,9 +597,18 @@ int Repl_semi_sync_master::report_reply_packet(uint32 server_id, rpl_semi_sync_master_get_ack++; report_reply_binlog(server_id, log_file_name, log_file_pos); + result= 0; l_end: + if (result == -1) + { + char buf[256]; + octet2hex(buf, (const char*) packet, std::min(static_cast(sizeof(buf)-1), + packet_len)); + sql_print_information("First bytes of the packet from semisync slave " + "server-id %d: %s", server_id, buf); + } DBUG_RETURN(result); } diff --git a/sql/semisync_master_ack_receiver.cc b/sql/semisync_master_ack_receiver.cc index b54ad58d153..559f939c42c 100644 --- a/sql/semisync_master_ack_receiver.cc +++ b/sql/semisync_master_ack_receiver.cc @@ -277,8 +277,18 @@ void Ack_receiver::run() if (likely(len != packet_error)) repl_semisync_master.report_reply_packet(slave->server_id(), net.read_pos, len); - else if (net.last_errno == ER_NET_READ_ERROR) - listener.clear_socket_info(slave); + else + { + if (net.last_errno == ER_NET_READ_ERROR) + { + listener.clear_socket_info(slave); + } + if (net.last_errno > 0 && global_system_variables.log_warnings > 2) + sql_print_warning("Semisync ack receiver got error %d \"%s\" " + "from slave server-id %d", + net.last_errno, ER_DEFAULT(net.last_errno), + slave->server_id()); + } } } mysql_mutex_unlock(&m_mutex); 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/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 9b411dbad40..b69f2807e46 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -12270,3 +12270,5 @@ ER_JSON_INVALID_VALUE_FOR_KEYWORD ER_JSON_SCHEMA_KEYWORD_UNSUPPORTED eng "%s keyword is not supported" sw "%s neno kuu halitumiki" +ER_JSON_NO_VARIABLE_SCHEMA + eng "Variable schema is not supported." diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index fb3f94d019e..534a9a1cfbf 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -172,11 +172,8 @@ extern "C" sig_handler handle_fatal_signal(int sig) my_safe_printf_stderr("[ERROR] mysqld got " SIGNAL_FMT " ;\n",sig); my_safe_printf_stderr("%s", - "This could be because you hit a bug. It is also possible that this binary\n" - "or one of the libraries it was linked against is corrupt, improperly built,\n" - "or misconfigured. This error can also be caused by malfunctioning hardware.\n\n"); - - my_safe_printf_stderr("%s", + "Sorry, we probably made a mistake, and this is a bug.\n\n" + "Your assistance in bug reporting will enable us to fix this for the next release.\n" "To report this bug, see https://mariadb.com/kb/en/reporting-bugs\n\n"); my_safe_printf_stderr("%s", @@ -309,7 +306,7 @@ extern "C" sig_handler handle_fatal_signal(int sig) } my_safe_printf_stderr("%s", "The manual page at " - "https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/ contains\n" + "https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mariadbd/ contains\n" "information that should help you find out what is causing the crash.\n"); #endif /* HAVE_STACKTRACE */ diff --git a/sql/slave.cc b/sql/slave.cc index 0a15cc55146..784724ff4a2 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -45,7 +45,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, @@ -62,7 +62,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" @@ -3200,6 +3199,14 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, mysql_mutex_lock(&mi->err_lock); /* err_lock is to protect mi->rli.last_error() */ mysql_mutex_lock(&mi->rli.err_lock); + + DBUG_EXECUTE_IF("hold_sss_with_err_lock", { + DBUG_ASSERT(!debug_sync_set_action( + thd, STRING_WITH_LEN("now SIGNAL sss_got_err_lock " + "WAIT_FOR sss_continue"))); + DBUG_SET("-d,hold_sss_with_err_lock"); + }); + protocol->store_string_or_null(mi->host, &my_charset_bin); protocol->store_string_or_null(mi->user, &my_charset_bin); protocol->store((uint32) mi->port); @@ -3279,7 +3286,8 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, while the slave is processing ignored events, such as those skipped due to slave_skip_counter. */ - if (mi->using_parallel() && idle && !mi->rli.parallel.workers_idle()) + if (mi->using_parallel() && idle && + !rpl_parallel::workers_idle(&mi->rli)) idle= false; } if (idle) @@ -4402,8 +4410,8 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, if (rli->last_master_timestamp < ev->when) { rli->last_master_timestamp= ev->when; - rli->sql_thread_caught_up= false; } + rli->sql_thread_caught_up= false; } int res= rli->parallel.do_event(serial_rgi, ev, event_size); @@ -4930,7 +4938,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")); thd->set_command(COM_SLAVE_IO); @@ -5510,19 +5524,25 @@ pthread_handler_t handle_slave_sql(void *arg) } else rli->gtid_skip_flag = GTID_SKIP_NOT; + mysql_mutex_lock(&rli->data_lock); if (init_relay_log_pos(rli, rli->group_relay_log_name, rli->group_relay_log_pos, - 1 /*need data lock*/, &errmsg, + 0 /*need data lock*/, &errmsg, 1 /*look for a description_event*/)) { rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, "Error initializing relay log position: %s", errmsg); + mysql_mutex_unlock(&rli->data_lock); goto err_before_start; } rli->reset_inuse_relaylog(); if (rli->alloc_inuse_relaylog(rli->group_relay_log_name)) + { + mysql_mutex_unlock(&rli->data_lock); goto err_before_start; + } + mysql_mutex_unlock(&rli->data_lock); strcpy(rli->future_event_master_log_name, rli->group_master_log_name); THD_CHECK_SENTRY(thd); diff --git a/sql/sp.cc b/sql/sp.cc index 9e4e29c48ca..3bc637b4327 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -2753,7 +2753,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); } @@ -2779,7 +2785,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 3b8bca64804..d468f15853d 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1396,7 +1396,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 @@ -1517,10 +1517,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/sp_pcontext.h b/sql/sp_pcontext.h index a2b26ac01e1..71846ad4620 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -372,7 +372,28 @@ public: class Lex_for_loop: public Lex_for_loop_st { public: - Lex_for_loop() { init(); } + /* + The label poiting to the body start, + either explicit or automatically generated. + Used during generation of "ITERATE loop_label" + to check if "loop_label" is a FOR loop label. + - In case of a FOR loop, some additional code + (cursor fetch or iteger increment) is generated before + the backward jump to the beginning of the loop body. + - In case of other loop types (WHILE, REPEAT) + only the jump is generated. + */ + const sp_label *m_start_label; + + Lex_for_loop() + :m_start_label(NULL) + { Lex_for_loop_st::init(); } + + Lex_for_loop(const Lex_for_loop_st &for_loop, const sp_label *start) + :m_start_label(start) + { + Lex_for_loop_st::operator=(for_loop); + } }; public: @@ -680,9 +701,9 @@ public: void set_for_loop(const Lex_for_loop_st &for_loop) { - m_for_loop.init(for_loop); + m_for_loop= Lex_for_loop(for_loop, last_label()); } - const Lex_for_loop_st &for_loop() + const Lex_for_loop &for_loop() { return m_for_loop; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 09af5523c76..23e059a08bc 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -957,6 +957,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()) { @@ -2305,6 +2306,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) { @@ -2340,6 +2344,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, @@ -2416,10 +2422,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) @@ -3394,10 +3403,18 @@ end: check_role_is_granted_callback, NULL) == -1)) { - /* Role is not granted but current user can see the role */ - my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s", - MYF(0), thd->security_ctx->priv_user, - thd->security_ctx->priv_host, rolename); + /* This happens for SET ROLE case and when `--skip-name-resolve` option + is used. In that situation host can be NULL and current user is always + target user, so printing `priv_user@priv_host` is not incorrect. + */ + if (!host) + my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s", + MYF(0), thd->security_ctx->priv_user, + thd->security_ctx->priv_host, rolename); + else + /* Role is not granted but current user can see the role */ + my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s", + MYF(0), user, host, rolename); } else { @@ -3468,6 +3485,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; @@ -3484,6 +3502,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*) @@ -5192,6 +5212,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, @@ -5256,6 +5277,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, @@ -5437,6 +5459,15 @@ public: }; +privilege_t GRANT_INFO::all_privilege() +{ + return (grant_table_user ? grant_table_user->cols : NO_ACL) | + (grant_table_role ? grant_table_role->cols : NO_ACL) | + (grant_public ? grant_public->cols : NO_ACL) | + privilege; +} + + void GRANT_NAME::set_user_details(const char *h, const char *d, const char *u, const char *t, bool is_routine) @@ -8454,8 +8485,7 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, if (!(~t_ref->grant.privilege & want_access)) continue; - if ((want_access&= ~(t_ref->grant.aggregate_cols() | - t_ref->grant.privilege))) + if ((want_access&= ~t_ref->grant.all_privilege())) { goto err; // impossible } @@ -8512,6 +8542,7 @@ inline privilege_t GRANT_INFO::aggregate_cols() (grant_public ? grant_public->cols : NO_ACL); } + void GRANT_INFO::refresh(const Security_context *sctx, const char *db, const char *table) { @@ -13550,8 +13581,37 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio) DBUG_RETURN(0); } + +/** + Determine if the client is MySQL Connector/NET. + + Checks whether the given connection attributes blob corresponds to + MySQL Connector/NET by examining the "_client_name" attribute, which is + expected to be the first attribute in the blob. + + @param connection_attrs - The connection attributes blob. + @param length - The length of the blob. + + @return true if the client is MySQL Connector/NET, false otherwise. +*/ +static inline bool is_connector_net_client(const char *connection_attrs, + size_t length) +{ + constexpr LEX_CSTRING prefix= + {STRING_WITH_LEN("\x0c_client_name\x13mysql-connector-net")}; + + if (length < prefix.length) + return false; + + /* Optimization to avoid following memcmp in common cases.*/ + if (connection_attrs[prefix.length - 1] != prefix.str[prefix.length - 1]) + return false; + + return !memcmp(connection_attrs, prefix.str, prefix.length); +} + static bool -read_client_connect_attrs(char **ptr, char *end, CHARSET_INFO *from_cs) +read_client_connect_attrs(char **ptr, char *end, THD* thd) { ulonglong length; char *ptr_save= *ptr; @@ -13574,10 +13634,14 @@ read_client_connect_attrs(char **ptr, char *end, CHARSET_INFO *from_cs) if (length > 65535) return true; - if (PSI_CALL_set_thread_connect_attrs(*ptr, (uint)length, from_cs) && + if (PSI_CALL_set_thread_connect_attrs(*ptr, (uint)length, thd->charset()) && current_thd->variables.log_warnings) sql_print_warning("Connection attributes of length %llu were truncated", length); + + /* Connector/Net crashes, when "show collations" returns NULL IDs*/ + if (is_connector_net_client(*ptr, length)) + thd->variables.old_behavior |= OLD_MODE_NO_NULL_COLLATION_IDS; return false; } @@ -13711,7 +13775,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) } if ((thd->client_capabilities & CLIENT_CONNECT_ATTRS) && - read_client_connect_attrs(&next_field, end, thd->charset())) + read_client_connect_attrs(&next_field, end, thd)) { my_message(ER_UNKNOWN_COM_ERROR, ER_THD(thd, ER_UNKNOWN_COM_ERROR), MYF(0)); @@ -14005,7 +14069,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, if ((thd->client_capabilities & CLIENT_CONNECT_ATTRS) && read_client_connect_attrs(&next_field, ((char *)net->read_pos) + pkt_len, - mpvio->auth_info.thd->charset())) + mpvio->auth_info.thd)) return packet_error; /* diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index e61b1d389b0..fcbd8a55c15 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -32,6 +32,9 @@ #include "sql_admin.h" #include "sql_statistics.h" #include "wsrep_mysqld.h" +#ifdef WITH_WSREP +#include "wsrep_trans_observer.h" +#endif const LEX_CSTRING msg_status= {STRING_WITH_LEN("status")}; const LEX_CSTRING msg_repair= { STRING_WITH_LEN("repair") }; @@ -445,6 +448,32 @@ dbug_err: return open_error; } +#ifdef WITH_WSREP +/** RAII class for temporarily disable wsrep_on in the connection. */ +class Disable_wsrep_on_guard +{ + public: + /** + @param thd - pointer to the context of connection in which + wsrep_on mode needs to be disabled. + @param disable - true if wsrep_on should be disabled + */ + explicit Disable_wsrep_on_guard(THD *thd, bool disable) + : m_thd(thd), m_orig_wsrep_on(thd->variables.wsrep_on) + { + if (disable) + thd->variables.wsrep_on= false; + } + + ~Disable_wsrep_on_guard() + { + m_thd->variables.wsrep_on= m_orig_wsrep_on; + } + private: + THD* m_thd; + bool m_orig_wsrep_on; +}; +#endif /* WITH_WSREP */ static void send_read_only_warning(THD *thd, const LEX_CSTRING *msg_status, @@ -524,6 +553,18 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, DBUG_ENTER("mysql_admin_table"); DBUG_PRINT("enter", ("extra_open_options: %u", extra_open_options)); +#ifdef WITH_WSREP + /* + CACHE INDEX and LOAD INDEX INTO CACHE statements are + local operations. Do not replicate them with Galera + */ + const bool disable_wsrep_on= (WSREP(thd) && + (lex->sql_command == SQLCOM_ASSIGN_TO_KEYCACHE || + lex->sql_command == SQLCOM_PRELOAD_KEYS)); + + Disable_wsrep_on_guard wsrep_on_guard(thd, disable_wsrep_on); +#endif /* WITH_WSREP */ + fill_check_table_metadata_fields(thd, &field_list); if (protocol->send_result_set_metadata(&field_list, @@ -582,7 +623,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ? MDL_SHARED_NO_READ_WRITE : lock_type >= TL_FIRST_WRITE ? MDL_SHARED_WRITE : MDL_SHARED_READ); - if (thd->check_killed()) { open_error= false; diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index ba5e7e9e7ba..288327cd504 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -634,25 +634,12 @@ bool Sql_cmd_alter_table::execute(THD *thd) if (check_grant(thd, priv_needed, first_table, FALSE, UINT_MAX, FALSE)) DBUG_RETURN(TRUE); /* purecov: inspected */ + #ifdef WITH_WSREP if (WSREP(thd) && (!thd->is_current_stmt_binlog_format_row() || !thd->find_temporary_table(first_table))) { - 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) - { - WSREP_WARN("ALTER TABLE isolation failure"); - DBUG_RETURN(TRUE); - } - /* It makes sense to set auto_increment_* to defaults in TOI operations. Must be done before wsrep_TOI_begin() since Query_log_event encapsulating @@ -665,6 +652,22 @@ bool Sql_cmd_alter_table::execute(THD *thd) thd->variables.auto_increment_offset = 1; thd->variables.auto_increment_increment = 1; } + + wsrep::key_array keys; + if (!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) + { + 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 9d2415d3a4d..e33b4728829 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -76,7 +76,9 @@ No_such_table_error_handler::handle_condition(THD *, *cond_hdl= NULL; if (!first_error) first_error= sql_errno; - if (sql_errno == ER_NO_SUCH_TABLE || sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE) + if (sql_errno == ER_NO_SUCH_TABLE + || sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE + || sql_errno == ER_UNKNOWN_SEQUENCES) { m_handled_errors++; return TRUE; @@ -994,7 +996,11 @@ void close_thread_table(THD *thd, TABLE **table_ptr) DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->s->db.str, table->s->table_name.str, - MDL_SHARED)); + MDL_SHARED) || + thd->mdl_context.is_lock_warrantee(MDL_key::TABLE, + table->s->db.str, + table->s->table_name.str, + MDL_SHARED)); table->vcol_cleanup_expr(thd); table->mdl_ticket= NULL; @@ -2316,6 +2322,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); } @@ -2335,6 +2342,7 @@ retry_share: if (result) { MYSQL_UNBIND_TABLE(table->file); + table->vcol_cleanup_expr(thd); tc_release_table(table); DBUG_RETURN(TRUE); } @@ -3668,7 +3676,8 @@ thr_lock_type read_lock_type_for_table(THD *thd, at THD::variables::sql_log_bin member. */ bool log_on= mysql_bin_log.is_open() && thd->variables.sql_log_bin; - if ((log_on == FALSE) || (thd->wsrep_binlog_format() == BINLOG_FORMAT_ROW) || + if ((log_on == FALSE) || + (thd->wsrep_binlog_format(thd->variables.binlog_format) == BINLOG_FORMAT_ROW) || (table_list->table->s->table_category == TABLE_CATEGORY_LOG) || (table_list->table->s->table_category == TABLE_CATEGORY_PERFORMANCE) || !(is_update_query(prelocking_ctx->sql_command) || @@ -7248,6 +7257,7 @@ set_new_item_local_context(THD *thd, Item_ident *item, TABLE_LIST *table_ref) if (!(context= new (thd->mem_root) Name_resolution_context)) return TRUE; context->init(); + context->select_lex= table_ref->select_lex; context->first_name_resolution_table= context->last_name_resolution_table= table_ref; item->context= context; @@ -8069,7 +8079,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 a2414de645b..98846cce087 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -712,6 +712,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) wsrep_ignore_table(false), wsrep_aborter(0), wsrep_delayed_BF_abort(false), + wsrep_ctas(false), /* wsrep-lib */ m_wsrep_next_trx_id(WSREP_UNDEFINED_TRX_ID), @@ -1229,6 +1230,7 @@ const Type_handler *THD::type_handler_for_datetime() const void THD::init() { DBUG_ENTER("thd::init"); + mdl_context.reset(); mysql_mutex_lock(&LOCK_global_system_variables); plugin_thdvar_init(this); /* @@ -1242,7 +1244,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) @@ -1537,6 +1541,8 @@ void THD::cleanup(void) else trans_rollback(this); + DEBUG_SYNC(this, "THD_cleanup_after_trans_cleanup"); + DBUG_ASSERT(open_tables == NULL); DBUG_ASSERT(m_transaction_psi == NULL); @@ -1599,6 +1605,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(); @@ -1637,6 +1647,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(); @@ -1649,6 +1660,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; @@ -1691,6 +1703,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(); @@ -1703,17 +1717,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); @@ -1721,6 +1724,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); @@ -2134,7 +2138,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 @@ -2145,6 +2153,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); } @@ -4744,7 +4753,7 @@ extern "C" enum thd_kill_levels thd_kill_level(const MYSQL_THD thd) if (unlikely(apc_target->have_apc_requests())) { if (thd == current_thd) - apc_target->process_apc_requests(); + apc_target->process_apc_requests(false); } return THD_IS_NOT_KILLED; } @@ -5596,7 +5605,7 @@ extern "C" int thd_binlog_format(const MYSQL_THD thd) if (WSREP(thd)) { /* for wsrep binlog format is meaningful also when binlogging is off */ - return (int) WSREP_BINLOG_FORMAT(thd->variables.binlog_format); + return (int) thd->wsrep_binlog_format(thd->variables.binlog_format); } if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG)) @@ -6412,11 +6421,14 @@ int THD::decide_logging_format(TABLE_LIST *tables) reset_binlog_local_stmt_filter(); + // Used binlog format + ulong binlog_format= wsrep_binlog_format(variables.binlog_format); /* We should not decide logging format if the binlog is closed or binlogging is off, or if the statement is filtered out from the binlog by filtering rules. */ + #ifdef WITH_WSREP if (WSREP_CLIENT_NNULL(this) && wsrep_thd_is_local(this) && @@ -6431,6 +6443,27 @@ int THD::decide_logging_format(TABLE_LIST *tables) DBUG_RETURN(-1); } } + + /* + If user has configured wsrep_forced_binlog_format to + STMT OR MIXED and used binlog_format would be same + and this is CREATE TABLE AS SELECT we will fall back + to ROW. + */ + if (wsrep_forced_binlog_format < BINLOG_FORMAT_ROW && + wsrep_ctas) + { + if (!get_stmt_da()->has_sql_condition(ER_UNKNOWN_ERROR)) + { + push_warning_printf(this, Sql_condition::WARN_LEVEL_WARN, + ER_UNKNOWN_ERROR, + "Galera does not support wsrep_forced_binlog_format = %s " + "in CREATE TABLE AS SELECT", + wsrep_forced_binlog_format == BINLOG_FORMAT_STMT ? + "STMT" : "MIXED"); + } + set_current_stmt_binlog_format_row(); + } #endif /* WITH_WSREP */ if (WSREP_EMULATE_BINLOG_NNULL(this) || @@ -6438,7 +6471,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) { if (is_bulk_op()) { - if (wsrep_binlog_format() == BINLOG_FORMAT_STMT) + if (binlog_format == BINLOG_FORMAT_STMT) { my_error(ER_BINLOG_NON_SUPPORTED_BULK, MYF(0)); DBUG_PRINT("info", @@ -6656,7 +6689,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) prev_access_table= table; } - if (wsrep_binlog_format() != BINLOG_FORMAT_ROW) + if (binlog_format != BINLOG_FORMAT_ROW) { /* DML statements that modify a table with an auto_increment @@ -6740,7 +6773,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) */ my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE), MYF(0)); } - else if ((wsrep_binlog_format() == BINLOG_FORMAT_ROW || is_bulk_op()) && + else if ((binlog_format == BINLOG_FORMAT_ROW || is_bulk_op()) && sqlcom_can_generate_row_events(this)) { /* @@ -6770,7 +6803,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) else { /* binlog_format = STATEMENT */ - if (wsrep_binlog_format() == BINLOG_FORMAT_STMT) + if (binlog_format == BINLOG_FORMAT_STMT) { if (lex->is_stmt_row_injection()) { @@ -6914,7 +6947,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) "and binlog_filter->db_ok(db) = %d", mysql_bin_log.is_open(), (variables.option_bits & OPTION_BIN_LOG), - (uint) wsrep_binlog_format(), + (uint) binlog_format, binlog_filter->db_ok(db.str))); if (WSREP_NNULL(this) && is_current_stmt_binlog_format_row()) binlog_prepare_for_row_logging(); @@ -6951,7 +6984,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) void THD::reconsider_logging_format_for_iodup(TABLE *table) { DBUG_ENTER("reconsider_logging_format_for_iodup"); - enum_binlog_format bf= (enum_binlog_format) wsrep_binlog_format(); + enum_binlog_format bf= (enum_binlog_format) wsrep_binlog_format(variables.binlog_format); DBUG_ASSERT(lex->duplicates == DUP_UPDATE); @@ -7016,7 +7049,7 @@ bool THD::binlog_table_should_be_logged(const LEX_CSTRING *db) { return (mysql_bin_log.is_open() && (variables.option_bits & OPTION_BIN_LOG) && - (wsrep_binlog_format() != BINLOG_FORMAT_STMT || + (wsrep_binlog_format(variables.binlog_format) != BINLOG_FORMAT_STMT || binlog_filter->db_ok(db->str))); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 214118d8431..4b006cc7993 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -202,10 +202,11 @@ enum enum_binlog_row_image { #define OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE (1 << 0) #define OLD_MODE_NO_PROGRESS_INFO (1 << 1) #define OLD_MODE_ZERO_DATE_TIME_CAST (1 << 2) -#define OLD_MODE_UTF8_IS_UTF8MB3 (1 << 3) -#define OLD_MODE_IGNORE_INDEX_ONLY_FOR_JOIN (1 << 4) -#define OLD_MODE_COMPAT_5_1_CHECKSUM (1 << 5) -#define OLD_MODE_LOCK_ALTER_TABLE_COPY (1 << 6) +#define OLD_MODE_UTF8_IS_UTF8MB3 (1 << 3) +#define OLD_MODE_IGNORE_INDEX_ONLY_FOR_JOIN (1 << 4) +#define OLD_MODE_COMPAT_5_1_CHECKSUM (1 << 5) +#define OLD_MODE_NO_NULL_COLLATION_IDS (1 << 6) +#define OLD_MODE_LOCK_ALTER_TABLE_COPY (1 << 7) #define OLD_MODE_DEFAULT_VALUE OLD_MODE_UTF8_IS_UTF8MB3 @@ -3365,6 +3366,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; /* @@ -3598,7 +3610,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; } @@ -3619,8 +3635,6 @@ public: inline void inc_examined_row_count() { inc_examined_row_count_fast(); - DBUG_EXECUTE_IF("debug_huge_number_of_examined_rows", - m_examined_row_count= (ULONGLONG_MAX - 1000000);); MYSQL_SET_STATEMENT_ROWS_EXAMINED(m_statement_psi, m_examined_row_count); } @@ -3797,7 +3811,7 @@ public: return TRUE; } if (apc_target.have_apc_requests()) - apc_target.process_apc_requests(); + apc_target.process_apc_requests(false); return FALSE; } @@ -4710,7 +4724,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; @@ -4805,7 +4820,7 @@ public: tests fail and so force them to propagate the lex->binlog_row_based_if_mixed upwards to the caller. */ - if ((wsrep_binlog_format() == BINLOG_FORMAT_MIXED) && (in_sub_stmt == 0)) + if ((wsrep_binlog_format(variables.binlog_format) == BINLOG_FORMAT_MIXED) && (in_sub_stmt == 0)) set_current_stmt_binlog_format_row(); DBUG_VOID_RETURN; @@ -4861,7 +4876,7 @@ public: show_system_thread(system_thread))); if (in_sub_stmt == 0) { - if (wsrep_binlog_format() == BINLOG_FORMAT_ROW) + if (wsrep_binlog_format(variables.binlog_format) == BINLOG_FORMAT_ROW) set_current_stmt_binlog_format_row(); else if (!has_temporary_tables()) set_current_stmt_binlog_format_stmt(); @@ -5141,13 +5156,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; } @@ -5217,8 +5243,7 @@ public: /* Relesae transactional locks if there are no active transactions */ void release_transactional_locks() { - if (!(server_status & - (SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY))) + if (!in_active_multi_stmt_transaction()) mdl_context.release_transactional_locks(this); } int decide_logging_format(TABLE_LIST *tables); @@ -5493,9 +5518,18 @@ public: */ bool is_awaiting_semisync_ack; - inline ulong wsrep_binlog_format() const + inline ulong wsrep_binlog_format(ulong binlog_format) const { - return WSREP_BINLOG_FORMAT(variables.binlog_format); +#ifdef WITH_WSREP + // During CTAS we force ROW format + if (wsrep_ctas) + return BINLOG_FORMAT_ROW; + else + return ((wsrep_forced_binlog_format != BINLOG_FORMAT_UNSPEC) ? + wsrep_forced_binlog_format : binlog_format); +#else + return (binlog_format); +#endif } #ifdef WITH_WSREP @@ -5560,7 +5594,8 @@ public: /* true if BF abort is observed in do_command() right after reading client's packet, and if the client has sent PS execute command. */ bool wsrep_delayed_BF_abort; - + // true if this transaction is CREATE TABLE AS SELECT (CTAS) + bool wsrep_ctas; /* Transaction id: * m_wsrep_next_trx_id is assigned on the first query after @@ -5722,8 +5757,6 @@ public: Item *sp_prepare_func_item(Item **it_addr, uint cols); bool sp_eval_expr(Field *result_field, Item **expr_item_ptr); - ilist online_alter_cache_list; - bool sql_parser(LEX *old_lex, LEX *lex, char *str, uint str_len, bool stmt_prepare_mode); @@ -7841,6 +7874,50 @@ class Sql_mode_save sql_mode_t old_mode; // SQL mode saved at construction time. }; + +/* + Save the current sql_mode. Switch off sql_mode flags which can prevent + normal parsing of VIEWs, expressions in generated columns. + Restore the old sql_mode on destructor. +*/ +class Sql_mode_save_for_frm_handling: public Sql_mode_save +{ +public: + Sql_mode_save_for_frm_handling(THD *thd) + :Sql_mode_save(thd) + { + /* + - MODE_REAL_AS_FLOAT affect only CREATE TABLE parsing + + MODE_PIPES_AS_CONCAT affect expression parsing + + MODE_ANSI_QUOTES affect expression parsing + + MODE_IGNORE_SPACE affect expression parsing + - MODE_IGNORE_BAD_TABLE_OPTIONS affect only CREATE/ALTER TABLE parsing + * MODE_ONLY_FULL_GROUP_BY affect execution + * MODE_NO_UNSIGNED_SUBTRACTION affect execution + - MODE_NO_DIR_IN_CREATE affect table creation only + - MODE_POSTGRESQL compounded from other modes + + MODE_ORACLE affects Item creation (e.g for CONCAT) + - MODE_MSSQL compounded from other modes + - MODE_DB2 compounded from other modes + - MODE_MAXDB affect only CREATE TABLE parsing + - MODE_NO_KEY_OPTIONS affect only SHOW + - MODE_NO_TABLE_OPTIONS affect only SHOW + - MODE_NO_FIELD_OPTIONS affect only SHOW + - MODE_MYSQL323 affect only SHOW + - MODE_MYSQL40 affect only SHOW + - MODE_ANSI compounded from other modes + (+ transaction mode) + ? MODE_NO_AUTO_VALUE_ON_ZERO affect UPDATEs + + MODE_NO_BACKSLASH_ESCAPES affect expression parsing + + MODE_EMPTY_STRING_IS_NULL affect expression parsing + */ + thd->variables.sql_mode&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | + MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES | + MODE_ORACLE | MODE_EMPTY_STRING_IS_NULL); + }; +}; + + class Switch_to_definer_security_ctx { public: @@ -7915,11 +7992,13 @@ public: class Use_relaxed_field_copy: public Sql_mode_save, - public Check_level_instant_set + public Check_level_instant_set, + public Abort_on_warning_instant_set { public: Use_relaxed_field_copy(THD *thd) : - Sql_mode_save(thd), Check_level_instant_set(thd, CHECK_FIELD_IGNORE) + Sql_mode_save(thd), Check_level_instant_set(thd, CHECK_FIELD_IGNORE), + Abort_on_warning_instant_set(thd, 0) { thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE); thd->variables.sql_mode|= MODE_INVALID_DATES; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index c5619b28f69..c55f2999c71 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1242,8 +1242,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 ad385128d8d..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); } @@ -1199,7 +1201,7 @@ With_element::process_columns_of_derived_unit(THD *thd, /* Rename the columns of the first select in the unit */ while ((item= it++, name= nm++)) { - item->set_name(thd, *name); + lex_string_set(&item->name, name->str); item->base_flags|= item_base_t::IS_EXPLICIT_NAME; } @@ -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 3fc75d8638e..6b442da858d 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -511,9 +511,9 @@ bool Sql_cmd_delete::delete_from_single_table(THD *thd) select=make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error); if (unlikely(error)) DBUG_RETURN(TRUE); - if (unlikely((select && select->check_quick(thd, safe_update, limit)) || - table->stat_records() == 0 || - !limit)) + if ((select && select->check_quick(thd, safe_update, limit, + Item_func::BITMAP_ALL)) || !limit || + table->stat_records() == 0) { query_plan.set_impossible_where(); if (thd->lex->describe || thd->lex->analyze_stmt) @@ -1060,6 +1060,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 20ee703666f..d41f725477f 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1235,6 +1235,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) goto err; JOIN *join= unit->first_select()->join; join->first_record= false; + if (join->zero_result_cause) + goto err; + for (uint i= join->top_join_tab_count; i < join->top_join_tab_count + join->aggr_tables; i++) @@ -1343,6 +1346,10 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived) derived->get_unit())); st_select_lex_unit *unit= derived->get_unit(); + // reset item names to that saved after wildcard expansion in JOIN::prepare + for(st_select_lex *sl= unit->first_select(); sl; sl= sl->next_select()) + sl->restore_item_list_names(); + derived->merged_for_insert= FALSE; unit->unclean(); unit->types.empty(); diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 85be61c34ef..76ed0ca2248 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -549,6 +549,18 @@ bool Warning_info::has_sql_condition(const char *message_str, size_t message_len return false; } +bool Warning_info::has_sql_condition(uint sql_errno) const +{ + Diagnostics_area::Sql_condition_iterator it(m_warn_list); + const Sql_condition *err; + + while ((err = it++)) + { + if (err->get_sql_errno() == sql_errno) + return true; + } + return false; +} void Warning_info::clear(ulonglong new_id) { diff --git a/sql/sql_error.h b/sql/sql_error.h index a453baec8f2..21161cb2e6a 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -602,6 +602,16 @@ private: */ bool has_sql_condition(const char *message_str, size_t message_length) const; + /** + Checks if Warning_info contains SQL-condition with the given error id + + @param sql_errno SQL-condition error number + + @return true if the Warning_info contains an SQL-condition with the given + error id. + */ + bool has_sql_condition(uint sql_errno) const; + /** Reset the warning information. Clear all warnings, the number of warnings, reset current row counter @@ -1167,6 +1177,9 @@ public: bool has_sql_condition(const char *message_str, size_t message_length) const { return get_warning_info()->has_sql_condition(message_str, message_length); } + bool has_sql_condition(uint sql_errno) const + { return get_warning_info()->has_sql_condition(sql_errno); } + void reset_for_next_command() { get_warning_info()->reset_for_next_command(); } diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index d2e0e3d6de7..b8c9c87ce62 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -2179,6 +2179,11 @@ void Explain_table_access::print_explain_json(Explain_query *query, writer->add_member("r_unpack_time_ms"); writer->add_double(jbuf_unpack_tracker.get_time_ms()); + DBUG_EXECUTE_IF("analyze_print_r_unpack_ops", + { + writer->add_member("r_unpack_ops"); + writer->add_ull(jbuf_unpack_tracker.get_loops()); + }); writer->add_member("r_other_time_ms"). add_double(jbuf_extra_time_tracker.get_time_ms()); diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc index 69d85f3343d..8681e08e014 100644 --- a/sql/sql_expression_cache.cc +++ b/sql/sql_expression_cache.cc @@ -151,6 +151,7 @@ void Expression_cache_tmptable::init() } cache_table->s->keys= 1; ref.null_rejecting= 1; + ref.const_ref_part_map= 0; ref.disable_cache= FALSE; ref.has_record= 0; ref.use_count= 0; diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 8f09211c0c6..3876516bfcb 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -693,7 +693,7 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, SQL_SELECT *res= make_select(table, 0, 0, cond, 0, 0, error); if (unlikely(!res) || unlikely(*error)) goto error; - (void) res->check_quick(thd, 0, HA_POS_ERROR); + (void) res->check_quick(thd, 0, HA_POS_ERROR, Item_func::BITMAP_ALL); if (!res->quick || res->quick->reset() == 0) return res; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3db671d525b..01d9f77427f 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 */ @@ -487,7 +488,7 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, } bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG); - if (WSREP_BINLOG_FORMAT(global_system_variables.binlog_format) == BINLOG_FORMAT_STMT && + if (thd->wsrep_binlog_format(global_system_variables.binlog_format) == BINLOG_FORMAT_STMT && log_on && mysql_bin_log.is_open()) { /* @@ -591,7 +592,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); @@ -2718,7 +2720,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) { /* @@ -2743,7 +2745,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; @@ -2772,11 +2774,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. */ @@ -2860,11 +2865,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); @@ -5112,17 +5121,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, - table_list->db.str, - table_list->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, table_list, 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_join_cache.cc b/sql/sql_join_cache.cc index a129456f73a..1ef4b3f44b4 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -1630,7 +1630,6 @@ bool JOIN_CACHE::put_record() bool JOIN_CACHE::get_record() { bool res; - ANALYZE_START_TRACKING(thd(), join_tab->jbuf_unpack_tracker); uchar *prev_rec_ptr= 0; if (with_length) pos+= size_of_rec_len; @@ -1646,7 +1645,6 @@ bool JOIN_CACHE::get_record() if (prev_cache) prev_cache->get_record_by_pos(prev_rec_ptr); } - ANALYZE_STOP_TRACKING(thd(), join_tab->jbuf_unpack_tracker); return res; } @@ -2062,10 +2060,11 @@ bool JOIN_CACHE::skip_if_matched() - In the case of a semi-nest the match flag may be in two states {MATCH_NOT_FOUND, MATCH_FOUND}. The record is skipped if the flag is set to MATCH_FOUND. - - In the case of a outer join nest when not_exists optimization is applied - the match may be in three states {MATCH_NOT_FOUND, MATCH_IMPOSSIBLE, - MATCH_FOUND. The record is skipped if the flag is set to MATCH_FOUND or - to MATCH_IMPOSSIBLE. + - In the case of an outer join the match may be in three states + {MATCH_NOT_FOUND, MATCH_IMPOSSIBLE, MATCH_FOUND}. + If not_exists optimization is applied the record is skipped when + the flag is set to MATCH_FOUND or to MATCH_IMPOSSIBLE. Otherwise + the record is skipped only when the flag is set to MATCH_IMPOSSIBLE. If the record is skipped the value of 'pos' is set to point to the position right after the record. @@ -2088,13 +2087,13 @@ bool JOIN_CACHE::skip_if_not_needed_match() if (prev_cache) offset+= prev_cache->get_size_of_rec_offset(); - if (!join_tab->check_only_first_match()) - return FALSE; - match_fl= get_match_flag_by_pos(pos+offset); skip= join_tab->first_sj_inner_tab ? - match_fl == MATCH_FOUND : // the case of semi-join - match_fl != MATCH_NOT_FOUND; // the case of outer-join + match_fl == MATCH_FOUND : // the case of semi-join + not_exists_opt_is_applicable && + join_tab->table->reginfo.not_exists_optimize ? + match_fl != MATCH_NOT_FOUND : // the case of not exist opt + match_fl == MATCH_IMPOSSIBLE; if (skip) { @@ -2351,8 +2350,12 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last) if ((rc= join_tab_execution_startup(join_tab)) < 0) goto finish2; - if (join_tab->need_to_build_rowid_filter) - join_tab->build_range_rowid_filter(); + if (join_tab->need_to_build_rowid_filter && + join_tab->build_range_rowid_filter()) + { + rc= NESTED_LOOP_ERROR; + goto finish2; + } /* Prepare to retrieve all records of the joined table */ if (unlikely((error= join_tab_scan->open()))) @@ -2393,7 +2396,7 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last) as candidates for matches. */ - bool not_exists_opt_is_applicable= true; + not_exists_opt_is_applicable= true; if (check_only_first_match && join_tab->first_inner) { /* @@ -2418,8 +2421,9 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last) } } - if (!check_only_first_match || - (join_tab->first_inner && !not_exists_opt_is_applicable) || + if ((!join_tab->on_precond && + (!check_only_first_match || + (join_tab->first_inner && !not_exists_opt_is_applicable))) || !skip_next_candidate_for_match(rec_ptr)) { ANALYZE_START_TRACKING(join->thd, join_tab->jbuf_unpack_tracker); diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h index 6c3e3423903..d2d2e1a1c01 100644 --- a/sql/sql_join_cache.h +++ b/sql/sql_join_cache.h @@ -343,6 +343,9 @@ protected: /* The length of an embedded key value */ uint emb_key_length; + /* This flag is used only when 'not exists' optimization can be applied */ + bool not_exists_opt_is_applicable; + /* This object provides the methods to iterate over records of the joined table join_tab when looking for join matches between @@ -539,6 +542,7 @@ protected: prev_cache= next_cache= 0; buff= 0; min_buff_size= max_buff_size= 0; // Caches + not_exists_opt_is_applicable= false; } /* diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5276e5c7d3e..eb9b3fbc478 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1418,7 +1418,6 @@ int Lex_input_stream::find_keyword(Lex_ident_cli_st *kwd, case CLOB_MARIADB_SYM: return CLOB_ORACLE_SYM; case CONTINUE_MARIADB_SYM: return CONTINUE_ORACLE_SYM; case DECLARE_MARIADB_SYM: return DECLARE_ORACLE_SYM; - case DECODE_MARIADB_SYM: return DECODE_ORACLE_SYM; case ELSEIF_MARIADB_SYM: return ELSEIF_ORACLE_SYM; case ELSIF_MARIADB_SYM: return ELSIF_ORACLE_SYM; case EXCEPTION_MARIADB_SYM: return EXCEPTION_ORACLE_SYM; @@ -1489,7 +1488,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)) @@ -2168,7 +2167,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); @@ -2612,7 +2622,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); } } } @@ -2634,7 +2649,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; @@ -2648,10 +2720,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 @@ -2966,6 +3069,7 @@ void st_select_lex::init_query() max_equal_elems= 0; ref_pointer_array.reset(); select_n_where_fields= 0; + order_group_num= 0; select_n_reserved= 0; select_n_having_items= 0; n_sum_items= 0; @@ -2985,9 +3089,11 @@ void st_select_lex::init_query() window_specs.empty(); window_funcs.empty(); + is_win_spec_list_built= false; tvc= 0; versioned_tables= 0; pushdown_select= 0; + orig_names_of_item_list_elems= 0; } void st_select_lex::init_select() @@ -3039,6 +3145,7 @@ void st_select_lex::init_select() versioned_tables= 0; is_tvc_wrapper= false; nest_flags= 0; + orig_names_of_item_list_elems= 0; item_list_usage= MARK_COLUMNS_READ; } @@ -3496,46 +3603,42 @@ List* st_select_lex::get_item_list() return &item_list; } -bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) -{ +uint st_select_lex::get_cardinality_of_ref_ptrs_slice(uint order_group_num_arg) +{ if (!((options & SELECT_DISTINCT) && !group_list.elements)) hidden_bit_fields= 0; - // find_order_in_list() may need some extra space, so multiply by two. - order_group_num*= 2; + if (!order_group_num) + order_group_num= order_group_num_arg; /* - We have to create array in prepared statement memory if it is a - prepared statement + find_order_in_list() may need some extra space, + so multiply order_group_num by 2 */ - Query_arena *arena= thd->stmt_arena; - const size_t n_elems= (n_sum_items + - n_child_sum_items + - item_list.elements + - select_n_reserved + - select_n_having_items + - select_n_where_fields + - order_group_num + - hidden_bit_fields + - fields_in_window_functions + 1) * (size_t) 5; - DBUG_ASSERT(n_elems % 5 == 0); + uint n= n_sum_items + + n_child_sum_items + + item_list.elements + + select_n_reserved + + select_n_having_items + + select_n_where_fields + + order_group_num * 2 + + hidden_bit_fields + + fields_in_window_functions + 1; + return n; +} + + +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()) - { - /* - We need to take 'n_sum_items' into account when allocating the array, - and this may actually increase during the optimization phase due to - MIN/MAX rewrite in Item_in_subselect::single_value_transformer. - In the usual case we can reuse the array from the prepare phase. - If we need a bigger array, we must allocate a new one. - */ - if (ref_pointer_array.size() >= n_elems) - return false; - } - Item **array= static_cast(arena->alloc(sizeof(Item*) * n_elems)); + return false; + + 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; } @@ -4688,18 +4791,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) @@ -7093,7 +7202,7 @@ bool LEX::sp_for_loop_increment(THD *thd, const Lex_for_loop_st &loop) } -bool LEX::sp_for_loop_intrange_finalize(THD *thd, const Lex_for_loop_st &loop) +bool LEX::sp_for_loop_intrange_iterate(THD *thd, const Lex_for_loop_st &loop) { sphead->reset_lex(thd); @@ -7103,13 +7212,11 @@ bool LEX::sp_for_loop_intrange_finalize(THD *thd, const Lex_for_loop_st &loop) thd->lex->sphead->restore_lex(thd))) return true; - // Generate a jump to the beginning of the loop - DBUG_ASSERT(this == thd->lex); - return sp_while_loop_finalize(thd); + return false; } -bool LEX::sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &loop) +bool LEX::sp_for_loop_cursor_iterate(THD *thd, const Lex_for_loop_st &loop) { sp_instr_cfetch *instr= new (thd->mem_root) sp_instr_cfetch(sphead->instructions(), @@ -7117,10 +7224,10 @@ bool LEX::sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &loop) if (unlikely(instr == NULL) || unlikely(sphead->add_instr(instr))) return true; instr->add_to_varlist(loop.m_index); - // Generate a jump to the beginning of the loop - return sp_while_loop_finalize(thd); + return false; } + bool LEX::sp_for_loop_outer_block_finalize(THD *thd, const Lex_for_loop_st &loop) { @@ -7749,13 +7856,22 @@ bool LEX::sp_iterate_statement(THD *thd, const LEX_CSTRING *label_name) bool LEX::sp_continue_loop(THD *thd, sp_label *lab) { - if (lab->ctx->for_loop().m_index) + const sp_pcontext::Lex_for_loop &for_loop= lab->ctx->for_loop(); + /* + FOR loops need some additional instructions (e.g. an integer increment or + a cursor fetch) before the "jump to the start of the body" instruction. + We need to check two things here: + - If we're in a FOR loop at all. + - If the label pointed by "lab" belongs exactly to the nearest FOR loop, + rather than to a nested LOOP/WHILE/REPEAT inside the FOR. + */ + if (for_loop.m_index /* we're in some FOR loop */ && + for_loop.m_start_label == lab /* lab belongs to the FOR loop */) { - // We're in a FOR loop, increment the index variable before backward jump - sphead->reset_lex(thd); - DBUG_ASSERT(this != thd->lex); - if (thd->lex->sp_for_loop_increment(thd, lab->ctx->for_loop()) || - thd->lex->sphead->restore_lex(thd)) + // We're in a FOR loop, and "ITERATE loop_label" belongs to this FOR loop. + if (for_loop.is_for_loop_cursor() ? + sp_for_loop_cursor_iterate(thd, for_loop) : + sp_for_loop_intrange_iterate(thd, for_loop)) return true; } return sp_change_context(thd, lab->ctx, false) || @@ -9451,6 +9567,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) { @@ -9529,16 +9775,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()) @@ -9561,9 +9801,22 @@ Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cdb, if (!db_int.str || check_routine_name(&name)) return NULL; + return make_item_func_call_generic(thd, Lex_ident_sys(db_int.str, db_int.length), 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_int, &name, true, args); + return builder->create_with_db(thd, &db, &name, true, args); } @@ -10004,8 +10257,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; } @@ -11284,6 +11546,72 @@ exit: } +/** + @brief + Save the original names of items from the item list. + + @retval + true - if an error occurs + false - otherwise +*/ + +bool st_select_lex::save_item_list_names(THD *thd) +{ + if (orig_names_of_item_list_elems) + return false; + + Query_arena *arena, backup; + arena= thd->activate_stmt_arena_if_needed(&backup); + + if (unlikely(!(orig_names_of_item_list_elems= new(thd->mem_root) + List))) + return true; + + List_iterator_fast li(item_list); + Item *item; + + while ((item= li++)) + { + 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); + orig_names_of_item_list_elems= 0; + return true; + } + } + + if (arena) + thd->restore_active_arena(arena, &backup); + + return false; +} + + +/** + @brief + Restore the name of each item in the item_list of this st_select_lex + from orig_names_of_item_list_elems. +*/ + +void st_select_lex::restore_item_list_names() +{ + if (!orig_names_of_item_list_elems) + return; + + DBUG_ASSERT(item_list.elements == orig_names_of_item_list_elems->elements); + + List_iterator_fast it(*orig_names_of_item_list_elems); + Lex_ident_sys *new_name; + List_iterator_fast li(item_list); + Item *item; + + while ((item= li++) && (new_name= it++)) + lex_string_set( &item->name, new_name->str); +} + bool LEX::stmt_install_plugin(const DDL_options_st &opt, const Lex_ident_sys_st &name, const LEX_CSTRING &soname) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c55a64bdd71..74f47782bc3 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -145,7 +145,7 @@ public: }; -struct Lex_ident_sys_st: public LEX_CSTRING +struct Lex_ident_sys_st: public LEX_CSTRING, Sql_alloc { public: bool copy_ident_cli(const THD *thd, const Lex_ident_cli_st *str); @@ -182,6 +182,10 @@ public: LEX_CSTRING tmp= {name, length}; set_valid_utf8(&tmp); } + Lex_ident_sys(const 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); @@ -1227,6 +1231,11 @@ public: List grouping_tmp_fields; List udf_list; /* udf function calls stack */ List *index_hints; /* list of USE/FORCE/IGNORE INDEX */ + /* + This list is used to restore the names of items + from item_list after each execution of the statement. + */ + List *orig_names_of_item_list_elems; List save_many_values; List *save_insert_list; @@ -1289,6 +1298,8 @@ public: and all inner subselects. */ uint select_n_where_fields; + /* Total number of elements in group by and order by lists */ + uint order_group_num; /* reserved for exists 2 in */ uint select_n_reserved; /* @@ -1443,6 +1454,9 @@ public: bool straight_fl); TABLE_LIST *convert_right_join(); List* get_item_list(); + bool save_item_list_names(THD *thd); + void restore_item_list_names(); + ulong get_table_join_options(); void set_lock_for_tables(thr_lock_type lock_type, bool for_update, bool skip_locks); @@ -1481,6 +1495,7 @@ public: init_select(); } bool setup_ref_array(THD *thd, uint order_group_num); + uint get_cardinality_of_ref_ptrs_slice(uint order_group_num_arg); void print(THD *thd, String *str, enum_query_type query_type); void print_item_list(THD *thd, String *str, enum_query_type query_type); void print_set_clause(THD *thd, String *str, enum_query_type query_type); @@ -1592,6 +1607,7 @@ public: bool no_to_clones); List window_specs; + bool is_win_spec_list_built; void prepare_add_window_spec(THD *thd); bool add_window_def(THD *thd, LEX_CSTRING *win_name, LEX_CSTRING *win_ref, SQL_I_List win_partition_list, @@ -2502,6 +2518,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. @@ -2822,8 +2847,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 *); @@ -4187,8 +4212,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, @@ -4316,7 +4375,7 @@ public: const LEX_CSTRING *index, const Lex_for_loop_bounds_st &bounds); bool sp_for_loop_intrange_condition_test(THD *thd, const Lex_for_loop_st &loop); - bool sp_for_loop_intrange_finalize(THD *thd, const Lex_for_loop_st &loop); + bool sp_for_loop_intrange_iterate(THD *thd, const Lex_for_loop_st &loop); /* Cursor FOR LOOP methods */ bool sp_for_loop_cursor_declarations(THD *thd, Lex_for_loop_st *loop, @@ -4332,7 +4391,7 @@ public: Lex_for_loop_bounds_st *bounds, sp_lex_cursor *cur); bool sp_for_loop_cursor_condition_test(THD *thd, const Lex_for_loop_st &loop); - bool sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &); + bool sp_for_loop_cursor_iterate(THD *thd, const Lex_for_loop_st &); /* Generic FOR LOOP methods*/ @@ -4390,9 +4449,12 @@ public: */ bool sp_for_loop_finalize(THD *thd, const Lex_for_loop_st &loop) { - return loop.is_for_loop_cursor() ? - sp_for_loop_cursor_finalize(thd, loop) : - sp_for_loop_intrange_finalize(thd, loop); + if (loop.is_for_loop_cursor() ? + sp_for_loop_cursor_iterate(thd, loop) : + sp_for_loop_intrange_iterate(thd, loop)) + return true; + // Generate a jump to the beginning of the loop + return sp_while_loop_finalize(thd); } bool sp_for_loop_outer_block_finalize(THD *thd, const Lex_for_loop_st &loop); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index cc6232d2517..08181835dba 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 665d2143872..6557f1c5ecd 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2435,7 +2435,7 @@ resume: MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); /* Reset values shown in processlist */ thd->examined_row_count_for_statement= thd->sent_row_count_for_statement= 0; - thd->set_command(COM_SLEEP); + thd->mark_connection_idle(); thd->m_statement_psi= NULL; thd->m_digest= NULL; @@ -2449,6 +2449,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(); @@ -4893,9 +4895,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 @@ -5865,7 +5913,7 @@ finish: thd->release_transactional_locks(); } } - else if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode()) + else if (! thd->in_sub_stmt && ! thd->in_active_multi_stmt_transaction()) { /* - If inside a multi-statement transaction, @@ -6779,6 +6827,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) FALSE, FALSE)) return TRUE; /* Access denied */ + thd->col_access= dst_table->grant.privilege; // for sql_show.cc /* Check_grant will grant access if there is any column privileges on all of the tables thanks to the fourth parameter (bool show_table). @@ -7648,6 +7697,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_partition.cc b/sql/sql_partition.cc index 466542b92e9..e9ba25fbc79 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2489,7 +2489,7 @@ char *generate_partition_syntax_for_frm(THD *thd, partition_info *part_info, HA_CREATE_INFO *create_info, Alter_info *alter_info) { - Sql_mode_instant_remove sms(thd, MODE_ANSI_QUOTES); + Sql_mode_save_for_frm_handling sql_mode_save(thd); char *res= generate_partition_syntax(thd, part_info, buf_length, true, create_info, alter_info); DBUG_EXECUTE_IF("generate_partition_syntax_for_frm", diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 8bab244c709..008aa2b5de1 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1688,7 +1688,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; @@ -1969,7 +1968,7 @@ static void plugin_load(MEM_ROOT *tmp_root) the mutex here to satisfy the assert */ mysql_mutex_lock(&LOCK_plugin); - plugin_add(tmp_root, false, &name, &dl, MYF(ME_ERROR_LOG)); + plugin_add(tmp_root, true, &name, &dl, MYF(ME_ERROR_LOG)); free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); mysql_mutex_unlock(&LOCK_plugin); } diff --git a/sql/sql_plugin_services.inl b/sql/sql_plugin_services.inl index b9f43057d60..1ee66942241 100644 --- a/sql/sql_plugin_services.inl +++ b/sql/sql_plugin_services.inl @@ -228,11 +228,6 @@ static struct json_service_st json_handler= json_unescape_json }; -static struct thd_mdl_service_st thd_mdl_handler= -{ - thd_mdl_context -}; - struct sql_service_st sql_service_handler= { mysql_init, @@ -258,6 +253,11 @@ struct sql_service_st sql_service_handler= mysql_ssl_set }; +static struct thd_mdl_service_st thd_mdl_handler= +{ + thd_mdl_context +}; + #define DEFINE_warning_function(name, ret) { \ static query_id_t last_query_id= -1; \ THD *thd= current_thd; \ @@ -352,8 +352,8 @@ 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 }, - { "thd_mdl_service", VERSION_thd_mdl, &thd_mdl_handler }, { "sql_service", VERSION_sql_service, &sql_service_handler }, + { "thd_mdl_service", VERSION_thd_mdl, &thd_mdl_handler }, { "provider_service_bzip2", VERSION_provider_bzip2, &provider_handler_bzip2 }, { "provider_service_lz4", VERSION_provider_lz4, &provider_handler_lz4 }, { "provider_service_lzma", VERSION_provider_lzma, &provider_handler_lzma }, diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index cca97ebd738..3e915cf3af5 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -130,6 +130,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 #include "sql_audit.h" // mysql_audit_release @@ -179,7 +180,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. */ @@ -277,7 +278,6 @@ private: class Ed_connection; - /****************************************************************************** Implementation ******************************************************************************/ @@ -3849,6 +3849,7 @@ 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(); @@ -3873,28 +3874,33 @@ static bool 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_QUERY, - 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 ****************************************************************************/ @@ -4472,7 +4478,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; } @@ -4481,7 +4487,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)); @@ -4490,7 +4496,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 @@ -5885,7 +5891,8 @@ bool Protocol_local::send_result_set_metadata(List *list, uint flags) for (uint pos= 0 ; (item= it++); pos++) { - if (store_item_metadata(thd, item, pos)) + Send_field sf(thd, item); + if (store_field_metadata(thd, sf, item->charset_for_protocol(), pos)) goto err; } @@ -6277,10 +6284,9 @@ extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql) 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(); - new_thd->client_capabilities= client_flag; - /* TOSO: decide if we should turn the auditing off for such threads. @@ -6311,4 +6317,3 @@ extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql) DBUG_PRINT("exit",("Mysql handler: %p", mysql)); DBUG_RETURN(mysql); } - diff --git a/sql/sql_priv.h b/sql/sql_priv.h index f5b408039c5..b4bf9d60ba1 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -173,7 +173,8 @@ #define OPTIMIZER_SWITCH_COND_PUSHDOWN_FROM_HAVING (1ULL << 33) #define OPTIMIZER_SWITCH_NOT_NULL_RANGE_SCAN (1ULL << 34) #define OPTIMIZER_SWITCH_HASH_JOIN_CARDINALITY (1ULL << 35) -#define OPTIMIZER_SWITCH_SARGABLE_CASEFOLD (1ULL << 36) +#define OPTIMIZER_SWITCH_CSET_NARROWING (1ULL << 36) +#define OPTIMIZER_SWITCH_SARGABLE_CASEFOLD (1ULL << 37) #define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \ 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 55c24e9f363..e7fdfea8b2b 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -4324,11 +4324,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)) @@ -4616,6 +4622,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; @@ -4623,6 +4633,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)) @@ -4634,7 +4657,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 { @@ -4643,12 +4669,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_select.cc b/sql/sql_select.cc index 44bb31db41c..d56b6052447 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -141,9 +141,10 @@ static int sort_keyuse(KEYUSE *a,KEYUSE *b); static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables); static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, bool allow_full_scan, table_map used_tables); -static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, +static bool get_quick_record_count(THD *thd, SQL_SELECT *select, TABLE *table, - const key_map *keys,ha_rows limit); + const key_map *keys,ha_rows limit, + ha_rows *quick_count); static void optimize_straight_join(JOIN *join, table_map join_tables); static bool greedy_search(JOIN *join, table_map remaining_tables, uint depth, uint use_cond_selectivity); @@ -241,8 +242,8 @@ static int join_read_last_key(JOIN_TAB *tab); static int join_no_more_records(READ_RECORD *info); static int join_read_next(READ_RECORD *info); static int join_init_quick_read_record(JOIN_TAB *tab); -static int test_if_quick_select(JOIN_TAB *tab); -static bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab); +static quick_select_return test_if_quick_select(JOIN_TAB *tab); +static int test_if_use_dynamic_range_scan(JOIN_TAB *join_tab); static int join_read_first(JOIN_TAB *tab); static int join_read_next(READ_RECORD *info); static int join_read_next_same(READ_RECORD *info); @@ -279,7 +280,8 @@ static bool test_if_cheaper_ordering(const JOIN_TAB *tab, static int test_if_order_by_key(JOIN *, ORDER *, TABLE *, uint, uint *); static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order, ha_rows select_limit, bool no_changes, - const key_map *map); + const key_map *map, + bool *fatal_error); static bool list_contains_unique_index(TABLE *table, bool (*find_func) (Field *, void *), void *data); static bool find_field_in_item_list (Field *field, void *data); @@ -1497,6 +1499,26 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num, if (setup_wild(thd, tables_list, fields_list, &all_fields, select_lex, false)) DBUG_RETURN(-1); + /* + If the select_lex is immediately contained within a derived table + AND this derived table is a CTE + WITH supplied column names + AND we have the correct number of elements in both lists + (mismatches found in mysql_derived_prepare/rename_columns_of_derived_unit) + THEN NOW is the time to take a copy of these item_names for + later restoration if required. + */ + TABLE_LIST *derived= select_lex->master_unit()->derived; + + if (derived && + derived->with && + derived->with->column_list.elements && + (derived->with->column_list.elements == select_lex->item_list.elements)) + { + if (select_lex->save_item_list_names(thd)) + DBUG_RETURN(-1); + } + if (thd->lex->current_select->first_cond_optimization) { if ( conds && ! thd->lex->current_select->merged_into) @@ -1974,7 +1996,8 @@ int JOIN::optimize() object a pointer to which is set in the field JOIN_TAB::rowid_filter of the joined table. - @retval false always + @retval false Ok + @retval true Error */ bool JOIN::make_range_rowid_filters() @@ -2015,17 +2038,25 @@ bool JOIN::make_range_rowid_filters() filter_map.clear_all(); filter_map.set_bit(tab->range_rowid_filter_info->get_key_no()); filter_map.merge(tab->table->with_impossible_ranges); - int rc= sel->test_quick_select(thd, filter_map, (table_map) 0, - (ha_rows) HA_POS_ERROR, - true /* force index */, false, true, true); - if (thd->is_error()) - goto no_filter; + quick_select_return rc; + /* + EQ_FUNC and EQUAL_FUNC already sent unusable key notes (if any) + during update_ref_and_keys(). Have only other functions raise notes + from can_optimize_scalar_range(). + */ + rc= sel->test_quick_select(thd, filter_map, (table_map) 0, + (ha_rows) HA_POS_ERROR, true, false, true, + true, Item_func::BITMAP_EXCEPT_ANY_EQUALITY); + if (rc == SQL_SELECT::ERROR || thd->is_error()) + { + DBUG_RETURN(true); /* Fatal error */ + } /* If SUBS_IN_TO_EXISTS strtrategy is chosen for the subquery then additional conditions are injected into WHERE/ON/HAVING and it may happen that the call of test_quick_select() discovers impossible range. */ - if (rc == -1) + if (rc == SQL_SELECT::IMPOSSIBLE_RANGE) { const_table_map|= tab->table->map; goto no_filter; @@ -3056,20 +3087,29 @@ int JOIN::optimize_stage2() tab= &join_tab[const_tables]; if (order) { + bool fatal_err; skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, true, // no_changes - &tab->table->keys_in_use_for_order_by); + &tab->table->keys_in_use_for_order_by, + &fatal_err); + if (fatal_err) + DBUG_RETURN(1); } if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array, order, fields_list, all_fields, &all_order_fields_used))) { + bool fatal_err= 0; const bool skip_group= skip_sort_order && test_if_skip_sort_order(tab, group_list, select_limit, - true, // no_changes - &tab->table->keys_in_use_for_group_by); + true, // no_changes + &tab->table->keys_in_use_for_group_by, + &fatal_err); + if (fatal_err) + DBUG_RETURN(1); + count_field_types(select_lex, &tmp_table_param, all_fields, 0); if ((skip_group && all_order_fields_used) || select_limit == HA_POS_ERROR || @@ -3334,12 +3374,16 @@ int JOIN::optimize_stage2() 'need_tmp' implies that there will be more postprocessing so the specified 'limit' should not be enforced yet. */ + bool fatal_err; const ha_rows limit = need_tmp ? HA_POS_ERROR : select_limit; if (test_if_skip_sort_order(tab, group_list, limit, false, - &tab->table->keys_in_use_for_group_by)) + &tab->table->keys_in_use_for_group_by, + &fatal_err)) { ordered_index_usage= ordered_index_group_by; } + if (fatal_err) + DBUG_RETURN(1); } /* @@ -3362,11 +3406,15 @@ int JOIN::optimize_stage2() else if (order && // ORDER BY wo/ preceding GROUP BY (simple_order || skip_sort_order)) // which is possibly skippable { + bool fatal_err; if (test_if_skip_sort_order(tab, order, select_limit, false, - &tab->table->keys_in_use_for_order_by)) + &tab->table->keys_in_use_for_order_by, + &fatal_err)) { ordered_index_usage= ordered_index_order_by; } + if (fatal_err) + DBUG_RETURN(1); } } @@ -5052,8 +5100,15 @@ select_handler *find_select_handler_inner(THD *thd, SELECT_LEX *select_lex, SELECT_LEX_UNIT *select_lex_unit) { - if (select_lex->master_unit()->outer_select()) + if (select_lex->master_unit()->outer_select() || + (select_lex_unit && select_lex->master_unit()->with_clause)) + { + /* + Pushdown is not supported neither for non-top-level SELECTs nor for parts + of SELECT_LEX_UNITs that have CTEs (SELECT_LEX_UNIT::with_clause) + */ return 0; + } TABLE_LIST *tbl= nullptr; // For SQLCOM_INSERT_SELECT the server takes TABLE_LIST @@ -5272,50 +5327,76 @@ err: } -/***************************************************************************** - Create JOIN_TABS, make a guess about the table types, - Approximate how many records will be used in each table -*****************************************************************************/ +/** + Approximate how many records are going to be returned by this table in this + select with this key. -static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, + @param thd Thread handle + @param select Select to be examined + @param table The table of interest + @param keys The keys of interest + @param limit Maximum number of rows of interest + @param quick_count Pointer to where we want the estimate written + + @return Status + @retval false Success + @retval true Error + +*/ +static bool get_quick_record_count(THD *thd, SQL_SELECT *select, TABLE *table, - const key_map *keys,ha_rows limit) + const key_map *keys,ha_rows limit, + ha_rows *quick_count) { - int error; + quick_select_return error; DBUG_ENTER("get_quick_record_count"); uchar buff[STACK_BUFF_ALLOC]; if (unlikely(check_stack_overrun(thd, STACK_MIN_SIZE, buff))) - DBUG_RETURN(0); // Fatal error flag is set + DBUG_RETURN(false); // Fatal error flag is set if (select) { select->head=table; table->reginfo.impossible_range=0; - if (likely((error= - select->test_quick_select(thd, *(key_map *)keys, - (table_map) 0, - limit, 0, FALSE, - TRUE, /* remove_where_parts*/ - FALSE, TRUE)) == - 1)) + /* + EQ_FUNC and EQUAL_FUNC already sent unusable key notes (if any) + during update_ref_and_keys(). Have only other functions raise notes + from can_optimize_scalar_range(). + */ + error= select->test_quick_select(thd, *(key_map *)keys, (table_map) 0, + limit, 0, FALSE, + TRUE, /* remove_where_parts*/ + FALSE, + Item_func::BITMAP_EXCEPT_ANY_EQUALITY); + + if (error == SQL_SELECT::OK) { - /* - opt_range_condition_rows was updated in test_quick_select to be - the smallest number of rows in any range. - select->quick->records is the number of rows in range with - smallest cost. - */ - DBUG_ASSERT(select->quick->records >= - table->opt_range_condition_rows); - DBUG_RETURN(table->opt_range_condition_rows); + if (select->quick) + { + /* + opt_range_condition_rows was updated in test_quick_select to be + the smallest number of rows in any range. + select->quick->records is the number of rows in range with + smallest cost. + */ + DBUG_ASSERT(select->quick->records >= + table->opt_range_condition_rows); + *quick_count= select->quick->records; + } + DBUG_RETURN(false); } - if (unlikely(error == -1)) + if (error == SQL_SELECT::IMPOSSIBLE_RANGE) { table->reginfo.impossible_range=1; - DBUG_RETURN(0); + *quick_count= 0; + DBUG_RETURN(false); } + if (unlikely(error == SQL_SELECT::ERROR)) + DBUG_RETURN(true); + DBUG_PRINT("warning",("Couldn't use record count on const keypart")); } - DBUG_RETURN(HA_POS_ERROR); /* This shouldn't happend */ + *quick_count= HA_POS_ERROR; + DBUG_RETURN(false); /* This shouldn't happen */ } /* @@ -5475,6 +5556,7 @@ make_join_statistics(JOIN *join, List &tables_list, /* The following should be optimized to only clear critical things */ bzero((void*)stat, sizeof(JOIN_TAB)* table_count); + join->top_join_tab_count= table_count; /* Initialize POSITION objects */ for (i=0 ; i <= table_count ; i++) @@ -6057,11 +6139,10 @@ make_join_statistics(JOIN *join, List &tables_list, (SORT_INFO*) 0, 1, &error); if (!select) goto error; - records= get_quick_record_count(join->thd, select, s->table, - &s->const_keys, join->row_limit); - if (join->thd->is_error()) + if (get_quick_record_count(join->thd, select, s->table, + &s->const_keys, join->row_limit, &records)) { - /* get_quick_record_count generated an error */ + /* There was an error in test_quick_select */ delete select; goto error; } @@ -6078,8 +6159,8 @@ make_join_statistics(JOIN *join, List &tables_list, join->cond_equal= &((Item_cond_and*) (join->conds))->m_cond_equal; s->quick=select->quick; - s->needed_reg=select->needed_reg; select->quick=0; + s->needed_reg=select->needed_reg; impossible_range= records == 0 && s->table->reginfo.impossible_range; if (optimizer_flag(join->thd, OPTIMIZER_SWITCH_USE_ROWID_FILTER)) s->table->init_cost_info_for_usable_range_rowid_filters(join->thd); @@ -7140,6 +7221,7 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field) { field->raise_note_cannot_use_key_part(thd, key, part, equal_str, + key_field->cond->compare_collation(), key_field->val, compat); } @@ -14023,15 +14105,19 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) */ if (sel->cond && !sel->cond->fixed()) sel->cond->quick_fix_field(); + quick_select_return res; - if (sel->test_quick_select(thd, tab->keys, - ((used_tables & ~ current_map) | - OUTER_REF_TABLE_BIT), - (join->select_options & - OPTION_FOUND_ROWS ? - HA_POS_ERROR : - join->unit->lim.get_select_limit()), 0, - FALSE, FALSE, FALSE) < 0) + if ((res= sel->test_quick_select(thd, tab->keys, + ((used_tables & ~ current_map) | + OUTER_REF_TABLE_BIT), + (join->select_options & + OPTION_FOUND_ROWS ? + HA_POS_ERROR : + join->unit->lim.get_select_limit()), + 0, + FALSE, FALSE, FALSE, + Item_func::BITMAP_ALL)) == + SQL_SELECT::IMPOSSIBLE_RANGE) { /* Before reporting "Impossible WHERE" for the whole query @@ -14039,18 +14125,23 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) */ sel->cond=orig_cond; if (!*tab->on_expr_ref || - sel->test_quick_select(thd, tab->keys, - used_tables & ~ current_map, - (join->select_options & - OPTION_FOUND_ROWS ? - HA_POS_ERROR : - join->unit->lim.get_select_limit()),0, - FALSE, FALSE, FALSE, TRUE) < 0) + (res= sel->test_quick_select(thd, tab->keys, + used_tables & ~ current_map, + (join->select_options & + OPTION_FOUND_ROWS ? + HA_POS_ERROR : + join->unit->lim.get_select_limit()), + 0, FALSE, FALSE, FALSE, + Item_func::BITMAP_NONE)) == + SQL_SELECT::IMPOSSIBLE_RANGE) DBUG_RETURN(1); // Impossible WHERE } else sel->cond=orig_cond; + if (res == SQL_SELECT::ERROR) + DBUG_RETURN(1); /* Some error in one of test_quick_select calls */ + /* Fix for EXPLAIN */ if (sel->quick) { @@ -15783,12 +15874,17 @@ bool error_if_full_join(JOIN *join) build_range_rowid_filter() Build range rowid filter. This function should only be called if - need_to_build_rowid_filter - is true + need_to_build_rowid_filter is true + + @retval + 0 ok + @retval + 1 Error, transaction should be rolled back */ -void JOIN_TAB::build_range_rowid_filter() +bool JOIN_TAB::build_range_rowid_filter() { + DBUG_ASSERT(need_to_build_rowid_filter && rowid_filter); /** @@ -15804,8 +15900,8 @@ void JOIN_TAB::build_range_rowid_filter() Rowid_filter_tracker *rowid_tracker= rowid_filter->get_tracker(); table->file->set_time_tracker(rowid_tracker->get_time_tracker()); rowid_tracker->start_tracking(join->thd); - - if (rowid_filter->build()) + Rowid_filter::build_return_code build_rc= rowid_filter->build(); + if (build_rc != Rowid_filter::SUCCESS) { /* Failed building rowid filter */ clear_range_rowid_filter(); @@ -15813,9 +15909,11 @@ void JOIN_TAB::build_range_rowid_filter() need_to_build_rowid_filter= false; rowid_tracker->stop_tracking(join->thd); table->file->set_time_tracker(table_tracker); + return (build_rc == Rowid_filter::FATAL_ERROR); } + /* Clear used rowid filter @@ -15889,7 +15987,6 @@ void JOIN_TAB::cleanup() */ table->pos_in_table_list->table= NULL; free_tmp_table(join->thd, table); - table= NULL; } else { @@ -15902,8 +15999,8 @@ void JOIN_TAB::cleanup() multiple times (it may be) */ tmp->table= NULL; - table= NULL; } + table= NULL; DBUG_VOID_RETURN; } /*if (table->pos_in_table_list && table->pos_in_table_list->derived) @@ -17265,7 +17362,8 @@ bool check_simple_equality(THD *thd, const Item::Context &ctx, Field *left_field= ((Item_field*) left_item)->field; Field *right_field= ((Item_field*) right_item)->field; - if (!left_field->eq_def(right_field)) + if (!left_field->eq_def(right_field) && + !fields_equal_using_narrowing(thd, left_field, right_field)) return FALSE; /* Search for multiple equalities containing field1 and/or field2 */ @@ -23233,6 +23331,7 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) { enum_nested_loop_state rc; JOIN_CACHE *cache= join_tab->cache; + int err; DBUG_ENTER("sub_select_cache"); /* @@ -23258,7 +23357,7 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) } join_tab->jbuf_loops_tracker->on_scan_init(); - if (!test_if_use_dynamic_range_scan(join_tab)) + if (!(err= test_if_use_dynamic_range_scan(join_tab))) { if (!cache->put_record()) DBUG_RETURN(NESTED_LOOP_OK); @@ -23270,6 +23369,10 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) rc= cache->join_records(FALSE); DBUG_RETURN(rc); } + + if (err < 0) + DBUG_RETURN(NESTED_LOOP_ERROR); + /* TODO: Check whether we really need the call below and we can't do without it. If it's not the case remove it. @@ -23452,7 +23555,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) { if (unlikely(join_tab->need_to_build_rowid_filter)) { - join_tab->build_range_rowid_filter(); + if (join_tab->build_range_rowid_filter()) + DBUG_RETURN(NESTED_LOOP_ERROR); /* We have to check join_tab->rowid_filter again as the above function may have cleared it in case of errors. @@ -24390,8 +24494,18 @@ join_read_prev_same(READ_RECORD *info) static int join_init_quick_read_record(JOIN_TAB *tab) { - if (test_if_quick_select(tab) == -1) - return -1; /* No possible records */ + quick_select_return res= test_if_quick_select(tab); + + if (res == SQL_SELECT::ERROR) + return 1; /* Fatal error */ + + if (res == SQL_SELECT::IMPOSSIBLE_RANGE) + return -1; /* No possible records */ + + /* + Proceed to read rows. If we've created a quick select, use it, otherwise + do a full scan. + */ return join_init_read_record(tab); } @@ -24403,7 +24517,13 @@ int read_first_record_seq(JOIN_TAB *tab) return tab->read_record.read_record(); } -static int + +/* + @brief + Create a new (dynamic) quick select. +*/ + +static quick_select_return test_if_quick_select(JOIN_TAB *tab) { DBUG_EXECUTE_IF("show_explain_probe_test_if_quick_select", @@ -24420,11 +24540,13 @@ test_if_quick_select(JOIN_TAB *tab) if (tab->table->file->inited != handler::NONE) tab->table->file->ha_index_or_rnd_end(); - int res= tab->select->test_quick_select(tab->join->thd, tab->keys, - (table_map) 0, HA_POS_ERROR, 0, - FALSE, /*remove where parts*/FALSE, - FALSE, - /* no warnings */ TRUE); + quick_select_return res; + res= tab->select->test_quick_select(tab->join->thd, tab->keys, + (table_map) 0, HA_POS_ERROR, 0, + FALSE, /*remove where parts*/FALSE, + FALSE, + /* no unusable key notes */ + Item_func::BITMAP_NONE); if (tab->explain_plan && tab->explain_plan->range_checked_fer) tab->explain_plan->range_checked_fer->collect_data(tab->select->quick); @@ -24432,10 +24554,29 @@ test_if_quick_select(JOIN_TAB *tab) } -static -bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab) +/* + @return + 1 - Yes, use dynamically built range + 0 - No, don't use dynamic range (but there's no error) + -1 - Fatal error +*/ + +static +int test_if_use_dynamic_range_scan(JOIN_TAB *join_tab) { - return (join_tab->use_quick == 2 && test_if_quick_select(join_tab) > 0); + if (unlikely(join_tab->use_quick == 2)) + { + quick_select_return res= test_if_quick_select(join_tab); + if (res == SQL_SELECT::ERROR) + return -1; + else + { + /* Both OK and IMPOSSIBLE_RANGE go here */ + return join_tab->select->quick ? 1 : 0; + } + } + else + return 0; } @@ -24457,7 +24598,10 @@ int join_init_read_record(JOIN_TAB *tab) } if (tab->need_to_build_rowid_filter) - tab->build_range_rowid_filter(); + { + if (tab->build_range_rowid_filter()) + return 1; /* Fatal error */ + } if (tab->filesort && tab->sort_table()) // Sort table. return 1; @@ -26282,7 +26426,8 @@ void compute_part_of_sort_key_for_equals(JOIN *join, TABLE *table, The index must cover all fields in , or it will not be considered. - @param no_changes No changes will be made to the query plan. + @param no_changes No changes will be made to the query plan. + @param fatal_error OUT A fatal error occurred @todo - sergeyp: Results of all index merge selects actually are ordered @@ -26296,7 +26441,7 @@ void compute_part_of_sort_key_for_equals(JOIN *join, TABLE *table, static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, - bool no_changes, const key_map *map) + bool no_changes, const key_map *map, bool *fatal_error) { int ref_key; uint UNINIT_VAR(ref_key_parts); @@ -26310,11 +26455,25 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, bool orig_cond_saved= false; int best_key= -1; bool changed_key= false; + THD *thd= tab->join->thd; + Json_writer_object trace_wrapper(thd); + Json_writer_array trace_arr(thd, "test_if_skip_sort_order"); DBUG_ENTER("test_if_skip_sort_order"); + *fatal_error= false; /* Check that we are always called with first non-const table */ DBUG_ASSERT(tab == tab->join->join_tab + tab->join->const_tables); + /* Sorting a single row can always be skipped */ + if (tab->type == JT_EQ_REF || + tab->type == JT_CONST || + tab->type == JT_SYSTEM) + { + Json_writer_object trace_skip(thd); + trace_skip.add("skipped", "single row access method"); + DBUG_RETURN(1); + } + /* Keys disabled by ALTER TABLE ... DISABLE KEYS should have already been taken into account. @@ -26449,7 +26608,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, */ key_map new_ref_key_map; COND *save_cond; - bool res; + quick_select_return res; new_ref_key_map.clear_all(); // Force the creation of quick select new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key. @@ -26464,13 +26623,16 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, HA_POS_ERROR : tab->join->unit-> lim.get_select_limit(), - TRUE, TRUE, FALSE, FALSE) <= 0; - if (res) + TRUE, TRUE, FALSE, FALSE, + Item_func::BITMAP_ALL); + // if we cannot use quick select + if (res != SQL_SELECT::OK || !tab->select->quick) { + if (res == SQL_SELECT::ERROR) + *fatal_error= true; select->cond= save_cond; goto use_filesort; } - DBUG_ASSERT(tab->select->quick); tab->type= JT_RANGE; tab->ref.key= -1; tab->ref.key_parts= 0; @@ -26539,7 +26701,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, !table->is_clustering_key(best_key))) goto use_filesort; - if (table->opt_range_keys.is_set(best_key) && best_key != ref_key) + if (select && table->opt_range_keys.is_set(best_key) && best_key != ref_key) { key_map tmp_map; tmp_map.clear_all(); // Force the creation of quick select @@ -26561,11 +26723,18 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, cond_saved= true; } - select->test_quick_select(join->thd, tmp_map, 0, - join->select_options & OPTION_FOUND_ROWS ? - HA_POS_ERROR : - join->unit->lim.get_select_limit(), - TRUE, FALSE, FALSE, FALSE); + quick_select_return res; + res = select->test_quick_select(join->thd, tmp_map, 0, + join->select_options & OPTION_FOUND_ROWS ? + HA_POS_ERROR : + join->unit->lim.get_select_limit(), + TRUE, FALSE, FALSE, FALSE, + Item_func::BITMAP_ALL); + if (res == SQL_SELECT::ERROR) + { + *fatal_error= true; + goto use_filesort; + } if (cond_saved) select->cond= saved_cond; @@ -27403,12 +27572,15 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref) enum_check_fields org_count_cuted_fields= thd->count_cuted_fields; MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set); bool result= 0; + key_part_map map= 1; thd->count_cuted_fields= CHECK_FIELD_IGNORE; - for (store_key **copy=ref->key_copy ; *copy ; copy++) + for (store_key **copy=ref->key_copy ; *copy ; copy++, map <<= 1) { + while (map & ref->const_ref_part_map) // skip const ref parts + map <<= 1; // no store_key objects for them if ((*copy)->copy(thd) & 1 || - (ref->null_rejecting && (*copy)->null_key)) + ((ref->null_rejecting & map) && (*copy)->null_key)) { result= 1; break; diff --git a/sql/sql_select.h b/sql/sql_select.h index 24dc3fafd27..f1198033c68 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -34,6 +34,8 @@ #include "opt_range.h" /* SQL_SELECT, QUICK_SELECT_I */ #include "filesort.h" +#include "cset_narrowing.h" + typedef struct st_join_table JOIN_TAB; /* Values in optimize */ #define KEY_OPTIMIZE_EXISTS 1U @@ -590,7 +592,7 @@ typedef struct st_join_table { /* True if the plan requires a rowid filter and it's not built yet */ bool need_to_build_rowid_filter; - void build_range_rowid_filter(); + bool build_range_rowid_filter(); void clear_range_rowid_filter(); void cleanup(); @@ -2036,7 +2038,14 @@ public: { enum_check_fields org_count_cuted_fields= thd->count_cuted_fields; Use_relaxed_field_copy urfc(to_field->table->in_use); + + /* If needed, perform CharsetNarrowing for making ref access lookup keys. */ + Utf8_narrow do_narrow(to_field, do_cset_narrowing); + store_key_result result= copy_inner(); + + do_narrow.stop(); + thd->count_cuted_fields= org_count_cuted_fields; return result; } @@ -2046,6 +2055,12 @@ public: uchar *null_ptr; uchar err; + /* + This is set to true if we need to do Charset Narrowing when making a lookup + key. + */ + bool do_cset_narrowing= false; + virtual enum store_key_result copy_inner()=0; }; @@ -2065,6 +2080,7 @@ class store_key_field: public store_key if (to_field) { copy_field.set(to_field,from_field,0); + setup_charset_narrowing(); } } @@ -2075,6 +2091,15 @@ class store_key_field: public store_key { copy_field.set(to_field, fld_item->field, 0); field_name= fld_item->full_name(); + setup_charset_narrowing(); + } + + /* Setup CharsetNarrowing if necessary */ + void setup_charset_narrowing() + { + do_cset_narrowing= + Utf8_narrow::should_do_narrowing(copy_field.to_field, + copy_field.from_field->charset()); } protected: @@ -2115,7 +2140,12 @@ public: :store_key(thd, to_field_arg, ptr, null_ptr_arg ? null_ptr_arg : item_arg->maybe_null() ? &err : (uchar*) 0, length), item(item_arg), use_value(val) - {} + { + /* Setup CharsetNarrowing to be done if necessary */ + do_cset_narrowing= + Utf8_narrow::should_do_narrowing(to_field, + item->collation.collation); + } store_key_item(store_key &arg, Item *new_item, bool val) :store_key(arg), item(new_item), use_value(val) {} @@ -2503,7 +2533,7 @@ Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field, extern bool test_if_ref(Item *, Item_field *left_item,Item *right_item); -inline bool optimizer_flag(THD *thd, ulonglong flag) +inline bool optimizer_flag(const THD *thd, ulonglong flag) { return (thd->variables.optimizer_switch & flag); } diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index 28ba88c09f0..f5652bd8886 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -187,7 +187,8 @@ void sequence_definition::store_fields(TABLE *table) true Failure */ -bool check_sequence_fields(LEX *lex, List *fields) +bool check_sequence_fields(LEX *lex, List *fields, + const LEX_CSTRING db, const LEX_CSTRING table_name) { Create_field *field; List_iterator_fast it(*fields); @@ -235,8 +236,7 @@ bool check_sequence_fields(LEX *lex, List *fields) err: my_error(ER_SEQUENCE_INVALID_TABLE_STRUCTURE, MYF(0), - lex->first_select_lex()->table_list.first->db.str, - lex->first_select_lex()->table_list.first->table_name.str, reason); + db.str, table_name.str, reason); DBUG_RETURN(TRUE); } @@ -301,7 +301,8 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *org_table_list) Query_tables_list query_tables_list_backup; TABLE_LIST table_list; // For sequence table DBUG_ENTER("sequence_insert"); - + DBUG_EXECUTE_IF("kill_query_on_sequence_insert", + thd->set_killed(KILL_QUERY);); /* seq is 0 if sequence was created with CREATE TABLE instead of CREATE SEQUENCE diff --git a/sql/sql_sequence.h b/sql/sql_sequence.h index 29c589e67cd..fba04686d69 100644 --- a/sql/sql_sequence.h +++ b/sql/sql_sequence.h @@ -162,6 +162,8 @@ public: class Create_field; extern bool prepare_sequence_fields(THD *thd, List *fields); -extern bool check_sequence_fields(LEX *lex, List *fields); +extern bool check_sequence_fields(LEX *lex, List *fields, + const LEX_CSTRING db, + const LEX_CSTRING table_name); extern bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *table_list); #endif /* SQL_SEQUENCE_INCLUDED */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1fcafd6ec08..c181203c15c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2803,7 +2803,7 @@ static const char *thread_state_info(THD *tmp) if (cond) return "Waiting on cond"; } - return NULL; + return ""; } @@ -6496,7 +6496,8 @@ int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond) tmp_cl->get_collation_name(MY_COLLATION_NAME_MODE_CONTEXT); LEX_CSTRING full_collation_name= tmp_cl->get_collation_name(MY_COLLATION_NAME_MODE_FULL); - bool is_context= cmp(context_collation_name, full_collation_name); + bool is_context= cmp(context_collation_name, full_collation_name) && + !(thd->variables.old_behavior & OLD_MODE_NO_NULL_COLLATION_IDS); /* Some collations are applicable to multiple character sets. Display them only once, with the short name (without the @@ -7061,12 +7062,25 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, if (show_table->file) { (void) read_statistics_for_tables(thd, tables, false); - show_table->file->info(HA_STATUS_VARIABLE | - HA_STATUS_NO_LOCK | - HA_STATUS_CONST | - HA_STATUS_TIME); + show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | + HA_STATUS_CONST | HA_STATUS_TIME); set_statistics_for_table(thd, show_table); } + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + bool need_column_checks= false; + /* we know that the table or at least some of the columns have + necessary privileges, but the caller didn't pass down the GRANT_INFO + object, so we have to rediscover everything again :( */ + if (!(thd->col_access & TABLE_ACLS)) + { + check_grant(thd, SELECT_ACL, tables, 0, 1, 1); + + if (!(tables->grant.privilege & TABLE_ACLS)) + need_column_checks= true; + } +#endif + for (uint i=0 ; i < show_table->s->keys ; i++,key_info++) { if ((key_info->flags & HA_INVISIBLE_KEY) && @@ -7075,6 +7089,26 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, KEY_PART_INFO *key_part= key_info->key_part; LEX_CSTRING *str; LEX_CSTRING unknown= {STRING_WITH_LEN("?unknown field?") }; + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (need_column_checks) + { + uint j; + for (j=0 ; j < key_info->user_defined_key_parts ; j++,key_part++) + { + uint access= get_column_grant(thd, &tables->grant, db_name->str, + table_name->str, + key_part->field->field_name.str); + + if (!access) + break; + } + if (j != key_info->user_defined_key_parts) + continue; + key_part= key_info->key_part; + } +#endif + for (uint j=0 ; j < key_info->user_defined_key_parts ; j++,key_part++) { if (key_part->field->invisible >= INVISIBLE_SYSTEM && @@ -7391,19 +7425,31 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, } else if (!tables->view) { +#ifndef NO_EMBEDDED_ACCESS_CHECKS + /* need any non-SELECT privilege on the table or any of its columns */ + const privilege_t need= TABLE_ACLS & ~SELECT_ACL; + if (!(thd->col_access & need)) + { + /* we know that the table or at least some of the columns have + necessary privileges, but the caller didn't pass down the GRANT_INFO + object, so we have to rediscover everything again :( */ + check_grant(thd, SELECT_ACL, tables, 0, 1, 1); + + if (!(tables->grant.all_privilege() & need)) + DBUG_RETURN(0); + } +#endif + List f_key_list; TABLE *show_table= tables->table; KEY *key_info=show_table->s->key_info; uint primary_key= show_table->s->primary_key; - show_table->file->info(HA_STATUS_VARIABLE | - HA_STATUS_NO_LOCK | + show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); for (uint i=0 ; i < show_table->s->keys ; i++, key_info++) { - if (i != primary_key && !(key_info->flags & HA_NOSAME)) - continue; - - if (i == primary_key && !strcmp(key_info->name.str, primary_key_name.str)) + if (i == primary_key && !strcmp(key_info->name.str, + primary_key_name.str)) { if (store_constraints(thd, table, db_name, table_name, key_info->name.str, key_info->name.length, @@ -7420,16 +7466,14 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, } // Table check constraints - for ( uint i = 0; i < show_table->s->table_check_constraints; i++ ) + for (uint i = 0; i < show_table->s->table_check_constraints; i++) { - Virtual_column_info *check = show_table->check_constraints[ i ]; + Virtual_column_info *check = show_table->check_constraints[i]; - if ( store_constraints( thd, table, db_name, table_name, check->name.str, - check->name.length, - STRING_WITH_LEN( "CHECK" ) ) ) - { - DBUG_RETURN( 1 ); - } + if (store_constraints(thd, table, db_name, table_name, + check->name.str, check->name.length, + STRING_WITH_LEN("CHECK"))) + DBUG_RETURN(1); } show_table->file->get_foreign_key_list(thd, &f_key_list); @@ -7440,7 +7484,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, if (store_constraints(thd, table, db_name, table_name, f_key_info->foreign_id->str, strlen(f_key_info->foreign_id->str), - "FOREIGN KEY", 11)) + STRING_WITH_LEN("FOREIGN KEY"))) DBUG_RETURN(1); } } @@ -7568,8 +7612,7 @@ store_key_column_usage(TABLE *table, const LEX_CSTRING *db_name, } -static int get_schema_key_column_usage_record(THD *thd, - TABLE_LIST *tables, +static int get_schema_key_column_usage_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, const LEX_CSTRING *db_name, const LEX_CSTRING *table_name) @@ -7590,29 +7633,59 @@ static int get_schema_key_column_usage_record(THD *thd, TABLE *show_table= tables->table; KEY *key_info=show_table->s->key_info; uint primary_key= show_table->s->primary_key; - show_table->file->info(HA_STATUS_VARIABLE | - HA_STATUS_NO_LOCK | + show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + bool need_column_checks= false; + /* we know that the table or at least some of the columns have + necessary privileges, but the caller didn't pass down the GRANT_INFO + object, so we have to rediscover everything again :( */ + if (!(thd->col_access & TABLE_ACLS)) + { + check_grant(thd, SELECT_ACL, tables, 0, 1, 1); + + if (!(tables->grant.privilege & TABLE_ACLS)) + need_column_checks= true; + } +#endif + for (uint i=0 ; i < show_table->s->keys ; i++, key_info++) { if (i != primary_key && !(key_info->flags & HA_NOSAME)) continue; uint f_idx= 0; KEY_PART_INFO *key_part= key_info->key_part; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (need_column_checks) + { + uint j; + for (j=0 ; j < key_info->user_defined_key_parts ; j++,key_part++) + { + uint access= get_column_grant(thd, &tables->grant, db_name->str, + table_name->str, + key_part->field->field_name.str); + + if (!access) + break; + } + if (j != key_info->user_defined_key_parts) + continue; + key_part= key_info->key_part; + } +#endif + for (uint j=0 ; j < key_info->user_defined_key_parts ; j++,key_part++) { - if (key_part->field) - { - f_idx++; - restore_record(table, s->default_values); - store_key_column_usage(table, db_name, table_name, - key_info->name.str, key_info->name.length, - key_part->field->field_name.str, - key_part->field->field_name.length, - (longlong) f_idx); - if (schema_table_store_record(thd, table)) - DBUG_RETURN(1); - } + f_idx++; + restore_record(table, s->default_values); + store_key_column_usage(table, db_name, table_name, + key_info->name.str, key_info->name.length, + key_part->field->field_name.str, + key_part->field->field_name.length, + (longlong) f_idx); + if (schema_table_store_record(thd, table)) + DBUG_RETURN(1); } } @@ -7626,6 +7699,23 @@ static int get_schema_key_column_usage_record(THD *thd, List_iterator_fast it(f_key_info->foreign_fields), it1(f_key_info->referenced_fields); uint f_idx= 0; + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (need_column_checks) + { + while ((r_info= it1++)) + { + uint access= get_column_grant(thd, &tables->grant, db_name->str, + table_name->str, r_info->str); + + if (!access) + break; + } + if (!it1.at_end()) + continue; + it1.rewind(); + } +#endif while ((f_info= it++)) { r_info= it1++; @@ -8398,10 +8488,24 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, { List f_key_list; TABLE *show_table= tables->table; - show_table->file->info(HA_STATUS_VARIABLE | - HA_STATUS_NO_LOCK | + show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + /* need any non-SELECT privilege on the table or any of its columns */ + const privilege_t need= TABLE_ACLS & ~SELECT_ACL; + if (!(thd->col_access & need)) + { + /* we know that the table or at least some of the columns have + necessary privileges, but the caller didn't pass down the GRANT_INFO + object, so we have to rediscover everything again :( */ + check_grant(thd, SELECT_ACL, tables, 0, 1, 1); + + if (!(tables->grant.all_privilege() & need)) + DBUG_RETURN(0); + } +#endif + show_table->file->get_foreign_key_list(thd, &f_key_list); FOREIGN_KEY_INFO *f_key_info; List_iterator_fast it(f_key_list); @@ -8416,8 +8520,28 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, table->field[3]->store(STRING_WITH_LEN("def"), cs); table->field[4]->store(f_key_info->referenced_db->str, f_key_info->referenced_db->length, cs); - table->field[10]->store(f_key_info->referenced_table->str, - f_key_info->referenced_table->length, cs); + bool show_ref_table= true; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + /* need any non-SELECT privilege on the table or any of its columns */ + if (!(thd->col_access & need)) + { + TABLE_LIST table_acl_check; + bzero((char*) &table_acl_check, sizeof(table_acl_check)); + table_acl_check.db= *f_key_info->referenced_db; + table_acl_check.table_name= *f_key_info->referenced_table; + table_acl_check.grant.privilege= thd->col_access; + check_grant(thd, SELECT_ACL, &table_acl_check, 0, 1, 1); + + if (!(table_acl_check.grant.all_privilege() & need)) + show_ref_table= false; + } +#endif + if (show_ref_table) + { + table->field[10]->set_notnull(); + table->field[10]->store(f_key_info->referenced_table->str, + f_key_info->referenced_table->length, cs); + } if (f_key_info->referenced_key_name) { table->field[5]->store(f_key_info->referenced_key_name->str, @@ -8815,9 +8939,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); } @@ -9827,7 +9951,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() }; @@ -9969,7 +10093,7 @@ ST_FIELD_INFO referential_constraints_fields_info[]= Column("UPDATE_RULE", Name(), NOT_NULL, OPEN_FULL_TABLE), Column("DELETE_RULE", Name(), NOT_NULL, OPEN_FULL_TABLE), Column("TABLE_NAME", Name(), NOT_NULL, OPEN_FULL_TABLE), - Column("REFERENCED_TABLE_NAME", Name(), NOT_NULL, OPEN_FULL_TABLE), + Column("REFERENCED_TABLE_NAME", Name(), NULLABLE, OPEN_FULL_TABLE), CEnd() }; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 8cddcf53abe..408a5cfe1f6 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3240,7 +3240,8 @@ void TABLE_STATISTICS_CB::update_stats_in_table(TABLE *table) for ( ; *field_ptr; field_ptr++, column_stats++) (*field_ptr)->read_stats= column_stats; /* Mark that stats are now usable */ - table->stats_is_read= true; + table->stats_is_read= (table->stats_cb->stats_available != + TABLE_STAT_NO_STATS); } @@ -3361,8 +3362,6 @@ read_statistics_for_tables(THD *thd, TABLE_LIST *tables, bool force_reload) } mysql_mutex_unlock(&table_share->LOCK_statistics); table->stats_cb->update_stats_in_table(table); - table->stats_is_read= (stats_cb->stats_available != - TABLE_STAT_NO_STATS); } } diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 3ec7eb06fa6..12802bc98e2 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -583,9 +583,7 @@ public: */ bool no_stat_values_provided() { - if (column_stat_nulls == no_values_provided_bitmap()) - return true; - return false; + return (column_stat_nulls == no_values_provided_bitmap()); } }; diff --git a/sql/sql_string.cc b/sql/sql_string.cc index ed83bf1e515..c183873ddc4 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -659,24 +659,6 @@ bool String::append_parenthesized(long nr, int radix) } -bool String::append_with_prefill(const char *s,uint32 arg_length, - uint32 full_length, char fill_char) -{ - int t_length= arg_length > full_length ? arg_length : full_length; - - if (realloc_with_extra_if_needed(str_length + t_length)) - return TRUE; - t_length= full_length - arg_length; - if (t_length > 0) - { - bfill(Ptr+str_length, t_length, fill_char); - str_length=str_length + t_length; - } - append(s, arg_length); - return FALSE; -} - - int Binary_string::strstr(const char *search, uint32 search_length, uint32 offset) const { if (search_length + offset <= str_length) diff --git a/sql/sql_string.h b/sql/sql_string.h index 1f21df619bf..6d8d4acdad9 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -446,6 +446,19 @@ public: float8store(Ptr + str_length, *d); str_length += 8; } + /* + Append a wide character. + The caller must have allocated at least cs->mbmaxlen bytes. + */ + int q_append_wc(my_wc_t wc, CHARSET_INFO *cs) + { + int mblen; + if ((mblen= cs->cset->wc_mb(cs, wc, + (uchar *) end(), + (uchar *) end() + cs->mbmaxlen)) > 0) + str_length+= (uint32) mblen; + return mblen; + } void q_append(const char *data, size_t data_len) { ASSERT_LENGTH(data_len); @@ -1075,8 +1088,6 @@ public: (quot && append(quot)); } bool append(const char *s, size_t size); - bool append_with_prefill(const char *s, uint32 arg_length, - uint32 full_length, char fill_char); bool append_parenthesized(long nr, int radix= 10); // Append with optional character set conversion from cs to charset() @@ -1086,6 +1097,31 @@ public: return append(s.str, s.length, cs); } + // Append a wide character + bool append_wc(my_wc_t wc) + { + if (reserve(mbmaxlen())) + return true; + int mblen= q_append_wc(wc, charset()); + if (mblen > 0) + return false; + else if (mblen == MY_CS_ILUNI && wc != '?') + return q_append_wc('?', charset()) <= 0; + return true; + } + + // Append a number with zero prefilling + bool append_zerofill(uint num, uint width) + { + static const char zeros[15]= "00000000000000"; + char intbuff[15]; + uint length= (uint) (int10_to_str(num, intbuff, 10) - intbuff); + if (length < width && + append(zeros, width - length, &my_charset_latin1)) + return true; + return append(intbuff, length, &my_charset_latin1); + } + /* Append a bitmask in an uint32 with a translation into a C-style human readable representation, e.g.: diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9b7516be3e9..55319a2242f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -60,11 +60,42 @@ #include "ddl_log.h" #include "debug.h" // debug_crash_here() #include -#include "wsrep_mysqld.h" #include "rpl_mi.h" #include "rpl_rli.h" #include "log.h" + +#ifdef WITH_WSREP +#include "wsrep_mysqld.h" + +/** RAII class for temporarily enabling wsrep_ctas in the connection. */ +class Enable_wsrep_ctas_guard +{ + public: + /** + @param thd - pointer to the context of connection in which + wsrep_ctas mode needs to be enabled. + @param ctas - true if this is CREATE TABLE AS SELECT and + wsrep_on + */ + explicit Enable_wsrep_ctas_guard(THD *thd, const bool ctas) + : m_thd(thd) + { + if (ctas) + thd->wsrep_ctas= true; + } + + ~Enable_wsrep_ctas_guard() + { + m_thd->wsrep_ctas= false; + } + private: + THD* m_thd; +}; + +#endif /* WITH_WSREP */ + #include "sql_debug.h" +#include "scope.h" #ifdef _WIN32 #include @@ -1549,11 +1580,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, } else { +#ifdef WITH_WSREP if (WSREP(thd) && hton && !wsrep_should_replicate_ddl(thd, hton)) { error= 1; goto err; } +#endif if (thd->locked_tables_mode == LTM_LOCK_TABLES || thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES) @@ -2827,7 +2860,8 @@ mysql_prepare_create_table_finalize(THD *thd, HA_CREATE_INFO *create_info, } /* The user specified fields: check that structure is ok */ - if (check_sequence_fields(thd->lex, &alter_info->create_list)) + if (check_sequence_fields(thd->lex, &alter_info->create_list, + alter_info->db, alter_info->table_name)) DBUG_RETURN(TRUE); } @@ -4468,7 +4502,13 @@ int create_table_impl(THD *thd, Rollback the empty transaction started in mysql_create_table() call to open_and_lock_tables() when we are using LOCK TABLES. */ - (void) trans_rollback_stmt(thd); + { + uint save_unsafe_rollback_flags= + thd->transaction->stmt.m_unsafe_rollback_flags; + (void) trans_rollback_stmt(thd); + thd->transaction->stmt.m_unsafe_rollback_flags= + save_unsafe_rollback_flags; + } /* Remove normal table without logging. Keep tables locked */ if (mysql_rm_table_no_locks(thd, &table_list, &thd->db, ddl_log_state_rm, @@ -4728,6 +4768,14 @@ int mysql_create_table_no_lock(THD *thd, if (res) { DBUG_ASSERT(thd->is_error()); + /* + Drop the new table, we were not completely done. + + Temporarily modify table_list to avoid dropping source sequence + in CREATE TABLE LIKE . + */ + TABLE_LIST *tail= table_list->next_local; + table_list->next_local= NULL; /* Drop the table as it wasn't completely done */ if (!mysql_rm_table_no_locks(thd, table_list, &thd->db, (DDL_LOG_STATE*) 0, @@ -4744,6 +4792,7 @@ int mysql_create_table_no_lock(THD *thd, */ res= 2; } + table_list->next_local= tail; } } @@ -4755,12 +4804,15 @@ int mysql_create_table_no_lock(THD *thd, @param thd thread handle @param seq sequence definition -@retval 0 failure -@retval 1 success +@retval false success +@retval true failure */ bool wsrep_check_sequence(THD* thd, const sequence_definition *seq) { enum legacy_db_type db_type; + + DBUG_ASSERT(WSREP(thd)); + if (thd->lex->create_info.used_fields & HA_CREATE_USED_ENGINE) { db_type= thd->lex->create_info.db_type->db_type; @@ -4775,7 +4827,7 @@ bool wsrep_check_sequence(THD* thd, const sequence_definition *seq) if (db_type != DB_TYPE_INNODB) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), - "Galera cluster does support only InnoDB sequences"); + "non-InnoDB sequences in Galera cluster"); return(true); } @@ -4786,8 +4838,7 @@ bool wsrep_check_sequence(THD* thd, const sequence_definition *seq) seq->cache) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), - "In Galera if you use CACHE you should set INCREMENT BY 0" - " to behave correctly in a cluster"); + "CACHE without INCREMENT BY 0 in Galera cluster"); return(true); } @@ -7155,6 +7206,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 @@ -9036,6 +9095,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; } } @@ -9146,8 +9229,7 @@ enum fk_column_change_type @retval FK_COLUMN_NO_CHANGE No significant changes are to be done on foreign key columns. @retval FK_COLUMN_DATA_CHANGE ALTER TABLE might result in value - change in foreign key column (and - foreign_key_checks is on). + change in foreign key column. @retval FK_COLUMN_RENAMED Foreign key column is renamed. @retval FK_COLUMN_DROPPED Foreign key column is dropped. */ @@ -9183,7 +9265,18 @@ fk_check_column_changes(THD *thd, Alter_info *alter_info, return FK_COLUMN_RENAMED; } - if ((old_field->is_equal(*new_field) == IS_EQUAL_NO) || + /* + Field_{num|decimal}::is_equal evaluates to IS_EQUAL_NO where + the new_field adds an AUTO_INCREMENT flag on a column due to a + limitation in MyISAM/ARIA. For the purposes of FK determination + it doesn't matter if AUTO_INCREMENT is there or not. + */ + const uint flags= new_field->flags; + new_field->flags&= ~AUTO_INCREMENT_FLAG; + const bool equal_result= old_field->is_equal(*new_field); + new_field->flags= flags; + + if ((equal_result == IS_EQUAL_NO) || ((new_field->flags & NOT_NULL_FLAG) && !(old_field->flags & NOT_NULL_FLAG))) { @@ -10221,6 +10314,12 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, table_list->lock_type= TL_READ; } + enum_tx_isolation iso_level_initial= thd->tx_isolation; + SCOPE_EXIT([thd, iso_level_initial](){ + thd->tx_isolation= iso_level_initial; + }); + thd->tx_isolation= ISO_REPEATABLE_READ; + DEBUG_SYNC(thd, "alter_table_before_open_tables"); thd->open_options|= HA_OPEN_FOR_ALTER; @@ -10253,13 +10352,21 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, bool is_reg_table= table->s->tmp_table == NO_TMP_TABLE; #ifdef WITH_WSREP + /* + If this ALTER TABLE is actually SEQUENCE we need to check + if we can support implementing storage engine. + */ + if (WSREP(thd) && table && table->s->sequence && + wsrep_check_sequence(thd, thd->lex->create_info.seq_create_info)) + DBUG_RETURN(TRUE); + if (WSREP(thd) && (thd->lex->sql_command == SQLCOM_ALTER_TABLE || thd->lex->sql_command == SQLCOM_CREATE_INDEX || thd->lex->sql_command == SQLCOM_DROP_INDEX) && !wsrep_should_replicate_ddl(thd, table_list->table->s->db_type())) DBUG_RETURN(true); -#endif +#endif /* WITH_WSREP */ DEBUG_SYNC(thd, "alter_table_after_open_tables"); @@ -11775,7 +11882,7 @@ static int online_alter_read_from_binlog(THD *thd, rpl_group_info *rgi, do { const auto *descr_event= rgi->rli->relay_log.description_event_for_exec; - auto *ev= Log_event::read_log_event(log_file, descr_event, false, ~0UL); + auto *ev= Log_event::read_log_event(log_file, descr_event, 0, 1, ~0UL); error= log_file->error; if (unlikely(!ev)) { @@ -12544,13 +12651,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) { @@ -12601,6 +12713,7 @@ bool Sql_cmd_create_table_like::execute(THD *thd) int res= 0; const bool used_engine= lex->create_info.used_fields & HA_CREATE_USED_ENGINE; + ulong binlog_format= thd->wsrep_binlog_format(thd->variables.binlog_format); DBUG_ASSERT((m_storage_engine_name.str != NULL) == used_engine); if (lex->create_info.resolve_to_charset_collation_context(thd, @@ -12645,6 +12758,24 @@ 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 + 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); +#endif + if (unlikely(thd->is_fatal_error)) { /* If out of memory when creating a copy of alter_info. */ @@ -12711,15 +12842,17 @@ bool Sql_cmd_create_table_like::execute(THD *thd) #endif #ifdef WITH_WSREP - if (select_lex->item_list.elements && // With SELECT - WSREP(thd) && thd->variables.wsrep_trx_fragment_size > 0) + if (wsrep_ctas) { - my_message( + if (thd->variables.wsrep_trx_fragment_size > 0) + { + my_message( ER_NOT_ALLOWED_COMMAND, "CREATE TABLE AS SELECT is not supported with streaming replication", MYF(0)); - res= 1; - goto end_with_restore_list; + res= 1; + goto end_with_restore_list; + } } #endif /* WITH_WSREP */ @@ -12749,7 +12882,7 @@ bool Sql_cmd_create_table_like::execute(THD *thd) (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs') */ if (thd->query_name_consts && mysql_bin_log.is_open() && - thd->wsrep_binlog_format() == BINLOG_FORMAT_STMT && + binlog_format == BINLOG_FORMAT_STMT && !mysql_bin_log.is_query_in_union(thd, thd->query_id)) { List_iterator_fast it(select_lex->item_list); @@ -12826,6 +12959,8 @@ bool Sql_cmd_create_table_like::execute(THD *thd) /* Store reference to table in case of LOCK TABLES */ create_info.table= create_table->table; + DEBUG_SYNC(thd, "wsrep_create_table_as_select"); + /* select_create is currently not re-execution friendly and needs to be created for every execution of a PS/SP. @@ -12884,13 +13019,18 @@ bool Sql_cmd_create_table_like::execute(THD *thd) !create_info.tmp_table())) { #ifdef WITH_WSREP + if (thd->lex->sql_command == SQLCOM_CREATE_SEQUENCE && + wsrep_check_sequence(thd, lex->create_info.seq_create_info)) + DBUG_RETURN(true); + WSREP_TO_ISOLATION_BEGIN_ALTER(create_table->db.str, create_table->table_name.str, first_table, &alter_info, NULL, &create_info) { WSREP_WARN("CREATE TABLE isolation failure"); - DBUG_RETURN(true); + res= true; + goto end_with_restore_list; } #endif /* WITH_WSREP */ } diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 11d0dcf4ce0..e332d524e16 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -28,13 +28,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 5304a535ad0..c9864e57fff 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -2575,7 +2575,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 9c19311c602..487f7cc9ebc 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 ac2ff437bab..c68809ec784 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 @@ -1823,6 +1807,7 @@ Type_handler::bit_and_int_mixture_handler(uint max_char_length) Note, independently from "treat_bit_as_number": - a single BIT argument gives BIT as a result - two BIT couterparts give BIT as a result + - (BIT + explicit NULL) or (explicit NULL + BIT) give BIT @details This function aggregates field types from the array of items. Found type is supposed to be used later as the result field type @@ -1854,8 +1839,11 @@ aggregate_for_result(const LEX_CSTRING &funcname, Item **items, uint nitems, { const Type_handler *cur= items[i]->type_handler(); set_if_bigger(max_display_length, items[i]->max_display_length()); - if (treat_bit_as_number && - ((type_handler() == &type_handler_bit) ^ (cur == &type_handler_bit))) + uint bit_count= (type_handler() == &type_handler_bit) + + (cur == &type_handler_bit); + uint null_count= (type_handler() == &type_handler_null) + + (cur == &type_handler_null); + if (treat_bit_as_number && bit_count == 1 && null_count == 0) { bit_and_non_bit_mixture_found= true; if (type_handler() == &type_handler_bit) @@ -4574,12 +4562,39 @@ Type_handler_timestamp_common::create_item_copy(THD *thd, Item *item) const /*************************************************************************/ +/* + This method handles YEAR and BIT data types. + It does not switch the data type to DECIAMAL on a + unsigned_flag mistmatch. This important for combinations + like YEAR+NULL, BIT+NULL. +*/ bool Type_handler_int_result:: Item_hybrid_func_fix_attributes(THD *thd, const LEX_CSTRING &name, Type_handler_hybrid_field_type *handler, Type_all_attributes *func, Item **items, uint nitems) const +{ + func->aggregate_attributes_int(items, nitems); + return false; +} + + +/* + This method handles general purpose integer data types + TINYINT, SHORTINT, MEDIUNINT, BIGINT. + It switches to DECIMAL in case if a mismatch in unsigned_flag found. + + Note, we should fix this to ignore all items with + type_handler()==&type_handler_null. + It's too late for 10.4. Let's do it eventually in a higher version. +*/ +bool Type_handler_general_purpose_int:: + Item_hybrid_func_fix_attributes(THD *thd, + const LEX_CSTRING &name, + Type_handler_hybrid_field_type *handler, + Type_all_attributes *func, + Item **items, uint nitems) const { bool unsigned_flag= items[0]->unsigned_flag; for (uint i= 1; i < nitems; i++) @@ -5644,6 +5659,14 @@ Type_handler_string_result::Item_func_hybrid_field_type_get_date( /***************************************************************************/ +bool Type_handler::Item_bool_rowready_func2_fix_length_and_dec(THD *thd, + Item_bool_rowready_func2 *func) const +{ + return func->fix_length_and_dec_generic(thd, this); +} + +/***************************************************************************/ + bool Type_handler_numeric:: Item_func_between_fix_length_and_dec(Item_func_between *func) const { diff --git a/sql/sql_type.h b/sql/sql_type.h index 6c135a40736..8215a3ee759 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -55,6 +55,7 @@ class Item_hybrid_func; class Item_func_min_max; class Item_func_hybrid_field_type; class Item_bool_func2; +class Item_bool_rowready_func2; class Item_func_between; class Item_func_in; class Item_func_round; @@ -150,8 +151,8 @@ scalar_comparison_op_to_lex_cstring(scalar_comparison_op op) case SCALAR_CMP_EQUAL: return LEX_CSTRING{STRING_WITH_LEN("<=>")}; case SCALAR_CMP_LT: return LEX_CSTRING{STRING_WITH_LEN("<")}; case SCALAR_CMP_LE: return LEX_CSTRING{STRING_WITH_LEN("<=")}; - case SCALAR_CMP_GE: return LEX_CSTRING{STRING_WITH_LEN(">")}; - case SCALAR_CMP_GT: return LEX_CSTRING{STRING_WITH_LEN(">=")}; + case SCALAR_CMP_GE: return LEX_CSTRING{STRING_WITH_LEN(">=")}; + case SCALAR_CMP_GT: return LEX_CSTRING{STRING_WITH_LEN(">")}; } DBUG_ASSERT(0); return LEX_CSTRING{STRING_WITH_LEN("")}; @@ -3268,10 +3269,16 @@ public: bool agg_item_collations(DTCollation &c, const LEX_CSTRING &name, Item **items, uint nitems, uint flags, int item_sep); + struct Single_coll_err + { + const DTCollation& coll; + bool first; + }; bool agg_item_set_converter(const DTCollation &coll, const LEX_CSTRING &name, Item **args, uint nargs, - uint flags, int item_sep); + uint flags, int item_sep, + const Single_coll_err *single_item_err= NULL); /* Collect arguments' character sets together. @@ -3683,7 +3690,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); @@ -4251,6 +4257,8 @@ public: } virtual bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr, Item *a, Item *b) const= 0; + virtual bool Item_bool_rowready_func2_fix_length_and_dec(THD *thd, + Item_bool_rowready_func2 *func) const; virtual bool Item_hybrid_func_fix_attributes(THD *thd, const LEX_CSTRING &name, Type_handler_hybrid_field_type *, @@ -5298,6 +5306,12 @@ public: return type_limits_int()->char_length(); } uint32 Item_decimal_notation_int_digits(const Item *item) const override; + bool Item_hybrid_func_fix_attributes(THD *thd, + const LEX_CSTRING &name, + Type_handler_hybrid_field_type *, + Type_all_attributes *atrr, + Item **items, + uint nitems) const override; bool partition_field_check(const LEX_CSTRING &, Item *item_expr) const override { diff --git a/sql/sql_type_fixedbin.h b/sql/sql_type_fixedbin.h index 8aaa7582cd5..698d9843e8a 100644 --- a/sql/sql_type_fixedbin.h +++ b/sql/sql_type_fixedbin.h @@ -136,6 +136,21 @@ public: return Fbt_null(item, false).is_null(); } + /* + Check at fix_fields() time if any of the items can return a nullable + value on conversion to Fbt. + */ + static bool fix_fields_maybe_null_on_conversion_to_fbt(Item **items, + uint count) + { + for (uint i= 0; i < count; i++) + { + if (Fbt::fix_fields_maybe_null_on_conversion_to_fbt(items[i])) + return true; + } + return false; + } + public: Fbt(Item *item, bool *error, bool warn= true) @@ -1534,6 +1549,16 @@ public: Fbt_null na(a), nb(b); return !na.is_null() && !nb.is_null() && !na.cmp(nb); } + bool Item_bool_rowready_func2_fix_length_and_dec(THD *thd, + Item_bool_rowready_func2 *func) const override + { + if (Type_handler::Item_bool_rowready_func2_fix_length_and_dec(thd, func)) + return true; + if (!func->maybe_null() && + Fbt::fix_fields_maybe_null_on_conversion_to_fbt(func->arguments(), 2)) + func->set_maybe_null(); + return false; + } bool Item_hybrid_func_fix_attributes(THD *thd, const LEX_CSTRING &name, Type_handler_hybrid_field_type *h, Type_all_attributes *attr, @@ -1715,6 +1740,9 @@ public: bool Item_func_between_fix_length_and_dec(Item_func_between *func) const override { + if (!func->maybe_null() && + Fbt::fix_fields_maybe_null_on_conversion_to_fbt(func->arguments(), 3)) + func->set_maybe_null(); return false; } longlong Item_func_between_val_int(Item_func_between *func) const override @@ -1737,6 +1765,10 @@ public: Item_func_in *func) const override { + if (!func->maybe_null() && + Fbt::fix_fields_maybe_null_on_conversion_to_fbt(func->arguments(), + func->argument_count())) + func->set_maybe_null(); if (func->compatible_types_scalar_bisection_possible()) { return func->value_list_convert_const_to_int(thd) || diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 398349bd3b6..790fa1a7d1f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -478,10 +478,9 @@ bool Sql_cmd_update::update_single_table(THD *thd) set_statistics_for_table(thd, table); select= make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error); - if (unlikely(error || thd->is_error() || !limit || - (select && select->check_quick(thd, safe_update, limit)) || - table->stat_records() == 0)) - + if (error || !limit || thd->is_error() || table->stat_records() == 0 || + (select && select->check_quick(thd, safe_update, limit, + Item_func::BITMAP_ALL))) { query_plan.set_impossible_where(); if (thd->lex->describe || thd->lex->analyze_stmt) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 10588b54fa5..25fa92cdafc 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1003,9 +1003,10 @@ static int mysql_register_view(THD *thd, DDL_LOG_STATE *ddl_log_state, is_query.length(0); backup_file_name[0]= 0; { - Sql_mode_instant_remove sms(thd, MODE_ANSI_QUOTES); + 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 | @@ -1491,35 +1492,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, lex_start(thd); lex->stmt_lex= old_lex; - sql_mode_t saved_mode= thd->variables.sql_mode; - /* switch off modes which can prevent normal parsing of VIEW - - MODE_REAL_AS_FLOAT affect only CREATE TABLE parsing - + MODE_PIPES_AS_CONCAT affect expression parsing - + MODE_ANSI_QUOTES affect expression parsing - + MODE_IGNORE_SPACE affect expression parsing - - MODE_IGNORE_BAD_TABLE_OPTIONS affect only CREATE/ALTER TABLE parsing - * MODE_ONLY_FULL_GROUP_BY affect execution - * MODE_NO_UNSIGNED_SUBTRACTION affect execution - - MODE_NO_DIR_IN_CREATE affect table creation only - - MODE_POSTGRESQL compounded from other modes - - MODE_ORACLE affects Item creation (e.g for CONCAT) - - MODE_MSSQL compounded from other modes - - MODE_DB2 compounded from other modes - - MODE_MAXDB affect only CREATE TABLE parsing - - MODE_NO_KEY_OPTIONS affect only SHOW - - MODE_NO_TABLE_OPTIONS affect only SHOW - - MODE_NO_FIELD_OPTIONS affect only SHOW - - MODE_MYSQL323 affect only SHOW - - MODE_MYSQL40 affect only SHOW - - MODE_ANSI compounded from other modes - (+ transaction mode) - ? MODE_NO_AUTO_VALUE_ON_ZERO affect UPDATEs - + MODE_NO_BACKSLASH_ESCAPES affect expression parsing - */ - thd->variables.sql_mode&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | - MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES | - MODE_ORACLE); - + Sql_mode_save_for_frm_handling sql_mode_save(thd); /* Parse the query. */ parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx); @@ -1532,8 +1505,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, (old_lex->sql_command == SQLCOM_SHOW_CREATE)) lex->sql_command= old_lex->sql_command; - thd->variables.sql_mode= saved_mode; - if (dbchanged && mysql_change_db(thd, &old_db, TRUE)) goto err; } @@ -1755,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_window.cc b/sql/sql_window.cc index 7c3e7617688..e0c7cef1a9e 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -207,27 +207,33 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, DBUG_ENTER("setup_windows"); List_iterator it(win_specs); - /* - Move all unnamed specifications after the named ones. - We could have avoided it if we had built two separate lists for - named and unnamed specifications. - */ - Query_arena *arena, backup; - arena= thd->activate_stmt_arena_if_needed(&backup); - uint i = 0; - uint elems= win_specs.elements; - while ((win_spec= it++) && i++ < elems) + if (!thd->lex->current_select->is_win_spec_list_built) { - if (win_spec->name() == NULL) - { - it.remove(); - win_specs.push_back(win_spec); - } - } - if (arena) - thd->restore_active_arena(arena, &backup); - it.rewind(); + /* + Move all unnamed specifications after the named ones. + We could have avoided it if we had built two separate lists for + named and unnamed specifications. + */ + Query_arena *arena, backup; + arena= thd->activate_stmt_arena_if_needed(&backup); + uint i = 0; + uint elems= win_specs.elements; + while ((win_spec= it++) && i++ < elems) + { + if (win_spec->name() == NULL) + { + it.remove(); + win_specs.push_back(win_spec); + } + } + if (arena) + thd->restore_active_arena(arena, &backup); + + it.rewind(); + + thd->lex->current_select->is_win_spec_list_built= true; + } List_iterator_fast itp(win_specs); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1696d82ead2..b83d9f21f5d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -821,8 +821,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token DATE_SYM /* SQL-2003-R, Oracle-R, PLSQL-R */ %token DAY_SYM /* SQL-2003-R */ %token DEALLOCATE_SYM /* SQL-2003-R */ -%token DECODE_MARIADB_SYM /* Function, non-reserved */ -%token DECODE_ORACLE_SYM /* Function, non-reserved */ %token DEFINER_SYM %token DELAYED_SYM %token DELAY_KEY_WRITE_SYM @@ -1557,7 +1555,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else ident_list ident_list_arg opt_expr_list - decode_when_list_oracle execute_using execute_params @@ -1858,8 +1855,17 @@ rule: %type sp_param_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 @@ -7310,11 +7316,7 @@ alter: | ALTER SEQUENCE_SYM opt_if_exists { LEX *lex= Lex; - lex->name= null_clex_str; - lex->table_type= TABLE_TYPE_UNKNOWN; lex->sql_command= SQLCOM_ALTER_SEQUENCE; - lex->create_info.init(); - lex->no_write_to_binlog= 0; DBUG_ASSERT(!lex->m_sql_cmd); if (Lex->main_select_push()) MYSQL_YYABORT; @@ -9848,8 +9850,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); } @@ -10266,6 +10276,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); @@ -10274,7 +10289,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); } @@ -10356,18 +10374,6 @@ function_call_nonkeyword: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | DECODE_MARIADB_SYM '(' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_func_decode(thd, $3, $5); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | DECODE_ORACLE_SYM '(' expr ',' decode_when_list_oracle ')' - { - $5->push_front($3, thd->mem_root); - if (unlikely(!($$= new (thd->mem_root) Item_func_decode_oracle(thd, *$5)))) - MYSQL_YYABORT; - } | EXTRACT_SYM '(' interval FROM expr ')' { $$=new (thd->mem_root) Item_extract(thd, $3, $5); @@ -10752,7 +10758,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); } @@ -10816,6 +10824,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: @@ -11540,25 +11585,6 @@ when_list_opt_else: } ; -decode_when_list_oracle: - expr ',' expr - { - $$= new (thd->mem_root) List; - if (unlikely($$ == NULL) || - unlikely($$->push_back($1, thd->mem_root)) || - unlikely($$->push_back($3, thd->mem_root))) - MYSQL_YYABORT; - - } - | decode_when_list_oracle ',' expr - { - $$= $1; - if (unlikely($$->push_back($3, thd->mem_root))) - MYSQL_YYABORT; - } - ; - - /* Equivalent to in the SQL:2003 standard. */ /* Warning - may return NULL in case of incomplete SELECT */ table_ref: @@ -15398,10 +15424,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); } ; @@ -16083,8 +16106,6 @@ keyword_sp_var_and_label: | DATAFILE_SYM | DATE_FORMAT_SYM | DAY_SYM - | DECODE_MARIADB_SYM - | DECODE_ORACLE_SYM | DEFINER_SYM | DELAY_KEY_WRITE_SYM | DES_KEY_FILE diff --git a/sql/structs.h b/sql/structs.h index 75bdc9e276b..c8351efd8bf 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -34,6 +34,7 @@ struct TABLE; class Type_handler; class Field; class Index_statistics; +struct Lex_ident_cli_st; class THD; @@ -873,13 +874,10 @@ public: { m_index= 0; m_target_bound= 0; + m_cursor_offset= 0; m_direction= 0; m_implicit_cursor= false; } - void init(const Lex_for_loop_st &other) - { - *this= other; - } bool is_for_loop_cursor() const { return m_target_bound == NULL; } bool is_for_loop_explicit_cursor() const { @@ -908,12 +906,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 09e9d9d3034..ffcfc90aca9 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1051,8 +1051,13 @@ static Sys_var_charptr_fscs Sys_datadir( CMD_LINE(REQUIRED_ARG, 'h'), DEFAULT(mysql_real_data_home)); #ifndef DBUG_OFF +static Sys_var_dbug Sys_dbug( + "debug", "Built-in DBUG debugger", sys_var::SESSION, + CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_has_super)); + static Sys_var_dbug Sys_debug_dbug( - "debug_dbug", "Built-in DBUG debugger", sys_var::SESSION, + "debug_dbug", "Built-in DBUG debugger. Alias for --debug", sys_var::SESSION, CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super)); #endif @@ -1551,7 +1556,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'), @@ -2880,8 +2885,9 @@ export const char *optimizer_switch_names[]= "condition_pushdown_from_having", "not_null_range_scan", "hash_join_cardinality", + "cset_narrowing", "sargable_casefold", - "default", + "default", NullS }; static bool check_legal_optimizer_switch(sys_var *self, THD *thd, @@ -3328,8 +3334,9 @@ Sys_secure_auth( "secure_auth", "Disallow authentication for accounts that have old (pre-4.1) " "passwords", - GLOBAL_VAR(opt_secure_auth), CMD_LINE(OPT_ARG), - DEFAULT(TRUE)); + GLOBAL_VAR(opt_secure_auth), CMD_LINE(OPT_ARG, OPT_SECURE_AUTH), + DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), + DEPRECATED(1006, "")); static bool check_require_secure_transport(sys_var *self, THD *thd, set_var *var) { @@ -3880,6 +3887,7 @@ static const char *old_mode_names[]= "UTF8_IS_UTF8MB3", "IGNORE_INDEX_ONLY_FOR_JOIN", // deprecated since 11.3 "COMPAT_5_1_CHECKSUM", // deprecated since 11.3 + "NO_NULL_COLLATION_IDS", // deprecated since 11.3 "LOCK_ALTER_TABLE_COPY", // deprecated since 11.3 0 }; @@ -5692,7 +5700,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 @@ -5700,7 +5708,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); @@ -5770,7 +5778,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)); @@ -5786,7 +5794,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 ae321e86cf7..120a4e202d7 100644 --- a/sql/sys_vars.inl +++ b/sql/sys_vars.inl @@ -2504,10 +2504,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, @@ -2516,26 +2516,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); @@ -2549,7 +2546,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; } @@ -2557,7 +2554,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 8bc16753e68..2b95cf25911 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1134,19 +1134,9 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, return vcol && vcol->expr->walk(&Item::check_field_expression_processor, 0, field); } - static bool check_constraint(Field *field, Virtual_column_info *vcol) - { - uint32 flags= field->flags; - /* Check constraints can refer it itself */ - field->flags|= NO_DEFAULT_VALUE_FLAG; - const bool res= check(field, vcol); - field->flags= flags; - return res; - } static bool check(Field *field) { if (check(field, field->vcol_info) || - check_constraint(field, field->check_constraint) || check(field, field->default_value)) return true; return false; @@ -1161,6 +1151,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, Field **vfield_ptr= table->vfield; Field **dfield_ptr= table->default_field; Virtual_column_info **check_constraint_ptr= table->check_constraints; + Sql_mode_save_for_frm_handling sql_mode_save(thd); Query_arena backup_arena; Virtual_column_info *vcol= 0; StringBuffer expr_str; @@ -1181,8 +1172,6 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, thd->stmt_arena= table->expr_arena; thd->update_charset(&my_charset_utf8mb4_general_ci, table->s->table_charset); expr_str.append(&parse_vcol_keyword); - Sql_mode_instant_remove sms(thd, MODE_NO_BACKSLASH_ESCAPES | - MODE_EMPTY_STRING_IS_NULL); while (pos < end) { @@ -1364,11 +1353,16 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, /* Check that expressions aren't referring to not yet initialized fields */ for (field_ptr= table->field; *field_ptr; field_ptr++) + { if (check_vcol_forward_refs::check(*field_ptr)) { *error_reported= true; goto end; } + if ((*field_ptr)->check_constraint) + (*field_ptr)->check_constraint->expr-> + walk(&Item::update_func_default_processor, 0, *field_ptr); + } table->find_constraint_correlated_indexes(); @@ -6039,7 +6033,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))))) { @@ -10629,6 +10623,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 35be3bd4b2d..4cfcb9ae41a 100644 --- a/sql/table.h +++ b/sql/table.h @@ -359,6 +359,9 @@ typedef struct st_grant_info const char *table); inline privilege_t aggregate_privs(); inline privilege_t aggregate_cols(); + + /* OR table and all column privileges */ + privilege_t all_privilege(); } GRANT_INFO; enum tmp_table_type @@ -2162,7 +2165,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/threadpool_common.cc b/sql/threadpool_common.cc index 10b7db4eb7e..22730550d1b 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -133,12 +133,17 @@ static void re_init_net_server_extension(THD *thd) #endif /* HAVE_PSI_INTERFACE */ +static inline bool has_unread_compressed_data(const NET *net) +{ + return net->compress && net->remain_in_buf; +} static inline void set_thd_idle(THD *thd) { thd->net.reading_or_writing= 1; #ifdef HAVE_PSI_INTERFACE - net_before_header_psi(&thd->net, thd, 0); + if (!has_unread_compressed_data(&thd->net)) + net_before_header_psi(&thd->net, thd, 0); #endif } @@ -381,10 +386,8 @@ static void handle_wait_timeout(THD *thd) static bool has_unread_data(THD* thd) { NET *net= &thd->net; - if (net->compress && net->remain_in_buf) - return true; Vio *vio= net->vio; - return vio->has_data(vio); + return vio->has_data(vio) || has_unread_compressed_data(net); } diff --git a/sql/transaction.cc b/sql/transaction.cc index 85a18410304..053466c0c14 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -416,7 +416,7 @@ bool trans_rollback_implicit(THD *thd) */ DBUG_ASSERT(thd->transaction->stmt.is_empty() && !thd->in_sub_stmt); - thd->server_status&= ~SERVER_STATUS_IN_TRANS; + thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); res= ha_rollback_trans(thd, true); /* @@ -641,10 +641,6 @@ bool trans_savepoint(THD *thd, LEX_CSTRING name) if (unlikely(ha_savepoint(thd, newsv))) DBUG_RETURN(TRUE); - int error= online_alter_savepoint_set(thd, name); - if (unlikely(error)) - DBUG_RETURN(error); - newsv->prev= thd->transaction->savepoints; thd->transaction->savepoints= newsv; @@ -704,8 +700,6 @@ bool trans_rollback_to_savepoint(THD *thd, LEX_CSTRING name) ER_WARNING_NOT_COMPLETE_ROLLBACK, ER_THD(thd, ER_WARNING_NOT_COMPLETE_ROLLBACK)); - res= res || online_alter_savepoint_rollback(thd, name); - thd->transaction->savepoints= sv; if (res) diff --git a/sql/unireg.cc b/sql/unireg.cc index 783c273f8b7..d936e047801 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -42,7 +42,8 @@ static uint pack_keys(uchar *,uint, KEY *, ulong, uint); static bool pack_header(THD *, uchar *, List &, HA_CREATE_INFO *, ulong, handler *); -static bool pack_vcols(String *, List &, List *); +static bool pack_vcols(THD *thd, String *, + List &, List *); static uint get_interval_id(uint *,List &, Create_field *); static bool pack_fields(uchar **, List &, HA_CREATE_INFO*, ulong); @@ -291,10 +292,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table, create_info->null_bits++; data_offset= (create_info->null_bits + 7) / 8; - sql_mode_t save_sql_mode= thd->variables.sql_mode; - thd->variables.sql_mode &= ~MODE_ANSI_QUOTES; - error= pack_vcols(&vcols, create_fields, create_info->check_constraint_list); - thd->variables.sql_mode= save_sql_mode; + error= pack_vcols(thd, &vcols, + create_fields, create_info->check_constraint_list); if (unlikely(error)) DBUG_RETURN(frm); @@ -792,9 +791,10 @@ static bool pack_expression(String *buf, Virtual_column_info *vcol, } -static bool pack_vcols(String *buf, List &create_fields, - List *check_constraint_list) +static bool pack_vcols(THD *thd, String *buf, List &create_fields, + List *check_constraint_list) { + Sql_mode_save_for_frm_handling sql_mode_save(thd); List_iterator it(create_fields); Create_field *field; diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index 90ede81a06a..8767f698bf2 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -204,6 +204,11 @@ int wsrep_apply_events(THD* thd, (thd->variables.option_bits & ~OPTION_SKIP_REPLICATION) | (ev->flags & LOG_EVENT_SKIP_REPLICATION_F ? OPTION_SKIP_REPLICATION : 0); + if (ev->get_type_code() == GTID_EVENT) + { + thd->variables.option_bits &= ~OPTION_GTID_BEGIN; + } + ev->thd= thd; exec_res= ev->apply_event(thd->wsrep_rgi); DBUG_PRINT("info", ("exec_event result: %d", exec_res)); diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc index 434ef5ff2f7..4c172d8804b 100644 --- a/sql/wsrep_client_service.cc +++ b/sql/wsrep_client_service.cc @@ -282,11 +282,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; @@ -298,6 +305,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_high_priority_service.cc b/sql/wsrep_high_priority_service.cc index c3e1c2638a8..96b7ff8f851 100644 --- a/sql/wsrep_high_priority_service.cc +++ b/sql/wsrep_high_priority_service.cc @@ -46,7 +46,7 @@ public: , m_server_status(thd->server_status) { m_thd->variables.option_bits&= ~OPTION_BEGIN; - m_thd->server_status&= ~SERVER_STATUS_IN_TRANS; + m_thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); m_thd->wsrep_cs().enter_toi_mode(ws_meta); } ~Wsrep_non_trans_mode() @@ -570,6 +570,7 @@ int Wsrep_applier_service::apply_write_set(const wsrep::ws_meta& ws_meta, THD* thd= m_thd; thd->variables.option_bits |= OPTION_BEGIN; + thd->variables.option_bits |= OPTION_GTID_BEGIN; thd->variables.option_bits |= OPTION_NOT_AUTOCOMMIT; DBUG_ASSERT(thd->wsrep_trx().active()); DBUG_ASSERT(thd->wsrep_trx().state() == wsrep::transaction::s_executing); @@ -601,6 +602,8 @@ int Wsrep_applier_service::apply_write_set(const wsrep::ws_meta& ws_meta, thd->wsrep_cs().fragment_applied(ws_meta.seqno()); } thd_proc_info(thd, "wsrep applied write set"); + + thd->variables.option_bits &= ~OPTION_GTID_BEGIN; DBUG_RETURN(ret); } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 9581535ebd3..865085045e5 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1718,7 +1718,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) { @@ -1734,7 +1740,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) @@ -1790,6 +1796,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); @@ -1808,6 +1816,24 @@ exit: } } + /* + 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; } @@ -2011,18 +2037,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, @@ -2942,6 +2993,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. */ @@ -3489,7 +3549,8 @@ int wsrep_ignored_error_code(Log_event* ev, int error) const THD* thd= ev->thd; DBUG_ASSERT(error); - DBUG_ASSERT(wsrep_thd_is_applying(thd)); + /* Note that binlog events can be executed on master also with + BINLOG '....'; */ DBUG_ASSERT(!wsrep_thd_is_local_toi(thd)); if ((wsrep_ignore_apply_errors & WSREP_IGNORE_ERRORS_ON_RECONCILING_DML)) @@ -3691,8 +3752,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 3efe3829f96..bfd92fb42d0 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -503,17 +503,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_on.h b/sql/wsrep_on.h index f85fe3d5d0d..a3ef834523c 100644 --- a/sql/wsrep_on.h +++ b/sql/wsrep_on.h @@ -46,10 +46,6 @@ extern ulong wsrep_forced_binlog_format; #define WSREP_EMULATE_BINLOG(thd) \ (WSREP(thd) && wsrep_emulate_bin_log) -#define WSREP_BINLOG_FORMAT(my_format) \ - ((wsrep_forced_binlog_format != BINLOG_FORMAT_UNSPEC) ? \ - wsrep_forced_binlog_format : my_format) - #else #define WSREP_ON false @@ -57,7 +53,6 @@ extern ulong wsrep_forced_binlog_format; #define WSREP_NNULL(T) (0) #define WSREP_EMULATE_BINLOG(thd) (0) #define WSREP_EMULATE_BINLOG_NNULL(thd) (0) -#define WSREP_BINLOG_FORMAT(my_format) ((ulong)my_format) #endif #endif 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_sst.cc b/sql/wsrep_sst.cc index 33f2088c260..ce19a1d91f2 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -172,6 +172,36 @@ static void* wsrep_sst_joiner_monitor_thread(void *arg __attribute__((unused))) return NULL; } +/* return true if character can be a part of a filename */ +static bool filename_char(int const c) +{ + return isalnum(c) || (c == '-') || (c == '_') || (c == '.'); +} + +/* return true if character can be a part of an address string */ +static bool address_char(int const c) +{ + return filename_char(c) || + (c == ':') || (c == '[') || (c == ']') || (c == '/'); +} + +static bool check_request_str(const char* const str, + bool (*check) (int c), + bool log_warn = true) +{ + for (size_t i(0); str[i] != '\0'; ++i) + { + if (!check(str[i])) + { + if (log_warn) WSREP_WARN("Illegal character in state transfer request: %i (%c).", + str[i], str[i]); + return true; + } + } + + return false; +} + bool wsrep_sst_method_check (sys_var *self, THD* thd, set_var* var) { if ((! var->save_result.string_value.str) || @@ -183,6 +213,16 @@ bool wsrep_sst_method_check (sys_var *self, THD* thd, set_var* var) return 1; } + /* check also that method name is alphanumeric string */ + if (check_request_str(var->save_result.string_value.str, + filename_char, false)) + { + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name.str, + var->save_result.string_value.str ? + var->save_result.string_value.str : "NULL"); + return 1; + } + return 0; } @@ -2028,35 +2068,6 @@ static int sst_donate_other (const char* method, return arg.err; } -/* return true if character can be a part of a filename */ -static bool filename_char(int const c) -{ - return isalnum(c) || (c == '-') || (c == '_') || (c == '.'); -} - -/* return true if character can be a part of an address string */ -static bool address_char(int const c) -{ - return filename_char(c) || - (c == ':') || (c == '[') || (c == ']') || (c == '/'); -} - -static bool check_request_str(const char* const str, - bool (*check) (int c)) -{ - for (size_t i(0); str[i] != '\0'; ++i) - { - if (!check(str[i])) - { - WSREP_WARN("Illegal character in state transfer request: %i (%c).", - str[i], str[i]); - return true; - } - } - - return false; -} - int wsrep_sst_donate(const std::string& msg, const wsrep::gtid& current_gtid, const bool bypass) @@ -2064,7 +2075,7 @@ int wsrep_sst_donate(const std::string& msg, const char* method= msg.data(); size_t method_len= strlen (method); - if (check_request_str(method, filename_char)) + if (check_request_str(method, filename_char, true)) { WSREP_ERROR("Bad SST method name. SST canceled."); return WSREP_CB_FAILURE; @@ -2086,7 +2097,7 @@ int wsrep_sst_donate(const std::string& msg, addr= data; } - if (check_request_str(addr, address_char)) + if (check_request_str(addr, address_char, true)) { WSREP_ERROR("Bad SST address string. SST canceled."); return WSREP_CB_FAILURE; 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/sql/wsrep_trans_observer.h b/sql/wsrep_trans_observer.h index 54493f245de..a963a2b18ce 100644 --- a/sql/wsrep_trans_observer.h +++ b/sql/wsrep_trans_observer.h @@ -196,6 +196,11 @@ static inline bool wsrep_run_commit_hook(THD* thd, bool all) wsrep_is_active(thd), wsrep_is_real(thd, all), wsrep_has_changes(thd), wsrep_thd_is_applying(thd), wsrep_is_ordered(thd))); + + /* skipping non-wsrep threads */ + if (!WSREP(thd)) + DBUG_RETURN(false); + /* Is MST commit or autocommit? */ bool ret= wsrep_is_active(thd) && wsrep_is_real(thd, all); /* Do not commit if we are aborting */ diff --git a/sql/xa.cc b/sql/xa.cc index 49be7fb5347..51375cae537 100644 --- a/sql/xa.cc +++ b/sql/xa.cc @@ -78,7 +78,7 @@ public: /* Error reported by the Resource Manager (RM) to the Transaction Manager. */ uint rm_error; enum xa_states xa_state; - XID xid; + XA_data xid; bool is_set(int32_t flag) { return m_state.load(std::memory_order_relaxed) & flag; } void set(int32_t flag) @@ -140,6 +140,7 @@ public: { XID_cache_element *element= (XID_cache_element*) (ptr + LF_HASH_OVERHEAD); element->m_state= 0; + new(&element->xid) XA_data(); } static void lf_alloc_destructor(uchar *ptr) { @@ -179,6 +180,11 @@ void XID_STATE::set_error(uint error) xid_cache_element->rm_error= error; } +void XID_STATE::set_online_alter_cache(Online_alter_cache_list *cache) +{ + if (is_explicit_XA()) + xid_cache_element->xid.online_alter_cache= cache; +} void XID_STATE::er_xaer_rmfail() const { @@ -646,7 +652,7 @@ bool trans_xa_commit(THD *thd) DBUG_ASSERT(!xid_state.xid_cache_element); xid_state.xid_cache_element= xs; - ha_commit_or_rollback_by_xid(thd->lex->xid, !res); + ha_commit_or_rollback_by_xid(&xs->xid, !res); if (!res && thd->is_error()) { // hton completion error retains xs/xid in the cache, @@ -826,7 +832,7 @@ bool trans_xa_rollback(THD *thd) DBUG_ASSERT(!xid_state.xid_cache_element); xid_state.xid_cache_element= xs; - ha_commit_or_rollback_by_xid(thd->lex->xid, 0); + ha_commit_or_rollback_by_xid(&xs->xid, 0); if (!res && thd->is_error()) { goto _end_external_xid; diff --git a/sql/xa.h b/sql/xa.h index a9b06e427c6..7c23b8c735e 100644 --- a/sql/xa.h +++ b/sql/xa.h @@ -34,6 +34,7 @@ struct XID_STATE { bool check_has_uncommitted_xa() const; bool is_explicit_XA() const { return xid_cache_element != 0; } void set_error(uint error); + void set_online_alter_cache(Online_alter_cache_list *); void er_xaer_rmfail() const; XID *get_xid() const; enum xa_states get_state_code() const; diff --git a/storage/archive/azio.c b/storage/archive/azio.c index 9cb9f4693ec..01911b4bfa4 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -197,7 +197,7 @@ int write_header(azio_stream *s) /* Write a very simple .az header: */ memset(buffer, 0, AZHEADER_SIZE + AZMETA_BUFFER_SIZE); - *(ptr + AZ_MAGIC_POS)= az_magic[0]; + *(ptr + AZ_MAGIC_POS)= (char) az_magic[0]; *(ptr + AZ_VERSION_POS)= (unsigned char)s->version; *(ptr + AZ_MINOR_VERSION_POS)= (unsigned char)s->minor_version; *(ptr + AZ_BLOCK_POS)= (unsigned char)(s->block_size/1024); /* Reserved for block size */ diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore index 74647cd90ca..15fc0328c60 160000 --- a/storage/columnstore/columnstore +++ b/storage/columnstore/columnstore @@ -1 +1 @@ -Subproject commit 74647cd90ca6af9af8028664a4f731dad6be007a +Subproject commit 15fc0328c603e4d61f89df6851357804c20af21e diff --git a/storage/federatedx/federatedx_pushdown.cc b/storage/federatedx/federatedx_pushdown.cc index 7615e61ae09..c4d77a73984 100644 --- a/storage/federatedx/federatedx_pushdown.cc +++ b/storage/federatedx/federatedx_pushdown.cc @@ -276,18 +276,6 @@ federatedx_handler_base::federatedx_handler_base(THD *thd_arg, TABLE *tbl_arg) query_table(tbl_arg) {} -ha_federatedx_select_handler::ha_federatedx_select_handler( - THD *thd, SELECT_LEX *select_lex, TABLE *tbl) - : select_handler(thd, federatedx_hton, select_lex), - federatedx_handler_base(thd, tbl) -{ - query.length(0); - select_lex->print(thd, &query, - enum_query_type(QT_VIEW_INTERNAL | - QT_ITEM_ORIGINAL_FUNC_NULLIF | - QT_PARSABLE)); -} - ha_federatedx_select_handler::~ha_federatedx_select_handler() = default; ha_federatedx_select_handler::ha_federatedx_select_handler( @@ -296,10 +284,7 @@ ha_federatedx_select_handler::ha_federatedx_select_handler( federatedx_handler_base(thd, tbl) { query.length(0); - lex_unit->print(&query, - enum_query_type(QT_VIEW_INTERNAL | QT_SELECT_ONLY | - QT_ITEM_ORIGINAL_FUNC_NULLIF | - QT_PARSABLE)); + lex_unit->print(&query, PRINT_QUERY_TYPE); } ha_federatedx_select_handler::ha_federatedx_select_handler( @@ -308,10 +293,31 @@ ha_federatedx_select_handler::ha_federatedx_select_handler( federatedx_handler_base(thd, tbl) { query.length(0); - select_lex->print(thd, &query, - enum_query_type(QT_VIEW_INTERNAL | QT_SELECT_ONLY | - QT_ITEM_ORIGINAL_FUNC_NULLIF | - QT_PARSABLE)); + if (get_pushdown_type() == select_pushdown_type::SINGLE_SELECT) + { + /* + Must use SELECT_LEX_UNIT::print() instead of SELECT_LEX::print() here + to print possible CTEs which are stored at SELECT_LEX_UNIT::with_clause + */ + select_lex->master_unit()->print(&query, PRINT_QUERY_TYPE); + } + else if (get_pushdown_type() == select_pushdown_type::PART_OF_UNIT) + { + /* + CTEs are not supported for partial select pushdown so use + SELECT_LEX::print() here + */ + select_lex->print(thd, &query, PRINT_QUERY_TYPE); + } + else + { + /* + Other select_pushdown_types are not allowed in this constructor. + The case of select_pushdown_type::WHOLE_UNIT is handled at another + overload of the constuctor + */ + DBUG_ASSERT(0); + } } int federatedx_handler_base::init_scan_() diff --git a/storage/federatedx/federatedx_pushdown.h b/storage/federatedx/federatedx_pushdown.h index c2ce80b0708..1d5bdab1378 100644 --- a/storage/federatedx/federatedx_pushdown.h +++ b/storage/federatedx/federatedx_pushdown.h @@ -62,8 +62,6 @@ public: class ha_federatedx_select_handler: public select_handler, public federatedx_handler_base { public: - ha_federatedx_select_handler(THD *thd_arg, SELECT_LEX *sel_lex, - TABLE *tbl); ha_federatedx_select_handler(THD *thd_arg, SELECT_LEX_UNIT *sel_unit, TABLE *tbl); ha_federatedx_select_handler(THD *thd_arg, SELECT_LEX *sel_lex, @@ -72,4 +70,9 @@ public: int init_scan() { return federatedx_handler_base::init_scan_(); } int next_row() { return federatedx_handler_base::next_row_(table); } int end_scan(); + +private: + static constexpr auto PRINT_QUERY_TYPE= + enum_query_type(QT_VIEW_INTERNAL | QT_SELECT_ONLY | + QT_ITEM_ORIGINAL_FUNC_NULLIF | QT_PARSABLE); }; diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index ee9f128e6c9..7ae0454aa0c 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -496,12 +496,6 @@ IF(MSVC) TARGET_COMPILE_OPTIONS(innobase PRIVATE "/wd4065") ENDIF() -MY_CHECK_CXX_COMPILER_FLAG(-Wno-unused-but-set-variable) -IF(have_CXX__Wno_unused_but_set_variable) - ADD_COMPILE_FLAGS(pars/pars0grm.cc fts/fts0pars.cc - COMPILE_FLAGS "-Wno-unused-but-set-variable") -ENDIF() - IF(NOT (PLUGIN_INNOBASE STREQUAL DYNAMIC)) TARGET_LINK_LIBRARIES(innobase tpool mysys) ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/extra/mariabackup ${CMAKE_BINARY_DIR}/extra/mariabackup) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 44b3ffd8da7..ef57989bf2e 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -212,10 +212,11 @@ ATTRIBUTE_COLD void btr_decryption_failed(const dict_index_t &index) @param[in] mode latch mode @param[in,out] mtr mini-transaction @param[out] err error code +@param[out] first set if this is a first-time access to the page @return block */ buf_block_t *btr_block_get(const dict_index_t &index, uint32_t page, rw_lock_type_t mode, - mtr_t *mtr, dberr_t *err) + mtr_t *mtr, dberr_t *err, bool *first) { ut_ad(mode != RW_NO_LATCH); dberr_t local_err; @@ -238,6 +239,8 @@ buf_block_t *btr_block_get(const dict_index_t &index, *err= DB_PAGE_CORRUPTED; block= nullptr; } + else if (!buf_page_make_young_if_needed(&block->page) && first) + *first= true; } else if (*err == DB_DECRYPTION_FAILED) btr_decryption_failed(index); @@ -297,6 +300,8 @@ btr_root_block_get( *err= DB_CORRUPTION; block= nullptr; } + else + buf_page_make_young_if_needed(&block->page); } else if (*err == DB_DECRYPTION_FAILED) btr_decryption_failed(*index); @@ -787,7 +792,8 @@ static rec_offs *btr_page_get_parent(rec_offs *offsets, mem_heap_t *heap, /************************************************************//** Returns the upper level node pointer to a page. It is assumed that mtr holds an x-latch on the tree. -@return rec_get_offsets() of the node pointer record */ +@return rec_get_offsets() of the node pointer record +@retval nullptr on corruption */ static rec_offs* btr_page_get_father_block( @@ -1112,9 +1118,9 @@ void btr_drop_temporary_table(const dict_table_t &table) for (const dict_index_t *index= table.indexes.start; index; index= dict_table_get_next_index(index)) { - if (buf_block_t *block= buf_page_get_low({SRV_TMP_SPACE_ID, index->page}, 0, - RW_X_LATCH, nullptr, BUF_GET, &mtr, - nullptr)) + if (buf_block_t *block= buf_page_get_gen({SRV_TMP_SPACE_ID, index->page}, + 0, RW_X_LATCH, nullptr, BUF_GET, + &mtr, nullptr)) { btr_free_but_not_root(block, MTR_LOG_NO_REDO); mtr.set_log_mode(MTR_LOG_NO_REDO); @@ -1220,6 +1226,7 @@ btr_write_autoinc(dict_index_t* index, ib_uint64_t autoinc, bool reset) if (buf_block_t *root= buf_page_get(page_id_t(space->id, index->page), space->zip_size(), RW_SX_LATCH, &mtr)) { + buf_page_make_young_if_needed(&root->page); mtr.set_named_space(space); page_set_autoinc(root, autoinc, &mtr, reset); } @@ -2373,6 +2380,11 @@ btr_attach_half_pages( offsets = btr_page_get_father_block(nullptr, heap, mtr, &cursor); + if (UNIV_UNLIKELY(!offsets)) { + mem_heap_free(heap); + return DB_CORRUPTION; + } + /* Replace the address of the old child node (= page) with the address of the new lower half */ @@ -3240,6 +3252,14 @@ btr_lift_page_up( offsets = btr_page_get_father_block(offsets, heap, mtr, &cursor); } + + if (UNIV_UNLIKELY(!offsets)) { +parent_corrupted: + mem_heap_free(heap); + *err = DB_CORRUPTION; + return nullptr; + } + father_block = btr_cur_get_block(&cursor); father_page_zip = buf_block_get_page_zip(father_block); @@ -3265,6 +3285,10 @@ btr_lift_page_up( &cursor); } + if (UNIV_UNLIKELY(!offsets)) { + goto parent_corrupted; + } + blocks[n_blocks++] = b = btr_cur_get_block(&cursor); } @@ -3477,6 +3501,10 @@ get_offsets: NULL, heap, mtr, &father_cursor); } + if (UNIV_UNLIKELY(!offsets)) { + goto corrupted; + } + if (adjust) { nth_rec = page_rec_get_n_recs_before(btr_cur_get_rec(cursor)); if (UNIV_UNLIKELY(!nth_rec || nth_rec == ULINT_UNDEFINED)) { diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc index 3c5b4b293f2..868d97ca74b 100644 --- a/storage/innobase/btr/btr0bulk.cc +++ b/storage/innobase/btr/btr0bulk.cc @@ -965,10 +965,10 @@ BtrBulk::pageCommit( /** Log free check */ inline void BtrBulk::logFreeCheck() { - if (log_sys.check_flush_or_checkpoint()) { + if (log_sys.check_for_checkpoint()) { release(); - log_check_margins(); + log_free_check(); latch(); } diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index b483e8657b0..fb0efe08130 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -1113,6 +1113,19 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, mtr_s_lock_index(index(), mtr); } + dberr_t err; + + if (!index()->table->space) + { + corrupted: + ut_ad("corrupted" == 0); // FIXME: remove this + err= DB_CORRUPTION; + func_exit: + if (UNIV_LIKELY_NULL(heap)) + mem_heap_free(heap); + return err; + } + const ulint zip_size= index()->table->space->zip_size(); /* Start with the root page. */ @@ -1125,7 +1138,6 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, low_match= 0; low_bytes= 0; search_loop: - dberr_t err; auto block_savepoint= mtr->get_savepoint(); buf_block_t *block= buf_page_get_gen(page_id, zip_size, rw_latch, guess, BUF_GET, mtr, &err); @@ -1133,26 +1145,18 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, { if (err == DB_DECRYPTION_FAILED) btr_decryption_failed(*index()); - func_exit: - if (UNIV_LIKELY_NULL(heap)) - mem_heap_free(heap); - return err; + goto func_exit; } if (!!page_is_comp(block->page.frame) != index()->table->not_redundant() || btr_page_get_index_id(block->page.frame) != index()->id || fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE || !fil_page_index_page_check(block->page.frame)) - { - corrupted: - ut_ad("corrupted" == 0); // FIXME: remove this - err= DB_CORRUPTION; - goto func_exit; - } + goto corrupted; page_cur.block= block; ut_ad(block == mtr->at_savepoint(block_savepoint)); - ut_ad(rw_latch != RW_NO_LATCH); + const bool not_first_access{buf_page_make_young_if_needed(&block->page)}; #ifdef UNIV_ZIP_DEBUG if (const page_zip_des_t *page_zip= buf_block_get_page_zip(block)) ut_a(page_zip_validate(page_zip, block->page.frame, index())); @@ -1432,6 +1436,9 @@ release_tree: case BTR_SEARCH_PREV: /* btr_pcur_move_to_prev() */ ut_ad(rw_latch == RW_S_LATCH || rw_latch == RW_X_LATCH); + if (!not_first_access) + buf_read_ahead_linear(page_id, zip_size); + if (page_has_prev(block->page.frame) && page_rec_is_first(page_cur.rec, block->page.frame)) { @@ -1464,6 +1471,8 @@ release_tree: case BTR_MODIFY_LEAF: case BTR_SEARCH_LEAF: rw_latch= rw_lock_type_t(latch_mode); + if (!not_first_access) + buf_read_ahead_linear(page_id, zip_size); break; case BTR_MODIFY_TREE: ut_ad(rw_latch == RW_X_LATCH); @@ -1497,6 +1506,14 @@ ATTRIBUTE_COLD void mtr_t::index_lock_upgrade() slot.type= MTR_MEMO_X_LOCK; } +/** Mark a non-leaf page "least recently used", but avoid invoking +buf_page_t::set_accessed(), because we do not want linear read-ahead */ +static void btr_cur_nonleaf_make_young(buf_page_t *bpage) +{ + if (UNIV_UNLIKELY(buf_page_peek_if_too_old(bpage))) + buf_page_make_young(bpage); +} + ATTRIBUTE_COLD dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, mtr_t *mtr) @@ -1598,6 +1615,8 @@ dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple, if (--height != btr_page_get_level(block->page.frame)) goto corrupted; + btr_cur_nonleaf_make_young(&block->page); + #ifdef UNIV_ZIP_DEBUG const page_zip_des_t *page_zip= buf_block_get_page_zip(block); ut_a(!page_zip || page_zip_validate(page_zip, block->page.frame, index())); @@ -1666,6 +1685,18 @@ dberr_t btr_cur_search_to_nth_level(ulint level, ut_ad(mtr->memo_contains_flagged(&index->lock, MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); + dberr_t err; + + if (!index->table->space) + { + corrupted: + err= DB_CORRUPTION; + func_exit: + if (UNIV_LIKELY_NULL(heap)) + mem_heap_free(heap); + return err; + } + const ulint zip_size= index->table->space->zip_size(); /* Start with the root page. */ @@ -1673,7 +1704,7 @@ dberr_t btr_cur_search_to_nth_level(ulint level, ulint height= ULINT_UNDEFINED; search_loop: - dberr_t err= DB_SUCCESS; + err= DB_SUCCESS; if (buf_block_t *b= mtr->get_already_latched(page_id, mtr_memo_type_t(rw_latch))) block= b; @@ -1684,6 +1715,8 @@ search_loop: btr_decryption_failed(*index); goto func_exit; } + else + btr_cur_nonleaf_make_young(&block->page); #ifdef UNIV_ZIP_DEBUG if (const page_zip_des_t *page_zip= buf_block_get_page_zip(block)) @@ -1694,14 +1727,7 @@ search_loop: btr_page_get_index_id(block->page.frame) != index->id || fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE || !fil_page_index_page_check(block->page.frame)) - { - corrupted: - err= DB_CORRUPTION; - func_exit: - if (UNIV_LIKELY_NULL(heap)) - mem_heap_free(heap); - return err; - } + goto corrupted; const uint32_t page_level= btr_page_get_level(block->page.frame); @@ -1819,17 +1845,15 @@ index_locked: ut_ad(n_blocks < BTR_MAX_LEVELS); ut_ad(savepoint + n_blocks == mtr->get_savepoint()); + bool first_access= false; buf_block_t* block= btr_block_get(*index, page, - height ? upper_rw_latch : root_leaf_rw_latch, mtr, &err); + height ? upper_rw_latch : root_leaf_rw_latch, + mtr, &err, &first_access); ut_ad(!block == (err != DB_SUCCESS)); if (!block) - { - if (err == DB_DECRYPTION_FAILED) - btr_decryption_failed(*index); break; - } if (first) page_cur_set_before_first(block, &page_cur); @@ -1913,10 +1937,16 @@ index_locked: offsets= rec_get_offsets(page_cur.rec, index, offsets, 0, ULINT_UNDEFINED, &heap); + page= btr_node_ptr_get_child_page_no(page_cur.rec, offsets); ut_ad(latch_mode != BTR_MODIFY_TREE || upper_rw_latch == RW_X_LATCH); - if (latch_mode != BTR_MODIFY_TREE); + if (latch_mode != BTR_MODIFY_TREE) + { + if (!height && first && first_access) + buf_read_ahead_linear(page_id_t(block->page.id().space(), page), + block->page.zip_size()); + } else if (btr_cur_need_opposite_intention(block->page, index->is_clust(), lock_intention, node_ptr_max_size, compress_limit, @@ -1954,7 +1984,6 @@ index_locked: } /* Go to the child node */ - page= btr_node_ptr_get_child_page_no(page_cur.rec, offsets); n_blocks++; } @@ -3603,22 +3632,14 @@ btr_cur_pess_upd_restore_supremum( const page_id_t block_id{block->page.id()}; const page_id_t prev_id(block_id.space(), prev_page_no); - dberr_t err; buf_block_t* prev_block - = buf_page_get_gen(prev_id, 0, RW_NO_LATCH, nullptr, - BUF_PEEK_IF_IN_POOL, mtr, &err); - /* Since we already held an x-latch on prev_block, it must - be available and not be corrupted unless the buffer pool got - corrupted somehow. */ + = mtr->get_already_latched(prev_id, MTR_MEMO_PAGE_X_FIX); if (UNIV_UNLIKELY(!prev_block)) { - return err; + return DB_CORRUPTION; } ut_ad(!memcmp_aligned<4>(prev_block->page.frame + FIL_PAGE_NEXT, block->page.frame + FIL_PAGE_OFFSET, 4)); - /* We must already have an x-latch on prev_block! */ - ut_ad(mtr->memo_contains_flagged(prev_block, MTR_MEMO_PAGE_X_FIX)); - lock_rec_reset_and_inherit_gap_locks(*prev_block, block_id, PAGE_HEAP_NO_SUPREMUM, page_rec_get_heap_no(rec)); @@ -6353,6 +6374,10 @@ btr_copy_blob_prefix( mtr.commit(); return copied_len; } + if (!buf_page_make_young_if_needed(&block->page)) { + buf_read_ahead_linear(id, 0); + } + page = buf_block_get_frame(block); blob_header = page + offset; diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc index f2af79af65e..0bf279ab371 100644 --- a/storage/innobase/btr/btr0pcur.cc +++ b/storage/innobase/btr/btr0pcur.cc @@ -25,9 +25,10 @@ Created 2/23/1996 Heikki Tuuri *******************************************************/ #include "btr0pcur.h" -#include "ut0byte.h" +#include "buf0rea.h" #include "rem0cmp.h" #include "trx0trx.h" +#include "ibuf0ibuf.h" /**************************************************************//** Resets a persistent cursor object, freeing ::old_rec_buf if it is @@ -255,13 +256,15 @@ static bool btr_pcur_optimistic_latch_leaves(buf_block_t *block, buf_page_get_gen(page_id_t(id.space(), left_page_no), zip_size, mode, nullptr, BUF_GET_POSSIBLY_FREED, mtr); - if (left_block && - btr_page_get_next(left_block->page.frame) != id.page_no()) + if (!left_block); + else if (btr_page_get_next(left_block->page.frame) != id.page_no()) { release_left_block: mtr->release_last_page(); return false; } + else + buf_page_make_young_if_needed(&left_block->page); } if (buf_page_optimistic_get(mode, block, pcur->modify_clock, mtr)) @@ -533,10 +536,11 @@ btr_pcur_move_to_next_page( } dberr_t err; + bool first_access = false; buf_block_t* next_block = btr_block_get( *cursor->index(), next_page_no, rw_lock_type_t(cursor->latch_mode & (RW_X_LATCH | RW_S_LATCH)), - mtr, &err); + mtr, &err, &first_access); if (UNIV_UNLIKELY(!next_block)) { return err; @@ -555,6 +559,10 @@ btr_pcur_move_to_next_page( const auto s = mtr->get_savepoint(); mtr->rollback_to_savepoint(s - 2, s - 1); + if (first_access) { + buf_read_ahead_linear(next_block->page.id(), + next_block->zip_size()); + } return DB_SUCCESS; } diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index a510766db5c..c32d32abbda 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -1135,7 +1135,6 @@ block_and_ahi_release_and_fail: } block->page.fix(); - block->page.set_accessed(); buf_page_make_young_if_needed(&block->page); static_assert(ulint{MTR_MEMO_PAGE_S_FIX} == ulint{BTR_SEARCH_LEAF}, ""); diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 0cb2a397902..dfa995dc16e 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -403,7 +403,7 @@ static bool buf_page_decrypt_after_read(buf_page_t *bpage, if (id.space() == SRV_TMP_SPACE_ID && innodb_encrypt_temporary_tables) { - slot = buf_pool.io_buf_reserve(); + slot = buf_pool.io_buf_reserve(false); slot->allocate(); bool ok = buf_tmp_page_decrypt(slot->crypt_buf, dst_frame); slot->release(); @@ -425,7 +425,7 @@ decompress: return false; } - slot = buf_pool.io_buf_reserve(); + slot = buf_pool.io_buf_reserve(false); slot->allocate(); decompress_with_slot: @@ -448,7 +448,7 @@ decrypt_failed: return false; } - slot = buf_pool.io_buf_reserve(); + slot = buf_pool.io_buf_reserve(false); slot->allocate(); /* decrypt using crypt_buf to dst_frame */ @@ -742,6 +742,206 @@ bool buf_page_is_corrupted(bool check_lsn, const byte *read_buf, #ifndef UNIV_INNOCHECKSUM +#ifdef __linux__ +#include +#include +#include + +/** Memory Pressure + +based off https://www.kernel.org/doc/html/latest/accounting/psi.html#pressure-interface +and https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html#memory */ +class mem_pressure +{ + /* triggers + eventfd */ + struct pollfd m_fds[3]; + nfds_t m_num_fds; + int m_event_fd= -1; + Atomic_relaxed m_abort= false; + + std::thread m_thd; + /* mem pressure garbage collection restricted to interval */ + static constexpr ulonglong max_interval_us= 60*1000000; + +public: + mem_pressure() : m_num_fds(0) {} + + bool setup() + { + static_assert(array_elements(m_fds) == (array_elements(m_triggers) + 1), + "insufficient fds"); + std::string memcgroup{"/sys/fs/cgroup"}; + std::string cgroup; + { + std::ifstream selfcgroup("/proc/self/cgroup"); + std::getline(selfcgroup, cgroup, '\n'); + } + + cgroup.erase(0, 3); // Remove "0::" + memcgroup+= cgroup + "/memory.pressure"; + + m_num_fds= 0; + for (auto trig= std::begin(m_triggers); trig!= std::end(m_triggers); ++trig) + { + if ((m_fds[m_num_fds].fd= + open(memcgroup.c_str(), O_RDWR | O_NONBLOCK | O_CLOEXEC)) < 0) + { + /* User can't do anything about it, no point giving warning */ + shutdown(); + return false; + } + my_register_filename(m_fds[m_num_fds].fd, memcgroup.c_str(), FILE_BY_OPEN, 0, MYF(0)); + ssize_t slen= strlen(*trig); + if (write(m_fds[m_num_fds].fd, *trig, slen) < slen) + { + /* we may fail this one, but continue to the next */ + my_close(m_fds[m_num_fds].fd, MYF(MY_WME)); + continue; + } + m_fds[m_num_fds].events= POLLPRI; + m_num_fds++; + } + if (m_num_fds < 1) + return false; + + if ((m_event_fd= eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK)) == -1) + { + /* User can't do anything about it, no point giving warning */ + shutdown(); + return false; + } + my_register_filename(m_event_fd, "mem_pressure_eventfd", FILE_BY_DUP, 0, MYF(0)); + m_fds[m_num_fds].fd= m_event_fd; + m_fds[m_num_fds].events= POLLIN; + m_num_fds++; + m_thd= std::thread(pressure_routine, this); + sql_print_information("InnoDB: Initialized memory pressure event listener"); + return true; + } + + void shutdown() + { + /* m_event_fd is in this list */ + while (m_num_fds) + { + m_num_fds--; + my_close(m_fds[m_num_fds].fd, MYF(MY_WME)); + m_fds[m_num_fds].fd= -1; + } + } + + static void pressure_routine(mem_pressure *m); + +#ifdef UNIV_DEBUG + void trigger_collection() + { + uint64_t u= 1; + if (m_event_fd >=0 && write(m_event_fd, &u, sizeof(uint64_t)) != sizeof(uint64_t)) + sql_print_information("InnoDB: (Debug) Failed to trigger memory pressure"); + else /* assumed failed to meet intialization criteria, so trigger directy */ + buf_pool.garbage_collect(); + } +#endif + + void quit() + { + uint64_t u= 1; + m_abort= true; + if (write(m_event_fd, &u, sizeof(uint64_t)) != sizeof(uint64_t)) + sql_print_warning("InnoDB: Failed to write memory pressure quit message"); + } + + void join() + { + if (m_thd.joinable()) + { + quit(); + m_thd.join(); + } + } + + static const char* const m_triggers[2]; +}; + + +/* + ref: https://docs.kernel.org/accounting/psi.html + maximum window size (second number) 10 seconds. + window size in multiples of 2 second interval required (for Unprivileged) + Time is in usec. +*/ +const char* const mem_pressure::m_triggers[]= + {"some 5000000 10000000", /* 5s out of 10s */ + "full 10000 2000000"}; /* 10ms out of 2s */ + +static mem_pressure mem_pressure_obj; + +void mem_pressure::pressure_routine(mem_pressure *m) +{ + DBUG_ASSERT(m == &mem_pressure_obj); + if (my_thread_init()) + { + m->shutdown(); + return; + } + + ulonglong last= microsecond_interval_timer() - max_interval_us; + while (!m->m_abort) + { + if (poll(&m->m_fds[0], m->m_num_fds, -1) < 0) + { + if (errno == EINTR) + continue; + else + { + sql_print_warning("InnoDB: memory pressure poll error %s", + strerror(errno)); + break; + } + } + if (!m->m_abort) + break; + + for (pollfd &p : st_::span(m->m_fds, m->m_num_fds)) + { + if (p.revents & POLLPRI) + { + ulonglong now= microsecond_interval_timer(); + if ((now - last) > max_interval_us) + { + last= now; + buf_pool.garbage_collect(); + } + } + +#ifdef UNIV_DEBUG + if (p.revents & POLLIN) + { + uint64_t u; + /* we haven't aborted, so this must be a debug trigger */ + if (read(p.fd, &u, sizeof(u)) >=0) + buf_pool.garbage_collect(); + } +#endif + } + } + m->shutdown(); + + my_thread_end(); +} + +/** Initialize mem pressure. */ +ATTRIBUTE_COLD void buf_mem_pressure_detect_init() +{ + mem_pressure_obj.setup(); +} + +ATTRIBUTE_COLD void buf_mem_pressure_shutdown() +{ + mem_pressure_obj.join(); +} +#endif /* __linux__ */ + #if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DODUMP) /** Enable buffers to be dumped to core files @@ -1099,6 +1299,11 @@ bool buf_pool_t::create() chunk_t::map_ref= chunk_t::map_reg; buf_LRU_old_ratio_update(100 * 3 / 8, false); btr_search_sys_create(); + +#ifdef __linux__ + if (srv_operation == SRV_OPERATION_NORMAL) + buf_mem_pressure_detect_init(); +#endif ut_ad(is_initialised()); return false; } @@ -1300,14 +1505,17 @@ void buf_pool_t::io_buf_t::close() n_slots= 0; } -buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve() +buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve(bool wait_for_reads) { for (;;) { for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++) if (s->acquire()) return s; + buf_dblwr.flush_buffered_writes(); os_aio_wait_until_no_pending_writes(true); + if (!wait_for_reads) + continue; for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++) if (s->acquire()) return s; @@ -1536,6 +1744,7 @@ struct find_interesting_trx inline void buf_pool_t::resize() { ut_ad(this == &buf_pool); + ut_ad(srv_shutdown_state < SRV_SHUTDOWN_CLEANUP); bool warning = false; @@ -1875,6 +2084,100 @@ calc_buf_pool_size: return; } +#ifdef __linux__ +inline void buf_pool_t::garbage_collect() +{ + mysql_mutex_lock(&mutex); + size_t freed= 0; + +#ifdef BTR_CUR_HASH_ADAPT + /* buf_LRU_free_page() will temporarily release and reacquire + buf_pool.mutex for invoking btr_search_drop_page_hash_index(). Thus, + we must protect ourselves with the hazard pointer. */ +rescan: +#else + lru_hp.set(nullptr); +#endif + for (buf_page_t *bpage= UT_LIST_GET_LAST(LRU), *prev; bpage; bpage= prev) + { + prev= UT_LIST_GET_PREV(LRU, bpage); +#ifdef BTR_CUR_HASH_ADAPT + lru_hp.set(prev); +#endif + auto state= bpage->state(); + ut_ad(state >= buf_page_t::FREED); + ut_ad(bpage->in_LRU_list); + + /* We try to free any pages that can be freed without writing out + anything. */ + switch (bpage->oldest_modification()) { + case 0: + try_to_evict: + if (buf_LRU_free_page(bpage, true)) + { + evicted: + freed++; +#ifdef BTR_CUR_HASH_ADAPT + bpage= prev; + prev= lru_hp.get(); + if (!prev && bpage) + goto rescan; +#endif + } + continue; + case 1: + break; + default: + if (state >= buf_page_t::UNFIXED) + continue; + } + + if (state < buf_page_t::READ_FIX && bpage->lock.u_lock_try(true)) + { + ut_ad(!bpage->is_io_fixed()); + lsn_t oldest_modification= bpage->oldest_modification(); + switch (oldest_modification) { + case 1: + mysql_mutex_lock(&flush_list_mutex); + oldest_modification= bpage->oldest_modification(); + if (oldest_modification) + { + ut_ad(oldest_modification == 1); + delete_from_flush_list(bpage); + } + mysql_mutex_unlock(&flush_list_mutex); + /* fall through */ + case 0: + bpage->lock.u_unlock(true); + goto try_to_evict; + default: + if (bpage->state() < buf_page_t::UNFIXED && + oldest_modification <= log_sys.get_flushed_lsn()) + { + release_freed_page(bpage); + goto evicted; + } + else + bpage->lock.u_unlock(true); + } + } + } + +#if defined MADV_FREE + /* FIXME: Issue fewer calls for larger contiguous blocks of + memory. For now, we assume that this is acceptable, because this + code should be executed rarely. */ + for (buf_page_t *bpage= UT_LIST_GET_FIRST(free); bpage; + bpage= UT_LIST_GET_NEXT(list, bpage)) + madvise(bpage->frame, srv_page_size, MADV_FREE); +#endif + mysql_mutex_unlock(&mutex); + sql_print_information("InnoDB: Memory pressure event freed %zu pages", + freed); + return; +} +#endif /* __linux__ */ + /** Thread pool task invoked by innodb_buffer_pool_size changes. */ static void buf_resize_callback(void *) { @@ -1903,12 +2206,23 @@ static tpool::waitable_task buf_resize_task(buf_resize_callback, void buf_resize_start() { - srv_thread_pool->submit_task(&buf_resize_task); +#if !defined(DBUG_OFF) && defined(__linux__) + DBUG_EXECUTE_IF("trigger_garbage_collection", + { + mem_pressure_obj.trigger_collection(); + } + ); +#endif + + srv_thread_pool->submit_task(&buf_resize_task); } void buf_resize_shutdown() { - buf_resize_task.wait(); +#ifdef __linux__ + buf_mem_pressure_shutdown(); +#endif + buf_resize_task.wait(); } @@ -2093,14 +2407,21 @@ lookup: if (discard_attempted || !bpage->frame) { - /* Even when we are holding a hash_lock, it should be - acceptable to wait for a page S-latch here, because - buf_page_t::read_complete() will not wait for buf_pool.mutex, - and because S-latch would not conflict with a U-latch - that would be protecting buf_page_t::write_complete(). */ - bpage->lock.s_lock(); + const bool got_s_latch= bpage->lock.s_lock_try(); hash_lock.unlock_shared(); - break; + if (UNIV_LIKELY(got_s_latch)) + break; + /* We may fail to acquire bpage->lock because + buf_page_t::read_complete() may be invoking + buf_pool_t::corrupted_evict() on this block, which it would + hold an exclusive latch on. + + Let us aqcuire and release buf_pool.mutex to ensure that any + buf_pool_t::corrupted_evict() will proceed before we reacquire + the hash_lock that it could be waiting for. */ + mysql_mutex_lock(&buf_pool.mutex); + mysql_mutex_unlock(&buf_pool.mutex); + goto lookup; } hash_lock.unlock_shared(); @@ -2119,7 +2440,6 @@ lookup: ut_ad(s < buf_page_t::READ_FIX || s >= buf_page_t::WRITE_FIX); } - bpage->set_accessed(); buf_page_make_young_if_needed(bpage); #ifdef UNIV_DEBUG @@ -2257,7 +2577,7 @@ or BUF_PEEK_IF_IN_POOL @return pointer to the block or NULL */ TRANSACTIONAL_TARGET buf_block_t* -buf_page_get_low( +buf_page_get_gen( const page_id_t page_id, ulint zip_size, ulint rw_latch, @@ -2450,7 +2770,7 @@ free_unfixed_block: wait_for_unzip: /* The page is being read or written, or another thread is executing buf_zip_decompress() - in buf_page_get_low() on it. */ + in buf_page_get_gen() on it. */ block->page.unfix(); std::this_thread::sleep_for( std::chrono::microseconds(100)); @@ -2473,10 +2793,7 @@ wait_for_unfix: ut_ad(&block->page == buf_pool.page_hash.get(page_id, chain)); /* Wait for any other threads to release their buffer-fix - on the compressed-only block descriptor. - FIXME: Never fix() before acquiring the lock. - Only in buf_page_get_gen(), buf_page_get_low(), buf_page_free() - we are violating that principle. */ + on the compressed-only block descriptor. */ state = block->page.state(); switch (state) { @@ -2502,7 +2819,7 @@ wait_for_unfix: goto wait_for_unfix; } - /* Ensure that another buf_page_get_low() will wait for + /* Ensure that another buf_page_get_gen() will wait for new_block->page.lock.x_unlock(). */ block->page.set_state(buf_page_t::READ_FIX); @@ -2613,72 +2930,9 @@ page_id_mismatch: ut_ad(page_id_t(page_get_space_id(block->page.frame), page_get_page_no(block->page.frame)) == page_id); - if (mode == BUF_GET_POSSIBLY_FREED || mode == BUF_PEEK_IF_IN_POOL) { - return block; - } - - const bool not_first_access{block->page.set_accessed()}; - buf_page_make_young_if_needed(&block->page); - if (!not_first_access) { - buf_read_ahead_linear(page_id, block->zip_size()); - } - return block; } -/** Get access to a database page. Buffered redo log may be applied. -@param[in] page_id page id -@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 -@param[in] rw_latch RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH -@param[in] guess guessed block or NULL -@param[in] mode BUF_GET, BUF_GET_IF_IN_POOL, -or BUF_PEEK_IF_IN_POOL -@param[in,out] mtr mini-transaction, or NULL -@param[out] err DB_SUCCESS or error code -@return pointer to the block or NULL */ -buf_block_t* -buf_page_get_gen( - const page_id_t page_id, - ulint zip_size, - ulint rw_latch, - buf_block_t* guess, - ulint mode, - mtr_t* mtr, - dberr_t* err) -{ - buf_block_t *block= recv_sys.recover(page_id); - if (UNIV_LIKELY(!block)) - return buf_page_get_low(page_id, zip_size, rw_latch, - guess, mode, mtr, err); - else if (UNIV_UNLIKELY(block == reinterpret_cast(-1))) - { - corrupted: - if (err) - *err= DB_CORRUPTION; - return nullptr; - } - if (err) - *err= DB_SUCCESS; - /* Recovery is a special case; we fix() before acquiring lock. */ - auto s= block->page.fix(); - ut_ad(s >= buf_page_t::FREED); - /* The block may be write-fixed at this point because we are not - holding a lock, but it must not be read-fixed. */ - ut_ad(s < buf_page_t::READ_FIX || s >= buf_page_t::WRITE_FIX); - if (s < buf_page_t::UNFIXED) - { - ut_ad(mode == BUF_GET_POSSIBLY_FREED || mode == BUF_PEEK_IF_IN_POOL); - mysql_mutex_lock(&buf_pool.mutex); - block->page.unfix(); - buf_LRU_free_page(&block->page, true); - mysql_mutex_unlock(&buf_pool.mutex); - goto corrupted; - } - - mtr->page_lock(block, rw_latch); - return block; -} - /********************************************************************//** This is the general function used to get optimistic access to a database page. @@ -2753,7 +3007,6 @@ bool buf_page_optimistic_get(ulint rw_latch, buf_block_t *block, block->page.fix(); ut_ad(!block->page.is_read_fixed()); - block->page.set_accessed(); buf_page_make_young_if_needed(&block->page); mtr->memo_push(block, mtr_memo_type_t(rw_latch)); } diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 6d84ff7a242..e9aea35533b 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -362,7 +362,7 @@ void buf_dblwr_t::recover() { byte *page= *i; const uint32_t page_no= page_get_page_no(page); - if (!page_no) /* recovered via Datafile::restore_from_doublewrite() */ + if (!page_no) /* recovered via recv_dblwr_t::restore_first_page() */ continue; const lsn_t lsn= mach_read_from_8(page + FIL_PAGE_LSN); @@ -528,7 +528,7 @@ static void buf_dblwr_check_page_lsn(const page_t* page, const fil_space_t& s) static void buf_dblwr_check_page_lsn(const buf_page_t &b, const byte *page) { - if (fil_space_t *space= fil_space_t::get(b.id().space())) + if (fil_space_t *space= fil_space_t::get_for_write(b.id().space())) { buf_dblwr_check_page_lsn(page, *space); space->release(); diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index 957632db940..80469caf86b 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -33,7 +33,7 @@ Created April 08, 2011 Vasil Dimov #include "buf0rea.h" #include "buf0dump.h" -#include "dict0dict.h" +#include "dict0load.h" #include "os0file.h" #include "srv0srv.h" #include "srv0start.h" @@ -562,6 +562,22 @@ buf_load() if (!SHUTTING_DOWN()) { std::sort(dump, dump + dump_n); + std::set missing; + for (const page_id_t id : st_::span + (dump, dump_n)) { + missing.emplace(id.space()); + } + for (std::set::iterator i = missing.begin(); + i != missing.end(); ) { + auto j = i++; + if (fil_space_t* space = fil_space_t::get(*j)) { + space->release(); + missing.erase(j); + } + } + if (!missing.empty()) { + dict_load_tablespaces(&missing); + } } /* Avoid calling the expensive fil_space_t::get() for each diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index ddfd7403cc7..e7f44b2e596 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -655,7 +655,7 @@ static byte *buf_page_encrypt(fil_space_t* space, buf_page_t* bpage, byte* s, ut_ad(!bpage->zip_size() || !page_compressed); /* Find free slot from temporary memory array */ - *slot= buf_pool.io_buf_reserve(); + *slot= buf_pool.io_buf_reserve(true); ut_a(*slot); (*slot)->allocate(); @@ -758,6 +758,19 @@ bool buf_page_t::flush(bool evict, fil_space_t *space) if (s < UNFIXED) { + if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE)) + { + const lsn_t lsn= + mach_read_from_8(my_assume_aligned<8> + (FIL_PAGE_LSN + (zip.data ? zip.data : frame))); + ut_ad(lsn >= oldest_modification()); + if (lsn > log_sys.get_flushed_lsn()) + { + mysql_mutex_unlock(&buf_pool.mutex); + log_write_up_to(lsn, true); + mysql_mutex_lock(&buf_pool.mutex); + } + } buf_pool.release_freed_page(this); return false; } @@ -1058,7 +1071,7 @@ static ulint buf_flush_try_neighbors(fil_space_t *space, for (ulint id_fold= id.fold(); id < high; ++id, ++id_fold) { - if (UNIV_UNLIKELY(space->is_stopping())) + if (UNIV_UNLIKELY(space->is_stopping_writes())) { if (bpage) bpage->lock.u_unlock(true); @@ -1162,12 +1175,31 @@ static ulint buf_free_from_unzip_LRU_list_batch() return(count); } +/** Acquire a tablespace reference for writing. +@param id tablespace identifier +@return tablespace +@retval nullptr if the tablespace is missing or inaccessible */ +fil_space_t *fil_space_t::get_for_write(uint32_t id) +{ + mysql_mutex_lock(&fil_system.mutex); + fil_space_t *space= fil_space_get_by_id(id); + const uint32_t n= space ? space->acquire_low(STOPPING_WRITES) : 0; + + if (n & STOPPING_WRITES) + space= nullptr; + else if ((n & CLOSING) && !space->prepare_acquired()) + space= nullptr; + + mysql_mutex_unlock(&fil_system.mutex); + return space; +} + /** Start writing out pages for a tablespace. @param id tablespace identifier @return tablespace and number of pages written */ static std::pair buf_flush_space(const uint32_t id) { - if (fil_space_t *space= fil_space_t::get(id)) + if (fil_space_t *space= fil_space_t::get_for_write(id)) return {space, space->flush_freed(true)}; return {nullptr, 0}; } @@ -1232,16 +1264,14 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict, ut_ad(state >= buf_page_t::FREED); ut_ad(bpage->in_LRU_list); - switch (bpage->oldest_modification()) { - case 0: + if (!bpage->oldest_modification()) + { evict: if (state != buf_page_t::FREED && (state >= buf_page_t::READ_FIX || (~buf_page_t::LRU_MASK & state))) continue; buf_LRU_free_page(bpage, true); ++n->evicted; - /* fall through */ - case 1: if (UNIV_LIKELY(scanned & 31)) continue; mysql_mutex_unlock(&buf_pool.mutex); @@ -1257,7 +1287,11 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict, switch (bpage->oldest_modification()) { case 1: mysql_mutex_lock(&buf_pool.flush_list_mutex); - buf_pool.delete_from_flush_list(bpage); + if (ut_d(lsn_t lsn=) bpage->oldest_modification()) + { + ut_ad(lsn == 1); /* It must be clean while we hold bpage->lock */ + buf_pool.delete_from_flush_list(bpage); + } mysql_mutex_unlock(&buf_pool.flush_list_mutex); /* fall through */ case 0: @@ -1296,7 +1330,7 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict, goto no_space; } } - else if (space->is_stopping()) + else if (space->is_stopping_writes()) { space->release(); space= nullptr; @@ -1448,7 +1482,7 @@ static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn) else ut_ad(!space); } - else if (space->is_stopping()) + else if (space->is_stopping_writes()) { space->release(); space= nullptr; @@ -1580,7 +1614,7 @@ bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed) ulint max_n_flush= srv_io_capacity; ulint n_flush= 0; - bool acquired= space->acquire(); + bool acquired= space->acquire_for_write(); { const uint32_t written{space->flush_freed(acquired)}; mysql_mutex_lock(&buf_pool.mutex); @@ -1623,7 +1657,7 @@ bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed) buf_flush_discard_page(bpage); else { - if (space->is_stopping()) + if (space->is_stopping_writes()) { space->release(); acquired= false; @@ -2083,6 +2117,8 @@ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) limit= lsn; buf_pool.page_cleaner_set_idle(false); pthread_cond_signal(&buf_pool.do_flush_list); + if (furious) + log_sys.set_check_for_checkpoint(); } mysql_mutex_unlock(&buf_pool.flush_list_mutex); } @@ -2502,10 +2538,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/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 24b4e512aa0..34776d1033c 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -794,6 +794,14 @@ void buf_page_make_young(buf_page_t *bpage) mysql_mutex_unlock(&buf_pool.mutex); } +bool buf_page_make_young_if_needed(buf_page_t *bpage) +{ + const bool not_first{bpage->set_accessed()}; + if (UNIV_UNLIKELY(buf_page_peek_if_too_old(bpage))) + buf_page_make_young(bpage); + return not_first; +} + /** Try to free a block. If bpage is a descriptor of a compressed-only ROW_FORMAT=COMPRESSED page, the buf_page_t object will be freed as well. The caller must hold buf_pool.mutex. @@ -815,7 +823,7 @@ bool buf_LRU_free_page(buf_page_t *bpage, bool zip) /* We must hold an exclusive hash_lock to prevent bpage->can_relocate() from changing due to a concurrent - execution of buf_page_get_low(). */ + execution of buf_page_get_gen(). */ buf_pool_t::hash_chain& chain= buf_pool.page_hash.cell_get(id.fold()); page_hash_latch& hash_lock = buf_pool.page_hash.lock_get(chain); /* We cannot use transactional_lock_guard here, diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 17c640d5ea0..70e71845083 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -586,6 +586,12 @@ failed: uint32_t prev= mach_read_from_4(my_assume_aligned<4>(f + FIL_PAGE_PREV)); uint32_t next= mach_read_from_4(my_assume_aligned<4>(f + FIL_PAGE_NEXT)); hash_lock.unlock_shared(); + /* The underlying file page of this buffer pool page could actually + be marked as freed, or a read of the page into the buffer pool might + be in progress. We may read uninitialized data here. + Suppress warnings of comparing uninitialized values. */ + MEM_MAKE_DEFINED(&prev, sizeof prev); + MEM_MAKE_DEFINED(&next, sizeof next); if (prev == FIL_NULL || next == FIL_NULL) goto fail; page_id_t id= page_id; diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc index 316d0f01322..84b8f8603b5 100644 --- a/storage/innobase/dict/dict0boot.cc +++ b/storage/innobase/dict/dict0boot.cc @@ -41,7 +41,10 @@ static constexpr page_id_t hdr_page_id{DICT_HDR_SPACE, DICT_HDR_PAGE_NO}; static buf_block_t *dict_hdr_get(mtr_t *mtr) { /* We assume that the DICT_HDR page is always readable and available. */ - return buf_page_get_gen(hdr_page_id, 0, RW_X_LATCH, nullptr, BUF_GET, mtr); + buf_block_t *b= + buf_page_get_gen(hdr_page_id, 0, RW_X_LATCH, nullptr, BUF_GET, mtr); + buf_page_make_young_if_needed(&b->page); + return b; } /**********************************************************************//** @@ -218,8 +221,7 @@ dberr_t dict_boot() dict_sys.create(); dberr_t err; - const buf_block_t *d = buf_page_get_gen(hdr_page_id, 0, RW_S_LATCH, - nullptr, BUF_GET, &mtr, &err); + const buf_block_t *d = recv_sys.recover(hdr_page_id, &mtr ,&err); if (!d) { mtr.commit(); return err; @@ -393,19 +395,6 @@ dberr_t dict_boot() UT_BITS_IN_BYTES(unsigned(table->indexes.start->n_nullable))); mtr.commit(); - - if (err == DB_SUCCESS) { - /* Load definitions of other indexes on system tables */ - - dict_load_sys_table(dict_sys.sys_tables); - dict_load_sys_table(dict_sys.sys_columns); - dict_load_sys_table(dict_sys.sys_indexes); - dict_load_sys_table(dict_sys.sys_fields); - dict_sys.unlock(); - dict_sys.load_sys_tables(); - } else { - dict_sys.unlock(); - } - + dict_sys.unlock(); return err; } diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index cce5f2f24d0..dd858287f46 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 5545727b015..2e47a059f37 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -662,7 +662,7 @@ dict_table_t::parse_name<>(char(&)[NAME_LEN + 1], char(&)[NAME_LEN + 1], @param[in] table_op operation to perform when opening @return table object after locking MDL shared @retval nullptr if the table is not readable, or if trylock && MDL blocked */ -template +template dict_table_t* dict_acquire_mdl_shared(dict_table_t *table, THD *thd, @@ -678,7 +678,6 @@ dict_acquire_mdl_shared(dict_table_t *table, if (trylock) { - static_assert(!trylock || !purge_thd, "usage"); dict_sys.freeze(SRW_LOCK_CALL); db_len= dict_get_db_name_len(table->name.m_name); dict_sys.unfreeze(); @@ -749,13 +748,7 @@ retry: } } -retry_table_open: dict_sys.freeze(SRW_LOCK_CALL); - if (purge_thd && purge_sys.must_wait_FTS()) - { - not_found= reinterpret_cast(-1); - goto return_without_mdl; - } table= dict_sys.find_table(table_id); if (table) table->acquire(); @@ -763,11 +756,6 @@ retry_table_open: { dict_sys.unfreeze(); dict_sys.lock(SRW_LOCK_CALL); - if (purge_thd && purge_sys.must_wait_FTS()) - { - dict_sys.unlock(); - goto retry_table_open; - } table= dict_load_table_on_id(table_id, table_op == DICT_TABLE_OP_LOAD_TABLESPACE ? DICT_ERR_IGNORE_RECOVER_LOCK @@ -826,24 +814,21 @@ return_without_mdl: goto retry; } -template dict_table_t* dict_acquire_mdl_shared +template dict_table_t* dict_acquire_mdl_shared (dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); -template dict_table_t* dict_acquire_mdl_shared +template dict_table_t* dict_acquire_mdl_shared (dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); /** Look up a table by numeric identifier. -@tparam purge_thd Whether the function is called by purge thread @param[in] table_id table identifier @param[in] dict_locked data dictionary locked @param[in] table_op operation to perform when opening @param[in,out] thd background thread, or NULL to not acquire MDL @param[out] mdl mdl ticket, or NULL @return table, NULL if does not exist */ -template -dict_table_t* -dict_table_open_on_id(table_id_t table_id, bool dict_locked, - dict_table_op_t table_op, THD *thd, - MDL_ticket **mdl) +dict_table_t *dict_table_open_on_id(table_id_t table_id, bool dict_locked, + dict_table_op_t table_op, THD *thd, + MDL_ticket **mdl) { if (!dict_locked) dict_sys.freeze(SRW_LOCK_CALL); @@ -852,16 +837,9 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, if (table) { - if (purge_thd && purge_sys.must_wait_FTS()) - { - table= reinterpret_cast(-1); - goto func_exit; - } - table->acquire(); if (thd && !dict_locked) - table= dict_acquire_mdl_shared( - table, thd, mdl, table_op); + table= dict_acquire_mdl_shared(table, thd, mdl, table_op); } else if (table_op != DICT_TABLE_OP_OPEN_ONLY_IF_CACHED) { @@ -875,44 +853,26 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, ? DICT_ERR_IGNORE_RECOVER_LOCK : DICT_ERR_IGNORE_FK_NOKEY); if (table) - { - if (purge_thd && purge_sys.must_wait_FTS()) - { - dict_sys.unlock(); - return reinterpret_cast(-1); - } table->acquire(); - } if (!dict_locked) { dict_sys.unlock(); if (table && thd) { dict_sys.freeze(SRW_LOCK_CALL); - table= dict_acquire_mdl_shared( - table, thd, mdl, table_op); + table= dict_acquire_mdl_shared(table, thd, mdl, table_op); dict_sys.unfreeze(); } return table; } } -func_exit: if (!dict_locked) dict_sys.unfreeze(); return table; } -template dict_table_t* dict_table_open_on_id -(table_id_t table_id, bool dict_locked, - dict_table_op_t table_op, THD *thd, - MDL_ticket **mdl); -template dict_table_t* dict_table_open_on_id -(table_id_t table_id, bool dict_locked, - dict_table_op_t table_op, THD *thd, - MDL_ticket **mdl); - /********************************************************************//** Looks for column n position in the clustered index. @return position in internal representation of the clustered index */ @@ -998,11 +958,12 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)) if (latch_ex_wait_start.compare_exchange_strong (old, now, std::memory_order_relaxed, std::memory_order_relaxed)) { +#ifdef UNIV_DEBUG + latch.x_lock(SRW_LOCK_ARGS(file, line)); +#else latch.wr_lock(SRW_LOCK_ARGS(file, line)); +#endif latch_ex_wait_start.store(0, std::memory_order_relaxed); - ut_ad(!latch_readers); - ut_ad(!latch_ex); - ut_d(latch_ex= pthread_self()); return; } @@ -1017,33 +978,39 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)) if (waited > threshold / 4) ib::warn() << "A long wait (" << waited << " seconds) was observed for dict_sys.latch"; +#ifdef UNIV_DEBUG + latch.x_lock(SRW_LOCK_ARGS(file, line)); +#else latch.wr_lock(SRW_LOCK_ARGS(file, line)); - ut_ad(!latch_readers); - ut_ad(!latch_ex); - ut_d(latch_ex= pthread_self()); +#endif } #ifdef UNIV_PFS_RWLOCK ATTRIBUTE_NOINLINE void dict_sys_t::unlock() { - ut_ad(latch_ex == pthread_self()); - ut_ad(!latch_readers); - ut_d(latch_ex= 0); +# ifdef UNIV_DEBUG + latch.x_unlock(); +# else latch.wr_unlock(); +# endif } ATTRIBUTE_NOINLINE void dict_sys_t::freeze(const char *file, unsigned line) { +# ifdef UNIV_DEBUG + latch.s_lock(file, line); +# else latch.rd_lock(file, line); - ut_ad(!latch_ex); - ut_d(latch_readers++); +# endif } ATTRIBUTE_NOINLINE void dict_sys_t::unfreeze() { - ut_ad(!latch_ex); - ut_ad(latch_readers--); +# ifdef UNIV_DEBUG + latch.s_unlock(); +# else latch.rd_unlock(); +# endif } #endif /* UNIV_PFS_RWLOCK */ @@ -2831,8 +2798,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, @@ -3552,6 +3518,7 @@ dict_foreign_parse_drop_constraints( const char* ptr1; const char* id; CHARSET_INFO* cs; + bool if_exists = false; ut_a(trx->mysql_thd); @@ -3605,6 +3572,7 @@ loop: ptr1 = dict_accept(cs, ptr1, "EXISTS", &success); if (success) { ptr = ptr1; + if_exists = true; } } @@ -3615,14 +3583,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; @@ -3644,6 +3612,9 @@ loop: return(DB_CANNOT_DROP_CONSTRAINT); } + ut_a(*n < 1000); + (*constraints_to_drop)[*n] = id; + (*n)++; goto loop; syntax_error: @@ -4544,7 +4515,11 @@ void dict_sys_t::close() temp_id_hash.free(); unlock(); +#ifdef UNIV_DEBUG + latch.free(); +#else latch.destroy(); +#endif mysql_mutex_destroy(&dict_foreign_err_mutex); diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index bf59fed9ee4..645e0c79490 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -33,8 +33,8 @@ Created 4/24/1996 Heikki Tuuri #include "dict0boot.h" #include "dict0crea.h" #include "dict0dict.h" -#include "dict0mem.h" #include "dict0stats.h" +#include "ibuf0ibuf.h" #include "fsp0file.h" #include "fts0priv.h" #include "mach0data.h" @@ -865,16 +865,31 @@ err_exit: return READ_OK; } -/** Open each tablespace found in the data dictionary. +/** @return SELECT MAX(space) FROM sys_tables */ +static uint32_t dict_find_max_space_id(btr_pcur_t *pcur, mtr_t *mtr) +{ + uint32_t max_space_id= 0; -In a crash recovery we already have some tablespace objects created from -processing the REDO log. We will compare the -space_id information in the data dictionary to what we find in the -tablespace file. In addition, more validation will be done if recovery -was needed and force_recovery is not set. + for (const rec_t *rec= dict_startscan_system(pcur, mtr, dict_sys.sys_tables); + rec; rec= dict_getnext_system_low(pcur, mtr)) + if (!dict_sys_tables_rec_check(rec)) + { + ulint len; + const byte *field= + rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__SPACE, &len); + ut_ad(len == 4); + max_space_id= std::max(max_space_id, mach_read_from_4(field)); + } -We also scan the biggest space id, and store it to fil_system. */ -void dict_load_tablespaces() + return max_space_id; +} + +/** Check MAX(SPACE) FROM SYS_TABLES and store it in fil_system. +Open each data file if an encryption plugin has been loaded. + +@param spaces set of tablespace files to open +@param upgrade whether we need to invoke ibuf_upgrade() */ +void dict_load_tablespaces(const std::set *spaces, bool upgrade) { uint32_t max_space_id = 0; btr_pcur_t pcur; @@ -884,6 +899,12 @@ void dict_load_tablespaces() dict_sys.lock(SRW_LOCK_CALL); + if (!spaces && !upgrade + && !encryption_key_id_exists(FIL_DEFAULT_ENCRYPTION_KEY)) { + max_space_id = dict_find_max_space_id(&pcur, &mtr); + goto done; + } + for (const rec_t *rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_tables); rec; rec = dict_getnext_system_low(&pcur, &mtr)) { @@ -915,14 +936,6 @@ void dict_load_tablespaces() continue; } - if (flags2 & DICT_TF2_DISCARDED) { - sql_print_information("InnoDB: Ignoring tablespace" - " for %.*s because " - "the DISCARD flag is set", - static_cast(len), field); - continue; - } - /* For tables or partitions using .ibd files, the flag DICT_TF2_USE_FILE_PER_TABLE was not set in MIX_LEN before MySQL 5.6.5. The flag should not have been @@ -935,6 +948,19 @@ void dict_load_tablespaces() continue; } + if (spaces && spaces->find(uint32_t(space_id)) + == spaces->end()) { + continue; + } + + if (flags2 & DICT_TF2_DISCARDED) { + sql_print_information("InnoDB: Ignoring tablespace" + " for %.*s because " + "the DISCARD flag is set", + static_cast(len), field); + continue; + } + const span name{field, len}; char* filepath = fil_make_filepath(nullptr, name, @@ -967,6 +993,7 @@ void dict_load_tablespaces() ut_free(filepath); } +done: mtr.commit(); fil_set_max_space_id_if_bigger(max_space_id); @@ -2240,22 +2267,10 @@ dict_load_tablespace( /* The tablespace may already be open. */ table->space = fil_space_for_table_exists_in_mem(table->space_id, table->flags); - if (table->space) { + if (table->space || table->file_unreadable) { return; } - if (ignore_err >= DICT_ERR_IGNORE_TABLESPACE) { - table->file_unreadable = true; - return; - } - - if (!(ignore_err & DICT_ERR_IGNORE_RECOVER_LOCK)) { - ib::error() << "Failed to find tablespace for table " - << table->name << " in the cache. Attempting" - " to load the tablespace with space id " - << table->space_id; - } - /* Use the remote filepath if needed. This parameter is optional in the call to fil_ibd_open(). If not supplied, it will be built from the table->name. */ @@ -2278,6 +2293,12 @@ dict_load_tablespace( if (!table->space) { /* We failed to find a sensible tablespace file */ table->file_unreadable = true; + + if (!(ignore_err & DICT_ERR_IGNORE_RECOVER_LOCK)) { + sql_print_error("InnoDB: Failed to load tablespace " + ULINTPF " for table %s", + table->space_id, table->name); + } } ut_free(filepath); diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index df69e313f09..97f8ba319d3 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -733,10 +733,10 @@ static void dict_stats_empty_index(dict_index_t *index) index->stat_n_leaf_pages = 1; } -/*********************************************************************//** -Write all zeros (or 1 where it makes sense) into a table and its indexes' -statistics members. The resulting stats correspond to an empty table. */ -static void dict_stats_empty_table(dict_table_t *table) +/** Write all zeros (or 1 where it makes sense) into a table and its indexes' +statistics members. The resulting stats correspond to an empty table. +@param table table statistics to be emptied */ +void dict_stats_empty_table(dict_table_t *table) { /* Initialize table/index level stats is now protected by table level lock_mutex.*/ diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 8463c20eace..1e2932384c5 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -405,7 +405,7 @@ static void dict_stats_schedule(int ms) void dict_stats_schedule_now() { - dict_stats_schedule(0); + dict_stats_schedule(10); } /** Shut down the dict_stats_thread. */ diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 8601685c536..0f4bf115d04 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -96,11 +96,9 @@ bool fil_space_t::try_to_close(bool print_info) if (!node->is_open()) continue; - /* Other thread is trying to do fil_delete_tablespace() - concurrently for the same tablespace. So ignore this - tablespace and try to close the other one */ const auto n= space.set_closing(); if (n & STOPPING) + /* Let fil_space_t::drop() in another thread handle this. */ continue; if (n & (PENDING | NEEDS_FSYNC)) { @@ -510,7 +508,7 @@ void fil_space_t::flush_low() std::memory_order_relaxed)) { ut_ad(n & PENDING); - if (n & STOPPING) + if (n & STOPPING_WRITES) return; if (n & NEEDS_FSYNC) break; @@ -1662,7 +1660,7 @@ static void fil_name_write(uint32_t space_id, const char *name, mtr->log_file_op(FILE_MODIFY, space_id, name); } -fil_space_t *fil_space_t::check_pending_operations(uint32_t id) +fil_space_t *fil_space_t::drop(uint32_t id, pfs_os_file_t *detached_handle) { ut_a(!is_system_tablespace(id)); mysql_mutex_lock(&fil_system.mutex); @@ -1676,7 +1674,6 @@ fil_space_t *fil_space_t::check_pending_operations(uint32_t id) if (space->pending() & STOPPING) { -being_deleted: /* A thread executing DDL and another thread executing purge may be executing fil_delete_tablespace() concurrently for the same tablespace. Wait for the other thread to complete the operation. */ @@ -1695,34 +1692,83 @@ being_deleted: mysql_mutex_lock(&fil_system.mutex); } } - else - { - if (space->crypt_data) - { - space->reacquire(); - mysql_mutex_unlock(&fil_system.mutex); - fil_space_crypt_close_tablespace(space); - mysql_mutex_lock(&fil_system.mutex); - space->release(); - } - if (space->set_stopping_check()) - goto being_deleted; - } + /* We must be the first one to set either STOPPING flag on the .ibd file, + because the flags are only being set here, within a critical section of + fil_system.mutex. */ + unsigned pending; + ut_d(pending=) + space->n_pending.fetch_add(STOPPING_READS + 1, std::memory_order_relaxed); + ut_ad(!(pending & STOPPING)); mysql_mutex_unlock(&fil_system.mutex); - for (ulint count= 0;; count++) + if (space->crypt_data) + fil_space_crypt_close_tablespace(space); + + if (space->purpose == FIL_TYPE_TABLESPACE) { - const unsigned pending= space->referenced(); - if (!pending) - return space; - /* Issue a warning every 10.24 seconds, starting after 2.56 seconds */ - if ((count & 511) == 128) - sql_print_warning("InnoDB: Trying to delete tablespace '%s' " - "but there are %u pending operations", - space->chain.start->name, id); - std::this_thread::sleep_for(std::chrono::milliseconds(20)); + if (id >= srv_undo_space_id_start && + id < srv_undo_space_id_start + srv_undo_tablespaces_open) + { + os_file_delete(innodb_data_file_key, space->chain.start->name); + goto deleted; + } + + /* Before deleting the file, persistently write a log record. */ + mtr_t mtr; + mtr.start(); + mtr.log_file_op(FILE_DELETE, id, space->chain.start->name); + mtr.commit_file(*space, nullptr); + + if (FSP_FLAGS_HAS_DATA_DIR(space->flags)) + RemoteDatafile::delete_link_file(space->name()); + + os_file_delete(innodb_data_file_key, space->chain.start->name); } + else + ut_ad(space->purpose == FIL_TYPE_IMPORT); + + if (char *cfg_name= fil_make_filepath(space->chain.start->name, + fil_space_t::name_type{}, CFG, false)) + { + os_file_delete_if_exists(innodb_data_file_key, cfg_name, nullptr); + ut_free(cfg_name); + } + + deleted: + mysql_mutex_lock(&fil_system.mutex); + ut_ad(space == fil_space_get_by_id(id)); + pending= + space->n_pending.fetch_add(STOPPING_WRITES - 1, std::memory_order_relaxed); + ut_ad((pending & STOPPING) == STOPPING_READS); + ut_ad(pending & PENDING); + pending&= PENDING; + if (--pending) + { + for (ulint count= 0;; count++) + { + ut_ad(space == fil_space_get_by_id(id)); + pending= space->n_pending.load(std::memory_order_relaxed) & PENDING; + if (!pending) + break; + mysql_mutex_unlock(&fil_system.mutex); + /* Issue a warning every 10.24 seconds, starting after 2.56 seconds */ + if ((count & 511) == 128) + sql_print_warning("InnoDB: Trying to delete tablespace '%s' " + "but there are %u pending operations", + space->chain.start->name, pending); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + mysql_mutex_lock(&fil_system.mutex); + } + } + + pfs_os_file_t handle= fil_system.detach(space, true); + mysql_mutex_unlock(&fil_system.mutex); + if (detached_handle) + *detached_handle = handle; + else + os_file_close(handle); + return space; } /** Close a single-table tablespace on failed IMPORT TABLESPACE. @@ -1731,37 +1777,29 @@ Free all pages used by the tablespace. */ void fil_close_tablespace(uint32_t id) { ut_ad(!is_system_tablespace(id)); - fil_space_t* space = fil_space_t::check_pending_operations(id); + fil_space_t* space = fil_space_t::drop(id, nullptr); if (!space) { return; } space->x_lock(); + ut_ad(space->is_stopping()); /* Invalidate in the buffer pool all pages belonging to the - tablespace. Since we have invoked space->set_stopping(), readahead + tablespace. Since space->is_stopping() holds, readahead can no longer read more pages of this tablespace to buf_pool. Thus we can clean the tablespace out of buf_pool completely and permanently. */ while (buf_flush_list_space(space)); - ut_ad(space->is_stopping()); - /* If it is a delete then also delete any generated files, otherwise - when we drop the database the remove directory will fail. */ - - if (char* cfg_name = fil_make_filepath(space->chain.start->name, - fil_space_t::name_type{}, - CFG, false)) { - os_file_delete_if_exists(innodb_data_file_key, cfg_name, NULL); - ut_free(cfg_name); - } - - /* If the free is successful, the wrlock will be released before - the space memory data structure is freed. */ - - if (!fil_space_free(id, true)) { - space->x_unlock(); + space->x_unlock(); + log_sys.latch.wr_lock(SRW_LOCK_CALL); + if (space->max_lsn != 0) { + ut_d(space->max_lsn = 0); + fil_system.named_spaces.remove(*space); } + log_sys.latch.wr_unlock(); + fil_space_free_low(space); } /** Delete a tablespace and associated .ibd file. @@ -1772,16 +1810,8 @@ pfs_os_file_t fil_delete_tablespace(uint32_t id) { ut_ad(!is_system_tablespace(id)); pfs_os_file_t handle= OS_FILE_CLOSED; - if (fil_space_t *space= fil_space_t::check_pending_operations(id)) - { - /* Before deleting the file(s), persistently write a log record. */ - mtr_t mtr; - mtr.start(); - mtr.log_file_op(FILE_DELETE, id, space->chain.start->name); - mtr.commit_file(*space, nullptr, &handle); + if (fil_space_t *space= fil_space_t::drop(id, &handle)) fil_space_free_low(space); - } - return handle; } @@ -2282,8 +2312,6 @@ func_exit: goto corrupted; } - os_file_get_last_error(operation_not_for_export, - !operation_not_for_export); if (!operation_not_for_export) { goto corrupted; } @@ -2546,21 +2574,15 @@ fil_ibd_load(uint32_t space_id, const char *filename, fil_space_t *&space) mysql_mutex_unlock(&fil_system.mutex); if (space) { - /* Compare the filename we are trying to open with the - filename from the first node of the tablespace we opened - previously. Fail if it is different. */ - fil_node_t* node = UT_LIST_GET_FIRST(space->chain); - if (0 != strcmp(innobase_basename(filename), - innobase_basename(node->name))) { - ib::info() - << "Ignoring data file '" << filename - << "' with space ID " << space->id - << ". Another data file called " << node->name - << " exists with the same space ID."; - space = NULL; - return(FIL_LOAD_ID_CHANGED); - } - return(FIL_LOAD_OK); + sql_print_information("InnoDB: Ignoring data file '%s'" + " with space ID " ULINTPF + ". Another data file called %s" + " exists" + " with the same space ID.", + filename, space->id, + UT_LIST_GET_FIRST(space->chain)->name); + space = NULL; + return FIL_LOAD_ID_CHANGED; } if (srv_operation == SRV_OPERATION_RESTORE) { @@ -3166,7 +3188,7 @@ ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void mtr_t::name_write() and write out FILE_MODIFY if needed, and write FILE_CHECKPOINT. @param lsn checkpoint LSN @return current LSN */ -lsn_t fil_names_clear(lsn_t lsn) +ATTRIBUTE_COLD lsn_t fil_names_clear(lsn_t lsn) { mtr_t mtr; diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc index bdc08b22f3a..9fa7a5a6c88 100644 --- a/storage/innobase/fil/fil0pagecompress.cc +++ b/storage/innobase/fil/fil0pagecompress.cc @@ -176,6 +176,7 @@ static ulint fil_page_compress_for_full_crc32( bool encrypted) { ulint comp_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags); + ulint comp_algo = fil_space_t::get_compression_algo(flags); if (comp_level == 0) { comp_level = page_zip_level; @@ -185,12 +186,13 @@ static ulint fil_page_compress_for_full_crc32( ulint write_size = fil_page_compress_low( buf, out_buf, header_len, - fil_space_t::get_compression_algo(flags), + comp_algo, static_cast(comp_level)); if (write_size == 0) { fail: - srv_stats.pages_page_compression_error.inc(); + if (comp_algo != PAGE_UNCOMPRESSED) + srv_stats.pages_page_compression_error.inc(); return 0; } @@ -270,7 +272,8 @@ static ulint fil_page_compress_for_non_full_crc32( header_len, comp_algo, comp_level); if (write_size == 0) { - srv_stats.pages_page_compression_error.inc(); + if (comp_algo != PAGE_UNCOMPRESSED) + srv_stats.pages_page_compression_error.inc(); return 0; } diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index e93ca4bc177..cafff419b05 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -449,7 +449,8 @@ Datafile::validate_for_recovery() return DB_SUCCESS; /* empty file */ } - if (restore_from_doublewrite()) { + if (recv_sys.dblwr.restore_first_page( + m_space_id, m_filepath, m_handle)) { return m_defer ? err : DB_CORRUPTION; } @@ -749,60 +750,6 @@ Datafile::find_space_id() return(DB_CORRUPTION); } - -/** Restore the first page of the tablespace from -the double write buffer. -@return whether the operation failed */ -bool -Datafile::restore_from_doublewrite() -{ - if (srv_operation > SRV_OPERATION_EXPORT_RESTORED) { - return true; - } - - /* Find if double write buffer contains page_no of given space id. */ - const page_id_t page_id(m_space_id, 0); - const byte* page = recv_sys.dblwr.find_page(page_id); - - if (!page) { - /* If the first page of the given user tablespace is not there - in the doublewrite buffer, then the recovery is going to fail - now. Hence this is treated as an error. */ - - ib::error() - << "Corrupted page " << page_id - << " of datafile '" << m_filepath - << "' could not be found in the doublewrite buffer."; - return(true); - } - - uint32_t flags = mach_read_from_4( - FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); - - if (!fil_space_t::is_valid_flags(flags, m_space_id)) { - flags = fsp_flags_convert_from_101(flags); - /* recv_dblwr_t::validate_page() inside find_page() - checked this already. */ - ut_ad(flags != UINT32_MAX); - /* The flags on the page should be converted later. */ - } - - ulint physical_size = fil_space_t::physical_size(flags); - - ut_a(page_get_page_no(page) == page_id.page_no()); - - ib::info() << "Restoring page " << page_id - << " of datafile '" << m_filepath - << "' from the doublewrite buffer. Writing " - << ib::bytes_iec{physical_size} << " into file '" - << m_filepath << "'"; - - return(os_file_write( - IORequestWrite, - m_filepath, m_handle, page, 0, physical_size) - != DB_SUCCESS); -} - /** Read an InnoDB Symbolic Link (ISL) file by name. @param link_filepath filepath of the ISL file @return data file name (must be freed by the caller) diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 1971d66ec94..4882a1964e1 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -1037,35 +1037,75 @@ static buf_block_t* fsp_page_create(fil_space_t *space, page_no_t offset, mtr_t *mtr) { - buf_block_t *block, *free_block; + buf_block_t *block; if (UNIV_UNLIKELY(space->is_being_truncated)) { const page_id_t page_id{space->id, offset}; - buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(page_id.fold()); - mysql_mutex_lock(&buf_pool.mutex); - block= reinterpret_cast - (buf_pool.page_hash.get(page_id, chain)); - if (block && block->page.oldest_modification() <= 1) - block= nullptr; - mysql_mutex_unlock(&buf_pool.mutex); - + uint32_t state; + block= mtr->get_already_latched(page_id, MTR_MEMO_PAGE_X_FIX); if (block) + goto have_latch; + else { - ut_ad(block->page.buf_fix_count() >= 1); - ut_ad(block->page.lock.x_lock_count() == 1); - ut_ad(mtr->have_x_latch(*block)); - free_block= block; - goto got_free_block; + buf_pool_t::hash_chain &chain= + buf_pool.page_hash.cell_get(page_id.fold()); + mysql_mutex_lock(&buf_pool.mutex); + block= reinterpret_cast + (buf_pool.page_hash.get(page_id, chain)); + if (!block) + { + mysql_mutex_unlock(&buf_pool.mutex); + goto create; + } } - } - free_block= buf_LRU_get_free_block(have_no_mutex); -got_free_block: - block= buf_page_create(space, static_cast(offset), - space->zip_size(), mtr, free_block); - if (UNIV_UNLIKELY(block != free_block)) - buf_pool.free_block(free_block); + if (!mtr->have_x_latch(*block)) + { + const bool got{block->page.lock.x_lock_try()}; + mysql_mutex_unlock(&buf_pool.mutex); + if (!got) + { + block->page.lock.x_lock(); + const page_id_t id{block->page.id()}; + if (UNIV_UNLIKELY(id != page_id)) + { + ut_ad(id.is_corrupted()); + block->page.lock.x_unlock(); + goto create; + } + } + state= block->page.fix() + 1; + mtr->memo_push(block, MTR_MEMO_PAGE_X_FIX); + } + else + { + mysql_mutex_unlock(&buf_pool.mutex); + have_latch: + state= block->page.state(); + } + + ut_ad(state > buf_page_t::FREED); + ut_ad(state < buf_page_t::READ_FIX); + ut_ad(block->page.lock.x_lock_count() == 1); + ut_ad(block->page.frame); +#ifdef BTR_CUR_HASH_ADAPT + ut_ad(!block->index); +#endif + + block->page.set_reinit(state < buf_page_t::UNFIXED + ? buf_page_t::FREED + : (state & buf_page_t::LRU_MASK)); + } + else + { + create: + buf_block_t *free_block= buf_LRU_get_free_block(have_no_mutex); + block= buf_page_create(space, static_cast(offset), + space->zip_size(), mtr, free_block); + if (UNIV_UNLIKELY(block != free_block)) + buf_pool.free_block(free_block); + } fsp_init_file_page(space, block, mtr); return block; diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc index ae445e5bd2b..5bea4596491 100644 --- a/storage/innobase/fsp/fsp0sysspace.cc +++ b/storage/innobase/fsp/fsp0sysspace.cc @@ -601,7 +601,9 @@ inline dberr_t SysTablespace::read_lsn_and_check_flags() if (err != DB_SUCCESS && (retry == 1 - || it->restore_from_doublewrite())) { + || recv_sys.dblwr.restore_first_page( + it->m_space_id, it->m_filepath, + it->handle()))) { it->close(); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index d2b90542ec6..0775d939002 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1609,10 +1609,11 @@ and common table associated with the fts table. already stopped*/ void purge_sys_t::stop_FTS(const dict_table_t &table, bool already_stopped) { - dict_sys.lock(SRW_LOCK_CALL); if (!already_stopped) purge_sys.stop_FTS(); + dict_sys.lock(SRW_LOCK_CALL); + fts_table_t fts_table; char table_name[MAX_FULL_NAME_LEN]; @@ -4255,6 +4256,11 @@ fts_sync( mysql_mutex_lock(&cache->lock); + if (cache->total_size == 0) { + mysql_mutex_unlock(&cache->lock); + return DB_SUCCESS; + } + /* Check if cache is being synced. Note: we release cache lock in fts_sync_write_words() to avoid long wait for the lock by other threads. */ diff --git a/storage/innobase/fts/fts0pars.cc b/storage/innobase/fts/fts0pars.cc index 56cc8d6052c..cb51784a7f1 100644 --- a/storage/innobase/fts/fts0pars.cc +++ b/storage/innobase/fts/fts0pars.cc @@ -83,15 +83,15 @@ #include "fts0tlex.h" #include "fts0pars.h" #include - extern int fts_lexer(YYSTYPE*, fts_lexer_t*); extern int fts_blexer(YYSTYPE*, yyscan_t); extern int fts_tlexer(YYSTYPE*, yyscan_t); - - - +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wpragmas" +# pragma GCC diagnostic ignored "-Wunknown-warning-option" +# pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#endif extern int ftserror(const char* p); - /* Required for reentrant parser */ #define ftslex fts_lexer diff --git a/storage/innobase/fts/fts0pars.y b/storage/innobase/fts/fts0pars.y index deebc79e4c4..903c72800f9 100644 --- a/storage/innobase/fts/fts0pars.y +++ b/storage/innobase/fts/fts0pars.y @@ -31,15 +31,15 @@ this program; if not, write to the Free Software Foundation, Inc., #include "fts0tlex.h" #include "fts0pars.h" #include - extern int fts_lexer(YYSTYPE*, fts_lexer_t*); extern int fts_blexer(YYSTYPE*, yyscan_t); extern int fts_tlexer(YYSTYPE*, yyscan_t); - - - +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wpragmas" +# pragma GCC diagnostic ignored "-Wunknown-warning-option" +# pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#endif extern int ftserror(const char* p); - /* Required for reentrant parser */ #define ftslex fts_lexer diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc index 43fcf5c82c8..65658835bb6 100644 --- a/storage/innobase/gis/gis0sea.cc +++ b/storage/innobase/gis/gis0sea.cc @@ -303,6 +303,8 @@ rtr_pcur_getnext_from_path( break; } + buf_page_make_young_if_needed(&block->page); + page = buf_block_get_frame(block); page_ssn = page_get_ssn_id(page); @@ -682,6 +684,8 @@ dberr_t rtr_search_to_nth_level(btr_cur_t *cur, que_thr_t *thr, return err; } + buf_page_make_young_if_needed(&block->page); + const page_t *page= buf_block_get_frame(block); #ifdef UNIV_ZIP_DEBUG if (rw_latch != RW_NO_LATCH) { @@ -1714,6 +1718,8 @@ corrupted: goto func_exit; } + buf_page_make_young_if_needed(&page_cursor->block->page); + /* Get the page SSN */ page = buf_block_get_frame(page_cursor->block); page_ssn = page_get_ssn_id(page); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 62daa270c2c..4164ce336b3 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -243,7 +243,7 @@ static void innodb_max_purge_lag_wait_update(THD *thd, st_mysql_sys_var *, const lsn_t lsn= log_sys.get_lsn(); if ((lsn - last) / 4 >= max_age / 5) buf_flush_ahead(last + max_age / 5, false); - srv_wake_purge_thread_if_not_active(); + purge_sys.wake_if_not_active(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } mysql_mutex_lock(&LOCK_global_system_variables); @@ -581,7 +581,13 @@ static PSI_rwlock_info all_innodb_rwlocks[] = # ifdef BTR_CUR_HASH_ADAPT { &btr_search_latch_key, "btr_search_latch", 0 }, # endif - { &dict_operation_lock_key, "dict_operation_lock", 0 }, + { &dict_operation_lock_key, "dict_operation_lock", +# ifdef UNIV_DEBUG + PSI_RWLOCK_FLAG_SX +# else + 0 +# endif + }, { &fil_space_latch_key, "fil_space_latch", 0 }, { &trx_i_s_cache_lock_key, "trx_i_s_cache_lock", 0 }, { &trx_purge_latch_key, "trx_purge_latch", 0 }, @@ -1532,7 +1538,8 @@ static void innodb_drop_database(handlerton*, char *path) os_file_close(detached); /* Any changes must be persisted before we return. */ - log_write_up_to(mtr.commit_lsn(), true); + if (mtr.commit_lsn()) + log_write_up_to(mtr.commit_lsn(), true); } my_free(namebuf); @@ -2047,8 +2054,6 @@ static void innodb_ddl_recovery_done(handlerton*) if (srv_start_after_restore && !high_level_read_only) drop_garbage_tables_after_restore(); srv_init_purge_tasks(); - purge_sys.coordinator_startup(); - srv_wake_purge_thread_if_not_active(); } } @@ -4239,6 +4244,11 @@ innobase_end(handlerton*, ha_panic_function) } } + /* Do system tablespace truncation during slow shutdown */ + if (!srv_fast_shutdown + && srv_operation == SRV_OPERATION_NORMAL) { + fsp_system_tablespace_truncate(); + } innodb_shutdown(); mysql_mutex_destroy(&log_requests.mutex); @@ -6408,9 +6418,9 @@ innobase_fts_text_cmp( const fts_string_t* s1 = (const fts_string_t*) p1; const fts_string_t* s2 = (const fts_string_t*) p2; - return(ha_compare_text( - charset, s1->f_str, static_cast(s1->f_len), - s2->f_str, static_cast(s2->f_len), 0)); + return(ha_compare_word(charset, + s1->f_str, static_cast(s1->f_len), + s2->f_str, static_cast(s2->f_len))); } /******************************************************************//** @@ -6431,9 +6441,9 @@ innobase_fts_text_case_cmp( newlen = strlen((const char*) s2->f_str); - return(ha_compare_text( - charset, s1->f_str, static_cast(s1->f_len), - s2->f_str, static_cast(newlen), 0)); + return(ha_compare_word(charset, + s1->f_str, static_cast(s1->f_len), + s2->f_str, static_cast(newlen))); } /******************************************************************//** @@ -6478,11 +6488,11 @@ innobase_fts_text_cmp_prefix( const fts_string_t* s2 = (const fts_string_t*) p2; int result; - result = ha_compare_text( - charset, s2->f_str, static_cast(s2->f_len), - s1->f_str, static_cast(s1->f_len), 1); + result = ha_compare_word_prefix(charset, + s2->f_str, static_cast(s2->f_len), + s1->f_str, static_cast(s1->f_len)); - /* We switched s1, s2 position in ha_compare_text. So we need + /* We switched s1, s2 position in the above call. So we need to negate the result */ return(-result); } @@ -7800,20 +7810,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; } @@ -7951,7 +7947,6 @@ set_max_autoinc: } } -report_error: /* Cleanup and exit. */ if (error == DB_TABLESPACE_DELETED) { ib_senderrf( @@ -11805,8 +11800,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); } @@ -13491,14 +13484,7 @@ int ha_innobase::delete_table(const char *name) /* FOREIGN KEY constraints cannot exist on partitioned tables. */; #endif else - { - dict_sys.freeze(SRW_LOCK_CALL); - for (const dict_foreign_t* f : table->referenced_set) - if (dict_table_t* child= f->foreign_table) - if ((err= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS) - break; - dict_sys.unfreeze(); - } + err= lock_table_children(table, trx); } dict_table_t *table_stats= nullptr, *index_stats= nullptr; @@ -13896,14 +13882,7 @@ int ha_innobase::truncate() dict_table_t *table_stats = nullptr, *index_stats = nullptr; MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; - dberr_t error= DB_SUCCESS; - - dict_sys.freeze(SRW_LOCK_CALL); - for (const dict_foreign_t *f : ib_table->referenced_set) - if (dict_table_t *child= f->foreign_table) - if ((error= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS) - break; - dict_sys.unfreeze(); + dberr_t error= lock_table_children(ib_table, trx); if (error == DB_SUCCESS) error= lock_table_for_trx(ib_table, trx, LOCK_X); @@ -14094,16 +14073,7 @@ ha_innobase::rename_table( /* There is no need to lock any FOREIGN KEY child tables. */ } else if (dict_table_t *table = dict_table_open_on_name( norm_from, false, DICT_ERR_IGNORE_FK_NOKEY)) { - dict_sys.freeze(SRW_LOCK_CALL); - for (const dict_foreign_t* f : table->referenced_set) { - if (dict_table_t* child = f->foreign_table) { - error = lock_table_for_trx(child, trx, LOCK_X); - if (error != DB_SUCCESS) { - break; - } - } - } - dict_sys.unfreeze(); + error = lock_table_children(table, trx); if (error == DB_SUCCESS) { error = lock_table_for_trx(table, trx, LOCK_X); } @@ -14745,12 +14715,7 @@ ha_innobase::info_low( DBUG_ASSERT(ib_table->get_ref_count() > 0); if (!ib_table->is_readable()) { - ib_table->stats_mutex_lock(); - ib_table->stat_initialized = true; - ib_table->stat_n_rows = 0; - ib_table->stat_clustered_index_size = 0; - ib_table->stat_sum_of_other_index_sizes = 0; - ib_table->stats_mutex_unlock(); + dict_stats_empty_table(ib_table); } if (flag & HA_STATUS_TIME) { @@ -15631,15 +15596,17 @@ ha_innobase::extra( { /* Warning: since it is not sure that MariaDB calls external_lock() before calling this function, m_prebuilt->trx can be obsolete! */ - trx_t* trx = check_trx_exists(ha_thd()); + trx_t* trx; switch (operation) { case HA_EXTRA_FLUSH: + (void)check_trx_exists(ha_thd()); if (m_prebuilt->blob_heap) { row_mysql_prebuilt_free_blob_heap(m_prebuilt); } break; case HA_EXTRA_RESET_STATE: + trx = check_trx_exists(ha_thd()); reset_template(); trx->duplicates = 0; stmt_boundary: @@ -15648,18 +15615,23 @@ ha_innobase::extra( trx->bulk_insert = false; break; case HA_EXTRA_NO_KEYREAD: + (void)check_trx_exists(ha_thd()); m_prebuilt->read_just_key = 0; break; case HA_EXTRA_KEYREAD: + (void)check_trx_exists(ha_thd()); m_prebuilt->read_just_key = 1; break; case HA_EXTRA_KEYREAD_PRESERVE_FIELDS: + (void)check_trx_exists(ha_thd()); m_prebuilt->keep_other_fields_on_keyread = 1; break; case HA_EXTRA_INSERT_WITH_UPDATE: + trx = check_trx_exists(ha_thd()); trx->duplicates |= TRX_DUP_IGNORE; goto stmt_boundary; case HA_EXTRA_NO_IGNORE_DUP_KEY: + trx = check_trx_exists(ha_thd()); trx->duplicates &= ~TRX_DUP_IGNORE; if (trx->is_bulk_insert()) { /* Allow a subsequent INSERT into an empty table @@ -15671,9 +15643,11 @@ ha_innobase::extra( } goto stmt_boundary; case HA_EXTRA_WRITE_CAN_REPLACE: + trx = check_trx_exists(ha_thd()); trx->duplicates |= TRX_DUP_REPLACE; goto stmt_boundary; case HA_EXTRA_WRITE_CANNOT_REPLACE: + trx = check_trx_exists(ha_thd()); trx->duplicates &= ~TRX_DUP_REPLACE; if (trx->is_bulk_insert()) { /* Allow a subsequent INSERT into an empty table @@ -15682,6 +15656,7 @@ ha_innobase::extra( } goto stmt_boundary; case HA_EXTRA_BEGIN_ALTER_COPY: + trx = check_trx_exists(ha_thd()); m_prebuilt->table->skip_alter_undo = 1; if (m_prebuilt->table->is_temporary() || !m_prebuilt->table->versioned_by_id()) { @@ -15694,8 +15669,10 @@ ha_innobase::extra( .first->second.set_versioned(0); break; case HA_EXTRA_END_ALTER_COPY: + trx = check_trx_exists(ha_thd()); m_prebuilt->table->skip_alter_undo = 0; - if (!m_prebuilt->table->is_temporary()) { + if (!m_prebuilt->table->is_temporary() + && !high_level_read_only) { log_buffer_flush_to_disk(); } break; @@ -16176,7 +16153,7 @@ innodb_show_status( DBUG_RETURN(0); } - srv_wake_purge_thread_if_not_active(); + purge_sys.wake_if_not_active(); /* We let the InnoDB Monitor to output at most MAX_STATUS_SIZE bytes of text. */ @@ -18207,11 +18184,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 @@ -18777,9 +18758,9 @@ static MYSQL_SYSVAR_ULONG(purge_batch_size, srv_purge_batch_size, PLUGIN_VAR_OPCMDARG, "Number of UNDO log pages to purge in one batch from the history list.", NULL, NULL, - 300, /* Default setting */ + 1000, /* Default setting */ 1, /* Minimum value */ - 5000, 0); /* Maximum value */ + innodb_purge_batch_size_MAX, 0); extern void srv_update_purge_thread_count(uint n); @@ -19305,16 +19286,15 @@ static MYSQL_SYSVAR_ULONGLONG(max_undo_log_size, srv_max_undo_log_size, static MYSQL_SYSVAR_ULONG(purge_rseg_truncate_frequency, srv_purge_rseg_truncate_frequency, - PLUGIN_VAR_OPCMDARG, - "Dictates rate at which UNDO records are purged. Value N means" - " purge rollback segment(s) on every Nth iteration of purge invocation", + PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_DEPRECATED, + "Deprecated parameter with no effect", NULL, NULL, 128, 1, 128, 0); static void innodb_undo_log_truncate_update(THD *thd, struct st_mysql_sys_var*, void*, const void *save) { if ((srv_undo_log_truncate= *static_cast(save))) - srv_wake_purge_thread_if_not_active(); + purge_sys.wake_if_not_active(); } static MYSQL_SYSVAR_BOOL(undo_log_truncate, srv_undo_log_truncate, @@ -19948,30 +19928,6 @@ static TABLE* innodb_find_table_for_vc(THD* thd, dict_table_t* table) return mysql_table; } -/** Only used by the purge thread -@param[in,out] table table whose virtual column template to be built */ -TABLE* innobase_init_vc_templ(dict_table_t* table) -{ - DBUG_ENTER("innobase_init_vc_templ"); - - ut_ad(table->vc_templ == NULL); - - TABLE *mysql_table= innodb_find_table_for_vc(current_thd, table); - - ut_ad(mysql_table); - if (!mysql_table) { - DBUG_RETURN(NULL); - } - - dict_vcol_templ_t* vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); - - dict_sys.lock(SRW_LOCK_CALL); - table->vc_templ = vc_templ; - innobase_build_v_templ(mysql_table, table, vc_templ, nullptr, true); - dict_sys.unlock(); - DBUG_RETURN(mysql_table); -} - /** Change dbname and table name in table->vc_templ. @param[in,out] table the table whose virtual column template dbname and tbname to be renamed. */ @@ -20529,6 +20485,10 @@ Compare_keys ha_innobase::compare_key_parts( if (old_part.length >= new_part.length) return Compare_keys::NotEqual; + if (old_part.length == old_field.key_length() && + new_part.length != new_field.length) + return Compare_keys::NotEqual; + return Compare_keys::EqualButKeyPartLength; } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index cde2d29fb5f..48bf59fb6f4 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2317,12 +2317,16 @@ innodb_instant_alter_column_allowed_reason: } } + bool need_rebuild = false; + switch (ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) { case ALTER_OPTIONS: - if (alter_options_need_rebuild(ha_alter_info, table)) { + if ((srv_file_per_table && !m_prebuilt->table->space_id) + || alter_options_need_rebuild(ha_alter_info, table)) { reason_rebuild = my_get_err_msg( ER_ALTER_OPERATION_TABLE_OPTIONS_NEED_REBUILD); ha_alter_info->unsupported_reason = reason_rebuild; + need_rebuild= true; break; } /* fall through */ @@ -2434,7 +2438,7 @@ innodb_instant_alter_column_allowed_reason: /* We should be able to do the operation in-place. See if we can do it online (LOCK=NONE) or without rebuild. */ - bool online = true, need_rebuild = false; + bool online = true; const uint fulltext_indexes = innobase_fulltext_exist(altered_table); /* Fix the key parts. */ @@ -4338,7 +4342,8 @@ static void unlock_and_close_files(const std::vector &deleted, row_mysql_unlock_data_dictionary(trx); for (pfs_os_file_t d : deleted) os_file_close(d); - log_write_up_to(trx->commit_lsn, true); + if (trx->commit_lsn) + log_write_up_to(trx->commit_lsn, true); } /** Commit a DDL transaction and unlink any deleted files. */ @@ -4681,11 +4686,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; @@ -6217,24 +6224,20 @@ empty_table: /* Convert the table to the instant ALTER TABLE format. */ mtr.commit(); mtr.start(); - index->set_modified(mtr); - if (buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, &mtr, + if (buf_block_t* root = btr_root_block_get(index, RW_S_LATCH, &mtr, &err)) { if (fil_page_get_type(root->page.frame) != FIL_PAGE_INDEX) { DBUG_ASSERT("wrong page type" == 0); err = DB_CORRUPTION; goto func_exit; } - - btr_set_instant(root, *index, &mtr); - mtr.commit(); - mtr.start(); - index->set_modified(mtr); - err = row_ins_clust_index_entry_low( - BTR_NO_LOCKING_FLAG, BTR_MODIFY_TREE, index, - index->n_uniq, entry, 0, thr); } + mtr.commit(); + mtr.start(); + err = row_ins_clust_index_entry_low( + BTR_NO_LOCKING_FLAG, BTR_MODIFY_TREE, index, + index->n_uniq, entry, 0, thr); goto func_exit; } @@ -7760,40 +7763,37 @@ bool check_col_is_in_fk_indexes( { char *fk_id= nullptr; - for (dict_foreign_set::iterator it= table->foreign_set.begin(); - it!= table->foreign_set.end();) + for (const auto &f : table->foreign_set) { - if (std::find(drop_fk.begin(), drop_fk.end(), (*it)) - != drop_fk.end()) - goto next_item; - for (ulint i= 0; i < (*it)->n_fields; i++) - if ((*it)->foreign_index->fields[i].col == col) + if (!f->foreign_index || + std::find(drop_fk.begin(), drop_fk.end(), f) != drop_fk.end()) + continue; + for (ulint i= 0; i < f->n_fields; i++) + if (f->foreign_index->fields[i].col == col) { - fk_id= (*it)->id; - goto err_exit; + fk_id= f->id; + goto err_exit; } -next_item: - it++; } 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) { fk_id= a->id; - goto err_exit; + goto err_exit; } } } for (const auto &f : table->referenced_set) { + if (!f->referenced_index) continue; for (ulint i= 0; i < f->n_fields; i++) { - if (!f->referenced_index) - continue; if (f->referenced_index->fields[i].col == col) { my_error(ER_FK_COLUMN_CANNOT_CHANGE_CHILD, MYF(0), @@ -8414,8 +8414,17 @@ err_exit: if (ha_alter_info->handler_flags & ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE) { - for (uint i= 0; i < table->s->fields; i++) { + for (uint i= 0, n_v_col= 0; i < table->s->fields; + i++) { Field* field = table->field[i]; + + /* Altering the virtual column is not + supported for inplace alter algorithm */ + if (field->vcol_info) { + n_v_col++; + continue; + } + for (const Create_field& new_field : ha_alter_info->alter_info->create_list) { if (new_field.field == field) { @@ -8430,7 +8439,7 @@ err_exit: field_changed: const char* col_name= field->field_name.str; dict_col_t *col= dict_table_get_nth_col( - m_prebuilt->table, i); + m_prebuilt->table, i - n_v_col); if (check_col_is_in_fk_indexes( m_prebuilt->table, col, col_name, span( @@ -11225,16 +11234,7 @@ ha_innobase::commit_inplace_alter_table( fts_optimize_remove_table(ctx->old_table); } - dict_sys.freeze(SRW_LOCK_CALL); - for (auto f : ctx->old_table->referenced_set) { - if (dict_table_t* child = f->foreign_table) { - error = lock_table_for_trx(child, trx, LOCK_X); - if (error != DB_SUCCESS) { - break; - } - } - } - dict_sys.unfreeze(); + error = lock_table_children(ctx->old_table, trx); if (ctx->new_table->fts) { ut_ad(!ctx->new_table->fts->add_wq); @@ -11671,7 +11671,6 @@ foreign_fail: } unlock_and_close_files(deleted, trx); - log_write_up_to(trx->commit_lsn, true); DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit", DBUG_SUICIDE();); trx->free(); @@ -11728,7 +11727,6 @@ foreign_fail: } unlock_and_close_files(deleted, trx); - log_write_up_to(trx->commit_lsn, true); DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit", DBUG_SUICIDE();); trx->free(); diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 6d35ea3c604..ec50418b8cc 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -4527,6 +4527,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) @@ -4575,6 +4584,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); @@ -4604,8 +4614,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", @@ -4623,8 +4640,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); } /*******************************************************************//** @@ -4795,6 +4814,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); @@ -4820,8 +4840,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(); @@ -4839,8 +4863,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); } /*******************************************************************//** @@ -5012,6 +5037,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); @@ -5047,11 +5073,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, @@ -5069,9 +5097,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 @@ -5220,6 +5250,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); @@ -5251,9 +5282,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", @@ -5270,9 +5306,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); } /*******************************************************************//** @@ -5404,6 +5442,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); @@ -5432,8 +5471,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", @@ -5450,6 +5494,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 @@ -5577,6 +5624,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); @@ -5612,8 +5660,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, @@ -5631,9 +5684,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 @@ -5770,6 +5825,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); @@ -5797,8 +5853,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", @@ -5815,9 +5875,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); } /*******************************************************************//** @@ -5951,6 +6013,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); @@ -5982,9 +6045,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", @@ -6001,9 +6068,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 @@ -6206,6 +6275,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/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index ce5e0541ecf..4fff8bed133 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -1012,8 +1012,7 @@ dberr_t ibuf_upgrade_needed() mtr.start(); mtr.x_lock_space(fil_system.sys_space); dberr_t err; - const buf_block_t *header_page= - buf_page_get_gen(ibuf_header, 0, RW_S_LATCH, nullptr, BUF_GET, &mtr, &err); + const buf_block_t *header_page= recv_sys.recover(ibuf_header, &mtr, &err); if (!header_page) { @@ -1026,8 +1025,7 @@ dberr_t ibuf_upgrade_needed() return err; } - const buf_block_t *root= buf_page_get_gen(ibuf_root, 0, RW_S_LATCH, nullptr, - BUF_GET, &mtr, &err); + const buf_block_t *root= recv_sys.recover(ibuf_root, &mtr, &err); if (!root) goto err_exit; diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index 0a615a75836..f46fae5bd2a 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -92,10 +92,12 @@ ATTRIBUTE_COLD void btr_decryption_failed(const dict_index_t &index); @param[in] mode latch mode @param[in,out] mtr mini-transaction @param[out] err error code +@param[out] first set if this is a first-time access to the page @return block */ buf_block_t *btr_block_get(const dict_index_t &index, uint32_t page, rw_lock_type_t mode, - mtr_t *mtr, dberr_t *err= nullptr); + mtr_t *mtr, dberr_t *err= nullptr, + bool *first= nullptr); /**************************************************************//** Gets the index id field of a page. diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 0628faf844e..697903a4f19 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -201,34 +201,12 @@ buf_page_get_gen( buf_block_t* guess, ulint mode, mtr_t* mtr, - dberr_t* err = NULL) - MY_ATTRIBUTE((nonnull(6))); - -/** This is the low level function used to get access to a database page. -@param[in] page_id page id -@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 -@param[in] rw_latch RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH -@param[in] guess guessed block or NULL -@param[in] mode BUF_GET, BUF_GET_IF_IN_POOL, -or BUF_PEEK_IF_IN_POOL -@param[in,out] mtr mini-transaction, or NULL if a - block with page_id is to be evicted -@param[out] err DB_SUCCESS or error code -@return pointer to the block or NULL */ -buf_block_t* -buf_page_get_low( - const page_id_t page_id, - ulint zip_size, - ulint rw_latch, - buf_block_t* guess, - ulint mode, - mtr_t* mtr, - dberr_t* err); + dberr_t* err = nullptr); /** Initialize a page in the buffer pool. The page is usually not read from a file even if it cannot be found in the buffer buf_pool. This is one of the functions which perform to a block a state transition NOT_USED => LRU -(the other is buf_page_get_low()). +(the other is buf_page_get_gen()). @param[in,out] space space object @param[in] offset offset of the tablespace @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 @@ -250,8 +228,6 @@ buf_block_t* buf_page_create_deferred(uint32_t space_id, ulint zip_size, mtr_t *mtr, buf_block_t *free_block); -/** Move a block to the start of the LRU list. */ -void buf_page_make_young(buf_page_t *bpage); /** Mark the page status as FREED for the given tablespace and page number. @param[in,out] space tablespace @param[in] page page number @@ -273,15 +249,6 @@ there is danger of dropping from the buffer pool. @return true if bpage should be made younger */ inline bool buf_page_peek_if_too_old(const buf_page_t *bpage); -/** Move a page to the start of the buffer pool LRU list if it is too old. -@param[in,out] bpage buffer pool page */ -inline void buf_page_make_young_if_needed(buf_page_t *bpage) -{ - if (UNIV_UNLIKELY(buf_page_peek_if_too_old(bpage))) { - buf_page_make_young(bpage); - } -} - /********************************************************************//** Increments the modify clock of a frame by 1. The caller must (1) own the buf_pool.mutex and block bufferfix count has to be zero, (2) or own an x-lock @@ -641,12 +608,9 @@ public: access_time= 0; } - void set_os_unused() + void set_os_unused() const { MEM_NOACCESS(frame, srv_page_size); -#ifdef MADV_FREE - madvise(frame, srv_page_size, MADV_FREE); -#endif } void set_os_used() const @@ -1260,6 +1224,11 @@ public: /** Resize from srv_buf_pool_old_size to srv_buf_pool_size. */ inline void resize(); +#ifdef __linux__ + /** Collect garbage (release pages from the LRU list) */ + inline void garbage_collect(); +#endif + /** @return whether resize() is in progress */ bool resize_in_progress() const { @@ -1786,7 +1755,8 @@ public: #endif /** Reserve a buffer. */ - buf_tmp_buffer_t *io_buf_reserve() { return io_buf.reserve(); } + buf_tmp_buffer_t *io_buf_reserve(bool wait_for_reads) + { return io_buf.reserve(wait_for_reads); } /** Remove a block from flush_list. @param bpage buffer pool page */ @@ -1821,7 +1791,7 @@ private: void close(); /** Reserve a buffer */ - buf_tmp_buffer_t *reserve(); + buf_tmp_buffer_t *reserve(bool wait_for_reads); } io_buf; /** whether resize() is in the critical path */ diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index 1328dbca340..c52fc05ce8f 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -120,6 +120,16 @@ buf_LRU_add_block( blocks in the LRU list, else put to the start; if the LRU list is very short, added to the start regardless of this parameter */ + +/** Move a block to the start of the buf_pool.LRU list. +@param bpage buffer pool page */ +void buf_page_make_young(buf_page_t *bpage); +/** Flag a page accessed in buf_pool and move it to the start of buf_pool.LRU +if it is too old. +@param bpage buffer pool page +@return whether this is not the first access */ +bool buf_page_make_young_if_needed(buf_page_t *bpage); + /******************************************************************//** Adds a block to the LRU list of decompressed zip pages. */ void diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 628ad8366af..61c6a3b1bf2 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -132,7 +132,7 @@ enum dict_table_op_t { @param[in] table_op operation to perform when opening @return table object after locking MDL shared @retval NULL if the table is not readable, or if trylock && MDL blocked */ -template +template dict_table_t* dict_acquire_mdl_shared(dict_table_t *table, THD *thd, @@ -146,7 +146,6 @@ dict_acquire_mdl_shared(dict_table_t *table, @param[in,out] thd background thread, or NULL to not acquire MDL @param[out] mdl mdl ticket, or NULL @return table, NULL if does not exist */ -template dict_table_t* dict_table_open_on_id(table_id_t table_id, bool dict_locked, dict_table_op_t table_op, THD *thd= nullptr, @@ -1312,14 +1311,14 @@ class dict_sys_t /** The my_hrtime_coarse().val of the oldest lock_wait() start, or 0 */ std::atomic latch_ex_wait_start; - /** the rw-latch protecting the data dictionary cache */ - alignas(CPU_LEVEL1_DCACHE_LINESIZE) srw_lock latch; #ifdef UNIV_DEBUG - /** whether latch is being held in exclusive mode (by any thread) */ - Atomic_relaxed latch_ex; - /** number of S-latch holders */ - Atomic_counter latch_readers; + typedef index_lock dict_lock; +#else + typedef srw_lock dict_lock; #endif + + /** the rw-latch protecting the data dictionary cache */ + alignas(CPU_LEVEL1_DCACHE_LINESIZE) dict_lock latch; public: /** Indexes of SYS_TABLE[] */ enum @@ -1470,15 +1469,12 @@ public: } #ifdef UNIV_DEBUG - /** @return whether any thread (not necessarily the current thread) - is holding the latch; that is, this check may return false - positives */ - bool frozen() const { return latch_readers || latch_ex; } - /** @return whether any thread (not necessarily the current thread) - is holding a shared latch */ - bool frozen_not_locked() const { return latch_readers; } + /** @return whether the current thread is holding the latch */ + bool frozen() const { return latch.have_any(); } + /** @return whether the current thread is holding a shared latch */ + bool frozen_not_locked() const { return latch.have_s(); } /** @return whether the current thread holds the exclusive latch */ - bool locked() const { return latch_ex == pthread_self(); } + bool locked() const { return latch.have_x(); } #endif private: /** Acquire the exclusive latch */ @@ -1493,13 +1489,12 @@ public: /** Exclusively lock the dictionary cache. */ void lock(SRW_LOCK_ARGS(const char *file, unsigned line)) { - if (latch.wr_lock_try()) - { - ut_ad(!latch_readers); - ut_ad(!latch_ex); - ut_d(latch_ex= pthread_self()); - } - else +#ifdef UNIV_DEBUG + ut_ad(!latch.have_any()); + if (!latch.x_lock_try()) +#else + if (!latch.wr_lock_try()) +#endif lock_wait(SRW_LOCK_ARGS(file, line)); } @@ -1514,24 +1509,30 @@ public: /** Unlock the data dictionary cache. */ void unlock() { - ut_ad(latch_ex == pthread_self()); - ut_ad(!latch_readers); - ut_d(latch_ex= 0); +# ifdef UNIV_DEBUG + latch.x_unlock(); +# else latch.wr_unlock(); +# endif } /** Acquire a shared lock on the dictionary cache. */ void freeze() { +# ifdef UNIV_DEBUG + ut_ad(!latch.have_any()); + latch.s_lock(); +# else latch.rd_lock(); - ut_ad(!latch_ex); - ut_d(latch_readers++); +# endif } /** Release a shared lock on the dictionary cache. */ void unfreeze() { - ut_ad(!latch_ex); - ut_ad(latch_readers--); +# ifdef UNIV_DEBUG + latch.s_unlock(); +# else latch.rd_unlock(); +# endif } #endif diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index bd55848a776..c774a792f0b 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -35,20 +35,18 @@ Created 4/24/1996 Heikki Tuuri #include "btr0types.h" #include +#include /** A stack of table names related through foreign key constraints */ typedef std::deque > dict_names_t; -/** Open each tablespace found in the data dictionary. +/** Check MAX(SPACE) FROM SYS_TABLES and store it in fil_system. +Open each data file if an encryption plugin has been loaded. -In a crash recovery we already have some tablespace objects created from -processing the REDO log. We will compare the -space_id information in the data dictionary to what we find in the -tablespace file. In addition, more validation will be done if recovery -was needed and force_recovery is not set. - -We also scan the biggest space id, and store it to fil_system. */ -void dict_load_tablespaces(); +@param spaces set of tablespace files to open +@param upgrade whether we need to invoke ibuf_upgrade() */ +void dict_load_tablespaces(const std::set *spaces= nullptr, + bool upgrade= false); /** Make sure the data_file_name is saved in dict_table_t if needed. @param[in,out] table Table object */ diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h index f7c13147b16..720c8e00474 100644 --- a/storage/innobase/include/dict0stats.h +++ b/storage/innobase/include/dict0stats.h @@ -224,4 +224,9 @@ dict_stats_save_index_stat( void test_dict_stats_all(); #endif /* UNIV_ENABLE_UNIT_TEST_DICT_STATS */ +/** Write all zeros (or 1 where it makes sense) into a table and its indexes' +statistics members. The resulting stats correspond to an empty table. +@param table table statistics to be emptied */ +void dict_stats_empty_table(dict_table_t *table); + #endif /* dict0stats_h */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 13f12cb4e5b..82148384d5e 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -365,16 +365,22 @@ private: /** Number of pending operations on the file. The tablespace cannot be freed while (n_pending & PENDING) != 0. */ std::atomic n_pending; + /** Flag in n_pending that indicates that the tablespace is about to be + deleted, and no further operations should be performed */ + static constexpr uint32_t STOPPING_READS= 1U << 31; /** Flag in n_pending that indicates that the tablespace is being deleted, and no further operations should be performed */ - static constexpr uint32_t STOPPING= 1U << 31; + static constexpr uint32_t STOPPING_WRITES= 1U << 30; + /** Flags in n_pending that indicate that the tablespace is being + deleted, and no further operations should be performed */ + static constexpr uint32_t STOPPING= STOPPING_READS | STOPPING_WRITES; /** Flag in n_pending that indicates that the tablespace is a candidate for being closed, and fil_node_t::is_open() can only be trusted after acquiring fil_system.mutex and resetting the flag */ - static constexpr uint32_t CLOSING= 1U << 30; + static constexpr uint32_t CLOSING= 1U << 29; /** Flag in n_pending that indicates that the tablespace needs fsync(). This must be the least significant flag bit; @see release_flush() */ - static constexpr uint32_t NEEDS_FSYNC= 1U << 29; + static constexpr uint32_t NEEDS_FSYNC= 1U << 28; /** The reference count */ static constexpr uint32_t PENDING= ~(STOPPING | CLOSING | NEEDS_FSYNC); /** latch protecting all page allocation bitmap pages */ @@ -486,20 +492,19 @@ public: /** Close each file. Only invoked on fil_system.temp_space. */ void close(); - /** Note that operations on the tablespace must stop. - @return whether the operations were already stopped */ - inline bool set_stopping_check(); /** Note that operations on the tablespace must stop. */ inline void set_stopping(); /** Note that operations on the tablespace can resume after truncation */ inline void clear_stopping(); - /** Look up the tablespace and wait for pending operations to cease - @param id tablespace identifier - @return tablespace - @retval nullptr if no tablespace was found */ - static fil_space_t *check_pending_operations(uint32_t id); + /** Drop the tablespace and wait for any pending operations to cease + @param id tablespace identifier + @param detached_handle pointer to file to be closed later, or nullptr + @return tablespace to invoke fil_space_free() on + @retval nullptr if no tablespace was found, or it was deleted by + another concurrent thread */ + static fil_space_t *drop(uint32_t id, pfs_os_file_t *detached_handle); private: MY_ATTRIBUTE((warn_unused_result)) @@ -523,13 +528,19 @@ public: MY_ATTRIBUTE((warn_unused_result)) /** Acquire a tablespace reference for I/O. + @param avoid when these flags are set, nothing will be acquired @return whether the file is usable */ - bool acquire() + bool acquire(uint32_t avoid= STOPPING | CLOSING) { - const auto flags= acquire_low(STOPPING | CLOSING) & (STOPPING | CLOSING); + const auto flags= acquire_low(avoid) & (avoid); return UNIV_LIKELY(!flags) || (flags == CLOSING && acquire_and_prepare()); } + /** Acquire a tablespace reference for writing. + @param avoid when these flags are set, nothing will be acquired + @return whether the file is writable */ + bool acquire_for_write() { return acquire(STOPPING_WRITES | CLOSING); } + /** Acquire another tablespace reference for I/O. */ inline void reacquire(); @@ -546,12 +557,12 @@ public: void clear_flush() { #if defined __GNUC__ && (defined __i386__ || defined __x86_64__) - static_assert(NEEDS_FSYNC == 1U << 29, "compatibility"); - __asm__ __volatile__("lock btrl $29, %0" : "+m" (n_pending)); + static_assert(NEEDS_FSYNC == 1U << 28, "compatibility"); + __asm__ __volatile__("lock btrl $28, %0" : "+m" (n_pending)); #elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) - static_assert(NEEDS_FSYNC == 1U << 29, "compatibility"); + static_assert(NEEDS_FSYNC == 1U << 28, "compatibility"); _interlockedbittestandreset(reinterpret_cast - (&n_pending), 29); + (&n_pending), 28); #else n_pending.fetch_and(~NEEDS_FSYNC, std::memory_order_release); #endif @@ -562,12 +573,12 @@ private: void clear_closing() { #if defined __GNUC__ && (defined __i386__ || defined __x86_64__) - static_assert(CLOSING == 1U << 30, "compatibility"); - __asm__ __volatile__("lock btrl $30, %0" : "+m" (n_pending)); + static_assert(CLOSING == 1U << 29, "compatibility"); + __asm__ __volatile__("lock btrl $29, %0" : "+m" (n_pending)); #elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) - static_assert(CLOSING == 1U << 30, "compatibility"); + static_assert(CLOSING == 1U << 29, "compatibility"); _interlockedbittestandreset(reinterpret_cast - (&n_pending), 30); + (&n_pending), 29); #else n_pending.fetch_and(~CLOSING, std::memory_order_relaxed); #endif @@ -578,8 +589,10 @@ private: public: /** @return whether close() of the file handle has been requested */ bool is_closing() const { return pending() & CLOSING; } - /** @return whether the tablespace is going to be dropped */ + /** @return whether the tablespace is about to be dropped */ bool is_stopping() const { return pending() & STOPPING; } + /** @return whether the tablespace is going to be dropped */ + bool is_stopping_writes() const { return pending() & STOPPING_WRITES; } /** @return number of pending operations */ bool is_ready_to_close() const { return (pending() & (PENDING | CLOSING)) == CLOSING; } @@ -588,7 +601,7 @@ public: /** @return whether fsync() or similar is needed, and the tablespace is not being dropped */ bool needs_flush_not_stopping() const - { return (pending() & (NEEDS_FSYNC | STOPPING)) == NEEDS_FSYNC; } + { return (pending() & (NEEDS_FSYNC | STOPPING_WRITES)) == NEEDS_FSYNC; } uint32_t referenced() const { return pending() & PENDING; } private: @@ -624,7 +637,7 @@ public: std::memory_order_relaxed)) { ut_ad(n & PENDING); - if (n & (NEEDS_FSYNC | STOPPING)) + if (n & (NEEDS_FSYNC | STOPPING_WRITES)) return false; } @@ -882,6 +895,11 @@ public: @return tablespace @retval nullptr if the tablespace is missing or inaccessible */ static fil_space_t *get(uint32_t id); + /** Acquire a tablespace reference for writing. + @param id tablespace identifier + @return tablespace + @retval nullptr if the tablespace is missing or inaccessible */ + static fil_space_t *get_for_write(uint32_t id); /** Add/remove the free page in the freed ranges list. @param[in] offset page number to be added @@ -1514,52 +1532,27 @@ inline void fil_space_t::reacquire() #endif /* SAFE_MUTEX */ } -/** Note that operations on the tablespace must stop. -@return whether the operations were already stopped */ -inline bool fil_space_t::set_stopping_check() -{ - mysql_mutex_assert_owner(&fil_system.mutex); -#if (defined __clang_major__ && __clang_major__ < 10) || defined __APPLE_CC__ - /* Only clang-10 introduced support for asm goto */ - return n_pending.fetch_or(STOPPING, std::memory_order_relaxed) & STOPPING; -#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__) - static_assert(STOPPING == 1U << 31, "compatibility"); - __asm__ goto("lock btsl $31, %0\t\njnc %l1" : : "m" (n_pending) - : "cc", "memory" : not_stopped); - return true; -not_stopped: - return false; -#elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) - static_assert(STOPPING == 1U << 31, "compatibility"); - return _interlockedbittestandset(reinterpret_cast - (&n_pending), 31); -#else - return n_pending.fetch_or(STOPPING, std::memory_order_relaxed) & STOPPING; -#endif -} - -/** Note that operations on the tablespace must stop. -@return whether the operations were already stopped */ +/** Note that operations on the tablespace must stop. */ inline void fil_space_t::set_stopping() { mysql_mutex_assert_owner(&fil_system.mutex); #if defined __GNUC__ && (defined __i386__ || defined __x86_64__) - static_assert(STOPPING == 1U << 31, "compatibility"); - __asm__ __volatile__("lock btsl $31, %0" : "+m" (n_pending)); + static_assert(STOPPING_WRITES == 1U << 30, "compatibility"); + __asm__ __volatile__("lock btsl $30, %0" : "+m" (n_pending)); #elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) - static_assert(STOPPING == 1U << 31, "compatibility"); - _interlockedbittestandset(reinterpret_cast(&n_pending), 31); + static_assert(STOPPING_WRITES == 1U << 30, "compatibility"); + _interlockedbittestandset(reinterpret_cast(&n_pending), 30); #else - n_pending.fetch_or(STOPPING, std::memory_order_relaxed); + n_pending.fetch_or(STOPPING_WRITES, std::memory_order_relaxed); #endif } inline void fil_space_t::clear_stopping() { mysql_mutex_assert_owner(&fil_system.mutex); - static_assert(STOPPING == 1U << 31, "compatibility"); - ut_d(auto n=) n_pending.fetch_sub(STOPPING, std::memory_order_relaxed); - ut_ad(n & STOPPING); + static_assert(STOPPING_WRITES == 1U << 30, "compatibility"); + ut_d(auto n=) n_pending.fetch_sub(STOPPING_WRITES, std::memory_order_relaxed); + ut_ad((n & STOPPING) == STOPPING_WRITES); } /** Flush pending writes from the file system cache to the file. */ @@ -1796,7 +1789,7 @@ bool fil_comp_algo_loaded(ulint comp_algo); and write out FILE_MODIFY if needed, and write FILE_CHECKPOINT. @param lsn checkpoint LSN @return current LSN */ -lsn_t fil_names_clear(lsn_t lsn); +ATTRIBUTE_COLD lsn_t fil_names_clear(lsn_t lsn); #ifdef UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH void test_make_filepath(); diff --git a/storage/innobase/include/fsp0file.h b/storage/innobase/include/fsp0file.h index 4f3cbcfd4e3..62dec39b91d 100644 --- a/storage/innobase/include/fsp0file.h +++ b/storage/innobase/include/fsp0file.h @@ -390,11 +390,6 @@ private: else DB_ERROR. */ dberr_t find_space_id(); - /** Restore the first page of the tablespace from - the double write buffer. - @return whether the operation failed */ - bool restore_from_doublewrite(); - /** Points into m_filepath to the file name with extension */ char* m_filename; 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/lock0lock.h b/storage/innobase/include/lock0lock.h index eca8c2cb614..8f0da1695ad 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -431,6 +431,13 @@ dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode, bool no_wait= false) MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Lock the child tables of a table. +@param table parent table +@param trx transaction +@return error code */ +dberr_t lock_table_children(dict_table_t *table, trx_t *trx) + MY_ATTRIBUTE((nonnull, warn_unused_result)); + /** Exclusively lock the data dictionary tables. @param trx dictionary transaction @return error code diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index bfbc7c91615..cdce87384f1 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -79,13 +79,6 @@ ATTRIBUTE_COLD void log_make_checkpoint(); /** Make a checkpoint at the latest lsn on shutdown. */ ATTRIBUTE_COLD void logs_empty_and_mark_files_at_shutdown(); -/** -Checks that there is enough free space in the log to start a new query step. -Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this -function may only be called if the calling thread owns no synchronization -objects! */ -ATTRIBUTE_COLD void log_check_margins(); - /******************************************************//** Prints info of the log. */ void @@ -179,24 +172,36 @@ private: std::atomic flushed_to_disk_lsn; /** log sequence number when log resizing was initiated, or 0 */ std::atomic resize_lsn; - /** set when there may be need to flush the log buffer, or - preflush buffer pool pages, or initiate a log checkpoint. + /** set when there may be need to initiate a log checkpoint. This must hold if lsn - last_checkpoint_lsn > max_checkpoint_age. */ - std::atomic check_flush_or_checkpoint_; - + std::atomic need_checkpoint; #if defined(__aarch64__) -/* On ARM, we do more spinning */ -typedef srw_spin_lock log_rwlock_t; -#define LSN_LOCK_ATTR MY_MUTEX_INIT_FAST + /* On ARM, we do more spinning */ + typedef srw_spin_lock log_rwlock; + typedef pthread_mutex_wrapper log_lsn_lock; +#elif defined _WIN32 + typedef srw_lock log_rwlock; + typedef pthread_mutex_wrapper log_lsn_lock; #else -typedef srw_lock log_rwlock_t; -#define LSN_LOCK_ATTR nullptr + typedef srw_lock log_rwlock; + typedef srw_mutex log_lsn_lock; #endif public: - /** rw-lock protecting buf */ - alignas(CPU_LEVEL1_DCACHE_LINESIZE) log_rwlock_t latch; + /** rw-lock protecting writes to buf; normal mtr_t::commit() + outside any log checkpoint is covered by a shared latch */ + alignas(CPU_LEVEL1_DCACHE_LINESIZE) log_rwlock latch; +private: + /** mutex protecting buf_free et al, together with latch */ + log_lsn_lock lsn_lock; +public: + /** first free offset within buf use; protected by lsn_lock */ + Atomic_relaxed buf_free; + /** number of write requests (to buf); protected by lsn_lock */ + size_t write_to_buf; + /** number of append_prepare_wait(); protected by lsn_lock */ + size_t waits; private: /** Last written LSN */ lsn_t write_lsn; @@ -227,20 +232,12 @@ private: /** Buffer for writing to resize_log; @see flush_buf */ byte *resize_flush_buf; - /** spin lock protecting lsn, buf_free in append_prepare() */ - alignas(CPU_LEVEL1_DCACHE_LINESIZE) pthread_mutex_t lsn_lock; - void init_lsn_lock() { pthread_mutex_init(&lsn_lock, LSN_LOCK_ATTR); } - void lock_lsn() { pthread_mutex_lock(&lsn_lock); } - void unlock_lsn() { pthread_mutex_unlock(&lsn_lock); } - void destroy_lsn_lock() { pthread_mutex_destroy(&lsn_lock); } + void init_lsn_lock() {lsn_lock.init(); } + void lock_lsn() { lsn_lock.wr_lock(); } + void unlock_lsn() {lsn_lock.wr_unlock(); } + void destroy_lsn_lock() { lsn_lock.destroy(); } public: - /** first free offset within buf use; protected by lsn_lock */ - Atomic_relaxed buf_free; - /** number of write requests (to buf); protected by exclusive lsn_lock */ - ulint write_to_buf; - /** number of waits in append_prepare(); protected by lsn_lock */ - ulint waits; /** recommended maximum size of buf, after which the buffer is flushed */ size_t max_buf_free; @@ -310,6 +307,9 @@ public: bool is_opened() const noexcept { return log.is_opened(); } + /** @return target write LSN to react on buf_free >= max_buf_free */ + inline lsn_t get_write_target() const; + /** @return LSN at which log resizing was started and is still in progress @retval 0 if no log resizing is in progress */ lsn_t resize_in_progress() const noexcept @@ -423,13 +423,14 @@ public: inline void persist(lsn_t lsn) noexcept; #endif - bool check_flush_or_checkpoint() const + bool check_for_checkpoint() const { - return UNIV_UNLIKELY - (check_flush_or_checkpoint_.load(std::memory_order_relaxed)); + return UNIV_UNLIKELY(need_checkpoint.load(std::memory_order_relaxed)); + } + void set_check_for_checkpoint(bool need= true) + { + need_checkpoint.store(need, std::memory_order_relaxed); } - void set_check_flush_or_checkpoint(bool flag= true) - { check_flush_or_checkpoint_.store(flag, std::memory_order_relaxed); } /** Make previous write_buf() durable and update flushed_to_disk_lsn. */ bool flush(lsn_t lsn) noexcept; @@ -450,8 +451,9 @@ public: private: /** Wait in append_prepare() for buffer to become available + @param lsn log sequence number to write up to @param ex whether log_sys.latch is exclusively locked */ - ATTRIBUTE_COLD static void append_prepare_wait(bool ex) noexcept; + ATTRIBUTE_COLD void append_prepare_wait(lsn_t lsn, bool ex) noexcept; public: /** Reserve space in the log buffer for appending data. @tparam pmem log_sys.is_pmem() diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index dadcd357ba8..583aa36269f 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -108,6 +108,14 @@ struct recv_dblwr_t byte* find_page(const page_id_t page_id, const fil_space_t *space= NULL, byte *tmp_buf= NULL); + /** Restore the first page of the given tablespace from + doublewrite buffer. + @param space_id tablespace identifier + @param name tablespace filepath + @param file tablespace file handle + @return whether the operation failed */ + bool restore_first_page(uint32_t space_id, const char *name, os_file_t file); + typedef std::deque > list; /** Recovered doublewrite buffer page frames */ @@ -281,12 +289,6 @@ private: @retval -1 if the page cannot be recovered due to corruption */ inline buf_block_t *recover_low(const map::iterator &p, mtr_t &mtr, buf_block_t *b, lsn_t init_lsn); - /** Attempt to initialize a page based on redo log records. - @param page_id page identifier - @return the recovered block - @retval nullptr if the page cannot be initialized based on log records - @retval -1 if the page cannot be recovered due to corruption */ - ATTRIBUTE_COLD buf_block_t *recover_low(const page_id_t page_id); /** All found log files (multiple ones are possible if we are upgrading from before MariaDB Server 10.5.1) */ @@ -431,15 +433,14 @@ public: /** @return whether log file corruption was found */ bool is_corrupt_log() const { return UNIV_UNLIKELY(found_corrupt_log); } - /** Attempt to initialize a page based on redo log records. + /** Read a page or recover it based on redo log records. @param page_id page identifier - @return the recovered block - @retval nullptr if the page cannot be initialized based on log records - @retval -1 if the page cannot be recovered due to corruption */ - buf_block_t *recover(const page_id_t page_id) - { - return UNIV_UNLIKELY(recovery_on) ? recover_low(page_id) : nullptr; - } + @param mtr mini-transaction + @param err error code + @return the requested block + @retval nullptr if the page cannot be accessed due to corruption */ + ATTRIBUTE_COLD + buf_block_t *recover(const page_id_t page_id, mtr_t *mtr, dberr_t *err); /** Try to recover a tablespace that was not readable earlier @param p iterator diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 81f1f2b0dc9..dc53abc3eb6 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -95,14 +95,8 @@ struct mtr_t { /** Commit a mini-transaction that is deleting or renaming a file. @param space tablespace that is being renamed or deleted @param name new file name (nullptr=the file will be deleted) - @param detached_handle if detached_handle != nullptr and if space is detached - during the function execution the file handle if its - node will be set to OS_FILE_CLOSED, and the previous - value of the file handle will be assigned to the - address, pointed by detached_handle. @return whether the operation succeeded */ - ATTRIBUTE_COLD bool commit_file(fil_space_t &space, const char *name, - pfs_os_file_t *detached_handle= nullptr); + ATTRIBUTE_COLD bool commit_file(fil_space_t &space, const char *name); /** Commit a mini-transaction that did not modify any pages, but generated some redo log on a higher level, such as @@ -111,7 +105,7 @@ struct mtr_t { This is to be used at log_checkpoint(). @param checkpoint_lsn the log sequence number of a checkpoint, or 0 @return current LSN */ - lsn_t commit_files(lsn_t checkpoint_lsn= 0); + ATTRIBUTE_COLD lsn_t commit_files(lsn_t checkpoint_lsn= 0); /** @return mini-transaction savepoint (current size of m_memo) */ ulint get_savepoint() const diff --git a/storage/innobase/include/row0ftsort.h b/storage/innobase/include/row0ftsort.h index 65508caf751..3ffa8243306 100644 --- a/storage/innobase/include/row0ftsort.h +++ b/storage/innobase/include/row0ftsort.h @@ -104,7 +104,10 @@ typedef UT_LIST_BASE_NODE_T(row_fts_token_t) fts_token_list_t; /** Structure stores information from string tokenization operation */ struct fts_tokenize_ctx { - ulint processed_len; /*!< processed string length */ + /** the processed string length in bytes + (when using the built-in tokenizer), + or the number of row_merge_fts_doc_tokenize_by_parser() calls */ + ulint processed_len; ulint init_pos; /*!< doc start position */ ulint buf_used; /*!< the sort buffer (ID) when tokenization stops, which @@ -115,6 +118,7 @@ struct fts_tokenize_ctx { ib_rbt_t* cached_stopword;/*!< in: stopword list */ dfield_t sort_field[FTS_NUM_FIELDS_SORT]; /*!< in: sort field */ + /** parsed tokens (when using an external parser) */ fts_token_list_t fts_token_list; fts_tokenize_ctx() : diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 2e5bdceb677..878d9c9f1a2 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -814,11 +814,6 @@ innobase_get_computed_value( const upd_t* update=NULL, bool ignore_warnings=false); -/** Get the computed value by supplying the base column values. -@param[in,out] table the table whose virtual column - template to be built */ -TABLE* innobase_init_vc_templ(dict_table_t* table); - /** Change dbname and table name in table->vc_templ. @param[in,out] table the table whose virtual column template dbname and tbname to be renamed. */ diff --git a/storage/innobase/include/row0purge.h b/storage/innobase/include/row0purge.h index 686bbaa7384..33ac8599036 100644 --- a/storage/innobase/include/row0purge.h +++ b/storage/innobase/include/row0purge.h @@ -24,8 +24,7 @@ Purge obsolete records Created 3/14/1997 Heikki Tuuri *******************************************************/ -#ifndef row0purge_h -#define row0purge_h +#pragma once #include "que0types.h" #include "btr0types.h" @@ -35,6 +34,7 @@ Created 3/14/1997 Heikki Tuuri #include "row0mysql.h" #include "mysqld.h" #include +#include class MDL_ticket; @@ -47,165 +47,70 @@ row_purge_step( que_thr_t* thr) /*!< in: query thread */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/** Info required to purge a record */ -struct trx_purge_rec_t +/** Purge worker context */ +struct purge_node_t { - /** Record to purge */ - trx_undo_rec_t *undo_rec; - /** File pointer to undo record */ + /** node type: QUE_NODE_PURGE */ + que_common_t common; + + /** DB_TRX_ID of the undo log record */ + trx_id_t trx_id; + /** DB_ROLL_PTR pointing to undo log record */ roll_ptr_t roll_ptr; -}; -/* Purge node structure */ + /** undo number of the record */ + undo_no_t undo_no; -struct purge_node_t{ - que_common_t common; /*!< node type: QUE_NODE_PURGE */ - /*----------------------*/ - /* Local storage for this graph node */ - roll_ptr_t roll_ptr;/* roll pointer to undo log record */ - - undo_no_t undo_no;/*!< undo number of the record */ - - ulint rec_type;/*!< undo log record type: TRX_UNDO_INSERT_REC, - ... */ -private: - /** latest unavailable table ID (do not bother looking up again) */ - table_id_t unavailable_table_id; - /** the latest modification of the table definition identified by - unavailable_table_id, or TRX_ID_MAX */ - trx_id_t def_trx_id; -public: - dict_table_t* table; /*!< table where purge is done */ - - ulint cmpl_info;/* compiler analysis info of an update */ - - upd_t* update; /*!< update vector for a clustered index - record */ - const dtuple_t* ref; /*!< NULL, or row reference to the next row to - handle */ - dtuple_t* row; /*!< NULL, or a copy (also fields copied to - heap) of the indexed fields of the row to - handle */ - dict_index_t* index; /*!< NULL, or the next index whose record should - be handled */ - mem_heap_t* heap; /*!< memory heap used as auxiliary storage for - row; this must be emptied after a successful - purge of a row */ - ibool found_clust;/*!< whether the clustered index record - determined by ref was found in the clustered - index, and we were able to position pcur on - it */ - btr_pcur_t pcur; /*!< persistent cursor used in searching the - clustered index record */ + /** record type: TRX_UNDO_INSERT_REC, ... */ + byte rec_type; + /** compiler analysis info of an update */ + byte cmpl_info; + /** whether the clustered index record determined by ref was found + in the clustered index of the table, and we were able to position + pcur on it */ + bool found_clust; #ifdef UNIV_DEBUG - /** whether the operation is in progress */ - bool in_progress; + /** whether the operation is in progress */ + bool in_progress= false; #endif - trx_id_t trx_id; /*!< trx id for this purging record */ + /** table where purge is done */ + dict_table_t *table= nullptr; + /** update vector for a clustered index record */ + upd_t *update; + /** row reference to the next row to handle, or nullptr */ + const dtuple_t *ref; + /** nullptr, or a deep copy of the indexed fields of the row to handle */ + dtuple_t *row; + /** nullptr, or the next index of table whose record should be handled */ + dict_index_t *index; + /** memory heap used as auxiliary storage; must be emptied between rows */ + mem_heap_t *heap; + /** persistent cursor to the clustered index record */ + btr_pcur_t pcur; - /** meta-data lock for the table name */ - MDL_ticket* mdl_ticket; + /** Undo recs to purge */ + std::queue undo_recs; - /** table id of the previous undo log record */ - table_id_t last_table_id; + /** map of table identifiers to table handles and meta-data locks */ + std::unordered_map> tables; - /** purge thread */ - THD* purge_thd; - - /** metadata lock holds for this number of undo log recs */ - int mdl_hold_recs; - - /** Undo recs to purge */ - std::queue undo_recs; - - /** Constructor */ - explicit purge_node_t(que_thr_t* parent) : - common(QUE_NODE_PURGE, parent), - unavailable_table_id(0), - table(NULL), - heap(mem_heap_create(256)), -#ifdef UNIV_DEBUG - in_progress(false), -#endif - mdl_ticket(NULL), - last_table_id(0), - purge_thd(NULL), - mdl_hold_recs(0) - { - } + /** Constructor */ + explicit purge_node_t(que_thr_t *parent) : + common(QUE_NODE_PURGE, parent), heap(mem_heap_create(256)), + tables(TRX_PURGE_TABLE_BUCKETS) {} #ifdef UNIV_DEBUG - /***********************************************************//** - Validate the persisent cursor. The purge node has two references - to the clustered index record - one via the ref member, and the - other via the persistent cursor. These two references must match - each other if the found_clust flag is set. - @return true if the persistent cursor is consistent with - the ref member.*/ - bool validate_pcur(); + /** Validate the persistent cursor. The purge node has two references + to the clustered index record: ref and pcur, which must match + each other if found_clust. + @return whether pcur is consistent with ref */ + bool validate_pcur(); #endif - /** Determine if a table should be skipped in purge. - @param[in] table_id table identifier - @return whether to skip the table lookup and processing */ - bool is_skipped(table_id_t id) const - { - return id == unavailable_table_id && trx_id <= def_trx_id; - } - - /** Remember that a table should be skipped in purge. - @param[in] id table identifier - @param[in] limit last transaction for which to skip */ - void skip(table_id_t id, trx_id_t limit) - { - DBUG_ASSERT(limit >= trx_id); - unavailable_table_id = id; - def_trx_id = limit; - } - /** Start processing an undo log record. */ inline void start(); - - /** Close the existing table and release the MDL for it. */ - void close_table() - { - last_table_id= 0; - if (!table) - { - ut_ad(!mdl_ticket); - return; - } - - innobase_reset_background_thd(purge_thd); - dict_table_close(table, false, purge_thd, mdl_ticket); - table= nullptr; - mdl_ticket= nullptr; - } - - - /** Retail mdl for the table id. - @param[in] table_id table id to be processed - @return true if retain mdl */ - bool retain_mdl(table_id_t table_id) - { - ut_ad(table_id); - if (last_table_id == table_id && mdl_hold_recs < 100) - { - ut_ad(table); - mdl_hold_recs++; - return true; - } - - mdl_hold_recs= 0; - close_table(); - return false; - } - - /** Reset the state at end @return the query graph parent */ - inline que_node_t *end(); + inline que_node_t *end(THD *); }; - -#endif diff --git a/storage/innobase/include/row0undo.h b/storage/innobase/include/row0undo.h index 4357a908ca3..ae067a8af4f 100644 --- a/storage/innobase/include/row0undo.h +++ b/storage/innobase/include/row0undo.h @@ -78,29 +78,15 @@ just in the case where the transaction modified the same record several times and another thread is currently doing the undo for successive versions of that index record. */ -/** Execution state of an undo node */ -enum undo_exec { - UNDO_NODE_FETCH_NEXT = 1, /*!< we should fetch the next - undo log record */ - /** rollback an insert into persistent table */ - UNDO_INSERT_PERSISTENT, - /** rollback an update (or delete) in a persistent table */ - UNDO_UPDATE_PERSISTENT, - /** rollback an insert into temporary table */ - UNDO_INSERT_TEMPORARY, - /** rollback an update (or delete) in a temporary table */ - UNDO_UPDATE_TEMPORARY, -}; - /** Undo node structure */ struct undo_node_t{ que_common_t common; /*!< node type: QUE_NODE_UNDO */ - undo_exec state; /*!< rollback execution state */ + bool is_temp;/*!< whether this is a temporary table */ trx_t* trx; /*!< trx for which undo is done */ roll_ptr_t roll_ptr;/*!< roll pointer to undo log record */ trx_undo_rec_t* undo_rec;/*!< undo log record */ undo_no_t undo_no;/*!< undo number of the record */ - ulint rec_type;/*!< undo log record type: TRX_UNDO_INSERT_REC, + byte rec_type;/*!< undo log record type: TRX_UNDO_INSERT_REC, ... */ trx_id_t new_trx_id; /*!< trx id to restore to clustered index record */ diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index b5320308e34..9734778bff6 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -501,10 +501,6 @@ Frees the data structures created in srv_init(). */ void srv_free(void); -/** Wake up the purge if there is work to do. */ -void -srv_wake_purge_thread_if_not_active(); - /******************************************************************//** Outputs to a file the output of the InnoDB Monitor. @return FALSE if not all information printed @@ -545,16 +541,6 @@ srv_que_task_enqueue_low( /*=====================*/ que_thr_t* thr); /*!< in: query thread */ -/** -Flag which is set, whenever innodb_purge_threads changes. -It is read and reset in srv_do_purge(). - -Thus it is Atomic_counter, not bool, since unprotected -reads are used. We just need an atomic with relaxed memory -order, to please Thread Sanitizer. -*/ -extern Atomic_counter srv_purge_thread_count_changed; - #ifdef UNIV_DEBUG /** @return whether purge or master task is active */ bool srv_any_background_activity(); diff --git a/storage/innobase/include/srw_lock.h b/storage/innobase/include/srw_lock.h index 1dca0cc1054..01067322a0a 100644 --- a/storage/innobase/include/srw_lock.h +++ b/storage/innobase/include/srw_lock.h @@ -34,7 +34,6 @@ this program; if not, write to the Free Software Foundation, Inc., # define SUX_LOCK_GENERIC /* Use dummy implementation for debugging purposes */ #endif -#ifdef SUX_LOCK_GENERIC /** An exclusive-only variant of srw_lock */ template class pthread_mutex_wrapper final @@ -70,7 +69,6 @@ template<> inline void pthread_mutex_wrapper::wr_lock() { if (!wr_lock_try()) wr_wait(); } # endif -#endif /** Futex-based mutex */ template @@ -541,7 +539,7 @@ public: /** @return whether any lock may be held by any thread */ bool is_locked_or_waiting() const noexcept { return lock.is_locked_or_waiting(); } - /** @return whether an exclusive lock may be held by any thread */ + /** @return whether a shared or exclusive lock may be held by any thread */ bool is_locked() const noexcept { return lock.is_locked(); } /** @return whether an exclusive lock may be held by any thread */ bool is_write_locked() const noexcept { return lock.is_write_locked(); } diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h index 79b5c294e2a..3ddd2e98fee 100644 --- a/storage/innobase/include/trx0purge.h +++ b/storage/innobase/include/trx0purge.h @@ -31,6 +31,7 @@ Created 3/26/1996 Heikki Tuuri #include "srw_lock.h" #include +#include /** Prepend the history list with an undo log. Remove the undo log segment from the rseg slot if it is too big for reuse. @@ -109,7 +110,8 @@ struct TrxUndoRsegsIterator { TrxUndoRsegsIterator(); /** Sets the next rseg to purge in purge_sys. Executed in the purge coordinator thread. - @return whether anything is to be purged */ + @retval false when nothing is to be purged + @retval true when purge_sys.rseg->latch was locked */ inline bool set_next(); private: @@ -126,6 +128,7 @@ private: /** The control structure used in the purge operation */ class purge_sys_t { + friend TrxUndoRsegsIterator; public: /** latch protecting view, m_enabled */ alignas(CPU_LEVEL1_DCACHE_LINESIZE) mutable srw_spin_lock latch; @@ -133,8 +136,14 @@ private: /** Read view at the start of a purge batch. Any encountered index records that are older than view will be removed. */ ReadViewBase view; + /** whether the subsystem has been initialized */ + bool m_initialized{false}; /** whether purge is enabled; protected by latch and std::atomic */ - std::atomic m_enabled; + std::atomic m_enabled{false}; +public: + /** whether purge is active (may hold table handles) */ + std::atomic m_active{false}; +private: /** number of pending stop() calls without resume() */ Atomic_counter m_paused; /** number of stop_SYS() calls without resume_SYS() */ @@ -147,7 +156,34 @@ private: /** Read view at the end of a purge batch (copied from view). Any undo pages containing records older than end_view may be freed. */ ReadViewBase end_view; + + struct hasher + { + size_t operator()(const page_id_t &id) const { return size_t(id.raw()); } + }; + + using unordered_map = + std::unordered_map= 8 + std::equal_to + /* GCC 4.8.5 would fail to find a matching allocator */ +#else + std::equal_to, + ut_allocator> +#endif + >; + /** map of buffer-fixed undo log pages processed during a purge batch */ + unordered_map pages; public: + /** @return the number of processed undo pages */ + size_t n_pages_handled() const { return pages.size(); } + + /** Look up an undo log page. + @param id undo page identifier + @return undo page + @retval nullptr in case the page is corrupted */ + buf_block_t *get_page(page_id_t id); + que_t* query; /*!< The query graph which will do the parallelized purge operation */ @@ -161,6 +197,9 @@ public: return undo_no <= other.undo_no; } + /** Free the undo pages up to this. */ + dberr_t free_history() const; + /** trx_t::no of the committed transaction */ trx_id_t trx_no; /** The record number within the committed transaction's undo @@ -172,13 +211,15 @@ public: committed transaction. */ iterator tail; /** The head of the purge queue; any older undo logs of committed - transactions may be discarded (history list truncation). */ + transactions may be discarded (history list truncation). + Protected by latch. */ iterator head; /*-----------------------------*/ bool next_stored; /*!< whether rseg holds the next record to purge */ trx_rseg_t* rseg; /*!< Rollback segment for the next undo record to purge */ +private: uint32_t page_no; /*!< Page number for the next undo record to purge, page number of the log header, if dummy record */ @@ -193,7 +234,7 @@ public: TrxUndoRsegsIterator rseg_iter; /*!< Iterator to get the next rseg to process */ - +public: purge_pq_t purge_queue; /*!< Binary min-heap, ordered on TrxUndoRsegs::trx_no. It is protected by the pq_mutex */ @@ -208,17 +249,6 @@ public: fil_space_t* last; } truncate; - /** Heap for reading the undo log records */ - mem_heap_t* heap; - /** - Constructor. - - Some members may require late initialisation, thus we just mark object as - uninitialised. Real initialisation happens in create(). - */ - - purge_sys_t(): m_enabled(false), heap(nullptr) {} - /** Create the instance */ void create(); @@ -231,12 +261,12 @@ public: bool paused() { return m_paused != 0; } - /** Enable purge at startup. Not protected by latch; the main thread - will wait for purge_sys.enabled() in srv_start() */ + /** Enable purge at startup. */ void coordinator_startup() { ut_ad(!enabled()); m_enabled.store(true, std::memory_order_relaxed); + wake_if_not_active(); } /** Disable purge at shutdown */ @@ -247,33 +277,56 @@ public: } /** @return whether the purge tasks are active */ - bool running() const; + static bool running(); + /** Stop purge during FLUSH TABLES FOR EXPORT. */ void stop(); /** Resume purge at UNLOCK TABLES after FLUSH TABLES FOR EXPORT */ void resume(); + /** Close and reopen all tables in case of a MDL conflict with DDL */ + dict_table_t *close_and_reopen(table_id_t id, THD *thd, MDL_ticket **mdl); private: - void wait_SYS(); - void wait_FTS(); + /** Suspend purge during a DDL operation on FULLTEXT INDEX tables */ + void wait_FTS(bool also_sys); public: /** Suspend purge in data dictionary tables */ - void stop_SYS(); + void stop_SYS() { m_SYS_paused++; } /** Resume purge in data dictionary tables */ static void resume_SYS(void *); - /** @return whether stop_SYS() is in effect */ - bool must_wait_SYS() const { return m_SYS_paused; } - /** check stop_SYS() */ - void check_stop_SYS() { if (must_wait_SYS()) wait_SYS(); } /** Pause purge during a DDL operation that could drop FTS_ tables. */ - void stop_FTS() { m_FTS_paused++; } + void stop_FTS(); /** Resume purge after stop_FTS(). */ void resume_FTS() { ut_d(const auto p=) m_FTS_paused--; ut_ad(p); } /** @return whether stop_SYS() is in effect */ bool must_wait_FTS() const { return m_FTS_paused; } - /** check stop_SYS() */ - void check_stop_FTS() { if (must_wait_FTS()) wait_FTS(); } + +private: + /** + Get the next record to purge and update the info in the purge system. + @param roll_ptr undo log pointer to the record + @return buffer-fixed reference to undo log record + @retval {nullptr,1} if the whole undo log can skipped in purge + @retval {nullptr,0} if nothing is left, or on corruption */ + inline trx_purge_rec_t get_next_rec(roll_ptr_t roll_ptr); + + /** Choose the next undo log to purge. + @return whether anything is to be purged */ + bool choose_next_log(); + + /** Update the last not yet purged history log info in rseg when + we have purged a whole undo log. Advances also purge_trx_no + past the purged log. */ + void rseg_get_next_history_log(); + +public: + /** + Fetch the next undo log record from the history list to purge. + @return buffer-fixed reference to undo log record + @retval {nullptr,1} if the whole undo log can skipped in purge + @retval {nullptr,0} if nothing is left, or on corruption */ + inline trx_purge_rec_t fetch_next_rec(); /** Determine if the history of a transaction is purgeable. @param trx_id transaction identifier @@ -308,6 +361,8 @@ public: template void clone_oldest_view() { + if (!also_end_view) + wait_FTS(true); latch.wr_lock(SRW_LOCK_CALL); trx_sys.clone_oldest_view(&view); if (also_end_view) @@ -316,8 +371,13 @@ public: latch.wr_unlock(); } - /** Update end_view at the end of a purge batch. */ - inline void clone_end_view(); + /** Wake up the purge threads if there is work to do. */ + void wake_if_not_active(); + + /** Release undo pages and update end_view at the end of a purge batch. + @retval false when nothing is to be purged + @retval true when purge_sys.rseg->latch was locked */ + inline void batch_cleanup(const iterator &head); struct view_guard { diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h index bb348d7ef8b..3d9b18689a7 100644 --- a/storage/innobase/include/trx0rec.h +++ b/storage/innobase/include/trx0rec.h @@ -28,32 +28,9 @@ Created 3/26/1996 Heikki Tuuri #include "trx0types.h" #include "row0types.h" -#include "mtr0mtr.h" -#include "rem0types.h" #include "page0types.h" -#include "row0log.h" #include "que0types.h" -/***********************************************************************//** -Copies the undo record to the heap. -@param undo_rec record in an undo log page -@param heap memory heap -@return copy of undo_rec -@retval nullptr if the undo log record is corrupted */ -inline trx_undo_rec_t* trx_undo_rec_copy(const trx_undo_rec_t *undo_rec, - mem_heap_t *heap) -{ - const size_t offset= ut_align_offset(undo_rec, srv_page_size); - const size_t end= mach_read_from_2(undo_rec); - if (end <= offset || end >= srv_page_size - FIL_PAGE_DATA_END) - return nullptr; - const size_t len= end - offset; - trx_undo_rec_t *rec= static_cast - (mem_heap_dup(heap, undo_rec, len)); - mach_write_to_2(rec, len); - return rec; -} - /**********************************************************************//** Reads the undo log record number. @return undo no */ @@ -74,9 +51,9 @@ const byte* trx_undo_rec_get_pars( /*==================*/ const trx_undo_rec_t* undo_rec, /*!< in: undo log record */ - ulint* type, /*!< out: undo record type: + byte* type, /*!< out: undo record type: TRX_UNDO_INSERT_REC, ... */ - ulint* cmpl_info, /*!< out: compiler info, relevant only + byte* cmpl_info, /*!< out: compiler info, relevant only for update type records */ bool* updated_extern, /*!< out: true if we updated an externally stored fild */ diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index d3055983177..7a62c9f0167 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -901,8 +901,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 1da8b340e0d..7682932392e 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -1105,6 +1105,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/include/trx0types.h b/storage/innobase/include/trx0types.h index d6ce902977c..bfa2adc0115 100644 --- a/storage/innobase/include/trx0types.h +++ b/storage/innobase/include/trx0types.h @@ -47,6 +47,7 @@ static constexpr uint32_t TRX_SYS_SPACE= 0; static const ulint TRX_MAGIC_N = 91118598; constexpr uint innodb_purge_threads_MAX= 32; +constexpr uint innodb_purge_batch_size_MAX= 5000; /** Transaction states (trx_t::state) */ enum trx_state_t { @@ -107,8 +108,22 @@ typedef byte trx_undo_rec_t; /* @} */ +/** Info required to purge a record */ +struct trx_purge_rec_t +{ + /** Undo log record, or nullptr (roll_ptr!=0 if the log can be skipped) */ + const trx_undo_rec_t *undo_rec; + /** File pointer to undo_rec */ + roll_ptr_t roll_ptr; +}; + typedef std::vector > trx_ids_t; +/** Number of std::unordered_map hash buckets expected to be needed +for table IDs in a purge batch. GNU libstdc++ would default to 1 and +enlarge and rehash on demand. */ +static constexpr size_t TRX_PURGE_TABLE_BUCKETS= 128; + /** The number of rollback segments; rollback segment id must fit in the 7 bits reserved for it in DB_ROLL_PTR. */ static constexpr unsigned TRX_SYS_N_RSEGS= 128; diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index 37ca85b28d3..2954cf73ecc 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -116,31 +116,16 @@ trx_undo_page_get_next_rec(const buf_block_t *undo_page, uint16_t rec, trx_undo_rec_t* trx_undo_get_prev_rec(buf_block_t *&block, uint16_t rec, uint32_t page_no, uint16_t offset, bool shared, mtr_t *mtr); -/** Get the next record in an undo log. -@param[in,out] block undo log page -@param[in] rec undo record offset in the page -@param[in] page_no undo log header page number -@param[in] offset undo log header offset on page -@param[in,out] mtr mini-transaction -@return undo log record, the page latched, NULL if none */ -trx_undo_rec_t* -trx_undo_get_next_rec(const buf_block_t *&block, uint16_t rec, - uint32_t page_no, uint16_t offset, mtr_t *mtr); -/** Get the first record in an undo log. -@param[in] space undo log header space -@param[in] page_no undo log header page number -@param[in] offset undo log header offset on page -@param[in] mode latching mode: RW_S_LATCH or RW_X_LATCH -@param[out] block undo log page -@param[in,out] mtr mini-transaction -@param[out] err error code -@return undo log record, the page latched -@retval nullptr if none */ +/** Get the first undo log record on a page. +@param[in] block undo log page +@param[in] page_no undo log header page number +@param[in] offset undo log header page offset +@return pointer to first record +@retval nullptr if none exists */ trx_undo_rec_t* -trx_undo_get_first_rec(const fil_space_t &space, uint32_t page_no, - uint16_t offset, ulint mode, const buf_block_t*& block, - mtr_t *mtr, dberr_t *err); +trx_undo_page_get_first_rec(const buf_block_t *block, uint32_t page_no, + uint16_t offset); /** Initialize an undo log page. NOTE: This corresponds to a redo log record and must not be changed! @@ -308,16 +293,16 @@ class UndorecApplier { /** Undo log block page id */ page_id_t page_id; - /** Undo log record pointer */ + /** Pointer to within undo log record */ const trx_undo_rec_t *undo_rec; - /** Offset of the undo log record within the block */ + /** Undo log record type */ + byte type; + /** compiler information */ + byte cmpl_info; + /** page_offset(undo_rec) of the start of undo_rec */ uint16_t offset; /** Transaction id of the undo log */ const trx_id_t trx_id; - /** Undo log record type */ - ulint type; - /** compiler information */ - ulint cmpl_info; /** Update vector */ upd_t *update; /** memory heap which can be used to build previous version of @@ -338,15 +323,10 @@ public: page_id= next_page_id; } - /** Assign the undo log record and offset */ - inline void assign_rec(const buf_block_t &block, uint16_t offset); - - uint16_t get_offset() const { return offset; } - page_id_t get_page_id() const { return page_id; } /** Handle the DML undo log and apply it on online indexes */ - inline void apply_undo_rec(); + inline void apply_undo_rec(const trx_undo_rec_t *rec); ~UndorecApplier() { @@ -368,12 +348,7 @@ private: /** Check whether the given roll pointer is generated by the current undo log record information stored. @return true if roll pointer matches with current undo log info */ - bool is_same(roll_ptr_t roll_ptr) const - { - uint16_t offset= static_cast(roll_ptr); - uint32_t page_no= static_cast(roll_ptr >> 16); - return page_no == page_id.page_no() && offset == this->offset; - } + inline bool is_same(roll_ptr_t roll_ptr) const; /** Clear the undo log record information */ void clear_undo_rec() diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index e2b338fa106..0f2d5380935 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1812,8 +1812,14 @@ func_exit: } else if (!wait_lock->is_waiting()) { - wait_lock= nullptr; - goto func_exit; + wait_lock= trx->lock.wait_lock; + if (!wait_lock) + goto func_exit; + if (!wait_lock->is_waiting()) + { + wait_lock= nullptr; + goto func_exit; + } } if (wait_lock->is_table()) @@ -3934,6 +3940,8 @@ static void lock_table_dequeue(lock_t *in_lock, bool owns_wait_mutex) dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode, bool no_wait) { + ut_ad(!dict_sys.frozen()); + mem_heap_t *heap= mem_heap_create(512); sel_node_t *node= sel_node_create(heap); que_thr_t *thr= pars_complete_graph_for_exec(node, trx, heap, nullptr); @@ -3970,6 +3978,36 @@ run_again: return err; } +/** Lock the child tables of a table. +@param table parent table +@param trx transaction +@return error code */ +dberr_t lock_table_children(dict_table_t *table, trx_t *trx) +{ + dict_sys.freeze(SRW_LOCK_CALL); + std::vector children; + + for (auto f : table->referenced_set) + if (dict_table_t *child= f->foreign_table) + { + child->acquire(); + children.emplace_back(child); + } + dict_sys.unfreeze(); + + dberr_t err= DB_SUCCESS; + + for (auto child : children) + if ((err= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS) + break; + + for (auto child : children) + child->release(); + + return err; +} + + /** Exclusively lock the data dictionary tables. @param trx dictionary transaction @return error code diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 635054870b7..f3deeca9381 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -99,6 +99,7 @@ bool log_t::create() /* LSN 0 and 1 are reserved; @see buf_page_t::oldest_modification_ */ lsn.store(FIRST_LSN, std::memory_order_relaxed); flushed_to_disk_lsn.store(FIRST_LSN, std::memory_order_relaxed); + need_checkpoint.store(true, std::memory_order_relaxed); write_lsn= FIRST_LSN; #ifndef HAVE_PMEM @@ -123,18 +124,17 @@ bool log_t::create() TRASH_ALLOC(flush_buf, buf_size); checkpoint_buf= static_cast(aligned_malloc(4096, 4096)); memset_aligned<4096>(checkpoint_buf, 0, 4096); + max_buf_free= buf_size / LOG_BUF_FLUSH_RATIO - LOG_BUF_FLUSH_MARGIN; #else ut_ad(!checkpoint_buf); ut_ad(!buf); ut_ad(!flush_buf); + max_buf_free= 1; #endif latch.SRW_LOCK_INIT(log_latch_key); init_lsn_lock(); - max_buf_free= buf_size / LOG_BUF_FLUSH_RATIO - LOG_BUF_FLUSH_MARGIN; - set_check_flush_or_checkpoint(); - last_checkpoint_lsn= FIRST_LSN; log_capacity= 0; max_modified_age_async= 0; @@ -235,6 +235,7 @@ void log_t::attach_low(log_file_t file, os_offset_t size) log.close(); mprotect(ptr, size_t(size), PROT_READ); buf= static_cast(ptr); + max_buf_free= size; # if defined __linux__ || defined _WIN32 set_block_size(CPU_LEVEL1_DCACHE_LINESIZE); # endif @@ -263,6 +264,7 @@ void log_t::attach_low(log_file_t file, os_offset_t size) TRASH_ALLOC(buf, buf_size); TRASH_ALLOC(flush_buf, buf_size); + max_buf_free= buf_size / LOG_BUF_FLUSH_RATIO - LOG_BUF_FLUSH_MARGIN; #endif #if defined __linux__ || defined _WIN32 @@ -837,8 +839,8 @@ template inline lsn_t log_t::write_buf() noexcept #ifndef SUX_LOCK_GENERIC ut_ad(latch.is_write_locked()); #endif - ut_ad(!srv_read_only_mode); ut_ad(!is_pmem()); + ut_ad(!srv_read_only_mode); const lsn_t lsn{get_lsn(std::memory_order_relaxed)}; @@ -873,7 +875,7 @@ template inline lsn_t log_t::write_buf() noexcept ... /* TODO: Update the LSN and adjust other code. */ #else /* The rest of the block will be written as garbage. - (We want to avoid memset() while holding mutex.) + (We want to avoid memset() while holding exclusive log_sys.latch) This block will be overwritten later, once records beyond the current LSN are generated. */ # ifdef HAVE_valgrind @@ -910,6 +912,7 @@ template inline lsn_t log_t::write_buf() noexcept write_lsn= lsn; } + set_check_for_checkpoint(false); return lsn; } @@ -951,8 +954,9 @@ wait and check if an already running write is covering the request. void log_write_up_to(lsn_t lsn, bool durable, const completion_callback *callback) { - ut_ad(!srv_read_only_mode); + ut_ad(!srv_read_only_mode || (log_sys.buf_free < log_sys.max_buf_free)); ut_ad(lsn != LSN_MAX); + ut_ad(lsn != 0); ut_ad(lsn <= log_sys.get_lsn()); #ifdef HAVE_PMEM @@ -1001,7 +1005,6 @@ repeat: @param durable whether to wait for a durable write to complete */ void log_buffer_flush_to_disk(bool durable) { - ut_ad(!srv_read_only_mode); log_write_up_to(log_sys.get_lsn(std::memory_order_acquire), durable); } @@ -1033,16 +1036,6 @@ ATTRIBUTE_COLD void log_write_and_flush() #endif } -/******************************************************************** - -Tries to establish a big enough margin of free space in the log buffer, such -that a new log entry can be catenated without an immediate need for a flush. */ -ATTRIBUTE_COLD static void log_flush_margin() -{ - if (log_sys.buf_free > log_sys.max_buf_free) - log_buffer_flush_to_disk(false); -} - /****************************************************************//** Tries to establish a big enough margin of free space in the log, such that a new log entry can be catenated without an immediate need for a @@ -1050,12 +1043,12 @@ checkpoint. NOTE: this function may only be called if the calling thread owns no synchronization objects! */ ATTRIBUTE_COLD static void log_checkpoint_margin() { - while (log_sys.check_flush_or_checkpoint()) + while (log_sys.check_for_checkpoint()) { log_sys.latch.rd_lock(SRW_LOCK_CALL); ut_ad(!recv_no_log_write); - if (!log_sys.check_flush_or_checkpoint()) + if (!log_sys.check_for_checkpoint()) { func_exit: log_sys.latch.rd_unlock(); @@ -1071,7 +1064,7 @@ func_exit: #ifndef DBUG_OFF skip_checkpoint: #endif - log_sys.set_check_flush_or_checkpoint(false); + log_sys.set_check_for_checkpoint(false); goto func_exit; } @@ -1085,30 +1078,17 @@ func_exit: } } -/** -Checks that there is enough free space in the log to start a new query step. -Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this -function may only be called if the calling thread owns no synchronization -objects! */ -ATTRIBUTE_COLD void log_check_margins() -{ - do - { - log_flush_margin(); - log_checkpoint_margin(); - ut_ad(!recv_no_log_write); - } - while (log_sys.check_flush_or_checkpoint()); -} - /** Wait for a log checkpoint if needed. NOTE that this function may only be called while not holding any synchronization objects except dict_sys.latch. */ void log_free_check() { ut_ad(!lock_sys.is_writer()); - if (log_sys.check_flush_or_checkpoint()) - log_check_margins(); + if (log_sys.check_for_checkpoint()) + { + ut_ad(!recv_no_log_write); + log_checkpoint_margin(); + } } extern void buf_resize_shutdown(); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index f2b2850e910..5880ae56670 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -821,7 +821,22 @@ processed: filename= tbl_name + 1; } } - space->add(filename, OS_FILE_CLOSED, size, false, false); + pfs_os_file_t handle= OS_FILE_CLOSED; + if (srv_operation == SRV_OPERATION_RESTORE) + { + /* During mariadb-backup --backup, a table could be renamed, + created and dropped, and we may be missing the file at this + point of --prepare. Try to create the file if it does not exist + already. If the file exists, we'll pass handle=OS_FILE_CLOSED + and the file will be opened normally in fil_space_t::acquire() + inside recv_sys_t::recover_deferred(). */ + bool success; + handle= os_file_create(innodb_data_file_key, filename, + OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT | + OS_FILE_ON_ERROR_SILENT, + OS_FILE_AIO, OS_DATA_FILE, false, &success); + } + space->add(filename, handle, size, false, false); space->recv_size= it->second.size; space->size_in_header= size; return space; @@ -1146,7 +1161,8 @@ static void fil_name_process(const char *name, ulint len, uint32_t space_id, file_name_t& f = p.first->second; - if (auto d = deferred_spaces.find(space_id)) { + auto d = deferred_spaces.find(space_id); + if (d) { if (deleted) { d->deleted = true; goto got_deleted; @@ -1219,7 +1235,16 @@ same_space: FILE_* record. */ ut_ad(space == NULL); - if (srv_force_recovery) { + if (srv_operation == SRV_OPERATION_RESTORE && d + && ftype == FILE_RENAME) { +rename: + d->file_name = fname.name; + f.name = fname.name; + break; + } + + if (srv_force_recovery + || srv_operation == SRV_OPERATION_RESTORE) { /* Without innodb_force_recovery, missing tablespaces will only be reported in @@ -1238,7 +1263,11 @@ same_space: break; case FIL_LOAD_DEFER: - /** Skip the deferred spaces + if (d && ftype == FILE_RENAME + && srv_operation == SRV_OPERATION_RESTORE) { + goto rename; + } + /* Skip the deferred spaces when lsn is already processed */ if (!if_exists) { deferred_spaces.add( @@ -2318,7 +2347,7 @@ struct recv_ring : public recv_buf { const size_t s(*this - start); ut_ad(s + len <= srv_page_size); - if (!log_sys.is_encrypted()) + if (!len || !log_sys.is_encrypted()) { if (start.ptr + s == ptr && ptr + len <= end()) return ptr; @@ -3115,7 +3144,7 @@ static buf_block_t *recv_recover_page(buf_block_t *block, mtr_t &mtr, skipped_after_init = false; ut_ad(end_lsn == page_lsn); if (end_lsn != page_lsn) { - sql_print_warning( + sql_print_information( "InnoDB: The last skipped log record" " LSN " LSN_PF " is not equal to page LSN " LSN_PF, @@ -3655,33 +3684,70 @@ inline buf_block_t *recv_sys_t::recover_low(const map::iterator &p, mtr_t &mtr, return block ? block : reinterpret_cast(-1); } -/** Attempt to initialize a page based on redo log records. +/** Read a page or recover it based on redo log records. @param page_id page identifier -@return recovered block -@retval nullptr if the page cannot be initialized based on log records */ -ATTRIBUTE_COLD buf_block_t *recv_sys_t::recover_low(const page_id_t page_id) +@param mtr mini-transaction +@param err error code +@return the requested block +@retval nullptr if the page cannot be accessed due to corruption */ +ATTRIBUTE_COLD +buf_block_t * +recv_sys_t::recover(const page_id_t page_id, mtr_t *mtr, dberr_t *err) { + if (!recovery_on) + must_read: + return buf_page_get_gen(page_id, 0, RW_S_LATCH, nullptr, BUF_GET, mtr, + err); + mysql_mutex_lock(&mutex); map::iterator p= pages.find(page_id); - if (p != pages.end() && !p->second.being_processed && p->second.skip_read) + if (p == pages.end() || p->second.being_processed || !p->second.skip_read) { - p->second.being_processed= 1; - const lsn_t init_lsn{mlog_init.last(page_id)}; mysql_mutex_unlock(&mutex); - buf_block_t *free_block= buf_LRU_get_free_block(have_no_mutex); - mtr_t mtr; - buf_block_t *block= recover_low(p, mtr, free_block, init_lsn); - p->second.being_processed= -1; - ut_ad(!block || block == reinterpret_cast(-1) || - block == free_block); - if (UNIV_UNLIKELY(!block)) - buf_pool.free_block(free_block); - return block; + goto must_read; } + p->second.being_processed= 1; + const lsn_t init_lsn{mlog_init.last(page_id)}; mysql_mutex_unlock(&mutex); - return nullptr; + buf_block_t *free_block= buf_LRU_get_free_block(have_no_mutex); + buf_block_t *block; + { + mtr_t local_mtr; + block= recover_low(p, local_mtr, free_block, init_lsn); + } + p->second.being_processed= -1; + if (UNIV_UNLIKELY(!block)) + { + buf_pool.free_block(free_block); + goto must_read; + } + else if (block == reinterpret_cast(-1)) + { + corrupted: + if (err) + *err= DB_CORRUPTION; + return nullptr; + } + + ut_ad(block == free_block); + auto s= block->page.fix(); + ut_ad(s >= buf_page_t::FREED); + /* The block may be write-fixed at this point because we are not + holding a latch, but it must not be read-fixed. */ + ut_ad(s < buf_page_t::READ_FIX || s >= buf_page_t::WRITE_FIX); + if (s < buf_page_t::UNFIXED) + { + mysql_mutex_lock(&buf_pool.mutex); + block->page.unfix(); + buf_LRU_free_page(&block->page, true); + mysql_mutex_unlock(&buf_pool.mutex); + goto corrupted; + } + + mtr->page_lock(block, RW_S_LATCH); + return block; } inline fil_space_t *fil_system_t::find(const char *path) const @@ -3922,7 +3988,6 @@ static bool recv_scan_log(bool last_phase) const size_t block_size_1{log_sys.get_block_size() - 1}; mysql_mutex_lock(&recv_sys.mutex); - ut_d(recv_sys.after_apply= last_phase); if (!last_phase) recv_sys.clear(); else @@ -4131,6 +4196,7 @@ static bool recv_scan_log(bool last_phase) recv_sys.lsn= rewound_lsn; } func_exit: + ut_d(recv_sys.after_apply= last_phase); mysql_mutex_unlock(&recv_sys.mutex); DBUG_RETURN(!store); } @@ -4726,6 +4792,14 @@ byte *recv_dblwr_t::find_page(const page_id_t page_id, if (page_get_page_no(page) != page_id.page_no() || page_get_space_id(page) != page_id.space()) continue; + if (page_id.page_no() == 0) + { + uint32_t flags= mach_read_from_4( + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); + if (!fil_space_t::is_valid_flags(flags, page_id.space())) + continue; + } + const lsn_t lsn= mach_read_from_8(page + FIL_PAGE_LSN); if (lsn <= max_lsn || !validate_page(page_id, page, space, tmp_buf)) @@ -4734,9 +4808,38 @@ byte *recv_dblwr_t::find_page(const page_id_t page_id, memset(page + FIL_PAGE_LSN, 0, 8); continue; } + + ut_a(page_get_page_no(page) == page_id.page_no()); max_lsn= lsn; result= page; } return result; } + +bool recv_dblwr_t::restore_first_page(uint32_t space_id, const char *name, + os_file_t file) +{ + const page_id_t page_id(space_id, 0); + const byte* page= find_page(page_id); + if (!page) + { + /* If the first page of the given user tablespace is not there + in the doublewrite buffer, then the recovery is going to fail + now. Hence this is treated as error. */ + ib::error() + << "Corrupted page " << page_id << " of datafile '" + << name <<"' could not be found in the doublewrite buffer."; + return true; + } + + ulint physical_size= fil_space_t::physical_size( + mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS)); + ib::info() << "Restoring page " << page_id << " of datafile '" + << name << "' from the doublewrite buffer. Writing " + << physical_size << " bytes into file '" << name << "'"; + + return os_file_write( + IORequestWrite, name, file, page, 0, physical_size) != + DB_SUCCESS; +} diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 37dbeb7eb7c..b3a1adb76b0 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -307,6 +307,22 @@ void mtr_t::release() m_memo.clear(); } +inline lsn_t log_t::get_write_target() const +{ +#ifndef SUX_LOCK_GENERIC + ut_ad(latch.is_locked()); +#endif + if (UNIV_LIKELY(buf_free < max_buf_free)) + return 0; + ut_ad(!is_pmem()); + /* The LSN corresponding to the end of buf is + write_lsn - (first_lsn & 4095) + buf_free, + but we use simpler arithmetics to return a smaller write target in + order to minimize waiting in log_write_up_to(). */ + ut_ad(max_buf_free >= 4096 * 4); + return write_lsn + max_buf_free / 2; +} + /** Commit a mini-transaction. */ void mtr_t::commit() { @@ -329,6 +345,7 @@ void mtr_t::commit() std::pair lsns{do_write()}; process_freed_pages(); size_t modified= 0; + const lsn_t write_lsn= log_sys.get_write_target(); if (m_made_dirty) { @@ -406,7 +423,8 @@ void mtr_t::commit() break; default: buf_page_t *bpage= static_cast(slot.object); - const auto s= bpage->unfix(); + ut_d(const auto s=) + bpage->unfix(); if (slot.type & MTR_MEMO_MODIFY) { ut_ad(slot.type == MTR_MEMO_PAGE_X_MODIFY || @@ -418,13 +436,10 @@ void mtr_t::commit() ut_ad(s < buf_page_t::READ_FIX); ut_ad(mach_read_from_8(bpage->frame + FIL_PAGE_LSN) <= m_commit_lsn); - if (s >= buf_page_t::UNFIXED) - { - mach_write_to_8(bpage->frame + FIL_PAGE_LSN, m_commit_lsn); - if (UNIV_LIKELY_NULL(bpage->zip.data)) - memcpy_aligned<8>(FIL_PAGE_LSN + bpage->zip.data, - FIL_PAGE_LSN + bpage->frame, 8); - } + mach_write_to_8(bpage->frame + FIL_PAGE_LSN, m_commit_lsn); + if (UNIV_LIKELY_NULL(bpage->zip.data)) + memcpy_aligned<8>(FIL_PAGE_LSN + bpage->zip.data, + FIL_PAGE_LSN + bpage->frame, 8); modified++; } switch (auto latch= slot.type & ~MTR_MEMO_MODIFY) { @@ -449,6 +464,9 @@ void mtr_t::commit() if (UNIV_UNLIKELY(lsns.second != PAGE_FLUSH_NO)) buf_flush_ahead(m_commit_lsn, lsns.second == PAGE_FLUSH_SYNC); + + if (UNIV_UNLIKELY(write_lsn != 0)) + log_write_up_to(write_lsn, false); } else { @@ -585,7 +603,7 @@ void mtr_t::commit_shrink(fil_space_t &space) mysql_mutex_lock(&fil_system.mutex); ut_ad(space.is_being_truncated); - ut_ad(space.is_stopping()); + ut_ad(space.is_stopping_writes()); space.clear_stopping(); space.is_being_truncated= false; mysql_mutex_unlock(&fil_system.mutex); @@ -597,14 +615,8 @@ void mtr_t::commit_shrink(fil_space_t &space) /** Commit a mini-transaction that is deleting or renaming a file. @param space tablespace that is being renamed or deleted @param name new file name (nullptr=the file will be deleted) -@param detached_handle if detached_handle != nullptr and if space is detached - during the function execution the file handle if its - node will be set to OS_FILE_CLOSED, and the previous - value of the file handle will be assigned to the - address, pointed by detached_handle. @return whether the operation succeeded */ -bool mtr_t::commit_file(fil_space_t &space, const char *name, - pfs_os_file_t *detached_handle) +bool mtr_t::commit_file(fil_space_t &space, const char *name) { ut_ad(is_active()); ut_ad(!high_level_read_only); @@ -654,7 +666,7 @@ bool mtr_t::commit_file(fil_space_t &space, const char *name, m_latch_ex= false; char *old_name= space.chain.start->name; - bool success; + bool success= true; if (name) { @@ -668,37 +680,6 @@ bool mtr_t::commit_file(fil_space_t &space, const char *name, mysql_mutex_unlock(&fil_system.mutex); ut_free(old_name); } - else - { - /* Remove any additional files. */ - if (char *cfg_name= fil_make_filepath(old_name, - fil_space_t::name_type{}, CFG, - false)) - { - os_file_delete_if_exists(innodb_data_file_key, cfg_name, nullptr); - ut_free(cfg_name); - } - - if (FSP_FLAGS_HAS_DATA_DIR(space.flags)) - RemoteDatafile::delete_link_file(space.name()); - - /* Remove the directory entry. The file will actually be deleted - when our caller closes the handle. */ - os_file_delete(innodb_data_file_key, old_name); - - mysql_mutex_lock(&fil_system.mutex); - /* Sanity checks after reacquiring fil_system.mutex */ - ut_ad(&space == fil_space_get_by_id(space.id)); - ut_ad(!space.referenced()); - ut_ad(space.is_stopping()); - - pfs_os_file_t handle = fil_system.detach(&space, true); - if (detached_handle) - *detached_handle = handle; - mysql_mutex_unlock(&fil_system.mutex); - - success= true; - } mysql_mutex_unlock(&buf_pool.flush_list_mutex); release_resources(); @@ -713,7 +694,7 @@ The caller must hold exclusive log_sys.latch. This is to be used at log_checkpoint(). @param checkpoint_lsn the log sequence number of a checkpoint, or 0 @return current LSN */ -lsn_t mtr_t::commit_files(lsn_t checkpoint_lsn) +ATTRIBUTE_COLD lsn_t mtr_t::commit_files(lsn_t checkpoint_lsn) { #ifndef SUX_LOCK_GENERIC ut_ad(log_sys.latch.is_write_locked()); @@ -872,26 +853,26 @@ ATTRIBUTE_COLD static void log_overwrite_warning(lsn_t lsn) } /** Wait in append_prepare() for buffer to become available +@param lsn log sequence number to write up to @param ex whether log_sys.latch is exclusively locked */ -ATTRIBUTE_COLD void log_t::append_prepare_wait(bool ex) noexcept +ATTRIBUTE_COLD void log_t::append_prepare_wait(lsn_t lsn, bool ex) noexcept { - log_sys.waits++; - log_sys.unlock_lsn(); + waits++; + unlock_lsn(); if (ex) - log_sys.latch.wr_unlock(); + latch.wr_unlock(); else - log_sys.latch.rd_unlock(); + latch.rd_unlock(); - DEBUG_SYNC_C("log_buf_size_exceeded"); - log_buffer_flush_to_disk(log_sys.is_pmem()); + log_write_up_to(lsn, is_pmem()); if (ex) - log_sys.latch.wr_lock(SRW_LOCK_CALL); + latch.wr_lock(SRW_LOCK_CALL); else - log_sys.latch.rd_lock(SRW_LOCK_CALL); + latch.rd_lock(SRW_LOCK_CALL); - log_sys.lock_lsn(); + lock_lsn(); } /** Reserve space in the log buffer for appending data. @@ -910,34 +891,30 @@ std::pair log_t::append_prepare(size_t size, bool ex) noexcept # endif #endif ut_ad(pmem == is_pmem()); - const lsn_t checkpoint_margin{last_checkpoint_lsn + log_capacity - size}; - const size_t avail{(pmem ? size_t(capacity()) : buf_size) - size}; lock_lsn(); write_to_buf++; - for (ut_d(int count= 50); - UNIV_UNLIKELY((pmem - ? size_t(get_lsn() - - get_flushed_lsn(std::memory_order_relaxed)) - : size_t{buf_free}) > avail); ) + const lsn_t l{lsn.load(std::memory_order_relaxed)}, end_lsn{l + size}; + size_t b{buf_free}; + + if (UNIV_UNLIKELY(pmem + ? (end_lsn - + get_flushed_lsn(std::memory_order_relaxed)) > capacity() + : b + size >= buf_size)) { - append_prepare_wait(ex); - ut_ad(count--); + append_prepare_wait(l, ex); + b= buf_free; } - const lsn_t l{lsn.load(std::memory_order_relaxed)}; - lsn.store(l + size, std::memory_order_relaxed); - const size_t b{buf_free}; - size_t new_buf_free{b}; - new_buf_free+= size; + lsn.store(end_lsn, std::memory_order_relaxed); + size_t new_buf_free= b + size; if (pmem && new_buf_free >= file_size) new_buf_free-= size_t(capacity()); buf_free= new_buf_free; unlock_lsn(); - if (UNIV_UNLIKELY(l > checkpoint_margin) || - (!pmem && b >= max_buf_free)) - set_check_flush_or_checkpoint(); + if (UNIV_UNLIKELY(end_lsn >= last_checkpoint_lsn + log_capacity)) + set_check_for_checkpoint(); return {l, &buf[b]}; } @@ -962,7 +939,7 @@ static mtr_t::page_flush_ahead log_close(lsn_t lsn) noexcept else if (UNIV_LIKELY(checkpoint_age <= log_sys.max_checkpoint_age)) return mtr_t::PAGE_FLUSH_ASYNC; - log_sys.set_check_flush_or_checkpoint(); + log_sys.set_check_for_checkpoint(); return mtr_t::PAGE_FLUSH_SYNC; } @@ -1182,9 +1159,6 @@ inline void log_t::resize_write(lsn_t lsn, const byte *end, size_t len, } } -/** Write the mini-transaction log to the redo log buffer. -@param len number of bytes to write -@return {start_lsn,flush_ahead} */ std::pair mtr_t::finish_write(size_t len) { diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 46f7ceecf65..86ff9c549bd 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -4164,7 +4164,6 @@ bool fil_node_t::read_page0() != DB_SUCCESS) { sql_print_error("InnoDB: Unable to read first page of file %s", name); -corrupted: aligned_free(page); return false; } @@ -4181,25 +4180,35 @@ corrupted: if (!fil_space_t::is_valid_flags(flags, space->id)) { uint32_t cflags= fsp_flags_convert_from_101(flags); - if (cflags == UINT32_MAX) + if (cflags != UINT32_MAX) { -invalid: - ib::error() << "Expected tablespace flags " - << ib::hex(space->flags) - << " but found " << ib::hex(flags) - << " in the file " << name; - goto corrupted; + uint32_t cf= cflags & ~FSP_FLAGS_MEM_MASK; + uint32_t sf= space->flags & ~FSP_FLAGS_MEM_MASK; + + if (fil_space_t::is_flags_equal(cf, sf) || + fil_space_t::is_flags_equal(sf, cf)) + { + flags= cflags; + goto flags_ok; + } } - uint32_t cf= cflags & ~FSP_FLAGS_MEM_MASK; - uint32_t sf= space->flags & ~FSP_FLAGS_MEM_MASK; - - if (!fil_space_t::is_flags_equal(cf, sf) && - !fil_space_t::is_flags_equal(sf, cf)) - goto invalid; - flags= cflags; + aligned_free(page); + goto invalid; } + if (!fil_space_t::is_flags_equal((flags & ~FSP_FLAGS_MEM_MASK), + (space->flags & ~FSP_FLAGS_MEM_MASK)) && + !fil_space_t::is_flags_equal((space->flags & ~FSP_FLAGS_MEM_MASK), + (flags & ~FSP_FLAGS_MEM_MASK))) + { +invalid: + sql_print_error("InnoDB: Expected tablespace flags 0x%zx but found 0x%zx" + " in the file %s", space->flags, flags, name); + return false; + } + + flags_ok: ut_ad(!(flags & FSP_FLAGS_MEM_MASK)); /* Try to read crypt_data from page 0 if it is not yet read. */ diff --git a/storage/innobase/pars/pars0grm.cc b/storage/innobase/pars/pars0grm.cc index 75d7089fb5e..c4d855e2adc 100644 --- a/storage/innobase/pars/pars0grm.cc +++ b/storage/innobase/pars/pars0grm.cc @@ -79,13 +79,13 @@ que_node_t */ #include "que0types.h" #include "que0que.h" #include "row0sel.h" - -#if defined __GNUC__ && (!defined __clang_major__ || __clang_major__ > 11) -#pragma GCC diagnostic ignored "-Wfree-nonheap-object" +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wpragmas" +# pragma GCC diagnostic ignored "-Wunknown-warning-option" +# pragma GCC diagnostic ignored "-Wfree-nonheap-object" +# pragma GCC diagnostic ignored "-Wunused-but-set-variable" #endif - #define YYSTYPE que_node_t* - /* #define __STDC__ */ int yylex(void); diff --git a/storage/innobase/pars/pars0grm.y b/storage/innobase/pars/pars0grm.y index baa7100cfde..c23d6844a78 100644 --- a/storage/innobase/pars/pars0grm.y +++ b/storage/innobase/pars/pars0grm.y @@ -37,13 +37,13 @@ que_node_t */ #include "que0types.h" #include "que0que.h" #include "row0sel.h" - -#if defined __GNUC__ && (!defined __clang_major__ || __clang_major__ > 11) -#pragma GCC diagnostic ignored "-Wfree-nonheap-object" +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wpragmas" +# pragma GCC diagnostic ignored "-Wunknown-warning-option" +# pragma GCC diagnostic ignored "-Wfree-nonheap-object" +# pragma GCC diagnostic ignored "-Wunused-but-set-variable" #endif - #define YYSTYPE que_node_t* - /* #define __STDC__ */ int yylex(void); 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 419a120c2af..9d85e2b1b70 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -489,7 +489,10 @@ row_merge_fts_doc_tokenize( /* Tokenize the data and add each word string, its corresponding doc id and position to sort buffer */ - while (t_ctx->processed_len < doc->text.f_len) { + while (parser + ? (!t_ctx->processed_len + || UT_LIST_GET_LEN(t_ctx->fts_token_list)) + : t_ctx->processed_len < doc->text.f_len) { ulint idx = 0; ulint cur_len; doc_id_t write_doc_id; @@ -829,7 +832,8 @@ loop: /* Not yet finish processing the "doc" on hand, continue processing it */ ut_ad(doc.text.f_str); - ut_ad(t_ctx.processed_len < doc.text.f_len); + ut_ad(buf[0]->index->parser + || t_ctx.processed_len < doc.text.f_len); } processed = row_merge_fts_doc_tokenize( @@ -839,7 +843,8 @@ loop: /* Current sort buffer full, need to recycle */ if (!processed) { - ut_ad(t_ctx.processed_len < doc.text.f_len); + ut_ad(buf[0]->index->parser + || t_ctx.processed_len < doc.text.f_len); ut_ad(t_ctx.rows_added[t_ctx.buf_used]); break; } @@ -1625,9 +1630,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/row0import.cc b/storage/innobase/row/row0import.cc index 5003f384e11..d3c8839e500 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -117,7 +117,6 @@ struct row_import { row_import() UNIV_NOTHROW : m_table(NULL), - m_version(0), m_hostname(NULL), m_table_name(NULL), m_autoinc(0), @@ -196,8 +195,6 @@ struct row_import { dict_table_t* m_table; /*!< Table instance */ - ulint m_version; /*!< Version of config file */ - byte* m_hostname; /*!< Hostname where the tablespace was exported */ byte* m_table_name; /*!< Exporting instance table @@ -2103,7 +2100,7 @@ dberr_t PageConverter::operator()(buf_block_t* block) UNIV_NOTHROW /* If we already had an old page with matching number in the buffer pool, evict it now, because we no longer evict the pages on DISCARD TABLESPACE. */ - buf_page_get_low(block->page.id(), get_zip_size(), RW_NO_LATCH, + buf_page_get_gen(block->page.id(), get_zip_size(), RW_NO_LATCH, nullptr, BUF_PEEK_IF_IN_POOL, nullptr, nullptr); @@ -2992,17 +2989,13 @@ row_import_read_meta_data( return(DB_IO_ERROR); } - cfg.m_version = mach_read_from_4(row); - /* Check the version number. */ - switch (cfg.m_version) { + switch (mach_read_from_4(row)) { case IB_EXPORT_CFG_VERSION_V1: - return(row_import_read_v1(file, thd, &cfg)); default: - ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - "Unsupported meta-data version number (" ULINTPF "), " - "file ignored", cfg.m_version); + ib_senderrf(thd, IB_LOG_LEVEL_ERROR, ER_NOT_SUPPORTED_YET, + "meta-data version"); } return(DB_ERROR); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index d5ff314bc2e..770675c5e43 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2637,14 +2637,17 @@ row_ins_clust_index_entry_low( ut_ad(!dict_index_is_online_ddl(index)); ut_ad(!index->table->persistent_autoinc); ut_ad(!index->is_instant()); + ut_ad(!entry->info_bits); mtr.set_log_mode(MTR_LOG_NO_REDO); } else { index->set_modified(mtr); - if (UNIV_UNLIKELY(entry->is_metadata())) { + if (UNIV_UNLIKELY(entry->info_bits != 0)) { + ut_ad(entry->is_metadata()); ut_ad(index->is_instant()); ut_ad(!dict_index_is_online_ddl(index)); ut_ad(mode == BTR_MODIFY_TREE); + ut_ad(flags == BTR_NO_LOCKING_FLAG); } else { if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) { @@ -2784,11 +2787,6 @@ avoid_bulk: skip_bulk_insert: if (UNIV_UNLIKELY(entry->info_bits != 0)) { - ut_ad(entry->is_metadata()); - ut_ad(flags == BTR_NO_LOCKING_FLAG); - ut_ad(index->is_instant()); - ut_ad(!dict_index_is_online_ddl(index)); - const rec_t* rec = btr_pcur_get_rec(&pcur); if (rec_get_info_bits(rec, page_rec_is_comp(rec)) @@ -2892,9 +2890,20 @@ do_insert: } } + if (err == DB_SUCCESS && entry->info_bits) { + if (buf_block_t* root + = btr_root_block_get(index, RW_X_LATCH, &mtr, + &err)) { + btr_set_instant(root, *index, &mtr); + } else { + ut_ad("cannot find root page" == 0); + } + } + mtr.commit(); if (big_rec) { + ut_ad(err == DB_SUCCESS); /* Online table rebuild could read (and ignore) the incomplete record at this point. If online rebuild is in progress, the diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index cb11deeb678..882e7c64550 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -3789,6 +3789,12 @@ dberr_t dict_table_t::clear(que_thr_t *thr) return err; } +inline bool UndorecApplier::is_same(roll_ptr_t roll_ptr) const +{ + return uint16_t(roll_ptr) == offset && + uint32_t(roll_ptr >> 16) == page_id.page_no(); +} + const rec_t * UndorecApplier::get_old_rec(const dtuple_t &tuple, dict_index_t *index, const rec_t **clust_rec, rec_offs **offsets) @@ -3914,8 +3920,7 @@ void UndorecApplier::log_insert(const dtuple_t &tuple, /* Update the row with virtual column values present in the undo log or update vector */ if (type == TRX_UNDO_UPD_DEL_REC) - row_upd_replace_vcol(row, table, update, false, - nullptr, + row_upd_replace_vcol(row, table, update, false, nullptr, (cmpl_info & UPD_NODE_NO_ORD_CHANGE) ? nullptr : undo_rec); else @@ -4037,7 +4042,7 @@ void UndorecApplier::log_update(const dtuple_t &tuple, if (table->n_v_cols) row_upd_replace_vcol(row, table, update, false, nullptr, (cmpl_info & UPD_NODE_NO_ORD_CHANGE) - ? nullptr : this->undo_rec); + ? nullptr : undo_rec); bool success= true; dict_index_t *index= dict_table_get_next_index(clust_index); diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 61035137100..b74227aa792 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -120,7 +120,7 @@ public: ut_ad(mtr_started == scan_mtr->is_active()); DBUG_EXECUTE_IF("row_merge_instrument_log_check_flush", - log_sys.set_check_flush_or_checkpoint();); + log_sys.set_check_for_checkpoint();); for (idx_tuple_vec::iterator it = m_dtuple_vec.begin(); it != m_dtuple_vec.end(); @@ -128,7 +128,7 @@ public: dtuple = *it; ut_ad(dtuple); - if (log_sys.check_flush_or_checkpoint()) { + if (log_sys.check_for_checkpoint()) { if (mtr_started) { if (!btr_pcur_move_to_prev_on_page(pcur)) { error = DB_CORRUPTION; @@ -2237,6 +2237,8 @@ end_of_index: goto err_exit; } + buf_page_make_young_if_needed(&block->page); + page_cur_set_before_first(block, cur); if (!page_cur_move_to_next(cur) || page_cur_is_after_last(cur)) { @@ -3055,7 +3057,7 @@ wait_again: if (err == DB_SUCCESS) { new_table->fts->cache->synced_doc_id = max_doc_id; - /* Update the max value as next FTS_DOC_ID */ + /* Update the max value as next FTS_DOC_ID */ if (max_doc_id >= new_table->fts->cache->next_doc_id) { new_table->fts->cache->next_doc_id = max_doc_id + 1; @@ -3547,17 +3549,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 && !(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", @@ -3566,15 +3557,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 && !(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); @@ -3598,13 +3580,6 @@ row_merge_sort( ut_free(run_offset); - /* Progress report only for "normal" indexes. */ -#ifndef __sun__ - if (dup && !(dup->index->type & DICT_FTS)) { - thd_progress_end(trx->mysql_thd); - } -#endif /* __sun__ */ - DBUG_RETURN(error); } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 18d8f4b6220..b7ff6ce46dc 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -81,7 +81,7 @@ static void row_mysql_delay_if_needed() const lsn_t lsn= log_sys.get_lsn(); if ((lsn - last) / 4 >= max_age / 5) buf_flush_ahead(last + max_age / 5, false); - srv_wake_purge_thread_if_not_active(); + purge_sys.wake_if_not_active(); std::this_thread::sleep_for(std::chrono::microseconds(delay)); } } diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index c4198a332a0..adac8ecfb37 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -115,7 +115,6 @@ row_purge_remove_clust_if_poss_low( if (table_id) { retry: - purge_sys.check_stop_FTS(); dict_sys.lock(SRW_LOCK_CALL); table = dict_sys.find_table(table_id); if (!table) { @@ -186,7 +185,6 @@ close_and_exit: table = nullptr; } - purge_sys.check_stop_SYS(); mtr.start(); index->set_modified(mtr); @@ -594,25 +592,12 @@ bool row_purge_del_mark(purge_node_t *node) return result; } -void purge_sys_t::wait_SYS() -{ - while (must_wait_SYS()) - std::this_thread::sleep_for(std::chrono::seconds(1)); -} - -void purge_sys_t::wait_FTS() -{ - while (must_wait_FTS()) - std::this_thread::sleep_for(std::chrono::seconds(1)); -} - /** Reset DB_TRX_ID, DB_ROLL_PTR of a clustered index record whose old history can no longer be observed. @param[in,out] node purge node @param[in,out] mtr mini-transaction (will be started and committed) */ static void row_purge_reset_trx_id(purge_node_t* node, mtr_t* mtr) { -retry: /* Reset DB_TRX_ID, DB_ROLL_PTR for old records. */ mtr->start(); @@ -648,17 +633,6 @@ retry: ut_ad(!rec_get_deleted_flag( rec, rec_offs_comp(offsets)) || rec_is_alter_metadata(rec, *index)); - switch (node->table->id) { - case DICT_TABLES_ID: - case DICT_COLUMNS_ID: - case DICT_INDEXES_ID: - if (purge_sys.must_wait_SYS()) { - mtr->commit(); - purge_sys.check_stop_SYS(); - goto retry; - } - } - DBUG_LOG("purge", "reset DB_TRX_ID=" << ib::hex(row_get_rec_trx_id( rec, index, offsets))); @@ -701,7 +675,7 @@ row_purge_upd_exist_or_extern_func( const que_thr_t*thr, /*!< in: query thread */ #endif /* UNIV_DEBUG */ purge_node_t* node, /*!< in: row purge node */ - trx_undo_rec_t* undo_rec) /*!< in: record to purge */ + const trx_undo_rec_t* undo_rec) /*!< in: record to purge */ { mem_heap_t* heap; @@ -801,7 +775,6 @@ skip_secondaries: buf_page_get(page_id_t(rseg.space->id, page_no), 0, RW_X_LATCH, &mtr)) { - block->page.set_accessed(); buf_page_make_young_if_needed(&block->page); byte* data_field = block->page.frame @@ -976,7 +949,7 @@ static bool row_purge_parse_undo_rec( purge_node_t* node, - trx_undo_rec_t* undo_rec, + const trx_undo_rec_t* undo_rec, que_thr_t* thr, bool* updated_extern) { @@ -985,7 +958,7 @@ row_purge_parse_undo_rec( table_id_t table_id; roll_ptr_t roll_ptr; byte info_bits; - ulint type; + byte type; const byte* ptr = trx_undo_rec_get_pars( undo_rec, &type, &node->cmpl_info, @@ -999,10 +972,7 @@ row_purge_parse_undo_rec( case TRX_UNDO_EMPTY: case TRX_UNDO_INSERT_METADATA: case TRX_UNDO_INSERT_REC: - /* These records do not store any transaction identifier. - - FIXME: Update SYS_TABLES.ID on both DISCARD TABLESPACE - and IMPORT TABLESPACE to get rid of the repeated lookups! */ + /* These records do not store any transaction identifier. */ node->trx_id = TRX_ID_MAX; break; default: @@ -1018,83 +988,35 @@ row_purge_parse_undo_rec( break; } - if (node->is_skipped(table_id)) { + auto &tables_entry= node->tables[table_id]; + node->table = tables_entry.first; + if (!node->table) { return false; } - trx_id_t trx_id = TRX_ID_MAX; - - if (node->retain_mdl(table_id)) { - ut_ad(node->table != NULL); - goto already_locked; +#ifndef DBUG_OFF + if (MDL_ticket* mdl = tables_entry.second) { + static_cast(thd_mdl_context(current_thd)) + ->lock_warrant = mdl->get_ctx(); } - -try_again: - purge_sys.check_stop_FTS(); - - node->table = dict_table_open_on_id( - table_id, false, DICT_TABLE_OP_NORMAL, node->purge_thd, - &node->mdl_ticket); - - if (node->table == reinterpret_cast(-1)) { - /* purge stop signal */ - goto try_again; - } - - if (!node->table) { - /* The table has been dropped: no need to do purge and - release mdl happened as a part of open process itself */ - goto err_exit; - } - -already_locked: +#endif ut_ad(!node->table->is_temporary()); - switch (type) { - case TRX_UNDO_INSERT_METADATA: - case TRX_UNDO_INSERT_REC: - break; - default: - if (!node->table->n_v_cols || node->table->vc_templ - || !dict_table_has_indexed_v_cols(node->table)) { - break; - } - /* Need server fully up for virtual column computation */ - if (!mysqld_server_started) { - - node->close_table(); - if (srv_shutdown_state > SRV_SHUTDOWN_NONE) { - return(false); - } - std::this_thread::sleep_for(std::chrono::seconds(1)); - goto try_again; - } - } - clust_index = dict_table_get_first_index(node->table); - if (!clust_index || clust_index->is_corrupted()) { + if (clust_index->is_corrupted()) { /* The table was corrupt in the data dictionary. dict_set_corrupted() works on an index, and we do not have an index to call it with. */ DBUG_ASSERT(table_id == node->table->id); - trx_id = node->table->def_trx_id; - if (!trx_id) { - trx_id = TRX_ID_MAX; - } - -err_exit: - node->close_table(); - node->skip(table_id, trx_id); - return(false); + return false; } - node->last_table_id = table_id; - - if (type == TRX_UNDO_INSERT_METADATA) { + switch (type) { + case TRX_UNDO_INSERT_METADATA: node->ref = &trx_undo_metadata; - return(true); - } else if (type == TRX_UNDO_EMPTY) { + return true; + case TRX_UNDO_EMPTY: node->ref = nullptr; return true; } @@ -1133,7 +1055,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool row_purge_record_func( purge_node_t* node, - trx_undo_rec_t* undo_rec, + const trx_undo_rec_t* undo_rec, #if defined UNIV_DEBUG || defined WITH_WSREP const que_thr_t*thr, #endif /* UNIV_DEBUG || WITH_WSREP */ @@ -1204,7 +1126,7 @@ void row_purge( /*======*/ purge_node_t* node, /*!< in: row purge node */ - trx_undo_rec_t* undo_rec, /*!< in: record to purge */ + const trx_undo_rec_t* undo_rec, /*!< in: record to purge */ que_thr_t* thr) /*!< in: query thread */ { if (undo_rec != reinterpret_cast(-1)) { @@ -1236,22 +1158,22 @@ inline void purge_node_t::start() ref= nullptr; index= nullptr; update= nullptr; - found_clust= FALSE; - rec_type= ULINT_UNDEFINED; - cmpl_info= ULINT_UNDEFINED; - if (!purge_thd) - purge_thd= current_thd; + found_clust= false; + rec_type= 0; + cmpl_info= 0; } /** Reset the state at end @return the query graph parent */ -inline que_node_t *purge_node_t::end() +inline que_node_t *purge_node_t::end(THD *thd) { DBUG_ASSERT(common.type == QUE_NODE_PURGE); - close_table(); ut_ad(undo_recs.empty()); ut_d(in_progress= false); - purge_thd= nullptr; + innobase_reset_background_thd(thd); +#ifndef DBUG_OFF + static_cast(thd_mdl_context(thd))->lock_warrant= nullptr; +#endif mem_heap_empty(heap); return common.parent; } @@ -1279,7 +1201,7 @@ row_purge_step( row_purge(node, purge_rec.undo_rec, thr); } - thr->run_node = node->end(); + thr->run_node = node->end(current_thd); return(thr); } diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index ffafd0437cc..b5dd0e380df 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -1222,6 +1222,7 @@ re_scan: if (!cur_block) { goto func_end; } + buf_page_make_young_if_needed(&cur_block->page); } else { mtr->start(); goto func_end; diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index f0f1ba74f26..b78a2c410af 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -369,11 +369,9 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked) const byte* ptr; undo_no_t undo_no; table_id_t table_id; - ulint dummy; + byte dummy; bool dummy_extern; - ut_ad(node->state == UNDO_INSERT_PERSISTENT - || node->state == UNDO_INSERT_TEMPORARY); ut_ad(node->trx->in_rollback); ut_ad(trx_undo_roll_ptr_is_insert(node->roll_ptr)); @@ -381,7 +379,7 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked) &dummy_extern, &undo_no, &table_id); node->update = NULL; - if (node->state == UNDO_INSERT_PERSISTENT) { + if (!node->is_temp) { node->table = dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_NORMAL); } else if (!dict_locked) { @@ -411,7 +409,7 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked) || dict_table_is_file_per_table(table) == !is_system_tablespace(table->space_id)); size_t len = mach_read_from_2(node->undo_rec) - + size_t(node->undo_rec - ptr) - 2; + - page_offset(ptr) - 2; const span name(reinterpret_cast(ptr), len); if (strlen(table->name.m_name) != len diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 63393d86502..bcc598e6523 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1056,12 +1056,10 @@ static bool row_undo_mod_parse_undo_rec(undo_node_t* node, bool dict_locked) trx_id_t trx_id; roll_ptr_t roll_ptr; byte info_bits; - ulint type; - ulint cmpl_info; + byte type; + byte cmpl_info; bool dummy_extern; - ut_ad(node->state == UNDO_UPDATE_PERSISTENT - || node->state == UNDO_UPDATE_TEMPORARY); ut_ad(node->trx->in_rollback); ut_ad(!trx_undo_roll_ptr_is_insert(node->roll_ptr)); @@ -1070,7 +1068,7 @@ static bool row_undo_mod_parse_undo_rec(undo_node_t* node, bool dict_locked) &dummy_extern, &undo_no, &table_id); node->rec_type = type; - if (node->state == UNDO_UPDATE_PERSISTENT) { + if (!node->is_temp) { node->table = dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_NORMAL); } else if (!dict_locked) { @@ -1169,7 +1167,7 @@ close_table: row_upd_replace_vcol(node->row, node->table, node->update, false, node->undo_row, (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) - ? NULL : ptr); + ? nullptr : ptr); } return true; diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc index 4d6d779eee6..f14673c173f 100644 --- a/storage/innobase/row/row0undo.cc +++ b/storage/innobase/row/row0undo.cc @@ -140,7 +140,6 @@ row_undo_node_create( undo->common.type = QUE_NODE_UNDO; undo->common.parent = parent; - undo->state = UNDO_NODE_FETCH_NEXT; undo->trx = trx; btr_pcur_init(&(undo->pcur)); @@ -219,8 +218,7 @@ row_undo_search_clust_to_pcur( log, first mark them DATA_MISSING. So we will know if the value gets updated */ if (node->table->n_v_cols - && (node->state == UNDO_UPDATE_PERSISTENT - || node->state == UNDO_UPDATE_TEMPORARY) + && !trx_undo_roll_ptr_is_insert(node->roll_ptr) && !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { for (ulint i = 0; i < dict_table_get_n_v_cols(node->table); i++) { @@ -258,8 +256,9 @@ func_exit: /** Get the latest undo log record for rollback. @param[in,out] node rollback context -@return whether an undo log record was fetched */ -static bool row_undo_rec_get(undo_node_t* node) +@return undo block for the undo log record +@retval nullptr if no undo log record was fetched */ +static buf_block_t* row_undo_rec_get(undo_node_t* node) { trx_t* trx = node->trx; @@ -272,7 +271,7 @@ static bool row_undo_rec_get(undo_node_t* node) trx_undo_t* update = trx->rsegs.m_redo.undo; trx_undo_t* temp = trx->rsegs.m_noredo.undo; const undo_no_t limit = trx->roll_limit; - bool is_temp = false; + node->is_temp = false; ut_ad(!update || !temp || update->empty() || temp->empty() || update->top_undo_no != temp->top_undo_no); @@ -288,7 +287,7 @@ static bool row_undo_rec_get(undo_node_t* node) if (temp && !temp->empty() && temp->top_undo_no >= limit) { if (!undo || undo->top_undo_no < temp->top_undo_no) { undo = temp; - is_temp = true; + node->is_temp = true; } } @@ -299,14 +298,14 @@ static bool row_undo_rec_get(undo_node_t* node) later, we will default to a full ROLLBACK. */ trx->roll_limit = 0; trx->in_rollback = false; - return false; + return nullptr; } ut_ad(!undo->empty()); ut_ad(limit <= undo->top_undo_no); node->roll_ptr = trx_undo_build_roll_ptr( - false, trx_sys.rseg_id(undo->rseg, !is_temp), + false, trx_sys.rseg_id(undo->rseg, !node->is_temp), undo->top_page_no, undo->top_offset); mtr_t mtr; @@ -316,9 +315,11 @@ static bool row_undo_rec_get(undo_node_t* node) page_id_t(undo->rseg->space->id, undo->top_page_no), 0, RW_S_LATCH, &mtr); if (!undo_page) { - return false; + return nullptr; } + buf_page_make_young_if_needed(&undo_page->page); + uint16_t offset = undo->top_offset; buf_block_t* prev_page = undo_page; @@ -338,12 +339,17 @@ static bool row_undo_rec_get(undo_node_t* node) ut_ad(undo->empty()); } - node->undo_rec = trx_undo_rec_copy(undo_page->page.frame + offset, - node->heap); + undo_page->fix(); mtr.commit(); - if (UNIV_UNLIKELY(!node->undo_rec)) { - return false; + node->undo_rec = undo_page->page.frame + offset; + + const size_t end = mach_read_from_2(node->undo_rec); + if (UNIV_UNLIKELY(end <= offset + || end >= srv_page_size - FIL_PAGE_DATA_END)) { + undo_page->unfix(); + node->undo_rec = nullptr; + return nullptr; } switch (node->undo_rec[2] & (TRX_UNDO_CMPL_INFO_MULT - 1)) { @@ -360,17 +366,11 @@ static bool row_undo_rec_get(undo_node_t* node) case TRX_UNDO_INSERT_REC: case TRX_UNDO_EMPTY: node->roll_ptr |= 1ULL << ROLL_PTR_INSERT_FLAG_POS; - node->state = is_temp - ? UNDO_INSERT_TEMPORARY : UNDO_INSERT_PERSISTENT; - break; - default: - node->state = is_temp - ? UNDO_UPDATE_TEMPORARY : UNDO_UPDATE_PERSISTENT; } trx->undo_no = node->undo_no = trx_undo_rec_get_undo_no( node->undo_rec); - return true; + return undo_page; } /***********************************************************//** @@ -387,29 +387,17 @@ row_undo( { ut_ad(node->trx->in_rollback); - if (node->state == UNDO_NODE_FETCH_NEXT && !row_undo_rec_get(node)) { + buf_block_t* undo_page = row_undo_rec_get(node); + + if (!undo_page) { /* Rollback completed for this query thread */ thr->run_node = que_node_get_parent(node); return DB_SUCCESS; } - dberr_t err; - - switch (node->state) { - case UNDO_INSERT_PERSISTENT: - case UNDO_INSERT_TEMPORARY: - err = row_undo_ins(node, thr); - break; - case UNDO_UPDATE_PERSISTENT: - case UNDO_UPDATE_TEMPORARY: - err = row_undo_mod(node, thr); - break; - default: - ut_ad("wrong state" == 0); - err = DB_CORRUPTION; - } - - node->state = UNDO_NODE_FETCH_NEXT; + dberr_t err = trx_undo_roll_ptr_is_insert(node->roll_ptr) + ? row_undo_ins(node, thr) : row_undo_mod(node, thr); + undo_page->unfix(); btr_pcur_close(&(node->pcur)); mem_heap_empty(node->heap); diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 96a10d159b8..76bd1eff9f1 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1060,10 +1060,8 @@ row_upd_replace_vcol( bool is_undo_log = true; /* We will read those unchanged (but indexed) virtual columns in */ - if (ptr != NULL) { - const byte* end_ptr; - - end_ptr = ptr + mach_read_from_2(ptr); + if (ptr) { + const byte* const end_ptr = ptr + mach_read_from_2(ptr); ptr += 2; while (ptr != end_ptr) { @@ -1189,7 +1187,7 @@ row_upd_replace( *ext = NULL; } - row_upd_replace_vcol(row, table, update, true, NULL, NULL); + row_upd_replace_vcol(row, table, update, true, nullptr, nullptr); } /***********************************************************//** @@ -2137,6 +2135,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 @@ -2215,12 +2232,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/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index c30ffeeb297..2bc1c2e6922 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -136,7 +136,7 @@ static monitor_info_t innodb_counter_info[] = "Number of row locks currently being waited for" " (innodb_row_lock_current_waits)", static_cast( - MONITOR_EXISTING | MONITOR_DEFAULT_ON), + MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT | MONITOR_DEFAULT_ON), MONITOR_DEFAULT_START, MONITOR_OVLD_ROW_LOCK_CURRENT_WAIT}, {"lock_row_lock_time", "lock", diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index c71222a7be7..32e9f9e923f 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -460,26 +460,8 @@ static srv_sys_t srv_sys; struct purge_coordinator_state { /** Snapshot of the last history length before the purge call.*/ - size_t m_history_length; + size_t history_size; Atomic_counter m_running; -private: - ulint count; - ulint n_use_threads; - ulint n_threads; - - ulint lsn_lwm; - ulint lsn_hwm; - ulonglong start_time; - ulint lsn_age_factor; - - static constexpr ulint adaptive_purge_threshold= 20; - static constexpr ulint safety_net= 20; - ulint series[innodb_purge_threads_MAX + 1]; - - inline void compute_series(); - inline void lazy_init(); - void refresh(bool full); - public: inline void do_purge(); }; @@ -890,6 +872,9 @@ srv_export_innodb_status(void) export_vars.innodb_data_written = srv_stats.data_written + (dblwr << srv_page_size_shift); + export_vars.innodb_buffer_pool_read_requests + = buf_pool.stat.n_page_gets; + export_vars.innodb_buffer_pool_bytes_data = buf_pool.stat.LRU_bytes + (UT_LIST_GET_LEN(buf_pool.unzip_LRU) @@ -1111,6 +1096,13 @@ bool srv_any_background_activity() static void purge_worker_callback(void*); static void purge_coordinator_callback(void*); +static void purge_truncation_callback(void*) +{ + purge_sys.latch.rd_lock(SRW_LOCK_CALL); + const purge_sys_t::iterator head= purge_sys.head; + purge_sys.latch.rd_unlock(); + head.free_history(); +} static tpool::task_group purge_task_group; tpool::waitable_task purge_worker_task(purge_worker_callback, nullptr, @@ -1118,56 +1110,49 @@ tpool::waitable_task purge_worker_task(purge_worker_callback, nullptr, static tpool::task_group purge_coordinator_task_group(1); static tpool::waitable_task purge_coordinator_task (purge_coordinator_callback, nullptr, &purge_coordinator_task_group); - -static tpool::timer *purge_coordinator_timer; +static tpool::task_group purge_truncation_task_group(1); +static tpool::waitable_task purge_truncation_task + (purge_truncation_callback, nullptr, &purge_truncation_task_group); /** Wake up the purge threads if there is work to do. */ -void srv_wake_purge_thread_if_not_active() +void purge_sys_t::wake_if_not_active() { - if (purge_sys.enabled() && !purge_sys.paused() && + if (enabled() && !paused() && !purge_state.m_running && (srv_undo_log_truncate || trx_sys.history_exists()) && ++purge_state.m_running == 1) srv_thread_pool->submit_task(&purge_coordinator_task); } /** @return whether the purge tasks are active */ -bool purge_sys_t::running() const +bool purge_sys_t::running() { return purge_coordinator_task.is_running(); } -/** Suspend purge in data dictionary tables */ -void purge_sys_t::stop_SYS() +void purge_sys_t::stop_FTS() { latch.rd_lock(SRW_LOCK_CALL); - ++m_SYS_paused; + m_FTS_paused++; latch.rd_unlock(); + while (m_active) + std::this_thread::sleep_for(std::chrono::seconds(1)); } /** Stop purge during FLUSH TABLES FOR EXPORT */ void purge_sys_t::stop() { - for (;;) + latch.wr_lock(SRW_LOCK_CALL); + + if (!enabled()) { - latch.wr_lock(SRW_LOCK_CALL); - - if (!enabled()) - { - /* Shutdown must have been initiated during FLUSH TABLES FOR EXPORT. */ - ut_ad(!srv_undo_sources); - latch.wr_unlock(); - return; - } - - ut_ad(srv_n_purge_threads > 0); - - if (!must_wait_SYS()) - break; - + /* Shutdown must have been initiated during FLUSH TABLES FOR EXPORT. */ + ut_ad(!srv_undo_sources); latch.wr_unlock(); - std::this_thread::sleep_for(std::chrono::seconds(1)); + return; } + ut_ad(srv_n_purge_threads > 0); + const auto paused= m_paused++; latch.wr_unlock(); @@ -1183,9 +1168,8 @@ void purge_sys_t::stop() /** Resume purge in data dictionary tables */ void purge_sys_t::resume_SYS(void *) { - ut_d(const auto s=) - purge_sys.m_SYS_paused--; - ut_ad(s); + ut_d(auto paused=) purge_sys.m_SYS_paused--; + ut_ad(paused); } /** Resume purge at UNLOCK TABLES after FLUSH TABLES FOR EXPORT */ @@ -1207,8 +1191,8 @@ void purge_sys_t::resume() if (paused == 1) { ib::info() << "Resuming purge"; - purge_state.m_running = 0; - srv_wake_purge_thread_if_not_active(); + purge_state.m_running= 1; + srv_thread_pool->submit_task(&purge_coordinator_task); MONITOR_ATOMIC_INC(MONITOR_PURGE_RESUME_COUNT); } latch.wr_unlock(); @@ -1302,8 +1286,7 @@ void srv_master_callback(void*) ut_a(srv_shutdown_state <= SRV_SHUTDOWN_INITIATED); MONITOR_INC(MONITOR_MASTER_THREAD_SLEEP); - if (!purge_state.m_running) - srv_wake_purge_thread_if_not_active(); + purge_sys.wake_if_not_active(); ulonglong counter_time= microsecond_interval_timer(); srv_sync_log_buffer_in_background(); MONITOR_INC_TIME_IN_MICRO_SECS(MONITOR_SRV_LOG_FLUSH_MICROSECOND, @@ -1380,202 +1363,80 @@ static bool srv_task_execute() static void purge_create_background_thds(int ); -std::mutex purge_thread_count_mtx; +/** Flag which is set, whenever innodb_purge_threads changes. */ +static Atomic_relaxed srv_purge_thread_count_changed; + +static std::mutex purge_thread_count_mtx; void srv_update_purge_thread_count(uint n) { std::lock_guard lk(purge_thread_count_mtx); ut_ad(n > 0); ut_ad(n <= innodb_purge_threads_MAX); srv_n_purge_threads = n; - srv_purge_thread_count_changed = 1; + srv_purge_thread_count_changed = true; } -Atomic_counter srv_purge_thread_count_changed; - inline void purge_coordinator_state::do_purge() { ut_ad(!srv_read_only_mode); - lazy_init(); - ut_ad(n_threads); - bool wakeup= false; - purge_coordinator_timer->disarm(); + if (!purge_sys.enabled() || purge_sys.paused()) + return; + + uint n_threads; - while (purge_sys.enabled() && !purge_sys.paused()) { -loop: - wakeup= false; - const auto now= my_interval_timer(); - const auto sigcount= m_running; - - if (now - start_time >= 1000000) - { - refresh(false); - start_time= now; - } - - const auto old_activity_count= srv_sys.activity_count; - const auto history_size= trx_sys.history_size(); + std::lock_guard lk(purge_thread_count_mtx); + n_threads= srv_n_purge_threads; + srv_purge_thread_count_changed= false; + goto first_loop; + } + do + { if (UNIV_UNLIKELY(srv_purge_thread_count_changed)) { /* Read the fresh value of srv_n_purge_threads, reset - the changed flag. Both are protected by purge_thread_count_mtx. - - This code does not run concurrently, it is executed - by a single purge_coordinator thread, and no races - involving srv_purge_thread_count_changed are possible. */ + the changed flag. Both are protected by purge_thread_count_mtx. */ { std::lock_guard lk(purge_thread_count_mtx); - n_threads= n_use_threads= srv_n_purge_threads; - srv_purge_thread_count_changed= 0; - } - refresh(true); - start_time= now; - } - else if (history_size > m_history_length) - { - /* dynamically adjust the purge thread based on redo log fill factor */ - if (n_use_threads < n_threads && lsn_age_factor < lsn_lwm) - { -more_threads: - ++n_use_threads; - lsn_hwm= lsn_lwm; - lsn_lwm-= series[n_use_threads]; - } - else if (n_use_threads > 1 && lsn_age_factor >= lsn_hwm) - { -fewer_threads: - --n_use_threads; - lsn_lwm= lsn_hwm; - lsn_hwm+= series[n_use_threads]; - } - else if (n_use_threads == 1 && lsn_age_factor >= 100 - safety_net) - { - wakeup= true; - break; + n_threads= srv_n_purge_threads; + srv_purge_thread_count_changed= false; } } - else if (n_threads > n_use_threads && - srv_max_purge_lag && m_history_length > srv_max_purge_lag) - goto more_threads; - else if (n_use_threads > 1 && old_activity_count == srv_sys.activity_count) - goto fewer_threads; + first_loop: + ut_ad(n_threads); - ut_ad(n_use_threads); - ut_ad(n_use_threads <= n_threads); - - m_history_length= history_size; + history_size= trx_sys.history_size(); if (!history_size) { + no_history: srv_dml_needed_delay= 0; + purge_truncation_task.wait(); + trx_purge_truncate_history(); + break; + } + + ulint n_pages_handled= trx_purge(n_threads, history_size); + if (!trx_sys.history_exists()) + goto no_history; + if (purge_sys.truncate.current || srv_shutdown_state != SRV_SHUTDOWN_NONE) + { + purge_truncation_task.wait(); trx_purge_truncate_history(); } else - { - ulint n_pages_handled= trx_purge(n_use_threads, history_size); - if (!(++count % srv_purge_rseg_truncate_frequency) || - purge_sys.truncate.current || - (srv_shutdown_state != SRV_SHUTDOWN_NONE && srv_fast_shutdown == 0)) - trx_purge_truncate_history(); - if (n_pages_handled) - continue; - } - - if (srv_dml_needed_delay); - else if (m_running == sigcount) - { - /* Purge was not woken up by srv_wake_purge_thread_if_not_active() */ - - /* The magic number 5000 is an approximation for the case where we have - cached undo log records which prevent truncate of rollback segments. */ - wakeup= history_size >= 5000 || - (history_size && history_size != trx_sys.history_size_approx()); + srv_thread_pool->submit_task(&purge_truncation_task); + if (!n_pages_handled) break; - } - - if (!trx_sys.history_exists()) - { - srv_dml_needed_delay= 0; - break; - } - - if (!srv_purge_should_exit(history_size)) - goto loop; } - - if (wakeup) - purge_coordinator_timer->set_time(10, 0); + while (purge_sys.enabled() && !purge_sys.paused() && + !srv_purge_should_exit(history_size)); m_running= 0; } -inline void purge_coordinator_state::compute_series() -{ - ulint points= n_threads; - memset(series, 0, sizeof series); - constexpr ulint spread= 100 - adaptive_purge_threshold - safety_net; - - /* We distribute spread across n_threads, - e.g.: spread of 60 is distributed across n_threads=4 as: 6+12+18+24 */ - - const ulint additional_points= (points * (points + 1)) / 2; - if (spread % additional_points == 0) - { - /* Arithmetic progression is possible. */ - const ulint delta= spread / additional_points; - ulint growth= delta; - do - { - series[points--]= growth; - growth += delta; - } - while (points); - return; - } - - /* Use average distribution to spread across the points */ - const ulint delta= spread / points; - ulint total= 0; - do - { - series[points--]= delta; - total+= delta; - } - while (points); - - for (points= 1; points <= n_threads && total++ < spread; ) - series[points++]++; -} - -inline void purge_coordinator_state::lazy_init() -{ - if (n_threads) - return; - n_threads= n_use_threads= srv_n_purge_threads; - refresh(true); - start_time= my_interval_timer(); -} - -void purge_coordinator_state::refresh(bool full) -{ - if (full) - { - compute_series(); - lsn_lwm= adaptive_purge_threshold; - lsn_hwm= adaptive_purge_threshold + series[n_threads]; - } - - log_sys.latch.rd_lock(SRW_LOCK_CALL); - const lsn_t last= log_sys.last_checkpoint_lsn, - max_age= log_sys.max_checkpoint_age; - log_sys.latch.rd_unlock(); - - lsn_age_factor= ulint(((log_sys.get_lsn() - last) * 100) / max_age); -} - - static std::list purge_thds; static std::mutex purge_thd_mutex; extern void* thd_attach_thd(THD*); @@ -1641,15 +1502,12 @@ static void purge_coordinator_callback(void*) void srv_init_purge_tasks() { purge_create_background_thds(innodb_purge_threads_MAX); - purge_coordinator_timer= srv_thread_pool->create_timer - (purge_coordinator_callback, nullptr); + purge_sys.coordinator_startup(); } static void srv_shutdown_purge_tasks() { purge_coordinator_task.disable(); - delete purge_coordinator_timer; - purge_coordinator_timer= nullptr; purge_worker_task.wait(); std::unique_lock lk(purge_thd_mutex); while (!purge_thds.empty()) @@ -1658,6 +1516,7 @@ static void srv_shutdown_purge_tasks() purge_thds.pop_front(); } n_purge_thds= 0; + purge_truncation_task.wait(); } /**********************************************************************//** @@ -1700,13 +1559,16 @@ void srv_purge_shutdown() if (purge_sys.enabled()) { if (!srv_fast_shutdown && !opt_bootstrap) + { + srv_purge_batch_size= innodb_purge_batch_size_MAX; srv_update_purge_thread_count(innodb_purge_threads_MAX); + } size_t history_size= trx_sys.history_size(); while (!srv_purge_should_exit(history_size)) { history_size= trx_sys.history_size(); ut_a(!purge_sys.paused()); - srv_wake_purge_thread_if_not_active(); + srv_thread_pool->submit_task(&purge_coordinator_task); purge_coordinator_task.wait(); } purge_sys.coordinator_shutdown(); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 153bdb2cf73..b33e1892b31 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -392,13 +392,6 @@ static dberr_t srv_undo_delete_old_tablespaces() DBUG_EXECUTE_IF("after_deleting_old_undo_success", return DB_ERROR;); - for (uint32_t i= 0; i < srv_undo_tablespaces_open; ++i) - { - char name[OS_FILE_MAX_PATH]; - snprintf(name, sizeof name, "%s/undo%03" PRIu32, srv_undo_dir, i + 1); - os_file_delete_if_exists(innodb_data_file_key, name, nullptr); - } - return DB_SUCCESS; } @@ -474,7 +467,7 @@ ATTRIBUTE_COLD static dberr_t srv_undo_tablespaces_reinit() rseg->init(nullptr, FIL_NULL); } - if (trx_sys.recovered_binlog_lsn + if (*trx_sys.recovered_binlog_filename #ifdef WITH_WSREP || !trx_sys.recovered_wsrep_xid.is_null() #endif /* WITH_WSREP */ @@ -482,7 +475,7 @@ ATTRIBUTE_COLD static dberr_t srv_undo_tablespaces_reinit() { /* Update binlog offset, binlog file name & wsrep xid in system tablespace rollback segment */ - if (trx_sys.recovered_binlog_lsn) + if (*trx_sys.recovered_binlog_filename) { ut_d(const size_t len = strlen(trx_sys.recovered_binlog_filename) + 1); ut_ad(len > 1); @@ -602,7 +595,8 @@ static uint32_t trx_rseg_get_n_undo_tablespaces() mtr_t mtr; mtr.start(); - if (const buf_block_t *sys_header= trx_sysf_get(&mtr, false)) + if (const buf_block_t *sys_header= + recv_sys.recover({TRX_SYS_SPACE, TRX_SYS_PAGE_NO}, &mtr, nullptr)) for (ulint rseg_id= 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) if (trx_sysf_rseg_get_page_no(sys_header, rseg_id) != FIL_NULL) if (uint32_t space= trx_sysf_rseg_get_space(sys_header, rseg_id)) @@ -616,8 +610,9 @@ static uint32_t trx_rseg_get_n_undo_tablespaces() @param[in] name tablespace file name @param[in] i undo tablespace count @return undo tablespace identifier -@retval 0 on failure */ -static uint32_t srv_undo_tablespace_open(bool create, const char *name, +@retval 0 if file doesn't exist +@retval ~0U if page0 is corrupted */ +static uint32_t srv_undo_tablespace_open(bool create, const char* name, uint32_t i) { bool success; @@ -653,14 +648,13 @@ static uint32_t srv_undo_tablespace_open(bool create, const char *name, { page_t *page= static_cast(aligned_malloc(srv_page_size, srv_page_size)); - dberr_t err= os_file_read(IORequestRead, fh, page, 0, srv_page_size, - nullptr); - if (err != DB_SUCCESS) + if (os_file_read(IORequestRead, fh, page, 0, srv_page_size, nullptr) != + DB_SUCCESS) { err_exit: ib::error() << "Unable to read first page of file " << name; aligned_free(page); - return err; + return ~0U; } uint32_t id= mach_read_from_4(FIL_PAGE_SPACE_ID + page); @@ -669,19 +663,20 @@ err_exit: FSP_HEADER_OFFSET + FSP_SPACE_ID + page, 4)) { ib::error() << "Inconsistent tablespace ID in file " << name; - err= DB_CORRUPTION; - goto err_exit; - } - - fsp_flags= mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); - if (buf_page_is_corrupted(false, page, fsp_flags)) - { - ib::error() << "Checksum mismatch in the first page of file " << name; - err= DB_CORRUPTION; goto err_exit; } space_id= id; + fsp_flags= mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); + + if (buf_page_is_corrupted(false, page, fsp_flags)) + { + sql_print_error("InnoDB: Checksum mismatch in the first page of file %s", + name); + if (recv_sys.dblwr.restore_first_page(space_id, name, fh)) + goto err_exit; + } + aligned_free(page); } @@ -793,17 +788,19 @@ static dberr_t srv_all_undo_tablespaces_open(bool create_new_undo, char name[OS_FILE_MAX_PATH]; snprintf(name, sizeof name, "%s/undo%03u", srv_undo_dir, i + 1); uint32_t space_id= srv_undo_tablespace_open(create_new_undo, name, i); - if (!space_id) - { + switch (space_id) { + case ~0U: + return DB_CORRUPTION; + case 0: if (!create_new_undo) - break; - ib::error() << "Unable to open create tablespace '" << name << "'."; + goto unused_undo; + sql_print_error("InnoDB: Unable to open create tablespace '%s'.", name); return DB_ERROR; + default: + /* Should be no gaps in undo tablespace ids. */ + ut_a(!i || prev_id + 1 == space_id); } - /* Should be no gaps in undo tablespace ids. */ - ut_a(!i || prev_id + 1 == space_id); - prev_id= space_id; /* Note the first undo tablespace id in case of @@ -816,14 +813,14 @@ static dberr_t srv_all_undo_tablespaces_open(bool create_new_undo, We stop at the first failure. These are undo tablespaces that are not in use and therefore not required by recovery. We only check that there are no gaps. */ - +unused_undo: for (uint32_t i= prev_id + 1; i < srv_undo_space_id_start + TRX_SYS_N_RSEGS; ++i) { char name[OS_FILE_MAX_PATH]; snprintf(name, sizeof name, "%s/undo%03u", srv_undo_dir, i); uint32_t space_id= srv_undo_tablespace_open(create_new_undo, name, i); - if (!space_id) + if (!space_id || space_id == ~0U) break; if (0 == srv_undo_tablespaces_open++) srv_undo_space_id_start= space_id; @@ -1555,20 +1552,6 @@ dberr_t srv_start(bool create_new_db) srv_undo_tablespaces_active = trx_rseg_get_n_undo_tablespaces(); - - if (srv_operation != SRV_OPERATION_RESTORE) { - dict_sys.load_sys_tables(); - } - - if (UNIV_UNLIKELY(must_upgrade_ibuf)) { - dict_load_tablespaces(); - err = ibuf_upgrade(); - if (err != DB_SUCCESS) { - break; - } - } - - err = trx_lists_init_at_db_start(); break; default: ut_ad("wrong mariabackup mode" == 0); @@ -1599,9 +1582,45 @@ dberr_t srv_start(bool create_new_db) return(srv_init_abort(DB_CORRUPTION)); } + if (srv_operation != SRV_OPERATION_RESTORE + || recv_needed_recovery) { + } + DBUG_PRINT("ib_log", ("apply completed")); - if (recv_needed_recovery) { + if (srv_operation != SRV_OPERATION_RESTORE) { + dict_sys.lock(SRW_LOCK_CALL); + dict_load_sys_table(dict_sys.sys_tables); + dict_sys.unlock(); + + if (UNIV_UNLIKELY(must_upgrade_ibuf)) { + dict_load_tablespaces(nullptr, true); + err = ibuf_upgrade(); + if (err != DB_SUCCESS) { + return srv_init_abort(err); + } + } + + dict_sys.lock(SRW_LOCK_CALL); + dict_load_sys_table(dict_sys.sys_columns); + dict_load_sys_table(dict_sys.sys_indexes); + dict_load_sys_table(dict_sys.sys_fields); + dict_sys.unlock(); + dict_sys.load_sys_tables(); + + err = trx_lists_init_at_db_start(); + if (err != DB_SUCCESS) { + return srv_init_abort(err); + } + + if (recv_needed_recovery) { + trx_sys_print_mysql_binlog_offset(); + } + } else if (recv_needed_recovery) { + err = trx_lists_init_at_db_start(); + if (err != DB_SUCCESS) { + return srv_init_abort(err); + } trx_sys_print_mysql_binlog_offset(); } } @@ -1957,11 +1976,9 @@ void innodb_preshutdown() if (srv_read_only_mode) return; if (!srv_fast_shutdown && srv_operation <= SRV_OPERATION_EXPORT_RESTORED) - { - if (trx_sys.is_initialised()) + if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO && srv_was_started) while (trx_sys.any_active_transactions()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } srv_shutdown_bg_undo_sources(); srv_purge_shutdown(); diff --git a/storage/innobase/sync/srw_lock.cc b/storage/innobase/sync/srw_lock.cc index e41451d8003..5afb79f24ff 100644 --- a/storage/innobase/sync/srw_lock.cc +++ b/storage/innobase/sync/srw_lock.cc @@ -143,8 +143,7 @@ static inline void srw_pause(unsigned delay) HMT_medium(); } -#ifdef SUX_LOCK_GENERIC -# ifndef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +#ifndef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP template<> void pthread_mutex_wrapper::wr_wait() { const unsigned delay= srw_pause_delay(); @@ -158,8 +157,9 @@ template<> void pthread_mutex_wrapper::wr_wait() pthread_mutex_lock(&lock); } -# endif +#endif +#ifdef SUX_LOCK_GENERIC template void ssux_lock_impl::init(); template void ssux_lock_impl::init(); template void ssux_lock_impl::destroy(); diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index fa447c5ed55..ddc4d400a18 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -38,10 +38,10 @@ Created 3/26/1996 Heikki Tuuri #include "trx0roll.h" #include "trx0rseg.h" #include "trx0trx.h" +#include "dict0load.h" +#include #include -#include - /** Maximum allowable purge history length. <=0 means 'infinite'. */ ulong srv_max_purge_lag = 0; @@ -66,9 +66,11 @@ TrxUndoRsegsIterator::TrxUndoRsegsIterator() /** Sets the next rseg to purge in purge_sys. Executed in the purge coordinator thread. -@return whether anything is to be purged */ -TRANSACTIONAL_INLINE inline bool TrxUndoRsegsIterator::set_next() +@retval false when nothing is to be purged +@retval true when purge_sys.rseg->latch was locked */ +inline bool TrxUndoRsegsIterator::set_next() { + ut_ad(!purge_sys.next_stored); mysql_mutex_lock(&purge_sys.pq_mutex); /* Only purge consumes events from the priority queue, user @@ -106,27 +108,23 @@ TRANSACTIONAL_INLINE inline bool TrxUndoRsegsIterator::set_next() ut_ad(purge_sys.rseg->space->id == TRX_SYS_SPACE || srv_is_undo_tablespace(purge_sys.rseg->space->id)); - trx_id_t last_trx_no; - { -#ifdef SUX_LOCK_GENERIC - purge_sys.rseg->latch.rd_lock(SRW_LOCK_CALL); -#else - transactional_shared_lock_guard rg - {purge_sys.rseg->latch}; -#endif - last_trx_no = purge_sys.rseg->last_trx_no(); + purge_sys.rseg->latch.wr_lock(SRW_LOCK_CALL); + trx_id_t last_trx_no = purge_sys.rseg->last_trx_no(); + purge_sys.hdr_offset = purge_sys.rseg->last_offset(); + purge_sys.hdr_page_no = purge_sys.rseg->last_page_no; - purge_sys.hdr_offset = purge_sys.rseg->last_offset(); - purge_sys.hdr_page_no = purge_sys.rseg->last_page_no; - -#ifdef SUX_LOCK_GENERIC - purge_sys.rseg->latch.rd_unlock(); -#endif - } - - /* Only the purge coordinator task will access this object + /* Only the purge_coordinator_task will access this object purge_sys.rseg_iter, or any of purge_sys.hdr_page_no, - purge_sys.tail, purge_sys.head, or modify purge_sys.view. */ + purge_sys.tail. + The field purge_sys.head and purge_sys.view are modified by + purge_sys_t::clone_end_view() + in the purge_coordinator_task + while holding exclusive purge_sys.latch. + The purge_sys.view may also be modified by + purge_sys_t::wake_if_not_active() while holding exclusive + purge_sys.latch. + The purge_sys.head may be read by + purge_truncation_callback(). */ ut_ad(last_trx_no == m_rsegs.trx_no); ut_a(purge_sys.hdr_page_no != FIL_NULL); ut_a(purge_sys.tail.trx_no <= last_trx_no); @@ -168,10 +166,9 @@ purge_graph_build() void purge_sys_t::create() { ut_ad(this == &purge_sys); - ut_ad(!heap); + ut_ad(!m_initialized); ut_ad(!enabled()); m_paused= 0; - m_SYS_paused= 0; query= purge_graph_build(); next_stored= false; rseg= NULL; @@ -184,18 +181,18 @@ void purge_sys_t::create() mysql_mutex_init(purge_sys_pq_mutex_key, &pq_mutex, nullptr); truncate.current= NULL; truncate.last= NULL; - heap= mem_heap_create(4096); + m_initialized= true; } /** Close the purge subsystem on shutdown. */ void purge_sys_t::close() { ut_ad(this == &purge_sys); - if (!heap) + if (!m_initialized) return; ut_ad(!enabled()); - trx_t* trx = query->trx; + trx_t *trx= query->trx; que_graph_free(query); ut_ad(!trx->id); ut_ad(trx->state == TRX_STATE_ACTIVE); @@ -204,8 +201,7 @@ void purge_sys_t::close() latch.destroy(); end_latch.destroy(); mysql_mutex_destroy(&pq_mutex); - mem_heap_free(heap); - heap= nullptr; + m_initialized= false; } /** Determine if the history of a transaction is purgeable. @@ -351,14 +347,21 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr) } /** Free an undo log segment. -@param block rollback segment header page +@param rseg_hdr rollback segment header page +@param block undo segment header page @param mtr mini-transaction */ -static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr) +static void trx_purge_free_segment(buf_block_t *rseg_hdr, buf_block_t *block, + mtr_t &mtr) { + ut_ad(mtr.memo_contains_flagged(rseg_hdr, MTR_MEMO_PAGE_X_FIX)); + ut_ad(mtr.memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX)); + while (!fseg_free_step_not_header(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER + block->page.frame, &mtr)) { + rseg_hdr->fix(); block->fix(); + ut_d(const page_id_t rseg_hdr_id{rseg_hdr->page.id()}); ut_d(const page_id_t id{block->page.id()}); mtr.commit(); /* NOTE: If the server is killed after the log that was produced @@ -369,8 +372,11 @@ static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr) This does not matter when using multiple innodb_undo_tablespaces; innodb_undo_log_truncate=ON will be able to reclaim the space. */ mtr.start(); + rseg_hdr->page.lock.x_lock(); + ut_ad(rseg_hdr->page.id() == rseg_hdr_id); block->page.lock.x_lock(); ut_ad(block->page.id() == id); + mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_MODIFY); mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY); } @@ -460,7 +466,7 @@ loop: free_segment: ut_ad(rseg.curr_size >= seg_size); rseg.curr_size-= seg_size; - trx_purge_free_segment(b, mtr); + trx_purge_free_segment(rseg_hdr, b, mtr); break; case TRX_UNDO_CACHED: /* rseg.undo_cached must point to this page */ @@ -537,6 +543,24 @@ static void trx_purge_cleanse_purge_queue(const fil_space_t& space) mysql_mutex_unlock(&purge_sys.pq_mutex); } +dberr_t purge_sys_t::iterator::free_history() const +{ + for (auto &rseg : trx_sys.rseg_array) + if (rseg.space) + { + ut_ad(rseg.is_persistent()); + log_free_check(); + rseg.latch.wr_lock(SRW_LOCK_CALL); + dberr_t err= + trx_purge_truncate_rseg_history(rseg, *this, !rseg.is_referenced() && + purge_sys.sees(rseg.needs_purge)); + rseg.latch.wr_unlock(); + if (err) + return err; + } + return DB_SUCCESS; +} + #if defined __GNUC__ && __GNUC__ == 4 && !defined __clang__ # if defined __arm__ || defined __aarch64__ /* Work around an internal compiler error in GCC 4.8.5 */ @@ -545,7 +569,8 @@ __attribute__((optimize(0))) #endif /** Remove unnecessary history data from rollback segments. NOTE that when this -function is called, the caller (purge_coordinator_callback) +function is called, the caller +(purge_coordinator_callback or purge_truncation_callback) must not have any latches on undo log pages! */ TRANSACTIONAL_TARGET void trx_purge_truncate_history() @@ -561,22 +586,7 @@ TRANSACTIONAL_TARGET void trx_purge_truncate_history() head.undo_no= 0; } - dberr_t err= DB_SUCCESS; - for (auto &rseg : trx_sys.rseg_array) - if (rseg.space) - { - ut_ad(rseg.is_persistent()); - log_free_check(); - rseg.latch.wr_lock(SRW_LOCK_CALL); - if (dberr_t e= - trx_purge_truncate_rseg_history(rseg, head, - !rseg.is_referenced() && - purge_sys.sees(rseg.needs_purge))) - err= e; - rseg.latch.wr_unlock(); - } - - if (err != DB_SUCCESS || srv_undo_tablespaces_active < 2) + if (head.free_history() != DB_SUCCESS || srv_undo_tablespaces_active < 2) return; while (srv_undo_log_truncate) @@ -675,7 +685,16 @@ not_free: mini-transaction commit and the server was killed, then discarding the to-be-trimmed pages without flushing would break crash recovery. */ + rescan: + if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE) && + srv_fast_shutdown) + { + fast_shutdown: + mtr.commit(); + return; + } + mysql_mutex_lock(&buf_pool.flush_list_mutex); for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.flush_list); bpage; ) { @@ -705,24 +724,28 @@ not_free: ut_ad(!bpage->is_io_fixed()); ut_ad(bpage->id().space() == space_id); - if (bpage->oldest_modification() > 2) - { + if (bpage->oldest_modification() > 2 && + !mtr.have_x_latch(*reinterpret_cast(bpage))) mtr.memo_push(reinterpret_cast(bpage), MTR_MEMO_PAGE_X_FIX); - mysql_mutex_lock(&buf_pool.flush_list_mutex); - ut_ad(bpage->oldest_modification() > 2); - bpage->reset_oldest_modification(); - } else { bpage->unfix(); bpage->lock.x_unlock(); - mysql_mutex_lock(&buf_pool.flush_list_mutex); } + mysql_mutex_lock(&buf_pool.flush_list_mutex); + if (prev != buf_pool.flush_hp.get()) { + /* The functions buf_pool_t::release_freed_page() or + buf_do_flush_list_batch() may be right now holding + buf_pool.mutex and waiting to acquire + buf_pool.flush_list_mutex. Ensure that they can proceed, + to avoid extreme waits. */ mysql_mutex_unlock(&buf_pool.flush_list_mutex); + mysql_mutex_lock(&buf_pool.mutex); + mysql_mutex_unlock(&buf_pool.mutex); goto rescan; } } @@ -732,6 +755,10 @@ not_free: mysql_mutex_unlock(&buf_pool.flush_list_mutex); + if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE) && + srv_fast_shutdown) + goto fast_shutdown; + /* Re-initialize tablespace, in a single mini-transaction. */ const ulint size= SRV_UNDO_TABLESPACE_SIZE_IN_PAGES; @@ -780,6 +807,7 @@ not_free: if trx_t::commit_empty() had been executed in the past, possibly before this server had been started up. */ + dberr_t err; buf_block_t *rblock= trx_rseg_header_create(&space, &rseg - trx_sys.rseg_array, trx_sys.get_max_trx_id(), @@ -821,36 +849,47 @@ not_free: } } -/***********************************************************************//** -Updates the last not yet purged history log info in rseg when we have purged -a whole undo log. Advances also purge_sys.purge_trx_no past the purged log. */ -static void trx_purge_rseg_get_next_history_log( - ulint* n_pages_handled)/*!< in/out: number of UNDO pages - handled */ +buf_block_t *purge_sys_t::get_page(page_id_t id) +{ + buf_block_t*& undo_page= pages[id]; + + if (undo_page) + return undo_page; + + mtr_t mtr; + mtr.start(); + undo_page= + buf_page_get_gen(id, 0, RW_S_LATCH, nullptr, BUF_GET_POSSIBLY_FREED, &mtr); + + if (UNIV_LIKELY(undo_page != nullptr)) + { + undo_page->fix(); + mtr.commit(); + return undo_page; + } + + mtr.commit(); + pages.erase(id); + return nullptr; +} + +void purge_sys_t::rseg_get_next_history_log() { fil_addr_t prev_log_addr; - mtr_t mtr; - mtr.start(); +#ifndef SUX_LOCK_GENERIC + ut_ad(rseg->latch.is_write_locked()); +#endif + ut_a(rseg->last_page_no != FIL_NULL); - purge_sys.rseg->latch.wr_lock(SRW_LOCK_CALL); + tail.trx_no= rseg->last_trx_no() + 1; + tail.undo_no= 0; + next_stored= false; - ut_a(purge_sys.rseg->last_page_no != FIL_NULL); - - purge_sys.tail.trx_no= purge_sys.rseg->last_trx_no() + 1; - purge_sys.tail.undo_no= 0; - purge_sys.next_stored= false; - - if (const buf_block_t* undo_page= - buf_page_get_gen(page_id_t(purge_sys.rseg->space->id, - purge_sys.rseg->last_page_no), - 0, RW_S_LATCH, nullptr, - BUF_GET_POSSIBLY_FREED, &mtr)) + if (buf_block_t *undo_page= + get_page(page_id_t(rseg->space->id, rseg->last_page_no))) { - const trx_ulogf_t *log_hdr= - undo_page->page.frame + purge_sys.rseg->last_offset(); - /* Increase the purge page count by one for every handled log */ - ++*n_pages_handled; + const byte *log_hdr= undo_page->page.frame + rseg->last_offset(); prev_log_addr= flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE); prev_log_addr.boffset = static_cast(prev_log_addr.boffset - TRX_UNDO_HISTORY_NODE); @@ -858,256 +897,386 @@ static void trx_purge_rseg_get_next_history_log( else prev_log_addr.page= FIL_NULL; - const bool empty= prev_log_addr.page == FIL_NULL; + if (prev_log_addr.page == FIL_NULL) + rseg->last_page_no= FIL_NULL; + else + { + /* Read the previous log header. */ + trx_id_t trx_no= 0; + if (const buf_block_t* undo_page= + get_page(page_id_t(rseg->space->id, + prev_log_addr.page))) + { + const byte *log_hdr= undo_page->page.frame + prev_log_addr.boffset; + trx_no= mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO); + } - if (empty) - /* No logs left in the history list */ - purge_sys.rseg->last_page_no= FIL_NULL; + if (UNIV_LIKELY(trx_no != 0)) + { + rseg->last_page_no= prev_log_addr.page; + rseg->set_last_commit(prev_log_addr.boffset, trx_no); - purge_sys.rseg->latch.wr_unlock(); - mtr.commit(); + /* Purge can also produce events, however these are already + ordered in the rollback segment and any user generated event + will be greater than the events that Purge produces. ie. Purge + can never produce events from an empty rollback segment. */ - if (empty) - return; + mysql_mutex_lock(&pq_mutex); + purge_queue.push(*rseg); + mysql_mutex_unlock(&pq_mutex); + } + } - /* Read the previous log header. */ - mtr.start(); - - trx_id_t trx_no= 0; - - if (const buf_block_t* undo_page= - buf_page_get_gen(page_id_t(purge_sys.rseg->space->id, prev_log_addr.page), - 0, RW_S_LATCH, nullptr, BUF_GET_POSSIBLY_FREED, &mtr)) - trx_no= mach_read_from_8(undo_page->page.frame + prev_log_addr.boffset + - TRX_UNDO_TRX_NO); - - mtr.commit(); - - if (UNIV_UNLIKELY(!trx_no)) - return; - - purge_sys.rseg->latch.wr_lock(SRW_LOCK_CALL); - purge_sys.rseg->last_page_no= prev_log_addr.page; - purge_sys.rseg->set_last_commit(prev_log_addr.boffset, trx_no); - - /* Purge can also produce events, however these are already ordered - in the rollback segment and any user generated event will be greater - than the events that Purge produces. ie. Purge can never produce - events from an empty rollback segment. */ - - mysql_mutex_lock(&purge_sys.pq_mutex); - purge_sys.purge_queue.push(*purge_sys.rseg); - mysql_mutex_unlock(&purge_sys.pq_mutex); - purge_sys.rseg->latch.wr_unlock(); + rseg->latch.wr_unlock(); } -/** Position the purge sys "iterator" on the undo record to use for purging. */ -static void trx_purge_read_undo_rec() +/** Position the purge sys "iterator" on the undo record to use for purging. +@retval false when nothing is to be purged +@retval true when purge_sys.rseg->latch was locked */ +bool purge_sys_t::choose_next_log() { - uint16_t offset; - uint32_t page_no; - ib_uint64_t undo_no; + if (!rseg_iter.set_next()) + return false; - purge_sys.hdr_offset = purge_sys.rseg->last_offset(); - page_no = purge_sys.hdr_page_no = purge_sys.rseg->last_page_no; + hdr_offset= rseg->last_offset(); + hdr_page_no= rseg->last_page_no; - if (purge_sys.rseg->needs_purge) { - mtr_t mtr; - mtr.start(); - const buf_block_t* undo_page; - if (trx_undo_rec_t* undo_rec = trx_undo_get_first_rec( - *purge_sys.rseg->space, purge_sys.hdr_page_no, - purge_sys.hdr_offset, RW_S_LATCH, - undo_page, &mtr, nullptr)) { + if (!rseg->needs_purge) + { + purge_nothing: + page_no= hdr_page_no; + offset= 0; + tail.undo_no= 0; + } + else + { + page_id_t id{rseg->space->id, hdr_page_no}; + buf_block_t *b= get_page(id); + if (!b) + goto purge_nothing; + const trx_undo_rec_t *undo_rec= + trx_undo_page_get_first_rec(b, hdr_page_no, hdr_offset); + if (!undo_rec) + { + if (mach_read_from_2(b->page.frame + hdr_offset + TRX_UNDO_NEXT_LOG)) + goto purge_nothing; + const uint32_t next= + mach_read_from_4(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE + + FLST_NEXT + FIL_ADDR_PAGE + b->page.frame); + if (next == FIL_NULL) + goto purge_nothing; + id.set_page_no(next); + b= get_page(id); + if (!b) + goto purge_nothing; + undo_rec= + trx_undo_page_get_first_rec(b, page_no, hdr_offset); + if (!undo_rec) + goto purge_nothing; + } - offset = page_offset(undo_rec); - undo_no = trx_undo_rec_get_undo_no(undo_rec); - page_no = undo_page->page.id().page_no(); - } else { - offset = 0; - undo_no = 0; - } + offset= page_offset(undo_rec); + tail.undo_no= trx_undo_rec_get_undo_no(undo_rec); + page_no= id.page_no(); + } - mtr.commit(); - } else { - offset = 0; - undo_no = 0; - } - - purge_sys.offset = offset; - purge_sys.page_no = page_no; - purge_sys.tail.undo_no = undo_no; - - purge_sys.next_stored = true; + next_stored= true; + return true; } -/***********************************************************************//** -Chooses the next undo log to purge and updates the info in purge_sys. This -function is used to initialize purge_sys when the next record to purge is -not known, and also to update the purge system info on the next record when -purge has handled the whole undo log for a transaction. */ -TRANSACTIONAL_TARGET static void trx_purge_choose_next_log() +/** +Get the next record to purge and update the info in the purge system. +@param roll_ptr undo log pointer to the record +@return buffer-fixed reference to undo log record +@retval {nullptr,1} if the whole undo log can skipped in purge +@retval {nullptr,0} if nothing is left, or on corruption */ +inline trx_purge_rec_t purge_sys_t::get_next_rec(roll_ptr_t roll_ptr) { - ut_ad(!purge_sys.next_stored); + ut_ad(next_stored); + ut_ad(tail.trx_no < low_limit_no()); +#ifndef SUX_LOCK_GENERIC + ut_ad(rseg->latch.is_write_locked()); +#endif - if (purge_sys.rseg_iter.set_next()) { - trx_purge_read_undo_rec(); - } else { - /* There is nothing to do yet. */ - std::this_thread::yield(); - } + if (!offset) + { + /* It is the dummy undo log record, which means that there is no + need to purge this undo log */ + rseg_get_next_history_log(); + + /* Look for the next undo log and record to purge */ + if (choose_next_log()) + rseg->latch.wr_unlock(); + return {nullptr, 1}; + } + + ut_ad(offset == uint16_t(roll_ptr)); + + page_id_t page_id{rseg->space->id, page_no}; + bool locked= true; + buf_block_t *b= get_page(page_id); + if (UNIV_UNLIKELY(!b)) + { + if (locked) + rseg->latch.wr_unlock(); + return {nullptr, 0}; + } + + if (const trx_undo_rec_t *rec2= + trx_undo_page_get_next_rec(b, offset, hdr_page_no, hdr_offset)) + { + got_rec: + ut_ad(page_no == page_id.page_no()); + offset= page_offset(rec2); + tail.undo_no= trx_undo_rec_get_undo_no(rec2); + } + else if (hdr_page_no != page_no || + !mach_read_from_2(b->page.frame + hdr_offset + TRX_UNDO_NEXT_LOG)) + { + uint32_t next= mach_read_from_4(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE + + FLST_NEXT + FIL_ADDR_PAGE + b->page.frame); + if (next != FIL_NULL) + { + page_id.set_page_no(next); + if (buf_block_t *next_page= get_page(page_id)) + { + rec2= trx_undo_page_get_first_rec(next_page, hdr_page_no, hdr_offset); + if (rec2) + { + page_no= next; + goto got_rec; + } + } + } + goto got_no_rec; + } + else + { + got_no_rec: + rseg_get_next_history_log(); + /* Look for the next undo log and record to purge */ + locked= choose_next_log(); + } + + if (locked) + rseg->latch.wr_unlock(); + + return {b->page.frame + uint16_t(roll_ptr), roll_ptr}; } -/***********************************************************************//** -Gets the next record to purge and updates the info in the purge system. -@return copy of an undo log record -@retval -1 if there is nothing to purge -@retval nullptr on corruption */ -static -trx_undo_rec_t* -trx_purge_get_next_rec( -/*===================*/ - ulint* n_pages_handled,/*!< in/out: number of UNDO pages - handled */ - mem_heap_t* heap) /*!< in: memory heap where copied */ +inline trx_purge_rec_t purge_sys_t::fetch_next_rec() { - mtr_t mtr; + roll_ptr_t roll_ptr; - ut_ad(purge_sys.next_stored); - ut_ad(purge_sys.tail.trx_no < purge_sys.low_limit_no()); + if (!next_stored) + { + bool locked= choose_next_log(); + ut_ad(locked == next_stored); + if (!locked) + goto got_nothing; + if (tail.trx_no >= low_limit_no()) + { + rseg->latch.wr_unlock(); + goto got_nothing; + } + /* row_purge_record_func() will later set ROLL_PTR_INSERT_FLAG for + TRX_UNDO_INSERT_REC */ + roll_ptr= trx_undo_build_roll_ptr(false, trx_sys.rseg_id(rseg, true), + page_no, offset); + } + else if (tail.trx_no >= low_limit_no()) + got_nothing: + return {nullptr, 0}; + else + { + roll_ptr= trx_undo_build_roll_ptr(false, trx_sys.rseg_id(rseg, true), + page_no, offset); + rseg->latch.wr_lock(SRW_LOCK_CALL); + } - const page_id_t page_id{purge_sys.rseg->space->id, purge_sys.page_no}; - const uint16_t offset = purge_sys.offset; - - if (offset == 0) { - /* It is the dummy undo log record, which means that there is - no need to purge this undo log */ - - trx_purge_rseg_get_next_history_log(n_pages_handled); - - /* Look for the next undo log and record to purge */ - - trx_purge_choose_next_log(); - return reinterpret_cast(-1); - } - - mtr.start(); - - const buf_block_t* undo_page - = buf_page_get_gen(page_id, 0, RW_S_LATCH, nullptr, - BUF_GET_POSSIBLY_FREED, &mtr); - if (UNIV_UNLIKELY(!undo_page)) { -corrupted: - mtr.commit(); - return nullptr; - } - - const buf_block_t* rec2_page = undo_page; - - const trx_undo_rec_t* rec2 = trx_undo_page_get_next_rec( - undo_page, offset, purge_sys.hdr_page_no, purge_sys.hdr_offset); - - if (rec2 == NULL) { - rec2 = trx_undo_get_next_rec(rec2_page, offset, - purge_sys.hdr_page_no, - purge_sys.hdr_offset, &mtr); - } - - if (rec2 == NULL) { - mtr_commit(&mtr); - - trx_purge_rseg_get_next_history_log(n_pages_handled); - - /* Look for the next undo log and record to purge */ - - trx_purge_choose_next_log(); - - mtr_start(&mtr); - - undo_page = buf_page_get_gen(page_id, 0, RW_S_LATCH, - nullptr, BUF_GET_POSSIBLY_FREED, - &mtr); - if (UNIV_UNLIKELY(!undo_page)) { - goto corrupted; - } - } else { - purge_sys.offset = page_offset(rec2); - purge_sys.page_no = rec2_page->page.id().page_no(); - purge_sys.tail.undo_no = trx_undo_rec_get_undo_no(rec2); - - if (undo_page != rec2_page) { - /* We advance to a new page of the undo log: */ - (*n_pages_handled)++; - } - } - - trx_undo_rec_t* rec_copy = trx_undo_rec_copy(undo_page->page.frame - + offset, heap); - - mtr.commit(); - return rec_copy; + /* The following will advance the purge iterator. */ + return get_next_rec(roll_ptr); } -/********************************************************************//** -Fetches the next undo log record from the history list to purge. It must be -released with the corresponding release function. -@return copy of an undo log record -@retval -1 if the whole undo log can skipped in purge -@retval nullptr if nothing is left, or on corruption */ -static MY_ATTRIBUTE((warn_unused_result)) -trx_undo_rec_t* -trx_purge_fetch_next_rec( -/*=====================*/ - roll_ptr_t* roll_ptr, /*!< out: roll pointer to undo record */ - ulint* n_pages_handled,/*!< in/out: number of UNDO log pages - handled */ - mem_heap_t* heap) /*!< in: memory heap where copied */ +/** Close all tables that were opened in a purge batch for a worker. +@param node purge task context +@param thd purge coordinator thread handle */ +static void trx_purge_close_tables(purge_node_t *node, THD *thd) { - if (!purge_sys.next_stored) { - trx_purge_choose_next_log(); + for (auto &t : node->tables) + { + if (!t.second.first); + else if (t.second.first == reinterpret_cast(-1)); + else + { + dict_table_close(t.second.first, false, thd, t.second.second); + t.second.first= reinterpret_cast(-1); + } + } +} - if (!purge_sys.next_stored) { - DBUG_PRINT("ib_purge", - ("no logs left in the history list")); - return nullptr; - } - } +void purge_sys_t::wait_FTS(bool also_sys) +{ + bool paused; + do + { + latch.wr_lock(SRW_LOCK_CALL); + paused= m_FTS_paused || (also_sys && m_SYS_paused); + latch.wr_unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + while (paused); +} - if (purge_sys.tail.trx_no >= purge_sys.low_limit_no()) { - return nullptr; - } +__attribute__((nonnull)) +/** Aqcuire a metadata lock on a table. +@param table table handle +@param mdl_context metadata lock acquisition context +@param mdl metadata lcok +@return table handle +@retval nullptr if the table is not found or accessible +@retval -1 if the purge of history must be suspended due to DDL */ +static dict_table_t *trx_purge_table_acquire(dict_table_t *table, + MDL_context *mdl_context, + MDL_ticket **mdl) +{ + ut_ad(dict_sys.frozen_not_locked()); + *mdl= nullptr; - /* fprintf(stderr, "Thread %lu purging trx %llu undo record %llu\n", - pthread_self(), iter->trx_no, iter->undo_no); */ + if (!table->is_readable() || table->corrupted) + { + table->release(); + return nullptr; + } - *roll_ptr = trx_undo_build_roll_ptr( - /* row_purge_record_func() will later set - ROLL_PTR_INSERT_FLAG for TRX_UNDO_INSERT_REC */ - false, - trx_sys.rseg_id(purge_sys.rseg, true), - purge_sys.page_no, purge_sys.offset); + size_t db_len= dict_get_db_name_len(table->name.m_name); + if (db_len == 0) + return table; /* InnoDB system tables are not covered by MDL */ - /* The following call will advance the stored values of the - purge iterator. */ + if (purge_sys.must_wait_FTS()) + { + must_wait: + table->release(); + return reinterpret_cast(-1); + } - return trx_purge_get_next_rec(n_pages_handled, heap); + char db_buf[NAME_LEN + 1]; + char tbl_buf[NAME_LEN + 1]; + size_t tbl_len; + + if (!table->parse_name(db_buf, tbl_buf, &db_len, &tbl_len)) + /* The name of an intermediate table starts with #sql */ + return table; + + { + MDL_request request; + MDL_REQUEST_INIT(&request,MDL_key::TABLE, db_buf, tbl_buf, MDL_SHARED, + MDL_EXPLICIT); + if (mdl_context->try_acquire_lock(&request)) + goto must_wait; + *mdl= request.ticket; + if (!*mdl) + goto must_wait; + } + + return table; +} + +/** Open a table handle for the purge of committed transaction history +@param table_id InnoDB table identifier +@param mdl_context metadata lock acquisition context +@param mdl metadata lcok +@return table handle +@retval nullptr if the table is not found or accessible +@retval -1 if the purge of history must be suspended due to DDL */ +static dict_table_t *trx_purge_table_open(table_id_t table_id, + MDL_context *mdl_context, + MDL_ticket **mdl) +{ + dict_sys.freeze(SRW_LOCK_CALL); + + dict_table_t *table= dict_sys.find_table(table_id); + + if (table) + table->acquire(); + else + { + dict_sys.unfreeze(); + dict_sys.lock(SRW_LOCK_CALL); + table= dict_load_table_on_id(table_id, DICT_ERR_IGNORE_FK_NOKEY); + if (table) + table->acquire(); + dict_sys.unlock(); + if (!table) + return nullptr; + dict_sys.freeze(SRW_LOCK_CALL); + } + + table= trx_purge_table_acquire(table, mdl_context, mdl); + dict_sys.unfreeze(); + return table; +} + +ATTRIBUTE_COLD +dict_table_t *purge_sys_t::close_and_reopen(table_id_t id, THD *thd, + MDL_ticket **mdl) +{ + MDL_context *mdl_context= static_cast(thd_mdl_context(thd)); + ut_ad(mdl_context); + retry: + ut_ad(m_active); + + for (que_thr_t *thr= UT_LIST_GET_FIRST(purge_sys.query->thrs); thr; + thr= UT_LIST_GET_NEXT(thrs, thr)) + { + purge_node_t *node= static_cast(thr->child); + trx_purge_close_tables(node, thd); + } + + m_active= false; + wait_FTS(false); + m_active= true; + + dict_table_t *table= trx_purge_table_open(id, mdl_context, mdl); + if (table == reinterpret_cast(-1)) + goto retry; + + for (que_thr_t *thr= UT_LIST_GET_FIRST(purge_sys.query->thrs); thr; + thr= UT_LIST_GET_NEXT(thrs, thr)) + { + purge_node_t *node= static_cast(thr->child); + for (auto &t : node->tables) + { + if (t.second.first) + { + t.second.first= trx_purge_table_open(t.first, mdl_context, + &t.second.second); + if (t.second.first == reinterpret_cast(-1)) + { + if (table) + dict_table_close(table, false, thd, *mdl); + goto retry; + } + } + } + } + + return table; } /** Run a purge batch. @param n_purge_threads number of purge threads -@return number of undo log pages handled in the batch */ -static -ulint -trx_purge_attach_undo_recs(ulint n_purge_threads) +@return new purge_sys.head */ +static purge_sys_t::iterator +trx_purge_attach_undo_recs(ulint n_purge_threads, THD *thd) { que_thr_t* thr; ulint i; - ulint n_pages_handled = 0; - ulint n_thrs = UT_LIST_GET_LEN(purge_sys.query->thrs); ut_a(n_purge_threads > 0); + ut_a(UT_LIST_GET_LEN(purge_sys.query->thrs) >= n_purge_threads); - purge_sys.head = purge_sys.tail; + purge_sys_t::iterator head = purge_sys.tail; #ifdef UNIV_DEBUG i = 0; @@ -1135,50 +1304,55 @@ trx_purge_attach_undo_recs(ulint n_purge_threads) /* Fetch and parse the UNDO records. The UNDO records are added to a per purge node vector. */ thr = UT_LIST_GET_FIRST(purge_sys.query->thrs); - ut_a(n_thrs > 0 && thr != NULL); - ut_ad(purge_sys.head <= purge_sys.tail); + ut_ad(head <= purge_sys.tail); i = 0; - std::unordered_map table_id_map; - mem_heap_empty(purge_sys.heap); + std::unordered_map + table_id_map(TRX_PURGE_TABLE_BUCKETS); + purge_sys.m_active = true; + + MDL_context* const mdl_context + = static_cast(thd_mdl_context(thd)); + ut_ad(mdl_context); + + const size_t max_pages = std::min(buf_pool.curr_size * 3 / 4, + size_t{srv_purge_batch_size}); while (UNIV_LIKELY(srv_undo_sources) || !srv_fast_shutdown) { - purge_node_t* node; - trx_purge_rec_t purge_rec; - - /* Get the purge node. */ - node = (purge_node_t*) thr->child; - ut_a(que_node_get_type(node) == QUE_NODE_PURGE); - /* Track the max {trx_id, undo_no} for truncating the UNDO logs once we have purged the records. */ - if (purge_sys.head <= purge_sys.tail) { - purge_sys.head = purge_sys.tail; + if (head <= purge_sys.tail) { + head = purge_sys.tail; } /* Fetch the next record, and advance the purge_sys.tail. */ - purge_rec.undo_rec = trx_purge_fetch_next_rec( - &purge_rec.roll_ptr, &n_pages_handled, - purge_sys.heap); + trx_purge_rec_t purge_rec = purge_sys.fetch_next_rec(); - if (purge_rec.undo_rec == NULL) { - break; - } else if (purge_rec.undo_rec - == reinterpret_cast(-1)) { + if (!purge_rec.undo_rec) { + if (!purge_rec.roll_ptr) { + break; + } + ut_ad(purge_rec.roll_ptr == 1); continue; } table_id_t table_id = trx_undo_rec_get_table_id( purge_rec.undo_rec); - purge_node_t *& table_node = table_id_map[table_id]; + purge_node_t*& table_node = table_id_map[table_id]; + + if (!table_node) { + std::pair p; + p.first = trx_purge_table_open(table_id, mdl_context, + &p.second); + if (p.first == reinterpret_cast(-1)) { + p.first = purge_sys.close_and_reopen( + table_id, thd, &p.second); + } - if (table_node) { - node = table_node; - } else { thr = UT_LIST_GET_NEXT(thrs, thr); if (!(++i % n_purge_threads)) { @@ -1186,20 +1360,29 @@ trx_purge_attach_undo_recs(ulint n_purge_threads) purge_sys.query->thrs); } - ut_a(thr != NULL); - table_node = node; + table_node = static_cast(thr->child); + ut_a(que_node_get_type(table_node) == QUE_NODE_PURGE); + ut_d(auto i=) + table_node->tables.emplace(table_id, p); + ut_ad(i.second); + if (p.first) { + goto enqueue; + } + } else if (table_node->tables[table_id].first) { +enqueue: + table_node->undo_recs.push(purge_rec); } - node->undo_recs.push(purge_rec); - - if (n_pages_handled >= srv_purge_batch_size) { + if (purge_sys.n_pages_handled() >= max_pages) { break; } } - ut_ad(purge_sys.head <= purge_sys.tail); + purge_sys.m_active = false; - return(n_pages_handled); + ut_ad(head <= purge_sys.tail); + + return head; } extern tpool::waitable_task purge_worker_task; @@ -1222,9 +1405,15 @@ static void trx_purge_wait_for_workers_to_complete() ut_ad(srv_get_task_queue_length() == 0); } -/** Update end_view at the end of a purge batch. */ -TRANSACTIONAL_INLINE void purge_sys_t::clone_end_view() +TRANSACTIONAL_INLINE +void purge_sys_t::batch_cleanup(const purge_sys_t::iterator &head) { + /* Release the undo pages. */ + for (auto p : pages) + p.second->unfix(); + pages.clear(); + pages.reserve(srv_purge_batch_size); + /* This is only invoked only by the purge coordinator, which is the only thread that can modify our inputs head, tail, view. Therefore, we only need to protect end_view from concurrent reads. */ @@ -1236,6 +1425,7 @@ TRANSACTIONAL_INLINE void purge_sys_t::clone_end_view() #else transactional_lock_guard g(end_latch); #endif + this->head= head; end_view= view; end_view.clamp_low_limit_id(trx_no); #ifdef SUX_LOCK_GENERIC @@ -1250,9 +1440,6 @@ Run a purge batch. @return number of undo log pages handled in the batch */ TRANSACTIONAL_TARGET ulint trx_purge(ulint n_tasks, ulint history_size) { - que_thr_t* thr = NULL; - ulint n_pages_handled; - ut_ad(n_tasks > 0); purge_sys.clone_oldest_view(); @@ -1263,11 +1450,15 @@ TRANSACTIONAL_TARGET ulint trx_purge(ulint n_tasks, ulint history_size) } #endif /* UNIV_DEBUG */ + THD* const thd = current_thd; + /* Fetch the UNDO recs that need to be purged. */ - n_pages_handled = trx_purge_attach_undo_recs(n_tasks); + const purge_sys_t::iterator head + = trx_purge_attach_undo_recs(n_tasks, thd); + const size_t n_pages = purge_sys.n_pages_handled(); { - ulint delay = n_pages_handled ? srv_max_purge_lag : 0; + ulint delay = n_pages ? srv_max_purge_lag : 0; if (UNIV_UNLIKELY(delay)) { if (delay >= history_size) { no_throttle: @@ -1284,6 +1475,8 @@ TRANSACTIONAL_TARGET ulint trx_purge(ulint n_tasks, ulint history_size) srv_dml_needed_delay = delay; } + que_thr_t* thr = nullptr; + /* Submit tasks to workers queue if using multi-threaded purge. */ for (ulint i = n_tasks; --i; ) { thr = que_fork_scheduler_round_robin(purge_sys.query, thr); @@ -1298,10 +1491,17 @@ TRANSACTIONAL_TARGET ulint trx_purge(ulint n_tasks, ulint history_size) trx_purge_wait_for_workers_to_complete(); - purge_sys.clone_end_view(); + for (thr = UT_LIST_GET_FIRST(purge_sys.query->thrs); thr; + thr = UT_LIST_GET_NEXT(thrs, thr)) { + purge_node_t* node = static_cast(thr->child); + trx_purge_close_tables(node, thd); + node->tables.clear(); + } + + purge_sys.batch_cleanup(head); MONITOR_INC_VALUE(MONITOR_PURGE_INVOKED, 1); - MONITOR_INC_VALUE(MONITOR_PURGE_N_PAGE_HANDLED, n_pages_handled); + MONITOR_INC_VALUE(MONITOR_PURGE_N_PAGE_HANDLED, n_pages); - return(n_pages_handled); + return n_pages; } diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 843c2f66175..2923dc6477d 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -484,9 +484,9 @@ const byte* trx_undo_rec_get_pars( /*==================*/ const trx_undo_rec_t* undo_rec, /*!< in: undo log record */ - ulint* type, /*!< out: undo record type: + byte* type, /*!< out: undo record type: TRX_UNDO_INSERT_REC, ... */ - ulint* cmpl_info, /*!< out: compiler info, relevant only + byte* cmpl_info, /*!< out: compiler info, relevant only for update type records */ bool* updated_extern, /*!< out: true if we updated an externally stored fild */ @@ -503,7 +503,7 @@ trx_undo_rec_get_pars( *type = type_cmpl & (TRX_UNDO_CMPL_INFO_MULT - 1); ut_ad(*type >= TRX_UNDO_RENAME_TABLE); ut_ad(*type <= TRX_UNDO_EMPTY); - *cmpl_info = type_cmpl / TRX_UNDO_CMPL_INFO_MULT; + *cmpl_info = byte(type_cmpl / TRX_UNDO_CMPL_INFO_MULT); *undo_no = mach_read_next_much_compressed(&ptr); *table_id = mach_read_next_much_compressed(&ptr); @@ -2068,12 +2068,24 @@ trx_undo_get_undo_rec_low( mtr.start(); - const buf_block_t* undo_page= - buf_page_get(page_id_t(rseg->space->id, page_no), 0, RW_S_LATCH, &mtr); - - trx_undo_rec_t *undo_rec= undo_page - ? trx_undo_rec_copy(undo_page->page.frame + offset, heap) - : nullptr; + trx_undo_rec_t *undo_rec= nullptr; + if (buf_block_t* undo_page= + buf_page_get(page_id_t(rseg->space->id, page_no), 0, RW_S_LATCH, &mtr)) + { + buf_page_make_young_if_needed(&undo_page->page); + undo_rec= undo_page->page.frame + offset; + const size_t end= mach_read_from_2(undo_rec); + if (UNIV_UNLIKELY(end <= offset || + end >= srv_page_size - FIL_PAGE_DATA_END)) + undo_rec= nullptr; + else + { + size_t len{end - offset}; + undo_rec= + static_cast(mem_heap_dup(heap, undo_rec, len)); + mach_write_to_2(undo_rec, len); + } + } mtr.commit(); return undo_rec; @@ -2160,14 +2172,14 @@ trx_undo_prev_version_build( { dtuple_t* entry; trx_id_t rec_trx_id; - ulint type; undo_no_t undo_no; table_id_t table_id; trx_id_t trx_id; roll_ptr_t roll_ptr; upd_t* update; + byte type; byte info_bits; - ulint cmpl_info; + byte cmpl_info; bool dummy_extern; byte* buf; @@ -2342,7 +2354,7 @@ trx_undo_prev_version_build( update vector to dtuple vrow */ if (v_status & TRX_UNDO_GET_OLD_V_VALUE) { row_upd_replace_vcol((dtuple_t*)*vrow, index->table, update, - false, NULL, NULL); + false, nullptr, nullptr); } #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index e730530adb2..d0231d54090 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -296,8 +296,13 @@ buf_block_t *trx_rseg_t::get(mtr_t *mtr, dberr_t *err) const if (err) *err= DB_TABLESPACE_NOT_FOUND; return nullptr; } - return buf_page_get_gen(page_id(), 0, RW_X_LATCH, nullptr, - BUF_GET, mtr, err); + + buf_block_t *block= buf_page_get_gen(page_id(), 0, RW_X_LATCH, nullptr, + BUF_GET, mtr, err); + if (UNIV_LIKELY(block != nullptr)) + buf_page_make_young_if_needed(&block->page); + + return block; } /** Upgrade a rollback segment header page to MariaDB 10.3 format. @@ -462,20 +467,32 @@ 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= + + /* 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(reinterpret_cast(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); - memcpy(trx_sys.recovered_binlog_filename, binlog_name, - TRX_RSEG_BINLOG_NAME_LEN); + 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 @@ -546,6 +563,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 @@ -560,6 +578,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 f56f0d5ce6f..7d21e34dfac 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -582,15 +582,16 @@ static dberr_t trx_resurrect_table_locks(trx_t *trx, const trx_undo_t &undo) undo.top_page_no), 0, RW_S_LATCH, nullptr, BUF_GET, &mtr, &err)) { + buf_page_make_young_if_needed(&block->page); buf_block_t *undo_block= block; const trx_undo_rec_t *undo_rec= block->page.frame + undo.top_offset; do { - ulint type; + byte type; + byte cmpl_info; undo_no_t undo_no; table_id_t table_id; - ulint cmpl_info; bool updated_extern; if (undo_block != block) @@ -980,7 +981,13 @@ void trx_t::commit_empty(mtr_t *mtr) trx_undo_t *&undo= rsegs.m_redo.undo; ut_ad(undo->state == TRX_UNDO_ACTIVE || undo->state == TRX_UNDO_PREPARED); - ut_ad(undo->size == 1); + + if (UNIV_UNLIKELY(undo->size != 1)) + { + sql_print_error("InnoDB: Undo log for transaction " TRX_ID_FMT + " is corrupted (" UINT32PF "!=1)", id, undo->size); + ut_ad("corrupted undo log" == 0); + } if (buf_block_t *u= buf_page_get(page_id_t(rseg->space->id, undo->hdr_page_no), 0, @@ -1504,6 +1511,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/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index 345a8362ec7..d17f84248f1 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -25,8 +25,8 @@ Created 3/26/1996 Heikki Tuuri *******************************************************/ #include "trx0undo.h" +#include "buf0rea.h" #include "fsp0fsp.h" -#include "mach0data.h" #include "mtr0log.h" #include "srv0mon.h" #include "srv0srv.h" @@ -128,8 +128,8 @@ uint16_t trx_undo_page_get_start(const buf_block_t *block, uint32_t page_no, @param[in] page_no undo log header page number @param[in] offset undo log header page offset @return pointer to first record -@retval NULL if none exists */ -static trx_undo_rec_t* +@retval nullptr if none exists */ +trx_undo_rec_t* trx_undo_page_get_first_rec(const buf_block_t *block, uint32_t page_no, uint16_t offset) { @@ -178,8 +178,12 @@ trx_undo_get_prev_rec_from_prev_page(buf_block_t *&block, uint16_t rec, block= buf_page_get(page_id_t(block->page.id().space(), prev_page_no), 0, shared ? RW_S_LATCH : RW_X_LATCH, mtr); + if (UNIV_UNLIKELY(!block)) + return nullptr; - return block ? trx_undo_page_get_last_rec(block, page_no, offset) : nullptr; + if (!buf_page_make_young_if_needed(&block->page)) + buf_read_ahead_linear(block->page.id(), 0); + return trx_undo_page_get_last_rec(block, page_no, offset); } /** Get the previous undo log record. @@ -253,25 +257,6 @@ trx_undo_get_next_rec_from_next_page(const buf_block_t *&block, return block ? trx_undo_page_get_first_rec(block, page_no, offset) : nullptr; } -/** Get the next record in an undo log. -@param[in,out] block undo log page -@param[in] rec undo record offset in the page -@param[in] page_no undo log header page number -@param[in] offset undo log header offset on page -@param[in,out] mtr mini-transaction -@return undo log record, the page latched, NULL if none */ -trx_undo_rec_t* -trx_undo_get_next_rec(const buf_block_t *&block, uint16_t rec, - uint32_t page_no, uint16_t offset, mtr_t *mtr) -{ - if (trx_undo_rec_t *next= trx_undo_page_get_next_rec(block, rec, page_no, - offset)) - return next; - - return trx_undo_get_next_rec_from_next_page(block, page_no, offset, - RW_S_LATCH, mtr); -} - /** Get the first record in an undo log. @param[in] space undo log header space @param[in] page_no undo log header page number @@ -282,35 +267,34 @@ trx_undo_get_next_rec(const buf_block_t *&block, uint16_t rec, @param[out] err error code @return undo log record, the page latched @retval nullptr if none */ -trx_undo_rec_t* +static trx_undo_rec_t* trx_undo_get_first_rec(const fil_space_t &space, uint32_t page_no, uint16_t offset, ulint mode, const buf_block_t*& block, mtr_t *mtr, dberr_t *err) { - block= buf_page_get_gen(page_id_t{space.id, page_no}, 0, mode, - nullptr, BUF_GET, mtr, err); + buf_block_t *b= buf_page_get_gen(page_id_t{space.id, page_no}, 0, mode, + nullptr, BUF_GET, mtr, err); + block= b; if (!block) return nullptr; - if (trx_undo_rec_t *rec= trx_undo_page_get_first_rec(block, page_no, offset)) + if (!buf_page_make_young_if_needed(&b->page)) + buf_read_ahead_linear(b->page.id(), 0); + + if (trx_undo_rec_t *rec= trx_undo_page_get_first_rec(b, page_no, offset)) return rec; return trx_undo_get_next_rec_from_next_page(block, page_no, offset, mode, mtr); } -inline void UndorecApplier::assign_rec(const buf_block_t &block, - uint16_t offset) -{ - ut_ad(block.page.lock.have_s()); - this->offset= offset; - this->undo_rec= trx_undo_rec_copy(block.page.frame + offset, heap); -} - -inline void UndorecApplier::apply_undo_rec() +inline void UndorecApplier::apply_undo_rec(const trx_undo_rec_t *rec) { + undo_rec= rec; if (!undo_rec) return; + offset= page_offset(undo_rec); + bool updated_extern= false; undo_no_t undo_no= 0; table_id_t table_id= 0; @@ -382,14 +366,14 @@ ATTRIBUTE_COLD void trx_t::apply_log() undo->hdr_offset); while (rec) { - log_applier.assign_rec(*block, page_offset(rec)); + block->page.fix(); mtr.commit(); - log_applier.apply_undo_rec(); + /* Since we are the only thread who could write to this undo page, + it is safe to dereference rec while only holding a buffer-fix. */ + log_applier.apply_undo_rec(rec); mtr.start(); - block= buf_page_get(log_applier.get_page_id(), 0, RW_S_LATCH, &mtr); - if (UNIV_UNLIKELY(!block)) - goto func_exit; - rec= trx_undo_page_get_next_rec(block, log_applier.get_offset(), + mtr.page_lock(block, RW_S_LATCH); + rec= trx_undo_page_get_next_rec(block, page_offset(rec), page_id.page_no(), undo->hdr_offset); } @@ -406,7 +390,6 @@ ATTRIBUTE_COLD void trx_t::apply_log() break; log_applier.assign_next(next_page_id); } -func_exit: mtr.commit(); apply_online_log= false; } @@ -634,8 +617,9 @@ static void trx_undo_write_xid(buf_block_t *block, uint16_t offset, static_cast(xid.bqual_length)); const ulint xid_length= static_cast(xid.gtrid_length + xid.bqual_length); - mtr->memcpy(*block, &block->page.frame[offset + TRX_UNDO_XA_XID], - xid.data, xid_length); + mtr->memcpy(*block, + &block->page.frame[offset + TRX_UNDO_XA_XID], + xid.data, xid_length); if (UNIV_LIKELY(xid_length < XIDDATASIZE)) mtr->memset(block, offset + TRX_UNDO_XA_XID + xid_length, XIDDATASIZE - xid_length, 0); @@ -682,6 +666,8 @@ buf_block_t *trx_undo_add_page(trx_undo_t *undo, mtr_t *mtr, dberr_t *err) 0, RW_X_LATCH, nullptr, BUF_GET, mtr, err); if (!header_block) goto func_exit; + buf_page_make_young_if_needed(&header_block->page); + *err= fsp_reserve_free_extents(&n_reserved, rseg->space, 1, FSP_UNDO, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) @@ -751,6 +737,8 @@ trx_undo_free_page( return FIL_NULL; } + buf_page_make_young_if_needed(&header_block->page); + *err = flst_remove(header_block, TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST, undo_block, TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE, mtr); @@ -759,6 +747,14 @@ trx_undo_free_page( return FIL_NULL; } + const fil_addr_t last_addr = flst_get_last( + TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + + header_block->page.frame); + if (UNIV_UNLIKELY(last_addr.page == page_no)) { + *err = DB_CORRUPTION; + return FIL_NULL; + } + *err = fseg_free_page(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER + header_block->page.frame, rseg->space, page_no, mtr); @@ -767,9 +763,6 @@ trx_undo_free_page( } buf_page_free(rseg->space, page_no, mtr); - const fil_addr_t last_addr = flst_get_last( - TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST - + header_block->page.frame); rseg->curr_size--; if (!in_history) { @@ -813,6 +806,9 @@ static dberr_t trx_undo_truncate_end(trx_undo_t &undo, undo_no_t limit, { ut_ad(is_temp == !undo.rseg->is_persistent()); + if (UNIV_UNLIKELY(undo.last_page_no == FIL_NULL)) + return DB_CORRUPTION; + for (mtr_t mtr;;) { mtr.start(); @@ -1256,8 +1252,8 @@ trx_undo_reuse_cached(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** pundo, ut_ad(rseg == trx->rsegs.m_redo.rseg); if (rseg->needs_purge <= trx->id) { - /* trx_purge_truncate_history() compares - rseg->needs_purge <= head.trx_no + /* trx_purge_truncate_history() checks + purge_sys.sees(rseg.needs_purge) so we need to compensate for that. The rseg->needs_purge after crash recovery would be at least trx->id + 1, @@ -1282,6 +1278,8 @@ trx_undo_reuse_cached(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** pundo, return NULL; } + buf_page_make_young_if_needed(&block->page); + UT_LIST_REMOVE(rseg->undo_cached, undo); *pundo = undo; @@ -1316,19 +1314,24 @@ trx_undo_assign(trx_t* trx, dberr_t* err, mtr_t* mtr) ut_ad(mtr->get_log_mode() == MTR_LOG_ALL); trx_undo_t* undo = trx->rsegs.m_redo.undo; + buf_block_t* block; if (undo) { - return buf_page_get_gen( + block = buf_page_get_gen( page_id_t(undo->rseg->space->id, undo->last_page_no), 0, RW_X_LATCH, undo->guess_block, BUF_GET, mtr, err); + if (UNIV_LIKELY(block != nullptr)) { + buf_page_make_young_if_needed(&block->page); + } + return block; } *err = DB_SUCCESS; trx_rseg_t* rseg = trx->rsegs.m_redo.rseg; rseg->latch.wr_lock(SRW_LOCK_CALL); - buf_block_t* block = trx_undo_reuse_cached( + block = trx_undo_reuse_cached( trx, rseg, &trx->rsegs.m_redo.undo, mtr, err); if (!block) { @@ -1369,12 +1372,17 @@ trx_undo_assign_low(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo, : &trx->rsegs.m_redo.undo)); ut_ad(mtr->get_log_mode() == (is_temp ? MTR_LOG_NO_REDO : MTR_LOG_ALL)); + buf_block_t* block; if (*undo) { - return buf_page_get_gen( + block = buf_page_get_gen( page_id_t(rseg->space->id, (*undo)->last_page_no), 0, RW_X_LATCH, (*undo)->guess_block, BUF_GET, mtr, err); + if (UNIV_LIKELY(block != nullptr)) { + buf_page_make_young_if_needed(&block->page); + } + return block; } DBUG_EXECUTE_IF( @@ -1384,7 +1392,6 @@ trx_undo_assign_low(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo, *err = DB_SUCCESS; rseg->latch.wr_lock(SRW_LOCK_CALL); - buf_block_t* block; if (is_temp) { ut_ad(!UT_LIST_GET_LEN(rseg->undo_cached)); } else { diff --git a/storage/maria/aria_s3_copy.cc b/storage/maria/aria_s3_copy.cc index 5c8c2abc7db..6dfe7572a3f 100644 --- a/storage/maria/aria_s3_copy.cc +++ b/storage/maria/aria_s3_copy.cc @@ -89,7 +89,9 @@ static struct my_option my_long_options[] = &opt_block_size, &opt_block_size, 0, GET_ULONG, REQUIRED_ARG, 4*1024*1024, 64*1024, 16*1024*1024, MALLOC_OVERHEAD, 1024, 0 }, {"s3_protocol_version", 'L', - "Protocol used to communication with S3. One of \"Auto\", \"Amazon\" or \"Original\".", + "Protocol used to communication with S3. One of \"Auto\", \"Legacy\", " + "\"Original\", \"Amazon\", \"Path\" or \"Domain\". " + "Note: \"Legacy\", \"Original\" and \"Amazon\" are deprecated.", &opt_protocol_version, &opt_protocol_version, &s3_protocol_typelib, GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', "Force copy even if target exists", @@ -191,7 +193,7 @@ static void get_options(int *argc, char ***argv) my_exit(-1); } if (opt_s3_debug) - ms3_debug(); + ms3_debug(1); } /* get_options */ @@ -214,9 +216,20 @@ int main(int argc, char** argv) ms3_set_option(global_s3_client, MS3_OPT_BUFFER_CHUNK_SIZE, &block_size); - if (opt_protocol_version) + if (opt_protocol_version > 2) { - uint8_t protocol_version= (uint8_t) opt_protocol_version; + uint8_t protocol_version; + switch (opt_protocol_version) + { + case 3: /* Legacy means v1 */ + case 4: /* Path means v1 */ + protocol_version= 1; + break; + case 5: /* Domain means v2 */ + protocol_version= 2; + break; + } + ms3_set_option(global_s3_client, MS3_OPT_FORCE_PROTOCOL_VERSION, &protocol_version); } diff --git a/storage/maria/ha_s3.cc b/storage/maria/ha_s3.cc index 1baf8c53869..d8bc7e86a87 100644 --- a/storage/maria/ha_s3.cc +++ b/storage/maria/ha_s3.cc @@ -121,6 +121,29 @@ static void update_secret_key(MYSQL_THD thd, } } +static void update_s3_debug(MYSQL_THD thd, + struct st_mysql_sys_var *var + __attribute__((unused)), + void *var_ptr __attribute__((unused)), + const void *save) +{ + char new_state= *(char *) save; + if (s3_debug != new_state) + { + s3_debug= new_state; + if (s3_hton) // If library is initalized + { + ms3_debug(new_state); + if (!new_state) + { + /* Ensure that all logging is written to log */ + fflush(stderr); + } + } + } +} + + /* Define system variables for S3 */ static MYSQL_SYSVAR_ULONG(block_size, s3_block_size, @@ -129,9 +152,9 @@ static MYSQL_SYSVAR_ULONG(block_size, s3_block_size, 4*1024*1024, 65536, 16*1024*1024, 8192); static MYSQL_SYSVAR_BOOL(debug, s3_debug, - PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + PLUGIN_VAR_RQCMDARG, "Generates trace file from libmarias3 on stderr for debugging", - 0, 0, 0); + 0, update_s3_debug, 0); static MYSQL_SYSVAR_BOOL(slave_ignore_updates, s3_slave_ignore_updates, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, @@ -147,7 +170,10 @@ static MYSQL_SYSVAR_BOOL(replicate_alter_as_create_select, static MYSQL_SYSVAR_ENUM(protocol_version, s3_protocol_version, PLUGIN_VAR_RQCMDARG, "Protocol used to communication with S3. One of " - "\"Auto\", \"Amazon\" or \"Original\".", + "\"Auto\", \"Legacy\", \"Original\", \"Amazon\", " + "\"Path\" or \"Domain\". " + "Note: \"Legacy\", \"Original\" and \"Amazon\" are " + "deprecated.", NULL, NULL, 0, &s3_protocol_typelib); static MYSQL_SYSVAR_ULONG(pagecache_age_threshold, @@ -1049,7 +1075,7 @@ static int ha_s3_init(void *p) s3_pagecache.big_block_free= s3_free; s3_init_library(); if (s3_debug) - ms3_debug(); + ms3_debug(1); struct s3_func s3f_real = { diff --git a/storage/maria/libmarias3 b/storage/maria/libmarias3 index 3846890513d..a81724ab07b 160000 --- a/storage/maria/libmarias3 +++ b/storage/maria/libmarias3 @@ -1 +1 @@ -Subproject commit 3846890513df0653b8919bc45a7600f9b55cab31 +Subproject commit a81724ab07bd28e16bf431419c24b6362d5894fc diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index bd014be0353..f30e2c78ffc 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -5796,9 +5796,9 @@ static int sort_maria_ft_key_write(MARIA_SORT_PARAM *sort_param, } get_key_full_length_rdonly(val_off, ft_buf->lastkey); - if (ha_compare_text(sort_param->seg->charset, - a+1,a_len-1, - ft_buf->lastkey+1,val_off-1, 0)==0) + if (ha_compare_word(sort_param->seg->charset, + a + 1, a_len - 1, + ft_buf->lastkey + 1, val_off - 1) == 0) { uchar *p; if (!ft_buf->buf) /* store in second-level tree */ diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c index 91e39716a2b..a7bc2a7f318 100644 --- a/storage/maria/ma_ft_boolean_search.c +++ b/storage/maria/ma_ft_boolean_search.c @@ -162,8 +162,8 @@ static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b) static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b) { /* ORDER BY word, ndepth */ - int i= ha_compare_text(cs, (uchar*) (*a)->word + 1,(*a)->len - 1, - (uchar*) (*b)->word + 1,(*b)->len - 1, 0); + int i= ha_compare_word(cs, (uchar*) (*a)->word + 1, (*a)->len - 1, + (uchar*) (*b)->word + 1, (*b)->len - 1); if (!i) i=CMP_NUM((*a)->ndepth, (*b)->ndepth); return i; @@ -403,13 +403,14 @@ static int _ft2_search_no_lock(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) if (!r && !ftbw->off) { - r= ha_compare_text(ftb->charset, - info->last_key.data+1, - info->last_key.data_length + info->last_key.ref_length- - extra-1, - (uchar*) ftbw->word+1, - ftbw->len-1, - (my_bool) (ftbw->flags & FTB_FLAG_TRUNC)); + r= ha_compare_word_or_prefix(ftb->charset, + info->last_key.data + 1, + info->last_key.data_length + + info->last_key.ref_length - + extra - 1, + (uchar*) ftbw->word + 1, + ftbw->len - 1, + (my_bool) (ftbw->flags & FTB_FLAG_TRUNC)); } if (r) /* not found */ @@ -899,9 +900,9 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param, for (a= 0, b= ftb->queue.elements, c= (a+b)/2; b-a>1; c= (a+b)/2) { ftbw= ftb->list[c]; - if (ha_compare_text(ftb->charset, (uchar*)word, len, - (uchar*)ftbw->word+1, ftbw->len-1, - (my_bool)(ftbw->flags&FTB_FLAG_TRUNC)) < 0) + if (ha_compare_word_or_prefix(ftb->charset, (uchar*) word, len, + (uchar*) ftbw->word + 1, ftbw->len - 1, + (my_bool) (ftbw->flags & FTB_FLAG_TRUNC)) < 0) b= c; else a= c; @@ -926,9 +927,9 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param, for (; c >= 0; c--) { ftbw= ftb->list[c]; - if (ha_compare_text(ftb->charset, (uchar*)word, len, - (uchar*)ftbw->word + 1,ftbw->len - 1, - (my_bool)(ftbw->flags & FTB_FLAG_TRUNC))) + if (ha_compare_word_or_prefix(ftb->charset, (uchar*) word, len, + (uchar*)ftbw->word + 1, ftbw->len - 1, + (my_bool) (ftbw->flags & FTB_FLAG_TRUNC))) { if (ftb->with_scan & FTB_FLAG_TRUNC) continue; diff --git a/storage/maria/ma_ft_nlq_search.c b/storage/maria/ma_ft_nlq_search.c index 6c4e30bca83..890de3db0ad 100644 --- a/storage/maria/ma_ft_nlq_search.c +++ b/storage/maria/ma_ft_nlq_search.c @@ -111,11 +111,11 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) while (!r && gweight) { if (key.data_length && - ha_compare_text(aio->charset, - info->last_key.data+1, + ha_compare_word(aio->charset, + info->last_key.data + 1, info->last_key.data_length + info->last_key.ref_length - extra - 1, - key.data+1, key.data_length-1, 0)) + key.data + 1, key.data_length - 1)) break; if (subkeys.i < 0) diff --git a/storage/maria/ma_ft_parser.c b/storage/maria/ma_ft_parser.c index 847965a8aee..f600873d54d 100644 --- a/storage/maria/ma_ft_parser.c +++ b/storage/maria/ma_ft_parser.c @@ -34,8 +34,8 @@ typedef struct st_my_maria_ft_parser_param static int FT_WORD_cmp(CHARSET_INFO* cs, FT_WORD *w1, FT_WORD *w2) { - return ha_compare_text(cs, (uchar*) w1->pos, w1->len, - (uchar*) w2->pos, w2->len, 0); + return ha_compare_word(cs, (uchar*) w1->pos, w1->len, + (uchar*) w2->pos, w2->len); } static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat) diff --git a/storage/maria/ma_ft_update.c b/storage/maria/ma_ft_update.c index b048a8a2c5a..868e15f9344 100644 --- a/storage/maria/ma_ft_update.c +++ b/storage/maria/ma_ft_update.c @@ -185,8 +185,7 @@ int _ma_ft_cmp(MARIA_HA *info, uint keynr, const uchar *rec1, const uchar *rec2) { if ((ftsi1.pos != ftsi2.pos) && (!ftsi1.pos || !ftsi2.pos || - ha_compare_text(cs, ftsi1.pos,ftsi1.len, - ftsi2.pos,ftsi2.len,0))) + ha_compare_word(cs, ftsi1.pos, ftsi1.len, ftsi2.pos, ftsi2.len))) DBUG_RETURN(THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT); } DBUG_RETURN(GEE_THEY_ARE_ABSOLUTELY_IDENTICAL); @@ -213,8 +212,8 @@ int _ma_ft_update(MARIA_HA *info, uint keynr, uchar *keybuf, error=0; while(old_word->pos && new_word->pos) { - cmp= ha_compare_text(cs, (uchar*) old_word->pos,old_word->len, - (uchar*) new_word->pos,new_word->len,0); + cmp= ha_compare_word(cs, (uchar*) old_word->pos, old_word->len, + (uchar*) new_word->pos, new_word->len); cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5); if (cmp < 0 || cmp2) diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index c3615e5271c..d62ec3c8c89 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -8457,34 +8457,41 @@ my_bool translog_is_file(uint file_no) static uint32 translog_first_file(TRANSLOG_ADDRESS horizon, int is_protected) { - uint min_file= 0, max_file; + uint min_file= 1, max_file; DBUG_ENTER("translog_first_file"); if (!is_protected) mysql_mutex_lock(&log_descriptor.purger_lock); - if (log_descriptor.min_file_number && - translog_is_file(log_descriptor.min_file_number)) + if (log_descriptor.min_file_number) { - DBUG_PRINT("info", ("cached %lu", - (ulong) log_descriptor.min_file_number)); - if (!is_protected) - mysql_mutex_unlock(&log_descriptor.purger_lock); - DBUG_RETURN(log_descriptor.min_file_number); + min_file= log_descriptor.min_file_number; + if (translog_is_file(log_descriptor.min_file_number)) + { + DBUG_PRINT("info", ("cached %lu", + (ulong) log_descriptor.min_file_number)); + if (!is_protected) + mysql_mutex_unlock(&log_descriptor.purger_lock); + DBUG_RETURN(log_descriptor.min_file_number); + } } max_file= LSN_FILE_NO(horizon); + if (!translog_is_file(max_file)) + { + if (!is_protected) + mysql_mutex_unlock(&log_descriptor.purger_lock); + DBUG_RETURN(max_file); /* For compatibility */ + } /* binary search for last file */ - while (min_file != max_file && min_file != (max_file - 1)) + while (min_file < max_file) { uint test= (min_file + max_file) / 2; DBUG_PRINT("info", ("min_file: %u test: %u max_file: %u", min_file, test, max_file)); - if (test == max_file) - test--; if (translog_is_file(test)) max_file= test; else - min_file= test; + min_file= test+1; } log_descriptor.min_file_number= max_file; if (!is_protected) @@ -8753,9 +8760,9 @@ my_bool translog_purge(TRANSLOG_ADDRESS low) /** @brief Purges files by stored min need file in case of - "ondemend" purge type + "one demand" purge type - @note This function do real work only if it is "ondemend" purge type + @note This function do real work only if it is "one demand" purge type and translog_purge() was called at least once and last time without errors @@ -8794,13 +8801,14 @@ my_bool translog_purge_at_flush() min_file= translog_first_file(translog_get_horizon(), 1); DBUG_ASSERT(min_file != 0); /* log is already started */ - for(i= min_file; i < log_descriptor.min_need_file && rc == 0; i++) + for(i= min_file; i < log_descriptor.min_need_file ; i++) { char path[FN_REFLEN], *file_name; DBUG_PRINT("info", ("purge file %lu\n", (ulong) i)); file_name= translog_filename_by_fileno(i, path); - rc= MY_TEST(mysql_file_delete(key_file_translog, + rc|= MY_TEST(mysql_file_delete(key_file_translog, file_name, MYF(MY_WME))); + DBUG_ASSERT(rc == 0); } mysql_mutex_unlock(&log_descriptor.purger_lock); diff --git a/storage/maria/ma_unique.c b/storage/maria/ma_unique.c index c9ad27c2a6c..5e7925b937c 100644 --- a/storage/maria/ma_unique.c +++ b/storage/maria/ma_unique.c @@ -237,11 +237,22 @@ my_bool _ma_unique_comp(MARIA_UNIQUEDEF *def, const uchar *a, const uchar *b, memcpy((void*) &pos_a, pos_a+keyseg->bit_start, sizeof(char*)); memcpy((void*) &pos_b, pos_b+keyseg->bit_start, sizeof(char*)); } - if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT1 || - type == HA_KEYTYPE_VARTEXT2) + if (type == HA_KEYTYPE_TEXT/* the CHAR data type*/) { - if (ha_compare_text(keyseg->charset, pos_a, a_length, - pos_b, b_length, 0)) + if (ha_compare_char_fixed(keyseg->charset, + pos_a, a_length, + pos_b, b_length, + keyseg->length / keyseg->charset->mbmaxlen, + FALSE/*b_is_prefix*/)) + return 1; + } + else if (type == HA_KEYTYPE_VARTEXT1 || + type == HA_KEYTYPE_VARTEXT2) + { + if (ha_compare_char_varying(keyseg->charset, + pos_a, a_length, + pos_b, b_length, + FALSE/*b_is_prefix*/)) return 1; } else diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index 88f3d22c205..9a6859bfd4d 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -891,8 +891,10 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0 get_key_length(alen,a); DBUG_ASSERT(info->ft1_to_ft2==0); if (alen == blen && - ha_compare_text(keyinfo->seg->charset, a, alen, - b, blen, 0) == 0) + ha_compare_char_varying(keyinfo->seg->charset, + a, alen, + b, blen, + FALSE/*b_is_prefix*/) == 0) { /* Yup. converting */ info->ft1_to_ft2=(DYNAMIC_ARRAY *) diff --git a/storage/maria/s3_func.c b/storage/maria/s3_func.c index 3d18ba8800d..d85dc8a0b40 100644 --- a/storage/maria/s3_func.c +++ b/storage/maria/s3_func.c @@ -39,7 +39,7 @@ static int s3_read_file_from_disk(const char *filename, uchar **to, /* Used by ha_s3.cc and tools to define different protocol options */ -static const char *protocol_types[]= {"Auto", "Original", "Amazon", NullS}; +static const char *protocol_types[]= {"Auto", "Original", "Amazon", "Legacy", "Path", "Domain", NullS}; TYPELIB s3_protocol_typelib= {array_elements(protocol_types)-1,"", protocol_types, NULL}; @@ -154,9 +154,23 @@ ms3_st *s3_open_connection(S3_INFO *s3) errno, ms3_error(errno)); my_errno= HA_ERR_NO_SUCH_TABLE; } - if (s3->protocol_version) + if (s3->protocol_version > 2) + { + uint8_t protocol_version; + switch (s3->protocol_version) + { + case 3: /* Legacy means v1 */ + case 4: /* Path means v1 */ + protocol_version= 1; + break; + case 5: /* Domain means v2 */ + protocol_version= 2; + break; + } + ms3_set_option(s3_client, MS3_OPT_FORCE_PROTOCOL_VERSION, - &s3->protocol_version); + &protocol_version); + } if (s3->port) ms3_set_option(s3_client, MS3_OPT_PORT_NUMBER, &s3->port); diff --git a/storage/mroonga/vendor/groonga/include/groonga/groonga.h b/storage/mroonga/vendor/groonga/include/groonga/groonga.h index 0e465152894..214b0745bfd 100644 --- a/storage/mroonga/vendor/groonga/include/groonga/groonga.h +++ b/storage/mroonga/vendor/groonga/include/groonga/groonga.h @@ -1640,7 +1640,7 @@ GRN_API int grn_charlen(grn_ctx *ctx, const char *str, const char *end); GRN_API grn_rc grn_ctx_push(grn_ctx *ctx, grn_obj *obj); GRN_API grn_obj *grn_ctx_pop(grn_ctx *ctx); -GRN_API int grn_obj_columns(grn_ctx *ctx, grn_obj *table, +GRN_API grn_rc grn_obj_columns(grn_ctx *ctx, grn_obj *table, const char *str, unsigned int str_size, grn_obj *res); GRN_API grn_rc grn_load(grn_ctx *ctx, grn_content_type input_type, diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index a91467c5b8d..f69f1869383 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -162,8 +162,8 @@ static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b) static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b) { /* ORDER BY word, ndepth */ - int i= ha_compare_text(cs, (uchar*) (*a)->word + 1, (*a)->len - 1, - (uchar*) (*b)->word + 1, (*b)->len - 1, 0); + int i= ha_compare_word(cs, (uchar*) (*a)->word + 1, (*a)->len - 1, + (uchar*) (*b)->word + 1, (*b)->len - 1); if (!i) i= CMP_NUM((*a)->ndepth, (*b)->ndepth); return i; @@ -407,12 +407,12 @@ static int _ft2_search_no_lock(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) if (!r && !ftbw->off) { - r= ha_compare_text(ftb->charset, - info->lastkey+1, - info->lastkey_length-extra-1, - (uchar*) ftbw->word+1, - ftbw->len-1, - (my_bool) (ftbw->flags & FTB_FLAG_TRUNC)); + r= ha_compare_word_or_prefix(ftb->charset, + info->lastkey + 1, + info->lastkey_length - extra - 1, + (uchar*) ftbw->word + 1, + ftbw->len - 1, + (my_bool) (ftbw->flags & FTB_FLAG_TRUNC)); } if (r) /* not found */ @@ -907,9 +907,9 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param, for (a= 0, b= ftb->queue.elements, c= (a+b)/2; b-a>1; c= (a+b)/2) { ftbw= ftb->list[c]; - if (ha_compare_text(ftb->charset, (uchar*)word, len, - (uchar*)ftbw->word+1, ftbw->len-1, - (my_bool) (ftbw->flags & FTB_FLAG_TRUNC)) < 0) + if (ha_compare_word_or_prefix(ftb->charset, (uchar*)word, len, + (uchar*)ftbw->word + 1, ftbw->len - 1, + (my_bool) (ftbw->flags & FTB_FLAG_TRUNC)) < 0) b= c; else a= c; @@ -934,9 +934,9 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param, for (; c >= 0; c--) { ftbw= ftb->list[c]; - if (ha_compare_text(ftb->charset, (uchar*)word, len, - (uchar*)ftbw->word + 1,ftbw->len - 1, - (my_bool)(ftbw->flags & FTB_FLAG_TRUNC))) + if (ha_compare_word_or_prefix(ftb->charset, (uchar*) word, len, + (uchar*) ftbw->word + 1, ftbw->len - 1, + (my_bool) (ftbw->flags & FTB_FLAG_TRUNC))) { if (ftb->with_scan & FTB_FLAG_TRUNC) continue; diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c index eb95d1e0b94..90a509057cf 100644 --- a/storage/myisam/ft_nlq_search.c +++ b/storage/myisam/ft_nlq_search.c @@ -109,8 +109,10 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) { if (keylen && - ha_compare_text(aio->charset,info->lastkey+1, - info->lastkey_length-extra-1, keybuff+1,keylen-1,0)) + ha_compare_word(aio->charset, + info->lastkey + 1, + info->lastkey_length - extra - 1, + keybuff + 1, keylen - 1)) break; if (subkeys.i < 0) diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c index 61b1915d5e0..ec392b6ecd8 100644 --- a/storage/myisam/ft_parser.c +++ b/storage/myisam/ft_parser.c @@ -32,8 +32,8 @@ typedef struct st_my_ft_parser_param static int FT_WORD_cmp(CHARSET_INFO* cs, FT_WORD *w1, FT_WORD *w2) { - return ha_compare_text(cs, (uchar*) w1->pos, w1->len, - (uchar*) w2->pos, w2->len, 0); + return ha_compare_word(cs, (uchar*) w1->pos, w1->len, + (uchar*) w2->pos, w2->len); } static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat) diff --git a/storage/myisam/ft_stopwords.c b/storage/myisam/ft_stopwords.c index 34c445cc163..b666c1f3a79 100644 --- a/storage/myisam/ft_stopwords.c +++ b/storage/myisam/ft_stopwords.c @@ -33,9 +33,9 @@ static TREE *stopwords3=NULL; static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)), FT_STOPWORD *w1, FT_STOPWORD *w2) { - return ha_compare_text(ft_stopword_cs, - (uchar *)w1->pos,w1->len, - (uchar *)w2->pos,w2->len,0); + return ha_compare_word(ft_stopword_cs, + (uchar *) w1->pos, w1->len, + (uchar *) w2->pos, w2->len); } static int FT_STOPWORD_free(FT_STOPWORD *w, TREE_FREE action, diff --git a/storage/myisam/ft_update.c b/storage/myisam/ft_update.c index 157e5423168..2da619dcdfd 100644 --- a/storage/myisam/ft_update.c +++ b/storage/myisam/ft_update.c @@ -181,8 +181,8 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const uchar *rec1, const uchar *rec2) { if ((ftsi1.pos != ftsi2.pos) && (!ftsi1.pos || !ftsi2.pos || - ha_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len, - (uchar*) ftsi2.pos,ftsi2.len,0))) + ha_compare_word(cs, (uchar*) ftsi1.pos, ftsi1.len, + (uchar*) ftsi2.pos, ftsi2.len))) DBUG_RETURN(THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT); } DBUG_RETURN(GEE_THEY_ARE_ABSOLUTELY_IDENTICAL); @@ -210,8 +210,8 @@ int _mi_ft_update(MI_INFO *info, uint keynr, uchar *keybuf, error=0; while(old_word->pos && new_word->pos) { - cmp= ha_compare_text(cs, (uchar*) old_word->pos,old_word->len, - (uchar*) new_word->pos,new_word->len,0); + cmp= ha_compare_word(cs, (uchar*) old_word->pos, old_word->len, + (uchar*) new_word->pos, new_word->len); cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5); if (cmp < 0 || cmp2) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 802f8f803ca..e050e46c8db 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -710,6 +710,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 */ @@ -1022,6 +1032,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/mi_check.c b/storage/myisam/mi_check.c index 87e51816d81..33fab259a9c 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -3963,9 +3963,9 @@ static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a) } get_key_full_length_rdonly(val_off, ft_buf->lastkey); - if (ha_compare_text(sort_param->seg->charset, - ((uchar *)a)+1,a_len-1, - (uchar*) ft_buf->lastkey+1,val_off-1, 0)==0) + if (ha_compare_word(sort_param->seg->charset, + ((uchar *)a) + 1, a_len - 1, + (uchar*) ft_buf->lastkey + 1, val_off - 1) == 0) { if (!ft_buf->buf) /* store in second-level tree */ { diff --git a/storage/myisam/mi_unique.c b/storage/myisam/mi_unique.c index e1d7aeaa711..ecc2b354849 100644 --- a/storage/myisam/mi_unique.c +++ b/storage/myisam/mi_unique.c @@ -212,11 +212,22 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const uchar *a, const uchar *b, memcpy((char**) &pos_a, pos_a+keyseg->bit_start, sizeof(char*)); memcpy((char**) &pos_b, pos_b+keyseg->bit_start, sizeof(char*)); } - if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT1 || - type == HA_KEYTYPE_VARTEXT2) + if (type == HA_KEYTYPE_TEXT/*The CHAR data type*/) { - if (ha_compare_text(keyseg->charset, (uchar *) pos_a, a_length, - (uchar *) pos_b, b_length, 0)) + if (ha_compare_char_fixed(keyseg->charset, + (uchar *) pos_a, a_length, + (uchar *) pos_b, b_length, + keyseg->length / keyseg->charset->mbmaxlen, + FALSE/*b_is_prefix*/)) + return 1; + } + else if (type == HA_KEYTYPE_VARTEXT1 || + type == HA_KEYTYPE_VARTEXT2) + { + if (ha_compare_char_varying(keyseg->charset, + (uchar *) pos_a, a_length, + (uchar *) pos_b, b_length, + FALSE/*b_is_prefix*/)) return 1; } else diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c index 7d489908725..e8a985a5fd4 100644 --- a/storage/myisam/mi_write.c +++ b/storage/myisam/mi_write.c @@ -542,7 +542,9 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo, get_key_length(alen,a); DBUG_ASSERT(info->ft1_to_ft2==0); if (alen == blen && - ha_compare_text(keyinfo->seg->charset, a, alen, b, blen, 0)==0) + ha_compare_word(keyinfo->seg->charset, + a, alen, + b, blen) == 0) { /* yup. converting */ info->ft1_to_ft2=(DYNAMIC_ARRAY *) diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index 375c1840f3e..0fb475c4d72 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -529,6 +529,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/perfschema/pfs.cc b/storage/perfschema/pfs.cc index 8b3a159f7a2..1373f9dd43d 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -3068,8 +3068,7 @@ pfs_start_table_io_wait_v1(PSI_table_locker_state *state, PFS_table_share *share= pfs_table->m_share; wait->m_thread_internal_id= pfs_thread->m_thread_internal_id; - if (wait->m_class == NULL || wait->m_class->m_type != PFS_CLASS_TABLE_LOCK) - wait->m_class= &global_table_io_class; + wait->m_class= &global_table_io_class; wait->m_timer_start= timer_start; wait->m_timer_end= 0; wait->m_object_instance_addr= pfs_table->m_identity; diff --git a/storage/perfschema/pfs_variable.cc b/storage/perfschema/pfs_variable.cc index 239c55b623c..3f7fd73683a 100644 --- a/storage/perfschema/pfs_variable.cc +++ b/storage/perfschema/pfs_variable.cc @@ -66,7 +66,7 @@ static inline SHOW_SCOPE show_scope_from_type(enum enum_mysql_show_type type) case SHOW_SIMPLE_FUNC: case SHOW_UNDEF: default: - return SHOW_SCOPE_UNDEF; + return SHOW_SCOPE_ALL; } return SHOW_SCOPE_UNDEF; } @@ -254,7 +254,7 @@ int PFS_system_variable_cache::do_materialize_all(THD *unsafe_thd) } /* Release lock taken in get_THD(). */ - mysql_mutex_unlock(&m_safe_thd->LOCK_thd_data); + mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill); m_materialized= true; ret= 0; @@ -354,7 +354,7 @@ int PFS_system_variable_cache::do_materialize_session(PFS_thread *pfs_thread) } /* Release lock taken in get_THD(). */ - mysql_mutex_unlock(&m_safe_thd->LOCK_thd_data); + mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill); m_materialized= true; ret= 0; @@ -407,7 +407,7 @@ int PFS_system_variable_cache::do_materialize_session(PFS_thread *pfs_thread, ui } /* Release lock taken in get_THD(). */ - mysql_mutex_unlock(&m_safe_thd->LOCK_thd_data); + mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill); m_materialized= true; ret= 0; @@ -458,7 +458,7 @@ int PFS_system_variable_cache::do_materialize_session(THD *unsafe_thd) } /* Release lock taken in get_THD(). */ - mysql_mutex_unlock(&m_safe_thd->LOCK_thd_data); + mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill); m_materialized= true; ret= 0; @@ -716,6 +716,7 @@ bool PFS_status_variable_cache::can_aggregate(enum_mysql_show_type variable_type case SHOW_CHAR_PTR: case SHOW_ARRAY: case SHOW_FUNC: + case SHOW_SIMPLE_FUNC: case SHOW_INT: case SHOW_LONG: case SHOW_LONGLONG: @@ -761,7 +762,7 @@ bool PFS_status_variable_cache::filter_show_var(const SHOW_VAR *show_var, bool s /** Build an array of SHOW_VARs from the global status array. Expand nested subarrays, filter unwanted variables. - NOTE: Must be done inside of LOCK_status to guard against plugin load/unload. + NOTE: Must be done under LOCK_all_status_vars */ bool PFS_status_variable_cache::init_show_var_array(enum_var_type scope, bool strict) { @@ -880,14 +881,12 @@ char * PFS_status_variable_cache::make_show_var_name(const char* prefix, const c */ bool PFS_status_variable_cache::do_initialize_session(void) { - /* Acquire LOCK_status to guard against plugin load/unload. */ - //if (m_current_thd->fill_status_recursion_level++ == 0) - mysql_mutex_lock(&LOCK_status); + /* Acquire LOCK_all_status_vars to guard against plugin load/unload. */ + mysql_rwlock_rdlock(&LOCK_all_status_vars); bool ret= init_show_var_array(OPT_SESSION, true); - //if (m_current_thd->fill_status_recursion_level-- == 1) - mysql_mutex_unlock(&LOCK_status); + mysql_rwlock_unlock(&LOCK_all_status_vars); return ret; } @@ -916,13 +915,12 @@ int PFS_status_variable_cache::do_materialize_global(void) m_materialized= false; DEBUG_SYNC(m_current_thd, "before_materialize_global_status_array"); - /* Acquire LOCK_status to guard against plugin load/unload. */ - //if (m_current_thd->fill_status_recursion_level++ == 0) - mysql_mutex_lock(&LOCK_status); + /* Acquire LOCK_all_status_vars to guard against plugin load/unload. */ + mysql_rwlock_rdlock(&LOCK_all_status_vars); /* - Build array of SHOW_VARs from global status array. Do this within - LOCK_status to ensure that the array remains unchanged during + Build array of SHOW_VARs from global status array. Do this under + LOCK_all_status_vars to ensure that the array remains unchanged during materialization. */ if (!m_external_init) @@ -945,8 +943,7 @@ int PFS_status_variable_cache::do_materialize_global(void) */ manifest(m_current_thd, m_show_var_array.front(), &status_totals, "", false, true); - //if (m_current_thd->fill_status_recursion_level-- == 1) - mysql_mutex_unlock(&LOCK_status); + mysql_rwlock_unlock(&LOCK_all_status_vars); m_materialized= true; DEBUG_SYNC(m_current_thd, "after_materialize_global_status_array"); @@ -966,13 +963,11 @@ int PFS_status_variable_cache::do_materialize_all(THD* unsafe_thd) m_materialized= false; m_cache.clear(); - /* Avoid recursive acquisition of LOCK_status. */ - //if (m_current_thd->fill_status_recursion_level++ == 0) - mysql_mutex_lock(&LOCK_status); + mysql_rwlock_rdlock(&LOCK_all_status_vars); /* - Build array of SHOW_VARs from global status array. Do this within - LOCK_status to ensure that the array remains unchanged while this + Build array of SHOW_VARs from global status array. Do this under + LOCK_all_status_vars to ensure that the array remains unchanged while this thread is materialized. */ if (!m_external_init) @@ -989,14 +984,13 @@ int PFS_status_variable_cache::do_materialize_all(THD* unsafe_thd) manifest(m_safe_thd, m_show_var_array.front(), status_vars, "", false, false); /* Release lock taken in get_THD(). */ - mysql_mutex_unlock(&m_safe_thd->LOCK_thd_data); + mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill); m_materialized= true; ret= 0; } - //if (m_current_thd->fill_status_recursion_level-- == 1) - mysql_mutex_unlock(&LOCK_status); + mysql_rwlock_unlock(&LOCK_all_status_vars); return ret; } @@ -1012,13 +1006,11 @@ int PFS_status_variable_cache::do_materialize_session(THD* unsafe_thd) m_materialized= false; m_cache.clear(); - /* Avoid recursive acquisition of LOCK_status. */ - //if (m_current_thd->fill_status_recursion_level++ == 0) - mysql_mutex_lock(&LOCK_status); + mysql_rwlock_rdlock(&LOCK_all_status_vars); /* - Build array of SHOW_VARs from global status array. Do this within - LOCK_status to ensure that the array remains unchanged while this + Build array of SHOW_VARs from global status array. Do this under + LOCK_all_status_vars to ensure that the array remains unchanged while this thread is materialized. */ if (!m_external_init) @@ -1035,14 +1027,13 @@ int PFS_status_variable_cache::do_materialize_session(THD* unsafe_thd) manifest(m_safe_thd, m_show_var_array.front(), status_vars, "", false, true); /* Release lock taken in get_THD(). */ - mysql_mutex_unlock(&m_safe_thd->LOCK_thd_data); + mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill); m_materialized= true; ret= 0; } - //if (m_current_thd->fill_status_recursion_level-- == 1) - mysql_mutex_unlock(&LOCK_status); + mysql_rwlock_unlock(&LOCK_all_status_vars); return ret; } @@ -1059,9 +1050,8 @@ int PFS_status_variable_cache::do_materialize_session(PFS_thread *pfs_thread) m_materialized= false; m_cache.clear(); - /* Acquire LOCK_status to guard against plugin load/unload. */ - //if (m_current_thd->fill_status_recursion_level++ == 0) - mysql_mutex_lock(&LOCK_status); + /* Acquire LOCK_all_status_vars to guard against plugin load/unload. */ + mysql_rwlock_rdlock(&LOCK_all_status_vars); /* The SHOW_VAR array must be initialized externally. */ assert(m_initialized); @@ -1077,14 +1067,13 @@ int PFS_status_variable_cache::do_materialize_session(PFS_thread *pfs_thread) manifest(m_safe_thd, m_show_var_array.front(), status_vars, "", false, true); /* Release lock taken in get_THD(). */ - mysql_mutex_unlock(&m_safe_thd->LOCK_thd_data); + mysql_mutex_unlock(&m_safe_thd->LOCK_thd_kill); m_materialized= true; ret= 0; } - //if (m_current_thd->fill_status_recursion_level-- == 1) - mysql_mutex_unlock(&LOCK_status); + mysql_rwlock_unlock(&LOCK_all_status_vars); return ret; } @@ -1103,9 +1092,8 @@ int PFS_status_variable_cache::do_materialize_client(PFS_client *pfs_client) m_materialized= false; m_cache.clear(); - /* Acquire LOCK_status to guard against plugin load/unload. */ - //if (m_current_thd->fill_status_recursion_level++ == 0) - mysql_mutex_lock(&LOCK_status); + /* Acquire LOCK_all_status_vars to guard against plugin load/unload. */ + mysql_rwlock_rdlock(&LOCK_all_status_vars); /* The SHOW_VAR array must be initialized externally. */ assert(m_initialized); @@ -1122,8 +1110,7 @@ int PFS_status_variable_cache::do_materialize_client(PFS_client *pfs_client) */ manifest(m_current_thd, m_show_var_array.front(), &status_totals, "", false, true); - //if (m_current_thd->fill_status_recursion_level-- == 1) - mysql_mutex_unlock(&LOCK_status); + mysql_rwlock_unlock(&LOCK_all_status_vars); m_materialized= true; return 0; @@ -1152,16 +1139,19 @@ void PFS_status_variable_cache::manifest(THD *thd, const SHOW_VAR *show_var_arra reevaluate the new SHOW_TYPE and value. Handle nested case where SHOW_FUNC resolves to another SHOW_FUNC. */ - if (show_var_ptr->type == SHOW_FUNC) + if (show_var_ptr->type == SHOW_FUNC || show_var_ptr->type == SHOW_SIMPLE_FUNC) { show_var_tmp= *show_var_ptr; /* Execute the function reference in show_var_tmp->value, which returns show_var_tmp with a new type and new value. */ - for (const SHOW_VAR *var= show_var_ptr; var->type == SHOW_FUNC; var= &show_var_tmp) + for (const SHOW_VAR *var= show_var_ptr; + var->type == SHOW_FUNC || var->type == SHOW_SIMPLE_FUNC; + var= &show_var_tmp) { - ((mysql_show_var_func)(var->value))(thd, &show_var_tmp, value_buf.data, NULL, m_query_scope); + ((mysql_show_var_func)(var->value))(thd, &show_var_tmp, value_buf.data, + &thd->status_var, m_query_scope); } show_var_ptr= &show_var_tmp; } @@ -1213,7 +1203,7 @@ Status_variable::Status_variable(const SHOW_VAR *show_var, STATUS_VAR *status_va /** Resolve status value, convert to string. show_var->value is an offset into status_vars. - NOTE: Assumes LOCK_status is held. + NOTE: Assumes LOCK_all_status_vars is held. */ void Status_variable::init(const SHOW_VAR *show_var, STATUS_VAR *status_vars, enum_var_type query_scope) { @@ -1279,7 +1269,7 @@ void sum_account_status(PFS_client *pfs_account, STATUS_VAR *status_totals) /** Reset aggregated status counter stats for account, user and host. - NOTE: Assumes LOCK_status is held. + NOTE: Assumes LOCK_all_status_vars is held. */ void reset_pfs_status_stats() { diff --git a/storage/perfschema/pfs_variable.h b/storage/perfschema/pfs_variable.h index d3ad4c7f900..fda8dc692d9 100644 --- a/storage/perfschema/pfs_variable.h +++ b/storage/perfschema/pfs_variable.h @@ -212,7 +212,7 @@ public: return false; /* Hold this lock to keep THD during materialization. */ - mysql_mutex_lock(&thd->LOCK_thd_data); + mysql_mutex_lock(&thd->LOCK_thd_kill); return true; } void set_unsafe_thd(THD *unsafe_thd) { m_unsafe_thd= unsafe_thd; } diff --git a/storage/perfschema/pfs_visitor.cc b/storage/perfschema/pfs_visitor.cc index 92a5c99e13b..7e3027ac9a6 100644 --- a/storage/perfschema/pfs_visitor.cc +++ b/storage/perfschema/pfs_visitor.cc @@ -1356,8 +1356,7 @@ PFS_connection_status_visitor::~PFS_connection_status_visitor() = default; /** Aggregate from global status. */ void PFS_connection_status_visitor::visit_global() { - /* NOTE: Requires lock on LOCK_status. */ - mysql_mutex_assert_owner(&LOCK_status); + /* NOTE: Requires lock on LOCK_all_status_vars. */ add_to_status(m_status_vars, &global_status_var); } diff --git a/storage/perfschema/table_helper.h b/storage/perfschema/table_helper.h index ddea4c08b36..87572ef2525 100644 --- a/storage/perfschema/table_helper.h +++ b/storage/perfschema/table_helper.h @@ -659,7 +659,7 @@ public: private: void make_row(const CHARSET_INFO *cs, const char* str, size_t length); - char m_str[1024]; + char m_str[2048]; uint m_length; const CHARSET_INFO *m_charset; }; diff --git a/storage/perfschema/unittest/stub_pfs_global.h b/storage/perfschema/unittest/stub_pfs_global.h index 4b792f9bfef..e6876dccfe6 100644 --- a/storage/perfschema/unittest/stub_pfs_global.h +++ b/storage/perfschema/unittest/stub_pfs_global.h @@ -58,7 +58,7 @@ void *pfs_malloc(PFS_builtin_memory_class *klass, size_t size, myf) void pfs_free(PFS_builtin_memory_class *, size_t, void *ptr) { if (ptr != NULL) - free(ptr); + aligned_free(ptr); } void *pfs_malloc_array(PFS_builtin_memory_class *klass, size_t n, size_t size, myf flags) diff --git a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result index 8612b922cab..68240d98533 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result @@ -30,7 +30,7 @@ lock_rec_locks lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 coun lock_table_lock_created lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of table locks created lock_table_lock_removed lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of table locks removed from the lock queue lock_table_locks lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Current number of table locks on tables -lock_row_lock_current_waits lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of row locks currently being waited for (innodb_row_lock_current_waits) +lock_row_lock_current_waits lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of row locks currently being waited for (innodb_row_lock_current_waits) lock_row_lock_time lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Time spent in acquiring row locks, in milliseconds (innodb_row_lock_time) lock_row_lock_time_max lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value The maximum time to acquire a row lock, in milliseconds (innodb_row_lock_time_max) lock_row_lock_waits lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of times a row lock had to be waited for (innodb_row_lock_waits) diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index a97a4500d71..05fff7201df 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -58,7 +58,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; @@ -118,7 +118,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; @@ -357,10 +357,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()) @@ -391,7 +391,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()); } } @@ -844,6 +844,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); @@ -872,10 +880,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 */ @@ -3575,7 +3580,7 @@ int ha_spider::multi_range_read_next_first( spider_free(spider_current_trx, multi_range_keys, MYF(0)); } 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))) ) @@ -3588,7 +3593,7 @@ int ha_spider::multi_range_read_next_first( 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); } error_num = 0; if ((range_res = mrr_funcs.next(mrr_iter, &mrr_cur_range))) @@ -6051,7 +6056,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)); @@ -8260,37 +8265,11 @@ int ha_spider::direct_delete_rows( int ha_spider::delete_all_rows() { - int error_num; THD *thd = ha_thd(); - backup_error_status(); DBUG_ENTER("ha_spider::delete_all_rows"); - DBUG_PRINT("info",("spider this=%p", this)); if (spider_param_delete_all_rows_type(thd, share->delete_all_rows_type)) DBUG_RETURN(HA_ERR_WRONG_COMMAND); - if (spider_param_read_only_mode(thd, share->read_only_mode)) - { - my_printf_error(ER_SPIDER_READ_ONLY_NUM, ER_SPIDER_READ_ONLY_STR, MYF(0), - table_share->db.str, table_share->table_name.str); - DBUG_RETURN(ER_SPIDER_READ_ONLY_NUM); - } - do_direct_update = FALSE; - if ((error_num = spider_db_delete_all_rows(this))) - DBUG_RETURN(check_error_mode(error_num)); - if (wide_handler->sql_command == SQLCOM_TRUNCATE && - table->found_next_number_field) - { - DBUG_PRINT("info",("spider reset auto increment")); - pthread_mutex_lock(&share->lgtm_tblhnd_share->auto_increment_mutex); - share->lgtm_tblhnd_share->auto_increment_lclval = 1; - share->lgtm_tblhnd_share->auto_increment_init = FALSE; - share->lgtm_tblhnd_share->auto_increment_value = 1; - DBUG_PRINT("info",("spider init auto_increment_lclval=%llu", - share->lgtm_tblhnd_share->auto_increment_lclval)); - DBUG_PRINT("info",("spider auto_increment_value=%llu", - share->lgtm_tblhnd_share->auto_increment_value)); - pthread_mutex_unlock(&share->lgtm_tblhnd_share->auto_increment_mutex); - } - DBUG_RETURN(0); + DBUG_RETURN(truncate()); } int ha_spider::truncate() @@ -8490,7 +8469,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)) @@ -8505,7 +8484,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, form->part_info, @@ -8922,12 +8901,6 @@ int ha_spider::delete_table( DBUG_PRINT("info", ("spider alter_info.flags: %llu alter_info.partition_flags: %lu", thd->lex->alter_info.flags, thd->lex->alter_info.partition_flags)); - if ((error_num = spider_sys_delete_table_sts( - current_thd, name, name_len))) - goto error; - if ((error_num = spider_sys_delete_table_crd( - current_thd, name, name_len))) - goto error; if ( !(table_tables = spider_open_sys_table( current_thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, @@ -9129,7 +9102,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; 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/ddl_log.result b/storage/spider/mysql-test/spider/bugfix/r/ddl_log.result new file mode 100644 index 00000000000..2abbcc6bc30 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/ddl_log.result @@ -0,0 +1,12 @@ +# restart: --plugin-load-add=ha_spider +# +# MDEV-32532 Assertion failure in ddl_log_increment_phase_no_lock upon +# partition operations with spider plugin loaded +# +CREATE TABLE t1 (a INT) PARTITION BY HASH (a) PARTITIONS 2; +ALTER TABLE t1 REBUILD PARTITION p0; +drop table t1; +# +# End of 10.10 +# +uninstall plugin spider; 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_26247.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26247.result index 723a81a965c..6eddf9a733e 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_26247.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26247.result @@ -28,8 +28,6 @@ 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; -set @old_spider_disable_group_by_handler=@@spider_disable_group_by_handler; -set spider_disable_group_by_handler=1; CREATE DATABASE auto_test_local; USE auto_test_local; CREATE TABLE t1 ( @@ -82,7 +80,6 @@ a22 22 connection master_1; DROP DATABASE IF EXISTS auto_test_local; -set spider_disable_group_by_handler=@old_spider_disable_group_by_handler; connection child2_1; DROP DATABASE IF EXISTS auto_test_remote; for master_1 @@ -91,6 +88,3 @@ child2_1 child2_2 child2_3 for child3 -# -# end of test mdev_26247 -# 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_27575.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result new file mode 100644 index 00000000000..5890a4e8a74 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result @@ -0,0 +1,19 @@ +# +# 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; +ERROR HY000: Table storage engine 'SPIDER' does not support the create option 'TEMPORARY' +# 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_28683.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28683.result new file mode 100644 index 00000000000..358c794ef86 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28683.result @@ -0,0 +1,22 @@ +# +# MDEV-28683 Spider: SIGSEGV in spider_db_direct_delete, SIGSEGV in spider_db_connect, ASAN: heap-use-after-free in spider_db_direct_delete +# +for master_1 +for child2 +for child3 +CREATE TABLE t (c INT) ENGINE=Spider; +SELECT * FROM t; +ERROR HY000: Unable to connect to foreign data source: localhost +INSERT INTO t (SELECT 1 FROM t); +ERROR HY000: Unable to connect to foreign data source: localhost +LOCK TABLES t WRITE CONCURRENT; +DELETE FROM t; +ERROR HY000: Unable to connect to foreign data source: localhost +UNLOCK TABLES; +DROP TABLE t; +for master_1 +for child2 +for child3 +# +# end of test mdev_28683 +# 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_28739_simple.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28739_simple.result new file mode 100644 index 00000000000..db232f8a6d3 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28739_simple.result @@ -0,0 +1,20 @@ +# +# MDEV-28739 Trying to lock uninitialized mutex or hang upon shutdown after using Spider with query_cache +# +for master_1 +for child2 +for child3 +set global query_cache_type= on; +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; +c +# restart +drop table t1, t2; +drop server srv; +for master_1 +for child2 +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 index 96d8a729c58..af4bef1efa9 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result @@ -4,8 +4,6 @@ for master_1 for child2 for child3 -set @old_spider_disable_group_by_handler=@@spider_disable_group_by_handler; -set spider_disable_group_by_handler=1; 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); @@ -17,7 +15,6 @@ SELECT t1_spider.* FROM t1_spider LEFT JOIN t2_spider LEFT JOIN t3_spider ON b = a DROP TABLE t1_spider, t2_spider, t3_spider, t1, t2, t3; drop server s; -set spider_disable_group_by_handler=@old_spider_disable_group_by_handler; for master_1 for child2 for child3 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..fd05aa155e4 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30014.result @@ -0,0 +1,36 @@ +# +# 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 +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 1ffbf2e6b01..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,6 +1,7 @@ # # 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: diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result index 13297e1003f..58873d2c6e5 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result @@ -4,8 +4,6 @@ for master_1 for child2 for child3 -set @old_spider_disable_group_by_handler=@@spider_disable_group_by_handler; -set spider_disable_group_by_handler=1; 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); @@ -16,7 +14,6 @@ a 2 DROP TABLE t1, t2; DROP SERVER srv; -set spider_disable_group_by_handler=@old_spider_disable_group_by_handler; for master_1 for child2 for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result index 28cb546e8c2..94b76de7df4 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result @@ -4,22 +4,16 @@ for master_1 for child2 for child3 -set @old_spider_disable_group_by_handler=@@spider_disable_group_by_handler; -set spider_disable_group_by_handler=1; 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"'; -SET SESSION optimizer_switch='semijoin=off'; -SELECT * FROM t2 -WHERE A BETWEEN 0 AND 10 AND B IN(SELECT B FROM t2 WHERE A BETWEEN 11 AND 20); +SELECT * FROM t2 WHERE b IN (SELECT b FROM t2 WHERE a > 10); a b -SET SESSION optimizer_switch='semijoin=on'; 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; -set spider_disable_group_by_handler=@old_spider_disable_group_by_handler; for master_1 for child2 for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_31996.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_31996.result new file mode 100644 index 00000000000..04d7e884676 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_31996.result @@ -0,0 +1,47 @@ +for master_1 +for child2 +for child3 +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +set session spider_delete_all_rows_type=0; +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2", delete_all_rows_type "0"'; +delete from t1; +drop table t1, t2; +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2", delete_all_rows_type "0"'; +insert ignore into t1 values (42), (378); +select * from t1; +c +42 +378 +delete from t1; +select * from t1; +c +drop table t1, t2; +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2", delete_all_rows_type "0"'; +truncate t1; +drop table t1, t2; +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2", delete_all_rows_type "0"'; +insert ignore into t1 values (42), (378); +select * from t1; +c +42 +378 +truncate t1; +select * from t1; +c +drop table t1, t2; +drop server srv; +for master_1 +for child2 +for child3 +# +# end of test tmp +# 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/slave_trx_isolation.result b/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result index ffccf2d5ef1..2d3c9f1ff8c 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result +++ b/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result @@ -52,8 +52,6 @@ set session time_zone = '+00:00';set @`spider_lc_./auto_test_remote/tbl_a` = '-x SET NAMES utf8mb3 set @old_lock_wait_timeout=@@session.lock_wait_timeout;set session lock_wait_timeout=1 set session lock_wait_timeout=@old_lock_wait_timeout -set @old_lock_wait_timeout=@@session.lock_wait_timeout;set session lock_wait_timeout=1 -set session lock_wait_timeout=@old_lock_wait_timeout set session transaction isolation level read committed;set session autocommit = 1;set session wait_timeout = 604800;set session sql_mode = 'strict_trans_tables,error_for_division_by_zero,no_auto_create_user,no_engine_substitution';start transaction SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%set %' SELECT pkey FROM tbl_a ORDER BY pkey; 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/t/ddl_log.test b/storage/spider/mysql-test/spider/bugfix/t/ddl_log.test new file mode 100644 index 00000000000..4fe45b83dea --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/ddl_log.test @@ -0,0 +1,17 @@ +--source include/have_partition.inc +--let $restart_parameters= --plugin-load-add=ha_spider +--source include/restart_mysqld.inc + +--echo # +--echo # MDEV-32532 Assertion failure in ddl_log_increment_phase_no_lock upon +--echo # partition operations with spider plugin loaded +--echo # +CREATE TABLE t1 (a INT) PARTITION BY HASH (a) PARTITIONS 2; +ALTER TABLE t1 REBUILD PARTITION p0; +drop table t1; + +--echo # +--echo # End of 10.10 +--echo # + +uninstall plugin spider; 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_26247.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26247.test index 8d27c6e0ad3..80328e05fd6 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_26247.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26247.test @@ -7,6 +7,7 @@ --source ../../t/test_init.inc --enable_result_log --enable_query_log + --connection child2_1 CREATE DATABASE auto_test_remote; USE auto_test_remote; @@ -33,10 +34,6 @@ INSERT INTO t2 VALUES (1, 11), (2, 22), (3, 33); INSERT INTO t3 VALUES (1, 111), (2, 222), (3, 333); --connection master_1 -#FIXME: this is a workaround. -set @old_spider_disable_group_by_handler=@@spider_disable_group_by_handler; -set spider_disable_group_by_handler=1; - CREATE DATABASE auto_test_local; USE auto_test_local; @@ -71,7 +68,6 @@ 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; -set spider_disable_group_by_handler=@old_spider_disable_group_by_handler; --connection child2_1 DROP DATABASE IF EXISTS auto_test_remote; @@ -80,6 +76,3 @@ DROP DATABASE IF EXISTS auto_test_remote; --source ../t/test_deinit.inc --enable_query_log --enable_result_log ---echo # ---echo # end of test mdev_26247 ---echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt index 7bc1c2127a6..b046607108b 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt @@ -1 +1 @@ ---init-file=$MYSQL_TEST_DIR/../storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql +--init-file=$MTR_SUITE_DIR/t/mdev_27233.sql 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..cc9b68ad115 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27575.test @@ -0,0 +1,28 @@ +--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"); +--error ER_ILLEGAL_HA_CREATE_OPTION +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_init_file.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.opt index f7ce5b39b5e..556df9cdc10 100644 --- 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 @@ -1 +1 @@ ---init-file=$MYSQL_TEST_DIR/../storage/spider/mysql-test/spider/bugfix/t/mdev_28218_init_file.sql +--init-file=$MTR_SUITE_DIR/t/mdev_28218_init_file.sql 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 index 37d8664c6da..5561f625c8e 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.opt +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.opt @@ -1,2 +1,2 @@ --plugin-load-add=ha_spider ---init-file=$MYSQL_TEST_DIR/../storage/spider/mysql-test/spider/bugfix/t/mdev_28218_mixed.sql +--init-file=$MTR_SUITE_DIR/t/mdev_28218_mixed.sql 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 index 0bfcc46f371..ac116fd0e4f 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_29163.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29163.test @@ -6,9 +6,6 @@ --source ../../t/test_init.inc --enable_result_log --enable_query_log -#FIXME: this is a workaround. -set @old_spider_disable_group_by_handler=@@spider_disable_group_by_handler; -set spider_disable_group_by_handler=1; evalp CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 (a INT); @@ -24,8 +21,6 @@ SELECT t1_spider.* FROM t1_spider LEFT JOIN t2_spider LEFT JOIN t3_spider ON b = # Cleanup DROP TABLE t1_spider, t2_spider, t3_spider, t1, t2, t3; drop server s; -set spider_disable_group_by_handler=@old_spider_disable_group_by_handler; - --disable_query_log --disable_result_log --source ../../t/test_deinit.inc 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 721a0996d96..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,10 +3,9 @@ --echo # MDEV-30370 mariadbd hangs when running with --wsrep-recover and --plugin-load-add=ha_spider.so --echo # -let $MYSQLD_DATADIR= `select @@datadir`; -let $PLUGIN_DIR=`select @@plugin_dir`; +call mtr.add_suppression(".*\\[Warning\\] InnoDB: Skipping buffer pool dump/restore during wsrep recovery"); --source include/kill_mysqld.inc ---exec $MYSQLD_CMD --datadir=$MYSQLD_DATADIR --wsrep-recover --plugin-dir=$PLUGIN_DIR --plugin-load-add=ha_spider +--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 index 6d14f155e62..03417013b07 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test @@ -6,9 +6,6 @@ --source ../../t/test_init.inc --enable_result_log --enable_query_log -set @old_spider_disable_group_by_handler=@@spider_disable_group_by_handler; -set spider_disable_group_by_handler=1; - evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 (a INT); @@ -21,7 +18,6 @@ SELECT a FROM t2 WHERE a IN ( SELECT a FROM t2 ); DROP TABLE t1, t2; DROP SERVER srv; -set spider_disable_group_by_handler=@old_spider_disable_group_by_handler; --disable_query_log --disable_result_log --source ../../t/test_deinit.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test index 48bfa740ba3..bec9dd6c316 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test @@ -6,25 +6,16 @@ --source ../../t/test_init.inc --enable_result_log --enable_query_log -set @old_spider_disable_group_by_handler=@@spider_disable_group_by_handler; -set spider_disable_group_by_handler=1; - 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"'; -SET SESSION optimizer_switch='semijoin=off'; -SELECT * FROM t2 -WHERE A BETWEEN 0 AND 10 AND B IN(SELECT B FROM t2 WHERE A BETWEEN 11 AND 20); - -SET SESSION optimizer_switch='semijoin=on'; - +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; -set spider_disable_group_by_handler=@old_spider_disable_group_by_handler; --disable_query_log --disable_result_log --source ../../t/test_deinit.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_31996.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_31996.test new file mode 100644 index 00000000000..3e823790c82 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_31996.test @@ -0,0 +1,50 @@ +--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'); + +set session spider_delete_all_rows_type=0; + +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2", delete_all_rows_type "0"'; +delete from t1; +drop table t1, t2; + +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2", delete_all_rows_type "0"'; +insert ignore into t1 values (42), (378); +select * from t1; +delete from t1; +select * from t1; +drop table t1, t2; + +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2", delete_all_rows_type "0"'; +truncate t1; +drop table t1, t2; + +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2", delete_all_rows_type "0"'; +insert ignore into t1 values (42), (378); +select * from t1; +truncate t1; +select * from t1; +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 tmp +--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/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_init_file.opt b/storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.opt index 60bb42d2918..d0f5777db87 100644 --- 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 @@ -1 +1 @@ ---init-file=$MYSQL_TEST_DIR/../storage/spider/mysql-test/spider/bugfix/t/udf_mysql_func_early_init_file.sql +--init-file=$MTR_SUITE_DIR/t/udf_mysql_func_early_init_file.sql 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 ccf9e305cf7..6014b1d79e3 100644 --- a/storage/spider/mysql-test/spider/include/init_spider.inc +++ b/storage/spider/mysql-test/spider/include/init_spider.inc @@ -158,27 +158,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 ff4f211faf5..ba7df543db0 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 (t1.`c` = t2.`c`) and (t0.`a` = t1.`a`) and (t3.`b` is not null) 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 (t1.`c` = t2.`c`) and (t0.`a` = t1.`a`) and (t3.`b` is not null) 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 02f985279f8..ef044734f03 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`) and (t3.`b` is not null)) 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`) and (t3.`b` 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_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 840328508fa..1c0900f870e 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 (t1.`c` = t2.`c`) and (t3.`b` 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_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 (t1.`c` = t2.`c`) and (t3.`b` 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/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/r/slave_trx_isolation.result b/storage/spider/mysql-test/spider/r/slave_trx_isolation.result index c48d68758bf..b572da16eb2 100644 --- a/storage/spider/mysql-test/spider/r/slave_trx_isolation.result +++ b/storage/spider/mysql-test/spider/r/slave_trx_isolation.result @@ -55,8 +55,6 @@ set session time_zone = '+00:00';set @`spider_lc_./auto_test_remote/tbl_a` = '-x SET NAMES utf8mb3 set @old_lock_wait_timeout=@@session.lock_wait_timeout;set session lock_wait_timeout=1 set session lock_wait_timeout=@old_lock_wait_timeout -set @old_lock_wait_timeout=@@session.lock_wait_timeout;set session lock_wait_timeout=1 -set session lock_wait_timeout=@old_lock_wait_timeout set session transaction isolation level read committed;set session autocommit = 1;set session wait_timeout = 604800;set session sql_mode = 'strict_trans_tables,error_for_division_by_zero,no_auto_create_user,no_engine_substitution';start transaction SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%set %' SELECT pkey FROM tbl_a ORDER BY pkey; 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 76c26f67416..d8288ef1383 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -409,7 +409,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), @@ -448,7 +448,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], @@ -856,6 +856,8 @@ int spider_free_conn( ip_port_conn->ip_port_count--; pthread_mutex_unlock(&ip_port_conn->mutex); } + if (conn->conn_holder_for_direct_join) + conn->conn_holder_for_direct_join->conn= NULL; spider_free_conn_alloc(conn); spider_free(spider_current_trx, conn, MYF(0)); DBUG_RETURN(0); @@ -1858,7 +1860,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 * @@ -3404,7 +3406,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; @@ -3437,7 +3439,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 d64ce3c3c1a..44bf57e443a 100644 --- a/storage/spider/spd_copy_tables.cc +++ b/storage/spider/spd_copy_tables.cc @@ -274,7 +274,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, @@ -587,7 +587,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], @@ -769,7 +769,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)) ) { @@ -981,7 +981,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, @@ -1002,7 +1002,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; @@ -1027,7 +1027,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, @@ -1048,7 +1048,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 2fc04954410..f9cf8a9c294 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -249,7 +249,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) { @@ -650,7 +650,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'; @@ -2173,7 +2173,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) @@ -2190,7 +2190,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) ) { @@ -2234,7 +2234,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); @@ -3088,7 +3088,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) @@ -3118,7 +3118,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) @@ -3161,7 +3161,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) @@ -3372,7 +3372,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)) @@ -3435,7 +3435,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); @@ -3790,7 +3790,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); @@ -7453,19 +7453,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); } } } @@ -7568,21 +7569,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); } @@ -7725,7 +7725,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()))) { @@ -7844,7 +7844,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()))) { @@ -8894,8 +8894,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 ( @@ -9005,8 +9005,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)); @@ -9159,7 +9159,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; @@ -9313,7 +9313,7 @@ int spider_db_udf_copy_tables( KEY *key_info = &table->key_info[table->s->primary_key]; 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_include.h b/storage/spider/spd_db_include.h index e3c34bf6bfc..92e8ae208ef 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -383,12 +383,6 @@ public: IO_CACHE *file, uint32 arg_length ); - bool append_with_prefill( - const char *s, - uint32 arg_length, - uint32 full_length, - char fill_char - ); int strstr( const String &search, uint32 offset = 0 @@ -548,34 +542,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; @@ -584,13 +570,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(); @@ -633,8 +612,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( @@ -648,24 +625,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( @@ -805,11 +772,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; @@ -1538,10 +1500,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 8cce4ec59f0..8b02e75317d 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -452,7 +452,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); @@ -545,7 +545,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), @@ -775,9 +775,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()); @@ -1828,7 +1828,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 * @@ -2068,7 +2068,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))) @@ -2098,7 +2098,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) { @@ -2642,7 +2642,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); @@ -2685,7 +2685,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); @@ -2728,7 +2728,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); @@ -2771,7 +2771,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); @@ -3108,7 +3108,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)); @@ -3162,7 +3162,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); @@ -3227,7 +3227,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)) @@ -3280,7 +3280,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))) { @@ -3962,7 +3962,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; @@ -4038,7 +4038,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()) || @@ -4106,7 +4106,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; @@ -4257,7 +4257,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()) || @@ -6025,7 +6025,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) @@ -6150,7 +6150,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) @@ -6287,7 +6287,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) @@ -6735,558 +6735,269 @@ int spider_db_mbase_util::append_escaped_util( DBUG_RETURN(0); } -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 || table->table_function) + 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); + DBUG_ASSERT(!table->table_function); + /* 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 ) { @@ -7387,7 +7098,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; } @@ -7461,7 +7172,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, @@ -7479,7 +7190,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)); @@ -7503,13 +7214,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); } @@ -7660,9 +7371,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) @@ -7801,7 +7512,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))) @@ -7869,8 +7580,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; @@ -7950,7 +7661,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; @@ -8000,8 +7711,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; @@ -8134,7 +7845,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++) { @@ -8468,7 +8179,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; } @@ -8541,14 +8252,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)) || @@ -8568,7 +8279,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, @@ -8672,7 +8383,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", @@ -8802,7 +8513,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); @@ -9053,7 +8764,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))) @@ -11039,7 +10750,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(), @@ -13093,14 +12804,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); @@ -13134,7 +12841,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) { @@ -14759,7 +14466,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) ) { @@ -14780,7 +14487,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) ) { @@ -14842,8 +14549,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, @@ -14851,27 +14557,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 ) { @@ -15224,7 +14909,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 c0a1d68d15e..bf94c94d4b4 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -158,40 +158,22 @@ public: spider_string *to, String *from ) override; - 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, @@ -199,11 +181,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; @@ -638,8 +615,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; my_hash_value_type *db_table_str_hash_value; uint table_nm_max_length; @@ -1465,10 +1445,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_direct_sql.cc b/storage/spider/spd_direct_sql.cc index 9f2c6aad0c0..3dd8e4293c1 100644 --- a/storage/spider/spd_direct_sql.cc +++ b/storage/spider/spd_direct_sql.cc @@ -109,7 +109,7 @@ int spider_udf_direct_sql_create_table_list( break; } 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), @@ -238,7 +238,7 @@ int spider_udf_direct_sql_create_conn_key( + direct_sql->tgt_filedsn_length + 1 + direct_sql->tgt_driver_length; 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); @@ -389,7 +389,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), @@ -420,7 +420,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(138); + conn->default_database.init_calc_mem(SPD_MID_UDF_DIRECT_SQL_CREATE_CONN_2); conn->conn_key_length = direct_sql->conn_key_length; conn->conn_key = tmp_name; @@ -1437,7 +1437,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)) @@ -1672,7 +1672,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 af2df35b5de..6236a7b974a 100644 --- a/storage/spider/spd_group_by_handler.cc +++ b/storage/spider/spd_group_by_handler.cc @@ -22,6 +22,7 @@ #include "probes_mysql.h" #include "sql_class.h" #include "sql_partition.h" +#include "sql_select.h" #include "ha_partition.h" #include "sql_common.h" #include @@ -42,11 +43,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)); @@ -65,24 +64,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)) @@ -364,7 +345,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))); } @@ -471,7 +452,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; @@ -493,11 +473,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; } @@ -554,7 +533,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))); } @@ -632,7 +611,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)), @@ -646,24 +625,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"); @@ -855,25 +816,24 @@ void spider_fields::free_conn_holder( } } } - conn_holder_arg->conn->conn_holder_for_direct_join = NULL; + if (conn_holder_arg->conn) + conn_holder_arg->conn->conn_holder_for_direct_join = NULL; DBUG_PRINT("info",("spider free conn_holder=%p", conn_holder_arg)); spider_free(spider_current_trx, conn_holder_arg, MYF(0)); 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", @@ -892,90 +852,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; @@ -995,117 +914,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; } @@ -1128,15 +942,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]) @@ -1172,9 +984,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; } @@ -1182,42 +992,20 @@ 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; @@ -1263,7 +1051,7 @@ int spider_group_by_handler::init_scan() } result_list->semi_split_read_base = 0; result_list->set_split_read = TRUE; - if ((error_num = spider_set_conn_bg_param(spider))) + if (int error_num = spider_set_conn_bg_param(spider)) DBUG_RETURN(error_num); DBUG_PRINT("info",("spider result_list.finish_flg = FALSE")); result_list->finish_flg = FALSE; @@ -1283,86 +1071,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())) @@ -1381,12 +1170,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; @@ -1394,14 +1179,12 @@ int spider_group_by_handler::init_scan() } DBUG_RETURN(error_num); } - } else { + } else + { 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]; @@ -1411,6 +1194,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); @@ -1418,37 +1202,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; @@ -1464,13 +1243,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; @@ -1479,13 +1255,45 @@ 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); } } } + 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); @@ -1594,7 +1402,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"); @@ -1616,8 +1425,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")); @@ -1632,17 +1440,11 @@ group_by_handler *spider_create_group_by_handler( } } while ((from = from->next_local)); + 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 (from->table->part_info) { partition_info *part_info = from->table->part_info; @@ -1656,6 +1458,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) { @@ -1669,8 +1476,6 @@ group_by_handler *spider_create_group_by_handler( } while ((from = from->next_local)) { - if (from->table->const_table) - continue; if (from->table->part_info) { partition_info *part_info = from->table->part_info; @@ -1684,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_tmp, 0, spider_bitmap_size(SPIDER_DBTON_SIZE)); for (roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count) { @@ -1704,8 +1514,6 @@ group_by_handler *spider_create_group_by_handler( from = query->from; do { - if (from->table->const_table) - continue; if (from->table->part_info) { partition_info *part_info = from->table->part_info; @@ -1733,10 +1541,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++)) @@ -1843,21 +1650,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 (from->table->part_info) { partition_info *part_info = from->table->part_info; @@ -1878,17 +1673,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, @@ -1908,8 +1696,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; } @@ -1917,26 +1704,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 (from->table->part_info) @@ -1950,19 +1732,12 @@ group_by_handler *spider_create_group_by_handler( spider = (ha_spider *) from->table->file; } 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, @@ -1981,17 +1756,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; } } @@ -2000,30 +1771,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 */ @@ -2035,16 +1796,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(); @@ -2052,8 +1811,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; @@ -2061,4 +1819,10 @@ 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); } diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index c6ccacf05d1..8ce18e401b0 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -171,6 +171,279 @@ typedef start_new_trans *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 \ diff --git a/storage/spider/spd_init_query.h b/storage/spider/spd_init_query.h index a322b73708d..ef234ac6c6f 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," @@ -210,7 +213,8 @@ static LEX_STRING spider_init_queries[] = { " 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;" + " add if not exists tgt_table_name char(64) default null," + " algorithm=copy, lock=shared;" )}, /* Fix for version 0.17 @@ -224,7 +228,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @col_type != 'binary(128)' then" " alter table mysql.spider_xa" - " modify data binary(128) not null default '';" + " modify data binary(128) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -236,7 +241,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @col_type != 'binary(128)' then" " alter table mysql.spider_xa_member" - " modify data binary(128) not null default '';" + " modify data binary(128) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, /* @@ -246,14 +252,16 @@ static LEX_STRING spider_init_queries[] = { "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);" + " add primary key (db_name, table_name, link_id)," + " algorithm=copy, lock=shared;" )}, /* Fix for version 2.8 */ {C_STRING_WITH_LEN( "alter table mysql.spider_tables" - " add column if not exists link_status tinyint not null default 1;" + " add column if not exists link_status tinyint not null default 1," + " algorithm=copy, lock=shared;" )}, /* Fix for version 2.10 @@ -269,7 +277,8 @@ static LEX_STRING spider_init_queries[] = { " 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;" + " 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" @@ -282,7 +291,8 @@ static LEX_STRING spider_init_queries[] = { " 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;" + " 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" @@ -295,7 +305,8 @@ static LEX_STRING spider_init_queries[] = { " 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;" + " add column if not exists default_group char(64) default null after default_file," + " algorithm=copy, lock=shared;" )}, /* Fix for version 2.28 @@ -309,7 +320,8 @@ static LEX_STRING spider_init_queries[] = { {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;" + " modify sid int unsigned not null default 0," + " algorithm=copy, lock=shared;" "end if;" )}, /* @@ -331,7 +343,8 @@ static LEX_STRING spider_init_queries[] = { " modify ssl_capath text," " modify ssl_cert text," " modify ssl_key text," - " modify default_file text;" + " modify default_file text," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -348,7 +361,8 @@ static LEX_STRING spider_init_queries[] = { " modify ssl_capath text," " modify ssl_cert text," " modify ssl_key text," - " modify default_file text;" + " modify default_file text," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -365,7 +379,8 @@ static LEX_STRING spider_init_queries[] = { " modify ssl_capath text," " modify ssl_cert text," " modify ssl_key text," - " modify default_file text;" + " modify default_file text," + " algorithm=copy, lock=shared;" "end if;" )}, /* @@ -374,7 +389,8 @@ static LEX_STRING spider_init_queries[] = { {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;" + " after ssl_verify_server_cert," + " algorithm=copy, lock=shared;" )}, /* Fix for version 3.3.6 @@ -382,12 +398,14 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "alter table mysql.spider_tables" " add column if not exists block_status tinyint not null default 0" - " after link_status;" + " 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);" + " 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" @@ -398,7 +416,8 @@ static LEX_STRING spider_init_queries[] = { {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 '';" + " modify link_id char(64) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -410,7 +429,8 @@ static LEX_STRING spider_init_queries[] = { {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 '';" + " modify link_id char(64) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, /* @@ -425,7 +445,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @col_type != 'char(199)' then" " alter table mysql.spider_tables" - " modify table_name char(199) not null default '';" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -437,7 +458,8 @@ static LEX_STRING spider_init_queries[] = { {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 '';" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -449,7 +471,8 @@ static LEX_STRING spider_init_queries[] = { {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 '';" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -461,7 +484,8 @@ static LEX_STRING spider_init_queries[] = { {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 '';" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -473,7 +497,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @col_type != 'char(199)' then" " alter table mysql.spider_table_sts" - " modify table_name char(199) not null default '';" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -485,7 +510,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @col_type != 'char(199)' then" " alter table mysql.spider_table_crd" - " modify table_name char(199) not null default '';" + " modify table_name char(199) not null default ''," + " algorithm=copy, lock=shared;" "end if;" )}, /* @@ -493,7 +519,8 @@ static LEX_STRING spider_init_queries[] = { */ {C_STRING_WITH_LEN( "alter table mysql.spider_table_sts" - " add column if not exists checksum bigint unsigned default null after update_time;" + " 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 @@ -506,7 +533,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @engine_name != 'Aria' then" " alter table mysql.spider_link_failed_log" - " engine=Aria transactional=1;" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -517,7 +545,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @engine_name != 'Aria' then" " alter table mysql.spider_link_mon_servers" - " engine=Aria transactional=1;" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -528,7 +557,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @engine_name != 'Aria' then" " alter table mysql.spider_table_crd" - " engine=Aria transactional=1;" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -539,7 +569,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @engine_name != 'Aria' then" " alter table mysql.spider_table_position_for_recovery" - " engine=Aria transactional=1;" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -550,7 +581,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @engine_name != 'Aria' then" " alter table mysql.spider_table_sts" - " engine=Aria transactional=1;" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -561,7 +593,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @engine_name != 'Aria' then" " alter table mysql.spider_tables" - " engine=Aria transactional=1;" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -572,7 +605,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @engine_name != 'Aria' then" " alter table mysql.spider_xa" - " engine=Aria transactional=1;" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -583,7 +617,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @engine_name != 'Aria' then" " alter table mysql.spider_xa_failed_log" - " engine=Aria transactional=1;" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" "end if;" )}, {C_STRING_WITH_LEN( @@ -594,7 +629,8 @@ static LEX_STRING spider_init_queries[] = { {C_STRING_WITH_LEN( "if @engine_name != 'Aria' then" " alter table mysql.spider_xa_member" - " engine=Aria transactional=1;" + " engine=Aria transactional=1," + " algorithm=copy, lock=shared;" "end if;" )}, /* @@ -602,51 +638,63 @@ static LEX_STRING spider_init_queries[] = { */ {C_STRING_WITH_LEN( "alter table mysql.spider_link_mon_servers" - " add column if not exists dsn char(64) default null after default_group;" + " add column if not exists dsn char(64) default null after default_group," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_tables" - " add column if not exists dsn char(64) default null after default_group;" + " add column if not exists dsn char(64) default null after default_group," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_xa_failed_log" - " add column if not exists dsn char(64) default null after default_group;" + " add column if not exists dsn char(64) default null after default_group," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_xa_member" - " add column if not exists dsn char(64) default null after default_group;" + " add column if not exists dsn char(64) default null after default_group," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_link_mon_servers" - " add column if not exists filedsn text default null after dsn;" + " add column if not exists filedsn text default null after dsn," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_tables" - " add column if not exists filedsn text default null after dsn;" + " add column if not exists filedsn text default null after dsn," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_xa_failed_log" - " add column if not exists filedsn text default null after dsn;" + " add column if not exists filedsn text default null after dsn," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_xa_member" - " add column if not exists filedsn text default null after dsn;" + " add column if not exists filedsn text default null after dsn," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_link_mon_servers" - " add column if not exists driver char(64) default null after filedsn;" + " add column if not exists driver char(64) default null after filedsn," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_tables" - " add column if not exists driver char(64) default null after filedsn;" + " add column if not exists driver char(64) default null after filedsn," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_xa_failed_log" - " add column if not exists driver char(64) default null after filedsn;" + " add column if not exists driver char(64) default null after filedsn," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "alter table mysql.spider_xa_member" - " add column if not exists driver char(64) default null after filedsn;" + " add column if not exists driver char(64) default null after filedsn," + " algorithm=copy, lock=shared;" )}, {C_STRING_WITH_LEN( "set @win_plugin := IF(@@version_compile_os like 'Win%', 1, 0);" @@ -657,7 +705,7 @@ static LEX_STRING spider_init_queries[] = { "if @win_plugin = 0 then" " begin not atomic" " declare exit handler for 1041, 1123" - " insert into mysql.func values" + " 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')," @@ -677,7 +725,7 @@ static LEX_STRING spider_init_queries[] = { "else" " begin not atomic" " declare exit handler for 1041, 1123" - " insert into mysql.func values" + " 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')," diff --git a/storage/spider/spd_malloc.cc b/storage/spider/spd_malloc.cc index 9b87560d218..245ecd6c600 100644 --- a/storage/spider/spd_malloc.cc +++ b/storage/spider/spd_malloc.cc @@ -922,23 +922,6 @@ bool spider_string::append( DBUG_RETURN(res); } -bool spider_string::append_with_prefill( - const char *s, - uint32 arg_length, - uint32 full_length, - char fill_char -) { - DBUG_ENTER("spider_string::append_with_prefill"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_ASSERT(mem_calc_inited); - DBUG_ASSERT((!current_alloc_mem && !str.is_alloced()) || - current_alloc_mem == str.alloced_length()); - bool res = str.append_with_prefill(s, arg_length, full_length, - fill_char); - SPIDER_STRING_CALC_MEM; - DBUG_RETURN(res); -} - int spider_string::strstr( const String &search, uint32 offset diff --git a/storage/spider/spd_param.cc b/storage/spider/spd_param.cc index 297350ff33d..664b8970366 100644 --- a/storage/spider/spd_param.cc +++ b/storage/spider/spd_param.cc @@ -2217,7 +2217,7 @@ static MYSQL_SYSVAR_UINT( "Static thread count of table sts", NULL, NULL, - 10, + 1, 1, 4294967295U, 0 @@ -2236,7 +2236,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 056c21e07ec..edad3163c0b 100644 --- a/storage/spider/spd_ping_table.cc +++ b/storage/spider/spd_ping_table.cc @@ -219,7 +219,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); @@ -325,7 +325,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, @@ -444,7 +444,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, @@ -1016,8 +1016,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); server_id = global_system_variables.server_id; if ( @@ -1455,7 +1455,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"); @@ -1598,7 +1598,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 7b96c483d5e..af3371cd040 100644 --- a/storage/spider/spd_sys_table.cc +++ b/storage/spider/spd_sys_table.cc @@ -324,38 +324,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_sys_close_table(thd, open_tables_backup); - 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_sys_close_table(thd, open_tables_backup); - 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: @@ -377,24 +345,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_sys_close_table(thd, open_tables_backup); - 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)) @@ -431,60 +381,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_sys_close_table(thd, open_tables_backup); - 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_sys_close_table(thd, open_tables_backup); - 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_sys_close_table(thd, open_tables_backup); - 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: @@ -504,22 +400,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_sys_close_table(thd, open_tables_backup); - 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: @@ -1453,58 +1333,6 @@ void spider_store_binlog_pos_gtid( DBUG_VOID_RETURN; } -/** - Stores sts info in the spider sts table - - Stores all fields except the db name and table name, which are - stored in `spider_store_tables_name()`. -*/ -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, @@ -1611,95 +1439,6 @@ int spider_insert_sys_table( DBUG_RETURN(error_num); } -/** - Inserts or updates a row in the spider sts system table - - @param table The spider sts system table - @param name The name of the spider table whose stat will be - inserted / updated in the sts table - @param name_length Length of the name - @param stat The stat of the spider table that will be - inserted / updated in the sts table - - @retval 0 or error -*/ -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, @@ -2734,72 +2473,6 @@ int spider_get_sys_tables_static_link_id( DBUG_RETURN(error_num); } -/** - Reads the table status from the system sts table - - The result is set into `stat` - - @param table The system sts table - @param stat The stat to read the table status into -*/ -void spider_get_sys_table_sts_info( - TABLE *table, - ha_statistics *stat -) { - MYSQL_TIME mysql_time; - uint not_used_uint; - 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)); - stat->check_time = (time_t) my_system_gmt_sec(&mysql_time, - ¬_used_long, ¬_used_uint); - table->field[SPIDER_TABLE_STS_CREATE_TIME_POS]->get_date(&mysql_time, - SPIDER_date_mode_t(0)); - stat->create_time = (time_t) my_system_gmt_sec(&mysql_time, - ¬_used_long, ¬_used_uint); - table->field[SPIDER_TABLE_STS_UPDATE_TIME_POS]->get_date(&mysql_time, - SPIDER_date_mode_t(0)); - stat->update_time = (time_t) my_system_gmt_sec(&mysql_time, - ¬_used_long, ¬_used_uint); - 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, @@ -3238,272 +2911,6 @@ int spider_get_link_statuses( DBUG_RETURN(0); } -/** - Inserts or updates status of a table into the system sts table - - @param thd Connection - @param name Name of the table whose status will be stored - @param name_length Length of `name` - @param stat The table status that will be stored into the - system sts table - @reval 0 for success, or error code -*/ -int spider_sys_insert_or_update_table_sts( - THD *thd, - const char *name, - uint name_length, - ha_statistics *stat -) { - 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, &error_num)) - ) { - goto error; - } - if ((error_num = spider_insert_or_update_table_sts( - table_sts, - name, - name_length, - stat - ))) - goto error; - spider_sys_close_table(thd, &open_tables_backup); - table_sts = NULL; - DBUG_RETURN(0); - -error: - if (table_sts) - spider_sys_close_table(thd, &open_tables_backup); - 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 -) { - 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, &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_sys_close_table(thd, &open_tables_backup); - table_crd = NULL; - DBUG_RETURN(0); - -error: - if (table_crd) - spider_sys_close_table(thd, &open_tables_backup); - DBUG_RETURN(error_num); -} - -int spider_sys_delete_table_sts( - THD *thd, - const char *name, - uint name_length -) { - 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, &error_num)) - ) { - goto error; - } - if ((error_num = spider_delete_table_sts( - table_sts, - name, - name_length - ))) - goto error; - spider_sys_close_table(thd, &open_tables_backup); - table_sts = NULL; - DBUG_RETURN(0); - -error: - if (table_sts) - spider_sys_close_table(thd, &open_tables_backup); - DBUG_RETURN(error_num); -} - -int spider_sys_delete_table_crd( - THD *thd, - const char *name, - uint name_length -) { - 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, &error_num)) - ) { - goto error; - } - if ((error_num = spider_delete_table_crd( - table_crd, - name, - name_length - ))) - goto error; - spider_sys_close_table(thd, &open_tables_backup); - table_crd = NULL; - DBUG_RETURN(0); - -error: - if (table_crd) - spider_sys_close_table(thd, &open_tables_backup); - DBUG_RETURN(error_num); -} - -/** - Reads table status of a table from the system sts table. - - @param thd Connection - @param name The name of the table for which to read status of - @param name_length The length of `name` - @param stat The struct to read the status into -*/ -int spider_sys_get_table_sts( - THD *thd, - const char *name, - uint name_length, - ha_statistics *stat -) { - 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, &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_sys_close_table(thd, &open_tables_backup); - table_sts = NULL; - DBUG_RETURN(0); - -error: - if (table_sts) - spider_sys_close_table(thd, &open_tables_backup); - DBUG_RETURN(error_num); -} - -int spider_sys_get_table_crd( - THD *thd, - const char *name, - uint name_length, - longlong *cardinality, - uint number_of_keys -) { - 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, &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_sys_close_table(thd, &open_tables_backup); - table_crd = NULL; - DBUG_RETURN(0); - -error: - if (index_inited) - spider_sys_index_end(table_crd); - - if (table_crd) - spider_sys_close_table(thd, &open_tables_backup); - 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 6cb6c3957a7..a51d6914c71 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 @@ -305,21 +286,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, @@ -456,17 +422,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, @@ -515,48 +470,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 -); - -int spider_sys_insert_or_update_table_crd( - THD *thd, - const char *name, - uint name_length, - longlong *cardinality, - uint number_of_keys -); - -int spider_sys_delete_table_sts( - THD *thd, - const char *name, - uint name_length -); - -int spider_sys_delete_table_crd( - THD *thd, - const char *name, - uint name_length -); - -int spider_sys_get_table_sts( - THD *thd, - const char *name, - uint name_length, - ha_statistics *stat -); - -int spider_sys_get_table_crd( - THD *thd, - const char *name, - uint name_length, - longlong *cardinality, - uint number_of_keys -); - 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 9136c419f93..75a73f72a8a 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -1134,7 +1134,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)) @@ -1328,7 +1328,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)) ) { @@ -1476,7 +1476,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)) ) { @@ -1544,7 +1544,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)) @@ -1607,7 +1607,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)) @@ -1665,7 +1665,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)) ) { @@ -1710,7 +1710,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)) ) { @@ -3310,7 +3310,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, @@ -4465,7 +4465,8 @@ int spider_create_conn_keys( share->conn_keys_charlen += conn_keys_lengths[all_link_idx] + 2; } if (!(share->conn_keys = (char **) - spider_bulk_malloc(spider_current_trx, 45, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_CONN_KEYS_1, + MYF(MY_WME | MY_ZEROFILL), &share->conn_keys, sizeof(char *) * share->all_link_count, &share->conn_keys_lengths, length_base, &share->conn_keys_hash_value, @@ -4657,7 +4658,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, @@ -4702,7 +4703,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, @@ -5369,8 +5370,8 @@ bool spider_init_share( DBUG_RETURN(TRUE); } - if (!(spider_share_malloc_for_spider(spider, share, 47, &tmp_name, - result_list))) + if (!(spider_share_malloc_for_spider(spider, share, SPD_MID_GET_SHARE_1, + &tmp_name, result_list))) { spider_share_init_error_free(share, new_share, true); DBUG_RETURN(TRUE); @@ -5572,8 +5573,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) { spider_free_sts_thread(share); @@ -5589,47 +5588,6 @@ int spider_free_share( spider_table_remove_share_from_crd_thread(share); spider_free_spider_object_for_share(&share->crd_spider); } - 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 - ); - } - 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 - ); - } spider_free_share_alloc(share); my_hash_delete(&spider_open_tables, (uchar*) share); pthread_mutex_destroy(&share->crd_mutex); @@ -5638,8 +5596,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); } @@ -5695,7 +5651,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)) @@ -5781,7 +5737,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, @@ -6024,7 +5980,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), @@ -6233,26 +6189,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) @@ -6402,13 +6345,6 @@ int spider_db_done( )); } - /* End Spider plugin deinit */ - if (do_delete_thd) - spider_destroy_thd(thd); - -/* -DBUG_ASSERT(0); -*/ DBUG_RETURN(0); } @@ -6482,6 +6418,16 @@ bool spider_init_system_tables() DBUG_RETURN(FALSE); } + +/* + Spider is typically loaded before ddl_recovery, but DDL statements + cannot be executed before ddl_recovery, so we delay system table creation. +*/ +static void spider_after_ddl_recovery(handlerton *) +{ + spider_init_system_tables(); +} + int spider_db_init( void *p ) { @@ -6512,6 +6458,7 @@ int spider_db_init( spider_hton->close_cursor_read_view = spider_close_cursor_read_view; */ spider_hton->panic = spider_panic; + spider_hton->signal_ddl_recovery_done= spider_after_ddl_recovery; spider_hton->close_connection = spider_close_connection; spider_hton->start_consistent_snapshot = spider_start_consistent_snapshot; spider_hton->flush_logs = spider_flush_logs; @@ -6625,7 +6572,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 * @@ -6634,7 +6581,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 * @@ -6645,7 +6592,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 * @@ -6655,7 +6602,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 * @@ -6669,7 +6616,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 * @@ -6678,7 +6625,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 * @@ -6688,14 +6635,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_udf_table_mon_mutex_count), &spider_udf_table_mon_conds, (uint) (sizeof(pthread_cond_t) * @@ -6731,7 +6678,7 @@ 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 * @@ -6744,7 +6691,7 @@ int spider_db_init( } 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) * @@ -6912,7 +6859,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); @@ -6934,7 +6881,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); @@ -7080,36 +7027,16 @@ int spider_get_sts( uint flag ) { int error_num = 0; - bool need_to_get = TRUE; DBUG_ENTER("spider_get_sts"); enum ha_sts_crd_get_type get_type = spider_get_sts_type(share, sts_interval, sts_sync); - 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 - ); - 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) - { - if (get_type == HA_GET_COPY) - share->stat = share->wide_share->stat; - else - /* Executes a `show table status` query and store the results in - share->stat */ - error_num = spider_db_show_table_status(spider, link_idx, sts_mode, flag); - } + if (get_type == HA_GET_COPY) + share->stat = share->wide_share->stat; + else + /* Executes a `show table status` query and store the results in + share->stat */ + error_num = spider_db_show_table_status(spider, link_idx, sts_mode, flag); if (get_type >= HA_GET_AFTER_LOCK) pthread_mutex_unlock(&share->wide_share->sts_mutex); @@ -7208,35 +7135,11 @@ int spider_get_crd( int crd_sync_level ) { int error_num = 0; - bool need_to_get = TRUE; DBUG_ENTER("spider_get_crd"); enum ha_sts_crd_get_type get_type = spider_get_crd_type(share, crd_interval, crd_sync); - 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 - ); - 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) - { - if (get_type == HA_GET_COPY) - memcpy(share->cardinality, share->wide_share->cardinality, - sizeof(longlong) * table->s->fields); - else - error_num = spider_db_show_index(spider, link_idx, table, crd_mode); - } if (get_type >= HA_GET_AFTER_LOCK) pthread_mutex_unlock(&share->wide_share->crd_mutex); if (error_num) @@ -7361,7 +7264,8 @@ SPIDER_INIT_ERROR_TABLE *spider_get_init_error_table( pthread_mutex_unlock(&spider_init_error_tbl_mutex); DBUG_RETURN(NULL); } - if (!spider_bulk_malloc(spider_current_trx, 54, MYF(MY_WME | MY_ZEROFILL), + if (!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) @@ -8423,7 +8327,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 + @@ -8752,7 +8656,7 @@ int spider_create_spider_object_for_share( } DBUG_PRINT("info",("spider spider=%p", (*spider))); 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), diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index a9847faaebe..b6a2bcd8494 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -166,7 +166,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)); @@ -482,7 +482,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)), @@ -1142,7 +1142,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), @@ -1171,7 +1171,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, @@ -1184,7 +1184,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, @@ -1197,7 +1197,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, @@ -1210,7 +1210,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, @@ -1262,7 +1262,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); } @@ -3160,6 +3160,14 @@ int spider_rollback( DBUG_RETURN(0); /* transaction is not started */ + /* 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) @@ -3680,7 +3688,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 6aa72847c81..62abbb9b0d0 100644 --- a/strings/ctype-uca.inl +++ b/strings/ctype-uca.inl @@ -416,8 +416,20 @@ MY_FUNCTION_NAME(scanner_next_pad_trim)(my_uca_scanner *scanner, flags & MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES ? my_space_weight(param->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 (param->cs->state & MY_CS_NOPAD) + res.weight= 0; + res.nchars= (uint) nchars; + } } else if (res.nchars > nchars) { diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index bab804f16bd..b7bdd0e98b0 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2632,7 +2632,7 @@ static const uint16 uni_FF20_FF5F[64]= static int hexlo(int x) { - static const char hex_lo_digit[256]= + static const signed char hex_lo_digit[256]= { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* ................ */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* ................ */ @@ -3698,4 +3698,16 @@ struct charset_info_st my_charset_utf8mb4_nopad_bin= &my_collation_utf8mb4_nopad_bin_handler }; +/* + Take a my_wc_t character and convert it to utf8mb3 representation. + Characters that are not in Basic Multilingual Plane are replaced with + MY_CS_REPLACEMENT_CHARACTER. +*/ +int my_wc_mb_utf8mb4_bmp_only(CHARSET_INFO *cs, my_wc_t wc, uchar *r, uchar *e) +{ + if (wc > 0xFFFF) + wc= MY_CS_REPLACEMENT_CHARACTER; + return my_wc_mb_utf8mb4(cs, wc, r, e); +} + #endif /* HAVE_CHARSET_utf8mb4 */ diff --git a/strings/json_lib.c b/strings/json_lib.c index 52c173f3604..47e0843d627 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -1093,7 +1093,7 @@ static int json_path_transitions[N_PATH_STATES][N_PATH_CLASSES]= /* AS */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, PS_T, PS_PT, JE_SYN, PS_NEG, PS_Z, PS_INT, PS_LAST, PS_AS, JE_SYN, JE_SYN, JE_SYN, JE_NOT_JSON_CHR, JE_BAD_CHR}, -/* KEY */ { JE_EOS, PS_KNM, PS_KWD, JE_SYN, PS_KNM, PS_KNM, JE_SYN, JE_SYN, +/* KEY */ { JE_EOS, PS_KNM, PS_KWD, JE_SYN, PS_KNM, PS_KNM, JE_SYN, PS_KNM, PS_KNM, PS_KNM, PS_KNM, PS_KNM, PS_KNM, JE_SYN, PS_KEYX, PS_KNM, JE_NOT_JSON_CHR, JE_BAD_CHR}, /* KNM */ { PS_KOK, PS_KNM, PS_AST, PS_EAR, PS_KNM, PS_KNM, PS_EKY, PS_KNM, 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 3f9b995febe..3f259d22917 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 8c96a75856b..3bab258d811 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -20058,8 +20058,10 @@ static void test_bug17512527() static void test_compressed_protocol() { MYSQL *mysql_local; + MYSQL_STMT *stmt; char query[4096], *end; int i; + int rc; myheader("test_compressed_protocol"); if (!(mysql_local= mysql_client_init(NULL))) @@ -20082,14 +20084,34 @@ static void test_compressed_protocol() for (i=0 ; i < 2 ; i++) { MYSQL_RES *res; - - int rc= mysql_real_query(mysql, query, (int) (end-query)); + rc= mysql_real_query(mysql, query, (int) (end-query)); myquery(rc); res= mysql_store_result(mysql); DBUG_ASSERT(res != 0); mysql_free_result(res); } + /* + Special compression protocol feature - it can pack + multiple protocol commands inside the same compression packet. + + mariadbclient does it when MYSQL_STMT is reused in multiple + mysql_stmt_prepare() calls. It sends then COM_STMT_CLOSE and + COM_STMT_PREPARE together in a single compression packet. + + Let's test, how server can handle that. There can be bugs + (MDEV-28561) + */ + stmt= mysql_stmt_init(mysql_local); + check_stmt(stmt); + for (i= 0; i < 2; i++) + { + rc= mysql_stmt_prepare(stmt, "DO 1", -1); + myquery(rc); + } + rc= mysql_stmt_close(stmt); + myquery(rc); + mysql_close(mysql_local); } @@ -21939,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 @@ -22463,6 +22524,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}, { "test_mdev_10075", test_mdev_10075}, diff --git a/tpool/tpool_structs.h b/tpool/tpool_structs.h index 099ae5c7ed1..ff3228c953a 100644 --- a/tpool/tpool_structs.h +++ b/tpool/tpool_structs.h @@ -155,12 +155,11 @@ public: { mysql_mutex_lock(&m_mtx); assert(!is_full()); + const bool was_empty= is_empty(); // put element to the logical end of the array m_cache[--m_pos] = ele; - /* Notify waiters when the cache becomes - not empty, or when it becomes full */ - if (m_pos == 1 || (m_waiters && is_full())) + if (was_empty || (is_full() && m_waiters)) pthread_cond_broadcast(&m_cv); mysql_mutex_unlock(&m_mtx); } diff --git a/unittest/sql/my_apc-t.cc b/unittest/sql/my_apc-t.cc index c08e7281c92..9edb209b1f6 100644 --- a/unittest/sql/my_apc-t.cc +++ b/unittest/sql/my_apc-t.cc @@ -100,7 +100,7 @@ void *test_apc_service_thread(void *ptr) //apc_target.enable(); for (int i = 0; i < 10 && !service_should_exit; i++) { - apc_target.process_apc_requests(); + apc_target.process_apc_requests(true); my_sleep(int_rand(30)); } } diff --git a/unittest/strings/strings-t.c b/unittest/strings/strings-t.c index be5fc085ef0..a681a4d38a1 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 151d4f8591d..a5d95f0175f 160000 --- a/wsrep-lib +++ b/wsrep-lib @@ -1 +1 @@ -Subproject commit 151d4f8591d26068afda997fb0d1f66b2f7f1964 +Subproject commit a5d95f0175f10b6127ea039c542725f6c4aa5cb9 diff --git a/zlib/ChangeLog b/zlib/ChangeLog index 457526bc6a5..8707988ac18 100644 --- a/zlib/ChangeLog +++ b/zlib/ChangeLog @@ -1,6 +1,24 @@ ChangeLog file for zlib +Changes in 1.3 (18 Aug 2023) +- Remove K&R function definitions and zlib2ansi +- Fix bug in deflateBound() for level 0 and memLevel 9 +- Fix bug when gzungetc() is used immediately after gzopen() +- Fix bug when using gzflush() with a very small buffer +- Fix crash when gzsetparams() attempted for transparent write +- Fix test/example.c to work with FORCE_STORED +- Rewrite of zran in examples (see zran.c version history) +- Fix minizip to allow it to open an empty zip file +- Fix reading disk number start on zip64 files in minizip +- Fix logic error in minizip argument processing +- Add minizip testing to Makefile +- Read multiple bytes instead of byte-by-byte in minizip unzip.c +- Add memory sanitizer to configure (--memory) +- Various portability improvements +- Various documentation improvements +- Various spelling and typo corrections + Changes in 1.2.13 (13 Oct 2022) - Fix configure issue that discarded provided CC definition - Correct incorrect inputs provided to the CRC functions @@ -1445,7 +1463,7 @@ Changes in 0.99 (27 Jan 96) - fix typo in Make_vms.com (f$trnlnm -> f$getsyi) - in fcalloc, normalize pointer if size > 65520 bytes - don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc. - use Z_BINARY instead of BINARY - document that gzclose after gzdopen will close the file - allow "a" as mode in gzopen diff --git a/zlib/FAQ b/zlib/FAQ index 99b7cf92e45..55f1cdc22f6 100644 --- a/zlib/FAQ +++ b/zlib/FAQ @@ -4,7 +4,7 @@ If your question is not there, please check the zlib home page http://zlib.net/ which may have more recent information. -The lastest zlib FAQ is at http://zlib.net/zlib_faq.html +The latest zlib FAQ is at http://zlib.net/zlib_faq.html 1. Is zlib Y2K-compliant? diff --git a/zlib/README b/zlib/README index ba34d1894a9..e02fc5aa206 100644 --- a/zlib/README +++ b/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.13 is a general purpose data compression library. All the code is +zlib 1.3 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -29,18 +29,17 @@ PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at -http://marknelson.us/1997/01/01/zlib-engine/ . +https://marknelson.us/posts/1997/01/01/zlib-engine.html . -The changes made in version 1.2.13 are documented in the file ChangeLog. +The changes made in version 1.3 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . -zlib is available in Java using the java.util.zip package, documented at -http://java.sun.com/developer/technicalArticles/Programming/compression/ . +zlib is available in Java using the java.util.zip package. Follow the API +Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . -A Perl interface to zlib written by Paul Marquess is available -at CPAN (Comprehensive Perl Archive Network) sites, including -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . +A Perl interface to zlib and bzip2 written by Paul Marquess +can be found at https://github.com/pmqs/IO-Compress . A Python interface to zlib written by A.M. Kuchling is available in Python 1.5 and later versions, see @@ -64,7 +63,7 @@ Notes for some targets: - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works when compiled with cc. -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is +- On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is necessary to get gzprintf working correctly. This is done by configure. - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with @@ -84,7 +83,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2022 Jean-loup Gailly and Mark Adler + (C) 1995-2023 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/zlib/adler32.c b/zlib/adler32.c index e82e8eedd13..df720f4b490 100644 --- a/zlib/adler32.c +++ b/zlib/adler32.c @@ -7,8 +7,6 @@ #include "zutil.h" -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - #define BASE 65521U /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ @@ -60,11 +58,7 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); #endif /* ========================================================================= */ -uLong ZEXPORT adler32_z(adler, buf, len) - uLong adler; - const Bytef *buf; - z_size_t len; -{ +uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { unsigned long sum2; unsigned n; @@ -131,20 +125,12 @@ uLong ZEXPORT adler32_z(adler, buf, len) } /* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ +uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { return adler32_z(adler, buf, len); } /* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { unsigned long sum1; unsigned long sum2; unsigned rem; @@ -169,18 +155,10 @@ local uLong adler32_combine_(adler1, adler2, len2) } /* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ +uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { return adler32_combine_(adler1, adler2, len2); } -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ +uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { return adler32_combine_(adler1, adler2, len2); } diff --git a/zlib/compress.c b/zlib/compress.c index 2ad5326c14e..f43bacf7ab9 100644 --- a/zlib/compress.c +++ b/zlib/compress.c @@ -19,13 +19,8 @@ memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ -int ZEXPORT compress2(dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen, int level) { z_stream stream; int err; const uInt max = (uInt)-1; @@ -65,12 +60,8 @@ int ZEXPORT compress2(dest, destLen, source, sourceLen, level) /* =========================================================================== */ -int ZEXPORT compress(dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ +int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); } @@ -78,9 +69,7 @@ int ZEXPORT compress(dest, destLen, source, sourceLen) If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ -uLong ZEXPORT compressBound(sourceLen) - uLong sourceLen; -{ +uLong ZEXPORT compressBound(uLong sourceLen) { return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13; } diff --git a/zlib/crc32.c b/zlib/crc32.c index f8357b083f7..6c38f5c04c6 100644 --- a/zlib/crc32.c +++ b/zlib/crc32.c @@ -103,19 +103,6 @@ # define ARMCRC32 #endif -/* Local functions. */ -local z_crc_t multmodp OF((z_crc_t a, z_crc_t b)); -local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); - -#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) - local z_word_t byte_swap OF((z_word_t word)); -#endif - -#if defined(W) && !defined(ARMCRC32) - local z_crc_t crc_word OF((z_word_t data)); - local z_word_t crc_word_big OF((z_word_t data)); -#endif - #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) /* Swap the bytes in a z_word_t to convert between little and big endian. Any @@ -123,9 +110,7 @@ local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); instruction, if one is available. This assumes that word_t is either 32 bits or 64 bits. */ -local z_word_t byte_swap(word) - z_word_t word; -{ +local z_word_t byte_swap(z_word_t word) { # if W == 8 return (word & 0xff00000000000000) >> 56 | @@ -146,24 +131,77 @@ local z_word_t byte_swap(word) } #endif +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Table of powers of x for combining CRC-32s, filled in by make_crc_table() + * below. + */ + local z_crc_t FAR x2n_table[32]; +#else +/* ========================================================================= + * Tables for byte-wise and braided CRC-32 calculations, and a table of powers + * of x for combining CRC-32s, all made by make_crc_table(). + */ +# include "crc32.h" +#endif + /* CRC polynomial. */ #define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ -#ifdef DYNAMIC_CRC_TABLE +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +local z_crc_t multmodp(z_crc_t a, z_crc_t b) { + z_crc_t m, p; + m = (z_crc_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +local z_crc_t x2nmodp(z_off64_t n, unsigned k) { + z_crc_t p; + + p = (z_crc_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Build the tables for byte-wise and braided CRC-32 calculations, and a table + * of powers of x for combining CRC-32s. + */ local z_crc_t FAR crc_table[256]; -local z_crc_t FAR x2n_table[32]; -local void make_crc_table OF((void)); #ifdef W local z_word_t FAR crc_big_table[256]; local z_crc_t FAR crc_braid_table[W][256]; local z_word_t FAR crc_braid_big_table[W][256]; - local void braid OF((z_crc_t [][256], z_word_t [][256], int, int)); + local void braid(z_crc_t [][256], z_word_t [][256], int, int); #endif #ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *, int)); - local void write_table32hi OF((FILE *, const z_word_t FAR *, int)); - local void write_table64 OF((FILE *, const z_word_t FAR *, int)); + local void write_table(FILE *, const z_crc_t FAR *, int); + local void write_table32hi(FILE *, const z_word_t FAR *, int); + local void write_table64(FILE *, const z_word_t FAR *, int); #endif /* MAKECRCH */ /* @@ -176,7 +214,6 @@ local void make_crc_table OF((void)); /* Definition of once functionality. */ typedef struct once_s once_t; -local void once OF((once_t *, void (*)(void))); /* Check for the availability of atomics. */ #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ @@ -196,10 +233,7 @@ struct once_s { invoke once() at the same time. The state must be a once_t initialized with ONCE_INIT. */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ +local void once(once_t *state, void (*init)(void)) { if (!atomic_load(&state->done)) { if (atomic_flag_test_and_set(&state->begun)) while (!atomic_load(&state->done)) @@ -222,10 +256,7 @@ struct once_s { /* Test and set. Alas, not atomic, but tries to minimize the period of vulnerability. */ -local int test_and_set OF((int volatile *)); -local int test_and_set(flag) - int volatile *flag; -{ +local int test_and_set(int volatile *flag) { int was; was = *flag; @@ -234,10 +265,7 @@ local int test_and_set(flag) } /* Run the provided init() function once. This is not thread-safe. */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ +local void once(once_t *state, void (*init)(void)) { if (!state->done) { if (test_and_set(&state->begun)) while (!state->done) @@ -279,8 +307,7 @@ local once_t made = ONCE_INIT; combinations of CRC register values and incoming bytes. */ -local void make_crc_table() -{ +local void make_crc_table(void) { unsigned i, j, n; z_crc_t p; @@ -447,11 +474,7 @@ local void make_crc_table() Write the 32-bit values in table[0..k-1] to out, five per line in hexadecimal separated by commas. */ -local void write_table(out, table, k) - FILE *out; - const z_crc_t FAR *table; - int k; -{ +local void write_table(FILE *out, const z_crc_t FAR *table, int k) { int n; for (n = 0; n < k; n++) @@ -464,11 +487,7 @@ local void write_table(out, table, k) Write the high 32-bits of each value in table[0..k-1] to out, five per line in hexadecimal separated by commas. */ -local void write_table32hi(out, table, k) -FILE *out; -const z_word_t FAR *table; -int k; -{ +local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { int n; for (n = 0; n < k; n++) @@ -484,11 +503,7 @@ int k; bits. If not, then the type cast and format string can be adjusted accordingly. */ -local void write_table64(out, table, k) - FILE *out; - const z_word_t FAR *table; - int k; -{ +local void write_table64(FILE *out, const z_word_t FAR *table, int k) { int n; for (n = 0; n < k; n++) @@ -498,8 +513,7 @@ local void write_table64(out, table, k) } /* Actually do the deed. */ -int main() -{ +int main(void) { make_crc_table(); return 0; } @@ -511,12 +525,7 @@ int main() Generate the little and big-endian braid tables for the given n and z_word_t size w. Each array must have room for w blocks of 256 elements. */ -local void braid(ltl, big, n, w) - z_crc_t ltl[][256]; - z_word_t big[][256]; - int n; - int w; -{ +local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { int k; z_crc_t i, p, q; for (k = 0; k < w; k++) { @@ -531,69 +540,13 @@ local void braid(ltl, big, n, w) } #endif -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables for byte-wise and braided CRC-32 calculations, and a table of powers - * of x for combining CRC-32s, all made by make_crc_table(). - */ -#include "crc32.h" #endif /* DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Routines used for CRC calculation. Some are also required for the table - * generation above. - */ - -/* - Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, - reflected. For speed, this requires that a not be zero. - */ -local z_crc_t multmodp(a, b) - z_crc_t a; - z_crc_t b; -{ - z_crc_t m, p; - - m = (z_crc_t)1 << 31; - p = 0; - for (;;) { - if (a & m) { - p ^= b; - if ((a & (m - 1)) == 0) - break; - } - m >>= 1; - b = b & 1 ? (b >> 1) ^ POLY : b >> 1; - } - return p; -} - -/* - Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been - initialized. - */ -local z_crc_t x2nmodp(n, k) - z_off64_t n; - unsigned k; -{ - z_crc_t p; - - p = (z_crc_t)1 << 31; /* x^0 == 1 */ - while (n) { - if (n & 1) - p = multmodp(x2n_table[k & 31], p); - n >>= 1; - k++; - } - return p; -} - /* ========================================================================= * This function can be used by asm versions of crc32(), and to force the * generation of the CRC tables in a threaded application. */ -const z_crc_t FAR * ZEXPORT get_crc_table() -{ +const z_crc_t FAR * ZEXPORT get_crc_table(void) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ @@ -619,11 +572,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table() #define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ #define Z_BATCH_MIN 800 /* fewest words in a final batch */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { z_crc_t val; z_word_t crc1, crc2; const z_word_t *word; @@ -723,18 +673,14 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) least-significant byte of the word as the first byte of data, without any pre or post conditioning. This is used to combine the CRCs of each braid. */ -local z_crc_t crc_word(data) - z_word_t data; -{ +local z_crc_t crc_word(z_word_t data) { int k; for (k = 0; k < W; k++) data = (data >> 8) ^ crc_table[data & 0xff]; return (z_crc_t)data; } -local z_word_t crc_word_big(data) - z_word_t data; -{ +local z_word_t crc_word_big(z_word_t data) { int k; for (k = 0; k < W; k++) data = (data << 8) ^ @@ -745,11 +691,8 @@ local z_word_t crc_word_big(data) #endif /* ========================================================================= */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { /* Return initial CRC, if requested. */ if (buf == Z_NULL) return 0; @@ -781,8 +724,8 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) words = (z_word_t const *)buf; /* Do endian check at execution time instead of compile time, since ARM - processors can change the endianess at execution time. If the - compiler knows what the endianess will be, it can optimize out the + processors can change the endianness at execution time. If the + compiler knows what the endianness will be, it can optimize out the check and the unused branch. */ endian = 1; if (*(unsigned char *)&endian) { @@ -1069,20 +1012,13 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) #endif /* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ +unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, + uInt len) { return crc32_z(crc, buf, len); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ @@ -1090,18 +1026,12 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2) } /* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { return crc32_combine64(crc1, crc2, (z_off64_t)len2); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen64(len2) - z_off64_t len2; -{ +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ @@ -1109,17 +1039,11 @@ uLong ZEXPORT crc32_combine_gen64(len2) } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen(len2) - z_off_t len2; -{ +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { return crc32_combine_gen64((z_off64_t)len2); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_op(crc1, crc2, op) - uLong crc1; - uLong crc2; - uLong op; -{ +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { return multmodp(op, crc1) ^ (crc2 & 0xffffffff); } diff --git a/zlib/deflate.c b/zlib/deflate.c index 4a689db3598..bd011751920 100644 --- a/zlib/deflate.c +++ b/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; + " deflate 1.3 Copyright 1995-2023 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -60,9 +60,6 @@ const char deflate_copyright[] = copyright string in the executable of your product. */ -/* =========================================================================== - * Function prototypes. - */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ @@ -70,29 +67,16 @@ typedef enum { finish_done /* finish done, accept no more input or output */ } block_state; -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +typedef block_state (*compress_func)(deflate_state *s, int flush); /* Compression function. Returns the block state after the call. */ -local int deflateStateCheck OF((z_streamp strm)); -local void slide_hash OF((deflate_state *s)); -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_stored(deflate_state *s, int flush); +local block_state deflate_fast(deflate_state *s, int flush); #ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -local uInt longest_match OF((deflate_state *s, IPos cur_match)); - -#ifdef ZLIB_DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); +local block_state deflate_slow(deflate_state *s, int flush); #endif +local block_state deflate_rle(deflate_state *s, int flush); +local block_state deflate_huff(deflate_state *s, int flush); /* =========================================================================== * Local data @@ -195,9 +179,12 @@ local const config configuration_table[10] = { * bit values at the expense of memory usage). We slide even when level == 0 to * keep the hash table consistent if we switch back to level > 0 later. */ -local void slide_hash(s) - deflate_state *s; -{ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) + __attribute__((no_sanitize("memory"))) +# endif +#endif +local void slide_hash(deflate_state *s) { unsigned n, m; Posf *p; uInt wsize = s->w_size; @@ -221,30 +208,177 @@ local void slide_hash(s) #endif } +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(deflate_state *s) { + unsigned n; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize + MAX_DIST(s)) { + + zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + if (s->insert > s->strstart) + s->insert = s->strstart; + slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + /* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ +int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, + int stream_size) { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ +int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, int strategy, + const char *version, int stream_size) { deflate_state *s; int wrap = 1; static const char my_version[] = ZLIB_VERSION; @@ -386,9 +520,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, /* ========================================================================= * Check for a valid deflate stream state. Return 0 if ok, 1 if not. */ -local int deflateStateCheck(strm) - z_streamp strm; -{ +local int deflateStateCheck(z_streamp strm) { deflate_state *s; if (strm == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) @@ -409,11 +541,8 @@ local int deflateStateCheck(strm) } /* ========================================================================= */ -int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ +int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { deflate_state *s; uInt str, n; int wrap; @@ -478,11 +607,8 @@ int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) } /* ========================================================================= */ -int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) - z_streamp strm; - Bytef *dictionary; - uInt *dictLength; -{ +int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { deflate_state *s; uInt len; @@ -500,9 +626,7 @@ int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) } /* ========================================================================= */ -int ZEXPORT deflateResetKeep(strm) - z_streamp strm; -{ +int ZEXPORT deflateResetKeep(z_streamp strm) { deflate_state *s; if (deflateStateCheck(strm)) { @@ -537,10 +661,32 @@ int ZEXPORT deflateResetKeep(strm) return Z_OK; } +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init(deflate_state *s) { + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +} + /* ========================================================================= */ -int ZEXPORT deflateReset(strm) - z_streamp strm; -{ +int ZEXPORT deflateReset(z_streamp strm) { int ret; ret = deflateResetKeep(strm); @@ -550,10 +696,7 @@ int ZEXPORT deflateReset(strm) } /* ========================================================================= */ -int ZEXPORT deflateSetHeader(strm, head) - z_streamp strm; - gz_headerp head; -{ +int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { if (deflateStateCheck(strm) || strm->state->wrap != 2) return Z_STREAM_ERROR; strm->state->gzhead = head; @@ -561,11 +704,7 @@ int ZEXPORT deflateSetHeader(strm, head) } /* ========================================================================= */ -int ZEXPORT deflatePending(strm, pending, bits) - unsigned *pending; - int *bits; - z_streamp strm; -{ +int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; if (pending != Z_NULL) *pending = strm->state->pending; @@ -575,11 +714,7 @@ int ZEXPORT deflatePending(strm, pending, bits) } /* ========================================================================= */ -int ZEXPORT deflatePrime(strm, bits, value) - z_streamp strm; - int bits; - int value; -{ +int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { deflate_state *s; int put; @@ -602,11 +737,7 @@ int ZEXPORT deflatePrime(strm, bits, value) } /* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ +int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { deflate_state *s; compress_func func; @@ -651,13 +782,8 @@ int ZEXPORT deflateParams(strm, level, strategy) } /* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ +int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, + int nice_length, int max_chain) { deflate_state *s; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -693,10 +819,7 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) * * Shifts are used to approximate divisions, for speed. */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { deflate_state *s; uLong fixedlen, storelen, wraplen; @@ -752,7 +875,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen) /* if not default parameters, return one of the conservative bounds */ if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen; + return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + + wraplen; /* default settings: return tight bound for that case -- ~0.03% overhead plus a small constant */ @@ -765,10 +889,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ -local void putShortMSB(s, b) - deflate_state *s; - uInt b; -{ +local void putShortMSB(deflate_state *s, uInt b) { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } @@ -779,9 +900,7 @@ local void putShortMSB(s, b) * applications may wish to modify it to avoid allocating a large * strm->next_out buffer and copying into it. (See also read_buf()). */ -local void flush_pending(strm) - z_streamp strm; -{ +local void flush_pending(z_streamp strm) { unsigned len; deflate_state *s = strm->state; @@ -812,10 +931,7 @@ local void flush_pending(strm) } while (0) /* ========================================================================= */ -int ZEXPORT deflate(strm, flush) - z_streamp strm; - int flush; -{ +int ZEXPORT deflate(z_streamp strm, int flush) { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; @@ -1127,9 +1243,7 @@ int ZEXPORT deflate(strm, flush) } /* ========================================================================= */ -int ZEXPORT deflateEnd(strm) - z_streamp strm; -{ +int ZEXPORT deflateEnd(z_streamp strm) { int status; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1153,11 +1267,10 @@ int ZEXPORT deflateEnd(strm) * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ -int ZEXPORT deflateCopy(dest, source) - z_streamp dest; - z_streamp source; -{ +int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { #ifdef MAXSEG_64K + (void)dest; + (void)source; return Z_STREAM_ERROR; #else deflate_state *ds; @@ -1205,66 +1318,6 @@ int ZEXPORT deflateCopy(dest, source) #endif /* MAXSEG_64K */ } -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init(s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -} - #ifndef FASTEST /* =========================================================================== * Set match_start to the longest match starting at the given string and @@ -1275,10 +1328,7 @@ local void lm_init(s) * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ +local uInt longest_match(deflate_state *s, IPos cur_match) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ @@ -1426,10 +1476,7 @@ local uInt longest_match(s, cur_match) /* --------------------------------------------------------------------------- * Optimized version for FASTEST only */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ +local uInt longest_match(deflate_state *s, IPos cur_match) { register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ @@ -1490,11 +1537,7 @@ local uInt longest_match(s, cur_match) /* =========================================================================== * Check that the match at match_start is indeed a match. */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ +local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ if (zmemcmp(s->window + match, s->window + start, length) != EQUAL) { @@ -1514,137 +1557,6 @@ local void check_match(s, start, match, length) # define check_match(s, start, match, length) #endif /* ZLIB_DEBUG */ -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize + MAX_DIST(s)) { - - zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - if (s->insert > s->strstart) - s->insert = s->strstart; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. @@ -1687,10 +1599,7 @@ local void fill_window(s) * copied. It is most efficient with large input and output buffers, which * maximizes the opportunities to have a single copy from next_in to next_out. */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_stored(deflate_state *s, int flush) { /* Smallest worthy block size when not flushing or finishing. By default * this is 32K. This can be as small as 507 bytes for memLevel == 1. For * large input and output buffers, the stored block size will be larger. @@ -1874,10 +1783,7 @@ local block_state deflate_stored(s, flush) * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_fast(deflate_state *s, int flush) { IPos hash_head; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ @@ -1976,10 +1882,7 @@ local block_state deflate_fast(s, flush) * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_slow(deflate_state *s, int flush) { IPos hash_head; /* head of hash chain */ int bflush; /* set if current block must be flushed */ @@ -2107,10 +2010,7 @@ local block_state deflate_slow(s, flush) * one. Do not maintain a hash table. (It will be regenerated if this run of * deflate switches away from Z_RLE.) */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_rle(deflate_state *s, int flush) { int bflush; /* set if current block must be flushed */ uInt prev; /* byte at distance one to match */ Bytef *scan, *strend; /* scan goes up to strend for length of run */ @@ -2181,10 +2081,7 @@ local block_state deflate_rle(s, flush) * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. * (It will be regenerated if this run of deflate switches away from Huffman.) */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_huff(deflate_state *s, int flush) { int bflush; /* set if current block must be flushed */ for (;;) { diff --git a/zlib/deflate.h b/zlib/deflate.h index 1a06cd5f25d..8696791429f 100644 --- a/zlib/deflate.h +++ b/zlib/deflate.h @@ -291,14 +291,14 @@ typedef struct internal_state { memory checker errors from longest match routines */ /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_init(deflate_state *s); +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last); +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); +void ZLIB_INTERNAL _tr_align(deflate_state *s); +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) diff --git a/zlib/gzclose.c b/zlib/gzclose.c index caeb99a3177..48d6a86f04b 100644 --- a/zlib/gzclose.c +++ b/zlib/gzclose.c @@ -8,9 +8,7 @@ /* gzclose() is in a separate file so that it is linked in only if it is used. That way the other gzclose functions can be used instead to avoid linking in unneeded compression or decompression routines. */ -int ZEXPORT gzclose(file) - gzFile file; -{ +int ZEXPORT gzclose(gzFile file) { #ifndef NO_GZCOMPRESS gz_statep state; diff --git a/zlib/gzguts.h b/zlib/gzguts.h index 57faf37165a..f9375047e8c 100644 --- a/zlib/gzguts.h +++ b/zlib/gzguts.h @@ -7,9 +7,8 @@ # ifndef _LARGEFILE_SOURCE # define _LARGEFILE_SOURCE 1 # endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif +# undef _FILE_OFFSET_BITS +# undef _TIME_BITS #endif #ifdef HAVE_HIDDEN @@ -119,8 +118,8 @@ /* gz* functions always use library allocation functions */ #ifndef STDC - extern voidp malloc OF((uInt size)); - extern void free OF((voidpf ptr)); + extern voidp malloc(uInt size); + extern void free(voidpf ptr); #endif /* get errno and strerror definition */ @@ -138,10 +137,10 @@ /* provide prototypes for these when building zlib without LFS */ #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); #endif /* default memLevel */ @@ -203,9 +202,9 @@ typedef struct { typedef gz_state FAR *gz_statep; /* shared functions */ -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); #if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +char ZLIB_INTERNAL *gz_strwinerror(DWORD error); #endif /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t @@ -214,6 +213,6 @@ char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); #ifdef INT_MAX # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) #else -unsigned ZLIB_INTERNAL gz_intmax OF((void)); +unsigned ZLIB_INTERNAL gz_intmax(void); # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) #endif diff --git a/zlib/gzlib.c b/zlib/gzlib.c index 55da46a453f..29fc4486fba 100644 --- a/zlib/gzlib.c +++ b/zlib/gzlib.c @@ -15,10 +15,6 @@ #endif #endif -/* Local functions */ -local void gz_reset OF((gz_statep)); -local gzFile gz_open OF((const void *, int, const char *)); - #if defined UNDER_CE /* Map the Windows error number in ERROR to a locale-dependent error message @@ -30,9 +26,7 @@ local gzFile gz_open OF((const void *, int, const char *)); The gz_strwinerror function does not change the current setting of GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror(error) - DWORD error; -{ +char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { static char buf[1024]; wchar_t *msgbuf; @@ -72,9 +66,7 @@ char ZLIB_INTERNAL *gz_strwinerror(error) #endif /* UNDER_CE */ /* Reset gzip file state */ -local void gz_reset(state) - gz_statep state; -{ +local void gz_reset(gz_statep state) { state->x.have = 0; /* no output data available */ if (state->mode == GZ_READ) { /* for reading ... */ state->eof = 0; /* not at end of file */ @@ -90,11 +82,7 @@ local void gz_reset(state) } /* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(path, fd, mode) - const void *path; - int fd; - const char *mode; -{ +local gzFile gz_open(const void *path, int fd, const char *mode) { gz_statep state; z_size_t len; int oflag; @@ -269,26 +257,17 @@ local gzFile gz_open(path, fd, mode) } /* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(path, mode) - const char *path; - const char *mode; -{ +gzFile ZEXPORT gzopen(const char *path, const char *mode) { return gz_open(path, -1, mode); } /* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(path, mode) - const char *path; - const char *mode; -{ +gzFile ZEXPORT gzopen64(const char *path, const char *mode) { return gz_open(path, -1, mode); } /* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(fd, mode) - int fd; - const char *mode; -{ +gzFile ZEXPORT gzdopen(int fd, const char *mode) { char *path; /* identifier for error messages */ gzFile gz; @@ -306,19 +285,13 @@ gzFile ZEXPORT gzdopen(fd, mode) /* -- see zlib.h -- */ #ifdef WIDECHAR -gzFile ZEXPORT gzopen_w(path, mode) - const wchar_t *path; - const char *mode; -{ +gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { return gz_open(path, -2, mode); } #endif /* -- see zlib.h -- */ -int ZEXPORT gzbuffer(file, size) - gzFile file; - unsigned size; -{ +int ZEXPORT gzbuffer(gzFile file, unsigned size) { gz_statep state; /* get internal structure and check integrity */ @@ -335,16 +308,14 @@ int ZEXPORT gzbuffer(file, size) /* check and set requested size */ if ((size << 1) < size) return -1; /* need to be able to double it */ - if (size < 2) - size = 2; /* need two bytes to check magic header */ + if (size < 8) + size = 8; /* needed to behave well with flushing */ state->want = size; return 0; } /* -- see zlib.h -- */ -int ZEXPORT gzrewind(file) - gzFile file; -{ +int ZEXPORT gzrewind(gzFile file) { gz_statep state; /* get internal structure */ @@ -365,11 +336,7 @@ int ZEXPORT gzrewind(file) } /* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(file, offset, whence) - gzFile file; - z_off64_t offset; - int whence; -{ +z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { unsigned n; z_off64_t ret; gz_statep state; @@ -442,11 +409,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) } /* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ +z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { z_off64_t ret; ret = gzseek64(file, (z_off64_t)offset, whence); @@ -454,9 +417,7 @@ z_off_t ZEXPORT gzseek(file, offset, whence) } /* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(file) - gzFile file; -{ +z_off64_t ZEXPORT gztell64(gzFile file) { gz_statep state; /* get internal structure and check integrity */ @@ -471,9 +432,7 @@ z_off64_t ZEXPORT gztell64(file) } /* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(file) - gzFile file; -{ +z_off_t ZEXPORT gztell(gzFile file) { z_off64_t ret; ret = gztell64(file); @@ -481,9 +440,7 @@ z_off_t ZEXPORT gztell(file) } /* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(file) - gzFile file; -{ +z_off64_t ZEXPORT gzoffset64(gzFile file) { z_off64_t offset; gz_statep state; @@ -504,9 +461,7 @@ z_off64_t ZEXPORT gzoffset64(file) } /* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(file) - gzFile file; -{ +z_off_t ZEXPORT gzoffset(gzFile file) { z_off64_t ret; ret = gzoffset64(file); @@ -514,9 +469,7 @@ z_off_t ZEXPORT gzoffset(file) } /* -- see zlib.h -- */ -int ZEXPORT gzeof(file) - gzFile file; -{ +int ZEXPORT gzeof(gzFile file) { gz_statep state; /* get internal structure and check integrity */ @@ -531,10 +484,7 @@ int ZEXPORT gzeof(file) } /* -- see zlib.h -- */ -const char * ZEXPORT gzerror(file, errnum) - gzFile file; - int *errnum; -{ +const char * ZEXPORT gzerror(gzFile file, int *errnum) { gz_statep state; /* get internal structure and check integrity */ @@ -552,9 +502,7 @@ const char * ZEXPORT gzerror(file, errnum) } /* -- see zlib.h -- */ -void ZEXPORT gzclearerr(file) - gzFile file; -{ +void ZEXPORT gzclearerr(gzFile file) { gz_statep state; /* get internal structure and check integrity */ @@ -578,11 +526,7 @@ void ZEXPORT gzclearerr(file) memory). Simply save the error message as a static string. If there is an allocation failure constructing the error message, then convert the error to out of memory. */ -void ZLIB_INTERNAL gz_error(state, err, msg) - gz_statep state; - int err; - const char *msg; -{ +void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { /* free previously allocated message and clear */ if (state->msg != NULL) { if (state->err != Z_MEM_ERROR) @@ -624,8 +568,7 @@ void ZLIB_INTERNAL gz_error(state, err, msg) available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax() -{ +unsigned ZLIB_INTERNAL gz_intmax(void) { unsigned p, q; p = 1; diff --git a/zlib/gzread.c b/zlib/gzread.c index a53d54a2208..d2f3dd434af 100644 --- a/zlib/gzread.c +++ b/zlib/gzread.c @@ -5,25 +5,12 @@ #include "gzguts.h" -/* Local functions */ -local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); -local int gz_avail OF((gz_statep)); -local int gz_look OF((gz_statep)); -local int gz_decomp OF((gz_statep)); -local int gz_fetch OF((gz_statep)); -local int gz_skip OF((gz_statep, z_off64_t)); -local z_size_t gz_read OF((gz_statep, voidp, z_size_t)); - /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from state->fd, and update state->eof, state->err, and state->msg as appropriate. This function needs to loop on read(), since read() is not guaranteed to read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(state, buf, len, have) - gz_statep state; - unsigned char *buf; - unsigned len; - unsigned *have; -{ +local int gz_load(gz_statep state, unsigned char *buf, unsigned len, + unsigned *have) { int ret; unsigned get, max = ((unsigned)-1 >> 2) + 1; @@ -53,9 +40,7 @@ local int gz_load(state, buf, len, have) If strm->avail_in != 0, then the current data is moved to the beginning of the input buffer, and then the remainder of the buffer is loaded with the available data from the input file. */ -local int gz_avail(state) - gz_statep state; -{ +local int gz_avail(gz_statep state) { unsigned got; z_streamp strm = &(state->strm); @@ -88,9 +73,7 @@ local int gz_avail(state) case, all further file reads will be directly to either the output buffer or a user buffer. If decompressing, the inflate state will be initialized. gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(state) - gz_statep state; -{ +local int gz_look(gz_statep state) { z_streamp strm = &(state->strm); /* allocate read buffers and inflate memory */ @@ -170,9 +153,7 @@ local int gz_look(state) data. If the gzip stream completes, state->how is reset to LOOK to look for the next gzip stream or raw data, once state->x.have is depleted. Returns 0 on success, -1 on failure. */ -local int gz_decomp(state) - gz_statep state; -{ +local int gz_decomp(gz_statep state) { int ret = Z_OK; unsigned had; z_streamp strm = &(state->strm); @@ -224,9 +205,7 @@ local int gz_decomp(state) looked for to determine whether to copy or decompress. Returns -1 on error, otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the end of the input file has been reached and all data has been processed. */ -local int gz_fetch(state) - gz_statep state; -{ +local int gz_fetch(gz_statep state) { z_streamp strm = &(state->strm); do { @@ -254,10 +233,7 @@ local int gz_fetch(state) } /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(state, len) - gz_statep state; - z_off64_t len; -{ +local int gz_skip(gz_statep state, z_off64_t len) { unsigned n; /* skip over len bytes or reach end-of-file, whichever comes first */ @@ -289,11 +265,7 @@ local int gz_skip(state, len) input. Return the number of bytes read. If zero is returned, either the end of file was reached, or there was an error. state->err must be consulted in that case to determine which. */ -local z_size_t gz_read(state, buf, len) - gz_statep state; - voidp buf; - z_size_t len; -{ +local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { z_size_t got; unsigned n; @@ -370,11 +342,7 @@ local z_size_t gz_read(state, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzread(file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ +int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { gz_statep state; /* get internal structure */ @@ -406,12 +374,7 @@ int ZEXPORT gzread(file, buf, len) } /* -- see zlib.h -- */ -z_size_t ZEXPORT gzfread(buf, size, nitems, file) - voidp buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ +z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) { z_size_t len; gz_statep state; @@ -442,9 +405,7 @@ z_size_t ZEXPORT gzfread(buf, size, nitems, file) #else # undef gzgetc #endif -int ZEXPORT gzgetc(file) - gzFile file; -{ +int ZEXPORT gzgetc(gzFile file) { unsigned char buf[1]; gz_statep state; @@ -469,17 +430,12 @@ int ZEXPORT gzgetc(file) return (int)gz_read(state, buf, 1) < 1 ? -1 : buf[0]; } -int ZEXPORT gzgetc_(file) -gzFile file; -{ +int ZEXPORT gzgetc_(gzFile file) { return gzgetc(file); } /* -- see zlib.h -- */ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ +int ZEXPORT gzungetc(int c, gzFile file) { gz_statep state; /* get internal structure */ @@ -487,6 +443,10 @@ int ZEXPORT gzungetc(c, file) return -1; state = (gz_statep)file; + /* in case this was just opened, set up the input buffer */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + /* check that we're reading and that there's no (serious) error */ if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) @@ -536,11 +496,7 @@ int ZEXPORT gzungetc(c, file) } /* -- see zlib.h -- */ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ +char * ZEXPORT gzgets(gzFile file, char *buf, int len) { unsigned left, n; char *str; unsigned char *eol; @@ -600,9 +556,7 @@ char * ZEXPORT gzgets(file, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzdirect(file) - gzFile file; -{ +int ZEXPORT gzdirect(gzFile file) { gz_statep state; /* get internal structure */ @@ -620,9 +574,7 @@ int ZEXPORT gzdirect(file) } /* -- see zlib.h -- */ -int ZEXPORT gzclose_r(file) - gzFile file; -{ +int ZEXPORT gzclose_r(gzFile file) { int ret, err; gz_statep state; diff --git a/zlib/gzwrite.c b/zlib/gzwrite.c index b7236f70d14..f6b0d7586d1 100644 --- a/zlib/gzwrite.c +++ b/zlib/gzwrite.c @@ -5,18 +5,10 @@ #include "gzguts.h" -/* Local functions */ -local int gz_init OF((gz_statep)); -local int gz_comp OF((gz_statep, int)); -local int gz_zero OF((gz_statep, z_off64_t)); -local z_size_t gz_write OF((gz_statep, voidpc, z_size_t)); - /* Initialize state for writing a gzip file. Mark initialization by setting state->size to non-zero. Return -1 on a memory allocation failure, or 0 on success. */ -local int gz_init(state) - gz_statep state; -{ +local int gz_init(gz_statep state) { int ret; z_streamp strm = &(state->strm); @@ -70,10 +62,7 @@ local int gz_init(state) deflate() flush value. If flush is Z_FINISH, then the deflate() state is reset to start a new gzip stream. If gz->direct is true, then simply write to the output file without compressing, and ignore flush. */ -local int gz_comp(state, flush) - gz_statep state; - int flush; -{ +local int gz_comp(gz_statep state, int flush) { int ret, writ; unsigned have, put, max = ((unsigned)-1 >> 2) + 1; z_streamp strm = &(state->strm); @@ -151,10 +140,7 @@ local int gz_comp(state, flush) /* Compress len zeros to output. Return -1 on a write error or memory allocation failure by gz_comp(), or 0 on success. */ -local int gz_zero(state, len) - gz_statep state; - z_off64_t len; -{ +local int gz_zero(gz_statep state, z_off64_t len) { int first; unsigned n; z_streamp strm = &(state->strm); @@ -184,11 +170,7 @@ local int gz_zero(state, len) /* Write len bytes from buf to file. Return the number of bytes written. If the returned value is less than len, then there was an error. */ -local z_size_t gz_write(state, buf, len) - gz_statep state; - voidpc buf; - z_size_t len; -{ +local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { z_size_t put = len; /* if len is zero, avoid unnecessary operations */ @@ -252,11 +234,7 @@ local z_size_t gz_write(state, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzwrite(file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ +int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { gz_statep state; /* get internal structure */ @@ -280,12 +258,8 @@ int ZEXPORT gzwrite(file, buf, len) } /* -- see zlib.h -- */ -z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) - voidpc buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ +z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, + gzFile file) { z_size_t len; gz_statep state; @@ -310,10 +284,7 @@ z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) } /* -- see zlib.h -- */ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ +int ZEXPORT gzputc(gzFile file, int c) { unsigned have; unsigned char buf[1]; gz_statep state; @@ -358,10 +329,7 @@ int ZEXPORT gzputc(file, c) } /* -- see zlib.h -- */ -int ZEXPORT gzputs(file, s) - gzFile file; - const char *s; -{ +int ZEXPORT gzputs(gzFile file, const char *s) { z_size_t len, put; gz_statep state; @@ -388,8 +356,7 @@ int ZEXPORT gzputs(file, s) #include /* -- see zlib.h -- */ -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) -{ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { int len; unsigned left; char *next; @@ -460,8 +427,7 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) return len; } -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) -{ +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { va_list va; int ret; @@ -474,13 +440,10 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) #else /* !STDC && !Z_HAVE_STDARG_H */ /* -- see zlib.h -- */ -int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ +int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, + int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, int a14, int a15, int a16, + int a17, int a18, int a19, int a20) { unsigned len, left; char *next; gz_statep state; @@ -562,10 +525,7 @@ int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, #endif /* -- see zlib.h -- */ -int ZEXPORT gzflush(file, flush) - gzFile file; - int flush; -{ +int ZEXPORT gzflush(gzFile file, int flush) { gz_statep state; /* get internal structure */ @@ -594,11 +554,7 @@ int ZEXPORT gzflush(file, flush) } /* -- see zlib.h -- */ -int ZEXPORT gzsetparams(file, level, strategy) - gzFile file; - int level; - int strategy; -{ +int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { gz_statep state; z_streamp strm; @@ -609,7 +565,7 @@ int ZEXPORT gzsetparams(file, level, strategy) strm = &(state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) return Z_STREAM_ERROR; /* if no change is requested, then do nothing */ @@ -636,9 +592,7 @@ int ZEXPORT gzsetparams(file, level, strategy) } /* -- see zlib.h -- */ -int ZEXPORT gzclose_w(file) - gzFile file; -{ +int ZEXPORT gzclose_w(gzFile file) { int ret = Z_OK; gz_statep state; diff --git a/zlib/infback.c b/zlib/infback.c index babeaf1806f..e7b25b307a3 100644 --- a/zlib/infback.c +++ b/zlib/infback.c @@ -15,9 +15,6 @@ #include "inflate.h" #include "inffast.h" -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - /* strm provides memory allocation functions in zalloc and zfree, or Z_NULL to use the library memory allocation functions. @@ -25,13 +22,9 @@ local void fixedtables OF((struct inflate_state FAR *state)); windowBits is in the range 8..15, and window is a user-supplied window and output buffer that is 2**windowBits bytes. */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ +int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, const char *version, + int stream_size) { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || @@ -80,9 +73,7 @@ int stream_size; used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ +local void fixedtables(struct inflate_state FAR *state) { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; @@ -248,13 +239,8 @@ struct inflate_state FAR *state; inflateBack() can also return Z_STREAM_ERROR if the input parameters are not correct, i.e. strm is Z_NULL or the state was not initialized. */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ +int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc) { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ @@ -632,9 +618,7 @@ void FAR *out_desc; return ret; } -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ +int ZEXPORT inflateBackEnd(z_streamp strm) { if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; ZFREE(strm, strm->state); diff --git a/zlib/inffast.c b/zlib/inffast.c index 1fec7f363fa..9354676e786 100644 --- a/zlib/inffast.c +++ b/zlib/inffast.c @@ -47,10 +47,7 @@ requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { struct inflate_state FAR *state; z_const unsigned char FAR *in; /* local strm->next_in */ z_const unsigned char FAR *last; /* have enough input while in < last */ diff --git a/zlib/inffast.h b/zlib/inffast.h index e5c1aa4ca8c..49c6d156c5c 100644 --- a/zlib/inffast.h +++ b/zlib/inffast.h @@ -8,4 +8,4 @@ subject to change. Applications should only use zlib.h. */ -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); diff --git a/zlib/inflate.c b/zlib/inflate.c index 8acbef44e99..b0757a9b249 100644 --- a/zlib/inflate.c +++ b/zlib/inflate.c @@ -91,20 +91,7 @@ # endif #endif -/* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); - -local int inflateStateCheck(strm) -z_streamp strm; -{ +local int inflateStateCheck(z_streamp strm) { struct inflate_state FAR *state; if (strm == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) @@ -116,9 +103,7 @@ z_streamp strm; return 0; } -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ +int ZEXPORT inflateResetKeep(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -142,9 +127,7 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ +int ZEXPORT inflateReset(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -155,10 +138,7 @@ z_streamp strm; return inflateResetKeep(strm); } -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ +int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { int wrap; struct inflate_state FAR *state; @@ -195,12 +175,8 @@ int windowBits; return inflateReset(strm); } -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ +int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size) { int ret; struct inflate_state FAR *state; @@ -239,22 +215,17 @@ int stream_size; return ret; } -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ +int ZEXPORT inflateInit_(z_streamp strm, const char *version, + int stream_size) { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ +int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; @@ -278,9 +249,7 @@ int value; used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ +local void fixedtables(struct inflate_state FAR *state) { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; @@ -342,7 +311,7 @@ struct inflate_state FAR *state; a.out > inffixed.h */ -void makefixed() +void makefixed(void) { unsigned low, size; struct inflate_state state; @@ -396,11 +365,7 @@ void makefixed() output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ -local int updatewindow(strm, end, copy) -z_streamp strm; -const Bytef *end; -unsigned copy; -{ +local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { struct inflate_state FAR *state; unsigned dist; @@ -622,10 +587,7 @@ unsigned copy; will return Z_BUF_ERROR if it has not reached the end of the stream. */ -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ +int ZEXPORT inflate(z_streamp strm, int flush) { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ @@ -1301,9 +1263,7 @@ int flush; return ret; } -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ +int ZEXPORT inflateEnd(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1315,11 +1275,8 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ +int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { struct inflate_state FAR *state; /* check state */ @@ -1338,11 +1295,8 @@ uInt *dictLength; return Z_OK; } -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ +int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { struct inflate_state FAR *state; unsigned long dictid; int ret; @@ -1373,10 +1327,7 @@ uInt dictLength; return Z_OK; } -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ +int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { struct inflate_state FAR *state; /* check state */ @@ -1401,11 +1352,8 @@ gz_headerp head; called again with more data and the *have state. *have is initialized to zero for the first call. */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -const unsigned char FAR *buf; -unsigned len; -{ +local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, + unsigned len) { unsigned got; unsigned next; @@ -1424,9 +1372,7 @@ unsigned len; return next; } -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ +int ZEXPORT inflateSync(z_streamp strm) { unsigned len; /* number of bytes to look at or looked at */ int flags; /* temporary to save header status */ unsigned long in, out; /* temporary to save total_in and total_out */ @@ -1482,9 +1428,7 @@ z_streamp strm; block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ +int ZEXPORT inflateSyncPoint(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1492,10 +1436,7 @@ z_streamp strm; return state->mode == STORED && state->bits == 0; } -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ +int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; @@ -1539,10 +1480,7 @@ z_streamp source; return Z_OK; } -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ +int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1557,10 +1495,7 @@ int subvert; #endif } -int ZEXPORT inflateValidate(strm, check) -z_streamp strm; -int check; -{ +int ZEXPORT inflateValidate(z_streamp strm, int check) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1572,9 +1507,7 @@ int check; return Z_OK; } -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ +long ZEXPORT inflateMark(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) @@ -1585,9 +1518,7 @@ z_streamp strm; (state->mode == MATCH ? state->was - state->length : 0)); } -unsigned long ZEXPORT inflateCodesUsed(strm) -z_streamp strm; -{ +unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return (unsigned long)-1; state = (struct inflate_state FAR *)strm->state; diff --git a/zlib/inftrees.c b/zlib/inftrees.c index 57d2793bec9..8a208c2daa8 100644 --- a/zlib/inftrees.c +++ b/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2022 Mark Adler + * Copyright (C) 1995-2023 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.13 Copyright 1995-2022 Mark Adler "; + " inflate 1.3 Copyright 1995-2023 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -29,14 +29,9 @@ const char inflate_copyright[] = table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work) { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ @@ -62,7 +57,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 194, 65}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/zlib/inftrees.h b/zlib/inftrees.h index f53665311c1..a10712d8cb5 100644 --- a/zlib/inftrees.h +++ b/zlib/inftrees.h @@ -57,6 +57,6 @@ typedef enum { DISTS } codetype; -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work); diff --git a/zlib/qnx/package.qpg b/zlib/qnx/package.qpg index ba2f1a2d6c3..d882af2bfb3 100644 --- a/zlib/qnx/package.qpg +++ b/zlib/qnx/package.qpg @@ -25,10 +25,10 @@ - - - - + + + + @@ -63,7 +63,7 @@ - 1.2.13 + 1.3.0 Medium Stable diff --git a/zlib/treebuild.xml b/zlib/treebuild.xml index 0017a45d3c5..1d1b007707c 100644 --- a/zlib/treebuild.xml +++ b/zlib/treebuild.xml @@ -1,6 +1,6 @@ - - + + zip compression library diff --git a/zlib/trees.c b/zlib/trees.c index 5f305c47221..8dbdc40bacc 100644 --- a/zlib/trees.c +++ b/zlib/trees.c @@ -122,39 +122,116 @@ struct static_tree_desc_s { int max_length; /* max bit length for the codes */ }; -local const static_tree_desc static_l_desc = +#ifdef NO_INIT_GLOBAL_POINTERS +# define TCONST +#else +# define TCONST const +#endif + +local TCONST static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; -local const static_tree_desc static_d_desc = +local TCONST static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; -local const static_tree_desc static_bl_desc = +local TCONST static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== - * Local (static) routines in this file. + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, const ct_data *ltree, - const ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned code, int len)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(unsigned code, int len) { + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(deflate_state *s) { + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(deflate_state *s) { + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->bits_sent = (s->bits_sent + 7) & ~7; +#endif +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = (ush)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = (ush)bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); + } +} #ifdef GEN_TREES_H -local void gen_trees_header OF((void)); +local void gen_trees_header(void); #endif #ifndef ZLIB_DEBUG @@ -167,27 +244,12 @@ local void gen_trees_header OF((void)); send_bits(s, tree[c].Code, tree[c].Len); } #endif -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef ZLIB_DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ +local void send_bits(deflate_state *s, int value, int length) { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; @@ -229,8 +291,7 @@ local void send_bits(s, value, length) /* =========================================================================== * Initialize the various 'constant' tables. */ -local void tr_static_init() -{ +local void tr_static_init(void) { #if defined(GEN_TREES_H) || !defined(STDC) static int static_init_done = 0; int n; /* iterates over tree elements */ @@ -323,8 +384,7 @@ local void tr_static_init() ((i) == (last)? "\n};\n\n" : \ ((i) % (width) == (width) - 1 ? ",\n" : ", ")) -void gen_trees_header() -{ +void gen_trees_header(void) { FILE *header = fopen("trees.h", "w"); int i; @@ -373,12 +433,26 @@ void gen_trees_header() } #endif /* GEN_TREES_H */ +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(deflate_state *s) { + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ +void ZLIB_INTERNAL _tr_init(deflate_state *s) { tr_static_init(); s->l_desc.dyn_tree = s->dyn_ltree; @@ -401,24 +475,6 @@ void ZLIB_INTERNAL _tr_init(s) init_block(s); } -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->sym_next = s->matches = 0; -} - #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ @@ -448,11 +504,7 @@ local void init_block(s) * when the heap property is re-established (each father smaller than its * two sons). */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ +local void pqdownheap(deflate_state *s, ct_data *tree, int k) { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { @@ -483,10 +535,7 @@ local void pqdownheap(s, tree, k) * The length opt_len is updated; static_len is also updated if stree is * not null. */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ +local void gen_bitlen(deflate_state *s, tree_desc *desc) { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; @@ -561,48 +610,9 @@ local void gen_bitlen(s, desc) } } -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes(tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = (ush)bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); - } -} +#ifdef DUMP_BL_TREE +# include +#endif /* =========================================================================== * Construct one Huffman tree and assigns the code bit strings and lengths. @@ -612,10 +622,7 @@ local void gen_codes(tree, max_code, bl_count) * and corresponding code. The length opt_len is updated; static_len is * also updated if stree is not null. The field max_code is set. */ -local void build_tree(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ +local void build_tree(deflate_state *s, tree_desc *desc) { ct_data *tree = desc->dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; @@ -700,11 +707,7 @@ local void build_tree(s, desc) * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ -local void scan_tree(s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ +local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ @@ -745,11 +748,7 @@ local void scan_tree(s, tree, max_code) * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ -local void send_tree(s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ +local void send_tree(deflate_state *s, ct_data *tree, int max_code) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ @@ -796,9 +795,7 @@ local void send_tree(s, tree, max_code) * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ -local int build_bl_tree(s) - deflate_state *s; -{ +local int build_bl_tree(deflate_state *s) { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ @@ -831,10 +828,8 @@ local int build_bl_tree(s) * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ +local void send_all_trees(deflate_state *s, int lcodes, int dcodes, + int blcodes) { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); @@ -860,12 +855,8 @@ local void send_all_trees(s, lcodes, dcodes, blcodes) /* =========================================================================== * Send a stored block */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ bi_windup(s); /* align on byte boundary */ put_short(s, (ush)stored_len); @@ -884,9 +875,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) /* =========================================================================== * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) */ -void ZLIB_INTERNAL _tr_flush_bits(s) - deflate_state *s; -{ +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { bi_flush(s); } @@ -894,9 +883,7 @@ void ZLIB_INTERNAL _tr_flush_bits(s) * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ +void ZLIB_INTERNAL _tr_align(deflate_state *s) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef ZLIB_DEBUG @@ -905,16 +892,99 @@ void ZLIB_INTERNAL _tr_align(s) bi_flush(s); } +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(deflate_state *s, const ct_data *ltree, + const ct_data *dtree) { + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in sym_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->sym_next != 0) do { + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); /* send length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= (unsigned)base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and sym_buf is ok: */ + Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); + + } while (sx < s->sym_next); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "block list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(deflate_state *s) { + /* block_mask is the bit mask of block-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long block_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("block-listed") bytes. */ + for (n = 0; n <= 31; n++, block_mask >>= 1) + if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("allow-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "block-listed" or "allow-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and write out the encoded block. */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ @@ -1011,11 +1081,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ -int ZLIB_INTERNAL _tr_tally(s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length - MIN_MATCH or unmatched char (dist==0) */ -{ +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; @@ -1035,147 +1101,3 @@ int ZLIB_INTERNAL _tr_tally(s, dist, lc) } return (s->sym_next == s->sym_end); } - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - const ct_data *ltree; /* literal tree */ - const ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->sym_next != 0) do { - dist = s->sym_buf[sx++] & 0xff; - dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; - lc = s->sym_buf[sx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS + 1, ltree); /* send length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s->sym_next); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long block_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>= 1) - if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("allow-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent + 7) & ~7; -#endif -} diff --git a/zlib/uncompr.c b/zlib/uncompr.c index f9532f46c1a..5e256663b45 100644 --- a/zlib/uncompr.c +++ b/zlib/uncompr.c @@ -24,12 +24,8 @@ Z_DATA_ERROR if the input data was corrupted, including if the input data is an incomplete zlib stream. */ -int ZEXPORT uncompress2(dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong *sourceLen; -{ +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong *sourceLen) { z_stream stream; int err; const uInt max = (uInt)-1; @@ -83,11 +79,7 @@ int ZEXPORT uncompress2(dest, destLen, source, sourceLen) err; } -int ZEXPORT uncompress(dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ +int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { return uncompress2(dest, destLen, source, &sourceLen); } diff --git a/zlib/win32/README-WIN32.txt b/zlib/win32/README-WIN32.txt index 050197d80f7..384c988fa84 100644 --- a/zlib/win32/README-WIN32.txt +++ b/zlib/win32/README-WIN32.txt @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.13 is a general purpose data compression library. All the code is +zlib 1.3.0 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) @@ -22,7 +22,7 @@ before asking for help. Manifest: -The package zlib-1.2.13-win32-x86.zip will contain the following files: +The package zlib-1.3.0-win32-x86.zip will contain the following files: README-WIN32.txt This document ChangeLog Changes since previous zlib packages diff --git a/zlib/zconf.h.cmakein b/zlib/zconf.h.cmakein index 247ba2461dd..310c43928a2 100644 --- a/zlib/zconf.h.cmakein +++ b/zlib/zconf.h.cmakein @@ -243,7 +243,11 @@ #endif #ifdef Z_SOLO - typedef unsigned long z_size_t; +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif #else # define z_longlong long long # if defined(NO_SIZE_T) @@ -522,7 +526,7 @@ typedef uLong FAR uLongf; #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# if defined(_WIN32) && !defined(__GNUC__) # define z_off64_t __int64 # else # define z_off64_t z_off_t diff --git a/zlib/zconf.h.in b/zlib/zconf.h.in index bf977d3e70a..fb76ffe312a 100644 --- a/zlib/zconf.h.in +++ b/zlib/zconf.h.in @@ -241,7 +241,11 @@ #endif #ifdef Z_SOLO - typedef unsigned long z_size_t; +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif #else # define z_longlong long long # if defined(NO_SIZE_T) @@ -520,7 +524,7 @@ typedef uLong FAR uLongf; #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# if defined(_WIN32) && !defined(__GNUC__) # define z_off64_t __int64 # else # define z_off64_t z_off_t diff --git a/zlib/zlib.3 b/zlib/zlib.3 index 6f6e91404df..4dd28967534 100644 --- a/zlib/zlib.3 +++ b/zlib/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "13 Oct 2022" +.TH ZLIB 3 "18 Aug 2023" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -105,9 +105,9 @@ before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). .SH AUTHORS AND LICENSE -Version 1.2.13 +Version 1.3 .LP -Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler +Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler .LP This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/zlib/zlib.h b/zlib/zlib.h index 429dfbb7659..da09785ed1d 100644 --- a/zlib/zlib.h +++ b/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.13, October 13th, 2022 + version 1.3, August 18th, 2023 - Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.13" -#define ZLIB_VERNUM 0x12d0 +#define ZLIB_VERSION "1.3" +#define ZLIB_VERNUM 0x1300 #define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 13 +#define ZLIB_VER_MINOR 3 +#define ZLIB_VER_REVISION 0 #define ZLIB_VER_SUBREVISION 0 /* @@ -78,8 +78,8 @@ extern "C" { even in the case of corrupted input. */ -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); +typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); +typedef void (*free_func)(voidpf opaque, voidpf address); struct internal_state; @@ -217,7 +217,7 @@ typedef gz_header FAR *gz_headerp; /* basic functions */ -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +ZEXTERN const char * ZEXPORT zlibVersion(void); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check @@ -225,12 +225,12 @@ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); */ /* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); +ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. + allocation functions. total_in, total_out, adler, and msg are initialized. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all @@ -247,7 +247,7 @@ ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); */ -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce @@ -320,8 +320,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. + avail_out is greater than six when the flush marker begins, in order to avoid + repeated flush markers upon calling deflate() again when avail_out == 0. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was @@ -360,7 +360,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); */ -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending @@ -375,7 +375,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateInit(z_streamp strm); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by @@ -383,7 +383,8 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); read or consumed. The allocation of a sliding window will be deferred to the first call of inflate (if the decompression does not complete on the first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. + them to use default allocation functions. total_in, total_out, adler, and + msg are initialized. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the @@ -397,7 +398,7 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); */ -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce @@ -517,7 +518,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); */ -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending @@ -535,12 +536,12 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); */ /* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); +ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); This is another version of deflateInit with more compression options. The fields zalloc, zfree and opaque must be initialized before by the caller. @@ -607,9 +608,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); +ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. When using the zlib format, this @@ -651,9 +652,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, not perform any compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); +ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); /* Returns the sliding dictionary being maintained by deflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied @@ -673,8 +674,8 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, stream state is inconsistent. */ -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); +ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, + z_streamp source); /* Sets the destination stream as a complete copy of the source stream. @@ -691,20 +692,20 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateReset(z_streamp strm); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate the internal compression state. The stream will leave the compression level and any other attributes that may have been - set unchanged. + set unchanged. total_in, total_out, adler, and msg are initialized. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); +ZEXTERN int ZEXPORT deflateParams(z_streamp strm, + int level, + int strategy); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2(). This can be @@ -729,7 +730,7 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, Then no more input data should be provided before the deflateParams() call. If this is done, the old level and strategy will be applied to the data compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). + applied to the data compressed after deflateParams(). deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if @@ -740,11 +741,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, retried with more output space. */ -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); +ZEXTERN int ZEXPORT deflateTune(z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain); /* Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for @@ -757,8 +758,8 @@ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, + uLong sourceLen); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or @@ -772,9 +773,9 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, than Z_FINISH or Z_NO_FLUSH are used. */ -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); +ZEXTERN int ZEXPORT deflatePending(z_streamp strm, + unsigned *pending, + int *bits); /* deflatePending() returns the number of bytes and bits of output that have been generated, but not yet provided in the available output. The bytes not @@ -787,9 +788,9 @@ ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); +ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, + int bits, + int value); /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits @@ -804,8 +805,8 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, source stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); +ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, + gz_headerp head); /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called @@ -821,16 +822,17 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gzip file" and give up. If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). + the time set to zero, and os set to the current operating system, with no + extra, name, or comment fields. The gzip header is returned to the default + state by deflateReset(). deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); +ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, + int windowBits); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized @@ -883,9 +885,9 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, deferred until inflate() is called. */ -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); +ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, @@ -906,9 +908,9 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflate(). */ -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); +ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); /* Returns the sliding dictionary being maintained by inflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied @@ -921,7 +923,7 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, stream state is inconsistent. */ -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateSync(z_streamp strm); /* Skips invalid compressed data until a possible full flush point (see above for the description of deflate with Z_FULL_FLUSH) can be found, or until all @@ -940,8 +942,8 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); input each time, until success or end of the input data. */ -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); +ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, + z_streamp source); /* Sets the destination stream as a complete copy of the source stream. @@ -956,18 +958,19 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateReset(z_streamp strm); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. + total_in, total_out, adler, and msg are initialized. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); +ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, + int windowBits); /* This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted @@ -980,9 +983,9 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, the windowBits parameter is invalid. */ -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); +ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, + int bits, + int value); /* This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the @@ -1001,7 +1004,7 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +ZEXTERN long ZEXPORT inflateMark(z_streamp strm); /* This function returns two values, one in the lower 16 bits of the return value, and the other in the remaining upper bits, obtained by shifting the @@ -1029,8 +1032,8 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); source stream state was inconsistent. */ -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); +ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, + gz_headerp head); /* inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after @@ -1070,8 +1073,8 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, */ /* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); +ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, + unsigned char FAR *window); Initialize the internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized @@ -1091,13 +1094,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, the version of the header file. */ -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); +typedef unsigned (*in_func)(void FAR *, + z_const unsigned char FAR * FAR *); +typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); +ZEXTERN int ZEXPORT inflateBack(z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc); /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is potentially more efficient than @@ -1165,7 +1168,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, cannot return Z_OK. */ -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); /* All memory allocated by inflateBackInit() is freed. @@ -1173,7 +1176,7 @@ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); state was inconsistent. */ -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +ZEXTERN uLong ZEXPORT zlibCompileFlags(void); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: @@ -1226,8 +1229,8 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); you need special options. */ -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size @@ -1241,9 +1244,9 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, buffer. */ -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte @@ -1257,15 +1260,15 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, Z_STREAM_ERROR if the level parameter is invalid. */ -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size @@ -1282,8 +1285,8 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, buffer with the uncompressed data up to that point. */ -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen); /* Same as uncompress, except that sourceLen is a pointer, where the length of the source is *sourceLen. On return, *sourceLen is the number of @@ -1302,7 +1305,7 @@ ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); Open the gzip (.gz) file at path for reading and decompressing, or compressing and writing. The mode parameter is as in fopen ("rb" or "wb") @@ -1339,7 +1342,7 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); file could not be opened. */ -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); /* Associate a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (if the file has @@ -1362,7 +1365,7 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); will not detect if fd is invalid (unless fd is -1). */ -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); /* Set the internal buffer size used by this library's functions for file to size. The default buffer size is 8192 bytes. This function must be called @@ -1378,7 +1381,7 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); too late. */ -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); /* Dynamically update the compression level and strategy for file. See the description of deflateInit2 for the meaning of these parameters. Previously @@ -1389,7 +1392,7 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); or Z_MEM_ERROR if there is a memory allocation error. */ -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); /* Read and decompress up to len uncompressed bytes from file into buf. If the input file is not in gzip format, gzread copies the given number of @@ -1419,8 +1422,8 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); Z_STREAM_ERROR. */ -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); +ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file); /* Read and decompress up to nitems items of size size from file into buf, otherwise operating as gzread() does. This duplicates the interface of @@ -1445,14 +1448,14 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, file, resetting and retrying on end-of-file, when size is not 1. */ -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); +ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); /* Compress and write the len uncompressed bytes at buf to file. gzwrite returns the number of uncompressed bytes written or 0 in case of error. */ -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); +ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, + z_size_t nitems, gzFile file); /* Compress and write nitems items of size size from buf to file, duplicating the interface of stdio's fwrite(), with size_t request and return types. If @@ -1465,7 +1468,7 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, is returned, and the error state is set to Z_STREAM_ERROR. */ -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); /* Convert, format, compress, and write the arguments (...) to file under control of the string format, as in fprintf. gzprintf returns the number of @@ -1480,7 +1483,7 @@ ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); This can be determined using zlibCompileFlags(). */ -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); /* Compress and write the given null-terminated string s to file, excluding the terminating null character. @@ -1488,7 +1491,7 @@ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); gzputs returns the number of characters written, or -1 in case of error. */ -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); /* Read and decompress bytes from file into buf, until len-1 characters are read, or until a newline character is read and transferred to buf, or an @@ -1502,13 +1505,13 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); buf are indeterminate. */ -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +ZEXTERN int ZEXPORT gzputc(gzFile file, int c); /* Compress and write c, converted to an unsigned char, into file. gzputc returns the value that was written, or -1 in case of error. */ -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +ZEXTERN int ZEXPORT gzgetc(gzFile file); /* Read and decompress one byte from file. gzgetc returns this byte or -1 in case of end of file or error. This is implemented as a macro for speed. @@ -1517,7 +1520,7 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); points to has been clobbered or not. */ -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); /* Push c back onto the stream for file to be read as the first character on the next read. At least one character of push-back is always allowed. @@ -1529,7 +1532,7 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); gzseek() or gzrewind(). */ -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); /* Flush all pending output to file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function @@ -1545,8 +1548,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); */ /* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); +ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, + z_off_t offset, int whence); Set the starting position to offset relative to whence for the next gzread or gzwrite on file. The offset represents a number of bytes in the @@ -1564,7 +1567,7 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, would be before the current position. */ -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +ZEXTERN int ZEXPORT gzrewind(gzFile file); /* Rewind file. This function is supported only for reading. @@ -1572,7 +1575,7 @@ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); */ /* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); Return the starting position for the next gzread or gzwrite on file. This position represents a number of bytes in the uncompressed data stream, @@ -1583,7 +1586,7 @@ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); */ /* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); +ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); Return the current compressed (actual) read or write offset of file. This offset includes the count of bytes that precede the gzip stream, for example @@ -1592,7 +1595,7 @@ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); be used for a progress indicator. On error, gzoffset() returns -1. */ -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +ZEXTERN int ZEXPORT gzeof(gzFile file); /* Return true (1) if the end-of-file indicator for file has been set while reading, false (0) otherwise. Note that the end-of-file indicator is set @@ -1607,7 +1610,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); has grown since the previous end of file was detected. */ -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +ZEXTERN int ZEXPORT gzdirect(gzFile file); /* Return true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed. @@ -1628,7 +1631,7 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); gzip file reading and decompression, which may not be desired.) */ -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose(gzFile file); /* Flush all pending output for file, if necessary, close file and deallocate the (de)compression state. Note that once file is closed, you @@ -1641,8 +1644,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); last read ended in the middle of a gzip stream, or Z_OK on success. */ -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_r(gzFile file); +ZEXTERN int ZEXPORT gzclose_w(gzFile file); /* Same as gzclose(), but gzclose_r() is only for use when reading, and gzclose_w() is only for use when writing or appending. The advantage to @@ -1653,7 +1656,7 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); zlib library. */ -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); /* Return the error message for the last error which occurred on file. errnum is set to zlib error number. If an error occurred in the file system @@ -1669,7 +1672,7 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); functions above that do not distinguish those cases in their return values. */ -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +ZEXTERN void ZEXPORT gzclearerr(gzFile file); /* Clear the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip @@ -1686,7 +1689,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); library. */ -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. An Adler-32 value is in the range of a 32-bit @@ -1706,15 +1709,15 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); if (adler != original_adler) error(); */ -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); +ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, + z_size_t len); /* Same as adler32(), but with a size_t length. */ /* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); +ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, + z_off_t len2); Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for @@ -1724,7 +1727,7 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, negative, the result has no meaning or utility. */ -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. @@ -1742,14 +1745,14 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ -ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf, - z_size_t len)); +ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, + z_size_t len); /* Same as crc32(), but with a size_t length. */ /* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); +ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were @@ -1759,13 +1762,13 @@ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); */ /* -ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2)); +ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with crc32_combine_op(). */ -ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op)); +ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); /* Give the same result as crc32_combine(), using op in place of len2. op is is generated from len2 by crc32_combine_gen(). This will be faster than @@ -1778,20 +1781,20 @@ ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op)); /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); +ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, + const char *version, int stream_size); +ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size); +ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size); #ifdef Z_PREFIX_SET # define z_deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) @@ -1836,7 +1839,7 @@ struct gzFile_s { unsigned char *next; z_off64_t pos; }; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ #ifdef Z_PREFIX_SET # undef z_gzgetc # define z_gzgetc(g) \ @@ -1853,13 +1856,13 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ * without large file support, _LFS64_LARGEFILE must also be true */ #ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); #endif #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) @@ -1881,50 +1884,50 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ # define crc32_combine_gen crc32_combine_gen64 # endif # ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); # endif #else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); + ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); #endif #else /* Z_SOLO */ - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); #endif /* !Z_SOLO */ /* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +ZEXTERN const char * ZEXPORT zError(int); +ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); +ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); +ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); +ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); +ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); #if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); +ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, + const char *mode); #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); +ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, + const char *format, + va_list va); # endif #endif diff --git a/zlib/zlib2ansi b/zlib/zlib2ansi deleted file mode 100755 index 23b2a1d5a3e..00000000000 --- a/zlib/zlib2ansi +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/perl - -# Transform K&R C function definitions into ANSI equivalent. -# -# Author: Paul Marquess -# Version: 1.0 -# Date: 3 October 2006 - -# TODO -# -# Assumes no function pointer parameters. unless they are typedefed. -# Assumes no literal strings that look like function definitions -# Assumes functions start at the beginning of a line - -use strict; -use warnings; - -local $/; -$_ = <>; - -my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments - -my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ; -my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ; -my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ; - - -while (s/^ - ( # Start $1 - ( # Start $2 - .*? # Minimal eat content - ( ^ \w [\w\s\*]+ ) # $3 -- function name - \s* # optional whitespace - ) # $2 - Matched up to before parameter list - - \( \s* # Literal "(" + optional whitespace - ( [^\)]+ ) # $4 - one or more anythings except ")" - \s* \) # optional whitespace surrounding a Literal ")" - - ( (?: $dList )+ ) # $5 - - $sp ^ { # literal "{" at start of line - ) # Remember to $1 - //xsom - ) -{ - my $all = $1 ; - my $prefix = $2; - my $param_list = $4 ; - my $params = $5; - - StripComments($params); - StripComments($param_list); - $param_list =~ s/^\s+//; - $param_list =~ s/\s+$//; - - my $i = 0 ; - my %pList = map { $_ => $i++ } - split /\s*,\s*/, $param_list; - my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ; - - my @params = split /\s*;\s*/, $params; - my @outParams = (); - foreach my $p (@params) - { - if ($p =~ /,/) - { - my @bits = split /\s*,\s*/, $p; - my $first = shift @bits; - $first =~ s/^\s*//; - push @outParams, $first; - $first =~ /^(\w+\s*)/; - my $type = $1 ; - push @outParams, map { $type . $_ } @bits; - } - else - { - $p =~ s/^\s+//; - push @outParams, $p; - } - } - - - my %tmp = map { /$pMatch/; $_ => $pList{$1} } - @outParams ; - - @outParams = map { " $_" } - sort { $tmp{$a} <=> $tmp{$b} } - @outParams ; - - print $prefix ; - print "(\n" . join(",\n", @outParams) . ")\n"; - print "{" ; - -} - -# Output any trailing code. -print ; -exit 0; - - -sub StripComments -{ - - no warnings; - - # Strip C & C++ comments - # From the perlfaq - $_[0] =~ - - s{ - /\* ## Start of /* ... */ comment - [^*]*\*+ ## Non-* followed by 1-or-more *'s - ( - [^/*][^*]*\*+ - )* ## 0-or-more things which don't start with / - ## but do end with '*' - / ## End of /* ... */ comment - - | ## OR C++ Comment - // ## Start of C++ comment // - [^\n]* ## followed by 0-or-more non end of line characters - - | ## OR various things which aren't comments: - - ( - " ## Start of " ... " string - ( - \\. ## Escaped char - | ## OR - [^"\\] ## Non "\ - )* - " ## End of " ... " string - - | ## OR - - ' ## Start of ' ... ' string - ( - \\. ## Escaped char - | ## OR - [^'\\] ## Non '\ - )* - ' ## End of ' ... ' string - - | ## OR - - . ## Anything other char - [^/"'\\]* ## Chars which doesn't start a comment, string or escape - ) - }{$2}gxs; - -} diff --git a/zlib/zutil.c b/zlib/zutil.c index 9543ae825e3..b1c5d2d3c6d 100644 --- a/zlib/zutil.c +++ b/zlib/zutil.c @@ -24,13 +24,11 @@ z_const char * const z_errmsg[10] = { }; -const char * ZEXPORT zlibVersion() -{ +const char * ZEXPORT zlibVersion(void) { return ZLIB_VERSION; } -uLong ZEXPORT zlibCompileFlags() -{ +uLong ZEXPORT zlibCompileFlags(void) { uLong flags; flags = 0; @@ -121,9 +119,7 @@ uLong ZEXPORT zlibCompileFlags() # endif int ZLIB_INTERNAL z_verbose = verbose; -void ZLIB_INTERNAL z_error(m) - char *m; -{ +void ZLIB_INTERNAL z_error(char *m) { fprintf(stderr, "%s\n", m); exit(1); } @@ -132,9 +128,7 @@ void ZLIB_INTERNAL z_error(m) /* exported to allow conversion of error code to string for compress() and * uncompress() */ -const char * ZEXPORT zError(err) - int err; -{ +const char * ZEXPORT zError(int err) { return ERR_MSG(err); } @@ -148,22 +142,14 @@ const char * ZEXPORT zError(err) #ifndef HAVE_MEMCPY -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ +void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ +int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { uInt j; for (j = 0; j < len; j++) { @@ -172,10 +158,7 @@ int ZLIB_INTERNAL zmemcmp(s1, s2, len) return 0; } -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ +void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ @@ -216,8 +199,7 @@ local ptr_table table[MAX_PTR]; * a protected system like OS/2. Use Microsoft C instead. */ -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { voidpf buf; ulg bsize = (ulg)items*size; @@ -242,8 +224,7 @@ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) return buf; } -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { int n; (void)opaque; @@ -279,14 +260,12 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) # define _hfree hfree #endif -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { (void)opaque; return _halloc((long)items, size); } -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; _hfree(ptr); } @@ -299,25 +278,18 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); +extern voidp malloc(uInt size); +extern voidp calloc(uInt items, uInt size); +extern void free(voidpf ptr); #endif -voidpf ZLIB_INTERNAL zcalloc(opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { (void)opaque; return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } -void ZLIB_INTERNAL zcfree(opaque, ptr) - voidpf opaque; - voidpf ptr; -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; free(ptr); } diff --git a/zlib/zutil.h b/zlib/zutil.h index 0bc7f4ecd1c..902a304cc2d 100644 --- a/zlib/zutil.h +++ b/zlib/zutil.h @@ -191,9 +191,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* provide prototypes for these when building zlib without LFS */ #if !defined(_WIN32) && \ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); #endif /* common defaults */ @@ -232,16 +232,16 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define zmemzero(dest, len) memset(dest, 0, len) # endif #else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); + void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); + int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); + void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); #endif /* Diagnostic functions */ #ifdef ZLIB_DEBUG # include extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); + extern void ZLIB_INTERNAL z_error(char *m); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} @@ -258,9 +258,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif #ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); + voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, + unsigned size); + void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); #endif #define ZALLOC(strm, items, size) \