1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge remote-tracking branch '11.3' into 11.4

This commit is contained in:
Sergei Golubchik
2023-12-21 15:40:55 +01:00
1327 changed files with 49062 additions and 15672 deletions

View File

@@ -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. If the changes are not amenable to automated testing, please explain why not and carefully describe how to test manually.
<!-- <!--
Tick one of the following boxes [x] to help us understand if the base branch for the PR is correct. (Currently the earliest maintained branch is 10.3) Tick one of the following boxes [x] to help us understand if the base branch for the PR is correct.
see [CODING_STANDARDS.md](https://github.com/MariaDB/server/blob/-/CODING_STANDARDS.md) for the latest versions.
--> -->
## Basing the PR against the correct MariaDB version ## Basing the PR against the correct MariaDB version
- [ ] *This is a new feature and the PR is based against the latest MariaDB development branch.* - [ ] *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. 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 ## 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. - [ ] For any trivial modifications to the PR, I am ok with the reviewer making the changes themselves.

View File

@@ -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. 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. 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 ```sh
git fetch upstream/10.3 # This assumes upstream is github.com/MariaDB/server git fetch upstream/10.11 # This assumes upstream is github.com/MariaDB/server
git rebase upstream/10.3 git rebase upstream/10.11
git push --force my_branch 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) ## Coding Style (C / C++ files)
Everyone has a preferred coding style, there is no real correct style for all projects around the world. Everyone has a preferred coding style, there is no real correct style for all projects around the world.

View File

@@ -1166,6 +1166,8 @@ static int install_used_plugin_data_types(void)
DYNAMIC_STRING ds_result; DYNAMIC_STRING ds_result;
const char *query = "SELECT table_comment FROM information_schema.tables" const char *query = "SELECT table_comment FROM information_schema.tables"
" WHERE table_comment LIKE 'Unknown data type: %'"; " WHERE table_comment LIKE 'Unknown data type: %'";
if (opt_systables_only)
return 0;
if (init_dynamic_string(&ds_result, "", 512, 512)) if (init_dynamic_string(&ds_result, "", 512, 512))
die("Out of memory"); die("Out of memory");
run_query(query, &ds_result, TRUE); run_query(query, &ds_result, TRUE);
@@ -1482,7 +1484,12 @@ int main(int argc, char **argv)
open_mysql_upgrade_file(); open_mysql_upgrade_file();
if (opt_check_upgrade) 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 mysqlcheck */
find_tool(mysqlcheck_path, IF_WIN("mariadb-check.exe", "mariadb-check"), self_name); find_tool(mysqlcheck_path, IF_WIN("mariadb-check.exe", "mariadb-check"), self_name);

View File

@@ -17,7 +17,7 @@
/* maintenance of mysql databases */ /* maintenance of mysql databases */
#define VER "9.1" #define VER "10.0"
#include "client_priv.h" #include "client_priv.h"
#include <signal.h> #include <signal.h>
#include <my_pthread.h> /* because of signal() */ #include <my_pthread.h> /* because of signal() */
@@ -36,12 +36,12 @@ char *host= NULL, *user= 0, *opt_password= 0,
*default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME;
ulonglong last_values[MAX_MYSQL_VAR+100]; ulonglong last_values[MAX_MYSQL_VAR+100];
static int interval=0; static int interval=0;
static my_bool option_force=0,interrupted=0,new_line=0, static my_bool option_force=0,interrupted=0,new_line=0, opt_compress= 0,
opt_compress= 0, opt_local= 0, opt_relative= 0, opt_verbose= 0, opt_local= 0, opt_relative= 0, tty_password= 0, opt_nobeep,
tty_password= 0, opt_nobeep, opt_shutdown_wait_for_slaves= 0; opt_shutdown_wait_for_slaves= 0, opt_not_used;
static my_bool debug_info_flag= 0, debug_check_flag= 0; 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 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 ulong opt_connect_timeout, opt_shutdown_timeout;
static char * unix_port=0; static char * unix_port=0;
static char *opt_plugin_dir= 0, *opt_default_auth= 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", 'u', "User for login if not current user.", &user,
&user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif #endif
{"verbose", 'v', "Write more information.", &opt_verbose, {"verbose", 'v', "Write more information."
&opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, "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, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0}, NO_ARG, 0, 0, 0, 0, 0, 0},
{"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_UINT, {"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 */ case 'I': /* Info */
usage(); usage();
exit(0); exit(0);
case 'v': /* --verbose */
opt_verbose++;
if (argument == disabled_my_option)
opt_verbose= 0;
break;
case OPT_CHARSETS_DIR: case OPT_CHARSETS_DIR:
#if MYSQL_VERSION_ID > 32300 #if MYSQL_VERSION_ID > 32300
charsets_dir = argument; charsets_dir = argument;
@@ -441,6 +448,7 @@ int main(int argc,char *argv[])
if (error > 0) if (error > 0)
break; break;
error= -error; /* don't exit with negative error codes */
/* /*
Command was well-formed, but failed on the server. Might succeed Command was well-formed, but failed on the server. Might succeed
on retry (if conditions on server change etc.), but needs --force 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_RES *result;
MYSQL_ROW row; MYSQL_ROW row;
const char *query;
if (mysql_query(mysql, (opt_verbose ? "show full processlist" : if (!opt_verbose)
"show processlist")) || query= "show processlist";
!(result = mysql_store_result(mysql))) 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, my_printf_error(0, "process list failed; error: '%s'", error_flags,
mysql_error(mysql)); mysql_error(mysql));
@@ -1129,24 +1144,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
else else
if (mysql_query(mysql,buff)) 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));
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);
}
ret = -1; ret = -1;
} }
password_done: password_done:

View File

@@ -3422,8 +3422,13 @@ int main(int argc, char** argv)
if (tmpdir.list) if (tmpdir.list)
free_tmpdir(&tmpdir); free_tmpdir(&tmpdir);
if (result_file && result_file != stdout) if (result_file)
my_fclose(result_file, MYF(0)); {
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. Ensure the GTID state is correct. If not, end in error.

View File

@@ -1912,8 +1912,13 @@ static FILE* open_sql_file_for_table(const char* table, int flags)
static void free_resources() static void free_resources()
{ {
if (md_result_file && md_result_file != stdout) if (md_result_file)
my_fclose(md_result_file, MYF(0)); {
if (md_result_file != stdout)
my_fclose(md_result_file, MYF(0));
else
fflush(md_result_file);
}
if (get_table_name_result) if (get_table_name_result)
mysql_free_result(get_table_name_result); mysql_free_result(get_table_name_result);
if (routine_res) if (routine_res)

View File

@@ -80,6 +80,9 @@ static my_bool non_blocking_api_enabled= 0;
#define DIE_BUFF_SIZE 256*1024 #define DIE_BUFF_SIZE 256*1024
#define RESULT_STRING_INIT_MEM 2048
#define RESULT_STRING_INCREMENT_MEM 2048
/* Flags controlling send and reap */ /* Flags controlling send and reap */
#define QUERY_SEND_FLAG 1 #define QUERY_SEND_FLAG 1
#define QUERY_REAP_FLAG 2 #define QUERY_REAP_FLAG 2
@@ -88,6 +91,8 @@ static my_bool non_blocking_api_enabled= 0;
#define CLOSED_CONNECTION "-closed_connection-" #define CLOSED_CONNECTION "-closed_connection-"
#define dynstr_append DO_NO_USE
#ifndef HAVE_SETENV #ifndef HAVE_SETENV
static int setenv(const char *name, const char *value, int overwrite); static int setenv(const char *name, const char *value, int overwrite);
#endif #endif
@@ -1730,7 +1735,7 @@ void log_msg(const char *fmt, ...)
va_end(args); va_end(args);
dynstr_append_mem(&ds_res, buff, len); dynstr_append_mem(&ds_res, buff, len);
dynstr_append(&ds_res, "\n"); dynstr_append_mem(&ds_res, STRING_WITH_LEN("\n"));
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@@ -1866,7 +1871,7 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...)
die("Out of memory"); die("Out of memory");
dynstr_append_os_quoted(&ds_cmdline, tool_path, NullS); 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); 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) if (strncmp(arg, "--", 2) == 0)
dynstr_append_os_quoted(&ds_cmdline, arg, NullS); dynstr_append_os_quoted(&ds_cmdline, arg, NullS);
else else
dynstr_append(&ds_cmdline, arg); dynstr_append_mem(&ds_cmdline, arg, strlen(arg));
dynstr_append(&ds_cmdline, " "); dynstr_append_mem(&ds_cmdline, STRING_WITH_LEN(" "));
} }
va_end(args); va_end(args);
#ifdef _WIN32 #ifdef _WIN32
dynstr_append(&ds_cmdline, "\""); dynstr_append_mem(&ds_cmdline, STRING_WITH_LEN("\""));
#endif #endif
DBUG_PRINT("info", ("Running: %s", ds_cmdline.str)); 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 Fallback to dump both files to result file and inform
about installing "diff" about installing "diff"
*/ */
dynstr_append(&ds_tmp, "\n"); char message[]=
dynstr_append(&ds_tmp, "\n"
"\n" "\n"
"The two files differ but it was not possible to execute 'diff' in\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" "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 #ifdef _WIN32
"or http://gnuwin32.sourceforge.net/packages/diffutils.htm\n" "or http://gnuwin32.sourceforge.net/packages/diffutils.htm\n"
#endif #endif
"\n"); "\n";
dynstr_append_mem(&ds_tmp, message, sizeof(message));
dynstr_append(&ds_tmp, " --- "); dynstr_append_mem(&ds_tmp, STRING_WITH_LEN(" --- "));
dynstr_append(&ds_tmp, filename1); dynstr_append_mem(&ds_tmp, filename1, strlen(filename1));
dynstr_append(&ds_tmp, " >>>\n"); dynstr_append_mem(&ds_tmp, STRING_WITH_LEN(" >>>\n"));
cat_file(&ds_tmp, filename1); cat_file(&ds_tmp, filename1);
dynstr_append(&ds_tmp, "<<<\n --- "); dynstr_append_mem(&ds_tmp, STRING_WITH_LEN("<<<\n --- "));
dynstr_append(&ds_tmp, filename1); dynstr_append_mem(&ds_tmp, filename1, strlen(filename1));
dynstr_append(&ds_tmp, " >>>\n"); dynstr_append_mem(&ds_tmp, STRING_WITH_LEN(" >>>\n"));
cat_file(&ds_tmp, filename2); cat_file(&ds_tmp, filename2);
dynstr_append(&ds_tmp, "<<<<\n"); dynstr_append_mem(&ds_tmp, STRING_WITH_LEN("<<<<\n"));
} }
if (ds) if (ds)
@@ -2819,9 +2825,9 @@ do_result_format_version(struct st_command *command)
set_result_format_version(version); 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_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); dynstr_free(&ds_version);
} }
@@ -3292,13 +3298,15 @@ static int replace(DYNAMIC_STRING *ds_str,
{ {
DYNAMIC_STRING ds_tmp; DYNAMIC_STRING ds_tmp;
const char *start= strstr(ds_str->str, search_str); const char *start= strstr(ds_str->str, search_str);
size_t prefixlen= start - ds_str->str;
if (!start) if (!start)
return 1; return 1;
init_dynamic_string(&ds_tmp, "", init_dynamic_string(&ds_tmp, "",
ds_str->length + replace_len, 256); 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_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_set(ds_str, ds_tmp.str);
dynstr_free(&ds_tmp); dynstr_free(&ds_tmp);
return 0; return 0;
@@ -3413,7 +3421,7 @@ void do_exec(struct st_command *command)
if (disable_result_log) if (disable_result_log)
{ {
/* Collect stderr output as well, for the case app. crashes or returns error.*/ /* 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'", DBUG_PRINT("info", ("Executing '%s' as '%s'",
@@ -3625,9 +3633,9 @@ void do_system(struct st_command *command)
else else
{ {
/* If ! abort_on_error, log message and continue */ /* 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); 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)) wild_compare(file->name, ds_wild.str, 0))
continue; continue;
ds_file_to_remove.length= directory_length; 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)); DBUG_PRINT("info", ("removing file: %s", ds_file_to_remove.str));
if ((error= (my_delete(ds_file_to_remove.str, MYF(MY_WME)) != 0))) if ((error= (my_delete(ds_file_to_remove.str, MYF(MY_WME)) != 0)))
sys_errno= my_errno; 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)) wild_compare(file->name, ds_wild->str, 0))
continue; continue;
replace_dynstr_append(ds, file->name); replace_dynstr_append(ds, file->name);
dynstr_append(ds, "\n"); dynstr_append_mem(ds, STRING_WITH_LEN("\n"));
} }
set_wild_chars(0); set_wild_chars(0);
my_dirend(dir_info); my_dirend(dir_info);
@@ -7703,7 +7711,7 @@ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field,
} }
else else
{ {
dynstr_append(ds, field->name); dynstr_append_mem(ds, field->name, strlen(field->name));
dynstr_append_mem(ds, "\t", 1); dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, len); replace_dynstr_append_mem(ds, val, len);
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
@@ -7814,9 +7822,10 @@ void append_metadata(DYNAMIC_STRING *ds,
uint num_fields) uint num_fields)
{ {
MYSQL_FIELD *field_end; MYSQL_FIELD *field_end;
dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t" dynstr_append_mem(ds, STRING_WITH_LEN(
"Column_alias\tType\tLength\tMax length\tIs_null\t" "Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
"Flags\tDecimals\tCharsetnr\n"); "Column_alias\tType\tLength\tMax length\tIs_null\t"
"Flags\tDecimals\tCharsetnr\n"));
for (field_end= field+num_fields ; for (field_end= field+num_fields ;
field < field_end ; field < field_end ;
@@ -7875,13 +7884,13 @@ void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows,
const char *info) const char *info)
{ {
char buf[40], buff2[21]; char buf[40], buff2[21];
sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2)); size_t len= sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2));
dynstr_append(ds, buf); dynstr_append_mem(ds, buf, len);
if (info) if (info)
{ {
dynstr_append(ds, "info: "); dynstr_append_mem(ds, STRING_WITH_LEN("info: "));
dynstr_append(ds, info); dynstr_append_mem(ds, info, strlen(info));
dynstr_append_mem(ds, "\n", 1); 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, (enum_session_state_type) type,
&data, &data_length)) &data, &data_length))
{ {
dynstr_append(ds, "-- "); dynstr_append_mem(ds, STRING_WITH_LEN("-- "));
if (type <= SESSION_TRACK_END) 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 else
{ {
DBUG_ASSERT(0); 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); dynstr_append_mem(ds, data, data_length);
} }
else else
@@ -7947,16 +7957,16 @@ static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql)
(enum_session_state_type) type, (enum_session_state_type) type,
&data, &data_length)) &data, &data_length))
{ {
dynstr_append(ds, "\n-- "); dynstr_append_mem(ds, STRING_WITH_LEN("\n-- "));
if (data == NULL) if (data == NULL)
{ {
DBUG_ASSERT(data_length == 0); DBUG_ASSERT(data_length == 0);
dynstr_append_mem(ds, "<NULL>", sizeof("<NULL>") - 1); dynstr_append_mem(ds, STRING_WITH_LEN("<NULL>"));
} }
else else
dynstr_append_mem(ds, data, data_length); dynstr_append_mem(ds, data, data_length);
} }
dynstr_append(ds, "\n\n"); dynstr_append_mem(ds, STRING_WITH_LEN("\n\n"));
} }
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
} }
@@ -8356,7 +8366,8 @@ void handle_error(struct st_command *command,
else if (command->expected_errors.err[0].type == ERR_SQLSTATE || else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
(command->expected_errors.err[0].type == ERR_ERRNO && (command->expected_errors.err[0].type == ERR_ERRNO &&
command->expected_errors.err[0].code.errnum != 0)) 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 */ /* OK */
revert_properties(); 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 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) DYNAMIC_STRING *ds_warnings)
{ {
my_bool ignore_second_execution= 0; my_bool ignore_second_execution= 0;
MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */
MYSQL *mysql= cn->mysql; MYSQL *mysql= cn->mysql;
MYSQL_STMT *stmt; MYSQL_STMT *stmt;
DYNAMIC_STRING ds_prepare_warnings; DYNAMIC_STRING ds_prepare_warnings;
DYNAMIC_STRING ds_execute_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_ENTER("run_query_stmt");
DBUG_PRINT("query", ("'%-.60s'", query)); DBUG_PRINT("query", ("'%-.60s'", query));
DBUG_PRINT("info", 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 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))) if (!(stmt= mysql_stmt_init(mysql)))
die("unable to init stmt structure"); 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); 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 Prepare the query
*/ */
@@ -8524,10 +8626,12 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command,
} }
#endif #endif
query_match_ps2_re = match_re(&ps2_re, query);
/* /*
Execute the query first time if second execution enable 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)) 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); mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
goto end; goto end;
} }
/* /*
We cannot run query twice if we get prepare warnings as these will otherwise be We cannot run query twice if we get prepare warnings as these will otherwise be
disabled disabled
*/ */
ignore_second_execution= (prepare_warnings_enabled && ignore_second_execution= (prepare_warnings_enabled &&
mysql_warning_count(mysql) != 0); 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; goto end;
} }
DBUG_ASSERT(ds->length == 0);
int err; int err;
do do
{ {
@@ -8563,75 +8689,82 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command,
if (cursor_protocol_enabled && !disable_warnings) if (cursor_protocol_enabled && !disable_warnings)
append_warnings(&ds_execute_warnings, mysql); append_warnings(&ds_execute_warnings, mysql);
/* if (!disable_result_log &&
We instruct that we want to update the "max_length" field in compare_2nd_execution &&
mysql_stmt_store_result(), this is our only way to know how much ps2_protocol_enabled &&
buffer to allocate for result data query_match_ps2_re &&
*/ display_result_sorted)
{ {
my_bool one= 1; init_dynamic_string(&ds_res_2_execution_unsorted, "",
if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one)) RESULT_STRING_INIT_MEM,
die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s", RESULT_STRING_INCREMENT_MEM);
mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); ds_res_2_output= &ds_res_2_execution_unsorted;
} }
else
ds_res_2_output= ds;
/* if (read_stmt_results(stmt, ds_res_2_output, command))
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), if (ds_res_2_output != ds)
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); {
goto end; 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) if (!disable_result_log)
{ {
/* /*
Not all statements creates a result set. If there is one we can The results of the first and second execution are compared
now create another normal result set that contains the meta only if result logging is enabled
data. This set can be handled almost like any other non prepared
statement result set.
*/ */
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 */ DYNAMIC_STRING *ds_res_1_execution_compare;
MYSQL_FIELD *fields= mysql_fetch_fields(res); DYNAMIC_STRING ds_res_1_execution_sorted;
uint num_fields= mysql_num_fields(res); if (display_result_sorted)
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)
{ {
DBUG_PRINT("info", ("warnings disabled")); init_dynamic_string(&ds_res_1_execution_sorted, "",
dynstr_set(&ds_prepare_warnings, NULL); 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
{ /*
/* Normally, if there is a result set, we do not show warnings from the
This is a query without resultset 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 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) if (display_session_track_info)
append_session_track_info(ds, mysql); append_session_track_info(ds, mysql);
if (!disable_warnings && !mysql_more_results(stmt->mysql)) if (!disable_warnings && !mysql_more_results(stmt->mysql))
{ {
/* Get the warnings from execute */ /* 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); mysql_sqlstate(mysql), ds);
else else
handle_no_error(command); handle_no_error(command);
end: end:
if (ds_res_1st_execution_init)
{
dynstr_free(&ds_res_1st_execution);
ds_res_1st_execution_init= FALSE;
}
if (!disable_warnings) if (!disable_warnings)
{ {
dynstr_free(&ds_prepare_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) void run_query(struct st_connection *cn, struct st_command *command, int flags)
{ {
MYSQL *mysql= cn->mysql; MYSQL *mysql= cn->mysql;
DYNAMIC_STRING *ds; DYNAMIC_STRING *rs_output; /* where to put results */
DYNAMIC_STRING *save_ds= NULL; DYNAMIC_STRING rs_cmp_result; /* here we put results to compare with
DYNAMIC_STRING ds_result; pre-recrded file */
DYNAMIC_STRING ds_sorted; DYNAMIC_STRING rs_unsorted; /* if we need sorted results, here we store
DYNAMIC_STRING ds_warnings; 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; char *query;
size_t query_len; size_t query_len;
my_bool view_created= 0, sp_created= 0; 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) if (!(flags & QUERY_SEND_FLAG) && !cn->pending)
die("Cannot reap on a connection without pending send"); die("Cannot reap on a connection without pending send");
init_dynamic_string(&ds_warnings, NULL, 0, 256); init_dynamic_string(&rs_warnings, NULL, 0, 256);
ds_warn= &ds_warnings; ds_warn= &rs_warnings;
/* /*
Evaluate query if this is an eval command 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) if (command->require_file)
{ {
init_dynamic_string(&ds_result, "", 1024, 1024); init_dynamic_string(&rs_cmp_result, "", 1024, 1024);
ds= &ds_result; rs_output= &rs_cmp_result;
} }
else else
ds= &ds_res; rs_output= &ds_res; // will be shown to colsole
/* /*
Log the query into the output buffer 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_query= command->query;
print_len= (int)(command->end - command->query); print_len= (int)(command->end - command->query);
} }
replace_dynstr_append_mem(ds, print_query, print_len); replace_dynstr_append_mem(rs_output, print_query, print_len);
dynstr_append_mem(ds, delimiter, delimiter_length); dynstr_append_mem(rs_output, delimiter, delimiter_length);
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(rs_output, "\n", 1);
} }
/* We're done with this flag */ /* 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 Collect warnings from create of the view that should otherwise
have been produced when the SELECT was executed have been produced when the SELECT was executed
*/ */
append_warnings(&ds_warnings, append_warnings(&rs_warnings,
service_connection_enabled ? service_connection_enabled ?
cur_con->util_mysql : cur_con->util_mysql :
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 that can be sorted before it's added to the
global result string global result string
*/ */
init_dynamic_string(&ds_sorted, "", 1024, 1024); init_dynamic_string(&rs_unsorted, "", 1024, 1024);
save_ds= ds; /* Remember original ds */ rs_sorted_save= rs_output; /* Remember original ds */
ds= &ds_sorted; 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. All other statements can be run using prepared statement C API.
*/ */
!match_re(&ps_re, query)) !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 else
run_query_normal(cn, command, flags, query, query_len, 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; ds_warn= 0;
if (display_result_sorted) if (display_result_sorted)
{ {
/* Sort the result set and append it to result */ /* Sort the result set and append it to result */
dynstr_append_sorted(save_ds, &ds_sorted, 1); dynstr_append_sorted(rs_sorted_save, &rs_unsorted, 1);
ds= save_ds; rs_output= rs_sorted_save;
dynstr_free(&ds_sorted); dynstr_free(&rs_unsorted);
} }
if (sp_created) 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 and the output should be checked against an already
existing file which has been specified using --require or --result 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) if (rs_output == &rs_cmp_result)
dynstr_free(&ds_result); dynstr_free(&rs_cmp_result);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@@ -9690,7 +9833,7 @@ void mark_progress(struct st_command* command __attribute__((unused)),
dynstr_append_mem(&ds_progress, "\t", 1); dynstr_append_mem(&ds_progress, "\t", 1);
/* Filename */ /* 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); dynstr_append_mem(&ds_progress, ":", 1);
/* Line in file */ /* 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)); 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)); init_alloc_root(PSI_NOT_INSTRUMENTED, &require_file_root, 1024, 1024, MYF(0));
parse_args(argc, argv); parse_args(argc, argv);
@@ -10316,7 +10459,7 @@ int main(int argc, char **argv)
if (p && *p == '#' && *(p+1) == '#') if (p && *p == '#' && *(p+1) == '#')
{ {
dynstr_append_mem(&ds_res, command->query, command->query_len); 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; break;
} }
@@ -10329,7 +10472,7 @@ int main(int argc, char **argv)
if (disable_query_log) if (disable_query_log)
break; break;
dynstr_append(&ds_res, "\n"); dynstr_append_mem(&ds_res, STRING_WITH_LEN("\n"));
break; break;
case Q_PING: case Q_PING:
handle_command_error(command, mysql_ping(cur_con->mysql), -1); 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++) for (i= 0; i < lines.elements ; i++)
{ {
const char **line= dynamic_element(&lines, i, const char**); const char **line= dynamic_element(&lines, i, const char**);
dynstr_append(ds, *line); dynstr_append_mem(ds, *line, strlen(*line));
dynstr_append(ds, "\n"); dynstr_append_mem(ds, STRING_WITH_LEN("\n"));
} }
delete_dynamic(&lines); delete_dynamic(&lines);

View File

@@ -90,7 +90,7 @@ IF(NOT CPACK_PACKAGE_FILE_NAME)
ENDIF() ENDIF()
SET_IF_UNSET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-${VERSION}") SET_IF_UNSET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-${VERSION}")
SET_IF_UNSET(CPACK_PACKAGE_CONTACT "MariaDB Developers <maria-developers@lists.launchpad.net>") SET_IF_UNSET(CPACK_PACKAGE_CONTACT "MariaDB Developers <developers@lists.mariadb.org>")
SET_IF_UNSET(CPACK_PACKAGE_VENDOR "MariaDB Foundation") SET_IF_UNSET(CPACK_PACKAGE_VENDOR "MariaDB Foundation")
SET_IF_UNSET(CPACK_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY} SET_IF_UNSET(CPACK_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}

View File

@@ -121,10 +121,6 @@ in
# there is intentionally no customizations whatsoever. # there is intentionally no customizations whatsoever.
;; ;;
# Ubuntu # Ubuntu
"bionic")
remove_rocksdb_tools
[ "$architecture" != amd64 ] && disable_pmem
;&
"focal") "focal")
replace_uring_with_aio replace_uring_with_aio
disable_libfmt disable_libfmt

2
debian/control vendored
View File

@@ -1,7 +1,7 @@
Source: mariadb Source: mariadb
Section: database Section: database
Priority: optional Priority: optional
Maintainer: MariaDB Developers <maria-developers@lists.launchpad.net> Maintainer: MariaDB Developers <developers@lists.mariadb.org>
Build-Depends: bison, Build-Depends: bison,
cmake, cmake,
cracklib-runtime <!nocheck>, cracklib-runtime <!nocheck>,

5
debian/copyright vendored
View File

@@ -2,12 +2,11 @@
== MariaDB == == MariaDB ==
The Debian package of MySQL was first debianzed on 1997-04-12 by Christian The Debian package of MySQL was first debianzed on 1997-04-12 by Christian
Schwarz <schwarz@debian.org> and ist maintained since 1999-04-20 by Schwarz <schwarz@debian.org> and is maintained since 1999-04-20 by
Christian Hammers <ch@debian.org>. Christian Hammers <ch@debian.org>.
The MariaDB packages were initially made by http://ourdelta.org/, and The MariaDB packages were initially made by http://ourdelta.org/, and
are now managed by the MariaDB development team, are now managed by the MariaDB development team, developers@lists.mariadb.org
maria-developers@lists.launchpad.net
MariaDB can be downloaded from https://downloads.mariadb.org/ MariaDB can be downloaded from https://downloads.mariadb.org/

View File

@@ -1,6 +1,7 @@
libmariadb.so.3 libmariadb3 #MINVER# libmariadb.so.3 libmariadb3 #MINVER#
* Build-Depends-Package: libmariadb-dev * Build-Depends-Package: libmariadb-dev
libmariadb_3@libmariadb_3 3.0.0 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 libmariadbclient_18@libmariadbclient_18 3.0.0
libmysqlclient_18@libmysqlclient_18 3.0.0 libmysqlclient_18@libmysqlclient_18 3.0.0
ma_pvio_register_callback@libmariadb_3 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_connection@libmariadb_3 3.0.0
mariadb_convert_string@libmariadb_3 3.0.0 mariadb_convert_string@libmariadb_3 3.0.0
mariadb_deinitialize_ssl@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_free_rpl_event@libmariadb_3 3.1.0
mariadb_get_charset_by_name@libmariadb_3 3.0.0 mariadb_get_charset_by_name@libmariadb_3 3.0.0
mariadb_get_charset_by_nr@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_get_infov@libmariadb_3 3.0.0
mariadb_reconnect@libmariadb_3 3.0.0 mariadb_reconnect@libmariadb_3 3.0.0
mariadb_rpl_close@libmariadb_3 3.1.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_fetch@libmariadb_3 3.1.0
mariadb_rpl_get_optionsv@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_open@libmariadb_3 3.1.0
mariadb_rpl_optionsv@libmariadb_3 3.1.0 mariadb_rpl_optionsv@libmariadb_3 3.1.0
mariadb_stmt_execute_direct@libmariadb_3 3.0.0 mariadb_stmt_execute_direct@libmariadb_3 3.0.0

View File

@@ -28,6 +28,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
#include <winioctl.h> #include <winioctl.h>
#endif #endif
#ifdef HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE
#include <linux/falloc.h>
#endif
typedef struct { typedef struct {
File fd; File fd;
my_bool init_ibd_done; 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) { if (datasize < n_bytes) {
/* This punches a "hole" in the file. */ /* This punches a "hole" in the file. */
size_t hole_bytes = n_bytes - datasize; size_t hole_bytes = n_bytes - datasize;
if (my_seek(fd, hole_bytes, MY_SEEK_CUR, MYF(MY_WME | MY_NABP)) my_off_t off = my_seek(fd, hole_bytes, MY_SEEK_CUR, MYF(MY_WME | MY_NABP));
== MY_FILEPOS_ERROR) if (off == MY_FILEPOS_ERROR)
return 1; 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; written += n_bytes;
ptr += n_bytes; ptr += n_bytes;

View File

@@ -127,7 +127,8 @@ int sd_notifyf() { return 0; }
int sys_var_init(); int sys_var_init();
/* === xtrabackup specific options === */ /* === 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; char *xtrabackup_target_dir= xtrabackup_real_target_dir;
static my_bool xtrabackup_version; static my_bool xtrabackup_version;
static my_bool verbose; static my_bool verbose;
@@ -410,6 +411,9 @@ uint opt_safe_slave_backup_timeout = 0;
const char *opt_history = NULL; 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 mariabackup_exe[FN_REFLEN];
char orig_argv1[FN_REFLEN]; char orig_argv1[FN_REFLEN];
@@ -1269,22 +1273,25 @@ struct my_option xb_client_options[]= {
{"compress", OPT_XTRA_COMPRESS, {"compress", OPT_XTRA_COMPRESS,
"Compress individual backup files using the " "Compress individual backup files using the "
"specified compression algorithm. Currently the only supported algorithm " "specified compression algorithm. It uses no longer maintained QuickLZ "
"is 'quicklz'. It is also the default algorithm, i.e. the one used when " "library hence this option was deprecated with MariaDB 10.1.31 and 10.2.13.",
"--compress is used without an argument.",
(G_PTR *) &xtrabackup_compress_alg, (G_PTR *) &xtrabackup_compress_alg, 0, (G_PTR *) &xtrabackup_compress_alg, (G_PTR *) &xtrabackup_compress_alg, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"compress-threads", OPT_XTRA_COMPRESS_THREADS, {"compress-threads", OPT_XTRA_COMPRESS_THREADS,
"Number of threads for parallel data compression. The default value is " "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,
(G_PTR *) &xtrabackup_compress_threads, 0, GET_UINT, REQUIRED_ARG, 1, 1, (G_PTR *) &xtrabackup_compress_threads, 0, GET_UINT, REQUIRED_ARG, 1, 1,
UINT_MAX, 0, 0, 0}, UINT_MAX, 0, 0, 0},
{"compress-chunk-size", OPT_XTRA_COMPRESS_CHUNK_SIZE, {"compress-chunk-size", OPT_XTRA_COMPRESS_CHUNK_SIZE,
"Size of working buffer(s) for compression threads in bytes. The default " "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,
(G_PTR *) &xtrabackup_compress_chunk_size, 0, GET_ULL, REQUIRED_ARG, (G_PTR *) &xtrabackup_compress_chunk_size, 0, GET_ULL, REQUIRED_ARG,
(1 << 16), 1024, ULONGLONG_MAX, 0, 0, 0}, (1 << 16), 1024, ULONGLONG_MAX, 0, 0, 0},
@@ -1405,7 +1412,9 @@ struct my_option xb_client_options[]= {
{"decompress", OPT_DECOMPRESS, {"decompress", OPT_DECOMPRESS,
"Decompresses all files with the .qp " "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, (uchar *) &opt_decompress, (uchar *) &opt_decompress, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0}, 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, "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}, &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, {"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, "Percentage of dirty pages allowed in bufferpool.",
(G_PTR*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, (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, {"innodb_use_native_aio", OPT_INNODB_USE_NATIVE_AIO,
"Use native AIO if supported on this platform.", "Use native AIO if supported on this platform.",
(G_PTR*) &srv_use_native_aio, (G_PTR*) &srv_use_native_aio,
@@ -1886,7 +1898,7 @@ static int prepare_export()
IF_WIN("\"","") "\"%s\" --mysqld \"%s\"" IF_WIN("\"","") "\"%s\" --mysqld \"%s\""
" --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
" --innodb --innodb-fast-shutdown=0 --loose-partition" " --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< " " --console --skip-log-error --skip-log-bin --bootstrap %s< "
BOOTSTRAP_FILENAME IF_WIN("\"",""), BOOTSTRAP_FILENAME IF_WIN("\"",""),
mariabackup_exe, mariabackup_exe,
@@ -1900,7 +1912,7 @@ static int prepare_export()
IF_WIN("\"","") "\"%s\" --mysqld" IF_WIN("\"","") "\"%s\" --mysqld"
" --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
" --innodb --innodb-fast-shutdown=0 --loose-partition" " --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< " " --console --log-error= --skip-log-bin --bootstrap %s< "
BOOTSTRAP_FILENAME IF_WIN("\"",""), BOOTSTRAP_FILENAME IF_WIN("\"",""),
mariabackup_exe, mariabackup_exe,
@@ -2448,6 +2460,7 @@ xtrabackup_read_metadata(char *filename)
{ {
FILE *fp; FILE *fp;
my_bool r = TRUE; my_bool r = TRUE;
int t;
fp = fopen(filename,"r"); fp = fopen(filename,"r");
if(!fp) { if(!fp) {
@@ -2478,6 +2491,9 @@ xtrabackup_read_metadata(char *filename)
} }
/* Optional fields */ /* Optional fields */
if (fscanf(fp, "recover_binlog_info = %d\n", &t) == 1) {
recover_binlog_info = (t == 1);
}
end: end:
fclose(fp); fclose(fp);
@@ -2527,11 +2543,13 @@ xtrabackup_print_metadata(char *buf, size_t buf_len)
"backup_type = %s\n" "backup_type = %s\n"
"from_lsn = " UINT64PF "\n" "from_lsn = " UINT64PF "\n"
"to_lsn = " UINT64PF "\n" "to_lsn = " UINT64PF "\n"
"last_lsn = " UINT64PF "\n", "last_lsn = " UINT64PF "\n"
"recover_binlog_info = %d\n",
metadata_type, metadata_type,
metadata_from_lsn, metadata_from_lsn,
metadata_to_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; 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 /** Implement --prepare
@return whether the operation succeeded */ @return whether the operation succeeded */
static bool xtrabackup_prepare_func(char** argv) static bool xtrabackup_prepare_func(char** argv)
@@ -6151,6 +6189,20 @@ error:
msg("Last binlog file %s, position %lld", msg("Last binlog file %s, position %lld",
trx_sys.recovered_binlog_filename, trx_sys.recovered_binlog_filename,
longlong(trx_sys.recovered_binlog_offset)); 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. */ /* Check whether the log is applied enough or not. */
@@ -6352,7 +6404,7 @@ static bool check_all_privileges()
} }
/* KILL ... */ /* 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( check_result |= check_privilege(
granted_privileges, granted_privileges,
"CONNECTION ADMIN", "*", "*", "CONNECTION ADMIN", "*", "*",
@@ -6373,7 +6425,7 @@ static bool check_all_privileges()
if (opt_galera_info || opt_slave_info if (opt_galera_info || opt_slave_info
|| opt_safe_slave_backup) { || opt_safe_slave_backup) {
check_result |= check_privilege(granted_privileges, check_result |= check_privilege(granted_privileges,
"SLAVE MONITOR", "*", "*", "REPLICA MONITOR", "*", "*",
PRIVILEGE_WARNING); PRIVILEGE_WARNING);
} }
@@ -6586,9 +6638,10 @@ void handle_options(int argc, char **argv, char ***argv_server,
server_default_groups.push_back(NULL); server_default_groups.push_back(NULL);
snprintf(conf_file, sizeof(conf_file), "my"); snprintf(conf_file, sizeof(conf_file), "my");
if (prepare && target_dir) { if (prepare) {
snprintf(conf_file, sizeof(conf_file), 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)) { if (!strncmp(argv[1], "--defaults-file=", 16)) {
/* Remove defaults-file*/ /* Remove defaults-file*/
for (int i = 2; ; i++) { for (int i = 2; ; i++) {

View File

@@ -171,7 +171,7 @@ extern uint opt_safe_slave_backup_timeout;
extern const char *opt_history; 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}; BINLOG_INFO_AUTO};
extern ulong opt_binlog_info; extern ulong opt_binlog_info;

View File

@@ -170,6 +170,7 @@ int main(int argc, char **argv)
if ((error= load_defaults(config_file, (const char **) load_default_groups, if ((error= load_defaults(config_file, (const char **) load_default_groups,
&count, &arguments))) &count, &arguments)))
{ {
my_free(load_default_groups);
my_end(0); my_end(0);
if (error == 4) if (error == 4)
return 0; return 0;

View File

@@ -83,7 +83,7 @@ static inline ulonglong uint6korr(const void *p)
#define HAVE_mi_uint5korr #define HAVE_mi_uint5korr
#define HAVE_mi_uint6korr #define HAVE_mi_uint6korr
#define HAVE_mi_uint7korr #define HAVE_mi_uint7korr
#define HAVE_mi_uint78orr #define HAVE_mi_uint8korr
/* Read numbers stored in high-bytes-first order */ /* Read numbers stored in high-bytes-first order */

View File

@@ -448,7 +448,8 @@ enum my_lex_states
MY_LEX_IDENT_OR_KEYWORD, MY_LEX_IDENT_OR_KEYWORD,
MY_LEX_IDENT_OR_HEX, MY_LEX_IDENT_OR_BIN, MY_LEX_IDENT_OR_NCHAR, 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_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; 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" #include "t_ctype.h"
#endif #endif
int my_wc_mb_utf8mb4_bmp_only(CHARSET_INFO *cs, my_wc_t wc, uchar *r,
uchar *e);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -25,6 +25,8 @@
#define ALLOC_MAX_BLOCK_TO_DROP 4096 #define ALLOC_MAX_BLOCK_TO_DROP 4096
#define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10 #define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10
#define ROOT_FLAG_READ_ONLY 4
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -53,10 +55,6 @@ typedef struct st_mem_root
unsigned short first_block_usage; unsigned short first_block_usage;
unsigned short flags; unsigned short flags;
#ifdef PROTECT_STATEMENT_MEMROOT
int read_only;
#endif
void (*error_handler)(void); void (*error_handler)(void);
PSI_memory_key psi_key; PSI_memory_key psi_key;

View File

@@ -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) \ #define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \
set_rec_bits(0, 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, extern int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a,
const uchar *b, uint key_length, uint nextflag, const uchar *b, uint key_length, uint nextflag,
uint *diff_pos); uint *diff_pos);

View File

@@ -666,15 +666,19 @@ extern void my_mutex_end(void);
We need to have at least 256K stack to handle calls to myisamchk_init() We need to have at least 256K stack to handle calls to myisamchk_init()
with the current number of keys and key parts. with the current number of keys and key parts.
*/ */
#if defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN) # if defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN)
#ifndef DBUG_OFF /*
#define DEFAULT_THREAD_STACK (1024*1024L) Optimized WITH_ASAN=ON executables produced
#else by GCC 12.3.0, GCC 13.2.0, or clang 16.0.6
#define DEFAULT_THREAD_STACK (383*1024L) /* 392192 */ would fail ./mtr main.1st when the stack size is 5 MiB.
#endif The minimum is more than 6 MiB for CMAKE_BUILD_TYPE=RelWithDebInfo and
#else more than 8 MiB for CMAKE_BUILD_TYPE=Debug.
#define DEFAULT_THREAD_STACK (292*1024L) /* 299008 */ Let us add some safety margin.
#endif */
# define DEFAULT_THREAD_STACK (10L<<20)
# else
# define DEFAULT_THREAD_STACK (292*1024L) /* 299008 */
# endif
#endif #endif
#define MY_PTHREAD_LOCK_READ 0 #define MY_PTHREAD_LOCK_READ 0

View File

@@ -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 *alloc_root(MEM_ROOT *mem_root, size_t Size);
extern void *multi_alloc_root(MEM_ROOT *mem_root, ...); extern void *multi_alloc_root(MEM_ROOT *mem_root, ...);
extern void free_root(MEM_ROOT *root, myf MyFLAGS); 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 set_prealloc_root(MEM_ROOT *root, char *ptr);
extern void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, extern void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
size_t prealloc_size); size_t prealloc_size);

View File

@@ -112,6 +112,7 @@ typedef struct st_handler_check_param
uint progress_counter; /* How often to call _report_progress() */ uint progress_counter; /* How often to call _report_progress() */
ulonglong progress, max_progress; ulonglong progress, max_progress;
void (*init_fix_record)(void *);
int (*fix_record)(struct st_myisam_info *info, uchar *record, int keynum); int (*fix_record)(struct st_myisam_info *info, uchar *record, int keynum);
mysql_mutex_t print_msg_mutex; mysql_mutex_t print_msg_mutex;

View File

@@ -268,7 +268,6 @@ typedef struct st_mysql
char *host,*user,*passwd,*unix_socket,*server_version,*host_info; char *host,*user,*passwd,*unix_socket,*server_version,*host_info;
char *info, *db; char *info, *db;
const struct charset_info_st *charset; const struct charset_info_st *charset;
MYSQL_FIELD *fields;
MEM_ROOT field_alloc; MEM_ROOT field_alloc;
my_ulonglong affected_rows; my_ulonglong affected_rows;
my_ulonglong insert_id; /* id if insert on table with NEXTNR */ my_ulonglong insert_id; /* id if insert on table with NEXTNR */
@@ -290,7 +289,8 @@ typedef struct st_mysql
/* session-wide random string */ /* session-wide random string */
char scramble[SCRAMBLE_LENGTH+1]; char scramble[SCRAMBLE_LENGTH+1];
my_bool auto_local_infile; my_bool auto_local_infile;
void *unused2, *unused3, *unused4, *unused5; void *unused2, *unused3, *unused4;
MYSQL_FIELD *fields;
LIST *stmts; /* list of all statements */ LIST *stmts; /* list of all statements */
const struct st_mysql_methods *methods; const struct st_mysql_methods *methods;

View File

@@ -121,5 +121,3 @@ MYSQL *mysql_real_connect_local(MYSQL *mysql);
#endif #endif
#endif /*MYSQL_SERVICE_SQL */ #endif /*MYSQL_SERVICE_SQL */

View File

@@ -51,6 +51,7 @@ ENDIF()
SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
libmysql.c ../sql-common/errmsg.c libmysql.c ../sql-common/errmsg.c
../sql-common/client.c ../sql-common/client.c
../sql/cset_narrowing.cc
../sql-common/my_user.c ../sql-common/pack.c ../sql-common/my_user.c ../sql-common/pack.c
../sql-common/client_plugin.c ../sql-common/client_plugin.c
../sql/password.c ../sql/discover.cc ../sql/derror.cc ../sql/password.c ../sql/discover.cc ../sql/derror.cc

View File

@@ -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 */; return mysql_errno(mysql) ? (int)packet_error : 1 /* length of the OK packet */;
} }
static void emb_on_close_free(MYSQL *mysql) static void emb_on_close_free(MYSQL *mysql)
{ {
my_free(mysql->info_buffer); my_free(mysql->info_buffer);
@@ -470,6 +471,7 @@ static void emb_on_close_free(MYSQL *mysql)
} }
} }
MYSQL_METHODS embedded_methods= MYSQL_METHODS embedded_methods=
{ {
emb_read_query_result, emb_read_query_result,
@@ -705,8 +707,7 @@ void *create_embedded_thd(ulong client_flag)
if (thd->variables.max_join_size == HA_POS_ERROR) if (thd->variables.max_join_size == HA_POS_ERROR)
thd->variables.option_bits |= OPTION_BIG_SELECTS; thd->variables.option_bits |= OPTION_BIG_SELECTS;
thd->proc_info=0; // Remove 'login' thd->mark_connection_idle();
thd->set_command(COM_SLEEP);
thd->set_time(); thd->set_time();
thd->init_for_queries(); thd->init_for_queries();
thd->client_capabilities= client_flag | MARIADB_CLIENT_EXTENDED_METADATA; 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; return 0;
} }

View File

@@ -34,7 +34,7 @@ CHECK TABLE
to check tables within the tablespace\&. to check tables within the tablespace\&.
.PP .PP
If checksum mismatches are found, you would normally restore the tablespace from backup or start the server and attempt to use 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\&. to make a backup of the tables within the tablespace\&.
.PP .PP
Invoke Invoke
@@ -75,9 +75,9 @@ Displays help and exits\&.
.sp -1 .sp -1
.IP \(bu 2.3 .IP \(bu 2.3
.\} .\}
\fB\-c, --count\fR \fB\-a \fR\fB\fInum\fB, --allow-mismatches=#\fR
.sp .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 .RE
.sp .sp
.RS 4 .RS 4
@@ -88,9 +88,9 @@ Print a count of the number of pages in the file\&.
.sp -1 .sp -1
.IP \(bu 2.3 .IP \(bu 2.3
.\} .\}
\fB\-d, --debug\fR \fB\-c, --count\fR
.sp .sp
Debug mode; prints checksums for each page\&. Print a count of the number of pages in the file\&.
.RE .RE
.sp .sp
.RS 4 .RS 4
@@ -140,7 +140,7 @@ Synonym for \fB--help\fR\&.
.sp -1 .sp -1
.IP \(bu 2.3 .IP \(bu 2.3
.\} .\}
\fB\-l, --leaf\fR \fB\-f, --leaf\fR
.sp .sp
Examine leaf index pages\&. Examine leaf index pages\&.
.RE .RE
@@ -153,6 +153,19 @@ Examine leaf index pages\&.
.sp -1 .sp -1
.IP \(bu 2.3 .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 \fB\-m \fR\fB\fInum\fB, --merge=#\fR\fR
.sp .sp
Leaf page count if merge given number of consecutive pages\&. 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 .sp -1
.IP \(bu 2.3 .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 \fB\-p \fR\fB\fInum\fB, --page-num=#\fR\fR
.sp .sp
Check only this page number\&. Check only this page number\&.
@@ -179,6 +205,32 @@ Check only this page number\&.
.sp -1 .sp -1
.IP \(bu 2.3 .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 \fB\-s \fR\fB\fInum\fB, --start-page\fR\fR
.sp .sp
Start at this page number\&. Start at this page number\&.
@@ -205,6 +257,32 @@ Skip corrupt pages\&.
.sp -1 .sp -1
.IP \(bu 2.3 .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 \fB\-v, --verbose\fR
.sp .sp
Verbose mode; print a progress indicator every five seconds\&. Verbose mode; print a progress indicator every five seconds\&.
@@ -225,7 +303,7 @@ Displays version information and exits\&.
.SH "COPYRIGHT" .SH "COPYRIGHT"
.br .br
.PP .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 .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. 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 .PP

View File

@@ -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. the bug is corrected in future releases.
If you want to submit your test case you can send it 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 to developers@lists.mariadb.org or attach it to a bug report on
https://mariadb.org/jira/. http://mariadb.org/jira/.
If the test case is really big or if it contains 'not public' data, 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, then put your .test file and .result file(s) into a tar.gz archive,

View File

@@ -58,11 +58,6 @@ DROP TABLE t1;
# CHAR # 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( EXECUTE IMMEDIATE REPLACE(
'CREATE TABLE t1 ( ' 'CREATE TABLE t1 ( '
' a CHAR(20) COLLATE <COLLATION>,' ' a CHAR(20) COLLATE <COLLATION>,'
@@ -72,7 +67,6 @@ SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('ss '); INSERT INTO t1 VALUES ('ss ');
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/; INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
DROP TABLE t1; DROP TABLE t1;
}
EXECUTE IMMEDIATE REPLACE( EXECUTE IMMEDIATE REPLACE(
'CREATE TABLE t1 ( ' 'CREATE TABLE t1 ( '

View File

@@ -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;

View File

@@ -1,7 +1,7 @@
# Remove anonymous users added by add_anonymous_users.inc # Remove anonymous users added by add_anonymous_users.inc
disable_warnings; disable_warnings;
disable_query_log; disable_query_log;
DELETE FROM mysql.user where host='localhost' and user=''; DELETE FROM mysql.global_priv where host='localhost' and user='';
FLUSH PRIVILEGES; FLUSH PRIVILEGES;
enable_query_log; enable_query_log;
enable_warnings; enable_warnings;

View File

@@ -1,6 +1,8 @@
SET SESSION character_set_connection=latin2; SET SESSION character_set_connection=latin2;
SET SESSION character_set_client=cp1250; SET SESSION character_set_client=cp1250;
--disable_service_connection
--echo # --echo #
--echo # Test litteral --echo # Test litteral
--echo # --echo #
@@ -129,3 +131,5 @@ EXPLAIN EXTENDED SELECT '';
EXPLAIN EXTENDED SELECT _latin1''; EXPLAIN EXTENDED SELECT _latin1'';
EXPLAIN EXTENDED SELECT N''; EXPLAIN EXTENDED SELECT N'';
EXPLAIN EXTENDED SELECT '' ''; EXPLAIN EXTENDED SELECT '' '';
--enable_service_connection

View File

@@ -310,6 +310,19 @@ INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19),
--source include/explain_utils.inc --source include/explain_utils.inc
DROP TABLE t1; 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 --echo #31
CREATE TABLE t1 (i INT); CREATE TABLE t1 (i INT);
INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19),

View File

@@ -162,7 +162,7 @@ INSERT INTO t1 VALUES
--echo --echo
--echo # Execute select with invalid timestamp, desc ordering --echo # Execute select with invalid timestamp, desc ordering
SELECT * SELECT *
FROM t1 FROM t1 FORCE INDEX(PRIMARY)
WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
ORDER BY ts DESC ORDER BY ts DESC
LIMIT 2; LIMIT 2;
@@ -171,7 +171,7 @@ LIMIT 2;
--echo # Should use index condition --echo # Should use index condition
EXPLAIN EXPLAIN
SELECT * SELECT *
FROM t1 FROM t1 FORCE INDEX(PRIMARY)
WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
ORDER BY ts DESC ORDER BY ts DESC
LIMIT 2; LIMIT 2;
@@ -458,6 +458,7 @@ INSERT INTO t2 VALUES (11,1);
INSERT INTO t2 VALUES (12,2); INSERT INTO t2 VALUES (12,2);
INSERT INTO t2 VALUES (15,4); INSERT INTO t2 VALUES (15,4);
analyze table t1,t2 persistent for all;
set @save_optimizer_switch= @@optimizer_switch; set @save_optimizer_switch= @@optimizer_switch;
set optimizer_switch='semijoin=off'; set optimizer_switch='semijoin=off';
@@ -729,6 +730,7 @@ INSERT INTO t2 VALUES
('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w'); ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w');
insert into t2 select seq from seq_1_to_100; 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'; SET SESSION optimizer_switch='index_condition_pushdown=off';
--replace_column 9 # --replace_column 9 #
EXPLAIN EXPLAIN

View File

@@ -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)
#

View File

@@ -0,0 +1 @@
--innodb_stats_auto_recalc=0

View File

@@ -11,6 +11,7 @@
connection default; connection default;
let $default_db=`select database()`; let $default_db=`select database()`;
let $MYSQLD_DATADIR= `SELECT @@datadir`; 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 #it will used at end of test for wait_for_status_var.inc primitive
#let $status_var= Threads_connected; #let $status_var= Threads_connected;
@@ -23,6 +24,7 @@ wait-maria_empty_logs.inc
EOF EOF
--source include/mysqladmin_shutdown.inc --source include/mysqladmin_shutdown.inc
--source include/wait_until_no_pidfile.inc
--disable_warnings --disable_warnings
if (!$mel_keep_control_file) if (!$mel_keep_control_file)

View File

@@ -59,7 +59,7 @@ let $_wfsie_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
if ($slave_io_errno == '') { if ($slave_io_errno == '') {
--echo !!!ERROR IN TEST: you must set \$slave_io_errno before you source --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 !!!so you probably want to add the following line to your test case:
--echo !!! --let \$slave_io_errno= $_wfsie_errno --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 --die !!!ERROR IN TEST: you must set \$slave_io_errno before sourcing wait_for_slave_io_error.inc

View File

@@ -21,6 +21,17 @@
# $slave_timeout # $slave_timeout
# See include/wait_for_slave_param.inc. # 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 # $rpl_debug
# See include/rpl_init.inc # See include/rpl_init.inc
@@ -31,9 +42,15 @@
--let $slave_param= Slave_IO_Running --let $slave_param= Slave_IO_Running
--let $slave_param_value= No --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 --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 --let $include_filename= wait_for_slave_io_to_stop.inc

View File

@@ -35,7 +35,7 @@
# $slave_error_param # $slave_error_param
# If set, this script will check if the column of the output from # 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, # 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. # to Last_IO_Errno or Last_SQL_Errno.
# #
# $rpl_debug # $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; let $_slave_param_comparison= $slave_param_comparison;
if (!$_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) --let $_show_slave_status_value= query_get_value("SHOW SLAVE STATUS", $slave_param, 1)
# Check if an error condition is reached. # 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) --let $_show_slave_status_error_value= query_get_value("SHOW SLAVE STATUS", $slave_error_param, 1)
if ($_show_slave_status_error_value) if ($_show_slave_status_error_value)

View File

@@ -21,6 +21,14 @@
# $slave_timeout # $slave_timeout
# See include/wait_for_slave_param.inc # 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 # $rpl_debug
# See include/rpl_init.inc # See include/rpl_init.inc
@@ -31,7 +39,10 @@
--let $slave_param= Slave_SQL_Running --let $slave_param= Slave_SQL_Running
--let $slave_param_value= No --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 --source include/wait_for_slave_param.inc
--let $slave_error_param= --let $slave_error_param=

View File

@@ -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

View File

@@ -154,7 +154,17 @@ sub collect_test_cases ($$$$) {
{ {
push (@$cases, @this_case); 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"); mtr_error("Could not find '$tname' in '$sname' suite");
} }
@@ -614,7 +624,7 @@ sub make_combinations($$@)
{ {
my ($test, $test_combs, @combinations) = @_; my ($test, $test_combs, @combinations) = @_;
return ($test) if $test->{'skip'} or not @combinations; return ($test) unless @combinations;
if ($combinations[0]->{skip}) { if ($combinations[0]->{skip}) {
$test->{skip} = 1; $test->{skip} = 1;
$test->{comment} = $combinations[0]->{skip} unless $test->{comment}; $test->{comment} = $combinations[0]->{skip} unless $test->{comment};
@@ -647,6 +657,8 @@ sub make_combinations($$@)
} }
} }
return ($test) if $test->{'skip'};
my @cases; my @cases;
foreach my $comb (@combinations) foreach my $comb (@combinations)
{ {

View File

@@ -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 titlebar_stat($) {
sub time_format($) { sub time_format($) {
@@ -116,10 +140,10 @@ sub _mtr_report_test_name ($) {
return unless defined $verbose; return unless defined $verbose;
print _name(). _timestamp(); print_out _name(). _timestamp();
printf "%-40s ", $tname; print_out (sprintf "%-40s ", $tname);
my $worker = $tinfo->{worker}; my $worker = $tinfo->{worker};
print "w$worker " if defined $worker; print_out "w$worker " if defined $worker;
return $tname; return $tname;
} }
@@ -661,14 +685,14 @@ sub mtr_report (@) {
{ {
my @s = split /\[ (\S+) \]/, _name() . "@_\n"; my @s = split /\[ (\S+) \]/, _name() . "@_\n";
if (@s > 1) { if (@s > 1) {
print $s[0]; print_out $s[0];
&$set_color($s[1]); &$set_color($s[1]);
print "[ $s[1] ]"; print_out "[ $s[1] ]";
&$set_color('reset'); &$set_color('reset');
print $s[2]; print_out $s[2];
titlebar_stat($s[1]) if $set_titlebar; titlebar_stat($s[1]) if $set_titlebar;
} else { } else {
print $s[0]; print_out $s[0];
} }
} }
} }
@@ -676,6 +700,7 @@ sub mtr_report (@) {
# Print warning to screen # Print warning to screen
sub mtr_warning (@) { sub mtr_warning (@) {
flush_out();
print STDERR _name(). _timestamp(). print STDERR _name(). _timestamp().
"mysql-test-run: WARNING: ". join(" ", @_). "\n"; "mysql-test-run: WARNING: ". join(" ", @_). "\n";
} }
@@ -683,7 +708,7 @@ sub mtr_warning (@) {
# Print error to screen and then exit # Print error to screen and then exit
sub mtr_error (@) { sub mtr_error (@) {
IO::Handle::flush(\*STDOUT) if IS_WINDOWS; flush_out();
print STDERR _name(). _timestamp(). print STDERR _name(). _timestamp().
"mysql-test-run: *** ERROR: ". join(" ", @_). "\n"; "mysql-test-run: *** ERROR: ". join(" ", @_). "\n";
if (IS_WINDOWS) if (IS_WINDOWS)

View File

@@ -1,5 +1,3 @@
#remove this include after fix MDEV-27871
--source include/no_view_protocol.inc
--disable_warnings --disable_warnings
DROP TABLE IF EXISTS t1; 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 # in Item::print_item_w_name on SELECT w/ optimizer_trace enabled
--echo # --echo #
--disable_view_protocol
SELECT '' LIMIT 0; SELECT '' LIMIT 0;
--enable_view_protocol
--error ER_WRONG_COLUMN_NAME --error ER_WRONG_COLUMN_NAME
CREATE TABLE t1 AS SELECT ''; CREATE TABLE t1 AS SELECT '';
@@ -320,7 +320,9 @@ create or replace table t2 (b int);
insert into t1 values(111111111),(-2147483648); insert into t1 values(111111111),(-2147483648);
insert into t2 values(1),(2); insert into t2 values(1),(2);
--enable_metadata --enable_metadata
--disable_view_protocol
select t1.a as a1 from t1 as t1,t2 order by t2.b,t1.a; select t1.a as a1 from t1 as t1,t2 order by t2.b,t1.a;
--enable_view_protocol
--disable_metadata --disable_metadata
drop table t1,t2; drop table t1,t2;

View File

@@ -1973,8 +1973,7 @@ ALTER TABLE ti1 DROP FOREIGN KEY fi1;
affected rows: 0 affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0 info: Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE tm1 DROP FOREIGN KEY fm1; ALTER TABLE tm1 DROP FOREIGN KEY fm1;
affected rows: 2 ERROR 42000: Can't DROP FOREIGN KEY `fm1`; check that it exists
info: Records: 2 Duplicates: 0 Warnings: 0
ALTER TABLE ti1 RENAME TO ti3; ALTER TABLE ti1 RENAME TO ti3;
affected rows: 0 affected rows: 0
ALTER TABLE tm1 RENAME TO tm3; ALTER TABLE tm1 RENAME TO tm3;

View File

@@ -1688,6 +1688,7 @@ ALTER TABLE ti1 DROP PRIMARY KEY;
ALTER TABLE tm1 DROP PRIMARY KEY; ALTER TABLE tm1 DROP PRIMARY KEY;
ALTER TABLE ti1 DROP FOREIGN KEY fi1; ALTER TABLE ti1 DROP FOREIGN KEY fi1;
--error ER_CANT_DROP_FIELD_OR_KEY
ALTER TABLE tm1 DROP FOREIGN KEY fm1; ALTER TABLE tm1 DROP FOREIGN KEY fm1;
ALTER TABLE ti1 RENAME TO ti3; ALTER TABLE ti1 RENAME TO ti3;

View File

@@ -1,3 +1,4 @@
set global default_storage_engine= innodb;
set default_storage_engine= innodb; set default_storage_engine= innodb;
connect con2, localhost, root,,; connect con2, localhost, root,,;
connection default; 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; alter table t1 add b int NULL, algorithm= copy, lock= none;
connection con2; connection con2;
insert into t1 values (1),(2),(3),(4),(5),(6); 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; select * from t1;
a a
1 1
@@ -496,6 +497,7 @@ a b UNIX_TIMESTAMP(row_start) UNIX_TIMESTAMP(row_end)
6 77 1.000000 2147483647.999999 6 77 1.000000 2147483647.999999
alter table t1 drop system versioning, algorithm= copy, lock= none; alter table t1 drop system versioning, algorithm= copy, lock= none;
ERROR 0A000: LOCK=NONE is not supported. Reason: DROP SYSTEM VERSIONING. Try LOCK=SHARED ERROR 0A000: LOCK=NONE is not supported. Reason: DROP SYSTEM VERSIONING. Try LOCK=SHARED
drop table t1;
# #
# Test ROLLBACK TO SAVEPOINT # Test ROLLBACK TO SAVEPOINT
# #
@@ -582,7 +584,7 @@ set debug_sync= 'reset';
drop table t1; drop table t1;
drop table t2; drop table t2;
drop table t3; 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); insert t1 values ('abcde1',1),('abcde2',2);
set debug_sync= 'now wait_for downgraded'; set debug_sync= 'now wait_for downgraded';
connection con2; connection con2;
@@ -838,7 +840,7 @@ a b
drop table t1; drop table t1;
set debug_sync= 'reset'; set debug_sync= 'reset';
## CHECK, UPDATE ## CHECK, UPDATE
create table t1 (a int) engine=innodb; create table t1 (a int);
insert t1 values (1),(2),(3),(4); insert t1 values (1),(2),(3),(4);
set debug_sync= 'now wait_for downgraded'; set debug_sync= 'now wait_for downgraded';
connection con2; connection con2;
@@ -863,7 +865,7 @@ a
14 14
drop table t1; drop table t1;
## DEFAULT, UPDATE ## DEFAULT, UPDATE
create table t1 (a int) engine=innodb; create table t1 (a int);
insert t1 values (1),(2),(3),(4); insert t1 values (1),(2),(3),(4);
set debug_sync= 'now wait_for downgraded'; set debug_sync= 'now wait_for downgraded';
connection con2; connection con2;
@@ -892,7 +894,7 @@ a b
drop table t1; drop table t1;
set debug_sync= 'reset'; set debug_sync= 'reset';
## VCOL + CHECK ## VCOL + CHECK
create table t1 (a int) engine=innodb; create table t1 (a int);
insert t1 values (1),(2),(3),(4); insert t1 values (1),(2),(3),(4);
set debug_sync= 'now wait_for downgraded'; set debug_sync= 'now wait_for downgraded';
connection con2; connection con2;
@@ -939,8 +941,8 @@ connection default;
drop table t1; drop table t1;
set debug_sync= reset; set debug_sync= reset;
### ###
create table t1 (a text, unique(a)) engine=innodb; create table t1 (a text, unique(a));
create table t2 (b text, unique(b)) engine=innodb; create table t2 (b text, unique(b));
insert into t2 values (null),(null); insert into t2 values (null),(null);
set debug_sync= 'now wait_for downgraded'; set debug_sync= 'now wait_for downgraded';
connection con2; connection con2;
@@ -958,7 +960,7 @@ set debug_sync= reset;
# #
# MDEV-29038 XA assertions failing in binlog_rollback and binlog_commit # 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); insert into t values (1);
xa begin 'xid'; xa begin 'xid';
set debug_sync= 'now wait_for downgraded'; set debug_sync= 'now wait_for downgraded';
@@ -1303,7 +1305,7 @@ drop table t;
# Test that correct fields are marked as explicit: # Test that correct fields are marked as explicit:
# Drop a, reorder b, add new column with default. # 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); insert into t values (1, 1), (2, 2), (3, 3);
set debug_sync= "alter_table_copy_end signal copy wait_for goon"; set debug_sync= "alter_table_copy_end signal copy wait_for goon";
alter table t drop primary key, drop a, alter table t drop primary key, drop a,
@@ -1334,7 +1336,7 @@ c x
3 123456 3 123456
drop table t; drop table t;
# Test that all the fields are unpacked. # 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); insert into t values (NULL, 123), (NULL, 456);
set debug_sync= "alter_table_copy_end signal copy wait_for goon"; set debug_sync= "alter_table_copy_end signal copy wait_for goon";
alter table t drop a, add primary key(b), algorithm=copy; alter table t drop a, add primary key(b), algorithm=copy;
@@ -1458,6 +1460,334 @@ connection default;
set old_mode= @old_old_mode; set old_mode= @old_old_mode;
drop table t1; drop table t1;
set debug_sync= reset; 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 con1;
disconnect con2; disconnect con2;
# #

View File

@@ -4,8 +4,10 @@
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/have_sequence.inc --source include/have_sequence.inc
--source include/have_partition.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,,) --connect (con2, localhost, root,,)
--connection default --connection default
@@ -368,7 +370,7 @@ alter table t1 add b int NULL, algorithm= copy, lock= none;
--connection con2 --connection con2
--reap --reap
--error ER_DUP_ENTRY --error ER_DUP_ENTRY,ER_DUP_KEY
insert into t1 values (1),(2),(3),(4),(5),(6); insert into t1 values (1),(2),(3),(4),(5),(6);
select * from t1; select * from t1;
set debug_sync= 'now SIGNAL end'; set debug_sync= 'now SIGNAL end';
@@ -629,6 +631,7 @@ alter table t1 drop system versioning, algorithm= copy, lock= none;
#--reap #--reap
#show create table t1; #show create table t1;
#select * from t1; #select * from t1;
drop table t1;
--echo # --echo #
--echo # Test ROLLBACK TO SAVEPOINT --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 # 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); insert t1 values ('abcde1',1),('abcde2',2);
--send set debug_sync= 'now wait_for downgraded' --send set debug_sync= 'now wait_for downgraded'
--connection con2 --connection con2
@@ -1007,7 +1010,7 @@ drop table t1;
set debug_sync= 'reset'; set debug_sync= 'reset';
--echo ## CHECK, UPDATE --echo ## CHECK, UPDATE
create table t1 (a int) engine=innodb; create table t1 (a int);
insert t1 values (1),(2),(3),(4); insert t1 values (1),(2),(3),(4);
--send set debug_sync= 'now wait_for downgraded' --send set debug_sync= 'now wait_for downgraded'
--connection con2 --connection con2
@@ -1026,7 +1029,7 @@ select * from t1;
drop table t1; drop table t1;
--echo ## DEFAULT, UPDATE --echo ## DEFAULT, UPDATE
create table t1 (a int) engine=innodb; create table t1 (a int);
insert t1 values (1),(2),(3),(4); insert t1 values (1),(2),(3),(4);
--send set debug_sync= 'now wait_for downgraded' --send set debug_sync= 'now wait_for downgraded'
--connection con2 --connection con2
@@ -1048,7 +1051,7 @@ drop table t1;
set debug_sync= 'reset'; set debug_sync= 'reset';
--echo ## VCOL + CHECK --echo ## VCOL + CHECK
create table t1 (a int) engine=innodb; create table t1 (a int);
insert t1 values (1),(2),(3),(4); insert t1 values (1),(2),(3),(4);
--send set debug_sync= 'now wait_for downgraded' --send set debug_sync= 'now wait_for downgraded'
--connection con2 --connection con2
@@ -1097,8 +1100,8 @@ set debug_sync= reset;
--echo ### --echo ###
create table t1 (a text, unique(a)) engine=innodb; create table t1 (a text, unique(a));
create table t2 (b text, unique(b)) engine=innodb; create table t2 (b text, unique(b));
insert into t2 values (null),(null); insert into t2 values (null),(null);
--send --send
set debug_sync= 'now wait_for downgraded'; set debug_sync= 'now wait_for downgraded';
@@ -1126,7 +1129,7 @@ set debug_sync= reset;
--echo # --echo #
--echo # MDEV-29038 XA assertions failing in binlog_rollback and binlog_commit --echo # MDEV-29038 XA assertions failing in binlog_rollback and binlog_commit
--echo # --echo #
create table t (a int) engine=innodb; create table t (a int);
insert into t values (1); insert into t values (1);
xa begin 'xid'; xa begin 'xid';
--send --send
@@ -1513,7 +1516,7 @@ drop table t;
--echo # Test that correct fields are marked as explicit: --echo # Test that correct fields are marked as explicit:
--echo # Drop a, reorder b, add new column with default. --echo # Drop a, reorder b, add new column with default.
--echo # --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); insert into t values (1, 1), (2, 2), (3, 3);
set debug_sync= "alter_table_copy_end signal copy wait_for goon"; set debug_sync= "alter_table_copy_end signal copy wait_for goon";
@@ -1539,7 +1542,7 @@ select * from t;
drop table t; drop table t;
--echo # Test that all the fields are unpacked. --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); insert into t values (NULL, 123), (NULL, 456);
set debug_sync= "alter_table_copy_end signal copy wait_for goon"; 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; drop table t1;
set debug_sync= reset; 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 con1
--disconnect con2 --disconnect con2

View File

@@ -417,5 +417,41 @@ test t1 B 1 NULL
test t1 B 2 NULL test t1 B 2 NULL
drop table t1; 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 # End of 10.6 tests
# #

View File

@@ -269,6 +269,43 @@ alter ignore table t1 rename key `b` to `B`, LOCK=shared;
select * from mysql.index_stats where table_name= "t1"; select * from mysql.index_stats where table_name= "t1";
drop table 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 #
--echo # End of 10.6 tests --echo # End of 10.6 tests
--echo # --echo #

View File

@@ -95,7 +95,7 @@ drop table t1;
# #
# BACKUP STAGE performs implicit commits # BACKUP STAGE performs implicit commits
# #
create table t1(a int) engine=InnoDB; create table t1(a int) stats_persistent=0, engine=InnoDB;
begin; begin;
insert into t1 values(1); insert into t1 values(1);
select lock_mode from information_schema.metadata_lock_info where thread_id>0; 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 # CHECK: RO transaction under BACKUP STAGE is a potential deadlock
# OTOH we most probably allow them under FTWRL as well # 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); insert into t1 values (1);
InnoDB 0 transactions not purged
backup stage start; backup stage start;
backup stage block_commit; backup stage block_commit;
begin; begin;

View File

@@ -120,7 +120,7 @@ drop table t1;
--echo # BACKUP STAGE performs implicit commits --echo # BACKUP STAGE performs implicit commits
--echo # --echo #
--disable_view_protocol --disable_view_protocol
create table t1(a int) engine=InnoDB; create table t1(a int) stats_persistent=0, engine=InnoDB;
begin; begin;
insert into t1 values(1); insert into t1 values(1);
select lock_mode from information_schema.metadata_lock_info where thread_id>0; 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 # OTOH we most probably allow them under FTWRL as well
--echo # --echo #
--disable_view_protocol --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); insert into t1 values (1);
--source ../suite/innodb/include/wait_all_purged.inc
backup stage start; backup stage start;
backup stage block_commit; backup stage block_commit;
begin; begin;

View File

@@ -1,6 +1,7 @@
# #
# Testing which locks we get from all stages # Testing which locks we get from all stages
# #
InnoDB 0 transactions not purged
BACKUP STAGE START; BACKUP STAGE START;
SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info
WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; WHERE TABLE_NAME NOT LIKE 'innodb_%_stats';
@@ -34,7 +35,8 @@ connection default;
# #
# testing if BACKUP STAGE FLUSH causes deadlocks with ALTER TABLE # 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; connection con2;
backup stage start; backup stage start;
connection default; connection default;
@@ -104,7 +106,8 @@ drop table t1;
# #
# testing if BACKUP STAGE FLUSH causes deadlocks with DROP TABLE # 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; start transaction;
insert into t1 values (1); insert into t1 values (1);
connection con1; connection con1;
@@ -132,6 +135,7 @@ connection default;
# Check if backup stage block_dll + concurrent drop table blocks select # Check if backup stage block_dll + concurrent drop table blocks select
# #
create table t1 (a int) engine=innodb; create table t1 (a int) engine=innodb;
InnoDB 0 transactions not purged
backup stage start; backup stage start;
backup stage block_ddl; backup stage block_ddl;
connection con1; connection con1;

View File

@@ -15,6 +15,8 @@
let $mdl= LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info let $mdl= LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info
WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; WHERE TABLE_NAME NOT LIKE 'innodb_%_stats';
--source ../suite/innodb/include/wait_all_purged.inc
BACKUP STAGE START; BACKUP STAGE START;
eval SELECT $mdl; eval SELECT $mdl;
BACKUP STAGE FLUSH; BACKUP STAGE FLUSH;
@@ -39,7 +41,8 @@ connection default;
--echo # testing if BACKUP STAGE FLUSH causes deadlocks with ALTER TABLE --echo # testing if BACKUP STAGE FLUSH causes deadlocks with ALTER TABLE
--echo # --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; connection con2;
backup stage start; backup stage start;
@@ -129,7 +132,8 @@ drop table t1;
--echo # testing if BACKUP STAGE FLUSH causes deadlocks with DROP TABLE --echo # testing if BACKUP STAGE FLUSH causes deadlocks with DROP TABLE
--echo # --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; start transaction;
# Acquires MDL lock # Acquires MDL lock
insert into t1 values (1); insert into t1 values (1);
@@ -165,6 +169,7 @@ connection default;
--echo # --echo #
create table t1 (a int) engine=innodb; create table t1 (a int) engine=innodb;
--source ../suite/innodb/include/wait_all_purged.inc
backup stage start; backup stage start;
backup stage block_ddl; backup stage block_ddl;
connection con1; connection con1;

View File

@@ -23,7 +23,7 @@ BACKUP UNLOCK;
# #
connect con1,localhost,root,,; connect con1,localhost,root,,;
connection default; connection default;
create table t1 (a int) engine=innodb; create table t1 (a int) stats_persistent=0,engine=innodb;
insert into t1 values (1); insert into t1 values (1);
backup lock t1; backup lock t1;
select * from t1; select * from t1;
@@ -184,5 +184,82 @@ ERROR HY000: Can't execute the query because you have a conflicting read lock
BACKUP UNLOCK; BACKUP UNLOCK;
DROP TABLE t3; 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 # End of MariaDB 10.4 tests
# #

View File

@@ -29,7 +29,7 @@ BACKUP UNLOCK;
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
connection default; connection default;
create table t1 (a int) engine=innodb; create table t1 (a int) stats_persistent=0,engine=innodb;
insert into t1 values (1); insert into t1 values (1);
backup lock t1; backup lock t1;
select * from t1; select * from t1;
@@ -214,7 +214,78 @@ LOCK TABLES t3 AS a2 WRITE, t3 AS a1 READ LOCAL;
DROP TABLE t3; DROP TABLE t3;
BACKUP UNLOCK; BACKUP UNLOCK;
DROP TABLE t3; 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 #
--echo # End of MariaDB 10.4 tests --echo # End of MariaDB 10.4 tests
--echo # --echo #

View File

@@ -17,6 +17,7 @@ FROM information_schema.processlist WHERE id = @con1_id;
ID USER COMMAND STATE INFO STAGE MAX_STAGE INFO_BINARY ID USER COMMAND STATE INFO STAGE MAX_STAGE INFO_BINARY
<con1_id> root Query Waiting for backup lock BACKUP STAGE START 0 0 BACKUP STAGE START <con1_id> root Query Waiting for backup lock BACKUP STAGE START 0 0 BACKUP STAGE START
BACKUP STAGE END; BACKUP STAGE END;
InnoDB 0 transactions not purged
connection con1; connection con1;
# The connection default has removed the backup lock. # The connection default has removed the backup lock.
# And so the current connection con1 can reap for its BACKUP STAGE START # And so the current connection con1 can reap for its BACKUP STAGE START

View File

@@ -50,6 +50,7 @@ FROM information_schema.processlist WHERE id = @con1_id;
# con1 uses @@global.lock_wait_timeout # con1 uses @@global.lock_wait_timeout
BACKUP STAGE END; BACKUP STAGE END;
--source ../suite/innodb/include/wait_all_purged.inc
--connection con1 --connection con1
--echo # The connection default has removed the backup lock. --echo # The connection default has removed the backup lock.

View File

@@ -1,67 +1,67 @@
drop table if exists t1, t2; drop table if exists t1, t2;
select 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;
CASE "b" when "a" then 1 when "b" then 2 END exp
2 2
select 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;
CASE "c" when "a" then 1 when "b" then 2 END exp
NULL NULL
select 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;
CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END exp
3 3
select 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;
CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END exp
ok ok
select 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;
CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END exp
ok ok
select 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;
CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end exp
a a
select CASE when 1=0 then "true" else "false" END; select CASE when 1=0 then "true" else "false" END as exp;
CASE when 1=0 then "true" else "false" END exp
false false
select 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;
CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END exp
one 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 id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: 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` 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; select CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END as exp;
CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END exp
two two
select (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;
(CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0 exp
2 2
select (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;
(CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0 exp
2.00 2.00
select case 1/0 when "a" then "true" else "false" END; select case 1/0 when "a" then "true" else "false" END as exp;
case 1/0 when "a" then "true" else "false" END exp
false false
Warnings: Warnings:
Warning 1365 Division by 0 Warning 1365 Division by 0
select case 1/0 when "a" then "true" END; select case 1/0 when "a" then "true" END as exp;
case 1/0 when "a" then "true" END exp
NULL NULL
Warnings: Warnings:
Warning 1365 Division by 0 Warning 1365 Division by 0
select (case 1/0 when "a" then "true" END) | 0; select (case 1/0 when "a" then "true" END) | 0 as exp;
(case 1/0 when "a" then "true" END) | 0 exp
NULL NULL
Warnings: Warnings:
Warning 1365 Division by 0 Warning 1365 Division by 0
select (case 1/0 when "a" then "true" END) + 0.0; select (case 1/0 when "a" then "true" END) + 0.0 as exp;
(case 1/0 when "a" then "true" END) + 0.0 exp
NULL NULL
Warnings: Warnings:
Warning 1365 Division by 0 Warning 1365 Division by 0
select case when 1>0 then "TRUE" else "FALSE" END; select case when 1>0 then "TRUE" else "FALSE" END as exp;
case when 1>0 then "TRUE" else "FALSE" END exp
TRUE TRUE
select case when 1<0 then "TRUE" else "FALSE" END; select case when 1<0 then "TRUE" else "FALSE" END as exp;
case when 1<0 then "TRUE" else "FALSE" END exp
FALSE FALSE
create table t1 (a int); create table t1 (a int);
insert into t1 values(1),(2),(3),(4); insert into t1 values(1),(2),(3),(4);
@@ -133,12 +133,12 @@ WHEN _latin1'a' COLLATE latin1_swedish_ci THEN 2
END; END;
ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_danish_ci,EXPLICIT), (latin1_swedish_ci,EXPLICIT) for operation 'case' ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_danish_ci,EXPLICIT), (latin1_swedish_ci,EXPLICIT) for operation 'case'
SELECT SELECT
CASE _latin1'a' COLLATE latin1_general_ci WHEN _latin1'A' 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, 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, 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 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 1 2 1 2
CREATE TABLE t1 SELECT COALESCE(_latin1'a',_latin2'a'); 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' 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 # End of 10.1 test
# #
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;
case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end exp
ok ok
Warnings: Warnings:
Warning 1292 Truncated incorrect time value: 'foo' 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'
Warning 1292 Truncated incorrect time value: 'foo' Warning 1292 Truncated incorrect time value: 'foo'
drop table t1; 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; select case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end as exp;
case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end exp
ok ok
# #
# End of 10.2 test # End of 10.2 test

View File

@@ -2,31 +2,29 @@
# Testing of CASE # Testing of CASE
# #
#remove this include after fix MDEV-27871
--source include/no_view_protocol.inc
--disable_warnings --disable_warnings
drop table if exists t1, t2; drop table if exists t1, t2;
--enable_warnings --enable_warnings
select 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;
select 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;
select 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;
select 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;
select 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;
select 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;
select CASE when 1=0 then "true" else "false" END; 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; 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; 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; 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; 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; 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; select case 1/0 when "a" then "true" else "false" END as exp;
select case 1/0 when "a" then "true" END; select case 1/0 when "a" then "true" END as exp;
select (case 1/0 when "a" then "true" END) | 0; select (case 1/0 when "a" then "true" END) | 0 as exp;
select (case 1/0 when "a" then "true" END) + 0.0; select (case 1/0 when "a" then "true" END) + 0.0 as exp;
select case when 1>0 then "TRUE" else "FALSE" END; select case when 1>0 then "TRUE" else "FALSE" END as exp;
select case when 1<0 then "TRUE" else "FALSE" END; select case when 1<0 then "TRUE" else "FALSE" END as exp;
# #
# Test bug when using GROUP BY on CASE # Test bug when using GROUP BY on CASE
@@ -83,10 +81,10 @@ SELECT CASE _latin1'a' COLLATE latin1_general_ci
END; END;
SELECT SELECT
CASE _latin1'a' COLLATE latin1_general_ci WHEN _latin1'A' 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, 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, 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 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 # 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'); select 'foo' in (time'10:00:00','0');
create table t1 (a time); create table t1 (a time);
@@ -308,7 +306,7 @@ select 'foo' in (a,'0') from t1;
drop table t1; drop table t1;
# first comparison should be as date, second as time # 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 #
--echo # End of 10.2 test --echo # End of 10.2 test

View File

@@ -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)); 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)) cast(cast("8:46:06.23434" AS time) as decimal(32,10))
84606.0000000000 84606.0000000000
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;
cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6)) exp
20110405084606.000000 20110405084606.000000
# #
# Check handling of cast with microseconds # Check handling of cast with microseconds
# #
select cast(cast(20010203101112.121314 as double) as datetime); select cast(cast(20010203101112.121314 as double) as datetime) as exp;
cast(cast(20010203101112.121314 as double) as datetime) exp
2001-02-03 10:11:12 2001-02-03 10:11:12
select cast(cast(010203101112.12 as double) as datetime); select cast(cast(010203101112.12 as double) as datetime) as exp;
cast(cast(010203101112.12 as double) as datetime) exp
2001-02-03 10:11:12 2001-02-03 10:11:12
select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime); select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime) as exp;
cast(cast(20010203101112.121314 as decimal(32,6)) as datetime) exp
2001-02-03 10:11:12 2001-02-03 10:11:12
select cast(20010203101112.121314 as datetime); select cast(20010203101112.121314 as datetime) as exp;
cast(20010203101112.121314 as datetime) exp
2001-02-03 10:11:12 2001-02-03 10:11:12
select cast(110203101112.121314 as datetime); select cast(110203101112.121314 as datetime) as exp;
cast(110203101112.121314 as datetime) exp
2011-02-03 10:11:12 2011-02-03 10:11:12
select cast(cast(010203101112.12 as double) as datetime); select cast(cast(010203101112.12 as double) as datetime) as exp;
cast(cast(010203101112.12 as double) as datetime) exp
2001-02-03 10:11:12 2001-02-03 10:11:12
select cast("2011-02-03 10:11:12.123456" as datetime); select cast("2011-02-03 10:11:12.123456" as datetime) as exp;
cast("2011-02-03 10:11:12.123456" as datetime) exp
2011-02-03 10:11:12 2011-02-03 10:11:12
select 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;
cast("2011-02-03 10:11:12.123456" as datetime(0)) exp
2011-02-03 10:11:12 2011-02-03 10:11:12
select 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;
cast("2011-02-03 10:11:12.123456" as datetime(5)) exp
2011-02-03 10:11:12.12345 2011-02-03 10:11:12.12345
select 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;
cast("2011-02-03 10:11:12.123456" as datetime(6)) exp
2011-02-03 10:11:12.123456 2011-02-03 10:11:12.123456
select cast("2011-02-03 10:11:12" as datetime(6)); select cast("2011-02-03 10:11:12" as datetime(6)) as exp;
cast("2011-02-03 10:11:12" as datetime(6)) exp
2011-02-03 10:11:12.000000 2011-02-03 10:11:12.000000
select cast(cast(20010203101112.5 as double) as datetime(1)); select cast(cast(20010203101112.5 as double) as datetime(1)) as exp;
cast(cast(20010203101112.5 as double) as datetime(1)) exp
2001-02-03 10:11:12.5 2001-02-03 10:11:12.5
select cast(cast(010203101112.12 as double) as datetime(2)); select cast(cast(010203101112.12 as double) as datetime(2)) as exp;
cast(cast(010203101112.12 as double) as datetime(2)) exp
2001-02-03 10:11:12.12 2001-02-03 10:11:12.12
select 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;
cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6)) exp
2001-02-03 10:11:12.121314 2001-02-03 10:11:12.121314
select cast(20010203101112.121314 as datetime(6)); select cast(20010203101112.121314 as datetime(6)) as exp;
cast(20010203101112.121314 as datetime(6)) exp
2001-02-03 10:11:12.121314 2001-02-03 10:11:12.121314
select cast(110203101112.121314 as datetime(6)); select cast(110203101112.121314 as datetime(6)) as exp;
cast(110203101112.121314 as datetime(6)) exp
2011-02-03 10:11:12.121314 2011-02-03 10:11:12.121314
select cast(cast(010203101112.12 as double) as datetime(6)); select cast(cast(010203101112.12 as double) as datetime(6)) as exp;
cast(cast(010203101112.12 as double) as datetime(6)) exp
2001-02-03 10:11:12.120000 2001-02-03 10:11:12.120000
select cast("2011-02-03 10:11:12.123456" as time); select cast("2011-02-03 10:11:12.123456" as time) as exp;
cast("2011-02-03 10:11:12.123456" as time) exp
10:11:12 10:11:12
select 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;
cast("2011-02-03 10:11:12.123456" as time(6)) exp
10:11:12.123456 10:11:12.123456
select cast("10:11:12.123456" as time); select cast("10:11:12.123456" as time) as exp;
cast("10:11:12.123456" as time) exp
10:11:12 10:11:12
select cast("10:11:12.123456" as time(0)); select cast("10:11:12.123456" as time(0)) as exp;
cast("10:11:12.123456" as time(0)) exp
10:11:12 10:11:12
select cast("10:11:12.123456" as time(5)); select cast("10:11:12.123456" as time(5)) as exp;
cast("10:11:12.123456" as time(5)) exp
10:11:12.12345 10:11:12.12345
select cast("10:11:12.123456" as time(6)); select cast("10:11:12.123456" as time(6)) as exp;
cast("10:11:12.123456" as time(6)) exp
10:11:12.123456 10:11:12.123456
select cast("10:11:12" as time(6)); select cast("10:11:12" as time(6)) as exp;
cast("10:11:12" as time(6)) exp
10:11:12.000000 10:11:12.000000
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) as exp;
cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time) exp
08:46:06 08:46:06
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) as time(6)) as exp;
cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6)) exp
08:46:06.000000 08:46:06.000000
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) as exp;
cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time) exp
08:46:06 08:46:06
select 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;
cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6)) exp
08:46:06.123456 08:46:06.123456
select cast(NULL as unsigned), cast(1/0 as unsigned); select cast(NULL as unsigned), cast(1/0 as unsigned);
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 Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL, `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 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop table t1; drop table t1;
select collation(cast("a" as char(10) binary)); select collation(cast("a" as char(10) binary));

View File

@@ -2,10 +2,6 @@
# Test of cast function # 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 # For TIME->DATETIME conversion
SET timestamp=unix_timestamp('2001-02-03 10:20:30'); 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(12.444 as double);
select cast(cast("20:01:01" as time) as datetime); 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("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 #
--echo # Check handling of cast with microseconds --echo # Check handling of cast with microseconds
--echo # --echo #
select cast(cast(20010203101112.121314 as double) as datetime); select cast(cast(20010203101112.121314 as double) as datetime) as exp;
select cast(cast(010203101112.12 as double) as datetime); select cast(cast(010203101112.12 as double) as datetime) as exp;
select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime); select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime) as exp;
select cast(20010203101112.121314 as datetime); select cast(20010203101112.121314 as datetime) as exp;
select cast(110203101112.121314 as datetime); select cast(110203101112.121314 as datetime) as exp;
select cast(cast(010203101112.12 as double) as datetime); 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) as exp;
select 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;
select 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;
select 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;
select cast("2011-02-03 10:11:12" as datetime(6)); select cast("2011-02-03 10:11:12" as datetime(6)) as exp;
select cast(cast(20010203101112.5 as double) as datetime(1)); select cast(cast(20010203101112.5 as double) as datetime(1)) as exp;
select cast(cast(010203101112.12 as double) as datetime(2)); select cast(cast(010203101112.12 as double) as datetime(2)) as exp;
select 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;
select cast(20010203101112.121314 as datetime(6)); select cast(20010203101112.121314 as datetime(6)) as exp;
select cast(110203101112.121314 as datetime(6)); select cast(110203101112.121314 as datetime(6)) as exp;
select cast(cast(010203101112.12 as double) as datetime(6)); 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) as exp;
select 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;
select cast("10:11:12.123456" as time); select cast("10:11:12.123456" as time) as exp;
select cast("10:11:12.123456" as time(0)); select cast("10:11:12.123456" as time(0)) as exp;
select cast("10:11:12.123456" as time(5)); select cast("10:11:12.123456" as time(5)) as exp;
select cast("10:11:12.123456" as time(6)); select cast("10:11:12.123456" as time(6)) as exp;
select cast("10:11:12" as time(6)); select cast("10:11:12" as time(6)) as exp;
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) as exp;
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) as time(6)) as exp;
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) as exp;
select 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;
# #
# Bug #28250: Run-Time Check Failure #3 - The variable 'value' is being used # 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; set names binary;
select cast(_latin1'test' as char character set latin2); select cast(_latin1'test' as char character set latin2);
--disable_service_connection
select cast(_koi8r'<27><><EFBFBD><EFBFBD>' as char character set cp1251); select cast(_koi8r'<27><><EFBFBD><EFBFBD>' as char character set cp1251);
--enable_service_connection
create table t1 select cast(_koi8r'<27><><EFBFBD><EFBFBD>' as char character set cp1251) as t; create table t1 select cast(_koi8r'<27><><EFBFBD><EFBFBD>' as char character set cp1251) as t;
show create table t1; show create table t1;
drop table t1; drop table t1;
@@ -170,6 +168,7 @@ drop table t1;
# #
# CAST to CHAR with/without length # CAST to CHAR with/without length
# #
--disable_service_connection
select select
cast(_latin1'ab' AS char) as c1, cast(_latin1'ab' AS char) as c1,
cast(_latin1'a ' AS char) as c2, cast(_latin1'a ' AS char) as c2,
@@ -177,6 +176,7 @@ select
cast(_latin1'a ' AS char(2)) as c4, cast(_latin1'a ' AS char(2)) as c4,
hex(cast(_latin1'a' AS char(2))) as c5; hex(cast(_latin1'a' AS char(2))) as c5;
select cast(1000 as CHAR(3)); select cast(1000 as CHAR(3));
--enable_service_connection
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
create table t1 select 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); CREATE TABLE t1 (a enum ('aac','aab','aaa') not null);
INSERT INTO t1 VALUES ('aaa'),('aab'),('aac'); INSERT INTO t1 VALUES ('aaa'),('aab'),('aac');
--disable_service_connection
# these two should be in enum order # 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) 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; SELECT a, CAST(a AS CHAR(3)) FROM t1 ORDER BY CAST(a AS CHAR(2)), a;
# these two should be in alphabetic order # 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 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; SELECT a, CAST(a AS CHAR(2)) FROM t1 ORDER BY CAST(a AS CHAR(3)), a;
--enable_service_connection
DROP TABLE t1; DROP TABLE t1;
# #
@@ -344,9 +346,11 @@ select cast(NULL as decimal(6)) as t1;
# Bug #17903: cast to char results in binary # Bug #17903: cast to char results in binary
# #
set names latin1; set names latin1;
--disable_service_connection
select hex(cast('a' as char(2) binary)); select hex(cast('a' as char(2) binary));
select hex(cast('a' as binary(2))); select hex(cast('a' as binary(2)));
select hex(cast('a' as char(2) binary)); 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. # Bug#29898: Item_date_typecast::val_int doesn't reset the null_value flag.
@@ -476,11 +480,13 @@ drop table t1;
# #
# CAST (... BINARY) # CAST (... BINARY)
# #
--disable_service_connection
select collation(cast("a" as char(10) binary)); 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) charset utf8 binary));
select collation(cast("a" as char(10) ascii 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 charset utf8));
select collation(cast("a" as char(10) binary ascii)); select collation(cast("a" as char(10) binary ascii));
--enable_service_connection
--echo # --echo #
--echo # MDEV-11030 Assertion `precision > 0' failed in decimal_bin_size --echo # MDEV-11030 Assertion `precision > 0' failed in decimal_bin_size
@@ -762,11 +768,14 @@ INSERT INTO t1 VALUES (-1.0);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
#enable after MDEV-32645 is fixed
--disable_view_protocol
SELECT CAST(-1e0 AS UNSIGNED); SELECT CAST(-1e0 AS UNSIGNED);
CREATE TABLE t1 (a BIGINT UNSIGNED); CREATE TABLE t1 (a BIGINT UNSIGNED);
INSERT INTO t1 VALUES (-1e0); INSERT INTO t1 VALUES (-1e0);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--enable_view_protocol
SELECT CAST(-1e308 AS UNSIGNED); SELECT CAST(-1e308 AS UNSIGNED);
CREATE TABLE t1 (a BIGINT UNSIGNED); CREATE TABLE t1 (a BIGINT UNSIGNED);

