Manual merge of mysql-next-mr-runtime upstream.
This commit is contained in:
commit
ecb6228c62
@ -62,6 +62,9 @@ enum options_client
|
|||||||
OPT_MYSQL_NUMBER_OF_QUERY,
|
OPT_MYSQL_NUMBER_OF_QUERY,
|
||||||
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
|
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
|
||||||
OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
|
OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
|
||||||
|
OPT_MYSQLDUMP_SLAVE_APPLY,
|
||||||
|
OPT_MYSQLDUMP_SLAVE_DATA,
|
||||||
|
OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
|
||||||
OPT_SLAP_CSV, OPT_SLAP_CREATE_STRING,
|
OPT_SLAP_CSV, OPT_SLAP_CREATE_STRING,
|
||||||
OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
|
OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
|
||||||
OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
|
OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
|
||||||
@ -78,6 +81,7 @@ enum options_client
|
|||||||
OPT_SLAP_DETACH,
|
OPT_SLAP_DETACH,
|
||||||
OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID,
|
OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID,
|
||||||
OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT,
|
OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT,
|
||||||
|
OPT_AUTO_VERTICAL_OUTPUT,
|
||||||
OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
|
OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
|
||||||
OPT_WRITE_BINLOG, OPT_DUMP_DATE,
|
OPT_WRITE_BINLOG, OPT_DUMP_DATE,
|
||||||
OPT_INIT_COMMAND,
|
OPT_INIT_COMMAND,
|
||||||
|
@ -143,6 +143,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0,
|
|||||||
tty_password= 0, opt_nobeep=0, opt_reconnect=1,
|
tty_password= 0, opt_nobeep=0, opt_reconnect=1,
|
||||||
opt_secure_auth= 0,
|
opt_secure_auth= 0,
|
||||||
default_pager_set= 0, opt_sigint_ignore= 0,
|
default_pager_set= 0, opt_sigint_ignore= 0,
|
||||||
|
auto_vertical_output= 0,
|
||||||
show_warnings= 0, executing_query= 0, interrupted_query= 0,
|
show_warnings= 0, executing_query= 0, interrupted_query= 0,
|
||||||
ignore_spaces= 0;
|
ignore_spaces= 0;
|
||||||
static my_bool debug_info_flag, debug_check_flag;
|
static my_bool debug_info_flag, debug_check_flag;
|
||||||
@ -185,6 +186,7 @@ static MEM_ROOT hash_mem_root;
|
|||||||
static uint prompt_counter;
|
static uint prompt_counter;
|
||||||
static char delimiter[16]= DEFAULT_DELIMITER;
|
static char delimiter[16]= DEFAULT_DELIMITER;
|
||||||
static uint delimiter_length= 1;
|
static uint delimiter_length= 1;
|
||||||
|
unsigned short terminal_width= 80;
|
||||||
|
|
||||||
#ifdef HAVE_SMEM
|
#ifdef HAVE_SMEM
|
||||||
static char *shared_memory_base_name=0;
|
static char *shared_memory_base_name=0;
|
||||||
@ -238,6 +240,8 @@ static const char* construct_prompt();
|
|||||||
static char *get_arg(char *line, my_bool get_next_arg);
|
static char *get_arg(char *line, my_bool get_next_arg);
|
||||||
static void init_username();
|
static void init_username();
|
||||||
static void add_int_to_prompt(int toadd);
|
static void add_int_to_prompt(int toadd);
|
||||||
|
static int get_result_width(MYSQL_RES *res);
|
||||||
|
static int get_field_disp_length(MYSQL_FIELD * field);
|
||||||
|
|
||||||
/* A structure which contains information on the commands this program
|
/* A structure which contains information on the commands this program
|
||||||
can understand. */
|
can understand. */
|
||||||
@ -1065,6 +1069,10 @@ static void mysql_end_timer(ulong start_time,char *buff);
|
|||||||
static void nice_time(double sec,char *buff,bool part_second);
|
static void nice_time(double sec,char *buff,bool part_second);
|
||||||
extern "C" sig_handler mysql_end(int sig);
|
extern "C" sig_handler mysql_end(int sig);
|
||||||
extern "C" sig_handler handle_sigint(int sig);
|
extern "C" sig_handler handle_sigint(int sig);
|
||||||
|
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
|
||||||
|
static sig_handler window_resize(int sig);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
int main(int argc,char *argv[])
|
||||||
{
|
{
|
||||||
@ -1144,8 +1152,8 @@ int main(int argc,char *argv[])
|
|||||||
if (sql_connect(current_host,current_db,current_user,opt_password,
|
if (sql_connect(current_host,current_db,current_user,opt_password,
|
||||||
opt_silent))
|
opt_silent))
|
||||||
{
|
{
|
||||||
quick=1; // Avoid history
|
quick= 1; // Avoid history
|
||||||
status.exit_status=1;
|
status.exit_status= 1;
|
||||||
mysql_end(-1);
|
mysql_end(-1);
|
||||||
}
|
}
|
||||||
if (!status.batch)
|
if (!status.batch)
|
||||||
@ -1157,6 +1165,13 @@ int main(int argc,char *argv[])
|
|||||||
signal(SIGINT, handle_sigint); // Catch SIGINT to clean up
|
signal(SIGINT, handle_sigint); // Catch SIGINT to clean up
|
||||||
signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up
|
signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up
|
||||||
|
|
||||||
|
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
|
||||||
|
/* Readline will call this if it installs a handler */
|
||||||
|
signal(SIGWINCH, window_resize);
|
||||||
|
/* call the SIGWINCH handler to get the default term width */
|
||||||
|
window_resize(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
|
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
|
||||||
INFO_INFO);
|
INFO_INFO);
|
||||||
sprintf((char*) glob_buffer.ptr(),
|
sprintf((char*) glob_buffer.ptr(),
|
||||||
@ -1329,6 +1344,16 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
|
||||||
|
sig_handler window_resize(int sig)
|
||||||
|
{
|
||||||
|
struct winsize window_size;
|
||||||
|
|
||||||
|
if (ioctl(fileno(stdin), TIOCGWINSZ, &window_size) == 0)
|
||||||
|
terminal_width= window_size.ws_col;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct my_option my_long_options[] =
|
static struct my_option my_long_options[] =
|
||||||
{
|
{
|
||||||
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
|
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
|
||||||
@ -1346,6 +1371,9 @@ static struct my_option my_long_options[] =
|
|||||||
{"no-auto-rehash", 'A',
|
{"no-auto-rehash", 'A',
|
||||||
"No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
|
"No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
|
||||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
|
{"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
|
||||||
|
"Automatically switch to vertical output mode if the result is wider than the terminal width.",
|
||||||
|
(uchar**) &auto_vertical_output, (uchar**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"batch", 'B',
|
{"batch", 'B',
|
||||||
"Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
"Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"character-sets-dir", OPT_CHARSETS_DIR,
|
{"character-sets-dir", OPT_CHARSETS_DIR,
|
||||||
@ -3052,7 +3080,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
|
|||||||
print_table_data_html(result);
|
print_table_data_html(result);
|
||||||
else if (opt_xml)
|
else if (opt_xml)
|
||||||
print_table_data_xml(result);
|
print_table_data_xml(result);
|
||||||
else if (vertical)
|
else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
|
||||||
print_table_data_vertically(result);
|
print_table_data_vertically(result);
|
||||||
else if (opt_silent && verbose <= 2 && !output_tables)
|
else if (opt_silent && verbose <= 2 && !output_tables)
|
||||||
print_tab_data(result);
|
print_tab_data(result);
|
||||||
@ -3383,6 +3411,65 @@ print_table_data(MYSQL_RES *result)
|
|||||||
my_afree((uchar*) num_flag);
|
my_afree((uchar*) num_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the length of a field after it would be rendered into text.
|
||||||
|
|
||||||
|
This doesn't know or care about multibyte characters. Assume we're
|
||||||
|
using such a charset. We can't know that all of the upcoming rows
|
||||||
|
for this column will have bytes that each render into some fraction
|
||||||
|
of a character. It's at least possible that a row has bytes that
|
||||||
|
all render into one character each, and so the maximum length is
|
||||||
|
still the number of bytes. (Assumption 1: This can't be better
|
||||||
|
because we can never know the number of characters that the DB is
|
||||||
|
going to send -- only the number of bytes. 2: Chars <= Bytes.)
|
||||||
|
|
||||||
|
@param field Pointer to a field to be inspected
|
||||||
|
|
||||||
|
@returns number of character positions to be used, at most
|
||||||
|
*/
|
||||||
|
static int get_field_disp_length(MYSQL_FIELD *field)
|
||||||
|
{
|
||||||
|
uint length= column_names ? field->name_length : 0;
|
||||||
|
|
||||||
|
if (quick)
|
||||||
|
length= max(length, field->length);
|
||||||
|
else
|
||||||
|
length= max(length, field->max_length);
|
||||||
|
|
||||||
|
if (length < 4 && !IS_NOT_NULL(field->flags))
|
||||||
|
length= 4; /* Room for "NULL" */
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
For a new result, return the max number of characters that any
|
||||||
|
upcoming row may return.
|
||||||
|
|
||||||
|
@param result Pointer to the result to judge
|
||||||
|
|
||||||
|
@returns The max number of characters in any row of this result
|
||||||
|
*/
|
||||||
|
static int get_result_width(MYSQL_RES *result)
|
||||||
|
{
|
||||||
|
unsigned int len= 0;
|
||||||
|
MYSQL_FIELD *field;
|
||||||
|
MYSQL_FIELD_OFFSET offset;
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
offset= mysql_field_tell(result);
|
||||||
|
DBUG_ASSERT(offset == 0);
|
||||||
|
#else
|
||||||
|
offset= 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while ((field= mysql_fetch_field(result)) != NULL)
|
||||||
|
len+= get_field_disp_length(field) + 3; /* plus bar, space, & final space */
|
||||||
|
|
||||||
|
(void) mysql_field_seek(result, offset);
|
||||||
|
|
||||||
|
return len + 1; /* plus final bar. */
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tee_print_sized_data(const char *data, unsigned int data_length, unsigned int total_bytes_to_send, bool right_justified)
|
tee_print_sized_data(const char *data, unsigned int data_length, unsigned int total_bytes_to_send, bool right_justified)
|
||||||
|
@ -900,23 +900,38 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
{
|
{
|
||||||
char buff[128],crypted_pw[64];
|
char buff[128],crypted_pw[64];
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
|
char *typed_password= NULL, *verified= NULL;
|
||||||
/* Do initialization the same way as we do in mysqld */
|
/* Do initialization the same way as we do in mysqld */
|
||||||
start_time=time((time_t*) 0);
|
start_time=time((time_t*) 0);
|
||||||
randominit(&rand_st,(ulong) start_time,(ulong) start_time/2);
|
randominit(&rand_st,(ulong) start_time,(ulong) start_time/2);
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 1)
|
||||||
{
|
{
|
||||||
my_printf_error(0, "Too few arguments to change password", error_flags);
|
my_printf_error(0, "Too few arguments to change password", error_flags);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (argv[1][0])
|
else if (argc == 1)
|
||||||
|
{
|
||||||
|
/* prompt for password */
|
||||||
|
typed_password= get_tty_password("New password: ");
|
||||||
|
verified= get_tty_password("Confirm new password: ");
|
||||||
|
if (strcmp(typed_password, verified) != 0)
|
||||||
|
{
|
||||||
|
my_printf_error(0,"Passwords don't match",MYF(ME_BELL));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
typed_password= argv[1];
|
||||||
|
|
||||||
|
if (typed_password[0])
|
||||||
{
|
{
|
||||||
char *pw= argv[1];
|
|
||||||
bool old= (find_type(argv[0], &command_typelib, 2) ==
|
bool old= (find_type(argv[0], &command_typelib, 2) ==
|
||||||
ADMIN_OLD_PASSWORD);
|
ADMIN_OLD_PASSWORD);
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
uint pw_len= (uint) strlen(pw);
|
size_t pw_len= strlen(typed_password);
|
||||||
if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'')
|
if (pw_len > 1 && typed_password[0] == '\'' &&
|
||||||
|
typed_password[pw_len-1] == '\'')
|
||||||
printf("Warning: single quotes were not trimmed from the password by"
|
printf("Warning: single quotes were not trimmed from the password by"
|
||||||
" your command\nline client, as you might have expected.\n");
|
" your command\nline client, as you might have expected.\n");
|
||||||
#endif
|
#endif
|
||||||
@ -954,9 +969,9 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (old)
|
if (old)
|
||||||
make_scrambled_password_323(crypted_pw, pw);
|
make_scrambled_password_323(crypted_pw, typed_password);
|
||||||
else
|
else
|
||||||
make_scrambled_password(crypted_pw, pw);
|
make_scrambled_password(crypted_pw, typed_password);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
crypted_pw[0]=0; /* No password */
|
crypted_pw[0]=0; /* No password */
|
||||||
@ -991,6 +1006,12 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* free up memory from prompted password */
|
||||||
|
if (typed_password != argv[1])
|
||||||
|
{
|
||||||
|
my_free(typed_password,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
my_free(verified,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
}
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1082,8 +1103,8 @@ static void usage(void)
|
|||||||
kill id,id,... Kill mysql threads");
|
kill id,id,... Kill mysql threads");
|
||||||
#if MYSQL_VERSION_ID >= 32200
|
#if MYSQL_VERSION_ID >= 32200
|
||||||
puts("\
|
puts("\
|
||||||
password new-password Change old password to new-password, MySQL 4.1 hashing.\n\
|
password [new-password] Change old password to new-password in current format\n\
|
||||||
old-password new-password Change old password to new-password in old format.\n");
|
old-password [new-password] Change old password to new-password in old format");
|
||||||
#endif
|
#endif
|
||||||
puts("\
|
puts("\
|
||||||
ping Check if mysqld is alive\n\
|
ping Check if mysqld is alive\n\
|
||||||
|
@ -128,7 +128,7 @@ static struct my_option my_long_options[] =
|
|||||||
"Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
|
"Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
|
||||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"write-binlog", OPT_WRITE_BINLOG,
|
{"write-binlog", OPT_WRITE_BINLOG,
|
||||||
"Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Enabled by default; use --skip-write-binlog when commands should not be sent to replication slaves.",
|
"Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Use --skip-write-binlog when commands should not be sent to replication slaves.",
|
||||||
(uchar**) &opt_write_binlog, (uchar**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
|
(uchar**) &opt_write_binlog, (uchar**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
|
||||||
1, 0, 0, 0, 0, 0},
|
1, 0, 0, 0, 0, 0},
|
||||||
{"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
|
{"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
|
||||||
|
@ -98,6 +98,8 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
|
|||||||
opt_complete_insert= 0, opt_drop_database= 0,
|
opt_complete_insert= 0, opt_drop_database= 0,
|
||||||
opt_replace_into= 0,
|
opt_replace_into= 0,
|
||||||
opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
|
opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
|
||||||
|
opt_slave_apply= 0,
|
||||||
|
opt_include_master_host_port= 0,
|
||||||
opt_events= 0,
|
opt_events= 0,
|
||||||
opt_alltspcs=0, opt_notspcs= 0;
|
opt_alltspcs=0, opt_notspcs= 0;
|
||||||
static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
|
static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
|
||||||
@ -118,7 +120,10 @@ static my_bool server_supports_switching_charsets= TRUE;
|
|||||||
static ulong opt_compatible_mode= 0;
|
static ulong opt_compatible_mode= 0;
|
||||||
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
|
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
|
||||||
#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
|
#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
|
||||||
|
#define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
|
||||||
|
#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
|
||||||
static uint opt_mysql_port= 0, opt_master_data;
|
static uint opt_mysql_port= 0, opt_master_data;
|
||||||
|
static uint opt_slave_data;
|
||||||
static uint my_end_arg;
|
static uint my_end_arg;
|
||||||
static char * opt_mysql_unix_port=0;
|
static char * opt_mysql_unix_port=0;
|
||||||
static int first_error=0;
|
static int first_error=0;
|
||||||
@ -206,6 +211,10 @@ static struct my_option my_long_options[] =
|
|||||||
{"allow-keywords", OPT_KEYWORDS,
|
{"allow-keywords", OPT_KEYWORDS,
|
||||||
"Allow creation of column names that are keywords.", (uchar**) &opt_keywords,
|
"Allow creation of column names that are keywords.", (uchar**) &opt_keywords,
|
||||||
(uchar**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
(uchar**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
|
{"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY,
|
||||||
|
"Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
|
||||||
|
(uchar**) &opt_slave_apply, (uchar**) &opt_slave_apply, 0, GET_BOOL, NO_ARG,
|
||||||
|
0, 0, 0, 0, 0, 0},
|
||||||
#ifdef __NETWARE__
|
#ifdef __NETWARE__
|
||||||
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
|
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
|
||||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
@ -264,6 +273,19 @@ static struct my_option my_long_options[] =
|
|||||||
{"disable-keys", 'K',
|
{"disable-keys", 'K',
|
||||||
"'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (uchar**) &opt_disable_keys,
|
"'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (uchar**) &opt_disable_keys,
|
||||||
(uchar**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
|
(uchar**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
|
||||||
|
{"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
|
||||||
|
"This causes the binary log position and filename of the master to be "
|
||||||
|
"appended to the dumped data output. Setting the value to 1, will print"
|
||||||
|
"it as a CHANGE MASTER command in the dumped data output; if equal"
|
||||||
|
" to 2, that command will be prefixed with a comment symbol. "
|
||||||
|
"This option will turn --lock-all-tables on, unless "
|
||||||
|
"--single-transaction is specified too (in which case a "
|
||||||
|
"global read lock is only taken a short time at the beginning of the dump "
|
||||||
|
"- don't forget to read about --single-transaction below). In all cases "
|
||||||
|
"any action on logs will happen at the exact moment of the dump."
|
||||||
|
"Option automatically turns --lock-tables off.",
|
||||||
|
(uchar**) &opt_slave_data, (uchar**) &opt_slave_data, 0,
|
||||||
|
GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
|
||||||
{"events", 'E', "Dump events.",
|
{"events", 'E', "Dump events.",
|
||||||
(uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL,
|
(uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL,
|
||||||
NO_ARG, 0, 0, 0, 0, 0, 0},
|
NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
@ -317,6 +339,12 @@ static struct my_option my_long_options[] =
|
|||||||
"use the directive multiple times, once for each table. Each table must "
|
"use the directive multiple times, once for each table. Each table must "
|
||||||
"be specified with both database and table names, e.g. --ignore-table=database.table",
|
"be specified with both database and table names, e.g. --ignore-table=database.table",
|
||||||
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
|
{"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
|
||||||
|
"Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
|
||||||
|
(uchar**) &opt_include_master_host_port,
|
||||||
|
(uchar**) &opt_include_master_host_port,
|
||||||
|
0, GET_BOOL, NO_ARG,
|
||||||
|
0, 0, 0, 0, 0, 0},
|
||||||
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
|
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
|
||||||
(uchar**) &opt_ignore, (uchar**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
|
(uchar**) &opt_ignore, (uchar**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
|
||||||
0, 0},
|
0, 0},
|
||||||
@ -402,7 +430,7 @@ static struct my_option my_long_options[] =
|
|||||||
(uchar**) &opt_routines, (uchar**) &opt_routines, 0, GET_BOOL,
|
(uchar**) &opt_routines, (uchar**) &opt_routines, 0, GET_BOOL,
|
||||||
NO_ARG, 0, 0, 0, 0, 0, 0},
|
NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"set-charset", OPT_SET_CHARSET,
|
{"set-charset", OPT_SET_CHARSET,
|
||||||
"Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset.",
|
"Add 'SET NAMES default_character_set' to the output.",
|
||||||
(uchar**) &opt_set_charset, (uchar**) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
|
(uchar**) &opt_set_charset, (uchar**) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
|
||||||
0, 0, 0, 0, 0},
|
0, 0, 0, 0, 0},
|
||||||
{"set-variable", 'O',
|
{"set-variable", 'O',
|
||||||
@ -764,6 +792,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
if (!argument) /* work like in old versions */
|
if (!argument) /* work like in old versions */
|
||||||
opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
|
opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
|
||||||
break;
|
break;
|
||||||
|
case (int) OPT_MYSQLDUMP_SLAVE_DATA:
|
||||||
|
if (!argument) /* work like in old versions */
|
||||||
|
opt_slave_data= MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL;
|
||||||
|
break;
|
||||||
case (int) OPT_OPTIMIZE:
|
case (int) OPT_OPTIMIZE:
|
||||||
extended_insert= opt_drop= opt_lock= quick= create_options=
|
extended_insert= opt_drop= opt_lock= quick= create_options=
|
||||||
opt_disable_keys= lock_tables= opt_set_charset= 1;
|
opt_disable_keys= lock_tables= opt_set_charset= 1;
|
||||||
@ -896,6 +928,14 @@ static int get_options(int *argc, char ***argv)
|
|||||||
return(EX_USAGE);
|
return(EX_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We don't delete master logs if slave data option */
|
||||||
|
if (opt_slave_data)
|
||||||
|
{
|
||||||
|
opt_lock_all_tables= !opt_single_transaction;
|
||||||
|
opt_master_data= 0;
|
||||||
|
opt_delete_master_logs= 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ensure consistency of the set of binlog & locking options */
|
/* Ensure consistency of the set of binlog & locking options */
|
||||||
if (opt_delete_master_logs && !opt_master_data)
|
if (opt_delete_master_logs && !opt_master_data)
|
||||||
opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
|
opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
|
||||||
@ -906,7 +946,10 @@ static int get_options(int *argc, char ***argv)
|
|||||||
return(EX_USAGE);
|
return(EX_USAGE);
|
||||||
}
|
}
|
||||||
if (opt_master_data)
|
if (opt_master_data)
|
||||||
|
{
|
||||||
opt_lock_all_tables= !opt_single_transaction;
|
opt_lock_all_tables= !opt_single_transaction;
|
||||||
|
opt_slave_data= 0;
|
||||||
|
}
|
||||||
if (opt_single_transaction || opt_lock_all_tables)
|
if (opt_single_transaction || opt_lock_all_tables)
|
||||||
lock_tables= 0;
|
lock_tables= 0;
|
||||||
if (enclosed && opt_enclosed)
|
if (enclosed && opt_enclosed)
|
||||||
@ -4333,6 +4376,130 @@ static int do_show_master_status(MYSQL *mysql_con)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int do_stop_slave_sql(MYSQL *mysql_con)
|
||||||
|
{
|
||||||
|
MYSQL_RES *slave;
|
||||||
|
/* We need to check if the slave sql is running in the first place */
|
||||||
|
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
|
||||||
|
return(1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MYSQL_ROW row= mysql_fetch_row(slave);
|
||||||
|
if (row && row[11])
|
||||||
|
{
|
||||||
|
/* if SLAVE SQL is not running, we don't stop it */
|
||||||
|
if (!strcmp(row[11],"No"))
|
||||||
|
{
|
||||||
|
mysql_free_result(slave);
|
||||||
|
/* Silently assume that they don't have the slave running */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mysql_free_result(slave);
|
||||||
|
|
||||||
|
/* now, stop slave if running */
|
||||||
|
if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add_stop_slave(void)
|
||||||
|
{
|
||||||
|
if (opt_comments)
|
||||||
|
fprintf(md_result_file,
|
||||||
|
"\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
|
||||||
|
fprintf(md_result_file, "STOP SLAVE;\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add_slave_statements(void)
|
||||||
|
{
|
||||||
|
if (opt_comments)
|
||||||
|
fprintf(md_result_file,
|
||||||
|
"\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
|
||||||
|
fprintf(md_result_file, "START SLAVE;\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_show_slave_status(MYSQL *mysql_con)
|
||||||
|
{
|
||||||
|
MYSQL_RES *slave;
|
||||||
|
const char *comment_prefix=
|
||||||
|
(opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
|
||||||
|
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
|
||||||
|
{
|
||||||
|
if (!ignore_errors)
|
||||||
|
{
|
||||||
|
/* SHOW SLAVE STATUS reports nothing and --force is not enabled */
|
||||||
|
my_printf_error(0, "Error: Slave not set up", MYF(0));
|
||||||
|
}
|
||||||
|
mysql_free_result(slave);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MYSQL_ROW row= mysql_fetch_row(slave);
|
||||||
|
if (row && row[9] && row[21])
|
||||||
|
{
|
||||||
|
/* SHOW MASTER STATUS reports file and position */
|
||||||
|
if (opt_comments)
|
||||||
|
fprintf(md_result_file,
|
||||||
|
"\n--\n-- Position to start replication or point-in-time "
|
||||||
|
"recovery from (the master of this slave)\n--\n\n");
|
||||||
|
|
||||||
|
fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
|
||||||
|
|
||||||
|
if (opt_include_master_host_port)
|
||||||
|
{
|
||||||
|
if (row[1])
|
||||||
|
fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
|
||||||
|
if (row[3])
|
||||||
|
fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
|
||||||
|
}
|
||||||
|
fprintf(md_result_file,
|
||||||
|
"MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
|
||||||
|
|
||||||
|
check_io(md_result_file);
|
||||||
|
}
|
||||||
|
mysql_free_result(slave);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_start_slave_sql(MYSQL *mysql_con)
|
||||||
|
{
|
||||||
|
MYSQL_RES *slave;
|
||||||
|
/* We need to check if the slave sql is stopped in the first place */
|
||||||
|
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
|
||||||
|
return(1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MYSQL_ROW row= mysql_fetch_row(slave);
|
||||||
|
if (row && row[11])
|
||||||
|
{
|
||||||
|
/* if SLAVE SQL is not running, we don't start it */
|
||||||
|
if (!strcmp(row[11],"Yes"))
|
||||||
|
{
|
||||||
|
mysql_free_result(slave);
|
||||||
|
/* Silently assume that they don't have the slave running */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mysql_free_result(slave);
|
||||||
|
|
||||||
|
/* now, start slave if stopped */
|
||||||
|
if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE"))
|
||||||
|
{
|
||||||
|
my_printf_error(0, "Error: Unable to start slave", MYF(0));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int do_flush_tables_read_lock(MYSQL *mysql_con)
|
static int do_flush_tables_read_lock(MYSQL *mysql_con)
|
||||||
{
|
{
|
||||||
@ -4995,6 +5162,9 @@ int main(int argc, char **argv)
|
|||||||
if (!path)
|
if (!path)
|
||||||
write_header(md_result_file, *argv);
|
write_header(md_result_file, *argv);
|
||||||
|
|
||||||
|
if (opt_slave_data && do_stop_slave_sql(mysql))
|
||||||
|
goto err;
|
||||||
|
|
||||||
if ((opt_lock_all_tables || opt_master_data) &&
|
if ((opt_lock_all_tables || opt_master_data) &&
|
||||||
do_flush_tables_read_lock(mysql))
|
do_flush_tables_read_lock(mysql))
|
||||||
goto err;
|
goto err;
|
||||||
@ -5013,8 +5183,13 @@ int main(int argc, char **argv)
|
|||||||
goto err;
|
goto err;
|
||||||
flush_logs= 0; /* not anymore; that would not be sensible */
|
flush_logs= 0; /* not anymore; that would not be sensible */
|
||||||
}
|
}
|
||||||
|
/* Add 'STOP SLAVE to beginning of dump */
|
||||||
|
if (opt_slave_apply && add_stop_slave())
|
||||||
|
goto err;
|
||||||
if (opt_master_data && do_show_master_status(mysql))
|
if (opt_master_data && do_show_master_status(mysql))
|
||||||
goto err;
|
goto err;
|
||||||
|
if (opt_slave_data && do_show_slave_status(mysql))
|
||||||
|
goto err;
|
||||||
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
|
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -5042,6 +5217,14 @@ int main(int argc, char **argv)
|
|||||||
dump_databases(argv);
|
dump_databases(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if --dump-slave , start the slave sql thread */
|
||||||
|
if (opt_slave_data && do_start_slave_sql(mysql))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* add 'START SLAVE' to end of dump */
|
||||||
|
if (opt_slave_apply && add_slave_statements())
|
||||||
|
goto err;
|
||||||
|
|
||||||
/* ensure dumped data flushed */
|
/* ensure dumped data flushed */
|
||||||
if (md_result_file && fflush(md_result_file))
|
if (md_result_file && fflush(md_result_file))
|
||||||
{
|
{
|
||||||
|
@ -75,7 +75,8 @@
|
|||||||
enum {
|
enum {
|
||||||
OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
|
OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
|
||||||
OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
|
OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
|
||||||
OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES
|
OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES,
|
||||||
|
OPT_RESULT_FORMAT_VERSION
|
||||||
};
|
};
|
||||||
|
|
||||||
static int record= 0, opt_sleep= -1;
|
static int record= 0, opt_sleep= -1;
|
||||||
@ -88,6 +89,7 @@ const char *opt_logdir= "";
|
|||||||
const char *opt_include= 0, *opt_charsets_dir;
|
const char *opt_include= 0, *opt_charsets_dir;
|
||||||
static int opt_port= 0;
|
static int opt_port= 0;
|
||||||
static int opt_max_connect_retries;
|
static int opt_max_connect_retries;
|
||||||
|
static int opt_result_format_version;
|
||||||
static my_bool opt_compress= 0, silent= 0, verbose= 0;
|
static my_bool opt_compress= 0, silent= 0, verbose= 0;
|
||||||
static my_bool debug_info_flag= 0, debug_check_flag= 0;
|
static my_bool debug_info_flag= 0, debug_check_flag= 0;
|
||||||
static my_bool tty_password= 0;
|
static my_bool tty_password= 0;
|
||||||
@ -284,11 +286,12 @@ enum enum_commands {
|
|||||||
Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
|
Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
|
||||||
Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
|
Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
|
||||||
Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER,
|
Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER,
|
||||||
|
Q_RESULT_FORMAT_VERSION,
|
||||||
Q_MOVE_FILE, Q_SEND_EVAL,
|
Q_MOVE_FILE, Q_SEND_EVAL,
|
||||||
|
|
||||||
Q_UNKNOWN, /* Unknown command. */
|
Q_UNKNOWN, /* Unknown command. */
|
||||||
Q_COMMENT, /* Comments, ignored. */
|
Q_COMMENT, /* Comments, ignored. */
|
||||||
Q_COMMENT_WITH_COMMAND
|
Q_COMMENT_WITH_COMMAND,
|
||||||
|
Q_EMPTY_LINE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -378,6 +381,7 @@ const char *command_names[]=
|
|||||||
"list_files_append_file",
|
"list_files_append_file",
|
||||||
"send_shutdown",
|
"send_shutdown",
|
||||||
"shutdown_server",
|
"shutdown_server",
|
||||||
|
"result_format",
|
||||||
"move_file",
|
"move_file",
|
||||||
"send_eval",
|
"send_eval",
|
||||||
|
|
||||||
@ -2193,6 +2197,59 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_result_format_version(ulong new_version)
|
||||||
|
{
|
||||||
|
switch (new_version){
|
||||||
|
case 1:
|
||||||
|
/* The first format */
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* New format that also writes comments and empty lines
|
||||||
|
from test file to result */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("Version format %lu has not yet been implemented", new_version);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
opt_result_format_version= new_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set the result format version to use when generating
|
||||||
|
the .result file
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_result_format_version(struct st_command *command)
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
static DYNAMIC_STRING ds_version;
|
||||||
|
const struct command_arg result_format_args[] = {
|
||||||
|
"version", ARG_STRING, TRUE, &ds_version, "Version to use",
|
||||||
|
};
|
||||||
|
|
||||||
|
DBUG_ENTER("do_result_format_version");
|
||||||
|
|
||||||
|
check_command_args(command, command->first_argument,
|
||||||
|
result_format_args,
|
||||||
|
sizeof(result_format_args)/sizeof(struct command_arg),
|
||||||
|
',');
|
||||||
|
|
||||||
|
/* Convert version number to int */
|
||||||
|
if (!str2int(ds_version.str, 10, (long) 0, (long) INT_MAX, &version))
|
||||||
|
die("Invalid version number: '%s'", ds_version.str);
|
||||||
|
|
||||||
|
set_result_format_version(version);
|
||||||
|
|
||||||
|
dynstr_append(&ds_res, "result_format: ");
|
||||||
|
dynstr_append_mem(&ds_res, ds_version.str, ds_version.length);
|
||||||
|
dynstr_append(&ds_res, "\n");
|
||||||
|
dynstr_free(&ds_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set variable from the result of a field in a query
|
Set variable from the result of a field in a query
|
||||||
|
|
||||||
@ -5273,7 +5330,7 @@ my_bool end_of_query(int c)
|
|||||||
|
|
||||||
int read_line(char *buf, int size)
|
int read_line(char *buf, int size)
|
||||||
{
|
{
|
||||||
char c, UNINIT_VAR(last_quote);
|
char c, UNINIT_VAR(last_quote), last_char= 0;
|
||||||
char *p= buf, *buf_end= buf + size - 1;
|
char *p= buf, *buf_end= buf + size - 1;
|
||||||
int skip_char= 0;
|
int skip_char= 0;
|
||||||
enum {R_NORMAL, R_Q, R_SLASH_IN_Q,
|
enum {R_NORMAL, R_Q, R_SLASH_IN_Q,
|
||||||
@ -5371,14 +5428,24 @@ int read_line(char *buf, int size)
|
|||||||
}
|
}
|
||||||
else if (my_isspace(charset_info, c))
|
else if (my_isspace(charset_info, c))
|
||||||
{
|
{
|
||||||
/* Skip all space at begining of line */
|
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{
|
{
|
||||||
|
if (last_char == '\n')
|
||||||
|
{
|
||||||
|
/* Two new lines in a row, return empty line */
|
||||||
|
DBUG_PRINT("info", ("Found two new lines in a row"));
|
||||||
|
*p++= c;
|
||||||
|
*p= 0;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Query hasn't started yet */
|
/* Query hasn't started yet */
|
||||||
start_lineno= cur_file->lineno;
|
start_lineno= cur_file->lineno;
|
||||||
DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d",
|
DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d",
|
||||||
start_lineno));
|
start_lineno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip all space at begining of line */
|
||||||
skip_char= 1;
|
skip_char= 1;
|
||||||
}
|
}
|
||||||
else if (end_of_query(c))
|
else if (end_of_query(c))
|
||||||
@ -5419,6 +5486,8 @@ int read_line(char *buf, int size)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_char= c;
|
||||||
|
|
||||||
if (!skip_char)
|
if (!skip_char)
|
||||||
{
|
{
|
||||||
/* Could be a multibyte character */
|
/* Could be a multibyte character */
|
||||||
@ -5628,9 +5697,10 @@ int read_command(struct st_command** command_ptr)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_to_format_v1(read_command_buf);
|
if (opt_result_format_version == 1)
|
||||||
|
convert_to_format_v1(read_command_buf);
|
||||||
|
|
||||||
DBUG_PRINT("info", ("query: %s", read_command_buf));
|
DBUG_PRINT("info", ("query: '%s'", read_command_buf));
|
||||||
if (*p == '#')
|
if (*p == '#')
|
||||||
{
|
{
|
||||||
command->type= Q_COMMENT;
|
command->type= Q_COMMENT;
|
||||||
@ -5640,6 +5710,10 @@ int read_command(struct st_command** command_ptr)
|
|||||||
command->type= Q_COMMENT_WITH_COMMAND;
|
command->type= Q_COMMENT_WITH_COMMAND;
|
||||||
p+= 2; /* Skip past -- */
|
p+= 2; /* Skip past -- */
|
||||||
}
|
}
|
||||||
|
else if (*p == '\n')
|
||||||
|
{
|
||||||
|
command->type= Q_EMPTY_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip leading spaces */
|
/* Skip leading spaces */
|
||||||
while (*p && my_isspace(charset_info, *p))
|
while (*p && my_isspace(charset_info, *p))
|
||||||
@ -5734,6 +5808,11 @@ static struct my_option my_long_options[] =
|
|||||||
{"result-file", 'R', "Read/Store result from/in this file.",
|
{"result-file", 'R', "Read/Store result from/in this file.",
|
||||||
(uchar**) &result_file_name, (uchar**) &result_file_name, 0,
|
(uchar**) &result_file_name, (uchar**) &result_file_name, 0,
|
||||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
|
{"result-format-version", OPT_RESULT_FORMAT_VERSION,
|
||||||
|
"Version of the result file format to use",
|
||||||
|
(uchar**) &opt_result_format_version,
|
||||||
|
(uchar**) &opt_result_format_version, 0,
|
||||||
|
GET_INT, REQUIRED_ARG, 1, 1, 2, 0, 0, 0},
|
||||||
{"server-arg", 'A', "Send option value to embedded server as a parameter.",
|
{"server-arg", 'A', "Send option value to embedded server as a parameter.",
|
||||||
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"server-file", 'F', "Read embedded server arguments from file.",
|
{"server-file", 'F', "Read embedded server arguments from file.",
|
||||||
@ -5943,6 +6022,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
sf_malloc_quick=1;
|
sf_malloc_quick=1;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case OPT_RESULT_FORMAT_VERSION:
|
||||||
|
set_result_format_version(opt_result_format_version);
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
print_version();
|
print_version();
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -7816,6 +7898,7 @@ int main(int argc, char **argv)
|
|||||||
case Q_MOVE_FILE: do_move_file(command); break;
|
case Q_MOVE_FILE: do_move_file(command); break;
|
||||||
case Q_CHMOD_FILE: do_chmod_file(command); break;
|
case Q_CHMOD_FILE: do_chmod_file(command); break;
|
||||||
case Q_PERL: do_perl(command); break;
|
case Q_PERL: do_perl(command); break;
|
||||||
|
case Q_RESULT_FORMAT_VERSION: do_result_format_version(command); break;
|
||||||
case Q_DELIMITER:
|
case Q_DELIMITER:
|
||||||
do_delimiter(command);
|
do_delimiter(command);
|
||||||
break;
|
break;
|
||||||
@ -7933,9 +8016,38 @@ int main(int argc, char **argv)
|
|||||||
do_sync_with_master2(command, 0);
|
do_sync_with_master2(command, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Q_COMMENT: /* Ignore row */
|
case Q_COMMENT:
|
||||||
|
{
|
||||||
command->last_argument= command->end;
|
command->last_argument= command->end;
|
||||||
|
|
||||||
|
/* Don't output comments in v1 */
|
||||||
|
if (opt_result_format_version == 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Don't output comments if query logging is off */
|
||||||
|
if (disable_query_log)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Write comment's with two starting #'s to result file */
|
||||||
|
const char* p= command->query;
|
||||||
|
if (p && *p == '#' && *(p+1) == '#')
|
||||||
|
{
|
||||||
|
dynstr_append_mem(&ds_res, command->query, command->query_len);
|
||||||
|
dynstr_append(&ds_res, "\n");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case Q_EMPTY_LINE:
|
||||||
|
/* Don't output newline in v1 */
|
||||||
|
if (opt_result_format_version == 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Don't output newline if query logging is off */
|
||||||
|
if (disable_query_log)
|
||||||
|
break;
|
||||||
|
|
||||||
|
dynstr_append(&ds_res, "\n");
|
||||||
|
break;
|
||||||
case Q_PING:
|
case Q_PING:
|
||||||
handle_command_error(command, mysql_ping(&cur_con->mysql));
|
handle_command_error(command, mysql_ping(&cur_con->mysql));
|
||||||
break;
|
break;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
#include <m_string.h>
|
#include <m_string.h>
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
|
#include <mysql_com.h>
|
||||||
#ifdef HAVE_FCONVERT
|
#ifdef HAVE_FCONVERT
|
||||||
#include <floatingpoint.h>
|
#include <floatingpoint.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,10 +22,6 @@
|
|||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NOT_FIXED_DEC
|
|
||||||
#define NOT_FIXED_DEC 31
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class String;
|
class String;
|
||||||
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
|
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
|
||||||
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
||||||
|
@ -601,15 +601,15 @@ dnl ---------------------------------------------------------------------------
|
|||||||
|
|
||||||
dnl MYSQL_NEEDS_MYSYS_NEW
|
dnl MYSQL_NEEDS_MYSYS_NEW
|
||||||
AC_DEFUN([MYSQL_NEEDS_MYSYS_NEW],
|
AC_DEFUN([MYSQL_NEEDS_MYSYS_NEW],
|
||||||
[AC_CACHE_CHECK([needs mysys_new helpers], mysql_use_mysys_new,
|
[AC_CACHE_CHECK([needs mysys_new helpers], mysql_cv_use_mysys_new,
|
||||||
[
|
[
|
||||||
AC_LANG_PUSH(C++)
|
AC_LANG_PUSH(C++)
|
||||||
AC_TRY_LINK([], [
|
AC_TRY_LINK([], [
|
||||||
class A { public: int b; }; A *a=new A; a->b=10; delete a;
|
class A { public: int b; }; A *a=new A; a->b=10; delete a;
|
||||||
], mysql_use_mysys_new=no, mysql_use_mysys_new=yes)
|
], mysql_cv_use_mysys_new=no, mysql_cv_use_mysys_new=yes)
|
||||||
AC_LANG_POP(C++)
|
AC_LANG_POP(C++)
|
||||||
])
|
])
|
||||||
if test "$mysql_use_mysys_new" = "yes"
|
if test "$mysql_cv_use_mysys_new" = "yes"
|
||||||
then
|
then
|
||||||
AC_DEFINE([USE_MYSYS_NEW], [1], [Needs to use mysys_new helpers])
|
AC_DEFINE([USE_MYSYS_NEW], [1], [Needs to use mysys_new helpers])
|
||||||
fi
|
fi
|
||||||
|
@ -260,4 +260,73 @@ typedef struct st_mysql_lex_string LEX_STRING;
|
|||||||
#define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
|
#define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
|
||||||
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
|
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
|
||||||
|
|
||||||
|
/* SPACE_INT is a word that contains only spaces */
|
||||||
|
#if SIZEOF_INT == 4
|
||||||
|
#define SPACE_INT 0x20202020
|
||||||
|
#elif SIZEOF_INT == 8
|
||||||
|
#define SPACE_INT 0x2020202020202020
|
||||||
|
#else
|
||||||
|
#error define the appropriate constant for a word full of spaces
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
Skip trailing space.
|
||||||
|
|
||||||
|
On most systems reading memory in larger chunks (ideally equal to the size of
|
||||||
|
the chinks that the machine physically reads from memory) causes fewer memory
|
||||||
|
access loops and hence increased performance.
|
||||||
|
This is why the 'int' type is used : it's closest to that (according to how
|
||||||
|
it's defined in C).
|
||||||
|
So when we determine the amount of whitespace at the end of a string we do
|
||||||
|
the following :
|
||||||
|
1. We divide the string into 3 zones :
|
||||||
|
a) from the start of the string (__start) to the first multiple
|
||||||
|
of sizeof(int) (__start_words)
|
||||||
|
b) from the end of the string (__end) to the last multiple of sizeof(int)
|
||||||
|
(__end_words)
|
||||||
|
c) a zone that is aligned to sizeof(int) and can be safely accessed
|
||||||
|
through an int *
|
||||||
|
2. We start comparing backwards from (c) char-by-char. If all we find is
|
||||||
|
space then we continue
|
||||||
|
3. If there are elements in zone (b) we compare them as unsigned ints to a
|
||||||
|
int mask (SPACE_INT) consisting of all spaces
|
||||||
|
4. Finally we compare the remaining part (a) of the string char by char.
|
||||||
|
This covers for the last non-space unsigned int from 3. (if any)
|
||||||
|
|
||||||
|
This algorithm works well for relatively larger strings, but it will slow
|
||||||
|
the things down for smaller strings (because of the additional calculations
|
||||||
|
and checks compared to the naive method). Thus the barrier of length 20
|
||||||
|
is added.
|
||||||
|
|
||||||
|
@param ptr pointer to the input string
|
||||||
|
@param len the length of the string
|
||||||
|
@return the last non-space character
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline const uchar *skip_trailing_space(const uchar *ptr,size_t len)
|
||||||
|
{
|
||||||
|
const uchar *end= ptr + len;
|
||||||
|
|
||||||
|
if (len > 20)
|
||||||
|
{
|
||||||
|
const uchar *end_words= (const uchar *)(intptr)
|
||||||
|
(((ulonglong)(intptr)end) / SIZEOF_INT * SIZEOF_INT);
|
||||||
|
const uchar *start_words= (const uchar *)(intptr)
|
||||||
|
((((ulonglong)(intptr)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
|
||||||
|
|
||||||
|
DBUG_ASSERT(((ulonglong)(intptr)ptr) >= SIZEOF_INT);
|
||||||
|
if (end_words > ptr)
|
||||||
|
{
|
||||||
|
while (end > end_words && end[-1] == 0x20)
|
||||||
|
end--;
|
||||||
|
if (end[-1] == 0x20 && start_words < end_words)
|
||||||
|
while (end > start_words && ((unsigned *)end)[-1] == SPACE_INT)
|
||||||
|
end -= SIZEOF_INT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (end > ptr && end[-1] == 0x20)
|
||||||
|
end--;
|
||||||
|
return (end);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -524,4 +524,5 @@ uchar *net_store_length(uchar *pkg, ulonglong length);
|
|||||||
#define MYSQL_STMT_HEADER 4
|
#define MYSQL_STMT_HEADER 4
|
||||||
#define MYSQL_LONG_DATA_HEADER 6
|
#define MYSQL_LONG_DATA_HEADER 6
|
||||||
|
|
||||||
|
#define NOT_FIXED_DEC 31
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,9 +51,6 @@ Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
|
|||||||
HANDLE event_client_wrote,
|
HANDLE event_client_wrote,
|
||||||
HANDLE event_client_read,
|
HANDLE event_client_read,
|
||||||
HANDLE event_conn_closed);
|
HANDLE event_conn_closed);
|
||||||
size_t vio_read_pipe(Vio *vio, uchar * buf, size_t size);
|
|
||||||
size_t vio_write_pipe(Vio *vio, const uchar * buf, size_t size);
|
|
||||||
int vio_close_pipe(Vio * vio);
|
|
||||||
#else
|
#else
|
||||||
#define HANDLE void *
|
#define HANDLE void *
|
||||||
#endif /* __WIN__ */
|
#endif /* __WIN__ */
|
||||||
@ -87,7 +84,8 @@ my_socket vio_fd(Vio*vio);
|
|||||||
my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port);
|
my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port);
|
||||||
/* Remotes in_addr */
|
/* Remotes in_addr */
|
||||||
void vio_in_addr(Vio *vio, struct in_addr *in);
|
void vio_in_addr(Vio *vio, struct in_addr *in);
|
||||||
my_bool vio_poll_read(Vio *vio,uint timeout);
|
my_bool vio_poll_read(Vio *vio, uint timeout);
|
||||||
|
my_bool vio_is_connected(Vio *vio);
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
@ -136,12 +134,6 @@ struct st_VioSSLFd
|
|||||||
void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
|
void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
|
|
||||||
#ifdef HAVE_SMEM
|
|
||||||
size_t vio_read_shared_memory(Vio *vio, uchar * buf, size_t size);
|
|
||||||
size_t vio_write_shared_memory(Vio *vio, const uchar * buf, size_t size);
|
|
||||||
int vio_close_shared_memory(Vio * vio);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void vio_end(void);
|
void vio_end(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -164,6 +156,8 @@ void vio_end(void);
|
|||||||
#define vio_peer_addr(vio, buf, prt) (vio)->peer_addr(vio, buf, prt)
|
#define vio_peer_addr(vio, buf, prt) (vio)->peer_addr(vio, buf, prt)
|
||||||
#define vio_in_addr(vio, in) (vio)->in_addr(vio, in)
|
#define vio_in_addr(vio, in) (vio)->in_addr(vio, in)
|
||||||
#define vio_timeout(vio, which, seconds) (vio)->timeout(vio, which, seconds)
|
#define vio_timeout(vio, which, seconds) (vio)->timeout(vio, which, seconds)
|
||||||
|
#define vio_poll_read(vio, timeout) (vio)->poll_read(vio, timeout)
|
||||||
|
#define vio_is_connected(vio) (vio)->is_connected(vio)
|
||||||
#endif /* !defined(DONT_MAP_VIO) */
|
#endif /* !defined(DONT_MAP_VIO) */
|
||||||
|
|
||||||
/* This enumerator is used in parser - should be always visible */
|
/* This enumerator is used in parser - should be always visible */
|
||||||
@ -208,6 +202,8 @@ struct st_vio
|
|||||||
my_bool (*was_interrupted)(Vio*);
|
my_bool (*was_interrupted)(Vio*);
|
||||||
int (*vioclose)(Vio*);
|
int (*vioclose)(Vio*);
|
||||||
void (*timeout)(Vio*, unsigned int which, unsigned int timeout);
|
void (*timeout)(Vio*, unsigned int which, unsigned int timeout);
|
||||||
|
my_bool (*poll_read)(Vio *vio, uint timeout);
|
||||||
|
my_bool (*is_connected)(Vio*);
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
void *ssl_arg;
|
void *ssl_arg;
|
||||||
#endif
|
#endif
|
||||||
|
@ -3478,10 +3478,7 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
|
|||||||
*/
|
*/
|
||||||
char buff[MAX_DOUBLE_STRING_REP_LENGTH];
|
char buff[MAX_DOUBLE_STRING_REP_LENGTH];
|
||||||
char *end;
|
char *end;
|
||||||
/* TODO: move this to a header shared between client and server. */
|
|
||||||
#define NOT_FIXED_DEC 31
|
|
||||||
if (field->decimals >= NOT_FIXED_DEC)
|
if (field->decimals >= NOT_FIXED_DEC)
|
||||||
#undef NOT_FIXED_DEC
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
DBL_DIG below is to ensure that the server and client has the same
|
DBL_DIG below is to ensure that the server and client has the same
|
||||||
|
@ -138,6 +138,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
|||||||
|
|
||||||
result= dispatch_command(command, thd, (char *) arg, arg_length);
|
result= dispatch_command(command, thd, (char *) arg, arg_length);
|
||||||
thd->cur_data= 0;
|
thd->cur_data= 0;
|
||||||
|
thd->mysys_var= NULL;
|
||||||
|
|
||||||
if (!skip_check)
|
if (!skip_check)
|
||||||
result= thd->is_error() ? -1 : 0;
|
result= thd->is_error() ? -1 : 0;
|
||||||
|
@ -73,3 +73,142 @@ UPDATE t1 SET t1.xstatus_vor = Greatest(t1.xstatus_vor,1) WHERE t1.aufnr =
|
|||||||
"40004712" AND t1.plnfl = "000001" AND t1.vornr > "0010" ORDER BY t1.vornr
|
"40004712" AND t1.plnfl = "000001" AND t1.vornr > "0010" ORDER BY t1.vornr
|
||||||
ASC LIMIT 1;
|
ASC LIMIT 1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
drop table if exists t1,t2,t3;
|
||||||
|
create table t1 (a int, b int, c int);
|
||||||
|
create table t2 (d int);
|
||||||
|
create table t3 (a1 int, b1 int, c1 int);
|
||||||
|
insert into t1 values(1,2,3);
|
||||||
|
insert into t1 values(11,22,33);
|
||||||
|
insert into t2 values(99);
|
||||||
|
select t1.* as 'with_alias' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
|
||||||
|
select t2.* as 'with_alias' from t2;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t2' at line 1
|
||||||
|
select t1.*, t1.* as 'with_alias' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
|
||||||
|
select t1.* as 'with_alias', t1.* from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', t1.* from t1' at line 1
|
||||||
|
select t1.* as 'with_alias', t1.* as 'alias2' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', t1.* as 'alias2' from t1' at line 1
|
||||||
|
select t1.* as 'with_alias', a, t1.* as 'alias2' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', a, t1.* as 'alias2' from t1' at line 1
|
||||||
|
select a, t1.* as 'with_alias' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
|
||||||
|
select t1.* as 'with_alias', a from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', a from t1' at line 1
|
||||||
|
select a, t1.* as 'with_alias', b from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', b from t1' at line 1
|
||||||
|
select (select d from t2 where d > a), t1.* as 'with_alias' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
|
||||||
|
select t1.* as 'with_alias', (select a from t2 where d > a) from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', (select a from t2 where d > a) from t1' at line 1
|
||||||
|
select a as 'x', t1.* as 'with_alias' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
|
||||||
|
select t1.* as 'with_alias', a as 'x' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', a as 'x' from t1' at line 1
|
||||||
|
select a as 'x', t1.* as 'with_alias', b as 'x' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', b as 'x' from t1' at line 1
|
||||||
|
select (select d from t2 where d > a) as 'x', t1.* as 'with_alias' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
|
||||||
|
select t1.* as 'with_alias', (select a from t2 where d > a) as 'x' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', (select a from t2 where d > a) as 'x' from t1' at line 1
|
||||||
|
select (select t2.* as 'x' from t2) from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'x' from t2) from t1' at line 1
|
||||||
|
select a, (select t2.* as 'x' from t2) from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'x' from t2) from t1' at line 1
|
||||||
|
select t1.*, (select t2.* as 'x' from t2) from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'x' from t2) from t1' at line 1
|
||||||
|
insert into t3 select t1.* as 'with_alias' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
|
||||||
|
insert into t3 select t2.* as 'with_alias', 1, 2 from t2;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', 1, 2 from t2' at line 1
|
||||||
|
insert into t3 select t2.* as 'with_alias', d as 'x', d as 'z' from t2;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', d as 'x', d as 'z' from t2' at line 1
|
||||||
|
insert into t3 select t2.*, t2.* as 'with_alias', 3 from t2;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', 3 from t2' at line 1
|
||||||
|
create table t3 select t1.* as 'with_alias' from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
|
||||||
|
create table t3 select t2.* as 'with_alias', 1, 2 from t2;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', 1, 2 from t2' at line 1
|
||||||
|
create table t3 select t2.* as 'with_alias', d as 'x', d as 'z' from t2;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', d as 'x', d as 'z' from t2' at line 1
|
||||||
|
create table t3 select t2.*, t2.* as 'with_alias', 3 from t2;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', 3 from t2' at line 1
|
||||||
|
select t1.* from t1;
|
||||||
|
a b c
|
||||||
|
1 2 3
|
||||||
|
11 22 33
|
||||||
|
select t2.* from t2;
|
||||||
|
d
|
||||||
|
99
|
||||||
|
select t1.*, t1.* from t1;
|
||||||
|
a b c a b c
|
||||||
|
1 2 3 1 2 3
|
||||||
|
11 22 33 11 22 33
|
||||||
|
select t1.*, a, t1.* from t1;
|
||||||
|
a b c a a b c
|
||||||
|
1 2 3 1 1 2 3
|
||||||
|
11 22 33 11 11 22 33
|
||||||
|
select a, t1.* from t1;
|
||||||
|
a a b c
|
||||||
|
1 1 2 3
|
||||||
|
11 11 22 33
|
||||||
|
select t1.*, a from t1;
|
||||||
|
a b c a
|
||||||
|
1 2 3 1
|
||||||
|
11 22 33 11
|
||||||
|
select a, t1.*, b from t1;
|
||||||
|
a a b c b
|
||||||
|
1 1 2 3 2
|
||||||
|
11 11 22 33 22
|
||||||
|
select (select d from t2 where d > a), t1.* from t1;
|
||||||
|
(select d from t2 where d > a) a b c
|
||||||
|
99 1 2 3
|
||||||
|
99 11 22 33
|
||||||
|
select t1.*, (select a from t2 where d > a) from t1;
|
||||||
|
a b c (select a from t2 where d > a)
|
||||||
|
1 2 3 1
|
||||||
|
11 22 33 11
|
||||||
|
select a as 'x', t1.* from t1;
|
||||||
|
x a b c
|
||||||
|
1 1 2 3
|
||||||
|
11 11 22 33
|
||||||
|
select t1.*, a as 'x' from t1;
|
||||||
|
a b c x
|
||||||
|
1 2 3 1
|
||||||
|
11 22 33 11
|
||||||
|
select a as 'x', t1.*, b as 'x' from t1;
|
||||||
|
x a b c x
|
||||||
|
1 1 2 3 2
|
||||||
|
11 11 22 33 22
|
||||||
|
select (select d from t2 where d > a) as 'x', t1.* from t1;
|
||||||
|
x a b c
|
||||||
|
99 1 2 3
|
||||||
|
99 11 22 33
|
||||||
|
select t1.*, (select a from t2 where d > a) as 'x' from t1;
|
||||||
|
a b c x
|
||||||
|
1 2 3 1
|
||||||
|
11 22 33 11
|
||||||
|
select (select t2.* from t2) from t1;
|
||||||
|
(select t2.* from t2)
|
||||||
|
99
|
||||||
|
99
|
||||||
|
select a, (select t2.* from t2) from t1;
|
||||||
|
a (select t2.* from t2)
|
||||||
|
1 99
|
||||||
|
11 99
|
||||||
|
select t1.*, (select t2.* from t2) from t1;
|
||||||
|
a b c (select t2.* from t2)
|
||||||
|
1 2 3 99
|
||||||
|
11 22 33 99
|
||||||
|
insert into t3 select t1.* from t1;
|
||||||
|
insert into t3 select t2.*, 1, 2 from t2;
|
||||||
|
insert into t3 select t2.*, d as 'x', d as 'z' from t2;
|
||||||
|
insert into t3 select t2.*, t2.*, 3 from t2;
|
||||||
|
create table t4 select t1.* from t1;
|
||||||
|
drop table t4;
|
||||||
|
create table t4 select t2.*, 1, 2 from t2;
|
||||||
|
drop table t4;
|
||||||
|
create table t4 select t2.*, d as 'x', d as 'z' from t2;
|
||||||
|
drop table t4;
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
@ -259,8 +259,8 @@ ERROR 42S02: Unknown table 't2' in MULTI DELETE
|
|||||||
DELETE FROM db1.t1 alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
DELETE FROM db1.t1 alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a' at line 1
|
||||||
DELETE FROM alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
DELETE FROM alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
||||||
ERROR 42S02: Unknown table 'alias' in MULTI DELETE
|
|
||||||
DELETE FROM db2.alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
DELETE FROM db2.alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
||||||
|
ERROR 42S02: Unknown table 'alias' in MULTI DELETE
|
||||||
DELETE FROM t1 USING t1 WHERE a = 1;
|
DELETE FROM t1 USING t1 WHERE a = 1;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
a
|
a
|
||||||
@ -279,6 +279,147 @@ ERROR 42000: Incorrect number of arguments for FUNCTION test.f1; expected 0, got
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
DROP DATABASE IF EXISTS db1;
|
||||||
|
DROP DATABASE IF EXISTS db2;
|
||||||
|
DROP DATABASE IF EXISTS db3;
|
||||||
|
DROP DATABASE IF EXISTS db4;
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
DROP PROCEDURE IF EXISTS count;
|
||||||
|
USE test;
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
CREATE DATABASE db2;
|
||||||
|
CREATE TABLE db1.t1 (a INT, b INT);
|
||||||
|
INSERT INTO db1.t1 VALUES (1,1),(2,2),(3,3);
|
||||||
|
CREATE TABLE db1.t2 AS SELECT * FROM db1.t1;
|
||||||
|
CREATE TABLE db2.t1 AS SELECT * FROM db1.t2;
|
||||||
|
CREATE TABLE db2.t2 AS SELECT * FROM db2.t1;
|
||||||
|
CREATE TABLE t1 AS SELECT * FROM db2.t2;
|
||||||
|
CREATE TABLE t2 AS SELECT * FROM t1;
|
||||||
|
CREATE PROCEDURE count_rows()
|
||||||
|
BEGIN
|
||||||
|
SELECT COUNT(*) AS "COUNT(db1.t1)" FROM db1.t1;
|
||||||
|
SELECT COUNT(*) AS "COUNT(db1.t2)" FROM db1.t2;
|
||||||
|
SELECT COUNT(*) AS "COUNT(db2.t1)" FROM db2.t1;
|
||||||
|
SELECT COUNT(*) AS "COUNT(db2.t2)" FROM db2.t2;
|
||||||
|
SELECT COUNT(*) AS "COUNT(test.t1)" FROM test.t1;
|
||||||
|
SELECT COUNT(*) AS "COUNT(test.t2)" FROM test.t2;
|
||||||
|
END|
|
||||||
|
CREATE DATABASE db3;
|
||||||
|
USE db3;
|
||||||
|
DROP DATABASE db3;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE a1,a2 FROM db1.t1 AS a1, db2.t2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2 AS a2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE FROM a1,a2 USING db1.t1 AS a1, db2.t2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2 AS a2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE a1 FROM db1.a1, db2.t2 AS a1;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE a1 FROM a1, db1.t1 AS a1;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE t1 FROM db1.t1, db2.t1 AS a1;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE t1 FROM db1.t1 AS a1, db2.t1 AS a2;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
DELETE t1 FROM db1.t1, db2.t1;
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
USE test;
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in MULTI DELETE
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in MULTI DELETE
|
||||||
|
DELETE a1,a2 FROM db1.t1 AS a1, db2.t2;
|
||||||
|
ERROR 42S02: Unknown table 'a2' in MULTI DELETE
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2 AS a2;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in MULTI DELETE
|
||||||
|
DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
ERROR 42S02: Table 'db3.t1' doesn't exist
|
||||||
|
DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
ERROR 42S02: Table 'db3.t1' doesn't exist
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in MULTI DELETE
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in MULTI DELETE
|
||||||
|
DELETE FROM a1,a2 USING db1.t1 AS a1, db2.t2;
|
||||||
|
ERROR 42S02: Unknown table 'a2' in MULTI DELETE
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2 AS a2;
|
||||||
|
ERROR 42S02: Unknown table 'a1' in MULTI DELETE
|
||||||
|
DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
ERROR 42S02: Table 'db3.t1' doesn't exist
|
||||||
|
DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
ERROR 42S02: Table 'db3.t1' doesn't exist
|
||||||
|
DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1;
|
||||||
|
ERROR 42000: Not unique table/alias: 'a1'
|
||||||
|
DELETE a1 FROM db1.a1, db2.t2 AS a1;
|
||||||
|
ERROR 42S02: Table 'db1.a1' doesn't exist
|
||||||
|
DELETE a1 FROM a1, db1.t1 AS a1;
|
||||||
|
ERROR 42000: Not unique table/alias: 'a1'
|
||||||
|
DELETE t1 FROM db1.t1, db2.t1 AS a1;
|
||||||
|
ERROR 42S02: Unknown table 't1' in MULTI DELETE
|
||||||
|
DELETE t1 FROM db1.t1 AS a1, db2.t1 AS a2;
|
||||||
|
ERROR 42S02: Unknown table 't1' in MULTI DELETE
|
||||||
|
DELETE t1 FROM db1.t1, db2.t1;
|
||||||
|
ERROR 42S02: Unknown table 't1' in MULTI DELETE
|
||||||
|
DELETE t1 FROM db1.t2 AS t1, db2.t2 AS t2 WHERE t2.a = 1 AND t1.a = t2.a;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
ROW_COUNT()
|
||||||
|
1
|
||||||
|
CALL count_rows();
|
||||||
|
COUNT(db1.t1)
|
||||||
|
3
|
||||||
|
COUNT(db1.t2)
|
||||||
|
2
|
||||||
|
COUNT(db2.t1)
|
||||||
|
3
|
||||||
|
COUNT(db2.t2)
|
||||||
|
3
|
||||||
|
COUNT(test.t1)
|
||||||
|
3
|
||||||
|
COUNT(test.t2)
|
||||||
|
3
|
||||||
|
DELETE a1, a2 FROM db2.t1 AS a1, t2 AS a2 WHERE a1.a = 2 AND a2.a = 2;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
ROW_COUNT()
|
||||||
|
2
|
||||||
|
CALL count_rows();
|
||||||
|
COUNT(db1.t1)
|
||||||
|
3
|
||||||
|
COUNT(db1.t2)
|
||||||
|
2
|
||||||
|
COUNT(db2.t1)
|
||||||
|
2
|
||||||
|
COUNT(db2.t2)
|
||||||
|
3
|
||||||
|
COUNT(test.t1)
|
||||||
|
3
|
||||||
|
COUNT(test.t2)
|
||||||
|
2
|
||||||
|
DROP DATABASE db1;
|
||||||
|
DROP DATABASE db2;
|
||||||
|
DROP PROCEDURE count_rows;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
#
|
#
|
||||||
# Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
|
# Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
|
||||||
# merge table
|
# merge table
|
||||||
|
@ -277,7 +277,7 @@ select * from t1;
|
|||||||
N M
|
N M
|
||||||
3 0
|
3 0
|
||||||
delete P1.*,p2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS p2 ON P1.N = p2.N;
|
delete P1.*,p2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS p2 ON P1.N = p2.N;
|
||||||
ERROR 42S02: Unknown table 'p2' in MULTI DELETE
|
ERROR HY000: The target table p2 of the DELETE is not updatable
|
||||||
delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||||
ERROR 42S22: Unknown column 'aaa' in 'field list'
|
ERROR 42S22: Unknown column 'aaa' in 'field list'
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@ -7,3 +7,13 @@ n
|
|||||||
2
|
2
|
||||||
3
|
3
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
SELECT GET_LOCK("dangling", 0);
|
||||||
|
GET_LOCK("dangling", 0)
|
||||||
|
1
|
||||||
|
SELECT GET_LOCK('dangling', 3600);;
|
||||||
|
SELECT GET_LOCK('dangling', 3600);;
|
||||||
|
SELECT RELEASE_LOCK('dangling');
|
||||||
|
RELEASE_LOCK('dangling')
|
||||||
|
1
|
||||||
|
GET_LOCK('dangling', 3600)
|
||||||
|
1
|
||||||
|
@ -282,3 +282,33 @@ TIMEDIFF(TIME('17:59:00'),TIME('17:00:00')),
|
|||||||
TIMEDIFF(TIME('17:00:00'),TIME('17:59:00'));
|
TIMEDIFF(TIME('17:00:00'),TIME('17:59:00'));
|
||||||
1Eq 1NEq1 1NEq2 2Eq 2NEq1 2NEq2 3Eq 3NEq1 3NEq2 Time0 Time00 Literal0000 TIMEDIFF(TIME('17:59:00'),TIME('17:00:00')) TIMEDIFF(TIME('17:00:00'),TIME('17:59:00'))
|
1Eq 1NEq1 1NEq2 2Eq 2NEq1 2NEq2 3Eq 3NEq1 3NEq2 Time0 Time00 Literal0000 TIMEDIFF(TIME('17:59:00'),TIME('17:00:00')) TIMEDIFF(TIME('17:00:00'),TIME('17:59:00'))
|
||||||
1 0 0 1 0 0 1 0 0 00:00:00 00:00:00 00:00:00 00:59:00 -00:59:00
|
1 0 0 1 0 0 1 0 0 00:00:00 00:00:00 00:00:00 00:59:00 -00:59:00
|
||||||
|
SELECT sec_to_time(3020399)=TIME('838:59:59');
|
||||||
|
sec_to_time(3020399)=TIME('838:59:59')
|
||||||
|
1
|
||||||
|
SELECT sec_to_time(-3020399)=TIME('-838:59:59');
|
||||||
|
sec_to_time(-3020399)=TIME('-838:59:59')
|
||||||
|
1
|
||||||
|
SELECT sec_to_time(-3020399)='-838:59:59';
|
||||||
|
sec_to_time(-3020399)='-838:59:59'
|
||||||
|
1
|
||||||
|
SELECT time(sec_to_time(-3020399))=TIME('-838:59:59');
|
||||||
|
time(sec_to_time(-3020399))=TIME('-838:59:59')
|
||||||
|
1
|
||||||
|
SELECT time(sec_to_time(-3020399))=TIME('-838:59:58');
|
||||||
|
time(sec_to_time(-3020399))=TIME('-838:59:58')
|
||||||
|
0
|
||||||
|
SELECT maketime(-1,0,1)='-01:00:01';
|
||||||
|
maketime(-1,0,1)='-01:00:01'
|
||||||
|
1
|
||||||
|
SELECT TIME(maketime(-1,0,1))=CAST('-01:00:01' AS TIME);
|
||||||
|
TIME(maketime(-1,0,1))=CAST('-01:00:01' AS TIME)
|
||||||
|
1
|
||||||
|
SELECT maketime(-1,0,1)=CAST('-01:00:01' AS TIME);
|
||||||
|
maketime(-1,0,1)=CAST('-01:00:01' AS TIME)
|
||||||
|
1
|
||||||
|
SELECT maketime(1,0,1)=CAST('01:00:01' AS TIME);
|
||||||
|
maketime(1,0,1)=CAST('01:00:01' AS TIME)
|
||||||
|
1
|
||||||
|
SELECT maketime(1,0,1)=CAST('01:00:02' AS TIME);
|
||||||
|
maketime(1,0,1)=CAST('01:00:02' AS TIME)
|
||||||
|
0
|
||||||
|
@ -1301,6 +1301,12 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SECOND;
|
|||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
|
||||||
SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
|
SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
|
||||||
|
select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond);
|
||||||
|
date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond)
|
||||||
|
1000-01-02 03:02:01.050000
|
||||||
|
select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond);
|
||||||
|
date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond)
|
||||||
|
1000-01-01 00:00:01.020000
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
|
select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND)
|
date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
|
@ -201,6 +201,202 @@ COUNT (*)
|
|||||||
ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno)
|
ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno)
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
WARNING: --server-arg option not supported in this configuration.
|
WARNING: --server-arg option not supported in this configuration.
|
||||||
|
*************************** 1. row ***************************
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
1: 1
|
||||||
|
2: 2
|
||||||
|
3: 3
|
||||||
|
4: 4
|
||||||
|
5: 5
|
||||||
|
6: 6
|
||||||
|
7: 7
|
||||||
|
8: 8
|
||||||
|
9: 9
|
||||||
|
0: 0
|
||||||
|
+---+
|
||||||
|
| 1 |
|
||||||
|
+---+
|
||||||
|
| 1 |
|
||||||
|
+---+
|
||||||
Warning (Code 1286): Unknown table engine 'nonexistent'
|
Warning (Code 1286): Unknown table engine 'nonexistent'
|
||||||
Warning (Code 1266): Using storage engine MyISAM for table 't2'
|
Warning (Code 1266): Using storage engine MyISAM for table 't2'
|
||||||
Warning (Code 1286): Unknown table engine 'nonexistent2'
|
Warning (Code 1286): Unknown table engine 'nonexistent2'
|
||||||
|
25
mysql-test/r/partition_sync.result
Normal file
25
mysql-test/r/partition_sync.result
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#
|
||||||
|
# Bug #43867 ALTER TABLE on a partitioned table
|
||||||
|
# causes unnecessary deadlocks
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int) PARTITION BY RANGE (a)
|
||||||
|
(PARTITION p0 VALUES LESS THAN (1),
|
||||||
|
PARTITION p1 VALUES LESS THAN (2));
|
||||||
|
INSERT INTO t1 VALUES (0),(1);
|
||||||
|
# Connection 2
|
||||||
|
BEGIN;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
0
|
||||||
|
1
|
||||||
|
# Connection 1
|
||||||
|
ALTER TABLE t1 DROP PARTITION p3;
|
||||||
|
ERROR HY000: Error in list of partitions to DROP
|
||||||
|
# Connection 2
|
||||||
|
# This failed with deadlock and should not do so.
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
0
|
||||||
|
1
|
||||||
|
# Connection 1
|
||||||
|
DROP TABLE t1;
|
17
mysql-test/r/rpl_mysqldump_slave.result
Normal file
17
mysql-test/r/rpl_mysqldump_slave.result
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
stop slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
reset master;
|
||||||
|
reset slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
start slave;
|
||||||
|
#
|
||||||
|
# New --dump-slave, --apply-slave-statements functionality
|
||||||
|
#
|
||||||
|
use test;
|
||||||
|
CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=107;
|
||||||
|
STOP SLAVE;
|
||||||
|
CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=107;
|
||||||
|
START SLAVE;
|
||||||
|
STOP SLAVE;
|
||||||
|
CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT='MASTER_MYPORT', MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=107;
|
||||||
|
START SLAVE;
|
@ -1659,6 +1659,18 @@ begin
|
|||||||
declare continue handler for sqlstate '00000' set @x=0;
|
declare continue handler for sqlstate '00000' set @x=0;
|
||||||
end$$
|
end$$
|
||||||
ERROR 42000: Bad SQLSTATE: '00000'
|
ERROR 42000: Bad SQLSTATE: '00000'
|
||||||
|
drop procedure if exists p1;
|
||||||
|
set @old_recursion_depth = @@max_sp_recursion_depth;
|
||||||
|
set @@max_sp_recursion_depth = 255;
|
||||||
|
create procedure p1(a int)
|
||||||
|
begin
|
||||||
|
declare continue handler for 1436 -- ER_STACK_OVERRUN_NEED_MORE
|
||||||
|
select 'exception';
|
||||||
|
call p1(a+1);
|
||||||
|
end|
|
||||||
|
call p1(1);
|
||||||
|
set @@max_sp_recursion_depth = @old_recursion_depth;
|
||||||
|
drop procedure p1;
|
||||||
LOAD DATA INFILE '../../tmp/proc.txt' INTO TABLE mysql.proc;
|
LOAD DATA INFILE '../../tmp/proc.txt' INTO TABLE mysql.proc;
|
||||||
CREATE TABLE t1 (a INT, b INT);
|
CREATE TABLE t1 (a INT, b INT);
|
||||||
INSERT INTO t1 VALUES (1,1), (2,2);
|
INSERT INTO t1 VALUES (1,1), (2,2);
|
||||||
|
@ -6941,6 +6941,101 @@ SELECT * FROM t1 WHERE a = f1();
|
|||||||
ERROR 42S02: Table 'test.t_non_existing' doesn't exist
|
ERROR 42S02: Table 'test.t_non_existing' doesn't exist
|
||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
CREATE PROCEDURE p1(a INT, b CHAR)
|
||||||
|
BEGIN
|
||||||
|
IF a > 0 THEN
|
||||||
|
CALL p1(a-1, 'ab');
|
||||||
|
ELSE
|
||||||
|
SELECT 1;
|
||||||
|
END IF;
|
||||||
|
END|
|
||||||
|
SET @save_max_sp_recursion= @@max_sp_recursion_depth;
|
||||||
|
SET @@max_sp_recursion_depth= 5;
|
||||||
|
CALL p1(4, 'a');
|
||||||
|
1
|
||||||
|
1
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 1
|
||||||
|
SET @@max_sp_recursion_depth= @save_max_sp_recursion;
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
CREATE PROCEDURE p1(a CHAR)
|
||||||
|
BEGIN
|
||||||
|
SELECT 1;
|
||||||
|
SELECT CAST('10 ' as UNSIGNED INTEGER);
|
||||||
|
SELECT 1;
|
||||||
|
END|
|
||||||
|
CALL p1('data truncated parameter');
|
||||||
|
1
|
||||||
|
1
|
||||||
|
CAST('10 ' as UNSIGNED INTEGER)
|
||||||
|
10
|
||||||
|
1
|
||||||
|
1
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: '10 '
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP PROCEDURE IF EXISTS p2;
|
||||||
|
DROP PROCEDURE IF EXISTS p3;
|
||||||
|
DROP PROCEDURE IF EXISTS p4;
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
CALL p2()|
|
||||||
|
CREATE PROCEDURE p2()
|
||||||
|
CALL p3()|
|
||||||
|
CREATE PROCEDURE p3()
|
||||||
|
CALL p4()|
|
||||||
|
CREATE PROCEDURE p4()
|
||||||
|
BEGIN
|
||||||
|
SELECT 1;
|
||||||
|
SELECT CAST('10 ' as UNSIGNED INTEGER);
|
||||||
|
SELECT 2;
|
||||||
|
END|
|
||||||
|
CALL p1();
|
||||||
|
1
|
||||||
|
1
|
||||||
|
CAST('10 ' as UNSIGNED INTEGER)
|
||||||
|
10
|
||||||
|
2
|
||||||
|
2
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: '10 '
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP PROCEDURE p2;
|
||||||
|
DROP PROCEDURE p3;
|
||||||
|
DROP PROCEDURE p4;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
DROP FUNCTION IF EXISTS f3;
|
||||||
|
DROP FUNCTION IF EXISTS f4;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (a CHAR(2));
|
||||||
|
INSERT INTO t1 VALUES ('aa');
|
||||||
|
CREATE FUNCTION f1() RETURNS CHAR
|
||||||
|
RETURN (SELECT f2())|
|
||||||
|
CREATE FUNCTION f2() RETURNS CHAR
|
||||||
|
RETURN (SELECT f3())|
|
||||||
|
CREATE FUNCTION f3() RETURNS CHAR
|
||||||
|
RETURN (SELECT f4())|
|
||||||
|
CREATE FUNCTION f4() RETURNS CHAR
|
||||||
|
BEGIN
|
||||||
|
RETURN (SELECT a FROM t1);
|
||||||
|
END|
|
||||||
|
SELECT f1();
|
||||||
|
f1()
|
||||||
|
a
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'f4()' at row 1
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
DROP FUNCTION f3;
|
||||||
|
DROP FUNCTION f4;
|
||||||
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# Bug#34197: CREATE PROCEDURE fails when COMMENT truncated in non
|
# Bug#34197: CREATE PROCEDURE fails when COMMENT truncated in non
|
||||||
# strict SQL mode
|
# strict SQL mode
|
||||||
|
@ -2115,3 +2115,50 @@ s1
|
|||||||
DELETE FROM t1;
|
DELETE FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TEMPORARY TABLE t2;
|
DROP TEMPORARY TABLE t2;
|
||||||
|
DROP TRIGGER IF EXISTS trg1;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE a CHAR;
|
||||||
|
SELECT 'ab' INTO a;
|
||||||
|
SELECT 'ab' INTO a;
|
||||||
|
SELECT 'a' INTO a;
|
||||||
|
END|
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
DROP TRIGGER trg1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TRIGGER IF EXISTS trg1;
|
||||||
|
DROP TRIGGER IF EXISTS trg2;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE trg1 CHAR;
|
||||||
|
SELECT 'ab' INTO trg1;
|
||||||
|
END|
|
||||||
|
CREATE TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE trg2 CHAR;
|
||||||
|
SELECT 'ab' INTO trg2;
|
||||||
|
END|
|
||||||
|
INSERT INTO t1 VALUES (0);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'trg1' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'trg2' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
0
|
||||||
|
SHOW WARNINGS;
|
||||||
|
Level Code Message
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'trg1' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'trg2' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'trg1' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'trg2' at row 1
|
||||||
|
DROP TRIGGER trg1;
|
||||||
|
DROP TRIGGER trg2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -85,6 +85,7 @@ sec_to_time(time_to_sec(t))
|
|||||||
13:00:00
|
13:00:00
|
||||||
09:00:00
|
09:00:00
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
End of 4.1 tests
|
||||||
select cast('100:55:50' as time) < cast('24:00:00' as time);
|
select cast('100:55:50' as time) < cast('24:00:00' as time);
|
||||||
cast('100:55:50' as time) < cast('24:00:00' as time)
|
cast('100:55:50' as time) < cast('24:00:00' as time)
|
||||||
0
|
0
|
||||||
@ -138,3 +139,27 @@ CAST(c AS TIME)
|
|||||||
00:00:00
|
00:00:00
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
CREATE TABLE t1 (f1 TIME);
|
||||||
|
INSERT INTO t1 VALUES ('24:00:00');
|
||||||
|
SELECT '24:00:00' = (SELECT f1 FROM t1);
|
||||||
|
'24:00:00' = (SELECT f1 FROM t1)
|
||||||
|
1
|
||||||
|
SELECT CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1);
|
||||||
|
CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1)
|
||||||
|
1
|
||||||
|
SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
|
||||||
|
CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1)
|
||||||
|
0
|
||||||
|
TRUNCATE t1;
|
||||||
|
INSERT INTO t1 VALUES ('-24:00:00');
|
||||||
|
SELECT CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1);
|
||||||
|
CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1)
|
||||||
|
0
|
||||||
|
SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
|
||||||
|
CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1)
|
||||||
|
1
|
||||||
|
SELECT '-24:00:00' = (SELECT f1 FROM t1);
|
||||||
|
'-24:00:00' = (SELECT f1 FROM t1)
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
|
End of 6.0 tests
|
||||||
|
@ -16,7 +16,7 @@ DELETE alias FROM a alias WHERE alias.i=1;
|
|||||||
SELECT * FROM a;
|
SELECT * FROM a;
|
||||||
i
|
i
|
||||||
insert into a values(2),(3);
|
insert into a values(2),(3);
|
||||||
delete a alias FROM a alias where alias.i=2;
|
delete alias FROM a alias where alias.i=2;
|
||||||
select * from a;
|
select * from a;
|
||||||
i
|
i
|
||||||
3
|
3
|
||||||
|
@ -25,7 +25,7 @@ INSERT INTO a VALUES(1);
|
|||||||
DELETE alias FROM a alias WHERE alias.i=1;
|
DELETE alias FROM a alias WHERE alias.i=1;
|
||||||
SELECT * FROM a;
|
SELECT * FROM a;
|
||||||
insert into a values(2),(3);
|
insert into a values(2),(3);
|
||||||
delete a alias FROM a alias where alias.i=2;
|
delete alias FROM a alias where alias.i=2;
|
||||||
select * from a;
|
select * from a;
|
||||||
save_master_pos;
|
save_master_pos;
|
||||||
connection slave;
|
connection slave;
|
||||||
|
@ -41,7 +41,10 @@ id rollno GROUP_CONCAT(name)
|
|||||||
4 3 Reco
|
4 3 Reco
|
||||||
7 4 Reco
|
7 4 Reco
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1260 4 line(s) were cut by GROUP_CONCAT()
|
Warning 1260 Row 1 was cut by GROUP_CONCAT()
|
||||||
|
Warning 1260 Row 2 was cut by GROUP_CONCAT()
|
||||||
|
Warning 1260 Row 3 was cut by GROUP_CONCAT()
|
||||||
|
Warning 1260 Row 4 was cut by GROUP_CONCAT()
|
||||||
## Changing session value of variable and verifying its behavior, ##
|
## Changing session value of variable and verifying its behavior, ##
|
||||||
## warning should come here ##
|
## warning should come here ##
|
||||||
SET @@session.group_concat_max_len = 10;
|
SET @@session.group_concat_max_len = 10;
|
||||||
@ -52,7 +55,9 @@ id rollno GROUP_CONCAT(name)
|
|||||||
4 3 Record_4,R
|
4 3 Record_4,R
|
||||||
7 4 Record_7,R
|
7 4 Record_7,R
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1260 3 line(s) were cut by GROUP_CONCAT()
|
Warning 1260 Row 2 was cut by GROUP_CONCAT()
|
||||||
|
Warning 1260 Row 5 was cut by GROUP_CONCAT()
|
||||||
|
Warning 1260 Row 7 was cut by GROUP_CONCAT()
|
||||||
'#--------------------FN_DYNVARS_034_03-------------------------#'
|
'#--------------------FN_DYNVARS_034_03-------------------------#'
|
||||||
## Connecting with new connection test_con2 ##
|
## Connecting with new connection test_con2 ##
|
||||||
## Verifying initial value of variable. It should be 4 ##
|
## Verifying initial value of variable. It should be 4 ##
|
||||||
@ -71,7 +76,7 @@ id rollno GROUP_CONCAT(name)
|
|||||||
4 3 Record_4,Record_6
|
4 3 Record_4,Record_6
|
||||||
7 4 Record_7,Record_8
|
7 4 Record_7,Record_8
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1260 1 line(s) were cut by GROUP_CONCAT()
|
Warning 1260 Row 3 was cut by GROUP_CONCAT()
|
||||||
'#--------------------FN_DYNVARS_034_04-------------------------#'
|
'#--------------------FN_DYNVARS_034_04-------------------------#'
|
||||||
## Setting session value of variable to 26. No warning should appear here ##
|
## Setting session value of variable to 26. No warning should appear here ##
|
||||||
## because the value after concatination is less than 30 ##
|
## because the value after concatination is less than 30 ##
|
||||||
|
@ -86,3 +86,132 @@ ASC LIMIT 1;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#27249 table_wild with alias: select t1.* as something
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1,t2,t3;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create table t1 (a int, b int, c int);
|
||||||
|
create table t2 (d int);
|
||||||
|
create table t3 (a1 int, b1 int, c1 int);
|
||||||
|
insert into t1 values(1,2,3);
|
||||||
|
insert into t1 values(11,22,33);
|
||||||
|
insert into t2 values(99);
|
||||||
|
|
||||||
|
# Invalid queries with alias on wild
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.* as 'with_alias' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t2.* as 'with_alias' from t2;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.*, t1.* as 'with_alias' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.* as 'with_alias', t1.* from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.* as 'with_alias', t1.* as 'alias2' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.* as 'with_alias', a, t1.* as 'alias2' from t1;
|
||||||
|
|
||||||
|
# other fields without alias
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select a, t1.* as 'with_alias' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.* as 'with_alias', a from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select a, t1.* as 'with_alias', b from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select (select d from t2 where d > a), t1.* as 'with_alias' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.* as 'with_alias', (select a from t2 where d > a) from t1;
|
||||||
|
|
||||||
|
# other fields with alias
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select a as 'x', t1.* as 'with_alias' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.* as 'with_alias', a as 'x' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select a as 'x', t1.* as 'with_alias', b as 'x' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select (select d from t2 where d > a) as 'x', t1.* as 'with_alias' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.* as 'with_alias', (select a from t2 where d > a) as 'x' from t1;
|
||||||
|
|
||||||
|
# some more subquery
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select (select t2.* as 'x' from t2) from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select a, (select t2.* as 'x' from t2) from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
select t1.*, (select t2.* as 'x' from t2) from t1;
|
||||||
|
|
||||||
|
# insert
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
insert into t3 select t1.* as 'with_alias' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
insert into t3 select t2.* as 'with_alias', 1, 2 from t2;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
insert into t3 select t2.* as 'with_alias', d as 'x', d as 'z' from t2;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
insert into t3 select t2.*, t2.* as 'with_alias', 3 from t2;
|
||||||
|
|
||||||
|
# create
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
create table t3 select t1.* as 'with_alias' from t1;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
create table t3 select t2.* as 'with_alias', 1, 2 from t2;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
create table t3 select t2.* as 'with_alias', d as 'x', d as 'z' from t2;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
create table t3 select t2.*, t2.* as 'with_alias', 3 from t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Valid queries without alias on wild
|
||||||
|
# (proof the above fail due to invalid aliasing)
|
||||||
|
#
|
||||||
|
|
||||||
|
select t1.* from t1;
|
||||||
|
select t2.* from t2;
|
||||||
|
select t1.*, t1.* from t1;
|
||||||
|
select t1.*, a, t1.* from t1;
|
||||||
|
|
||||||
|
# other fields without alias
|
||||||
|
select a, t1.* from t1;
|
||||||
|
select t1.*, a from t1;
|
||||||
|
select a, t1.*, b from t1;
|
||||||
|
select (select d from t2 where d > a), t1.* from t1;
|
||||||
|
select t1.*, (select a from t2 where d > a) from t1;
|
||||||
|
|
||||||
|
# other fields with alias
|
||||||
|
select a as 'x', t1.* from t1;
|
||||||
|
select t1.*, a as 'x' from t1;
|
||||||
|
select a as 'x', t1.*, b as 'x' from t1;
|
||||||
|
select (select d from t2 where d > a) as 'x', t1.* from t1;
|
||||||
|
select t1.*, (select a from t2 where d > a) as 'x' from t1;
|
||||||
|
|
||||||
|
# some more subquery
|
||||||
|
select (select t2.* from t2) from t1;
|
||||||
|
select a, (select t2.* from t2) from t1;
|
||||||
|
select t1.*, (select t2.* from t2) from t1;
|
||||||
|
|
||||||
|
# insert
|
||||||
|
insert into t3 select t1.* from t1;
|
||||||
|
insert into t3 select t2.*, 1, 2 from t2;
|
||||||
|
insert into t3 select t2.*, d as 'x', d as 'z' from t2;
|
||||||
|
insert into t3 select t2.*, t2.*, 3 from t2;
|
||||||
|
|
||||||
|
# create
|
||||||
|
create table t4 select t1.* from t1;
|
||||||
|
drop table t4;
|
||||||
|
create table t4 select t2.*, 1, 2 from t2;
|
||||||
|
drop table t4;
|
||||||
|
create table t4 select t2.*, d as 'x', d as 'z' from t2;
|
||||||
|
drop table t4;
|
||||||
|
|
||||||
|
# end
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
|
||||||
|
# End of 5.2 tests
|
||||||
|
@ -265,8 +265,8 @@ DELETE FROM t1, alias USING t1, t2 alias WHERE t1.a = alias.a;
|
|||||||
DELETE FROM t1, t2 USING t1, t2 alias WHERE t1.a = alias.a;
|
DELETE FROM t1, t2 USING t1, t2 alias WHERE t1.a = alias.a;
|
||||||
--error ER_PARSE_ERROR
|
--error ER_PARSE_ERROR
|
||||||
DELETE FROM db1.t1 alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
DELETE FROM db1.t1 alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
||||||
--error ER_UNKNOWN_TABLE
|
|
||||||
DELETE FROM alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
DELETE FROM alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
DELETE FROM db2.alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
DELETE FROM db2.alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
||||||
DELETE FROM t1 USING t1 WHERE a = 1;
|
DELETE FROM t1 USING t1 WHERE a = 1;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
@ -293,6 +293,159 @@ DROP FUNCTION f1;
|
|||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#27525: table not found when using multi-table-deletes with aliases over
|
||||||
|
# several databas
|
||||||
|
# Bug#21148: MULTI-DELETE fails to resolve a table by alias if it's from a
|
||||||
|
# different database
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP DATABASE IF EXISTS db1;
|
||||||
|
DROP DATABASE IF EXISTS db2;
|
||||||
|
DROP DATABASE IF EXISTS db3;
|
||||||
|
DROP DATABASE IF EXISTS db4;
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
DROP PROCEDURE IF EXISTS count;
|
||||||
|
--enable_warnings
|
||||||
|
USE test;
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
CREATE DATABASE db2;
|
||||||
|
|
||||||
|
CREATE TABLE db1.t1 (a INT, b INT);
|
||||||
|
INSERT INTO db1.t1 VALUES (1,1),(2,2),(3,3);
|
||||||
|
CREATE TABLE db1.t2 AS SELECT * FROM db1.t1;
|
||||||
|
CREATE TABLE db2.t1 AS SELECT * FROM db1.t2;
|
||||||
|
CREATE TABLE db2.t2 AS SELECT * FROM db2.t1;
|
||||||
|
CREATE TABLE t1 AS SELECT * FROM db2.t2;
|
||||||
|
CREATE TABLE t2 AS SELECT * FROM t1;
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
CREATE PROCEDURE count_rows()
|
||||||
|
BEGIN
|
||||||
|
SELECT COUNT(*) AS "COUNT(db1.t1)" FROM db1.t1;
|
||||||
|
SELECT COUNT(*) AS "COUNT(db1.t2)" FROM db1.t2;
|
||||||
|
SELECT COUNT(*) AS "COUNT(db2.t1)" FROM db2.t1;
|
||||||
|
SELECT COUNT(*) AS "COUNT(db2.t2)" FROM db2.t2;
|
||||||
|
SELECT COUNT(*) AS "COUNT(test.t1)" FROM test.t1;
|
||||||
|
SELECT COUNT(*) AS "COUNT(test.t2)" FROM test.t2;
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Testing without a selected database
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE DATABASE db3;
|
||||||
|
USE db3;
|
||||||
|
DROP DATABASE db3;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
# Detect missing table references
|
||||||
|
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE a1,a2 FROM db1.t1 AS a1, db2.t2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2 AS a2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE FROM a1,a2 USING db1.t1 AS a1, db2.t2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2 AS a2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
|
||||||
|
# Ambiguous table references
|
||||||
|
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE a1 FROM db1.a1, db2.t2 AS a1;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE a1 FROM a1, db1.t1 AS a1;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE t1 FROM db1.t1, db2.t1 AS a1;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE t1 FROM db1.t1 AS a1, db2.t1 AS a2;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
DELETE t1 FROM db1.t1, db2.t1;
|
||||||
|
|
||||||
|
# Test all again, now with a selected database
|
||||||
|
|
||||||
|
USE test;
|
||||||
|
|
||||||
|
# Detect missing table references
|
||||||
|
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE a1,a2 FROM db1.t1 AS a1, db2.t2;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE a1,a2 FROM db1.t1, db2.t2 AS a2;
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE FROM a1,a2 USING db1.t1 AS a1, db2.t2;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE FROM a1,a2 USING db1.t1, db2.t2 AS a2;
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
|
||||||
|
|
||||||
|
# Ambiguous table references
|
||||||
|
|
||||||
|
--error ER_NONUNIQ_TABLE
|
||||||
|
DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1;
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
DELETE a1 FROM db1.a1, db2.t2 AS a1;
|
||||||
|
--error ER_NONUNIQ_TABLE
|
||||||
|
DELETE a1 FROM a1, db1.t1 AS a1;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE t1 FROM db1.t1, db2.t1 AS a1;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE t1 FROM db1.t1 AS a1, db2.t1 AS a2;
|
||||||
|
--error ER_UNKNOWN_TABLE
|
||||||
|
DELETE t1 FROM db1.t1, db2.t1;
|
||||||
|
|
||||||
|
# Test multiple-table cross database deletes
|
||||||
|
|
||||||
|
DELETE t1 FROM db1.t2 AS t1, db2.t2 AS t2 WHERE t2.a = 1 AND t1.a = t2.a;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
CALL count_rows();
|
||||||
|
DELETE a1, a2 FROM db2.t1 AS a1, t2 AS a2 WHERE a1.a = 2 AND a2.a = 2;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
CALL count_rows();
|
||||||
|
|
||||||
|
DROP DATABASE db1;
|
||||||
|
DROP DATABASE db2;
|
||||||
|
DROP PROCEDURE count_rows;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
|
--echo # Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
|
||||||
--echo # merge table
|
--echo # merge table
|
||||||
|
@ -158,7 +158,7 @@ UPDATE `t1` AS P1 INNER JOIN (SELECT aaaa FROM `t1` GROUP BY N HAVING Count(M) >
|
|||||||
delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
--replace_result P2 p2
|
--replace_result P2 p2
|
||||||
--error ER_UNKNOWN_TABLE
|
--error ER_NON_UPDATABLE_TABLE
|
||||||
delete P1.*,P2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
delete P1.*,P2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||||
-- error 1054
|
-- error 1054
|
||||||
delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
--source include/not_embedded.inc
|
||||||
|
|
||||||
# Save the initial number of concurrent sessions
|
# Save the initial number of concurrent sessions
|
||||||
--source include/count_sessions.inc
|
--source include/count_sessions.inc
|
||||||
@ -22,6 +23,38 @@ disconnect con2;
|
|||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#10374 GET_LOCK does not let connection to close on the server side if it's aborted
|
||||||
|
#
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
SELECT GET_LOCK("dangling", 0);
|
||||||
|
connect(con1, localhost, root,,);
|
||||||
|
connection con1;
|
||||||
|
--send SELECT GET_LOCK('dangling', 3600);
|
||||||
|
connection default;
|
||||||
|
let $wait_condition=
|
||||||
|
SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = "User lock"
|
||||||
|
AND INFO = "SELECT GET_LOCK('dangling', 3600)";
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
dirty_close con1;
|
||||||
|
let $wait_condition=
|
||||||
|
SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = "User lock"
|
||||||
|
AND INFO = "SELECT GET_LOCK('dangling', 3600)";
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
connect(con1, localhost, root,,);
|
||||||
|
--send SELECT GET_LOCK('dangling', 3600);
|
||||||
|
connection default;
|
||||||
|
let $wait_condition=
|
||||||
|
SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = "User lock"
|
||||||
|
AND INFO = "SELECT GET_LOCK('dangling', 3600)";
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
SELECT RELEASE_LOCK('dangling');
|
||||||
|
connection con1;
|
||||||
|
--reap
|
||||||
|
connection default;
|
||||||
|
disconnect con1;
|
||||||
|
|
||||||
# Wait till all disconnects are completed
|
# Wait till all disconnects are completed
|
||||||
--source include/wait_until_count_sessions.inc
|
--source include/wait_until_count_sessions.inc
|
||||||
|
|
||||||
|
@ -169,4 +169,26 @@ SELECT TIMEDIFF(TIME('17:00:00'),TIME('17:00:00'))=TIME('00:00:00') AS 1Eq,
|
|||||||
TIMEDIFF(TIME('17:59:00'),TIME('17:00:00')),
|
TIMEDIFF(TIME('17:59:00'),TIME('17:00:00')),
|
||||||
TIMEDIFF(TIME('17:00:00'),TIME('17:59:00'));
|
TIMEDIFF(TIME('17:00:00'),TIME('17:59:00'));
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#42661 - sec_to_time() and signedness
|
||||||
|
#
|
||||||
|
|
||||||
|
SELECT sec_to_time(3020399)=TIME('838:59:59');
|
||||||
|
SELECT sec_to_time(-3020399)=TIME('-838:59:59');
|
||||||
|
SELECT sec_to_time(-3020399)='-838:59:59';
|
||||||
|
SELECT time(sec_to_time(-3020399))=TIME('-838:59:59');
|
||||||
|
SELECT time(sec_to_time(-3020399))=TIME('-838:59:58');
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#42662 - maketime() and signedness
|
||||||
|
#
|
||||||
|
|
||||||
|
# TIME(...) and CAST(... AS TIME) go through the same code-path here,
|
||||||
|
# but we'll explicitly show show that both work in case the ever changes.
|
||||||
|
SELECT maketime(-1,0,1)='-01:00:01';
|
||||||
|
SELECT TIME(maketime(-1,0,1))=CAST('-01:00:01' AS TIME);
|
||||||
|
SELECT maketime(-1,0,1)=CAST('-01:00:01' AS TIME);
|
||||||
|
SELECT maketime(1,0,1)=CAST('01:00:01' AS TIME);
|
||||||
|
SELECT maketime(1,0,1)=CAST('01:00:02' AS TIME);
|
||||||
|
|
||||||
# End of 5.0 tests
|
# End of 5.0 tests
|
||||||
|
@ -819,6 +819,16 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SECOND;
|
|||||||
--error ER_PARSE_ERROR
|
--error ER_PARSE_ERROR
|
||||||
SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
|
SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #36466:
|
||||||
|
# Adding days to day_microsecond changes interpretation of microseconds
|
||||||
|
#
|
||||||
|
|
||||||
|
# show that we treat fractions of seconds correctly (zerofill from right to
|
||||||
|
# six places) even if we left out fields on the left.
|
||||||
|
select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond);
|
||||||
|
select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond);
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
-- source include/not_embedded.inc
|
|
||||||
|
|
||||||
# Save the initial number of concurrent sessions
|
# Save the initial number of concurrent sessions
|
||||||
--source include/count_sessions.inc
|
--source include/count_sessions.inc
|
||||||
|
|
||||||
|
@ -366,6 +366,14 @@ remove_file $MYSQLTEST_VARDIR/tmp/bug31060.sql;
|
|||||||
--exec $MYSQL --server-arg=no-defaults test -e "quit"
|
--exec $MYSQL --server-arg=no-defaults test -e "quit"
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#26780: patch to add auto vertical output option to the cli.
|
||||||
|
#
|
||||||
|
# Make this wide enough that it will wrap almost everywhere.
|
||||||
|
--exec $MYSQL test --auto-vertical-output --table -e "SELECT 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0;"
|
||||||
|
# Too short to wrap.
|
||||||
|
--exec $MYSQL test --auto-vertical-output --table -e "SELECT 1;"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #25146: Some warnings/errors not shown when using --show-warnings
|
# Bug #25146: Some warnings/errors not shown when using --show-warnings
|
||||||
#
|
#
|
||||||
|
41
mysql-test/t/partition_sync.test
Normal file
41
mysql-test/t/partition_sync.test
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
--source include/have_partition.inc
|
||||||
|
# Save the initial number of concurrent sessions.
|
||||||
|
--source include/count_sessions.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #43867 ALTER TABLE on a partitioned table
|
||||||
|
--echo # causes unnecessary deadlocks
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int) PARTITION BY RANGE (a)
|
||||||
|
(PARTITION p0 VALUES LESS THAN (1),
|
||||||
|
PARTITION p1 VALUES LESS THAN (2));
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (0),(1);
|
||||||
|
|
||||||
|
connect(con1,localhost,root);
|
||||||
|
|
||||||
|
--echo # Connection 2
|
||||||
|
connection con1;
|
||||||
|
BEGIN;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--echo # Connection 1
|
||||||
|
connection default;
|
||||||
|
--error ER_DROP_PARTITION_NON_EXISTENT
|
||||||
|
ALTER TABLE t1 DROP PARTITION p3;
|
||||||
|
|
||||||
|
--echo # Connection 2
|
||||||
|
connection con1;
|
||||||
|
--echo # This failed with deadlock and should not do so.
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--echo # Connection 1
|
||||||
|
connection default;
|
||||||
|
disconnect con1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
# Check that all connections opened by test cases in this file are really
|
||||||
|
# gone so execution of other tests won't be affected by their presence.
|
||||||
|
--source include/wait_until_count_sessions.inc
|
25
mysql-test/t/rpl_mysqldump_slave.test
Normal file
25
mysql-test/t/rpl_mysqldump_slave.test
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
source include/master-slave.inc;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # New --dump-slave, --apply-slave-statements functionality
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
# There is a gap between when START SLAVE returns and when MASTER_LOG_FILE and
|
||||||
|
# MASTER_LOG_POS are set. Ensure that we don't call SHOW SLAVE STATUS during
|
||||||
|
# that gap.
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
use test;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
|
||||||
|
# Execute mysqldump with --dump-slave
|
||||||
|
--exec $MYSQL_DUMP_SLAVE --compact --dump-slave test
|
||||||
|
|
||||||
|
# Execute mysqldump with --dump-slave and --apply-slave-statements
|
||||||
|
--exec $MYSQL_DUMP_SLAVE --compact --dump-slave --apply-slave-statements test
|
||||||
|
|
||||||
|
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||||
|
# Execute mysqldump with --dump-slave ,--apply-slave-statements and --include-master-host-port
|
||||||
|
--exec $MYSQL_DUMP_SLAVE --compact --dump-slave --apply-slave-statements --include-master-host-port test
|
@ -7,10 +7,17 @@ let $shm= query_get_value("SHOW VARIABLES LIKE 'shared_memory'", Value, 1);
|
|||||||
if (`SELECT '$shm' != 'ON'`){
|
if (`SELECT '$shm' != 'ON'`){
|
||||||
skip No shm support;
|
skip No shm support;
|
||||||
}
|
}
|
||||||
|
let $shm_name= query_get_value("SHOW GLOBAL VARIABLES LIKE 'shared_memory_base_name'", Value, 1);
|
||||||
|
|
||||||
|
# Connect using SHM for testing
|
||||||
|
connect(shm_con,localhost,root,,,,$shm_name,SHM);
|
||||||
|
|
||||||
# Source select test case
|
# Source select test case
|
||||||
-- source include/common-tests.inc
|
-- source include/common-tests.inc
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
disconnect shm_con;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #24924: shared-memory-base-name that is too long causes buffer overflow
|
# Bug #24924: shared-memory-base-name that is too long causes buffer overflow
|
||||||
#
|
#
|
||||||
@ -20,7 +27,6 @@ if (`SELECT '$shm' != 'ON'`){
|
|||||||
# Bug #33899: Deadlock in mysql_real_query with shared memory connections
|
# Bug #33899: Deadlock in mysql_real_query with shared memory connections
|
||||||
#
|
#
|
||||||
|
|
||||||
let $name= query_get_value("SHOW GLOBAL VARIABLES LIKE 'shared_memory_base_name'", Value, 1);
|
|
||||||
let $stmt= `SELECT REPEAT('a', 2048)`;
|
let $stmt= `SELECT REPEAT('a', 2048)`;
|
||||||
|
|
||||||
SET @max_allowed_packet= @@global.max_allowed_packet;
|
SET @max_allowed_packet= @@global.max_allowed_packet;
|
||||||
@ -30,7 +36,7 @@ SET GLOBAL max_allowed_packet= 1024;
|
|||||||
SET GLOBAL net_buffer_length= 1024;
|
SET GLOBAL net_buffer_length= 1024;
|
||||||
|
|
||||||
--error 1
|
--error 1
|
||||||
--exec echo SELECT '$stmt'| $MYSQL --protocol=memory --shared-memory-base-name=$name 2>&1
|
--exec echo SELECT '$stmt'| $MYSQL --protocol=memory --shared-memory-base-name=$shm_name 2>&1
|
||||||
|
|
||||||
SET GLOBAL max_allowed_packet= @max_allowed_packet;
|
SET GLOBAL max_allowed_packet= @max_allowed_packet;
|
||||||
SET GLOBAL net_buffer_length= @net_buffer_length;
|
SET GLOBAL net_buffer_length= @net_buffer_length;
|
||||||
|
@ -2419,6 +2419,27 @@ end$$
|
|||||||
|
|
||||||
delimiter ;$$
|
delimiter ;$$
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#15192: "fatal errors" are caught by handlers in stored procedures
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists p1;
|
||||||
|
--enable_warnings
|
||||||
|
set @old_recursion_depth = @@max_sp_recursion_depth;
|
||||||
|
set @@max_sp_recursion_depth = 255;
|
||||||
|
delimiter |;
|
||||||
|
create procedure p1(a int)
|
||||||
|
begin
|
||||||
|
declare continue handler for 1436 -- ER_STACK_OVERRUN_NEED_MORE
|
||||||
|
select 'exception';
|
||||||
|
call p1(a+1);
|
||||||
|
end|
|
||||||
|
delimiter ;|
|
||||||
|
--error 0,ER_STACK_OVERRUN_NEED_MORE,ER_SP_RECURSION_LIMIT
|
||||||
|
call p1(1);
|
||||||
|
set @@max_sp_recursion_depth = @old_recursion_depth;
|
||||||
|
drop procedure p1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#NNNN: New bug synopsis
|
# BUG#NNNN: New bug synopsis
|
||||||
|
@ -8295,6 +8295,119 @@ SELECT * FROM t1 WHERE a = f1();
|
|||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#36649: Condition area is not properly cleaned up after stored routine invocation
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
CREATE PROCEDURE p1(a INT, b CHAR)
|
||||||
|
BEGIN
|
||||||
|
IF a > 0 THEN
|
||||||
|
CALL p1(a-1, 'ab');
|
||||||
|
ELSE
|
||||||
|
SELECT 1;
|
||||||
|
END IF;
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
SET @save_max_sp_recursion= @@max_sp_recursion_depth;
|
||||||
|
SET @@max_sp_recursion_depth= 5;
|
||||||
|
CALL p1(4, 'a');
|
||||||
|
SET @@max_sp_recursion_depth= @save_max_sp_recursion;
|
||||||
|
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ensure that rules for message list clean up are being respected.
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
CREATE PROCEDURE p1(a CHAR)
|
||||||
|
BEGIN
|
||||||
|
SELECT 1;
|
||||||
|
SELECT CAST('10 ' as UNSIGNED INTEGER);
|
||||||
|
SELECT 1;
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
CALL p1('data truncated parameter');
|
||||||
|
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cascading stored procedure/function calls.
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP PROCEDURE IF EXISTS p2;
|
||||||
|
DROP PROCEDURE IF EXISTS p3;
|
||||||
|
DROP PROCEDURE IF EXISTS p4;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
CALL p2()|
|
||||||
|
CREATE PROCEDURE p2()
|
||||||
|
CALL p3()|
|
||||||
|
CREATE PROCEDURE p3()
|
||||||
|
CALL p4()|
|
||||||
|
CREATE PROCEDURE p4()
|
||||||
|
BEGIN
|
||||||
|
SELECT 1;
|
||||||
|
SELECT CAST('10 ' as UNSIGNED INTEGER);
|
||||||
|
SELECT 2;
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
CALL p1();
|
||||||
|
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP PROCEDURE p2;
|
||||||
|
DROP PROCEDURE p3;
|
||||||
|
DROP PROCEDURE p4;
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
DROP FUNCTION IF EXISTS f3;
|
||||||
|
DROP FUNCTION IF EXISTS f4;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a CHAR(2));
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES ('aa');
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
CREATE FUNCTION f1() RETURNS CHAR
|
||||||
|
RETURN (SELECT f2())|
|
||||||
|
CREATE FUNCTION f2() RETURNS CHAR
|
||||||
|
RETURN (SELECT f3())|
|
||||||
|
CREATE FUNCTION f3() RETURNS CHAR
|
||||||
|
RETURN (SELECT f4())|
|
||||||
|
CREATE FUNCTION f4() RETURNS CHAR
|
||||||
|
BEGIN
|
||||||
|
RETURN (SELECT a FROM t1);
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
SELECT f1();
|
||||||
|
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
DROP FUNCTION f3;
|
||||||
|
DROP FUNCTION f4;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug#34197: CREATE PROCEDURE fails when COMMENT truncated in non
|
--echo # Bug#34197: CREATE PROCEDURE fails when COMMENT truncated in non
|
||||||
--echo # strict SQL mode
|
--echo # strict SQL mode
|
||||||
|
@ -2425,3 +2425,67 @@ DELETE FROM t1;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TEMPORARY TABLE t2;
|
DROP TEMPORARY TABLE t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#36649: Condition area is not properly cleaned up after stored routine invocation
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TRIGGER IF EXISTS trg1;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE a CHAR;
|
||||||
|
SELECT 'ab' INTO a;
|
||||||
|
SELECT 'ab' INTO a;
|
||||||
|
SELECT 'a' INTO a;
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
DROP TRIGGER trg1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Successive trigger actuations
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TRIGGER IF EXISTS trg1;
|
||||||
|
DROP TRIGGER IF EXISTS trg2;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
|
||||||
|
CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE trg1 CHAR;
|
||||||
|
SELECT 'ab' INTO trg1;
|
||||||
|
END|
|
||||||
|
|
||||||
|
CREATE TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE trg2 CHAR;
|
||||||
|
SELECT 'ab' INTO trg2;
|
||||||
|
END|
|
||||||
|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (0);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW WARNINGS;
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
|
||||||
|
DROP TRIGGER trg1;
|
||||||
|
DROP TRIGGER trg2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ drop table t1;
|
|||||||
# SELECT CAST(0.2359591234567e+30 AS TIME);
|
# SELECT CAST(0.2359591234567e+30 AS TIME);
|
||||||
# ##########################################################
|
# ##########################################################
|
||||||
|
|
||||||
# End of 4.1 tests
|
--echo End of 4.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#29555: Comparing time values as strings may lead to a wrong result.
|
# Bug#29555: Comparing time values as strings may lead to a wrong result.
|
||||||
@ -90,3 +90,22 @@ DROP TABLE t1;
|
|||||||
|
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#42664 - Sign ignored for TIME types when not comparing as longlong
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (f1 TIME);
|
||||||
|
INSERT INTO t1 VALUES ('24:00:00');
|
||||||
|
SELECT '24:00:00' = (SELECT f1 FROM t1);
|
||||||
|
SELECT CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1);
|
||||||
|
SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
|
||||||
|
TRUNCATE t1;
|
||||||
|
INSERT INTO t1 VALUES ('-24:00:00');
|
||||||
|
SELECT CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1);
|
||||||
|
SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
|
||||||
|
SELECT '-24:00:00' = (SELECT f1 FROM t1);
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo End of 6.0 tests
|
||||||
|
@ -155,7 +155,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
|
|||||||
DBUG_ASSERT(alloc_root_inited(mem_root));
|
DBUG_ASSERT(alloc_root_inited(mem_root));
|
||||||
|
|
||||||
length+=ALIGN_SIZE(sizeof(USED_MEM));
|
length+=ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME))))
|
if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR))))
|
||||||
{
|
{
|
||||||
if (mem_root->error_handler)
|
if (mem_root->error_handler)
|
||||||
(*mem_root->error_handler)();
|
(*mem_root->error_handler)();
|
||||||
@ -198,7 +198,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
|
|||||||
get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
|
get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
get_size= max(get_size, block_size);
|
get_size= max(get_size, block_size);
|
||||||
|
|
||||||
if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
|
if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME | ME_FATALERROR))))
|
||||||
{
|
{
|
||||||
if (mem_root->error_handler)
|
if (mem_root->error_handler)
|
||||||
(*mem_root->error_handler)();
|
(*mem_root->error_handler)();
|
||||||
|
@ -1222,6 +1222,14 @@ void my_print_help(const struct my_option *options)
|
|||||||
printf("%s", comment);
|
printf("%s", comment);
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
|
||||||
|
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
|
||||||
|
{
|
||||||
|
if (optp->def_value != 0)
|
||||||
|
{
|
||||||
|
printf("%*s(Defaults to on; use --skip-%s to disable.)\n", name_space, "", optp->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ Event_basic::Event_basic()
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("Event_basic::Event_basic");
|
DBUG_ENTER("Event_basic::Event_basic");
|
||||||
/* init memory root */
|
/* init memory root */
|
||||||
init_alloc_root(&mem_root, 256, 512);
|
init_sql_alloc(&mem_root, 256, 512);
|
||||||
dbname.str= name.str= NULL;
|
dbname.str= name.str= NULL;
|
||||||
dbname.length= name.length= 0;
|
dbname.length= name.length= 0;
|
||||||
time_zone= NULL;
|
time_zone= NULL;
|
||||||
|
350
sql/field.cc
350
sql/field.cc
@ -6819,86 +6819,6 @@ int Field_string::do_save_field_metadata(uchar *metadata_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Compare two packed keys
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
pack_cmp()
|
|
||||||
a New key
|
|
||||||
b Original key
|
|
||||||
length Key length
|
|
||||||
insert_or_update 1 if this is an insert or update
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
< 0 a < b
|
|
||||||
0 a = b
|
|
||||||
> 0 a > b
|
|
||||||
*/
|
|
||||||
|
|
||||||
int Field_string::pack_cmp(const uchar *a, const uchar *b, uint length,
|
|
||||||
my_bool insert_or_update)
|
|
||||||
{
|
|
||||||
uint a_length, b_length;
|
|
||||||
if (length > 255)
|
|
||||||
{
|
|
||||||
a_length= uint2korr(a);
|
|
||||||
b_length= uint2korr(b);
|
|
||||||
a+= 2;
|
|
||||||
b+= 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a_length= (uint) *a++;
|
|
||||||
b_length= (uint) *b++;
|
|
||||||
}
|
|
||||||
return field_charset->coll->strnncollsp(field_charset,
|
|
||||||
a, a_length,
|
|
||||||
b, b_length,
|
|
||||||
insert_or_update);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compare a packed key against row.
|
|
||||||
|
|
||||||
@param key Original key
|
|
||||||
@param length Key length. (May be less than field length)
|
|
||||||
@param insert_or_update 1 if this is an insert or update
|
|
||||||
|
|
||||||
@return
|
|
||||||
< 0 row < key
|
|
||||||
@return
|
|
||||||
0 row = key
|
|
||||||
@return
|
|
||||||
> 0 row > key
|
|
||||||
*/
|
|
||||||
|
|
||||||
int Field_string::pack_cmp(const uchar *key, uint length,
|
|
||||||
my_bool insert_or_update)
|
|
||||||
{
|
|
||||||
uint row_length, local_key_length;
|
|
||||||
uchar *end;
|
|
||||||
if (length > 255)
|
|
||||||
{
|
|
||||||
local_key_length= uint2korr(key);
|
|
||||||
key+= 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
local_key_length= (uint) *key++;
|
|
||||||
|
|
||||||
/* Only use 'length' of key, not field_length */
|
|
||||||
end= ptr + length;
|
|
||||||
while (end > ptr && end[-1] == ' ')
|
|
||||||
end--;
|
|
||||||
row_length= (uint) (end - ptr);
|
|
||||||
|
|
||||||
return field_charset->coll->strnncollsp(field_charset,
|
|
||||||
ptr, row_length,
|
|
||||||
key, local_key_length,
|
|
||||||
insert_or_update);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint Field_string::packed_col_length(const uchar *data_ptr, uint length)
|
uint Field_string::packed_col_length(const uchar *data_ptr, uint length)
|
||||||
{
|
{
|
||||||
if (length > 255)
|
if (length > 255)
|
||||||
@ -7258,90 +7178,6 @@ uchar *Field_varstring::pack(uchar *to, const uchar *from,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uchar *
|
|
||||||
Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length,
|
|
||||||
bool low_byte_first __attribute__((unused)))
|
|
||||||
{
|
|
||||||
uint length= length_bytes == 1 ? (uint) *key : uint2korr(key);
|
|
||||||
uint local_char_length= ((field_charset->mbmaxlen > 1) ?
|
|
||||||
max_length/field_charset->mbmaxlen : max_length);
|
|
||||||
key+= length_bytes;
|
|
||||||
if (length > local_char_length)
|
|
||||||
{
|
|
||||||
local_char_length= my_charpos(field_charset, key, key+length,
|
|
||||||
local_char_length);
|
|
||||||
set_if_smaller(length, local_char_length);
|
|
||||||
}
|
|
||||||
*to++= (char) (length & 255);
|
|
||||||
if (max_length > 255)
|
|
||||||
*to++= (char) (length >> 8);
|
|
||||||
if (length)
|
|
||||||
memcpy(to, key, length);
|
|
||||||
return to+length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Unpack a key into a record buffer.
|
|
||||||
|
|
||||||
A VARCHAR key has a maximum size of 64K-1.
|
|
||||||
In its packed form, the length field is one or two bytes long,
|
|
||||||
depending on 'max_length'.
|
|
||||||
|
|
||||||
@param to Pointer into the record buffer.
|
|
||||||
@param key Pointer to the packed key.
|
|
||||||
@param max_length Key length limit from key description.
|
|
||||||
|
|
||||||
@return
|
|
||||||
Pointer to end of 'key' (To the next key part if multi-segment key)
|
|
||||||
*/
|
|
||||||
|
|
||||||
const uchar *
|
|
||||||
Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length,
|
|
||||||
bool low_byte_first __attribute__((unused)))
|
|
||||||
{
|
|
||||||
/* get length of the blob key */
|
|
||||||
uint32 length= *key++;
|
|
||||||
if (max_length > 255)
|
|
||||||
length+= (*key++) << 8;
|
|
||||||
|
|
||||||
/* put the length into the record buffer */
|
|
||||||
if (length_bytes == 1)
|
|
||||||
*ptr= (uchar) length;
|
|
||||||
else
|
|
||||||
int2store(ptr, length);
|
|
||||||
memcpy(ptr + length_bytes, key, length);
|
|
||||||
return key + length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a packed key that will be used for storage in the index tree.
|
|
||||||
|
|
||||||
@param to Store packed key segment here
|
|
||||||
@param from Key segment (as given to index_read())
|
|
||||||
@param max_length Max length of key
|
|
||||||
|
|
||||||
@return
|
|
||||||
end of key storage
|
|
||||||
*/
|
|
||||||
|
|
||||||
uchar *
|
|
||||||
Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
|
|
||||||
bool low_byte_first __attribute__((unused)))
|
|
||||||
{
|
|
||||||
/* Key length is always stored as 2 bytes */
|
|
||||||
uint length= uint2korr(from);
|
|
||||||
if (length > max_length)
|
|
||||||
length= max_length;
|
|
||||||
*to++= (char) (length & 255);
|
|
||||||
if (max_length > 255)
|
|
||||||
*to++= (char) (length >> 8);
|
|
||||||
if (length)
|
|
||||||
memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
|
|
||||||
return to+length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Unpack a varstring field from row data.
|
Unpack a varstring field from row data.
|
||||||
|
|
||||||
@ -7384,59 +7220,6 @@ Field_varstring::unpack(uchar *to, const uchar *from,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Field_varstring::pack_cmp(const uchar *a, const uchar *b,
|
|
||||||
uint key_length_arg,
|
|
||||||
my_bool insert_or_update)
|
|
||||||
{
|
|
||||||
uint a_length, b_length;
|
|
||||||
if (key_length_arg > 255)
|
|
||||||
{
|
|
||||||
a_length=uint2korr(a); a+= 2;
|
|
||||||
b_length=uint2korr(b); b+= 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a_length= (uint) *a++;
|
|
||||||
b_length= (uint) *b++;
|
|
||||||
}
|
|
||||||
return field_charset->coll->strnncollsp(field_charset,
|
|
||||||
a, a_length,
|
|
||||||
b, b_length,
|
|
||||||
insert_or_update);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Field_varstring::pack_cmp(const uchar *b, uint key_length_arg,
|
|
||||||
my_bool insert_or_update)
|
|
||||||
{
|
|
||||||
uchar *a= ptr+ length_bytes;
|
|
||||||
uint a_length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
|
|
||||||
uint b_length;
|
|
||||||
uint local_char_length= ((field_charset->mbmaxlen > 1) ?
|
|
||||||
key_length_arg / field_charset->mbmaxlen :
|
|
||||||
key_length_arg);
|
|
||||||
|
|
||||||
if (key_length_arg > 255)
|
|
||||||
{
|
|
||||||
b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
b_length= (uint) *b++;
|
|
||||||
|
|
||||||
if (a_length > local_char_length)
|
|
||||||
{
|
|
||||||
local_char_length= my_charpos(field_charset, a, a+a_length,
|
|
||||||
local_char_length);
|
|
||||||
set_if_smaller(a_length, local_char_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return field_charset->coll->strnncollsp(field_charset,
|
|
||||||
a, a_length,
|
|
||||||
b, b_length,
|
|
||||||
insert_or_update);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint Field_varstring::packed_col_length(const uchar *data_ptr, uint length)
|
uint Field_varstring::packed_col_length(const uchar *data_ptr, uint length)
|
||||||
{
|
{
|
||||||
if (length > 255)
|
if (length > 255)
|
||||||
@ -8135,139 +7918,6 @@ const uchar *Field_blob::unpack(uchar *to,
|
|||||||
DBUG_RETURN(from + master_packlength + length);
|
DBUG_RETURN(from + master_packlength + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keys for blobs are like keys on varchars */
|
|
||||||
|
|
||||||
int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg,
|
|
||||||
my_bool insert_or_update)
|
|
||||||
{
|
|
||||||
uint a_length, b_length;
|
|
||||||
if (key_length_arg > 255)
|
|
||||||
{
|
|
||||||
a_length=uint2korr(a); a+=2;
|
|
||||||
b_length=uint2korr(b); b+=2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a_length= (uint) *a++;
|
|
||||||
b_length= (uint) *b++;
|
|
||||||
}
|
|
||||||
return field_charset->coll->strnncollsp(field_charset,
|
|
||||||
a, a_length,
|
|
||||||
b, b_length,
|
|
||||||
insert_or_update);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
|
|
||||||
my_bool insert_or_update)
|
|
||||||
{
|
|
||||||
uchar *a;
|
|
||||||
uint a_length, b_length;
|
|
||||||
memcpy_fixed(&a,ptr+packlength,sizeof(char*));
|
|
||||||
if (!a)
|
|
||||||
return key_length_arg > 0 ? -1 : 0;
|
|
||||||
|
|
||||||
a_length= get_length(ptr);
|
|
||||||
if (key_length_arg > 255)
|
|
||||||
{
|
|
||||||
b_length= uint2korr(b); b+=2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
b_length= (uint) *b++;
|
|
||||||
return field_charset->coll->strnncollsp(field_charset,
|
|
||||||
a, a_length,
|
|
||||||
b, b_length,
|
|
||||||
insert_or_update);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a packed key that will be used for storage from a MySQL row. */
|
|
||||||
|
|
||||||
uchar *
|
|
||||||
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
|
|
||||||
bool low_byte_first __attribute__((unused)))
|
|
||||||
{
|
|
||||||
uchar *save= ptr;
|
|
||||||
ptr= (uchar*) from;
|
|
||||||
uint32 length=get_length(); // Length of from string
|
|
||||||
uint local_char_length= ((field_charset->mbmaxlen > 1) ?
|
|
||||||
max_length/field_charset->mbmaxlen : max_length);
|
|
||||||
if (length)
|
|
||||||
get_ptr((uchar**) &from);
|
|
||||||
if (length > local_char_length)
|
|
||||||
local_char_length= my_charpos(field_charset, from, from+length,
|
|
||||||
local_char_length);
|
|
||||||
set_if_smaller(length, local_char_length);
|
|
||||||
*to++= (uchar) length;
|
|
||||||
if (max_length > 255) // 2 byte length
|
|
||||||
*to++= (uchar) (length >> 8);
|
|
||||||
memcpy(to, from, length);
|
|
||||||
ptr=save; // Restore org row pointer
|
|
||||||
return to+length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Unpack a blob key into a record buffer.
|
|
||||||
|
|
||||||
A blob key has a maximum size of 64K-1.
|
|
||||||
In its packed form, the length field is one or two bytes long,
|
|
||||||
depending on 'max_length'.
|
|
||||||
Depending on the maximum length of a blob, its length field is
|
|
||||||
put into 1 to 4 bytes. This is a property of the blob object,
|
|
||||||
described by 'packlength'.
|
|
||||||
Blobs are internally stored apart from the record buffer, which
|
|
||||||
contains a pointer to the blob buffer.
|
|
||||||
|
|
||||||
|
|
||||||
@param to Pointer into the record buffer.
|
|
||||||
@param from Pointer to the packed key.
|
|
||||||
@param max_length Key length limit from key description.
|
|
||||||
|
|
||||||
@return
|
|
||||||
Pointer into 'from' past the last byte copied from packed key.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const uchar *
|
|
||||||
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
|
|
||||||
bool low_byte_first __attribute__((unused)))
|
|
||||||
{
|
|
||||||
/* get length of the blob key */
|
|
||||||
uint32 length= *from++;
|
|
||||||
if (max_length > 255)
|
|
||||||
length+= *from++ << 8;
|
|
||||||
|
|
||||||
/* put the length into the record buffer */
|
|
||||||
put_length(to, length);
|
|
||||||
|
|
||||||
/* put the address of the blob buffer or NULL */
|
|
||||||
if (length)
|
|
||||||
memcpy_fixed(to + packlength, &from, sizeof(from));
|
|
||||||
else
|
|
||||||
bzero(to + packlength, sizeof(from));
|
|
||||||
|
|
||||||
/* point to first byte of next field in 'from' */
|
|
||||||
return from + length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Create a packed key that will be used for storage from a MySQL key. */
|
|
||||||
|
|
||||||
uchar *
|
|
||||||
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
|
|
||||||
bool low_byte_first __attribute__((unused)))
|
|
||||||
{
|
|
||||||
uint length=uint2korr(from);
|
|
||||||
if (length > max_length)
|
|
||||||
length=max_length;
|
|
||||||
*to++= (char) (length & 255);
|
|
||||||
if (max_length > 255)
|
|
||||||
*to++= (char) (length >> 8);
|
|
||||||
if (length)
|
|
||||||
memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
|
|
||||||
return to+length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint Field_blob::packed_col_length(const uchar *data_ptr, uint length)
|
uint Field_blob::packed_col_length(const uchar *data_ptr, uint length)
|
||||||
{
|
{
|
||||||
if (length > 255)
|
if (length > 255)
|
||||||
|
42
sql/field.h
42
sql/field.h
@ -25,7 +25,6 @@
|
|||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NOT_FIXED_DEC 31
|
|
||||||
#define DATETIME_DEC 6
|
#define DATETIME_DEC 6
|
||||||
const uint32 max_field_size= (uint32) 4294967295U;
|
const uint32 max_field_size= (uint32) 4294967295U;
|
||||||
|
|
||||||
@ -410,32 +409,11 @@ public:
|
|||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uchar *pack_key(uchar* to, const uchar *from,
|
|
||||||
uint max_length, bool low_byte_first)
|
|
||||||
{
|
|
||||||
return pack(to, from, max_length, low_byte_first);
|
|
||||||
}
|
|
||||||
virtual uchar *pack_key_from_key_image(uchar* to, const uchar *from,
|
|
||||||
uint max_length, bool low_byte_first)
|
|
||||||
{
|
|
||||||
return pack(to, from, max_length, low_byte_first);
|
|
||||||
}
|
|
||||||
virtual const uchar *unpack_key(uchar* to, const uchar *from,
|
|
||||||
uint max_length, bool low_byte_first)
|
|
||||||
{
|
|
||||||
return unpack(to, from, max_length, low_byte_first);
|
|
||||||
}
|
|
||||||
virtual uint packed_col_length(const uchar *to, uint length)
|
virtual uint packed_col_length(const uchar *to, uint length)
|
||||||
{ return length;}
|
{ return length;}
|
||||||
virtual uint max_packed_col_length(uint max_length)
|
virtual uint max_packed_col_length(uint max_length)
|
||||||
{ return max_length;}
|
{ return max_length;}
|
||||||
|
|
||||||
virtual int pack_cmp(const uchar *a,const uchar *b, uint key_length_arg,
|
|
||||||
my_bool insert_or_update)
|
|
||||||
{ return cmp(a,b); }
|
|
||||||
virtual int pack_cmp(const uchar *b, uint key_length_arg,
|
|
||||||
my_bool insert_or_update)
|
|
||||||
{ return cmp(ptr,b); }
|
|
||||||
uint offset(uchar *record)
|
uint offset(uchar *record)
|
||||||
{
|
{
|
||||||
return (uint) (ptr - record);
|
return (uint) (ptr - record);
|
||||||
@ -1503,9 +1481,6 @@ public:
|
|||||||
int compatible_field_size(uint field_metadata,
|
int compatible_field_size(uint field_metadata,
|
||||||
const Relay_log_info *rli);
|
const Relay_log_info *rli);
|
||||||
uint row_pack_length() { return (field_length + 1); }
|
uint row_pack_length() { return (field_length + 1); }
|
||||||
int pack_cmp(const uchar *a,const uchar *b,uint key_length,
|
|
||||||
my_bool insert_or_update);
|
|
||||||
int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update);
|
|
||||||
uint packed_col_length(const uchar *to, uint length);
|
uint packed_col_length(const uchar *to, uint length);
|
||||||
uint max_packed_col_length(uint max_length);
|
uint max_packed_col_length(uint max_length);
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
@ -1579,16 +1554,8 @@ public:
|
|||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
virtual uchar *pack(uchar *to, const uchar *from,
|
virtual uchar *pack(uchar *to, const uchar *from,
|
||||||
uint max_length, bool low_byte_first);
|
uint max_length, bool low_byte_first);
|
||||||
uchar *pack_key(uchar *to, const uchar *from, uint max_length, bool low_byte_first);
|
|
||||||
uchar *pack_key_from_key_image(uchar* to, const uchar *from,
|
|
||||||
uint max_length, bool low_byte_first);
|
|
||||||
virtual const uchar *unpack(uchar* to, const uchar *from,
|
virtual const uchar *unpack(uchar* to, const uchar *from,
|
||||||
uint param_data, bool low_byte_first);
|
uint param_data, bool low_byte_first);
|
||||||
const uchar *unpack_key(uchar* to, const uchar *from,
|
|
||||||
uint max_length, bool low_byte_first);
|
|
||||||
int pack_cmp(const uchar *a, const uchar *b, uint key_length,
|
|
||||||
my_bool insert_or_update);
|
|
||||||
int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update);
|
|
||||||
int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L);
|
int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L);
|
||||||
int key_cmp(const uchar *,const uchar*);
|
int key_cmp(const uchar *,const uchar*);
|
||||||
int key_cmp(const uchar *str, uint length);
|
int key_cmp(const uchar *str, uint length);
|
||||||
@ -1764,17 +1731,8 @@ public:
|
|||||||
}
|
}
|
||||||
virtual uchar *pack(uchar *to, const uchar *from,
|
virtual uchar *pack(uchar *to, const uchar *from,
|
||||||
uint max_length, bool low_byte_first);
|
uint max_length, bool low_byte_first);
|
||||||
uchar *pack_key(uchar *to, const uchar *from,
|
|
||||||
uint max_length, bool low_byte_first);
|
|
||||||
uchar *pack_key_from_key_image(uchar* to, const uchar *from,
|
|
||||||
uint max_length, bool low_byte_first);
|
|
||||||
virtual const uchar *unpack(uchar *to, const uchar *from,
|
virtual const uchar *unpack(uchar *to, const uchar *from,
|
||||||
uint param_data, bool low_byte_first);
|
uint param_data, bool low_byte_first);
|
||||||
const uchar *unpack_key(uchar* to, const uchar *from,
|
|
||||||
uint max_length, bool low_byte_first);
|
|
||||||
int pack_cmp(const uchar *a, const uchar *b, uint key_length,
|
|
||||||
my_bool insert_or_update);
|
|
||||||
int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update);
|
|
||||||
uint packed_col_length(const uchar *col_ptr, uint length);
|
uint packed_col_length(const uchar *col_ptr, uint length);
|
||||||
uint max_packed_col_length(uint max_length);
|
uint max_packed_col_length(uint max_length);
|
||||||
void free() { value.free(); }
|
void free() { value.free(); }
|
||||||
|
@ -1980,8 +1980,7 @@ partition_element *ha_partition::find_partition_element(uint part_id)
|
|||||||
return part_elem;
|
return part_elem;
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||||
current_thd->fatal_error(); // Abort
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -855,7 +855,8 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
*is_null= item->get_time(<ime);
|
*is_null= item->get_time(<ime);
|
||||||
value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(<ime) : 0;
|
value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(<ime) *
|
||||||
|
(ltime.neg ? -1 : 1) : 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Do not cache GET_USER_VAR() function as its const_item() may return TRUE
|
Do not cache GET_USER_VAR() function as its const_item() may return TRUE
|
||||||
|
@ -3474,6 +3474,48 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Wait for a given condition to be signaled within the specified timeout.
|
||||||
|
|
||||||
|
@param cond the condition variable to wait on
|
||||||
|
@param lock the associated mutex
|
||||||
|
@param abstime the amount of time in seconds to wait
|
||||||
|
|
||||||
|
@retval return value from pthread_cond_timedwait
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INTERRUPT_INTERVAL (5 * ULL(1000000000))
|
||||||
|
|
||||||
|
static int interruptible_wait(THD *thd, pthread_cond_t *cond,
|
||||||
|
pthread_mutex_t *lock, double time)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
struct timespec abstime;
|
||||||
|
ulonglong slice, timeout= (ulonglong) (time * 1000000000.0);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Wait for a fixed interval. */
|
||||||
|
if (timeout > INTERRUPT_INTERVAL)
|
||||||
|
slice= INTERRUPT_INTERVAL;
|
||||||
|
else
|
||||||
|
slice= timeout;
|
||||||
|
|
||||||
|
timeout-= slice;
|
||||||
|
set_timespec_nsec(abstime, slice);
|
||||||
|
error= pthread_cond_timedwait(cond, lock, &abstime);
|
||||||
|
if (error == ETIMEDOUT || error == ETIME)
|
||||||
|
{
|
||||||
|
/* Return error if timed out or connection is broken. */
|
||||||
|
if (!timeout || !thd->is_connected())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (error && timeout);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a user level lock. If the thread has an old lock this is first released.
|
Get a user level lock. If the thread has an old lock this is first released.
|
||||||
|
|
||||||
@ -3489,8 +3531,7 @@ longlong Item_func_get_lock::val_int()
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
String *res=args[0]->val_str(&value);
|
String *res=args[0]->val_str(&value);
|
||||||
longlong timeout=args[1]->val_int();
|
double timeout= args[1]->val_real();
|
||||||
struct timespec abstime;
|
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
User_level_lock *ull;
|
User_level_lock *ull;
|
||||||
int error;
|
int error;
|
||||||
@ -3554,12 +3595,11 @@ longlong Item_func_get_lock::val_int()
|
|||||||
thd->mysys_var->current_mutex= &LOCK_user_locks;
|
thd->mysys_var->current_mutex= &LOCK_user_locks;
|
||||||
thd->mysys_var->current_cond= &ull->cond;
|
thd->mysys_var->current_cond= &ull->cond;
|
||||||
|
|
||||||
set_timespec(abstime,timeout);
|
|
||||||
error= 0;
|
error= 0;
|
||||||
while (ull->locked && !thd->killed)
|
while (ull->locked && !thd->killed)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("waiting on lock"));
|
DBUG_PRINT("info", ("waiting on lock"));
|
||||||
error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime);
|
error= interruptible_wait(thd, &ull->cond, &LOCK_user_locks, timeout);
|
||||||
if (error == ETIMEDOUT || error == ETIME)
|
if (error == ETIMEDOUT || error == ETIME)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("lock wait timeout"));
|
DBUG_PRINT("info", ("lock wait timeout"));
|
||||||
@ -3754,13 +3794,13 @@ void Item_func_benchmark::print(String *str, enum_query_type query_type)
|
|||||||
longlong Item_func_sleep::val_int()
|
longlong Item_func_sleep::val_int()
|
||||||
{
|
{
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
struct timespec abstime;
|
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
|
double timeout;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
|
||||||
double time= args[0]->val_real();
|
timeout= args[0]->val_real();
|
||||||
/*
|
/*
|
||||||
On 64-bit OSX pthread_cond_timedwait() waits forever
|
On 64-bit OSX pthread_cond_timedwait() waits forever
|
||||||
if passed abstime time has already been exceeded by
|
if passed abstime time has already been exceeded by
|
||||||
@ -3770,10 +3810,8 @@ longlong Item_func_sleep::val_int()
|
|||||||
We assume that the lines between this test and the call
|
We assume that the lines between this test and the call
|
||||||
to pthread_cond_timedwait() will be executed in less than 0.00001 sec.
|
to pthread_cond_timedwait() will be executed in less than 0.00001 sec.
|
||||||
*/
|
*/
|
||||||
if (time < 0.00001)
|
if (timeout < 0.00001)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
set_timespec_nsec(abstime, (ulonglong)(time * ULL(1000000000)));
|
|
||||||
|
|
||||||
pthread_cond_init(&cond, NULL);
|
pthread_cond_init(&cond, NULL);
|
||||||
pthread_mutex_lock(&LOCK_user_locks);
|
pthread_mutex_lock(&LOCK_user_locks);
|
||||||
@ -3785,7 +3823,7 @@ longlong Item_func_sleep::val_int()
|
|||||||
error= 0;
|
error= 0;
|
||||||
while (!thd->killed)
|
while (!thd->killed)
|
||||||
{
|
{
|
||||||
error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime);
|
error= interruptible_wait(thd, &cond, &LOCK_user_locks, timeout);
|
||||||
if (error == ETIMEDOUT || error == ETIME)
|
if (error == ETIMEDOUT || error == ETIME)
|
||||||
break;
|
break;
|
||||||
error= 0;
|
error= 0;
|
||||||
@ -3817,7 +3855,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
|
|||||||
uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
|
uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
|
||||||
if (!my_hash_inited(hash))
|
if (!my_hash_inited(hash))
|
||||||
return 0;
|
return 0;
|
||||||
if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME))))
|
if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME | ME_FATALERROR))))
|
||||||
return 0;
|
return 0;
|
||||||
entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
|
entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
|
||||||
extra_size;
|
extra_size;
|
||||||
@ -3955,6 +3993,8 @@ bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
|
|||||||
@param dv derivation for new value
|
@param dv derivation for new value
|
||||||
@param unsigned_arg indiates if a value of type INT_RESULT is unsigned
|
@param unsigned_arg indiates if a value of type INT_RESULT is unsigned
|
||||||
|
|
||||||
|
@note Sets error and fatal error if allocation fails.
|
||||||
|
|
||||||
@retval
|
@retval
|
||||||
false success
|
false success
|
||||||
@retval
|
@retval
|
||||||
@ -3998,7 +4038,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
|
|||||||
if (entry->value == pos)
|
if (entry->value == pos)
|
||||||
entry->value=0;
|
entry->value=0;
|
||||||
entry->value= (char*) my_realloc(entry->value, length,
|
entry->value= (char*) my_realloc(entry->value, length,
|
||||||
MYF(MY_ALLOW_ZERO_PTR | MY_WME));
|
MYF(MY_ALLOW_ZERO_PTR | MY_WME |
|
||||||
|
ME_FATALERROR));
|
||||||
if (!entry->value)
|
if (!entry->value)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -4035,7 +4076,6 @@ Item_func_set_user_var::update_hash(void *ptr, uint length,
|
|||||||
if (::update_hash(entry, (null_value= args[0]->null_value),
|
if (::update_hash(entry, (null_value= args[0]->null_value),
|
||||||
ptr, length, res_type, cs, dv, unsigned_arg))
|
ptr, length, res_type, cs, dv, unsigned_arg))
|
||||||
{
|
{
|
||||||
current_thd->fatal_error(); // Probably end of memory
|
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -4768,11 +4808,6 @@ void Item_func_get_user_var::fix_length_and_dec()
|
|||||||
m_cached_result_type= STRING_RESULT;
|
m_cached_result_type= STRING_RESULT;
|
||||||
max_length= MAX_BLOB_WIDTH;
|
max_length= MAX_BLOB_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error)
|
|
||||||
thd->fatal_error();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4843,18 +4878,16 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
|
|||||||
|
|
||||||
void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs)
|
void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs)
|
||||||
{
|
{
|
||||||
if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs,
|
::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs,
|
||||||
DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
|
DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
|
||||||
current_thd->fatal_error(); // Probably end of memory
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_user_var_as_out_param::set_value(const char *str, uint length,
|
void Item_user_var_as_out_param::set_value(const char *str, uint length,
|
||||||
CHARSET_INFO* cs)
|
CHARSET_INFO* cs)
|
||||||
{
|
{
|
||||||
if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
|
::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
|
||||||
DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
|
DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
|
||||||
current_thd->fatal_error(); // Probably end of memory
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1740,8 +1740,6 @@ subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
|
|||||||
:subselect_engine(item_arg, result_arg)
|
:subselect_engine(item_arg, result_arg)
|
||||||
{
|
{
|
||||||
unit= u;
|
unit= u;
|
||||||
if (!result_arg) //out of memory
|
|
||||||
current_thd->fatal_error();
|
|
||||||
unit->item= item_arg;
|
unit->item= item_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1753,10 +1751,7 @@ int subselect_single_select_engine::prepare()
|
|||||||
join= new JOIN(thd, select_lex->item_list,
|
join= new JOIN(thd, select_lex->item_list,
|
||||||
select_lex->options | SELECT_NO_UNLOCK, result);
|
select_lex->options | SELECT_NO_UNLOCK, result);
|
||||||
if (!join || !result)
|
if (!join || !result)
|
||||||
{
|
return 1; /* Fatal error is set already. */
|
||||||
thd->fatal_error(); //out of memory
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
prepared= 1;
|
prepared= 1;
|
||||||
SELECT_LEX *save_select= thd->lex->current_select;
|
SELECT_LEX *save_select= thd->lex->current_select;
|
||||||
thd->lex->current_select= select_lex;
|
thd->lex->current_select= select_lex;
|
||||||
|
@ -865,6 +865,8 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
|||||||
{
|
{
|
||||||
const char *end=str+length;
|
const char *end=str+length;
|
||||||
uint i;
|
uint i;
|
||||||
|
long msec_length= 0;
|
||||||
|
|
||||||
while (str != end && !my_isdigit(cs,*str))
|
while (str != end && !my_isdigit(cs,*str))
|
||||||
str++;
|
str++;
|
||||||
|
|
||||||
@ -874,12 +876,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
|||||||
const char *start= str;
|
const char *start= str;
|
||||||
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
|
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
|
||||||
value= value*LL(10) + (longlong) (*str - '0');
|
value= value*LL(10) + (longlong) (*str - '0');
|
||||||
if (transform_msec && i == count - 1) // microseconds always last
|
msec_length= 6 - (str - start);
|
||||||
{
|
|
||||||
long msec_length= 6 - (uint) (str - start);
|
|
||||||
if (msec_length > 0)
|
|
||||||
value*= (long) log_10_int[msec_length];
|
|
||||||
}
|
|
||||||
values[i]= value;
|
values[i]= value;
|
||||||
while (str != end && !my_isdigit(cs,*str))
|
while (str != end && !my_isdigit(cs,*str))
|
||||||
str++;
|
str++;
|
||||||
@ -893,6 +890,10 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (transform_msec && msec_length > 0)
|
||||||
|
values[count - 1] *= (long) log_10_int[msec_length];
|
||||||
|
|
||||||
return (str != end);
|
return (str != end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1854,7 +1855,7 @@ longlong Item_func_sec_to_time::val_int()
|
|||||||
sec_to_time(arg_val, args[0]->unsigned_flag, <ime);
|
sec_to_time(arg_val, args[0]->unsigned_flag, <ime);
|
||||||
|
|
||||||
return (ltime.neg ? -1 : 1) *
|
return (ltime.neg ? -1 : 1) *
|
||||||
((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
|
(longlong) ((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2666,7 +2667,8 @@ longlong Item_time_typecast::val_int()
|
|||||||
null_value= 1;
|
null_value= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ltime.hour * 10000L + ltime.minute * 100 + ltime.second;
|
return (ltime.neg ? -1 : 1) *
|
||||||
|
(longlong) ((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
String *Item_time_typecast::val_str(String *str)
|
String *Item_time_typecast::val_str(String *str)
|
||||||
|
@ -1074,9 +1074,9 @@ inline bool check_access(THD *thd, ulong access, const char *db,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline bool check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables,
|
inline bool check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables,
|
||||||
bool no_errors,
|
|
||||||
bool any_combination_of_privileges_will_do,
|
bool any_combination_of_privileges_will_do,
|
||||||
uint number)
|
uint number,
|
||||||
|
bool no_errors)
|
||||||
{ return false; }
|
{ return false; }
|
||||||
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
|
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
|
||||||
|
|
||||||
|
@ -175,8 +175,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
|||||||
error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
||||||
if(error)
|
if(error)
|
||||||
{
|
{
|
||||||
tl->table->file->print_error(error, MYF(0));
|
tl->table->file->print_error(error, MYF(ME_FATALERROR));
|
||||||
tl->table->in_use->fatal_error();
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
count*= tl->table->file->stats.records;
|
count*= tl->table->file->stats.records;
|
||||||
@ -427,8 +426,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
|||||||
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
|
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
|
||||||
return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
|
return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
|
||||||
/* HA_ERR_LOCK_DEADLOCK or some other error */
|
/* HA_ERR_LOCK_DEADLOCK or some other error */
|
||||||
table->file->print_error(error, MYF(0));
|
table->file->print_error(error, MYF(ME_FATALERROR));
|
||||||
table->in_use->fatal_error();
|
|
||||||
return(error);
|
return(error);
|
||||||
}
|
}
|
||||||
removed_tables|= table->map;
|
removed_tables|= table->map;
|
||||||
|
@ -4880,6 +4880,7 @@ ER_ZLIB_Z_DATA_ERROR
|
|||||||
spa "ZLIB: Dato de entrada fué corrompido para zlib"
|
spa "ZLIB: Dato de entrada fué corrompido para zlib"
|
||||||
ER_CUT_VALUE_GROUP_CONCAT
|
ER_CUT_VALUE_GROUP_CONCAT
|
||||||
eng "Row %u was cut by GROUP_CONCAT()"
|
eng "Row %u was cut by GROUP_CONCAT()"
|
||||||
|
por "Linha %u foi cortada por GROUP_CONCAT()"
|
||||||
ER_WARN_TOO_FEW_RECORDS 01000
|
ER_WARN_TOO_FEW_RECORDS 01000
|
||||||
eng "Row %ld doesn't contain data for all columns"
|
eng "Row %ld doesn't contain data for all columns"
|
||||||
ger "Zeile %ld enthält nicht für alle Felder Daten"
|
ger "Zeile %ld enthält nicht für alle Felder Daten"
|
||||||
|
@ -1711,6 +1711,9 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
|||||||
ret= SP_OK;
|
ret= SP_OK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
/* Query might have been killed, don't set error. */
|
||||||
|
if (thd->killed)
|
||||||
|
break;
|
||||||
/*
|
/*
|
||||||
Any error when loading an existing routine is either some problem
|
Any error when loading an existing routine is either some problem
|
||||||
with the mysql.proc table, or a parse error because the contents
|
with the mysql.proc table, or a parse error because the contents
|
||||||
|
@ -1086,7 +1086,6 @@ sp_head::execute(THD *thd)
|
|||||||
Item_change_list old_change_list;
|
Item_change_list old_change_list;
|
||||||
String old_packet;
|
String old_packet;
|
||||||
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
|
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
|
||||||
|
|
||||||
Object_creation_ctx *saved_creation_ctx;
|
Object_creation_ctx *saved_creation_ctx;
|
||||||
Warning_info *saved_warning_info, warning_info(thd->warning_info->warn_id());
|
Warning_info *saved_warning_info, warning_info(thd->warning_info->warn_id());
|
||||||
|
|
||||||
@ -4017,10 +4016,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex,
|
|||||||
TABLE_LIST *table;
|
TABLE_LIST *table;
|
||||||
|
|
||||||
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
|
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
|
||||||
{
|
|
||||||
thd->fatal_error();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
table->db_length= strlen(db);
|
table->db_length= strlen(db);
|
||||||
table->db= thd->strmake(db, table->db_length);
|
table->db= thd->strmake(db, table->db_length);
|
||||||
table->table_name_length= strlen(name);
|
table->table_name_length= strlen(name);
|
||||||
|
@ -1331,12 +1331,12 @@ end:
|
|||||||
@param thd Pointer to the thread handler
|
@param thd Pointer to the thread handler
|
||||||
@param sql A pointer to the sql statement *
|
@param sql A pointer to the sql statement *
|
||||||
@param query_length Length of the statement in characters
|
@param query_length Length of the statement in characters
|
||||||
|
|
||||||
@return status code
|
@return status code
|
||||||
@retval 1 Query was not cached.
|
@retval 0 Query was not cached.
|
||||||
@retval 0 The query was cached and user was sent the result.
|
@retval 1 The query was cached and user was sent the result.
|
||||||
@retval -1 The query was cached but we didn't have rights to use it.
|
@retval -1 The query was cached but we didn't have rights to use it.
|
||||||
|
|
||||||
In case of -1, no error is sent to the client.
|
In case of -1, no error is sent to the client.
|
||||||
|
|
||||||
*) The buffer must be allocated memory of size:
|
*) The buffer must be allocated memory of size:
|
||||||
|
@ -1982,9 +1982,15 @@ public:
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
inline bool vio_ok() const { return net.vio != 0; }
|
inline bool vio_ok() const { return net.vio != 0; }
|
||||||
|
/** Return FALSE if connection to client is broken. */
|
||||||
|
bool is_connected()
|
||||||
|
{
|
||||||
|
return vio_ok() ? vio_is_connected(net.vio) : FALSE;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
void clear_error();
|
void clear_error();
|
||||||
inline bool vio_ok() const { return true; }
|
inline bool vio_ok() const { return TRUE; }
|
||||||
|
inline bool is_connected() { return TRUE; }
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
Mark the current error as fatal. Warning: this does not
|
Mark the current error as fatal. Warning: this does not
|
||||||
@ -1993,6 +1999,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline void fatal_error()
|
inline void fatal_error()
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(main_da.is_error());
|
||||||
is_fatal_error= 1;
|
is_fatal_error= 1;
|
||||||
DBUG_PRINT("error",("Fatal error set"));
|
DBUG_PRINT("error",("Fatal error set"));
|
||||||
}
|
}
|
||||||
@ -2158,7 +2165,10 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
x_free(db);
|
x_free(db);
|
||||||
db= new_db ? my_strndup(new_db, new_db_len, MYF(MY_WME)) : NULL;
|
if (new_db)
|
||||||
|
db= my_strndup(new_db, new_db_len, MYF(MY_WME | ME_FATALERROR));
|
||||||
|
else
|
||||||
|
db= NULL;
|
||||||
}
|
}
|
||||||
db_length= db ? new_db_len : 0;
|
db_length= db ? new_db_len : 0;
|
||||||
return new_db && !db;
|
return new_db && !db;
|
||||||
|
@ -1922,20 +1922,17 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
|||||||
if (! (di= find_handler(thd, table_list)))
|
if (! (di= find_handler(thd, table_list)))
|
||||||
{
|
{
|
||||||
if (!(di= new Delayed_insert()))
|
if (!(di= new Delayed_insert()))
|
||||||
{
|
|
||||||
thd->fatal_error();
|
|
||||||
goto end_create;
|
goto end_create;
|
||||||
}
|
|
||||||
pthread_mutex_lock(&LOCK_thread_count);
|
pthread_mutex_lock(&LOCK_thread_count);
|
||||||
thread_count++;
|
thread_count++;
|
||||||
pthread_mutex_unlock(&LOCK_thread_count);
|
pthread_mutex_unlock(&LOCK_thread_count);
|
||||||
di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
|
di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
|
||||||
di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0);
|
di->thd.set_query(my_strdup(table_list->table_name,
|
||||||
|
MYF(MY_WME | ME_FATALERROR)), 0);
|
||||||
if (di->thd.db == NULL || di->thd.query() == NULL)
|
if (di->thd.db == NULL || di->thd.query() == NULL)
|
||||||
{
|
{
|
||||||
/* The error is reported */
|
/* The error is reported */
|
||||||
delete di;
|
delete di;
|
||||||
thd->fatal_error();
|
|
||||||
goto end_create;
|
goto end_create;
|
||||||
}
|
}
|
||||||
di->table_list= *table_list; // Needed to open table
|
di->table_list= *table_list; // Needed to open table
|
||||||
@ -1953,8 +1950,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
|||||||
pthread_mutex_unlock(&di->mutex);
|
pthread_mutex_unlock(&di->mutex);
|
||||||
di->unlock();
|
di->unlock();
|
||||||
delete di;
|
delete di;
|
||||||
my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
|
my_error(ER_CANT_CREATE_THREAD, MYF(ME_FATALERROR), error);
|
||||||
thd->fatal_error();
|
|
||||||
goto end_create;
|
goto end_create;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2331,8 +2327,8 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
|
|||||||
}
|
}
|
||||||
if (!(di->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED))
|
if (!(di->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED))
|
||||||
{
|
{
|
||||||
thd->fatal_error();
|
my_error(ER_DELAYED_NOT_SUPPORTED, MYF(ME_FATALERROR),
|
||||||
my_error(ER_DELAYED_NOT_SUPPORTED, MYF(0), di->table_list.table_name);
|
di->table_list.table_name);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (di->table->triggers)
|
if (di->table->triggers)
|
||||||
|
@ -458,7 +458,7 @@ struct ilink
|
|||||||
struct ilink **prev,*next;
|
struct ilink **prev,*next;
|
||||||
static void *operator new(size_t size) throw ()
|
static void *operator new(size_t size) throw ()
|
||||||
{
|
{
|
||||||
return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE));
|
return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE | ME_FATALERROR));
|
||||||
}
|
}
|
||||||
static void operator delete(void* ptr_arg, size_t size)
|
static void operator delete(void* ptr_arg, size_t size)
|
||||||
{
|
{
|
||||||
|
126
sql/sql_parse.cc
126
sql/sql_parse.cc
@ -1369,54 +1369,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
thd->stmt_da->disable_status(); // Don't send anything back
|
thd->stmt_da->disable_status(); // Don't send anything back
|
||||||
error=TRUE; // End server
|
error=TRUE; // End server
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef REMOVED
|
|
||||||
case COM_CREATE_DB: // QQ: To be removed
|
|
||||||
{
|
|
||||||
LEX_STRING db, alias;
|
|
||||||
HA_CREATE_INFO create_info;
|
|
||||||
|
|
||||||
status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]);
|
|
||||||
if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
|
|
||||||
thd->make_lex_string(&alias, db.str, db.length, FALSE) ||
|
|
||||||
check_db_name(&db))
|
|
||||||
{
|
|
||||||
my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
|
|
||||||
is_schema_db(db.str)))
|
|
||||||
break;
|
|
||||||
general_log_print(thd, command, "%.*s", db.length, db.str);
|
|
||||||
bzero(&create_info, sizeof(create_info));
|
|
||||||
mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
|
|
||||||
&create_info, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COM_DROP_DB: // QQ: To be removed
|
|
||||||
{
|
|
||||||
status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]);
|
|
||||||
LEX_STRING db;
|
|
||||||
|
|
||||||
if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
|
|
||||||
check_db_name(&db))
|
|
||||||
{
|
|
||||||
my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str)))
|
|
||||||
break;
|
|
||||||
if (thd->locked_tables || thd->active_transaction())
|
|
||||||
{
|
|
||||||
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
|
||||||
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
general_log_write(thd, command, "%.*s", db.length, db.str);
|
|
||||||
mysql_rm_db(thd, db.str, 0, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
case COM_BINLOG_DUMP:
|
case COM_BINLOG_DUMP:
|
||||||
{
|
{
|
||||||
@ -2073,7 +2025,6 @@ mysql_execute_command(THD *thd)
|
|||||||
A better approach would be to reset this for any commands
|
A better approach would be to reset this for any commands
|
||||||
that is not a SHOW command or a select that only access local
|
that is not a SHOW command or a select that only access local
|
||||||
variables, but for now this is probably good enough.
|
variables, but for now this is probably good enough.
|
||||||
Don't reset warnings when executing a stored routine.
|
|
||||||
*/
|
*/
|
||||||
if ((sql_command_flags[lex->sql_command] & CF_DIAGNOSTIC_STMT) != 0)
|
if ((sql_command_flags[lex->sql_command] & CF_DIAGNOSTIC_STMT) != 0)
|
||||||
thd->warning_info->set_read_only(TRUE);
|
thd->warning_info->set_read_only(TRUE);
|
||||||
@ -2276,7 +2227,7 @@ mysql_execute_command(THD *thd)
|
|||||||
privileges_requested,
|
privileges_requested,
|
||||||
all_tables, FALSE, UINT_MAX, FALSE);
|
all_tables, FALSE, UINT_MAX, FALSE);
|
||||||
else
|
else
|
||||||
res= check_access(thd, privileges_requested, any_db, 0, 0, 0, UINT_MAX);
|
res= check_access(thd, privileges_requested, any_db, 0, 0, 0, 0);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
break;
|
break;
|
||||||
@ -5830,7 +5781,6 @@ bool check_stack_overrun(THD *thd, long margin,
|
|||||||
my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
|
my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
|
||||||
stack_used, my_thread_stack_size, margin);
|
stack_used, my_thread_stack_size, margin);
|
||||||
my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
|
my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
|
||||||
thd->fatal_error();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
@ -6494,13 +6444,17 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||||||
DBUG_RETURN(0); /* purecov: inspected */
|
DBUG_RETURN(0); /* purecov: inspected */
|
||||||
if (table->db.str)
|
if (table->db.str)
|
||||||
{
|
{
|
||||||
|
ptr->is_fqtn= TRUE;
|
||||||
ptr->db= table->db.str;
|
ptr->db= table->db.str;
|
||||||
ptr->db_length= table->db.length;
|
ptr->db_length= table->db.length;
|
||||||
}
|
}
|
||||||
else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
|
else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
else
|
||||||
|
ptr->is_fqtn= FALSE;
|
||||||
|
|
||||||
ptr->alias= alias_str;
|
ptr->alias= alias_str;
|
||||||
|
ptr->is_alias= alias ? TRUE : FALSE;
|
||||||
if (lower_case_table_names && table->table.length)
|
if (lower_case_table_names && table->table.length)
|
||||||
table->table.length= my_casedn_str(files_charset_info, table->table.str);
|
table->table.length= my_casedn_str(files_charset_info, table->table.str);
|
||||||
ptr->table_name=table->table.str;
|
ptr->table_name=table->table.str;
|
||||||
@ -7547,6 +7501,63 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Given a table in the source list, find a correspondent table in the
|
||||||
|
table references list.
|
||||||
|
|
||||||
|
@param lex Pointer to LEX representing multi-delete.
|
||||||
|
@param src Source table to match.
|
||||||
|
@param ref Table references list.
|
||||||
|
|
||||||
|
@remark The source table list (tables listed before the FROM clause
|
||||||
|
or tables listed in the FROM clause before the USING clause) may
|
||||||
|
contain table names or aliases that must match unambiguously one,
|
||||||
|
and only one, table in the target table list (table references list,
|
||||||
|
after FROM/USING clause).
|
||||||
|
|
||||||
|
@return Matching table, NULL otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl,
|
||||||
|
TABLE_LIST *tables)
|
||||||
|
{
|
||||||
|
TABLE_LIST *match= NULL;
|
||||||
|
DBUG_ENTER("multi_delete_table_match");
|
||||||
|
|
||||||
|
for (TABLE_LIST *elem= tables; elem; elem= elem->next_local)
|
||||||
|
{
|
||||||
|
int cmp;
|
||||||
|
|
||||||
|
if (tbl->is_fqtn && elem->is_alias)
|
||||||
|
continue; /* no match */
|
||||||
|
if (tbl->is_fqtn && elem->is_fqtn)
|
||||||
|
cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
|
||||||
|
strcmp(tbl->db, elem->db);
|
||||||
|
else if (elem->is_alias)
|
||||||
|
cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
|
||||||
|
else
|
||||||
|
cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
|
||||||
|
strcmp(tbl->db, elem->db);
|
||||||
|
|
||||||
|
if (cmp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
match= elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match)
|
||||||
|
my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
|
||||||
|
|
||||||
|
DBUG_RETURN(match);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Link tables in auxilary table list of multi-delete with corresponding
|
Link tables in auxilary table list of multi-delete with corresponding
|
||||||
elements in main table list, and set proper locks for them.
|
elements in main table list, and set proper locks for them.
|
||||||
@ -7572,20 +7583,9 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
|
|||||||
{
|
{
|
||||||
lex->table_count++;
|
lex->table_count++;
|
||||||
/* All tables in aux_tables must be found in FROM PART */
|
/* All tables in aux_tables must be found in FROM PART */
|
||||||
TABLE_LIST *walk;
|
TABLE_LIST *walk= multi_delete_table_match(lex, target_tbl, tables);
|
||||||
for (walk= tables; walk; walk= walk->next_local)
|
|
||||||
{
|
|
||||||
if (!my_strcasecmp(table_alias_charset,
|
|
||||||
target_tbl->alias, walk->alias) &&
|
|
||||||
!strcmp(walk->db, target_tbl->db))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!walk)
|
if (!walk)
|
||||||
{
|
|
||||||
my_error(ER_UNKNOWN_TABLE, MYF(0),
|
|
||||||
target_tbl->table_name, "MULTI DELETE");
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
|
||||||
if (!walk->derived)
|
if (!walk->derived)
|
||||||
{
|
{
|
||||||
target_tbl->table_name= walk->table_name;
|
target_tbl->table_name= walk->table_name;
|
||||||
|
@ -2407,8 +2407,7 @@ char *generate_partition_syntax(partition_info *part_info,
|
|||||||
default:
|
default:
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
/* We really shouldn't get here, no use in continuing from here */
|
/* We really shouldn't get here, no use in continuing from here */
|
||||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||||
current_thd->fatal_error();
|
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
}
|
}
|
||||||
if (part_info->part_expr)
|
if (part_info->part_expr)
|
||||||
@ -5483,10 +5482,7 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
|
|||||||
&lpt->deleted, lpt->pack_frm_data,
|
&lpt->deleted, lpt->pack_frm_data,
|
||||||
lpt->pack_frm_len)))
|
lpt->pack_frm_len)))
|
||||||
{
|
{
|
||||||
if (error != ER_OUTOFMEMORY)
|
file->print_error(error, MYF(error != ER_OUTOFMEMORY ? 0 : ME_FATALERROR));
|
||||||
file->print_error(error, MYF(0));
|
|
||||||
else
|
|
||||||
lpt->thd->fatal_error();
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
@ -9708,7 +9708,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
Item_sum *item_sum=(Item_sum*) item;
|
Item_sum *item_sum=(Item_sum*) item;
|
||||||
result= item_sum->create_tmp_field(group, table, convert_blob_length);
|
result= item_sum->create_tmp_field(group, table, convert_blob_length);
|
||||||
if (!result)
|
if (!result)
|
||||||
thd->fatal_error();
|
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
case Item::FIELD_ITEM:
|
case Item::FIELD_ITEM:
|
||||||
@ -10852,8 +10852,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
|||||||
We don't want this error to be converted to a warning, e.g. in case of
|
We don't want this error to be converted to a warning, e.g. in case of
|
||||||
INSERT IGNORE ... SELECT.
|
INSERT IGNORE ... SELECT.
|
||||||
*/
|
*/
|
||||||
thd->fatal_error();
|
table->file->print_error(error, MYF(ME_FATALERROR));
|
||||||
table->file->print_error(error,MYF(0));
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15059,8 +15058,7 @@ calc_group_buffer(JOIN *join,ORDER *group)
|
|||||||
default:
|
default:
|
||||||
/* This case should never be choosen */
|
/* This case should never be choosen */
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||||
join->thd->fatal_error();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parts++;
|
parts++;
|
||||||
|
@ -128,7 +128,7 @@ bool servers_init(bool dont_read_servers_table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the mem root for data */
|
/* Initialize the mem root for data */
|
||||||
init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
|
init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
|
||||||
|
|
||||||
if (dont_read_servers_table)
|
if (dont_read_servers_table)
|
||||||
goto end;
|
goto end;
|
||||||
@ -180,7 +180,7 @@ static bool servers_load(THD *thd, TABLE_LIST *tables)
|
|||||||
|
|
||||||
my_hash_reset(&servers_cache);
|
my_hash_reset(&servers_cache);
|
||||||
free_root(&mem, MYF(0));
|
free_root(&mem, MYF(0));
|
||||||
init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
|
init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
|
||||||
|
|
||||||
init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0,
|
init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
@ -1705,6 +1705,32 @@ public:
|
|||||||
template class I_List<thread_info>;
|
template class I_List<thread_info>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const char *thread_state_info(THD *tmp)
|
||||||
|
{
|
||||||
|
if (tmp->locked)
|
||||||
|
return "Locked";
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (tmp->net.reading_or_writing)
|
||||||
|
{
|
||||||
|
if (tmp->net.reading_or_writing == 2)
|
||||||
|
return "Writing to net";
|
||||||
|
else if (tmp->command == COM_SLEEP)
|
||||||
|
return "";
|
||||||
|
else
|
||||||
|
return "Reading from net";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (tmp->proc_info)
|
||||||
|
return tmp->proc_info;
|
||||||
|
else if (tmp->mysys_var && tmp->mysys_var->current_cond)
|
||||||
|
return "Waiting on cond";
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
||||||
{
|
{
|
||||||
Item *field;
|
Item *field;
|
||||||
@ -1766,20 +1792,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
|||||||
if ((mysys_var= tmp->mysys_var))
|
if ((mysys_var= tmp->mysys_var))
|
||||||
pthread_mutex_lock(&mysys_var->mutex);
|
pthread_mutex_lock(&mysys_var->mutex);
|
||||||
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
|
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
|
||||||
#ifndef EMBEDDED_LIBRARY
|
thd_info->state_info= thread_state_info(tmp);
|
||||||
thd_info->state_info= (char*) (tmp->locked ? "Locked" :
|
|
||||||
tmp->net.reading_or_writing ?
|
|
||||||
(tmp->net.reading_or_writing == 2 ?
|
|
||||||
"Writing to net" :
|
|
||||||
thd_info->command == COM_SLEEP ? "" :
|
|
||||||
"Reading from net") :
|
|
||||||
tmp->proc_info ? tmp->proc_info :
|
|
||||||
tmp->mysys_var &&
|
|
||||||
tmp->mysys_var->current_cond ?
|
|
||||||
"Waiting on cond" : NullS);
|
|
||||||
#else
|
|
||||||
thd_info->state_info= (char*)"Writing to net";
|
|
||||||
#endif
|
|
||||||
if (mysys_var)
|
if (mysys_var)
|
||||||
pthread_mutex_unlock(&mysys_var->mutex);
|
pthread_mutex_unlock(&mysys_var->mutex);
|
||||||
|
|
||||||
@ -1891,21 +1904,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
|
|||||||
table->field[5]->store((longlong)(tmp->start_time ?
|
table->field[5]->store((longlong)(tmp->start_time ?
|
||||||
now - tmp->start_time : 0), FALSE);
|
now - tmp->start_time : 0), FALSE);
|
||||||
/* STATE */
|
/* STATE */
|
||||||
#ifndef EMBEDDED_LIBRARY
|
if ((val= thread_state_info(tmp)))
|
||||||
val= (char*) (tmp->locked ? "Locked" :
|
|
||||||
tmp->net.reading_or_writing ?
|
|
||||||
(tmp->net.reading_or_writing == 2 ?
|
|
||||||
"Writing to net" :
|
|
||||||
tmp->command == COM_SLEEP ? "" :
|
|
||||||
"Reading from net") :
|
|
||||||
tmp->proc_info ? tmp->proc_info :
|
|
||||||
tmp->mysys_var &&
|
|
||||||
tmp->mysys_var->current_cond ?
|
|
||||||
"Waiting on cond" : NullS);
|
|
||||||
#else
|
|
||||||
val= (char *) (tmp->proc_info ? tmp->proc_info : NullS);
|
|
||||||
#endif
|
|
||||||
if (val)
|
|
||||||
{
|
{
|
||||||
table->field[6]->store(val, strlen(val), cs);
|
table->field[6]->store(val, strlen(val), cs);
|
||||||
table->field[6]->set_notnull();
|
table->field[6]->set_notnull();
|
||||||
@ -5071,8 +5070,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||||
current_thd->fatal_error();
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
table->field[7]->set_notnull();
|
table->field[7]->set_notnull();
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
#include <m_string.h>
|
#include <m_string.h>
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
|
#include <mysql_com.h>
|
||||||
#ifdef HAVE_FCONVERT
|
#ifdef HAVE_FCONVERT
|
||||||
#include <floatingpoint.h>
|
#include <floatingpoint.h>
|
||||||
#endif
|
#endif
|
||||||
@ -499,22 +500,6 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TO_BE_REMOVED
|
|
||||||
bool String::append(FILE* file, uint32 arg_length, myf my_flags)
|
|
||||||
{
|
|
||||||
if (realloc(str_length+arg_length))
|
|
||||||
return TRUE;
|
|
||||||
if (my_fread(file, (uchar*) Ptr + str_length, arg_length, my_flags))
|
|
||||||
{
|
|
||||||
shrink(str_length);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
str_length+=arg_length;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool String::append(IO_CACHE* file, uint32 arg_length)
|
bool String::append(IO_CACHE* file, uint32 arg_length)
|
||||||
{
|
{
|
||||||
if (realloc(str_length+arg_length))
|
if (realloc(str_length+arg_length))
|
||||||
|
@ -22,10 +22,6 @@
|
|||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NOT_FIXED_DEC
|
|
||||||
#define NOT_FIXED_DEC 31
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class String;
|
class String;
|
||||||
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
|
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
|
||||||
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
||||||
|
@ -1660,7 +1660,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name)
|
|||||||
DBUG_ENTER("drop_all_triggers");
|
DBUG_ENTER("drop_all_triggers");
|
||||||
|
|
||||||
bzero(&table, sizeof(table));
|
bzero(&table, sizeof(table));
|
||||||
init_alloc_root(&table.mem_root, 8192, 0);
|
init_sql_alloc(&table.mem_root, 8192, 0);
|
||||||
|
|
||||||
if (Table_triggers_list::check_n_load(thd, db, name, &table, 1))
|
if (Table_triggers_list::check_n_load(thd, db, name, &table, 1))
|
||||||
{
|
{
|
||||||
@ -1871,7 +1871,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
|
|||||||
DBUG_ENTER("change_table_name");
|
DBUG_ENTER("change_table_name");
|
||||||
|
|
||||||
bzero(&table, sizeof(table));
|
bzero(&table, sizeof(table));
|
||||||
init_alloc_root(&table.mem_root, 8192, 0);
|
init_sql_alloc(&table.mem_root, 8192, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This method interfaces the mysql server code protected by
|
This method interfaces the mysql server code protected by
|
||||||
|
@ -662,11 +662,13 @@ int mysql_update(THD *thd,
|
|||||||
If (ignore && error is ignorable) we don't have to
|
If (ignore && error is ignorable) we don't have to
|
||||||
do anything; otherwise...
|
do anything; otherwise...
|
||||||
*/
|
*/
|
||||||
|
myf flags= 0;
|
||||||
|
|
||||||
if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
|
if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
|
||||||
thd->fatal_error(); /* Other handler errors are fatal */
|
flags|= ME_FATALERROR; /* Other handler errors are fatal */
|
||||||
|
|
||||||
prepare_record_for_error_message(error, table);
|
prepare_record_for_error_message(error, table);
|
||||||
table->file->print_error(error,MYF(0));
|
table->file->print_error(error,MYF(flags));
|
||||||
error= 1;
|
error= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -763,9 +765,8 @@ int mysql_update(THD *thd,
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* purecov: begin inspected */
|
/* purecov: begin inspected */
|
||||||
thd->fatal_error();
|
|
||||||
prepare_record_for_error_message(loc_error, table);
|
prepare_record_for_error_message(loc_error, table);
|
||||||
table->file->print_error(loc_error,MYF(0));
|
table->file->print_error(loc_error,MYF(ME_FATALERROR));
|
||||||
error= 1;
|
error= 1;
|
||||||
/* purecov: end */
|
/* purecov: end */
|
||||||
}
|
}
|
||||||
@ -1742,11 +1743,13 @@ bool multi_update::send_data(List<Item> ¬_used_values)
|
|||||||
If (ignore && error == is ignorable) we don't have to
|
If (ignore && error == is ignorable) we don't have to
|
||||||
do anything; otherwise...
|
do anything; otherwise...
|
||||||
*/
|
*/
|
||||||
|
myf flags= 0;
|
||||||
|
|
||||||
if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
|
if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
|
||||||
thd->fatal_error(); /* Other handler errors are fatal */
|
flags|= ME_FATALERROR; /* Other handler errors are fatal */
|
||||||
|
|
||||||
prepare_record_for_error_message(error, table);
|
prepare_record_for_error_message(error, table);
|
||||||
table->file->print_error(error,MYF(0));
|
table->file->print_error(error,MYF(flags));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2029,9 +2032,8 @@ int multi_update::do_updates()
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
{
|
{
|
||||||
thd->fatal_error();
|
|
||||||
prepare_record_for_error_message(local_error, table);
|
prepare_record_for_error_message(local_error, table);
|
||||||
table->file->print_error(local_error,MYF(0));
|
table->file->print_error(local_error,MYF(ME_FATALERROR));
|
||||||
}
|
}
|
||||||
|
|
||||||
err2:
|
err2:
|
||||||
|
@ -1190,7 +1190,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
|
|
||||||
%type <item>
|
%type <item>
|
||||||
literal text_literal insert_ident order_ident
|
literal text_literal insert_ident order_ident
|
||||||
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
|
simple_ident expr opt_expr opt_else sum_expr in_sum_expr
|
||||||
variable variable_aux bool_pri
|
variable variable_aux bool_pri
|
||||||
predicate bit_expr
|
predicate bit_expr
|
||||||
table_wild simple_expr udf_expr
|
table_wild simple_expr udf_expr
|
||||||
@ -1350,7 +1350,7 @@ END_OF_INPUT
|
|||||||
%type <NONE>
|
%type <NONE>
|
||||||
'-' '+' '*' '/' '%' '(' ')'
|
'-' '+' '*' '/' '%' '(' ')'
|
||||||
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
|
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
|
||||||
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM
|
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM
|
||||||
%%
|
%%
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -6946,7 +6946,14 @@ select_item_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
select_item:
|
select_item:
|
||||||
remember_name select_item2 remember_end select_alias
|
remember_name table_wild remember_end
|
||||||
|
{
|
||||||
|
THD *thd= YYTHD;
|
||||||
|
|
||||||
|
if (add_item_to_list(thd, $2))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| remember_name expr remember_end select_alias
|
||||||
{
|
{
|
||||||
THD *thd= YYTHD;
|
THD *thd= YYTHD;
|
||||||
DBUG_ASSERT($1 < $3);
|
DBUG_ASSERT($1 < $3);
|
||||||
@ -6983,11 +6990,6 @@ remember_end:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
select_item2:
|
|
||||||
table_wild { $$=$1; /* table.* */ }
|
|
||||||
| expr { $$=$1; }
|
|
||||||
;
|
|
||||||
|
|
||||||
select_alias:
|
select_alias:
|
||||||
/* empty */ { $$=null_lex_str;}
|
/* empty */ { $$=null_lex_str;}
|
||||||
| AS ident { $$=$2; }
|
| AS ident { $$=$2; }
|
||||||
@ -10048,7 +10050,7 @@ delete:
|
|||||||
lex->ignore= 0;
|
lex->ignore= 0;
|
||||||
lex->select_lex.init_order();
|
lex->select_lex.init_order();
|
||||||
}
|
}
|
||||||
opt_delete_options single_multi {}
|
opt_delete_options single_multi
|
||||||
;
|
;
|
||||||
|
|
||||||
single_multi:
|
single_multi:
|
||||||
@ -10063,45 +10065,45 @@ single_multi:
|
|||||||
| table_wild_list
|
| table_wild_list
|
||||||
{ mysql_init_multi_delete(Lex); }
|
{ mysql_init_multi_delete(Lex); }
|
||||||
FROM join_table_list where_clause
|
FROM join_table_list where_clause
|
||||||
{
|
{
|
||||||
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| FROM table_alias_ref_list
|
| FROM table_alias_ref_list
|
||||||
{ mysql_init_multi_delete(Lex); }
|
{ mysql_init_multi_delete(Lex); }
|
||||||
USING join_table_list where_clause
|
USING join_table_list where_clause
|
||||||
{
|
{
|
||||||
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
table_wild_list:
|
table_wild_list:
|
||||||
table_wild_one {}
|
table_wild_one
|
||||||
| table_wild_list ',' table_wild_one {}
|
| table_wild_list ',' table_wild_one
|
||||||
;
|
;
|
||||||
|
|
||||||
table_wild_one:
|
table_wild_one:
|
||||||
ident opt_wild opt_table_alias
|
ident opt_wild
|
||||||
{
|
{
|
||||||
Table_ident *ti= new Table_ident($1);
|
Table_ident *ti= new Table_ident($1);
|
||||||
if (ti == NULL)
|
if (ti == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
if (!Select->add_table_to_list(YYTHD,
|
if (!Select->add_table_to_list(YYTHD,
|
||||||
ti,
|
ti,
|
||||||
$3,
|
NULL,
|
||||||
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
|
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
|
||||||
Lex->lock_option))
|
Lex->lock_option))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| ident '.' ident opt_wild opt_table_alias
|
| ident '.' ident opt_wild
|
||||||
{
|
{
|
||||||
Table_ident *ti= new Table_ident(YYTHD, $1, $3, 0);
|
Table_ident *ti= new Table_ident(YYTHD, $1, $3, 0);
|
||||||
if (ti == NULL)
|
if (ti == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
if (!Select->add_table_to_list(YYTHD,
|
if (!Select->add_table_to_list(YYTHD,
|
||||||
ti,
|
ti,
|
||||||
$5,
|
NULL,
|
||||||
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
|
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
|
||||||
Lex->lock_option))
|
Lex->lock_option))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
@ -1332,6 +1332,12 @@ struct TABLE_LIST
|
|||||||
*/
|
*/
|
||||||
bool create;
|
bool create;
|
||||||
bool internal_tmp_table;
|
bool internal_tmp_table;
|
||||||
|
/** TRUE if an alias for this table was specified in the SQL. */
|
||||||
|
bool is_alias;
|
||||||
|
/** TRUE if the table is referred to in the statement using a fully
|
||||||
|
qualified name (<db_name>.<table_name>).
|
||||||
|
*/
|
||||||
|
bool is_fqtn;
|
||||||
|
|
||||||
|
|
||||||
/* View creation context. */
|
/* View creation context. */
|
||||||
|
@ -1594,7 +1594,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
|
|||||||
my_hash_free(&tz_names);
|
my_hash_free(&tz_names);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
init_alloc_root(&tz_storage, 32 * 1024, 0);
|
init_sql_alloc(&tz_storage, 32 * 1024, 0);
|
||||||
VOID(pthread_mutex_init(&tz_LOCK, MY_MUTEX_INIT_FAST));
|
VOID(pthread_mutex_init(&tz_LOCK, MY_MUTEX_INIT_FAST));
|
||||||
tz_inited= 1;
|
tz_inited= 1;
|
||||||
|
|
||||||
|
@ -30,10 +30,6 @@
|
|||||||
|
|
||||||
#define DECIMAL_MAX_LENGTH ((8 * 9) - 8)
|
#define DECIMAL_MAX_LENGTH ((8 * 9) - 8)
|
||||||
|
|
||||||
#ifndef NOT_FIXED_DEC
|
|
||||||
#define NOT_FIXED_DEC 31
|
|
||||||
#endif
|
|
||||||
|
|
||||||
C_MODE_START
|
C_MODE_START
|
||||||
extern int decimal_bin_size(int, int);
|
extern int decimal_bin_size(int, int);
|
||||||
C_MODE_END
|
C_MODE_END
|
||||||
|
@ -278,14 +278,11 @@ void my_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
|
|||||||
{
|
{
|
||||||
const uchar *pos = key;
|
const uchar *pos = key;
|
||||||
|
|
||||||
key+= len;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Remove trailing spaces. We have to do this to be able to compare
|
Remove trailing spaces. We have to do this to be able to compare
|
||||||
'A ' and 'A' as identical
|
'A ' and 'A' as identical
|
||||||
*/
|
*/
|
||||||
while (key > pos && key[-1] == ' ')
|
key= skip_trailing_space(key, len);
|
||||||
key--;
|
|
||||||
|
|
||||||
for (; pos < (uchar*) key ; pos++)
|
for (; pos < (uchar*) key ; pos++)
|
||||||
{
|
{
|
||||||
|
@ -678,13 +678,12 @@ void my_hash_sort_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
|
|||||||
const uchar *key, size_t len,
|
const uchar *key, size_t len,
|
||||||
ulong *nr1, ulong *nr2)
|
ulong *nr1, ulong *nr2)
|
||||||
{
|
{
|
||||||
const uchar *end= key+len;
|
const uchar *end;
|
||||||
/*
|
/*
|
||||||
Remove end space. We have to do this to be able to compare
|
Remove end space. We have to do this to be able to compare
|
||||||
'AE' and 'Ä' as identical
|
'AE' and 'Ä' as identical
|
||||||
*/
|
*/
|
||||||
while (end > key && end[-1] == ' ')
|
end= skip_trailing_space(key, len);
|
||||||
end--;
|
|
||||||
|
|
||||||
for (; key < end ; key++)
|
for (; key < end ; key++)
|
||||||
{
|
{
|
||||||
|
@ -469,14 +469,11 @@ static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
|
|||||||
{
|
{
|
||||||
const uchar *pos = key;
|
const uchar *pos = key;
|
||||||
|
|
||||||
key+= len;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Remove trailing spaces. We have to do this to be able to compare
|
Remove trailing spaces. We have to do this to be able to compare
|
||||||
'A ' and 'A' as identical
|
'A ' and 'A' as identical
|
||||||
*/
|
*/
|
||||||
while (key > pos && key[-1] == ' ')
|
key= skip_trailing_space(key, len);
|
||||||
key--;
|
|
||||||
|
|
||||||
for (; pos < (uchar*) key ; pos++)
|
for (; pos < (uchar*) key ; pos++)
|
||||||
{
|
{
|
||||||
|
@ -304,14 +304,13 @@ void my_hash_sort_simple(CHARSET_INFO *cs,
|
|||||||
ulong *nr1, ulong *nr2)
|
ulong *nr1, ulong *nr2)
|
||||||
{
|
{
|
||||||
register uchar *sort_order=cs->sort_order;
|
register uchar *sort_order=cs->sort_order;
|
||||||
const uchar *end= key + len;
|
const uchar *end;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Remove end space. We have to do this to be able to compare
|
Remove end space. We have to do this to be able to compare
|
||||||
'A ' and 'A' as identical
|
'A ' and 'A' as identical
|
||||||
*/
|
*/
|
||||||
while (end > key && end[-1] == ' ')
|
end= skip_trailing_space(key, len);
|
||||||
end--;
|
|
||||||
|
|
||||||
for (; key < (uchar*) end ; key++)
|
for (; key < (uchar*) end ; key++)
|
||||||
{
|
{
|
||||||
@ -1165,9 +1164,8 @@ size_t my_well_formed_len_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
|||||||
size_t my_lengthsp_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
size_t my_lengthsp_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
const char *ptr, size_t length)
|
const char *ptr, size_t length)
|
||||||
{
|
{
|
||||||
const char *end= ptr+length;
|
const char *end;
|
||||||
while (end > ptr && end[-1] == ' ')
|
end= (const char *) skip_trailing_space((const uchar *)ptr, length);
|
||||||
end--;
|
|
||||||
return (size_t) (end-ptr);
|
return (size_t) (end-ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
vio/vio.c
32
vio/vio.c
@ -22,6 +22,28 @@
|
|||||||
|
|
||||||
#include "vio_priv.h"
|
#include "vio_priv.h"
|
||||||
|
|
||||||
|
#if defined(__WIN__) || defined(HAVE_SMEM)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Stub poll_read method that defaults to indicate that there
|
||||||
|
is data to read.
|
||||||
|
|
||||||
|
Used for named pipe and shared memory VIO types.
|
||||||
|
|
||||||
|
@param vio Unused.
|
||||||
|
@param timeout Unused.
|
||||||
|
|
||||||
|
@retval FALSE There is data to read.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static my_bool no_poll_read(Vio *vio __attribute__((unused)),
|
||||||
|
uint timeout __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper to fill most of the Vio* with defaults.
|
* Helper to fill most of the Vio* with defaults.
|
||||||
*/
|
*/
|
||||||
@ -60,6 +82,9 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
|||||||
vio->vioblocking =vio_blocking;
|
vio->vioblocking =vio_blocking;
|
||||||
vio->is_blocking =vio_is_blocking;
|
vio->is_blocking =vio_is_blocking;
|
||||||
|
|
||||||
|
vio->poll_read =no_poll_read;
|
||||||
|
vio->is_connected =vio_is_connected_pipe;
|
||||||
|
|
||||||
vio->timeout=vio_win32_timeout;
|
vio->timeout=vio_win32_timeout;
|
||||||
/* Set default timeout */
|
/* Set default timeout */
|
||||||
vio->read_timeout_millis = INFINITE;
|
vio->read_timeout_millis = INFINITE;
|
||||||
@ -87,6 +112,9 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
|||||||
vio->vioblocking =vio_blocking;
|
vio->vioblocking =vio_blocking;
|
||||||
vio->is_blocking =vio_is_blocking;
|
vio->is_blocking =vio_is_blocking;
|
||||||
|
|
||||||
|
vio->poll_read =no_poll_read;
|
||||||
|
vio->is_connected =vio_is_connected_shared_memory;
|
||||||
|
|
||||||
/* Currently, shared memory is on Windows only, hence the below is ok*/
|
/* Currently, shared memory is on Windows only, hence the below is ok*/
|
||||||
vio->timeout= vio_win32_timeout;
|
vio->timeout= vio_win32_timeout;
|
||||||
/* Set default timeout */
|
/* Set default timeout */
|
||||||
@ -112,6 +140,8 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
|||||||
vio->vioblocking =vio_ssl_blocking;
|
vio->vioblocking =vio_ssl_blocking;
|
||||||
vio->is_blocking =vio_is_blocking;
|
vio->is_blocking =vio_is_blocking;
|
||||||
vio->timeout =vio_timeout;
|
vio->timeout =vio_timeout;
|
||||||
|
vio->poll_read =vio_poll_read;
|
||||||
|
vio->is_connected =vio_is_connected;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
@ -130,6 +160,8 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
|||||||
vio->vioblocking =vio_blocking;
|
vio->vioblocking =vio_blocking;
|
||||||
vio->is_blocking =vio_is_blocking;
|
vio->is_blocking =vio_is_blocking;
|
||||||
vio->timeout =vio_timeout;
|
vio->timeout =vio_timeout;
|
||||||
|
vio->poll_read =vio_poll_read;
|
||||||
|
vio->is_connected =vio_is_connected;
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,20 @@
|
|||||||
void vio_win32_timeout(Vio *vio, uint which, uint timeout);
|
void vio_win32_timeout(Vio *vio, uint which, uint timeout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WIN__
|
||||||
|
size_t vio_read_pipe(Vio *vio, uchar * buf, size_t size);
|
||||||
|
size_t vio_write_pipe(Vio *vio, const uchar * buf, size_t size);
|
||||||
|
my_bool vio_is_connected_pipe(Vio *vio);
|
||||||
|
int vio_close_pipe(Vio * vio);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SMEM
|
||||||
|
size_t vio_read_shared_memory(Vio *vio, uchar * buf, size_t size);
|
||||||
|
size_t vio_write_shared_memory(Vio *vio, const uchar * buf, size_t size);
|
||||||
|
my_bool vio_is_connected_shared_memory(Vio *vio);
|
||||||
|
int vio_close_shared_memory(Vio * vio);
|
||||||
|
#endif
|
||||||
|
|
||||||
void vio_timeout(Vio *vio,uint which, uint timeout);
|
void vio_timeout(Vio *vio,uint which, uint timeout);
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
|
166
vio/viosocket.c
166
vio/viosocket.c
@ -350,28 +350,163 @@ void vio_in_addr(Vio *vio, struct in_addr *in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return 0 if there is data to be read */
|
/**
|
||||||
|
Indicate whether there is data to read on a given socket.
|
||||||
|
|
||||||
my_bool vio_poll_read(Vio *vio,uint timeout)
|
@note An exceptional condition event and/or errors are
|
||||||
|
interpreted as if there is data to read.
|
||||||
|
|
||||||
|
@param sd A connected socket.
|
||||||
|
@param timeout Maximum time in seconds to poll.
|
||||||
|
|
||||||
|
@retval FALSE There is data to read.
|
||||||
|
@retval TRUE There is no data to read.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static my_bool socket_poll_read(my_socket sd, uint timeout)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_POLL
|
#ifdef __WIN__
|
||||||
return 0;
|
int res;
|
||||||
#else
|
my_socket fd= sd;
|
||||||
|
fd_set readfds, errorfds;
|
||||||
|
struct timeval tm;
|
||||||
|
DBUG_ENTER("socket_poll_read");
|
||||||
|
tm.tv_sec= timeout;
|
||||||
|
tm.tv_usec= 0;
|
||||||
|
FD_ZERO(&readfds);
|
||||||
|
FD_ZERO(&errorfds);
|
||||||
|
FD_SET(fd, &readfds);
|
||||||
|
FD_SET(fd, &errorfds);
|
||||||
|
if ((res= select(fd, &readfds, NULL, &errorfds, &tm) <= 0))
|
||||||
|
{
|
||||||
|
DBUG_RETURN(res < 0 ? 0 : 1);
|
||||||
|
}
|
||||||
|
res= FD_ISSET(fd, &readfds) || FD_ISSET(fd, &errorfds);
|
||||||
|
DBUG_RETURN(!res);
|
||||||
|
#elif defined(HAVE_POLL)
|
||||||
struct pollfd fds;
|
struct pollfd fds;
|
||||||
int res;
|
int res;
|
||||||
DBUG_ENTER("vio_poll");
|
DBUG_ENTER("socket_poll_read");
|
||||||
fds.fd=vio->sd;
|
fds.fd=sd;
|
||||||
fds.events=POLLIN;
|
fds.events=POLLIN;
|
||||||
fds.revents=0;
|
fds.revents=0;
|
||||||
if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
|
if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
|
||||||
{
|
{
|
||||||
DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
|
DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
|
||||||
}
|
}
|
||||||
DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
|
DBUG_RETURN(fds.revents & (POLLIN | POLLERR | POLLHUP) ? 0 : 1);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the amount of data that can be read from a socket.
|
||||||
|
|
||||||
|
@param vio A VIO object.
|
||||||
|
@param bytes[out] The amount of bytes available.
|
||||||
|
|
||||||
|
@retval FALSE Success.
|
||||||
|
@retval TRUE Failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static my_bool socket_peek_read(Vio *vio, uint *bytes)
|
||||||
|
{
|
||||||
|
#ifdef __WIN__
|
||||||
|
int len;
|
||||||
|
if (ioctlsocket(vio->sd, FIONREAD, &len))
|
||||||
|
return TRUE;
|
||||||
|
*bytes= len;
|
||||||
|
return FALSE;
|
||||||
|
#elif FIONREAD_IN_SYS_IOCTL
|
||||||
|
int len;
|
||||||
|
if (ioctl(vio->sd, FIONREAD, &len) < 0)
|
||||||
|
return TRUE;
|
||||||
|
*bytes= len;
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
char buf[1024];
|
||||||
|
ssize_t res= recv(vio->sd, &buf, sizeof(buf), MSG_PEEK);
|
||||||
|
if (res < 0)
|
||||||
|
return TRUE;
|
||||||
|
*bytes= res;
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Indicate whether there is data to read on a given socket.
|
||||||
|
|
||||||
|
@remark Errors are interpreted as if there is data to read.
|
||||||
|
|
||||||
|
@param sd A connected socket.
|
||||||
|
@param timeout Maximum time in seconds to wait.
|
||||||
|
|
||||||
|
@retval FALSE There is data (or EOF) to read. Also FALSE if error.
|
||||||
|
@retval TRUE There is _NO_ data to read or timed out.
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool vio_poll_read(Vio *vio, uint timeout)
|
||||||
|
{
|
||||||
|
my_socket sd= vio->sd;
|
||||||
|
DBUG_ENTER("vio_poll_read");
|
||||||
|
#ifdef HAVE_OPENSSL
|
||||||
|
if (vio->type == VIO_TYPE_SSL)
|
||||||
|
sd= SSL_get_fd((SSL*) vio->ssl_arg);
|
||||||
|
#endif
|
||||||
|
DBUG_RETURN(socket_poll_read(sd, timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Determine if the endpoint of a connection is still available.
|
||||||
|
|
||||||
|
@remark The socket is assumed to be disconnected if an EOF
|
||||||
|
condition is encountered.
|
||||||
|
|
||||||
|
@param vio The VIO object.
|
||||||
|
|
||||||
|
@retval TRUE EOF condition not found.
|
||||||
|
@retval FALSE EOF condition is signaled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool vio_is_connected(Vio *vio)
|
||||||
|
{
|
||||||
|
uint bytes= 0;
|
||||||
|
DBUG_ENTER("vio_is_connected");
|
||||||
|
|
||||||
|
/* In the presence of errors the socket is assumed to be connected. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
The first step of detecting a EOF condition is veryfing
|
||||||
|
whether there is data to read. Data in this case would
|
||||||
|
be the EOF.
|
||||||
|
*/
|
||||||
|
if (vio_poll_read(vio, 0))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
The second step is read() or recv() from the socket returning
|
||||||
|
0 (EOF). Unfortunelly, it's not possible to call read directly
|
||||||
|
as we could inadvertently read meaningful connection data.
|
||||||
|
Simulate a read by retrieving the number of bytes available to
|
||||||
|
read -- 0 meaning EOF.
|
||||||
|
*/
|
||||||
|
if (socket_peek_read(vio, &bytes))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENSSL
|
||||||
|
/* There might be buffered data at the SSL layer. */
|
||||||
|
if (!bytes && vio->type == VIO_TYPE_SSL)
|
||||||
|
bytes= SSL_pending((SSL*) vio->ssl_arg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DBUG_RETURN(bytes ? TRUE : FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void vio_timeout(Vio *vio, uint which, uint timeout)
|
void vio_timeout(Vio *vio, uint which, uint timeout)
|
||||||
{
|
{
|
||||||
#if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)
|
#if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)
|
||||||
@ -494,6 +629,15 @@ size_t vio_write_pipe(Vio * vio, const uchar* buf, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_bool vio_is_connected_pipe(Vio *vio)
|
||||||
|
{
|
||||||
|
if (PeekNamedPipe(vio->hPipe, NULL, 0, NULL, NULL, NULL))
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return (GetLastError() != ERROR_BROKEN_PIPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int vio_close_pipe(Vio * vio)
|
int vio_close_pipe(Vio * vio)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
@ -644,6 +788,12 @@ size_t vio_write_shared_memory(Vio * vio, const uchar* buf, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_bool vio_is_connected_shared_memory(Vio *vio)
|
||||||
|
{
|
||||||
|
return (WaitForSingleObject(vio->event_conn_closed, 0) != WAIT_OBJECT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Close shared memory and DBUG_PRINT any errors that happen on closing.
|
Close shared memory and DBUG_PRINT any errors that happen on closing.
|
||||||
@return Zero if all closing functions succeed, and nonzero otherwise.
|
@return Zero if all closing functions succeed, and nonzero otherwise.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user