Manual merge of mysql-next-mr-runtime upstream.

This commit is contained in:
Davi Arnaut 2009-11-19 21:48:08 -02:00
commit ecb6228c62
84 changed files with 2377 additions and 703 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,3 @@
-- source include/not_embedded.inc
# Save the initial number of concurrent sessions
--source include/count_sessions.inc

View File

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

View 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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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(); }

View File

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

View File

@ -855,7 +855,8 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
else
{
*is_null= item->get_time(&ltime);
value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(&ltime) : 0;
value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(&ltime) *
(ltime.neg ? -1 : 1) : 0;
}
/*
Do not cache GET_USER_VAR() function as its const_item() may return TRUE

View File

@ -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 */);
}

View File

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

View File

@ -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, &ltime);
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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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> &not_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:

View File

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

View File

@ -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. */

View File

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

View File

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

View File

@ -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++)
{

View File

@ -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++)
{

View File

@ -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++)
{

View File

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

View File

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

View File

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

View File

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