View File

@@ -1,4 +1,6 @@
set global secure_auth=0; set global secure_auth=0;
Warnings:
Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release
create user test_nopw; create user test_nopw;
grant select on test.* to test_nopw; grant select on test.* to test_nopw;
create user test_oldpw identified by password "09301740536db389"; create user test_oldpw identified by password "09301740536db389";
@@ -90,6 +92,8 @@ NULL
FLUSH STATUS; FLUSH STATUS;
Value of com_select did not change Value of com_select did not change
set global secure_auth=default; 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'); set timestamp=unix_timestamp('2010-10-10 10:10:10');
select now(); select now();
now() now()

View File

@@ -308,6 +308,19 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop table t1; 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 # MDEV-32439 INSERT IGNORE VALUES (one row) errors on constraint
# #
CREATE TABLE t1 (v1 varchar(10), v2 varchar(10), constraint unequal check (v1 != v2)); CREATE TABLE t1 (v1 varchar(10), v2 varchar(10), constraint unequal check (v1 != v2));

View File

@@ -231,6 +231,23 @@ alter table t1 force;
show create table t1; show create table t1;
drop 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 #
--echo # MDEV-32439 INSERT IGNORE VALUES (one row) errors on constraint --echo # MDEV-32439 INSERT IGNORE VALUES (one row) errors on constraint
--echo # --echo #

