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_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
|
||||
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_AUTO_GENERATE_SQL_LOAD_TYPE, OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
|
||||
OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
|
||||
@ -78,6 +81,7 @@ enum options_client
|
||||
OPT_SLAP_DETACH,
|
||||
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_AUTO_VERTICAL_OUTPUT,
|
||||
OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
|
||||
OPT_WRITE_BINLOG, OPT_DUMP_DATE,
|
||||
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,
|
||||
opt_secure_auth= 0,
|
||||
default_pager_set= 0, opt_sigint_ignore= 0,
|
||||
auto_vertical_output= 0,
|
||||
show_warnings= 0, executing_query= 0, interrupted_query= 0,
|
||||
ignore_spaces= 0;
|
||||
static my_bool debug_info_flag, debug_check_flag;
|
||||
@ -185,6 +186,7 @@ static MEM_ROOT hash_mem_root;
|
||||
static uint prompt_counter;
|
||||
static char delimiter[16]= DEFAULT_DELIMITER;
|
||||
static uint delimiter_length= 1;
|
||||
unsigned short terminal_width= 80;
|
||||
|
||||
#ifdef HAVE_SMEM
|
||||
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 void init_username();
|
||||
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
|
||||
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);
|
||||
extern "C" sig_handler mysql_end(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[])
|
||||
{
|
||||
@ -1144,8 +1152,8 @@ int main(int argc,char *argv[])
|
||||
if (sql_connect(current_host,current_db,current_user,opt_password,
|
||||
opt_silent))
|
||||
{
|
||||
quick=1; // Avoid history
|
||||
status.exit_status=1;
|
||||
quick= 1; // Avoid history
|
||||
status.exit_status= 1;
|
||||
mysql_end(-1);
|
||||
}
|
||||
if (!status.batch)
|
||||
@ -1157,6 +1165,13 @@ int main(int argc,char *argv[])
|
||||
signal(SIGINT, handle_sigint); // Catch SIGINT 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.",
|
||||
INFO_INFO);
|
||||
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[] =
|
||||
{
|
||||
{"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 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},
|
||||
{"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',
|
||||
"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,
|
||||
@ -3052,7 +3080,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
|
||||
print_table_data_html(result);
|
||||
else if (opt_xml)
|
||||
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);
|
||||
else if (opt_silent && verbose <= 2 && !output_tables)
|
||||
print_tab_data(result);
|
||||
@ -3383,6 +3411,65 @@ print_table_data(MYSQL_RES *result)
|
||||
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
|
||||
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];
|
||||
time_t start_time;
|
||||
char *typed_password= NULL, *verified= NULL;
|
||||
/* Do initialization the same way as we do in mysqld */
|
||||
start_time=time((time_t*) 0);
|
||||
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);
|
||||
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) ==
|
||||
ADMIN_OLD_PASSWORD);
|
||||
#ifdef __WIN__
|
||||
uint pw_len= (uint) strlen(pw);
|
||||
if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'')
|
||||
size_t pw_len= strlen(typed_password);
|
||||
if (pw_len > 1 && typed_password[0] == '\'' &&
|
||||
typed_password[pw_len-1] == '\'')
|
||||
printf("Warning: single quotes were not trimmed from the password by"
|
||||
" your command\nline client, as you might have expected.\n");
|
||||
#endif
|
||||
@ -954,9 +969,9 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
||||
}
|
||||
}
|
||||
if (old)
|
||||
make_scrambled_password_323(crypted_pw, pw);
|
||||
make_scrambled_password_323(crypted_pw, typed_password);
|
||||
else
|
||||
make_scrambled_password(crypted_pw, pw);
|
||||
make_scrambled_password(crypted_pw, typed_password);
|
||||
}
|
||||
else
|
||||
crypted_pw[0]=0; /* No password */
|
||||
@ -991,6 +1006,12 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
||||
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++;
|
||||
break;
|
||||
}
|
||||
@ -1082,8 +1103,8 @@ static void usage(void)
|
||||
kill id,id,... Kill mysql threads");
|
||||
#if MYSQL_VERSION_ID >= 32200
|
||||
puts("\
|
||||
password new-password Change old password to new-password, MySQL 4.1 hashing.\n\
|
||||
old-password new-password Change old password to new-password in old format.\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");
|
||||
#endif
|
||||
puts("\
|
||||
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.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"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,
|
||||
1, 0, 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_replace_into= 0,
|
||||
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_alltspcs=0, opt_notspcs= 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;
|
||||
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
|
||||
#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_slave_data;
|
||||
static uint my_end_arg;
|
||||
static char * opt_mysql_unix_port=0;
|
||||
static int first_error=0;
|
||||
@ -206,6 +211,10 @@ static struct my_option my_long_options[] =
|
||||
{"allow-keywords", 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},
|
||||
{"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__
|
||||
{"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},
|
||||
@ -264,6 +273,19 @@ static struct my_option my_long_options[] =
|
||||
{"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,
|
||||
(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.",
|
||||
(uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL,
|
||||
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 "
|
||||
"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},
|
||||
{"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.",
|
||||
(uchar**) &opt_ignore, (uchar**) &opt_ignore, 0, GET_BOOL, NO_ARG, 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,
|
||||
NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"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,
|
||||
0, 0, 0, 0, 0},
|
||||
{"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 */
|
||||
opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
|
||||
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:
|
||||
extended_insert= opt_drop= opt_lock= quick= create_options=
|
||||
opt_disable_keys= lock_tables= opt_set_charset= 1;
|
||||
@ -896,6 +928,14 @@ static int get_options(int *argc, char ***argv)
|
||||
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 */
|
||||
if (opt_delete_master_logs && !opt_master_data)
|
||||
opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
|
||||
@ -906,7 +946,10 @@ static int get_options(int *argc, char ***argv)
|
||||
return(EX_USAGE);
|
||||
}
|
||||
if (opt_master_data)
|
||||
{
|
||||
opt_lock_all_tables= !opt_single_transaction;
|
||||
opt_slave_data= 0;
|
||||
}
|
||||
if (opt_single_transaction || opt_lock_all_tables)
|
||||
lock_tables= 0;
|
||||
if (enclosed && opt_enclosed)
|
||||
@ -4333,6 +4376,130 @@ static int do_show_master_status(MYSQL *mysql_con)
|
||||
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)
|
||||
{
|
||||
@ -4995,6 +5162,9 @@ int main(int argc, char **argv)
|
||||
if (!path)
|
||||
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) &&
|
||||
do_flush_tables_read_lock(mysql))
|
||||
goto err;
|
||||
@ -5013,8 +5183,13 @@ int main(int argc, char **argv)
|
||||
goto err;
|
||||
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))
|
||||
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! */
|
||||
goto err;
|
||||
|
||||
@ -5042,6 +5217,14 @@ int main(int argc, char **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 */
|
||||
if (md_result_file && fflush(md_result_file))
|
||||
{
|
||||
|
@ -75,7 +75,8 @@
|
||||
enum {
|
||||
OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
|
||||
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;
|
||||
@ -88,6 +89,7 @@ const char *opt_logdir= "";
|
||||
const char *opt_include= 0, *opt_charsets_dir;
|
||||
static int opt_port= 0;
|
||||
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 debug_info_flag= 0, debug_check_flag= 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_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
|
||||
Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER,
|
||||
Q_RESULT_FORMAT_VERSION,
|
||||
Q_MOVE_FILE, Q_SEND_EVAL,
|
||||
|
||||
Q_UNKNOWN, /* Unknown command. */
|
||||
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",
|
||||
"send_shutdown",
|
||||
"shutdown_server",
|
||||
"result_format",
|
||||
"move_file",
|
||||
"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
|
||||
|
||||
@ -5273,7 +5330,7 @@ my_bool end_of_query(int c)
|
||||
|
||||
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;
|
||||
int skip_char= 0;
|
||||
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))
|
||||
{
|
||||
/* Skip all space at begining of line */
|
||||
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 */
|
||||
start_lineno= cur_file->lineno;
|
||||
DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d",
|
||||
start_lineno));
|
||||
}
|
||||
|
||||
/* Skip all space at begining of line */
|
||||
skip_char= 1;
|
||||
}
|
||||
else if (end_of_query(c))
|
||||
@ -5419,6 +5486,8 @@ int read_line(char *buf, int size)
|
||||
|
||||
}
|
||||
|
||||
last_char= c;
|
||||
|
||||
if (!skip_char)
|
||||
{
|
||||
/* Could be a multibyte character */
|
||||
@ -5628,9 +5697,10 @@ int read_command(struct st_command** command_ptr)
|
||||
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 == '#')
|
||||
{
|
||||
command->type= Q_COMMENT;
|
||||
@ -5640,6 +5710,10 @@ int read_command(struct st_command** command_ptr)
|
||||
command->type= Q_COMMENT_WITH_COMMAND;
|
||||
p+= 2; /* Skip past -- */
|
||||
}
|
||||
else if (*p == '\n')
|
||||
{
|
||||
command->type= Q_EMPTY_LINE;
|
||||
}
|
||||
|
||||
/* Skip leading spaces */
|
||||
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.",
|
||||
(uchar**) &result_file_name, (uchar**) &result_file_name, 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.",
|
||||
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"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;
|
||||
#endif
|
||||
break;
|
||||
case OPT_RESULT_FORMAT_VERSION:
|
||||
set_result_format_version(opt_result_format_version);
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(0);
|
||||
@ -7816,6 +7898,7 @@ int main(int argc, char **argv)
|
||||
case Q_MOVE_FILE: do_move_file(command); break;
|
||||
case Q_CHMOD_FILE: do_chmod_file(command); break;
|
||||
case Q_PERL: do_perl(command); break;
|
||||
case Q_RESULT_FORMAT_VERSION: do_result_format_version(command); break;
|
||||
case Q_DELIMITER:
|
||||
do_delimiter(command);
|
||||
break;
|
||||
@ -7933,9 +8016,38 @@ int main(int argc, char **argv)
|
||||
do_sync_with_master2(command, 0);
|
||||
break;
|
||||
}
|
||||
case Q_COMMENT: /* Ignore row */
|
||||
case Q_COMMENT:
|
||||
{
|
||||
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;
|
||||
}
|
||||
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:
|
||||
handle_command_error(command, mysql_ping(&cur_con->mysql));
|
||||
break;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
#include <mysql_com.h>
|
||||
#ifdef HAVE_FCONVERT
|
||||
#include <floatingpoint.h>
|
||||
#endif
|
||||
|
@ -22,10 +22,6 @@
|
||||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
#ifndef NOT_FIXED_DEC
|
||||
#define NOT_FIXED_DEC 31
|
||||
#endif
|
||||
|
||||
class String;
|
||||
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
|
||||
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
||||
|
@ -601,15 +601,15 @@ dnl ---------------------------------------------------------------------------
|
||||
|
||||
dnl 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_TRY_LINK([], [
|
||||
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++)
|
||||
])
|
||||
if test "$mysql_use_mysys_new" = "yes"
|
||||
if test "$mysql_cv_use_mysys_new" = "yes"
|
||||
then
|
||||
AC_DEFINE([USE_MYSYS_NEW], [1], [Needs to use mysys_new helpers])
|
||||
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 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
|
||||
|
@ -524,4 +524,5 @@ uchar *net_store_length(uchar *pkg, ulonglong length);
|
||||
#define MYSQL_STMT_HEADER 4
|
||||
#define MYSQL_LONG_DATA_HEADER 6
|
||||
|
||||
#define NOT_FIXED_DEC 31
|
||||
#endif
|
||||
|
@ -51,9 +51,6 @@ Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
|
||||
HANDLE event_client_wrote,
|
||||
HANDLE event_client_read,
|
||||
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
|
||||
#define HANDLE void *
|
||||
#endif /* __WIN__ */
|
||||
@ -87,7 +84,8 @@ my_socket vio_fd(Vio*vio);
|
||||
my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port);
|
||||
/* Remotes in_addr */
|
||||
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
|
||||
#include <openssl/opensslv.h>
|
||||
@ -136,12 +134,6 @@ struct st_VioSSLFd
|
||||
void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
|
||||
#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);
|
||||
|
||||
#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_in_addr(vio, in) (vio)->in_addr(vio, in)
|
||||
#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) */
|
||||
|
||||
/* This enumerator is used in parser - should be always visible */
|
||||
@ -208,6 +202,8 @@ struct st_vio
|
||||
my_bool (*was_interrupted)(Vio*);
|
||||
int (*vioclose)(Vio*);
|
||||
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
|
||||
void *ssl_arg;
|
||||
#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 *end;
|
||||
/* TODO: move this to a header shared between client and server. */
|
||||
#define NOT_FIXED_DEC 31
|
||||
if (field->decimals >= NOT_FIXED_DEC)
|
||||
#undef NOT_FIXED_DEC
|
||||
{
|
||||
/*
|
||||
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);
|
||||
thd->cur_data= 0;
|
||||
thd->mysys_var= NULL;
|
||||
|
||||
if (!skip_check)
|
||||
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
|
||||
ASC LIMIT 1;
|
||||
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;
|
||||
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;
|
||||
ERROR 42S02: Unknown table 'alias' in MULTI DELETE
|
||||
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;
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
@ -279,6 +279,147 @@ ERROR 42000: Incorrect number of arguments for FUNCTION test.f1; expected 0, got
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION f1;
|
||||
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,
|
||||
# merge table
|
||||
|
@ -277,7 +277,7 @@ select * from t1;
|
||||
N M
|
||||
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;
|
||||
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;
|
||||
ERROR 42S22: Unknown column 'aaa' in 'field list'
|
||||
drop table t1;
|
||||
|
@ -7,3 +7,13 @@ n
|
||||
2
|
||||
3
|
||||
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'));
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
select 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)
|
||||
End of 5.0 tests
|
||||
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 1266): Using storage engine MyISAM for table 't2'
|
||||
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;
|
||||
end$$
|
||||
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;
|
||||
CREATE TABLE t1 (a INT, b INT);
|
||||
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
|
||||
DROP FUNCTION f1;
|
||||
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
|
||||
# strict SQL mode
|
||||
|
@ -2115,3 +2115,50 @@ s1
|
||||
DELETE FROM t1;
|
||||
DROP TABLE t1;
|
||||
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
|
||||
09:00:00
|
||||
drop table t1;
|
||||
End of 4.1 tests
|
||||
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)
|
||||
0
|
||||
@ -138,3 +139,27 @@ CAST(c AS TIME)
|
||||
00:00:00
|
||||
DROP TABLE t1;
|
||||
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;
|
||||
i
|
||||
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;
|
||||
i
|
||||
3
|
||||
|
@ -25,7 +25,7 @@ INSERT INTO a VALUES(1);
|
||||
DELETE alias FROM a alias WHERE alias.i=1;
|
||||
SELECT * FROM a;
|
||||
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;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
|
@ -41,7 +41,10 @@ id rollno GROUP_CONCAT(name)
|
||||
4 3 Reco
|
||||
7 4 Reco
|
||||
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, ##
|
||||
## warning should come here ##
|
||||
SET @@session.group_concat_max_len = 10;
|
||||
@ -52,7 +55,9 @@ id rollno GROUP_CONCAT(name)
|
||||
4 3 Record_4,R
|
||||
7 4 Record_7,R
|
||||
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-------------------------#'
|
||||
## Connecting with new connection test_con2 ##
|
||||
## Verifying initial value of variable. It should be 4 ##
|
||||
@ -71,7 +76,7 @@ id rollno GROUP_CONCAT(name)
|
||||
4 3 Record_4,Record_6
|
||||
7 4 Record_7,Record_8
|
||||
Warnings:
|
||||
Warning 1260 1 line(s) were cut by GROUP_CONCAT()
|
||||
Warning 1260 Row 3 was cut by GROUP_CONCAT()
|
||||
'#--------------------FN_DYNVARS_034_04-------------------------#'
|
||||
## Setting session value of variable to 26. No warning should appear here ##
|
||||
## because the value after concatination is less than 30 ##
|
||||
|
@ -86,3 +86,132 @@ ASC LIMIT 1;
|
||||
drop table t1;
|
||||
|
||||
# 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;
|
||||
--error ER_PARSE_ERROR
|
||||
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;
|
||||
--error ER_UNKNOWN_TABLE
|
||||
DELETE FROM db2.alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
|
||||
DELETE FROM t1 USING t1 WHERE a = 1;
|
||||
SELECT * FROM t1;
|
||||
@ -293,6 +293,159 @@ DROP FUNCTION f1;
|
||||
|
||||
--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 # Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
|
||||
--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;
|
||||
select * from t1;
|
||||
--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;
|
||||
-- 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;
|
||||
|
@ -1,3 +1,4 @@
|
||||
--source include/not_embedded.inc
|
||||
|
||||
# Save the initial number of concurrent sessions
|
||||
--source include/count_sessions.inc
|
||||
@ -22,6 +23,38 @@ disconnect con2;
|
||||
|
||||
# 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
|
||||
--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: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
|
||||
|
@ -819,6 +819,16 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SECOND;
|
||||
--error ER_PARSE_ERROR
|
||||
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
|
||||
|
||||
#
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
# Save the initial number of concurrent sessions
|
||||
--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"
|
||||
--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
|
||||
#
|
||||
|
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'`){
|
||||
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 include/common-tests.inc
|
||||
|
||||
connection default;
|
||||
disconnect shm_con;
|
||||
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
let $name= query_get_value("SHOW GLOBAL VARIABLES LIKE 'shared_memory_base_name'", Value, 1);
|
||||
let $stmt= `SELECT REPEAT('a', 2048)`;
|
||||
|
||||
SET @max_allowed_packet= @@global.max_allowed_packet;
|
||||
@ -30,7 +36,7 @@ SET GLOBAL max_allowed_packet= 1024;
|
||||
SET GLOBAL net_buffer_length= 1024;
|
||||
|
||||
--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 net_buffer_length= @net_buffer_length;
|
||||
|
@ -2419,6 +2419,27 @@ end$$
|
||||
|
||||
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
|
||||
|
@ -8295,6 +8295,119 @@ SELECT * FROM t1 WHERE a = f1();
|
||||
DROP FUNCTION f1;
|
||||
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 # Bug#34197: CREATE PROCEDURE fails when COMMENT truncated in non
|
||||
--echo # strict SQL mode
|
||||
|
@ -2425,3 +2425,67 @@ DELETE FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
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);
|
||||
# ##########################################################
|
||||
|
||||
# End of 4.1 tests
|
||||
--echo End of 4.1 tests
|
||||
|
||||
#
|
||||
# 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
|
||||
|
||||
|
||||
#
|
||||
# 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));
|
||||
|
||||
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)
|
||||
(*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= 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)
|
||||
(*mem_root->error_handler)();
|
||||
|
@ -1222,6 +1222,14 @@ void my_print_help(const struct my_option *options)
|
||||
printf("%s", comment);
|
||||
}
|
||||
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");
|
||||
/* init memory root */
|
||||
init_alloc_root(&mem_root, 256, 512);
|
||||
init_sql_alloc(&mem_root, 256, 512);
|
||||
dbname.str= name.str= NULL;
|
||||
dbname.length= name.length= 0;
|
||||
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)
|
||||
{
|
||||
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.
|
||||
|
||||
@ -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)
|
||||
{
|
||||
if (length > 255)
|
||||
@ -8135,139 +7918,6 @@ const uchar *Field_blob::unpack(uchar *to,
|
||||
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)
|
||||
{
|
||||
if (length > 255)
|
||||
|
42
sql/field.h
42
sql/field.h
@ -25,7 +25,6 @@
|
||||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
#define NOT_FIXED_DEC 31
|
||||
#define DATETIME_DEC 6
|
||||
const uint32 max_field_size= (uint32) 4294967295U;
|
||||
|
||||
@ -410,32 +409,11 @@ public:
|
||||
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)
|
||||
{ return length;}
|
||||
virtual uint max_packed_col_length(uint 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)
|
||||
{
|
||||
return (uint) (ptr - record);
|
||||
@ -1503,9 +1481,6 @@ public:
|
||||
int compatible_field_size(uint field_metadata,
|
||||
const Relay_log_info *rli);
|
||||
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 max_packed_col_length(uint max_length);
|
||||
uint size_of() const { return sizeof(*this); }
|
||||
@ -1579,16 +1554,8 @@ public:
|
||||
void sql_type(String &str) const;
|
||||
virtual uchar *pack(uchar *to, const uchar *from,
|
||||
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,
|
||||
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 key_cmp(const uchar *,const uchar*);
|
||||
int key_cmp(const uchar *str, uint length);
|
||||
@ -1764,17 +1731,8 @@ public:
|
||||
}
|
||||
virtual uchar *pack(uchar *to, const uchar *from,
|
||||
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,
|
||||
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 max_packed_col_length(uint max_length);
|
||||
void free() { value.free(); }
|
||||
|
@ -1980,8 +1980,7 @@ partition_element *ha_partition::find_partition_element(uint part_id)
|
||||
return part_elem;
|
||||
}
|
||||
DBUG_ASSERT(0);
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
||||
current_thd->fatal_error(); // Abort
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -855,7 +855,8 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
|
||||
else
|
||||
{
|
||||
*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
|
||||
|
@ -3474,6 +3474,48 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
|
||||
|
||||
#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.
|
||||
|
||||
@ -3489,8 +3531,7 @@ longlong Item_func_get_lock::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String *res=args[0]->val_str(&value);
|
||||
longlong timeout=args[1]->val_int();
|
||||
struct timespec abstime;
|
||||
double timeout= args[1]->val_real();
|
||||
THD *thd=current_thd;
|
||||
User_level_lock *ull;
|
||||
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_cond= &ull->cond;
|
||||
|
||||
set_timespec(abstime,timeout);
|
||||
error= 0;
|
||||
while (ull->locked && !thd->killed)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
struct timespec abstime;
|
||||
pthread_cond_t cond;
|
||||
double timeout;
|
||||
int error;
|
||||
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
||||
double time= args[0]->val_real();
|
||||
timeout= args[0]->val_real();
|
||||
/*
|
||||
On 64-bit OSX pthread_cond_timedwait() waits forever
|
||||
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
|
||||
to pthread_cond_timedwait() will be executed in less than 0.00001 sec.
|
||||
*/
|
||||
if (time < 0.00001)
|
||||
if (timeout < 0.00001)
|
||||
return 0;
|
||||
|
||||
set_timespec_nsec(abstime, (ulonglong)(time * ULL(1000000000)));
|
||||
|
||||
pthread_cond_init(&cond, NULL);
|
||||
pthread_mutex_lock(&LOCK_user_locks);
|
||||
@ -3785,7 +3823,7 @@ longlong Item_func_sleep::val_int()
|
||||
error= 0;
|
||||
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)
|
||||
break;
|
||||
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;
|
||||
if (!my_hash_inited(hash))
|
||||
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;
|
||||
entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
|
||||
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 unsigned_arg indiates if a value of type INT_RESULT is unsigned
|
||||
|
||||
@note Sets error and fatal error if allocation fails.
|
||||
|
||||
@retval
|
||||
false success
|
||||
@retval
|
||||
@ -3998,7 +4038,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
|
||||
if (entry->value == pos)
|
||||
entry->value=0;
|
||||
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)
|
||||
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),
|
||||
ptr, length, res_type, cs, dv, unsigned_arg))
|
||||
{
|
||||
current_thd->fatal_error(); // Probably end of memory
|
||||
null_value= 1;
|
||||
return 1;
|
||||
}
|
||||
@ -4768,11 +4808,6 @@ void Item_func_get_user_var::fix_length_and_dec()
|
||||
m_cached_result_type= STRING_RESULT;
|
||||
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)
|
||||
{
|
||||
if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs,
|
||||
DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
|
||||
current_thd->fatal_error(); // Probably end of memory
|
||||
::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs,
|
||||
DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
|
||||
}
|
||||
|
||||
|
||||
void Item_user_var_as_out_param::set_value(const char *str, uint length,
|
||||
CHARSET_INFO* cs)
|
||||
{
|
||||
if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
|
||||
DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
|
||||
current_thd->fatal_error(); // Probably end of memory
|
||||
::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
|
||||
DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1740,8 +1740,6 @@ subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
|
||||
:subselect_engine(item_arg, result_arg)
|
||||
{
|
||||
unit= u;
|
||||
if (!result_arg) //out of memory
|
||||
current_thd->fatal_error();
|
||||
unit->item= item_arg;
|
||||
}
|
||||
|
||||
@ -1753,10 +1751,7 @@ int subselect_single_select_engine::prepare()
|
||||
join= new JOIN(thd, select_lex->item_list,
|
||||
select_lex->options | SELECT_NO_UNLOCK, result);
|
||||
if (!join || !result)
|
||||
{
|
||||
thd->fatal_error(); //out of memory
|
||||
return 1;
|
||||
}
|
||||
return 1; /* Fatal error is set already. */
|
||||
prepared= 1;
|
||||
SELECT_LEX *save_select= thd->lex->current_select;
|
||||
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;
|
||||
uint i;
|
||||
long msec_length= 0;
|
||||
|
||||
while (str != end && !my_isdigit(cs,*str))
|
||||
str++;
|
||||
|
||||
@ -874,12 +876,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
||||
const char *start= str;
|
||||
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
|
||||
value= value*LL(10) + (longlong) (*str - '0');
|
||||
if (transform_msec && i == count - 1) // microseconds always last
|
||||
{
|
||||
long msec_length= 6 - (uint) (str - start);
|
||||
if (msec_length > 0)
|
||||
value*= (long) log_10_int[msec_length];
|
||||
}
|
||||
msec_length= 6 - (str - start);
|
||||
values[i]= value;
|
||||
while (str != end && !my_isdigit(cs,*str))
|
||||
str++;
|
||||
@ -893,6 +890,10 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (transform_msec && msec_length > 0)
|
||||
values[count - 1] *= (long) log_10_int[msec_length];
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
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)
|
||||
|
@ -1074,9 +1074,9 @@ inline bool check_access(THD *thd, ulong access, const char *db,
|
||||
return false;
|
||||
}
|
||||
inline bool check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables,
|
||||
bool no_errors,
|
||||
bool any_combination_of_privileges_will_do,
|
||||
uint number)
|
||||
uint number,
|
||||
bool no_errors)
|
||||
{ return false; }
|
||||
#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);
|
||||
if(error)
|
||||
{
|
||||
tl->table->file->print_error(error, MYF(0));
|
||||
tl->table->in_use->fatal_error();
|
||||
tl->table->file->print_error(error, MYF(ME_FATALERROR));
|
||||
return error;
|
||||
}
|
||||
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)
|
||||
return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
|
||||
/* HA_ERR_LOCK_DEADLOCK or some other error */
|
||||
table->file->print_error(error, MYF(0));
|
||||
table->in_use->fatal_error();
|
||||
table->file->print_error(error, MYF(ME_FATALERROR));
|
||||
return(error);
|
||||
}
|
||||
removed_tables|= table->map;
|
||||
|
@ -4880,6 +4880,7 @@ ER_ZLIB_Z_DATA_ERROR
|
||||
spa "ZLIB: Dato de entrada fué corrompido para zlib"
|
||||
ER_CUT_VALUE_GROUP_CONCAT
|
||||
eng "Row %u was cut by GROUP_CONCAT()"
|
||||
por "Linha %u foi cortada por GROUP_CONCAT()"
|
||||
ER_WARN_TOO_FEW_RECORDS 01000
|
||||
eng "Row %ld doesn't contain data for all columns"
|
||||
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;
|
||||
break;
|
||||
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
|
||||
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;
|
||||
String old_packet;
|
||||
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
|
||||
|
||||
Object_creation_ctx *saved_creation_ctx;
|
||||
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;
|
||||
|
||||
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
|
||||
{
|
||||
thd->fatal_error();
|
||||
return NULL;
|
||||
}
|
||||
table->db_length= strlen(db);
|
||||
table->db= thd->strmake(db, table->db_length);
|
||||
table->table_name_length= strlen(name);
|
||||
|
@ -1331,12 +1331,12 @@ end:
|
||||
@param thd Pointer to the thread handler
|
||||
@param sql A pointer to the sql statement *
|
||||
@param query_length Length of the statement in characters
|
||||
|
||||
|
||||
@return status code
|
||||
@retval 1 Query was not cached.
|
||||
@retval 0 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 0 Query was not cached.
|
||||
@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.
|
||||
|
||||
In case of -1, no error is sent to the client.
|
||||
|
||||
*) The buffer must be allocated memory of size:
|
||||
|
@ -1982,9 +1982,15 @@ public:
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
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
|
||||
void clear_error();
|
||||
inline bool vio_ok() const { return true; }
|
||||
inline bool vio_ok() const { return TRUE; }
|
||||
inline bool is_connected() { return TRUE; }
|
||||
#endif
|
||||
/**
|
||||
Mark the current error as fatal. Warning: this does not
|
||||
@ -1993,6 +1999,7 @@ public:
|
||||
*/
|
||||
inline void fatal_error()
|
||||
{
|
||||
DBUG_ASSERT(main_da.is_error());
|
||||
is_fatal_error= 1;
|
||||
DBUG_PRINT("error",("Fatal error set"));
|
||||
}
|
||||
@ -2158,7 +2165,10 @@ public:
|
||||
else
|
||||
{
|
||||
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;
|
||||
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= new Delayed_insert()))
|
||||
{
|
||||
thd->fatal_error();
|
||||
goto end_create;
|
||||
}
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thread_count++;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
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)
|
||||
{
|
||||
/* The error is reported */
|
||||
delete di;
|
||||
thd->fatal_error();
|
||||
goto end_create;
|
||||
}
|
||||
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);
|
||||
di->unlock();
|
||||
delete di;
|
||||
my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
|
||||
thd->fatal_error();
|
||||
my_error(ER_CANT_CREATE_THREAD, MYF(ME_FATALERROR), error);
|
||||
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))
|
||||
{
|
||||
thd->fatal_error();
|
||||
my_error(ER_DELAYED_NOT_SUPPORTED, MYF(0), di->table_list.table_name);
|
||||
my_error(ER_DELAYED_NOT_SUPPORTED, MYF(ME_FATALERROR),
|
||||
di->table_list.table_name);
|
||||
goto err;
|
||||
}
|
||||
if (di->table->triggers)
|
||||
|
@ -458,7 +458,7 @@ struct ilink
|
||||
struct ilink **prev,*next;
|
||||
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)
|
||||
{
|
||||
|
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
|
||||
error=TRUE; // End server
|
||||
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
|
||||
case COM_BINLOG_DUMP:
|
||||
{
|
||||
@ -2073,7 +2025,6 @@ mysql_execute_command(THD *thd)
|
||||
A better approach would be to reset this for any commands
|
||||
that is not a SHOW command or a select that only access local
|
||||
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)
|
||||
thd->warning_info->set_read_only(TRUE);
|
||||
@ -2276,7 +2227,7 @@ mysql_execute_command(THD *thd)
|
||||
privileges_requested,
|
||||
all_tables, FALSE, UINT_MAX, FALSE);
|
||||
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)
|
||||
break;
|
||||
@ -5830,7 +5781,6 @@ bool check_stack_overrun(THD *thd, long margin,
|
||||
my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
|
||||
stack_used, my_thread_stack_size, margin);
|
||||
my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
|
||||
thd->fatal_error();
|
||||
return 1;
|
||||
}
|
||||
#ifndef DBUG_OFF
|
||||
@ -6494,13 +6444,17 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
DBUG_RETURN(0); /* purecov: inspected */
|
||||
if (table->db.str)
|
||||
{
|
||||
ptr->is_fqtn= TRUE;
|
||||
ptr->db= table->db.str;
|
||||
ptr->db_length= table->db.length;
|
||||
}
|
||||
else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
|
||||
DBUG_RETURN(0);
|
||||
else
|
||||
ptr->is_fqtn= FALSE;
|
||||
|
||||
ptr->alias= alias_str;
|
||||
ptr->is_alias= alias ? TRUE : FALSE;
|
||||
if (lower_case_table_names && table->table.length)
|
||||
table->table.length= my_casedn_str(files_charset_info, 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
|
||||
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++;
|
||||
/* All tables in aux_tables must be found in FROM PART */
|
||||
TABLE_LIST *walk;
|
||||
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;
|
||||
}
|
||||
TABLE_LIST *walk= multi_delete_table_match(lex, target_tbl, tables);
|
||||
if (!walk)
|
||||
{
|
||||
my_error(ER_UNKNOWN_TABLE, MYF(0),
|
||||
target_tbl->table_name, "MULTI DELETE");
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (!walk->derived)
|
||||
{
|
||||
target_tbl->table_name= walk->table_name;
|
||||
|
@ -2407,8 +2407,7 @@ char *generate_partition_syntax(partition_info *part_info,
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
/* We really shouldn't get here, no use in continuing from here */
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
||||
current_thd->fatal_error();
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
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->pack_frm_len)))
|
||||
{
|
||||
if (error != ER_OUTOFMEMORY)
|
||||
file->print_error(error, MYF(0));
|
||||
else
|
||||
lpt->thd->fatal_error();
|
||||
file->print_error(error, MYF(error != ER_OUTOFMEMORY ? 0 : ME_FATALERROR));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
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;
|
||||
result= item_sum->create_tmp_field(group, table, convert_blob_length);
|
||||
if (!result)
|
||||
thd->fatal_error();
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||
return result;
|
||||
}
|
||||
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
|
||||
INSERT IGNORE ... SELECT.
|
||||
*/
|
||||
thd->fatal_error();
|
||||
table->file->print_error(error,MYF(0));
|
||||
table->file->print_error(error, MYF(ME_FATALERROR));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
@ -15059,8 +15058,7 @@ calc_group_buffer(JOIN *join,ORDER *group)
|
||||
default:
|
||||
/* This case should never be choosen */
|
||||
DBUG_ASSERT(0);
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
||||
join->thd->fatal_error();
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||
}
|
||||
}
|
||||
parts++;
|
||||
|
@ -128,7 +128,7 @@ bool servers_init(bool dont_read_servers_table)
|
||||
}
|
||||
|
||||
/* 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)
|
||||
goto end;
|
||||
@ -180,7 +180,7 @@ static bool servers_load(THD *thd, TABLE_LIST *tables)
|
||||
|
||||
my_hash_reset(&servers_cache);
|
||||
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,
|
||||
FALSE);
|
||||
|
@ -1705,6 +1705,32 @@ public:
|
||||
template class I_List<thread_info>;
|
||||
#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)
|
||||
{
|
||||
Item *field;
|
||||
@ -1766,20 +1792,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
||||
if ((mysys_var= tmp->mysys_var))
|
||||
pthread_mutex_lock(&mysys_var->mutex);
|
||||
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
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
|
||||
thd_info->state_info= thread_state_info(tmp);
|
||||
if (mysys_var)
|
||||
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 ?
|
||||
now - tmp->start_time : 0), FALSE);
|
||||
/* STATE */
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
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)
|
||||
if ((val= thread_state_info(tmp)))
|
||||
{
|
||||
table->field[6]->store(val, strlen(val), cs);
|
||||
table->field[6]->set_notnull();
|
||||
@ -5071,8 +5070,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
||||
current_thd->fatal_error();
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
table->field[7]->set_notnull();
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
#include <mysql_com.h>
|
||||
#ifdef HAVE_FCONVERT
|
||||
#include <floatingpoint.h>
|
||||
#endif
|
||||
@ -499,22 +500,6 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs)
|
||||
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)
|
||||
{
|
||||
if (realloc(str_length+arg_length))
|
||||
|
@ -22,10 +22,6 @@
|
||||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
#ifndef NOT_FIXED_DEC
|
||||
#define NOT_FIXED_DEC 31
|
||||
#endif
|
||||
|
||||
class String;
|
||||
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
|
||||
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");
|
||||
|
||||
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))
|
||||
{
|
||||
@ -1871,7 +1871,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
|
||||
DBUG_ENTER("change_table_name");
|
||||
|
||||
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
|
||||
|
@ -662,11 +662,13 @@ int mysql_update(THD *thd,
|
||||
If (ignore && error is ignorable) we don't have to
|
||||
do anything; otherwise...
|
||||
*/
|
||||
myf flags= 0;
|
||||
|
||||
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);
|
||||
table->file->print_error(error,MYF(0));
|
||||
table->file->print_error(error,MYF(flags));
|
||||
error= 1;
|
||||
break;
|
||||
}
|
||||
@ -763,9 +765,8 @@ int mysql_update(THD *thd,
|
||||
*/
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
thd->fatal_error();
|
||||
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;
|
||||
/* 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
|
||||
do anything; otherwise...
|
||||
*/
|
||||
myf flags= 0;
|
||||
|
||||
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);
|
||||
table->file->print_error(error,MYF(0));
|
||||
table->file->print_error(error,MYF(flags));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
@ -2029,9 +2032,8 @@ int multi_update::do_updates()
|
||||
|
||||
err:
|
||||
{
|
||||
thd->fatal_error();
|
||||
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:
|
||||
|
@ -1190,7 +1190,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
|
||||
%type <item>
|
||||
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
|
||||
predicate bit_expr
|
||||
table_wild simple_expr udf_expr
|
||||
@ -1350,7 +1350,7 @@ END_OF_INPUT
|
||||
%type <NONE>
|
||||
'-' '+' '*' '/' '%' '(' ')'
|
||||
',' '!' '{' '}' '&' '|' 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:
|
||||
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;
|
||||
DBUG_ASSERT($1 < $3);
|
||||
@ -6983,11 +6990,6 @@ remember_end:
|
||||
}
|
||||
;
|
||||
|
||||
select_item2:
|
||||
table_wild { $$=$1; /* table.* */ }
|
||||
| expr { $$=$1; }
|
||||
;
|
||||
|
||||
select_alias:
|
||||
/* empty */ { $$=null_lex_str;}
|
||||
| AS ident { $$=$2; }
|
||||
@ -10048,7 +10050,7 @@ delete:
|
||||
lex->ignore= 0;
|
||||
lex->select_lex.init_order();
|
||||
}
|
||||
opt_delete_options single_multi {}
|
||||
opt_delete_options single_multi
|
||||
;
|
||||
|
||||
single_multi:
|
||||
@ -10063,45 +10065,45 @@ single_multi:
|
||||
| table_wild_list
|
||||
{ mysql_init_multi_delete(Lex); }
|
||||
FROM join_table_list where_clause
|
||||
{
|
||||
{
|
||||
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| FROM table_alias_ref_list
|
||||
{ mysql_init_multi_delete(Lex); }
|
||||
USING join_table_list where_clause
|
||||
{
|
||||
{
|
||||
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
table_wild_list:
|
||||
table_wild_one {}
|
||||
| table_wild_list ',' table_wild_one {}
|
||||
table_wild_one
|
||||
| table_wild_list ',' table_wild_one
|
||||
;
|
||||
|
||||
table_wild_one:
|
||||
ident opt_wild opt_table_alias
|
||||
ident opt_wild
|
||||
{
|
||||
Table_ident *ti= new Table_ident($1);
|
||||
if (ti == NULL)
|
||||
MYSQL_YYABORT;
|
||||
if (!Select->add_table_to_list(YYTHD,
|
||||
ti,
|
||||
$3,
|
||||
NULL,
|
||||
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
|
||||
Lex->lock_option))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| ident '.' ident opt_wild opt_table_alias
|
||||
| ident '.' ident opt_wild
|
||||
{
|
||||
Table_ident *ti= new Table_ident(YYTHD, $1, $3, 0);
|
||||
if (ti == NULL)
|
||||
MYSQL_YYABORT;
|
||||
if (!Select->add_table_to_list(YYTHD,
|
||||
ti,
|
||||
$5,
|
||||
NULL,
|
||||
TL_OPTION_UPDATING | TL_OPTION_ALIAS,
|
||||
Lex->lock_option))
|
||||
MYSQL_YYABORT;
|
||||
|
@ -1332,6 +1332,12 @@ struct TABLE_LIST
|
||||
*/
|
||||
bool create;
|
||||
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. */
|
||||
|
@ -1594,7 +1594,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
|
||||
my_hash_free(&tz_names);
|
||||
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));
|
||||
tz_inited= 1;
|
||||
|
||||
|
@ -30,10 +30,6 @@
|
||||
|
||||
#define DECIMAL_MAX_LENGTH ((8 * 9) - 8)
|
||||
|
||||
#ifndef NOT_FIXED_DEC
|
||||
#define NOT_FIXED_DEC 31
|
||||
#endif
|
||||
|
||||
C_MODE_START
|
||||
extern int decimal_bin_size(int, int);
|
||||
C_MODE_END
|
||||
|
@ -278,14 +278,11 @@ void my_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||
{
|
||||
const uchar *pos = key;
|
||||
|
||||
key+= len;
|
||||
|
||||
/*
|
||||
Remove trailing spaces. We have to do this to be able to compare
|
||||
'A ' and 'A' as identical
|
||||
*/
|
||||
while (key > pos && key[-1] == ' ')
|
||||
key--;
|
||||
key= skip_trailing_space(key, len);
|
||||
|
||||
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,
|
||||
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
|
||||
'AE' and 'Ä' as identical
|
||||
*/
|
||||
while (end > key && end[-1] == ' ')
|
||||
end--;
|
||||
end= skip_trailing_space(key, len);
|
||||
|
||||
for (; key < end ; key++)
|
||||
{
|
||||
|
@ -469,14 +469,11 @@ static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||
{
|
||||
const uchar *pos = key;
|
||||
|
||||
key+= len;
|
||||
|
||||
/*
|
||||
Remove trailing spaces. We have to do this to be able to compare
|
||||
'A ' and 'A' as identical
|
||||
*/
|
||||
while (key > pos && key[-1] == ' ')
|
||||
key--;
|
||||
key= skip_trailing_space(key, len);
|
||||
|
||||
for (; pos < (uchar*) key ; pos++)
|
||||
{
|
||||
|
@ -304,14 +304,13 @@ void my_hash_sort_simple(CHARSET_INFO *cs,
|
||||
ulong *nr1, ulong *nr2)
|
||||
{
|
||||
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
|
||||
'A ' and 'A' as identical
|
||||
*/
|
||||
while (end > key && end[-1] == ' ')
|
||||
end--;
|
||||
end= skip_trailing_space(key, len);
|
||||
|
||||
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)),
|
||||
const char *ptr, size_t length)
|
||||
{
|
||||
const char *end= ptr+length;
|
||||
while (end > ptr && end[-1] == ' ')
|
||||
end--;
|
||||
const char *end;
|
||||
end= (const char *) skip_trailing_space((const uchar *)ptr, length);
|
||||
return (size_t) (end-ptr);
|
||||
}
|
||||
|
||||
|
32
vio/vio.c
32
vio/vio.c
@ -22,6 +22,28 @@
|
||||
|
||||
#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.
|
||||
*/
|
||||
@ -60,6 +82,9 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
||||
vio->vioblocking =vio_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;
|
||||
/* Set default timeout */
|
||||
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->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*/
|
||||
vio->timeout= vio_win32_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->is_blocking =vio_is_blocking;
|
||||
vio->timeout =vio_timeout;
|
||||
vio->poll_read =vio_poll_read;
|
||||
vio->is_connected =vio_is_connected;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
@ -130,6 +160,8 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
|
||||
vio->vioblocking =vio_blocking;
|
||||
vio->is_blocking =vio_is_blocking;
|
||||
vio->timeout =vio_timeout;
|
||||
vio->poll_read =vio_poll_read;
|
||||
vio->is_connected =vio_is_connected;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
@ -29,6 +29,20 @@
|
||||
void vio_win32_timeout(Vio *vio, uint which, uint timeout);
|
||||
#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);
|
||||
|
||||
#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
|
||||
return 0;
|
||||
#else
|
||||
#ifdef __WIN__
|
||||
int res;
|
||||
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;
|
||||
int res;
|
||||
DBUG_ENTER("vio_poll");
|
||||
fds.fd=vio->sd;
|
||||
DBUG_ENTER("socket_poll_read");
|
||||
fds.fd=sd;
|
||||
fds.events=POLLIN;
|
||||
fds.revents=0;
|
||||
if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
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)
|
||||
{
|
||||
#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 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.
|
||||
@return Zero if all closing functions succeed, and nonzero otherwise.
|
||||
|
Loading…
x
Reference in New Issue
Block a user