View File

@@ -1,4 +1,6 @@
SET global secure_auth=0; 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; connect con1,localhost,root,,mysql;
show tables; show tables;
Tables_in_mysql Tables_in_mysql
@@ -412,6 +414,8 @@ test
test test
drop procedure p1; drop procedure p1;
SET global secure_auth=default; 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 # MDEV-19282: Log more specific warning with log_warnings=2 if
# connection is aborted prior to authentication # connection is aborted prior to authentication

View File

@@ -260,6 +260,7 @@ Note 1051 Unknown table 'test.t1,mysqltest2.t2'
create table test.t1 (i int) engine=myisam; create table test.t1 (i int) engine=myisam;
create table mysqltest2.t2 like test.t1; create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write; lock table test.t1 write, mysqltest2.t2 write;
InnoDB 0 transactions not purged
select * from information_schema.metadata_lock_info; select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DDL NULL Backup lock

View File

@@ -216,6 +216,7 @@ drop table if exists test.t1,mysqltest2.t2;
create table test.t1 (i int) engine=myisam; create table test.t1 (i int) engine=myisam;
create table mysqltest2.t2 like test.t1; create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write; lock table test.t1 write, mysqltest2.t2 write;
--source ../suite/innodb/include/wait_all_purged.inc
--replace_column 1 # --replace_column 1 #
--sorted_result --sorted_result
select * from information_schema.metadata_lock_info; select * from information_schema.metadata_lock_info;

View File

@@ -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 <09> mb3-replacement-char <09>
3 mb4-smiley 😊 mb3-replacement-char <09>
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 <09> mb3-replacement-char <09>
3 mb4-smiley 😊 mb3-replacement-char <09>
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 <09> mb3-replacement-char <09>
3 mb4-smiley 😊 mb3-replacement-char <09>
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 <09> mb3-replacement-char <09>
3 mb4-smiley 😊 mb3-replacement-char <09>
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 <09> mb3-replacement-char <09>
3 mb4-smiley 😊 mb3-replacement-char <09>
# 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":
["(<28>) <= (mb3) <= (<28>)"],
"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 <09>
#
# 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 <09> mb3-replacement-char <09> mb3-replacement-char <09>
3 mb4-smiley 😊 mb3-replacement-char <09> mb3-replacement-char <09>
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;

View File

@@ -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;

View File

@@ -2337,4 +2337,303 @@ set sql_mode="oracle";
with data as (select 1 as id) with data as (select 1 as id)
select id into @myid from data; select id into @myid from data;
set sql_mode= @save_sql_mode; 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": "<derived2>",
"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 # End of 10.4 tests

View File

@@ -1796,4 +1796,187 @@ with data as (select 1 as id)
select id into @myid from data; select id into @myid from data;
set sql_mode= @save_sql_mode; 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 --echo # End of 10.4 tests

View File

@@ -3383,6 +3383,50 @@ INSERT INTO t VALUES (0,0);
DELETE FROM t WHERE c2<c1; DELETE FROM t WHERE c2<c1;
DROP TABLE t; DROP TABLE t;
# #
# MDEV-28835 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on INSERT
#
SET NAMES latin1,character_set_connection=binary;
# Binary format, binary 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'))
4D6F6E646179
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'))
2D3031
# latin1 format, binary result
SELECT DATE_FORMAT('2004-02-02',_latin1'%W');
DATE_FORMAT('2004-02-02',_latin1'%W')
Monday
SELECT HEX(DATE_FORMAT('2004-02-02',_latin1'%W'));
HEX(DATE_FORMAT('2004-02-02',_latin1'%W'))
4D6F6E646179
SELECT DATE_FORMAT(TIME'-01:01:01',_latin1'%h');
DATE_FORMAT(TIME'-01:01:01',_latin1'%h')
-01
SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_latin1'%h'));
HEX(DATE_FORMAT(TIME'-01:01:01',_latin1'%h'))
2D3031
# Binary format, latin1 result
SET NAMES latin1;
SELECT DATE_FORMAT('2004-02-02',_binary'%W');
DATE_FORMAT('2004-02-02',_binary'%W')
Monday
SELECT HEX(DATE_FORMAT('2004-02-02',_binary'%W'));
HEX(DATE_FORMAT('2004-02-02',_binary'%W'))
4D6F6E646179
SELECT DATE_FORMAT(TIME'-01:01:01',_binary'%h');
DATE_FORMAT(TIME'-01:01:01',_binary'%h')
-01
SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_binary'%h'));
HEX(DATE_FORMAT(TIME'-01:01:01',_binary'%h'))
2D3031
#
# End of 10.4 tests # End of 10.4 tests
# #
# #

View File

@@ -225,6 +225,31 @@ INSERT INTO t VALUES (0,0);
DELETE FROM t WHERE c2<c1; DELETE FROM t WHERE c2<c1;
DROP TABLE t; DROP TABLE t;
--echo #
--echo # MDEV-28835 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on INSERT
--echo #
SET NAMES latin1,character_set_connection=binary;
--echo # Binary format, binary 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 # latin1 format, binary result
SELECT DATE_FORMAT('2004-02-02',_latin1'%W');
SELECT HEX(DATE_FORMAT('2004-02-02',_latin1'%W'));
SELECT DATE_FORMAT(TIME'-01:01:01',_latin1'%h');
SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_latin1'%h'));
--echo # Binary format, latin1 result
SET NAMES latin1;
SELECT DATE_FORMAT('2004-02-02',_binary'%W');
SELECT HEX(DATE_FORMAT('2004-02-02',_binary'%W'));
SELECT DATE_FORMAT(TIME'-01:01:01',_binary'%h');
SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_binary'%h'));
--echo # --echo #
--echo # End of 10.4 tests --echo # End of 10.4 tests
--echo # --echo #

View File

@@ -614,18 +614,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; 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 id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where 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); 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 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 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); 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 id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where 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; 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 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 1 SIMPLE t1 range s1 s1 11 NULL 1 Using index condition
EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci; 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 id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where 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; DROP TABLE t1;
create table t1(f1 varchar(10) character set latin2 collate latin2_hungarian_ci, key(f1)); create table t1(f1 varchar(10) character set latin2 collate latin2_hungarian_ci, key(f1));
insert into t1 set f1=0x3F3F9DC73F; insert into t1 set f1=0x3F3F9DC73F;
@@ -643,8 +649,8 @@ check table t1 extended;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
drop table t1; drop table t1;
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;
least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) f1
a a
create table t1 create table t1
select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; 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 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop table t1; drop table t1;
select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate 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;
case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate exp
latin5_turkish_ci then 2 else 3 end
3 3
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;
concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) exp
abc abc
# #
# Bug#11765016 57926: ILLEGAL MIX OF COLLATIONS FOR OPERATION 'UNION' .. USING CONCAT/FUNCTION/ # Bug#11765016 57926: ILLEGAL MIX OF COLLATIONS FOR OPERATION 'UNION' .. USING CONCAT/FUNCTION/

View File

@@ -1,5 +1,3 @@
#remove this include after fix MDEV-27871
--source include/no_view_protocol.inc
--disable_warnings --disable_warnings
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
@@ -248,16 +246,16 @@ drop table t1;
# #
# Bug#41627 Illegal mix of collations in LEAST / GREATEST / CASE # 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 create table t1
select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1; select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1;
show create table t1; show create table t1;
drop table t1; drop table t1;
select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate 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 # --echo #

View File

@@ -888,7 +888,7 @@ ERROR HY000: Invalid cp932 character string: '\x81\xAD'
EXECUTE IMMEDIATE CONCAT('SET STATEMENT ',@seq, '.a=1 SELECT 1'); EXECUTE IMMEDIATE CONCAT('SET STATEMENT ',@seq, '.a=1 SELECT 1');
ERROR HY000: Invalid cp932 character string: '\x81\xAD' ERROR HY000: Invalid cp932 character string: '\x81\xAD'
EXECUTE IMMEDIATE CONCAT('SET STATEMENT a.',@seq, '=1 SELECT 1'); 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 # 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'); EXECUTE IMMEDIATE CONCAT('SET SESSION ',@seq, '.a=1 SELECT 1');
ERROR HY000: Invalid cp932 character string: '\x81\xAD' ERROR HY000: Invalid cp932 character string: '\x81\xAD'
EXECUTE IMMEDIATE CONCAT('SET SESSION a.',@seq, '=1 SELECT 1'); 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 # 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'); EXECUTE IMMEDIATE CONCAT('SET ', @seq, '.a=1');
ERROR HY000: Invalid cp932 character string: '\x81\xAD' ERROR HY000: Invalid cp932 character string: '\x81\xAD'
EXECUTE IMMEDIATE CONCAT('SET a.', @seq, '=1'); 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 # 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;'); EXECUTE IMMEDIATE CONCAT('BEGIN ',@seq, '.a(1); END;');
ERROR HY000: Invalid cp932 character string: '\x81\xAD' ERROR HY000: Invalid cp932 character string: '\x81\xAD'
EXECUTE IMMEDIATE CONCAT('BEGIN a.',@seq, '(1); END;'); 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 # 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'); EXECUTE IMMEDIATE CONCAT(@seq, '.a:=1');
ERROR HY000: Invalid cp932 character string: '\x81\xAD' ERROR HY000: Invalid cp932 character string: '\x81\xAD'
EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); 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; SET sql_mode=DEFAULT;
# #
# End of 10.5 tests # End of 10.5 tests

View File

@@ -1,6 +1,4 @@
# remove this include in 10.6 version, # remove this include in 10.6 version,
# if MDEV-27871 will be fix
--source include/no_view_protocol.inc
-- source include/have_eucjpms.inc -- source include/have_eucjpms.inc

View File

@@ -6138,13 +6138,13 @@ DROP TABLE t1;
# MDEV-7661 Unexpected result for: CAST(0xHHHH AS CHAR CHARACTER SET xxx) for incorrect byte sequences # MDEV-7661 Unexpected result for: CAST(0xHHHH AS CHAR CHARACTER SET xxx) for incorrect byte sequences
# #
set sql_mode=''; set sql_mode='';
SELECT HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)); SELECT HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)) as exp;
HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)) exp
3F41 3F41
Warnings: Warnings:
Warning 1300 Invalid gb2312 character string: '\xA3A' Warning 1300 Invalid gb2312 character string: '\xA3A'
SELECT 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;
HEX(CONVERT(CAST(0xA341 AS CHAR CHARACTER SET gb2312) USING utf8)) exp
3F41 3F41
Warnings: Warnings:
Warning 1300 Invalid gb2312 character string: '\xA3A' Warning 1300 Invalid gb2312 character string: '\xA3A'

View File

@@ -452,8 +452,8 @@ DROP TABLE t1;
#enable after fix MDEV-27871 #enable after fix MDEV-27871
--disable_view_protocol --disable_view_protocol
set sql_mode=''; set sql_mode='';
SELECT HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)); SELECT HEX(CAST(0xA341 AS CHAR CHARACTER SET gb2312)) as exp;
SELECT 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;
set sql_mode=default; set sql_mode=default;
--enable_view_protocol --enable_view_protocol

View File

@@ -19619,7 +19619,7 @@ ERROR HY000: Invalid sjis character string: '
EXECUTE IMMEDIATE CONCAT('SET STATEMENT ',@seq, '.a=1 SELECT 1'); EXECUTE IMMEDIATE CONCAT('SET STATEMENT ',@seq, '.a=1 SELECT 1');
ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD'
EXECUTE IMMEDIATE CONCAT('SET STATEMENT a.',@seq, '=1 SELECT 1'); EXECUTE IMMEDIATE CONCAT('SET STATEMENT a.',@seq, '=1 SELECT 1');
ERROR HY000: Invalid sjis character string: '<27>_x81<EFBFBD>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81'
# #
# SET SESSION (bad|good.bad|bad.good)=1 # 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'); EXECUTE IMMEDIATE CONCAT('SET SESSION ',@seq, '.a=1 SELECT 1');
ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD'
EXECUTE IMMEDIATE CONCAT('SET SESSION a.',@seq, '=1 SELECT 1'); EXECUTE IMMEDIATE CONCAT('SET SESSION a.',@seq, '=1 SELECT 1');
ERROR HY000: Invalid sjis character string: '<27>_x81<EFBFBD>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81'
# #
# SET (bad|good.bad|bad.good)=1 # SET (bad|good.bad|bad.good)=1
# #
@@ -19637,7 +19637,7 @@ ERROR HY000: Invalid sjis character string: '
EXECUTE IMMEDIATE CONCAT('SET ', @seq, '.a=1'); EXECUTE IMMEDIATE CONCAT('SET ', @seq, '.a=1');
ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD'
EXECUTE IMMEDIATE CONCAT('SET a.', @seq, '=1'); EXECUTE IMMEDIATE CONCAT('SET a.', @seq, '=1');
ERROR HY000: Invalid sjis character string: '<27>_x81<EFBFBD>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81'
# #
# Oracle SP call: BEGIN (bad|good.bad|bad.good)(params); END # 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;'); EXECUTE IMMEDIATE CONCAT('BEGIN ',@seq, '.a(1); END;');
ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD'
EXECUTE IMMEDIATE CONCAT('BEGIN a.',@seq, '(1); END;'); EXECUTE IMMEDIATE CONCAT('BEGIN a.',@seq, '(1); END;');
ERROR HY000: Invalid sjis character string: '<27>_x81<EFBFBD>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81'
# #
# Oracle assignment: (bad|good.bad|bad.good):= value # Oracle assignment: (bad|good.bad|bad.good):= value
# #
@@ -19656,7 +19656,7 @@ ERROR HY000: Invalid sjis character string: '
EXECUTE IMMEDIATE CONCAT(@seq, '.a:=1'); EXECUTE IMMEDIATE CONCAT(@seq, '.a:=1');
ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81<38>_xAD'
EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1');
ERROR HY000: Invalid sjis character string: '<27>_x81<EFBFBD>_xAD' ERROR HY000: Invalid sjis character string: '<27>_x81'
SET sql_mode=DEFAULT; SET sql_mode=DEFAULT;
# #
# End of 10.5 tests # End of 10.5 tests

View File

@@ -209,9 +209,6 @@ DROP TABLE t1;
--echo # WL#3664 WEIGHT_STRING --echo # WL#3664 WEIGHT_STRING
--echo # --echo #
# enable view-protocol after fix MDEV-27871
--disable_view_protocol
set names sjis; set names sjis;
--source include/weight_string.inc --source include/weight_string.inc
--source include/weight_string_l1.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_l1.inc
--source include/weight_string_8140.inc --source include/weight_string_8140.inc
--enable_view_protocol
--echo # --echo #
--echo # End of 5.6 tests --echo # End of 5.6 tests
--echo # --echo #

View File

@@ -7964,8 +7964,8 @@ hex(weight_string(cast(_latin1 0xDF6368 as char),25, 4,0xC0))
# #
# Bug#33077 weight of supplementary characters is not 0xfffd # Bug#33077 weight of supplementary characters is not 0xfffd
# #
select 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;
hex(weight_string(_utf8mb4 0xF0908080 /* U+10000 */ collate utf8mb4_unicode_ci)) exp
FFFD FFFD
# #
# Bug#53064 garbled data when using utf8_german2_ci collation # Bug#53064 garbled data when using utf8_german2_ci collation

View File

@@ -552,10 +552,7 @@ set @@collation_connection=ucs2_czech_ci;
--echo # --echo #
--echo # Bug#33077 weight of supplementary characters is not 0xfffd --echo # Bug#33077 weight of supplementary characters is not 0xfffd
--echo # --echo #
#enable_after_fix MDEV-27871 select hex(weight_string(_utf8mb4 0xF0908080 /* U+10000 */ collate utf8mb4_unicode_ci)) as exp;
--disable_view_protocol
select hex(weight_string(_utf8mb4 0xF0908080 /* U+10000 */ collate utf8mb4_unicode_ci));
--enable_view_protocol
--echo # --echo #
--echo # Bug#53064 garbled data when using utf8_german2_ci collation --echo # Bug#53064 garbled data when using utf8_german2_ci collation

View File

@@ -2958,5 +2958,69 @@ HEX(OCT(a))
DROP TABLE t; DROP TABLE t;
SET NAMES utf8; 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 # End of 10.4 tests
# #

View File

@@ -1120,6 +1120,48 @@ SELECT HEX(OCT(a)) FROM t;
DROP TABLE t; DROP TABLE t;
SET NAMES utf8; 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 #
--echo # End of 10.4 tests --echo # End of 10.4 tests

View File

@@ -977,6 +977,20 @@ INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
ERROR 23000: Duplicate entry 'ß ' for key 'a' ERROR 23000: Duplicate entry 'ß ' for key 'a'
DROP TABLE t1; DROP TABLE t1;
EXECUTE IMMEDIATE REPLACE( EXECUTE IMMEDIATE REPLACE(
'CREATE TABLE t1 ( '
' a CHAR(20) COLLATE <COLLATION>,'
'UNIQUE(a(3)))',
'<COLLATION>', @@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 ( ' 'CREATE TABLE t1 ( '
' a CHAR(20) COLLATE <COLLATION>,' ' a CHAR(20) COLLATE <COLLATION>,'
'UNIQUE(a(3)) USING HASH)', 'UNIQUE(a(3)) USING HASH)',
@@ -1053,6 +1067,145 @@ INSERT INTO t1 VALUES ('ss ');
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/; INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
DROP TABLE t1; DROP TABLE t1;
SET DEFAULT_STORAGE_ENGINE=DEFAULT; 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 # End of 10.4 tests
# #

View File

@@ -68,6 +68,14 @@ SET DEFAULT_STORAGE_ENGINE=HEAP;
SET DEFAULT_STORAGE_ENGINE=DEFAULT; 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 #
--echo # End of 10.4 tests --echo # End of 10.4 tests
--echo # --echo #

View File

@@ -1,4 +1,3 @@
drop table if exists t1;
create table t1 (a char(10), tmsp timestamp); create table t1 (a char(10), tmsp timestamp);
insert into t1 set a = 1; insert into t1 set a = 1;
insert delayed into t1 set a = 2; 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 ERROR 42000: FUNCTION test.b does not exist
DROP TABLE t1; DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
DROP TABLE IF EXISTS t1,t2;
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'; SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`id` int(11) PRIMARY KEY auto_increment, `id` int(11) PRIMARY KEY auto_increment,
@@ -293,7 +291,6 @@ set global low_priority_updates = 1;
select @@global.low_priority_updates; select @@global.low_priority_updates;
@@global.low_priority_updates @@global.low_priority_updates
1 1
drop table if exists t1;
create table t1 (a int, b int); create table t1 (a int, b int);
insert into t1 values (1,1); insert into t1 values (1,1);
lock table t1 read; lock table t1 read;
@@ -322,7 +319,6 @@ set global low_priority_updates = @old_delayed_updates;
# #
# Bug #47682 strange behaviour of INSERT DELAYED # Bug #47682 strange behaviour of INSERT DELAYED
# #
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (f1 integer); CREATE TABLE t1 (f1 integer);
CREATE TABLE t2 (f1 integer); CREATE TABLE t2 (f1 integer);
FLUSH TABLES WITH READ LOCK; FLUSH TABLES WITH READ LOCK;
@@ -335,8 +331,6 @@ End of 5.1 tests
# #
# Bug #47274 assert in open_table on CREATE TABLE <already existing> # Bug #47274 assert in open_table on CREATE TABLE <already existing>
# #
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 ( f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1)); CREATE TABLE t1 ( f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1));
# The following CREATE TABLEs before gave an assert. # The following CREATE TABLEs before gave an assert.
INSERT DELAYED t1 VALUES (4); INSERT DELAYED t1 VALUES (4);
@@ -352,14 +346,12 @@ CREATE TABLE t2 (f1 INTEGER);
INSERT DELAYED t1 VALUES (7); INSERT DELAYED t1 VALUES (7);
CREATE TABLE t1 LIKE t2; CREATE TABLE t1 LIKE t2;
ERROR 42S01: Table 't1' already exists ERROR 42S01: Table 't1' already exists
DROP TABLE t2; DROP TABLE t2, t1;
DROP TABLE t1;
# #
# Test for bug #56251 "Deadlock with INSERT DELAYED and MERGE tables". # Test for bug #56251 "Deadlock with INSERT DELAYED and MERGE tables".
# #
connect con1,localhost,root,,; connect con1,localhost,root,,;
connection default; connection default;
drop table if exists t1, t2, tm;
create table t1(a int); create table t1(a int);
create table t2(a int); create table t2(a int);
create table tm(a int) engine=merge union=(t1, t2); create table tm(a int) engine=merge union=(t1, t2);

View File

@@ -21,9 +21,6 @@ select @@global.default_storage_engine in
("memory","myisam","archive","blackhole") as `TRUE`; ("memory","myisam","archive","blackhole") as `TRUE`;
enable_query_log; enable_query_log;
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a char(10), tmsp timestamp); create table t1 (a char(10), tmsp timestamp);
insert into t1 set a = 1; insert into t1 set a = 1;
insert delayed into t1 set a = 2; 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 # 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'; SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`id` int(11) PRIMARY KEY auto_increment, `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; set global low_priority_updates = 1;
select @@global.low_priority_updates; select @@global.low_priority_updates;
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int, b int); create table t1 (a int, b int);
insert into t1 values (1,1); insert into t1 values (1,1);
lock table t1 read; 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 # Bug #47682 strange behaviour of INSERT DELAYED
--echo # --echo #
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE TABLE t1 (f1 integer); CREATE TABLE t1 (f1 integer);
CREATE TABLE t2 (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 <already existing> --echo # Bug #47274 assert in open_table on CREATE TABLE <already existing>
--echo # --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)); CREATE TABLE t1 ( f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1));
--echo # The following CREATE TABLEs before gave an assert. --echo # The following CREATE TABLEs before gave an assert.
@@ -404,9 +386,7 @@ INSERT DELAYED t1 VALUES (7);
--error ER_TABLE_EXISTS_ERROR --error ER_TABLE_EXISTS_ERROR
CREATE TABLE t1 LIKE t2; CREATE TABLE t1 LIKE t2;
DROP TABLE t2; DROP TABLE t2, t1;
DROP TABLE t1;
# The following test is disabled as it fails randomly # The following test is disabled as it fails randomly
if (0) if (0)
@@ -420,10 +400,6 @@ if (0)
--disable_ps_protocol --disable_ps_protocol
--disable_view_protocol --disable_view_protocol
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE TABLE t1 (a INT); CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT); CREATE TABLE t2 (a INT);
CREATE TABLE t3 (a INT); CREATE TABLE t3 (a INT);
@@ -577,9 +553,6 @@ DROP TABLE t1, t2, t3;
--disable_view_protocol --disable_view_protocol
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
connection default; connection default;
--disable_warnings
drop table if exists t1, t2, tm;
--enable_warnings
create table t1(a int); create table t1(a int);
create table t2(a int); create table t2(a int);
create table tm(a int) engine=merge union=(t1, t2); create table tm(a int) engine=merge union=(t1, t2);

View File

@@ -610,4 +610,49 @@ c1 c2 c3
2 1 4 2 1 4
2 2 5 2 2 5
drop table t1; 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 End of 11.1 tests

View File

@@ -667,4 +667,31 @@ select *from t1;
drop table 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 --echo End of 11.1 tests

View File

@@ -16,6 +16,7 @@ analyze table t1;
--echo # Delete with limit (quick select - range acces) --echo # Delete with limit (quick select - range acces)
--echo # --echo #
--disable_view_protocol
start transaction; start transaction;
--enable_info --enable_info
delete from t1 where (select count(*) from t1 b where b.c1=t1.c1) = 500 limit 1; delete from t1 where (select count(*) from t1 b where b.c1=t1.c1) = 500 limit 1;
@@ -111,6 +112,7 @@ rollback;
start transaction; 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; 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; rollback;
--enable_view_protocol
drop view v1; drop view v1;
drop table t1; drop table t1;

View File

@@ -22791,6 +22791,121 @@ a SUBQ
4 1=11373 4 1=11373
5 1=11612 5 1=11612
drop table t1,t2,t3; 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 <derived2> 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 # End of 10.4 tests
# #
# MDEV-28958: condition pushable into view after simplification # MDEV-28958: condition pushable into view after simplification

View File

@@ -4214,6 +4214,94 @@ eval $q;
drop table t1,t2,t3; 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 # End of 10.4 tests
--echo # --echo #

View File

@@ -891,5 +891,20 @@ SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v);
a b a b
DROP VIEW v; DROP VIEW v;
DROP TABLE t1, t2, t3; 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 # End of 10.4 tests
SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent;

View File

@@ -499,6 +499,24 @@ SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v);
DROP VIEW v; DROP VIEW v;
DROP TABLE t1, t2, t3; 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 --echo # End of 10.4 tests
SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent;

Some files were not shown because too many files have changed in this diff Show More