mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
Merge mysql.com:/usr/local/bk/mysql-5.0
into mysql.com:/home/pem/work/bug7049/mysql-5.0
This commit is contained in:
commit
6a88684eb3
73 changed files with 1054 additions and 758 deletions
|
@ -14,7 +14,7 @@ path=`dirname $0`
|
|||
if [ -z "$just_clean" ]
|
||||
then
|
||||
commands="$commands
|
||||
CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\" CXXLDFLAGS=\"$CXXLDFLAGS\" \
|
||||
CC=\"$CC\" CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\" CXXLDFLAGS=\"$CXXLDFLAGS\" \
|
||||
$configure"
|
||||
fi
|
||||
|
||||
|
|
|
@ -104,6 +104,10 @@ else
|
|||
make=make
|
||||
fi
|
||||
|
||||
if test -z "$CC" ; then
|
||||
CC=gcc
|
||||
fi
|
||||
|
||||
if test -z "$CXX" ; then
|
||||
CXX=gcc
|
||||
fi
|
||||
|
|
|
@ -320,7 +320,7 @@ static void initialize_readline (char *name);
|
|||
static void fix_history(String *final_command);
|
||||
#endif
|
||||
|
||||
static COMMANDS *find_command (char *name,char cmd_name);
|
||||
static COMMANDS *find_command(char *name,char cmd_name);
|
||||
static bool add_line(String &buffer,char *line,char *in_string,
|
||||
bool *ml_comment);
|
||||
static void remove_cntrl(String &buffer);
|
||||
|
@ -1109,10 +1109,12 @@ static int read_and_execute(bool interactive)
|
|||
}
|
||||
|
||||
|
||||
static COMMANDS *find_command (char *name,char cmd_char)
|
||||
static COMMANDS *find_command(char *name,char cmd_char)
|
||||
{
|
||||
uint len;
|
||||
char *end;
|
||||
DBUG_ENTER("find_command");
|
||||
DBUG_PRINT("enter",("name: '%s' char: %d", name ? name : "NULL", cmd_char));
|
||||
|
||||
if (!name)
|
||||
{
|
||||
|
@ -1124,12 +1126,16 @@ static COMMANDS *find_command (char *name,char cmd_char)
|
|||
while (my_isspace(charset_info,*name))
|
||||
name++;
|
||||
/*
|
||||
As special case we allow row that starts with word delimiter
|
||||
to be able to change delimiter if someone has delimiter 'delimiter'.
|
||||
If there is an \\g in the row or if the row has a delimiter but
|
||||
this is not a delimiter command, let add_line() take care of
|
||||
parsing the row and calling find_command()
|
||||
*/
|
||||
if (strstr(name, "\\g") || (strstr(name, delimiter) &&
|
||||
strncmp(name, "delimiter", 9)))
|
||||
return ((COMMANDS *) 0);
|
||||
strlen(name) >= 9 &&
|
||||
my_strnncoll(charset_info,(uchar*) name,
|
||||
9,
|
||||
(const uchar*) "delimiter", 9)))
|
||||
DBUG_RETURN((COMMANDS *) 0);
|
||||
if ((end=strcont(name," \t")))
|
||||
{
|
||||
len=(uint) (end - name);
|
||||
|
@ -1145,15 +1151,18 @@ static COMMANDS *find_command (char *name,char cmd_char)
|
|||
for (uint i= 0; commands[i].name; i++)
|
||||
{
|
||||
if (commands[i].func &&
|
||||
((name &&
|
||||
((name &&
|
||||
!my_strnncoll(charset_info,(uchar*)name,len,
|
||||
(uchar*)commands[i].name,len) &&
|
||||
!commands[i].name[len] &&
|
||||
(!end || (end && commands[i].takes_params))) ||
|
||||
!name && commands[i].cmd_char == cmd_char))
|
||||
return (&commands[i]);
|
||||
{
|
||||
DBUG_PRINT("exit",("found command: %s", commands[i].name));
|
||||
DBUG_RETURN(&commands[i]);
|
||||
}
|
||||
}
|
||||
return ((COMMANDS *) 0);
|
||||
DBUG_RETURN((COMMANDS *) 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1164,15 +1173,16 @@ static bool add_line(String &buffer,char *line,char *in_string,
|
|||
char buff[80], *pos, *out;
|
||||
COMMANDS *com;
|
||||
bool need_space= 0;
|
||||
DBUG_ENTER("add_line");
|
||||
|
||||
if (!line[0] && buffer.is_empty())
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
#ifdef HAVE_READLINE
|
||||
if (status.add_to_history && line[0] && not_in_history(line))
|
||||
add_history(line);
|
||||
#endif
|
||||
#ifdef USE_MB
|
||||
char *strend=line+(uint) strlen(line);
|
||||
char *end_of_line=line+(uint) strlen(line);
|
||||
#endif
|
||||
|
||||
for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
|
||||
|
@ -1181,13 +1191,14 @@ static bool add_line(String &buffer,char *line,char *in_string,
|
|||
buffer.is_empty())
|
||||
continue;
|
||||
#ifdef USE_MB
|
||||
int l;
|
||||
int length;
|
||||
if (use_mb(charset_info) &&
|
||||
(l = my_ismbchar(charset_info, pos, strend))) {
|
||||
while (l--)
|
||||
*out++ = *pos++;
|
||||
pos--;
|
||||
continue;
|
||||
(length= my_ismbchar(charset_info, pos, end_of_line)))
|
||||
{
|
||||
while (length--)
|
||||
*out++ = *pos++;
|
||||
pos--;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (!*ml_comment && inchar == '\\')
|
||||
|
@ -1207,7 +1218,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
|
|||
const String tmp(line,(uint) (out-line), charset_info);
|
||||
buffer.append(tmp);
|
||||
if ((*com->func)(&buffer,pos-1) > 0)
|
||||
return 1; // Quit
|
||||
DBUG_RETURN(1); // Quit
|
||||
if (com->takes_params)
|
||||
{
|
||||
for (pos++ ;
|
||||
|
@ -1225,29 +1236,40 @@ static bool add_line(String &buffer,char *line,char *in_string,
|
|||
{
|
||||
sprintf(buff,"Unknown command '\\%c'.",inchar);
|
||||
if (put_info(buff,INFO_ERROR) > 0)
|
||||
return 1;
|
||||
DBUG_RETURN(1);
|
||||
*out++='\\';
|
||||
*out++=(char) inchar;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
else if (!*ml_comment && (*pos == *delimiter &&
|
||||
is_prefix(pos + 1, delimiter + 1)) &&
|
||||
!*in_string)
|
||||
else if (!*ml_comment && !*in_string &&
|
||||
(*pos == *delimiter && is_prefix(pos + 1, delimiter + 1) ||
|
||||
buffer.length() == 0 && (out - line) >= 9 &&
|
||||
!my_strcasecmp(charset_info, line, "delimiter")))
|
||||
{
|
||||
uint old_delimiter_length= delimiter_length;
|
||||
if (out != line)
|
||||
buffer.append(line, (uint) (out - line)); // Add this line
|
||||
if ((com= find_command(buffer.c_ptr(), 0)))
|
||||
{
|
||||
if (com->func == com_delimiter)
|
||||
{
|
||||
/*
|
||||
Delimiter wants the get rest of the given line as argument to
|
||||
allow one to change ';' to ';;' and back
|
||||
*/
|
||||
char *end= strend(pos);
|
||||
buffer.append(pos, (uint) (end - pos));
|
||||
/* Ensure pos will point at \0 after the pos+= below */
|
||||
pos= end - old_delimiter_length + 1;
|
||||
}
|
||||
if ((*com->func)(&buffer, buffer.c_ptr()) > 0)
|
||||
return 1; // Quit
|
||||
DBUG_RETURN(1); // Quit
|
||||
}
|
||||
else
|
||||
{
|
||||
if (com_go(&buffer, 0) > 0) // < 0 is not fatal
|
||||
return 1;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
buffer.length(0);
|
||||
out= line;
|
||||
|
@ -1299,9 +1321,9 @@ static bool add_line(String &buffer,char *line,char *in_string,
|
|||
if (buffer.length() + length >= buffer.alloced_length())
|
||||
buffer.realloc(buffer.length()+length+IO_SIZE);
|
||||
if (!(*ml_comment) && buffer.append(line,length))
|
||||
return 1;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
** master/autocommit code by Brian Aker <brian@tangent.org>
|
||||
** SSL by
|
||||
** Andrei Errapart <andreie@no.spam.ee>
|
||||
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
|
||||
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
|
||||
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
|
||||
** and adapted to mysqldump 05/11/01 by Jani Tolonen
|
||||
** Added --single-transaction option 06/06/2002 by Peter Zaitsev
|
||||
|
@ -1172,23 +1172,25 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
|
|||
This function has logic to print the appropriate syntax depending on whether
|
||||
this is a procedure or functions
|
||||
|
||||
RETURN 0 succes, 1 if error
|
||||
RETURN
|
||||
0 Success
|
||||
1 Error
|
||||
*/
|
||||
|
||||
static uint dump_routines_for_db (char *db)
|
||||
static uint dump_routines_for_db(char *db)
|
||||
{
|
||||
char query_buff[512];
|
||||
const char *routine_type[]={"FUNCTION", "PROCEDURE"};
|
||||
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3], *routine_name;
|
||||
const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
|
||||
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
|
||||
char *routine_name;
|
||||
int i;
|
||||
FILE *sql_file = md_result_file;
|
||||
FILE *sql_file= md_result_file;
|
||||
MYSQL_RES *routine_res, *routine_list_res;
|
||||
MYSQL_ROW row, routine_list_row;
|
||||
|
||||
DBUG_ENTER("dump_routines_for_db");
|
||||
DBUG_PRINT("enter", ("db: '%s'", db));
|
||||
|
||||
mysql_real_escape_string(sock, db_name_buff, db, strlen(db));
|
||||
DBUG_PRINT("enter", ("db: '%s'", db_name_buff));
|
||||
|
||||
/* nice comments */
|
||||
if (opt_comments)
|
||||
|
@ -1201,10 +1203,10 @@ static uint dump_routines_for_db (char *db)
|
|||
if (lock_tables)
|
||||
mysql_query(sock, "LOCK TABLES mysql.proc READ");
|
||||
|
||||
fprintf(sql_file, "DELIMITER //\n");
|
||||
fprintf(sql_file, "DELIMITER ;;\n");
|
||||
|
||||
/* 0, retrieve and dump functions, 1, procedures */
|
||||
for (i=0; i <= 1; i++)
|
||||
for (i= 0; i <= 1; i++)
|
||||
{
|
||||
my_snprintf(query_buff, sizeof(query_buff),
|
||||
"SHOW %s STATUS WHERE Db = '%s'",
|
||||
|
@ -1216,18 +1218,18 @@ static uint dump_routines_for_db (char *db)
|
|||
if (mysql_num_rows(routine_list_res))
|
||||
{
|
||||
|
||||
while((routine_list_row= mysql_fetch_row(routine_list_res)))
|
||||
while ((routine_list_row= mysql_fetch_row(routine_list_res)))
|
||||
{
|
||||
DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i],
|
||||
name_buff));
|
||||
routine_name=quote_name(routine_list_row[1], name_buff, 0);
|
||||
routine_name= quote_name(routine_list_row[1], name_buff, 0);
|
||||
my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s",
|
||||
routine_type[i], routine_name);
|
||||
|
||||
if (mysql_query_with_error_report(sock, &routine_res, query_buff))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
while ((row=mysql_fetch_row(routine_res)))
|
||||
while ((row= mysql_fetch_row(routine_res)))
|
||||
{
|
||||
/*
|
||||
if the user has EXECUTE privilege he see routine names, but NOT the
|
||||
|
@ -1238,16 +1240,18 @@ static uint dump_routines_for_db (char *db)
|
|||
if (strlen(row[2]))
|
||||
{
|
||||
if (opt_drop)
|
||||
fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */ //\n",
|
||||
fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;;\n",
|
||||
routine_type[i], routine_name);
|
||||
/*
|
||||
we need to change sql_mode only for the CREATE PROCEDURE/FUNCTION
|
||||
otherwise we may need to re-quote routine_name
|
||||
we need to change sql_mode only for the CREATE
|
||||
PROCEDURE/FUNCTION otherwise we may need to re-quote routine_name
|
||||
*/;
|
||||
fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/ //\n",
|
||||
fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/;;\n",
|
||||
row[1] /* sql_mode */);
|
||||
fprintf(sql_file, "/*!50003 %s */ //\n", row[2]);
|
||||
fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ //\n");
|
||||
fprintf(sql_file, "/*!50003 %s */;;\n", row[2]);
|
||||
fprintf(sql_file,
|
||||
"/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/"
|
||||
";;\n");
|
||||
}
|
||||
} /* end of routine printing */
|
||||
} /* end of list of routines */
|
||||
|
@ -1283,7 +1287,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
|||
{
|
||||
MYSQL_RES *tableRes;
|
||||
MYSQL_ROW row;
|
||||
my_bool init=0;
|
||||
my_bool init=0, delayed, write_data, complete_insert;
|
||||
uint num_fields;
|
||||
char *result_table, *opt_quoted_table;
|
||||
const char *insert_option;
|
||||
|
@ -1292,31 +1296,33 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
|||
char query_buff[512];
|
||||
FILE *sql_file = md_result_file;
|
||||
int len;
|
||||
|
||||
DBUG_ENTER("get_table_structure");
|
||||
DBUG_PRINT("enter", ("db: %s, table: %s", db, table));
|
||||
DBUG_PRINT("enter", ("db: %s table: %s", db, table));
|
||||
|
||||
*ignore_flag= check_if_ignore_table(table, table_type);
|
||||
|
||||
if (opt_delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
|
||||
delayed= opt_delayed;
|
||||
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
|
||||
{
|
||||
delayed= 0;
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"-- Unable to use delayed inserts for table '%s' because it's of\
|
||||
type %s\n", table, table_type);
|
||||
"-- Warning: Unable to use delayed inserts for table '%s' "
|
||||
"because it's of type %s\n", table, table_type);
|
||||
}
|
||||
|
||||
if (!(*ignore_flag & IGNORE_DATA))
|
||||
complete_insert= 0;
|
||||
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
|
||||
{
|
||||
complete_insert= opt_complete_insert;
|
||||
if (!insert_pat_inited)
|
||||
insert_pat_inited= init_dynamic_string(&insert_pat, "", 1024, 1024);
|
||||
else
|
||||
dynstr_set(&insert_pat, "");
|
||||
}
|
||||
|
||||
insert_option= ((opt_delayed && opt_ignore &&
|
||||
!(*ignore_flag & IGNORE_INSERT_DELAYED)) ?
|
||||
" DELAYED IGNORE " :
|
||||
opt_delayed && !(*ignore_flag & IGNORE_INSERT_DELAYED) ? " DELAYED " :
|
||||
opt_ignore ? " IGNORE " : "");
|
||||
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
|
||||
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "-- Retrieving table structure for table %s...\n", table);
|
||||
|
@ -1448,17 +1454,18 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
|||
}
|
||||
|
||||
/*
|
||||
if *ignore_flag & IGNORE_DATA is true, then we don't build up insert statements
|
||||
for the table's data. Note: in subsequent lines of code, this test will
|
||||
have to be performed each time we are appending to insert_pat.
|
||||
If write_data is true, then we build up insert statements for
|
||||
the table's data. Note: in subsequent lines of code, this test
|
||||
will have to be performed each time we are appending to
|
||||
insert_pat.
|
||||
*/
|
||||
if (!(*ignore_flag & IGNORE_DATA))
|
||||
if (write_data)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, "INSERT ", 7);
|
||||
dynstr_append(&insert_pat, insert_option);
|
||||
dynstr_append_mem(&insert_pat, "INTO ", 5);
|
||||
dynstr_append(&insert_pat, opt_quoted_table);
|
||||
if (opt_complete_insert)
|
||||
if (complete_insert)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, " (", 2);
|
||||
}
|
||||
|
@ -1472,15 +1479,16 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
|||
|
||||
while ((row=mysql_fetch_row(tableRes)))
|
||||
{
|
||||
if (init)
|
||||
if (complete_insert)
|
||||
{
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
if (init)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, ", ", 2);
|
||||
}
|
||||
init=1;
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
}
|
||||
init=1;
|
||||
dynstr_append(&insert_pat,
|
||||
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
|
||||
}
|
||||
}
|
||||
num_fields= (uint) mysql_num_rows(tableRes);
|
||||
mysql_free_result(tableRes);
|
||||
|
@ -1528,7 +1536,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
|||
check_io(sql_file);
|
||||
}
|
||||
|
||||
if (!(*ignore_flag & IGNORE_DATA))
|
||||
if (write_data)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, "INSERT ", 7);
|
||||
dynstr_append(&insert_pat, insert_option);
|
||||
|
@ -1554,11 +1562,11 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
|||
fputs(",\n",sql_file);
|
||||
check_io(sql_file);
|
||||
}
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
if (complete_insert)
|
||||
dynstr_append_mem(&insert_pat, ", ", 2);
|
||||
}
|
||||
init=1;
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
if (opt_complete_insert)
|
||||
dynstr_append(&insert_pat,
|
||||
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
|
||||
if (!tFlag)
|
||||
|
@ -1719,7 +1727,7 @@ continue_xml:
|
|||
check_io(sql_file);
|
||||
}
|
||||
}
|
||||
if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
|
||||
if (opt_complete_insert)
|
||||
{
|
||||
dynstr_append_mem(&insert_pat, ") VALUES ", 9);
|
||||
if (!extended_insert)
|
||||
|
@ -1753,7 +1761,6 @@ static void dump_triggers_for_table (char *table, char *db)
|
|||
char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3];
|
||||
char query_buff[512];
|
||||
FILE *sql_file = md_result_file;
|
||||
|
||||
DBUG_ENTER("dump_triggers_for_table");
|
||||
DBUG_PRINT("enter", ("db: %s, table: %s", db, table));
|
||||
result_table= quote_name(table, table_buff, 1);
|
||||
|
@ -1771,11 +1778,11 @@ static void dump_triggers_for_table (char *table, char *db)
|
|||
}
|
||||
if (mysql_num_rows(result))
|
||||
fprintf(sql_file, "\n/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n\
|
||||
DELIMITER //;\n");
|
||||
DELIMITER ;;\n");
|
||||
while ((row=mysql_fetch_row(result)))
|
||||
{
|
||||
fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\" */ //\n\
|
||||
/*!50003 CREATE TRIGGER %s %s %s ON %s FOR EACH ROW%s */ //\n\n",
|
||||
fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n\
|
||||
/*!50003 CREATE TRIGGER %s %s %s ON %s FOR EACH ROW%s */;;\n\n",
|
||||
row[6], /* sql_mode */
|
||||
quote_name(row[0], name_buff, 0), /* Trigger */
|
||||
row[4], /* Timing */
|
||||
|
@ -1785,8 +1792,8 @@ DELIMITER //;\n");
|
|||
}
|
||||
if (mysql_num_rows(result))
|
||||
fprintf(sql_file,
|
||||
"DELIMITER ;//\n\
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;");
|
||||
"DELIMITER ;\n"
|
||||
"/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;\n");
|
||||
mysql_free_result(result);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
@ -1812,10 +1819,10 @@ static char *add_load_option(char *ptr,const char *object,
|
|||
|
||||
|
||||
/*
|
||||
** Allow the user to specify field terminator strings like:
|
||||
** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
|
||||
** This is done by doubleing ' and add a end -\ if needed to avoid
|
||||
** syntax errors from the SQL parser.
|
||||
Allow the user to specify field terminator strings like:
|
||||
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
|
||||
This is done by doubling ' and add a end -\ if needed to avoid
|
||||
syntax errors from the SQL parser.
|
||||
*/
|
||||
|
||||
static char *field_escape(char *to,const char *from,uint length)
|
||||
|
@ -1874,7 +1881,7 @@ static void dump_table(char *table, char *db)
|
|||
{
|
||||
char ignore_flag;
|
||||
char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3];
|
||||
char table_type[NAME_LEN];
|
||||
char table_type[NAME_LEN];
|
||||
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
|
||||
char *query= query_buf;
|
||||
int error= 0;
|
||||
|
@ -1889,7 +1896,7 @@ static void dump_table(char *table, char *db)
|
|||
Make sure you get the create table info before the following check for
|
||||
--no-data flag below. Otherwise, the create table info won't be printed.
|
||||
*/
|
||||
num_fields= get_table_structure(table, db, (char *)&table_type, &ignore_flag);
|
||||
num_fields= get_table_structure(table, db, table_type, &ignore_flag);
|
||||
|
||||
/* Check --no-data flag */
|
||||
if (dFlag)
|
||||
|
@ -1901,7 +1908,9 @@ static void dump_table(char *table, char *db)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
DBUG_PRINT("info", ("ignore_flag %x num_fields %d", ignore_flag, num_fields));
|
||||
DBUG_PRINT("info",
|
||||
("ignore_flag: %x num_fields: %d", (int) ignore_flag,
|
||||
num_fields));
|
||||
/*
|
||||
If the table type is a merge table or any type that has to be
|
||||
_completely_ ignored and no data dumped
|
||||
|
@ -1910,7 +1919,7 @@ static void dump_table(char *table, char *db)
|
|||
{
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"-- Skipping data for table '%s' because it's of type %s\n",
|
||||
"-- Warning: Skipping data for table '%s' because it's of type %s\n",
|
||||
table, table_type);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
@ -1927,7 +1936,6 @@ static void dump_table(char *table, char *db)
|
|||
result_table= quote_name(table,table_buff, 1);
|
||||
opt_quoted_table= quote_name(table, table_buff2, 0);
|
||||
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "-- Sending SELECT query...\n");
|
||||
if (path)
|
||||
|
@ -2989,7 +2997,7 @@ char check_if_ignore_table(const char *table_name, char *table_type)
|
|||
DBUG_RETURN(result); /* assume table is ok */
|
||||
}
|
||||
if (!(row[1]))
|
||||
strmake(table_type,"VIEW", NAME_LEN-1);
|
||||
strmake(table_type, "VIEW", NAME_LEN-1);
|
||||
else
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -143,7 +143,8 @@ typedef struct
|
|||
long code;
|
||||
} st_error;
|
||||
|
||||
static st_error global_error[] = {
|
||||
static st_error global_error[] =
|
||||
{
|
||||
#include <mysqld_ername.h>
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
@ -218,7 +219,8 @@ static int ps_match_re(char *);
|
|||
static char *ps_eprint(int);
|
||||
static void ps_free_reg(void);
|
||||
|
||||
static const char *embedded_server_groups[] = {
|
||||
static const char *embedded_server_groups[]=
|
||||
{
|
||||
"server",
|
||||
"embedded",
|
||||
"mysqltest_SERVER",
|
||||
|
@ -735,9 +737,7 @@ err:
|
|||
static int check_result(DYNAMIC_STRING* ds, const char *fname,
|
||||
my_bool require_option)
|
||||
{
|
||||
int error= RESULT_OK;
|
||||
int res= dyn_string_cmp(ds, fname);
|
||||
|
||||
DBUG_ENTER("check_result");
|
||||
|
||||
if (res && require_option)
|
||||
|
@ -747,18 +747,16 @@ static int check_result(DYNAMIC_STRING* ds, const char *fname,
|
|||
break; /* ok */
|
||||
case RESULT_LENGTH_MISMATCH:
|
||||
verbose_msg("Result length mismatch");
|
||||
error= RESULT_LENGTH_MISMATCH;
|
||||
break;
|
||||
case RESULT_CONTENT_MISMATCH:
|
||||
verbose_msg("Result content mismatch");
|
||||
error= RESULT_CONTENT_MISMATCH;
|
||||
break;
|
||||
default: /* impossible */
|
||||
die("Unknown error code from dyn_string_cmp()");
|
||||
}
|
||||
if (error)
|
||||
if (res != RESULT_OK)
|
||||
reject_dump(fname, ds->str, ds->length);
|
||||
DBUG_RETURN(error);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1286,7 +1284,7 @@ int do_modify_var(struct st_query *query, const char *name,
|
|||
if (*p != '$')
|
||||
die("First argument to %s must be a variable (start with $)", name);
|
||||
v= var_get(p, &p, 1, 0);
|
||||
switch (operator){
|
||||
switch (operator) {
|
||||
case DO_DEC:
|
||||
v->int_val--;
|
||||
break;
|
||||
|
|
|
@ -20,7 +20,7 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [
|
|||
-L\$(top_builddir)/extra/yassl/taocrypt/src -ltaocrypt"
|
||||
openssl_includes="-I\$(top_srcdir)/extra/yassl/include"
|
||||
AC_DEFINE([HAVE_OPENSSL], [1], [Defined by configure. Using yaSSL for OpenSSL emulation.])
|
||||
|
||||
AC_DEFINE([HAVE_YASSL], [1], [Defined by configure. Using yaSSL for OpenSSL emulation.])
|
||||
# System specific checks
|
||||
yassl_integer_extra_cxxflags=""
|
||||
case $host_cpu--$CXX_VERSION in
|
||||
|
|
|
@ -98,7 +98,6 @@ extern int NEAR my_errno; /* Last error in mysys */
|
|||
#define MY_RETURN_REAL_PATH 32 /* return full path for file */
|
||||
#define MY_SAFE_PATH 64 /* Return NULL if too long path */
|
||||
#define MY_RELATIVE_PATH 128 /* name is relative to 'dir' */
|
||||
#define MY_UNIX_PATH 256 /* convert path to UNIX format */
|
||||
|
||||
/* My seek flags */
|
||||
#define MY_SEEK_SET 0
|
||||
|
|
|
@ -409,7 +409,7 @@ my_bool check_scramble(const char *reply, const char *message,
|
|||
const unsigned char *hash_stage2);
|
||||
void get_salt_from_password(unsigned char *res, const char *password);
|
||||
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
|
||||
void octet2hex(char *to, const unsigned char *str, unsigned int len);
|
||||
char *octet2hex(char *to, const char *str, unsigned int len);
|
||||
|
||||
/* end of password.c */
|
||||
|
||||
|
|
|
@ -541,16 +541,16 @@ create table t1 ( a timestamp );
|
|||
alter table t1 add unique ( a(1) );
|
||||
ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys
|
||||
drop table t1;
|
||||
create database mysqltest1;
|
||||
create database mysqltest;
|
||||
create table t1 (c1 int);
|
||||
alter table t1 rename mysqltest1.t1;
|
||||
alter table t1 rename mysqltest.t1;
|
||||
drop table t1;
|
||||
ERROR 42S02: Unknown table 't1'
|
||||
alter table mysqltest1.t1 rename t1;
|
||||
alter table mysqltest.t1 rename t1;
|
||||
drop table t1;
|
||||
create table t1 (c1 int);
|
||||
use mysqltest1;
|
||||
drop database mysqltest1;
|
||||
use mysqltest;
|
||||
drop database mysqltest;
|
||||
alter table test.t1 rename t1;
|
||||
ERROR 3D000: No database selected
|
||||
alter table test.t1 rename test.t1;
|
||||
|
|
|
@ -1079,29 +1079,31 @@ char(53647)
|
|||
select char(0xff,0x8f);
|
||||
char(0xff,0x8f)
|
||||
ÿ<EFBFBD>
|
||||
Warnings:
|
||||
Warning 1300 Invalid utf8 character string: 'FF8F'
|
||||
set sql_mode=traditional;
|
||||
select char(0xff,0x8f);
|
||||
char(0xff,0x8f)
|
||||
NULL
|
||||
Warnings:
|
||||
Error 1300 Invalid utf8 character string: 'FF8F'
|
||||
ÿ<EFBFBD>
|
||||
select convert(char(0xff,0x8f) using utf8);
|
||||
convert(char(0xff,0x8f) using utf8)
|
||||
ÿ<EFBFBD>
|
||||
select char(195);
|
||||
char(195)
|
||||
NULL
|
||||
Warnings:
|
||||
Error 1300 Invalid utf8 character string: 'C3'
|
||||
Ã
|
||||
select convert(char(195) using utf8);
|
||||
convert(char(195) using utf8)
|
||||
Ã
|
||||
select char(196);
|
||||
char(196)
|
||||
NULL
|
||||
Warnings:
|
||||
Error 1300 Invalid utf8 character string: 'C4'
|
||||
select char(2557);
|
||||
char(2557)
|
||||
NULL
|
||||
Warnings:
|
||||
Error 1300 Invalid utf8 character string: 'FD'
|
||||
Ä
|
||||
select convert(char(196) using utf8);
|
||||
convert(char(196) using utf8)
|
||||
Ä
|
||||
select hex(char(2557));
|
||||
hex(char(2557))
|
||||
09FD
|
||||
select hex(convert(char(2557) using utf8));
|
||||
hex(convert(char(2557) using utf8))
|
||||
09FD
|
||||
set names utf8;
|
||||
create table t1 (a char(1)) default character set utf8;
|
||||
create table t2 (a char(1)) default character set utf8;
|
||||
|
|
|
@ -74,6 +74,12 @@ CREATE TABLE federated.t2 (
|
|||
)
|
||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
|
||||
SHOW CREATE TABLE federated.t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`id` int(20) NOT NULL,
|
||||
`name` varchar(32) NOT NULL default ''
|
||||
) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:9308/federated/t1'
|
||||
INSERT INTO federated.t2 (id, name) VALUES (1, 'foo');
|
||||
INSERT INTO federated.t2 (id, name) VALUES (2, 'fee');
|
||||
SELECT * FROM federated.t2;
|
||||
|
|
|
@ -21,6 +21,9 @@ length(_latin1'\n\t\n\b\0\\_\\%\\')
|
|||
select concat('monty',' was here ','again'),length('hello'),char(ascii('h')),ord('h');
|
||||
concat('monty',' was here ','again') length('hello') char(ascii('h')) ord('h')
|
||||
monty was here again 5 h 104
|
||||
select hex(char(256));
|
||||
hex(char(256))
|
||||
0100
|
||||
select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
|
||||
locate('he','hello') locate('he','hello',2) locate('lo','hello',2)
|
||||
1 0 4
|
||||
|
@ -598,7 +601,7 @@ collation(hex(130)) coercibility(hex(130))
|
|||
latin1_swedish_ci 4
|
||||
select collation(char(130)), coercibility(hex(130));
|
||||
collation(char(130)) coercibility(hex(130))
|
||||
latin1_swedish_ci 4
|
||||
binary 4
|
||||
select collation(format(130,10)), coercibility(format(130,10));
|
||||
collation(format(130,10)) coercibility(format(130,10))
|
||||
latin1_swedish_ci 4
|
||||
|
@ -720,7 +723,7 @@ t1 CREATE TABLE `t1` (
|
|||
`oct(130)` varchar(64) NOT NULL default '',
|
||||
`conv(130,16,10)` varchar(64) NOT NULL default '',
|
||||
`hex(130)` varchar(6) NOT NULL default '',
|
||||
`char(130)` varchar(1) NOT NULL default '',
|
||||
`char(130)` varbinary(1) NOT NULL default '',
|
||||
`format(130,10)` varchar(4) NOT NULL default '',
|
||||
`left(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '',
|
||||
`right(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '',
|
||||
|
@ -818,6 +821,9 @@ lpad(12345, 5, "#")
|
|||
SELECT conv(71, 10, 36), conv('1Z', 36, 10);
|
||||
conv(71, 10, 36) conv('1Z', 36, 10)
|
||||
1Z 71
|
||||
SELECT conv(71, 10, 37), conv('1Z', 37, 10), conv(0,1,10),conv(0,0,10), conv(0,-1,10);
|
||||
conv(71, 10, 37) conv('1Z', 37, 10) conv(0,1,10) conv(0,0,10) conv(0,-1,10)
|
||||
NULL NULL NULL NULL NULL
|
||||
create table t1 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
|
||||
insert into t1 values (1,'aaaaaaaaaa'), (2,'bbbbbbbbbb');
|
||||
create table t2 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
drop table if exists t1;
|
||||
create table t1(a int);
|
||||
insert into t1 values(1);
|
||||
ERROR at line 9: DELIMITER must be followed by a 'delimiter' character or string
|
||||
|
||||
Test default delimiter ;
|
||||
a
|
||||
|
|
|
@ -1869,31 +1869,32 @@ UNLOCK TABLES;
|
|||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
|
||||
/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
|
||||
DELIMITER //;
|
||||
/*!50003 SET SESSION SQL_MODE="" */ //
|
||||
DELIMITER ;;
|
||||
/*!50003 SET SESSION SQL_MODE="" */;;
|
||||
/*!50003 CREATE TRIGGER `trg1` BEFORE INSERT ON `t1` FOR EACH ROW
|
||||
begin
|
||||
if new.a > 10 then
|
||||
set new.a := 10;
|
||||
set new.a := 11;
|
||||
end if;
|
||||
end */ //
|
||||
end */;;
|
||||
|
||||
/*!50003 SET SESSION SQL_MODE="" */ //
|
||||
/*!50003 SET SESSION SQL_MODE="" */;;
|
||||
/*!50003 CREATE TRIGGER `trg2` BEFORE UPDATE ON `t1` FOR EACH ROW begin
|
||||
if old.a % 2 = 0 then set new.b := 12; end if;
|
||||
end */ //
|
||||
end */;;
|
||||
|
||||
/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */ //
|
||||
/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */;;
|
||||
/*!50003 CREATE TRIGGER `trg3` AFTER UPDATE ON `t1` FOR EACH ROW
|
||||
begin
|
||||
if new.a = -1 then
|
||||
set @fired:= "Yes";
|
||||
end if;
|
||||
end */ //
|
||||
end */;;
|
||||
|
||||
DELIMITER ;//
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;DROP TABLE IF EXISTS `t2`;
|
||||
DELIMITER ;
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;
|
||||
DROP TABLE IF EXISTS `t2`;
|
||||
CREATE TABLE `t2` (
|
||||
`a` int(11) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
@ -1905,17 +1906,18 @@ UNLOCK TABLES;
|
|||
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
|
||||
|
||||
/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
|
||||
DELIMITER //;
|
||||
/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */ //
|
||||
DELIMITER ;;
|
||||
/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */;;
|
||||
/*!50003 CREATE TRIGGER `trg4` BEFORE INSERT ON `t2` FOR EACH ROW
|
||||
begin
|
||||
if new.a > 10 then
|
||||
set @fired:= "No";
|
||||
end if;
|
||||
end */ //
|
||||
end */;;
|
||||
|
||||
DELIMITER ;//
|
||||
DELIMITER ;
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
|
@ -2077,37 +2079,37 @@ LOCK TABLES `t1` WRITE;
|
|||
INSERT INTO `t1` VALUES (1),(2),(3),(4),(5);
|
||||
UNLOCK TABLES;
|
||||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
DELIMITER //
|
||||
/*!50003 DROP FUNCTION IF EXISTS `bug9056_func1` */ //
|
||||
/*!50003 SET SESSION SQL_MODE=""*/ //
|
||||
DELIMITER ;;
|
||||
/*!50003 DROP FUNCTION IF EXISTS `bug9056_func1` */;;
|
||||
/*!50003 SET SESSION SQL_MODE=""*/;;
|
||||
/*!50003 CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
|
||||
RETURN a+b */ //
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ //
|
||||
/*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */ //
|
||||
/*!50003 SET SESSION SQL_MODE=""*/ //
|
||||
RETURN a+b */;;
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
|
||||
/*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */;;
|
||||
/*!50003 SET SESSION SQL_MODE=""*/;;
|
||||
/*!50003 CREATE FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1)
|
||||
begin
|
||||
set f1= concat( 'hello', f1 );
|
||||
return f1;
|
||||
end */ //
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ //
|
||||
/*!50003 DROP PROCEDURE IF EXISTS `a'b` */ //
|
||||
/*!50003 SET SESSION SQL_MODE="REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI"*/ //
|
||||
end */;;
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
|
||||
/*!50003 DROP PROCEDURE IF EXISTS `a'b` */;;
|
||||
/*!50003 SET SESSION SQL_MODE="REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI"*/;;
|
||||
/*!50003 CREATE PROCEDURE "a'b"()
|
||||
select 1 */ //
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ //
|
||||
/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc1` */ //
|
||||
/*!50003 SET SESSION SQL_MODE=""*/ //
|
||||
select 1 */;;
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
|
||||
/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc1` */;;
|
||||
/*!50003 SET SESSION SQL_MODE=""*/;;
|
||||
/*!50003 CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
|
||||
BEGIN SELECT a+b INTO c; end */ //
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ //
|
||||
/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc2` */ //
|
||||
/*!50003 SET SESSION SQL_MODE=""*/ //
|
||||
BEGIN SELECT a+b INTO c; end */;;
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
|
||||
/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc2` */;;
|
||||
/*!50003 SET SESSION SQL_MODE=""*/;;
|
||||
/*!50003 CREATE PROCEDURE `bug9056_proc2`(OUT a INT)
|
||||
BEGIN
|
||||
select sum(id) from t1 into a;
|
||||
END */ //
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ //
|
||||
END */;;
|
||||
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
|
||||
DELIMITER ;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
DROP TABLE IF EXISTS t1,t2;
|
||||
CREATE TABLE t1 (a int);
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
CREATE TABLE t2 (a int, b int);
|
||||
|
|
|
@ -809,4 +809,11 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
explain select * from t2 where a = 'a' or a='a ';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ref a a 13 const # Using where
|
||||
update t1 set a='b' where a<>'a';
|
||||
explain select * from t1 where a not between 'b' and 'b';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 13 NULL # Using where
|
||||
select * from t1 where a not between 'b' and 'b';
|
||||
a filler
|
||||
a
|
||||
drop table t1,t2,t3;
|
||||
|
|
|
@ -834,3 +834,41 @@ ERROR HY000: Not allowed to set autocommit from a stored function or trigger
|
|||
create trigger bug12712
|
||||
before insert on t1 for each row set session autocommit = 0;
|
||||
ERROR HY000: Not allowed to set autocommit from a stored function or trigger
|
||||
drop procedure if exists bug13510_1|
|
||||
drop procedure if exists bug13510_2|
|
||||
drop procedure if exists bug13510_3|
|
||||
drop procedure if exists bug13510_4|
|
||||
create procedure bug13510_1()
|
||||
begin
|
||||
declare password varchar(10);
|
||||
set password = 'foo1';
|
||||
select password;
|
||||
end|
|
||||
ERROR 42000: Variable 'password' must be quoted with `...`, or renamed
|
||||
create procedure bug13510_2()
|
||||
begin
|
||||
declare names varchar(10);
|
||||
set names = 'foo2';
|
||||
select names;
|
||||
end|
|
||||
ERROR 42000: Variable 'names' must be quoted with `...`, or renamed
|
||||
create procedure bug13510_3()
|
||||
begin
|
||||
declare password varchar(10);
|
||||
set `password` = 'foo3';
|
||||
select password;
|
||||
end|
|
||||
create procedure bug13510_4()
|
||||
begin
|
||||
declare names varchar(10);
|
||||
set `names` = 'foo4';
|
||||
select names;
|
||||
end|
|
||||
call bug13510_3()|
|
||||
password
|
||||
foo3
|
||||
call bug13510_4()|
|
||||
names
|
||||
foo4
|
||||
drop procedure bug13510_3|
|
||||
drop procedure bug13510_4|
|
||||
|
|
|
@ -11,7 +11,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
|||
master-bin.000001 98 User var 1 139 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci
|
||||
master-bin.000001 139 Query 1 231 use `test`; INSERT INTO t1 VALUES(@`a b`)
|
||||
master-bin.000001 231 User var 1 273 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci
|
||||
master-bin.000001 273 User var 1 311 @`var2`=_latin1 0x61 COLLATE latin1_swedish_ci
|
||||
master-bin.000001 273 User var 1 311 @`var2`=_binary 0x61 COLLATE binary
|
||||
master-bin.000001 311 Query 1 411 use `test`; insert into t1 values (@var1),(@var2)
|
||||
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
|
||||
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
|
||||
|
@ -24,7 +24,7 @@ SET @@session.sql_mode=0;
|
|||
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
|
||||
INSERT INTO t1 VALUES(@`a b`);
|
||||
SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`;
|
||||
SET @`var2`:=_latin1 0x61 COLLATE `latin1_swedish_ci`;
|
||||
SET @`var2`:=_binary 0x61 COLLATE `binary`;
|
||||
SET TIMESTAMP=10000;
|
||||
insert into t1 values (@var1),(@var2);
|
||||
# End of log file
|
||||
|
|
|
@ -847,13 +847,16 @@ cast(1 as char(3))
|
|||
drop view v1;
|
||||
create table t1 (a int);
|
||||
create view v1 as select a from t1;
|
||||
create database seconddb;
|
||||
rename table v1 to seconddb.v1;
|
||||
ERROR HY000: Changing schema from 'test' to 'seconddb' is not allowed.
|
||||
create view v3 as select a from t1;
|
||||
create database mysqltest;
|
||||
rename table v1 to mysqltest.v1;
|
||||
ERROR HY000: Changing schema from 'test' to 'mysqltest' is not allowed.
|
||||
rename table v1 to v2;
|
||||
rename table v3 to v1, v2 to t1;
|
||||
ERROR 42S01: Table 't1' already exists
|
||||
drop table t1;
|
||||
drop view v2;
|
||||
drop database seconddb;
|
||||
drop view v2,v3;
|
||||
drop database mysqltest;
|
||||
create view v1 as select 'a',1;
|
||||
create view v2 as select * from v1 union all select * from v1;
|
||||
create view v3 as select * from v2 where 1 = (select `1` from v2);
|
||||
|
@ -2298,3 +2301,25 @@ a
|
|||
3
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b INT, INDEX(a,b));
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
CREATE TABLE t3 (a INT);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||
INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
|
||||
INSERT INTO t3 VALUES (1),(2),(3);
|
||||
CREATE VIEW v1 AS SELECT t1.* FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b;
|
||||
CREATE VIEW v2 AS SELECT t3.* FROM t1,t3 WHERE t1.a=t3.a;
|
||||
EXPLAIN SELECT t1.* FROM t1 JOIN t2 WHERE t1.a=t2.a AND t1.b=t2.b AND t1.a=1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
|
||||
1 SIMPLE t2 ref a a 10 const,test.t1.b 2 Using where; Using index
|
||||
EXPLAIN SELECT * FROM v1 WHERE a=1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
|
||||
1 PRIMARY t2 ref a a 10 const,test.t1.b 2 Using where; Using index
|
||||
EXPLAIN SELECT * FROM v2 WHERE a=1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
|
||||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
|
|
@ -373,24 +373,24 @@ drop table t1;
|
|||
# Bug#11493 - Alter table rename to default database does not work without
|
||||
# db name qualifying
|
||||
#
|
||||
create database mysqltest1;
|
||||
create database mysqltest;
|
||||
create table t1 (c1 int);
|
||||
# Move table to other database.
|
||||
alter table t1 rename mysqltest1.t1;
|
||||
alter table t1 rename mysqltest.t1;
|
||||
# Assure that it has moved.
|
||||
--error 1051
|
||||
drop table t1;
|
||||
# Move table back.
|
||||
alter table mysqltest1.t1 rename t1;
|
||||
alter table mysqltest.t1 rename t1;
|
||||
# Assure that it is back.
|
||||
drop table t1;
|
||||
# Now test for correct message if no database is selected.
|
||||
# Create t1 in 'test'.
|
||||
create table t1 (c1 int);
|
||||
# Change to other db.
|
||||
use mysqltest1;
|
||||
use mysqltest;
|
||||
# Drop the current db. This de-selects any db.
|
||||
drop database mysqltest1;
|
||||
drop database mysqltest;
|
||||
# Now test for correct message.
|
||||
--error 1046
|
||||
alter table test.t1 rename t1;
|
||||
|
|
|
@ -880,9 +880,13 @@ select char(0xff,0x8f);
|
|||
# incorrect value in strict mode: return NULL with "Error" level warning
|
||||
set sql_mode=traditional;
|
||||
select char(0xff,0x8f);
|
||||
select convert(char(0xff,0x8f) using utf8);
|
||||
select char(195);
|
||||
select convert(char(195) using utf8);
|
||||
select char(196);
|
||||
select char(2557);
|
||||
select convert(char(196) using utf8);
|
||||
select hex(char(2557));
|
||||
select hex(convert(char(2557) using utf8));
|
||||
|
||||
#
|
||||
# Bug#12891: UNION doesn't return DISTINCT result for multi-byte characters
|
||||
|
|
|
@ -75,6 +75,8 @@ eval CREATE TABLE federated.t2 (
|
|||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
|
||||
|
||||
SHOW CREATE TABLE federated.t2;
|
||||
|
||||
INSERT INTO federated.t2 (id, name) VALUES (1, 'foo');
|
||||
INSERT INTO federated.t2 (id, name) VALUES (2, 'fee');
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ select bit_length('\n\t\r\b\0\_\%\\');
|
|||
select char_length('\n\t\r\b\0\_\%\\');
|
||||
select length(_latin1'\n\t\n\b\0\\_\\%\\');
|
||||
select concat('monty',' was here ','again'),length('hello'),char(ascii('h')),ord('h');
|
||||
select hex(char(256));
|
||||
select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
|
||||
select instr('hello','HE'), instr('hello',binary 'HE'), instr(binary 'hello','HE');
|
||||
select position(binary 'll' in 'hello'),position('a' in binary 'hello');
|
||||
|
@ -467,6 +468,7 @@ SELECT lpad(12345, 5, "#");
|
|||
#
|
||||
|
||||
SELECT conv(71, 10, 36), conv('1Z', 36, 10);
|
||||
SELECT conv(71, 10, 37), conv('1Z', 37, 10), conv(0,1,10),conv(0,0,10), conv(0,-1,10);
|
||||
|
||||
#
|
||||
# Bug in SUBSTRING when mixed with CONCAT and ORDER BY (Bug #3089)
|
||||
|
|
|
@ -14,7 +14,7 @@ create table t1(a int);
|
|||
insert into t1 values(1);
|
||||
|
||||
# Test delimiters
|
||||
--exec $MYSQL test < "./t/mysql_delimiter.sql"
|
||||
--exec $MYSQL test 2>&1 < "./t/mysql_delimiter.sql"
|
||||
|
||||
--disable_query_log
|
||||
# Test delimiter : supplied on the command line
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
# Can't run test of external client with embedded server
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1,t2;
|
||||
--enable_warnings
|
||||
|
||||
#
|
||||
## Bug #5036 mysqlshow is missing a column
|
||||
#
|
||||
|
|
|
@ -625,4 +625,9 @@ explain select * from t2 where a between 'a' and 'a ';
|
|||
--replace_column 9 #
|
||||
explain select * from t2 where a = 'a' or a='a ';
|
||||
|
||||
update t1 set a='b' where a<>'a';
|
||||
--replace_column 9 #
|
||||
explain select * from t1 where a not between 'b' and 'b';
|
||||
select * from t1 where a not between 'b' and 'b';
|
||||
|
||||
drop table t1,t2,t3;
|
||||
|
|
|
@ -1212,6 +1212,59 @@ call bug9367();
|
|||
drop procedure bug9367;
|
||||
drop table t1;
|
||||
--enable_parsing
|
||||
|
||||
#
|
||||
# BUG#13510: Setting password local variable changes current password
|
||||
#
|
||||
delimiter |;
|
||||
--disable_warnings
|
||||
drop procedure if exists bug13510_1|
|
||||
drop procedure if exists bug13510_2|
|
||||
drop procedure if exists bug13510_3|
|
||||
drop procedure if exists bug13510_4|
|
||||
--enable_warnings
|
||||
|
||||
--error ER_SP_BAD_VAR_SHADOW
|
||||
create procedure bug13510_1()
|
||||
begin
|
||||
declare password varchar(10);
|
||||
|
||||
set password = 'foo1';
|
||||
select password;
|
||||
end|
|
||||
|
||||
--error ER_SP_BAD_VAR_SHADOW
|
||||
create procedure bug13510_2()
|
||||
begin
|
||||
declare names varchar(10);
|
||||
|
||||
set names = 'foo2';
|
||||
select names;
|
||||
end|
|
||||
|
||||
create procedure bug13510_3()
|
||||
begin
|
||||
declare password varchar(10);
|
||||
|
||||
set `password` = 'foo3';
|
||||
select password;
|
||||
end|
|
||||
|
||||
create procedure bug13510_4()
|
||||
begin
|
||||
declare names varchar(10);
|
||||
|
||||
set `names` = 'foo4';
|
||||
select names;
|
||||
end|
|
||||
|
||||
call bug13510_3()|
|
||||
call bug13510_4()|
|
||||
|
||||
drop procedure bug13510_3|
|
||||
drop procedure bug13510_4|
|
||||
delimiter ;|
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
|
|
@ -790,13 +790,16 @@ drop view v1;
|
|||
#
|
||||
create table t1 (a int);
|
||||
create view v1 as select a from t1;
|
||||
create database seconddb;
|
||||
create view v3 as select a from t1;
|
||||
create database mysqltest;
|
||||
-- error 1450
|
||||
rename table v1 to seconddb.v1;
|
||||
rename table v1 to mysqltest.v1;
|
||||
rename table v1 to v2;
|
||||
--error 1050
|
||||
rename table v3 to v1, v2 to t1;
|
||||
drop table t1;
|
||||
drop view v2;
|
||||
drop database seconddb;
|
||||
drop view v2,v3;
|
||||
drop database mysqltest;
|
||||
|
||||
#
|
||||
# bug handling from VIEWs
|
||||
|
@ -2167,3 +2170,23 @@ SELECT v_1.a FROM v1 AS v_1 GROUP BY v_1.a HAVING v_1.a IN (1,2,3);
|
|||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #13327 view wasn't using index for const condition
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a INT, b INT, INDEX(a,b));
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
CREATE TABLE t3 (a INT);
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||
INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
|
||||
INSERT INTO t3 VALUES (1),(2),(3);
|
||||
CREATE VIEW v1 AS SELECT t1.* FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b;
|
||||
CREATE VIEW v2 AS SELECT t3.* FROM t1,t3 WHERE t1.a=t3.a;
|
||||
EXPLAIN SELECT t1.* FROM t1 JOIN t2 WHERE t1.a=t2.a AND t1.b=t2.b AND t1.a=1;
|
||||
EXPLAIN SELECT * FROM v1 WHERE a=1;
|
||||
EXPLAIN SELECT * FROM v2 WHERE a=1;
|
||||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,12 @@
|
|||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
/*
|
||||
Formats a filename with possible replace of directory of extension
|
||||
Function can handle the case where 'to' == 'name'
|
||||
For a description of the flag values, consult my_sys.h
|
||||
The arguments should be in unix format.
|
||||
*/
|
||||
|
||||
/*
|
||||
Formats a filename with possible replace of directory of extension
|
||||
Function can handle the case where 'to' == 'name'
|
||||
For a description of the flag values, consult my_sys.h
|
||||
The arguments should be in unix format.
|
||||
*/
|
||||
|
||||
my_string fn_format(my_string to, const char *name, const char *dir,
|
||||
const char *extension, uint flag)
|
||||
|
@ -54,8 +53,7 @@ my_string fn_format(my_string to, const char *name, const char *dir,
|
|||
pack_dirname(dev,dev); /* Put in ./.. and ~/.. */
|
||||
if (flag & MY_UNPACK_FILENAME)
|
||||
(void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */
|
||||
if (flag & MY_UNIX_PATH)
|
||||
to_unix_path(dev); /* Fix to MySQL representation */
|
||||
|
||||
if ((pos= (char*) strchr(name,FN_EXTCHAR)) != NullS)
|
||||
{
|
||||
if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */
|
||||
|
|
|
@ -2750,9 +2750,12 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond,
|
|||
gettimeofday(&now, &tz);
|
||||
/* Prepare timeout value */
|
||||
timeout.tv_sec= now.tv_sec + KEYCACHE_TIMEOUT;
|
||||
timeout.tv_nsec= now.tv_usec * 1000; /* timeval uses microseconds. */
|
||||
/* timespec uses nanoseconds. */
|
||||
/* 1 nanosecond = 1000 micro seconds. */
|
||||
/*
|
||||
timeval uses microseconds.
|
||||
timespec uses nanoseconds.
|
||||
1 nanosecond = 1000 micro seconds
|
||||
*/
|
||||
timeout.tv_nsec= now.tv_usec * 1000;
|
||||
KEYCACHE_THREAD_TRACE_END("started waiting");
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
cnt++;
|
||||
|
@ -2762,17 +2765,15 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond,
|
|||
#endif
|
||||
rc= pthread_cond_timedwait(cond, mutex, &timeout);
|
||||
KEYCACHE_THREAD_TRACE_BEGIN("finished waiting");
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
if (rc == ETIMEDOUT)
|
||||
if (rc == ETIMEDOUT || rc == ETIME)
|
||||
{
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
fprintf(keycache_debug_log,"aborted by keycache timeout\n");
|
||||
fclose(keycache_debug_log);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rc == ETIMEDOUT)
|
||||
keycache_dump();
|
||||
}
|
||||
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
KEYCACHE_DBUG_ASSERT(rc != ETIMEDOUT);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
** The following is a simple implementation of posix conditions
|
||||
*****************************************************************************/
|
||||
|
||||
#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
|
||||
#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
|
||||
#include "mysys_priv.h"
|
||||
#if defined(THREAD) && defined(OS2)
|
||||
#include <m_string.h>
|
||||
|
@ -31,134 +31,109 @@
|
|||
|
||||
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
|
||||
{
|
||||
APIRET rc = 0;
|
||||
HEV event;
|
||||
cond->waiting=0;
|
||||
/* Warp3 FP29 or Warp4 FP4 or better required */
|
||||
rc = DosCreateEventSem( NULL, &cond->semaphore, 0x0800, 0);
|
||||
if (rc)
|
||||
return ENOMEM;
|
||||
|
||||
cond->waiting= 0;
|
||||
/* Warp3 FP29 or Warp4 FP4 or better required */
|
||||
if (DosCreateEventSem(NULL, &cond->semaphore, 0x0800, 0))
|
||||
return ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_cond_destroy(pthread_cond_t *cond)
|
||||
{
|
||||
APIRET rc;
|
||||
|
||||
do {
|
||||
rc = DosCloseEventSem(cond->semaphore);
|
||||
if (rc == 301) DosPostEventSem(cond->semaphore);
|
||||
} while (rc == 301);
|
||||
if (rc)
|
||||
return EINVAL;
|
||||
|
||||
return 0;
|
||||
for (;;)
|
||||
{
|
||||
APIRET rc;
|
||||
if ((rc= DosCloseEventSem(cond->semaphore)) != 301)
|
||||
return rc ? EINVAL : 0;
|
||||
DosPostEventSem(cond->semaphore);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
APIRET rc;
|
||||
int rval;
|
||||
|
||||
rval = 0;
|
||||
cond->waiting++;
|
||||
|
||||
if (mutex) pthread_mutex_unlock(mutex);
|
||||
|
||||
rc = DosWaitEventSem(cond->semaphore,SEM_INDEFINITE_WAIT);
|
||||
if (rc != 0)
|
||||
rval = EINVAL;
|
||||
|
||||
if (mutex) pthread_mutex_lock(mutex);
|
||||
|
||||
cond->waiting--;
|
||||
|
||||
return rval;
|
||||
int rval= 0;
|
||||
cond->waiting++;
|
||||
if (mutex)
|
||||
pthread_mutex_unlock(mutex);
|
||||
if (DosWaitEventSem(cond->semaphore, SEM_INDEFINITE_WAIT))
|
||||
rval= EINVAL;
|
||||
if (mutex)
|
||||
pthread_mutex_lock(mutex);
|
||||
cond->waiting--;
|
||||
return rval;
|
||||
}
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
struct timespec *abstime)
|
||||
struct timespec *abstime)
|
||||
{
|
||||
struct timeb curtime;
|
||||
int result;
|
||||
long timeout;
|
||||
APIRET rc;
|
||||
int rval;
|
||||
int rval= 0;
|
||||
|
||||
_ftime(&curtime);
|
||||
timeout= ((long) (abstime->ts_sec - curtime.time)*1000L +
|
||||
(long)((abstime->ts_nsec/1000) - curtime.millitm)/1000L);
|
||||
if (timeout < 0) /* Some safety */
|
||||
timeout = 0L;
|
||||
_ftime(&curtime);
|
||||
timeout= ((long) (abstime->ts_sec - curtime.time) * 1000L +
|
||||
(long) ((abstime->ts_nsec / 1000) - curtime.millitm) / 1000L);
|
||||
if (timeout < 0) /* Some safety */
|
||||
timeout= 0L;
|
||||
|
||||
rval = 0;
|
||||
cond->waiting++;
|
||||
cond->waiting++;
|
||||
|
||||
if (mutex) pthread_mutex_unlock(mutex);
|
||||
if (mutex)
|
||||
pthread_mutex_unlock(mutex);
|
||||
if (DosWaitEventSem(cond->semaphore, timeout) != 0)
|
||||
rval= ETIMEDOUT;
|
||||
if (mutex)
|
||||
pthread_mutex_lock(mutex);
|
||||
|
||||
rc = DosWaitEventSem(cond->semaphore, timeout);
|
||||
if (rc != 0)
|
||||
rval= ETIMEDOUT;
|
||||
cond->waiting--;
|
||||
|
||||
if (mutex) pthread_mutex_lock(mutex);
|
||||
|
||||
cond->waiting--;
|
||||
|
||||
return rval;
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
int pthread_cond_signal(pthread_cond_t *cond)
|
||||
{
|
||||
APIRET rc;
|
||||
|
||||
/* Bring the next thread off the condition queue: */
|
||||
rc = DosPostEventSem(cond->semaphore);
|
||||
return 0;
|
||||
/* Bring the next thread off the condition queue: */
|
||||
DosPostEventSem(cond->semaphore);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
int i;
|
||||
APIRET rc;
|
||||
|
||||
/*
|
||||
* Enter a loop to bring all threads off the
|
||||
* condition queue:
|
||||
*/
|
||||
i = cond->waiting;
|
||||
while (i--) rc = DosPostEventSem(cond->semaphore);
|
||||
|
||||
return 0 ;
|
||||
int i;
|
||||
/* Enter a loop to bring all threads off the condition queue */
|
||||
for (i= cond->waiting; i--;)
|
||||
DosPostEventSem(cond->semaphore);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pthread_attr_init(pthread_attr_t *connect_att)
|
||||
{
|
||||
connect_att->dwStackSize = 0;
|
||||
connect_att->dwCreatingFlag = 0;
|
||||
connect_att->priority = 0;
|
||||
connect_att->dwStackSize= 0;
|
||||
connect_att->dwCreatingFlag= 0;
|
||||
connect_att->priority= 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack)
|
||||
int pthread_attr_setstacksize(pthread_attr_t *connect_att, DWORD stack)
|
||||
{
|
||||
connect_att->dwStackSize=stack;
|
||||
connect_att->dwStackSize= stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setprio(pthread_attr_t *connect_att,int priority)
|
||||
int pthread_attr_setprio(pthread_attr_t *connect_att, int priority)
|
||||
{
|
||||
connect_att->priority=priority;
|
||||
connect_att->priority= priority;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_destroy(pthread_attr_t *connect_att)
|
||||
{
|
||||
bzero((gptr) connect_att,sizeof(*connect_att));
|
||||
bzero((gptr) connect_att, sizeof(*connect_att));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -166,22 +141,22 @@ int pthread_attr_destroy(pthread_attr_t *connect_att)
|
|||
** Fix localtime_r() to be a bit safer
|
||||
****************************************************************************/
|
||||
|
||||
struct tm *localtime_r(const time_t *timep,struct tm *tmp)
|
||||
struct tm *localtime_r(const time_t *timep, struct tm *tmp)
|
||||
{
|
||||
if (*timep == (time_t) -1) /* This will crash win32 */
|
||||
if (*timep == (time_t) - 1) /* This will crash win32 */
|
||||
{
|
||||
bzero(tmp,sizeof(*tmp));
|
||||
bzero(tmp, sizeof(*tmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct tm *res=localtime(timep);
|
||||
if (!res) /* Wrong date */
|
||||
struct tm *res= localtime(timep);
|
||||
if (!res) /* Wrong date */
|
||||
{
|
||||
bzero(tmp,sizeof(*tmp)); /* Keep things safe */
|
||||
bzero(tmp, sizeof(*tmp)); /* Keep things safe */
|
||||
return 0;
|
||||
}
|
||||
*tmp= *res;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
#endif /* __WIN__ */
|
||||
#endif /* __WIN__ */
|
||||
|
|
|
@ -408,9 +408,10 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
|
|||
set_timespec(wait_timeout, table_lock_wait_timeout);
|
||||
while (!thread_var->abort || in_wait_list)
|
||||
{
|
||||
int rc= can_deadlock ? pthread_cond_timedwait(cond, &data->lock->mutex,
|
||||
&wait_timeout) :
|
||||
pthread_cond_wait(cond, &data->lock->mutex);
|
||||
int rc= (can_deadlock ?
|
||||
pthread_cond_timedwait(cond, &data->lock->mutex,
|
||||
&wait_timeout) :
|
||||
pthread_cond_wait(cond, &data->lock->mutex));
|
||||
/*
|
||||
We must break the wait if one of the following occurs:
|
||||
- the connection has been aborted (!thread_var->abort), but
|
||||
|
@ -426,7 +427,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
|
|||
*/
|
||||
if (data->cond == 0)
|
||||
break;
|
||||
if (rc == ETIMEDOUT)
|
||||
if (rc == ETIMEDOUT || rc == ETIME)
|
||||
{
|
||||
result= THR_LOCK_WAIT_TIMEOUT;
|
||||
break;
|
||||
|
|
|
@ -239,7 +239,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
|
|||
pthread_mutex_unlock(&mp->global);
|
||||
error=pthread_cond_timedwait(cond,&mp->mutex,abstime);
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (error && (error != EINTR && error != ETIMEDOUT))
|
||||
if (error && (error != EINTR && error != ETIMEDOUT && error != ETIME))
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Got error: %d (%d) when doing a safe_mutex_timedwait at %s, line %d\n", error, errno, file, line);
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ cd $SOURCE
|
|||
for i in COPYING ChangeLog README EXCEPTIONS-CLIENT\
|
||||
INSTALL-SOURCE INSTALL-WIN \
|
||||
INSTALL-WIN-SOURCE \
|
||||
Docs/INSTALL-BINARY
|
||||
Docs/INSTALL-BINARY Docs/manual.chm
|
||||
do
|
||||
print_debug "Copying file '$i'"
|
||||
if [ -f $i ]
|
||||
|
|
|
@ -469,7 +469,7 @@ int Instance::stop()
|
|||
status= pthread_cond_timedwait(&COND_instance_stopped,
|
||||
&LOCK_instance,
|
||||
&timeout);
|
||||
if (status == ETIMEDOUT)
|
||||
if (status == ETIMEDOUT || status == ETIME)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond,
|
|||
pthread_mutex_t *mutex,
|
||||
struct timespec *wait_time)
|
||||
{
|
||||
int rc;
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
if (shutdown_in_progress)
|
||||
{
|
||||
|
@ -154,7 +155,8 @@ int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond,
|
|||
info->current_cond= cond;
|
||||
pthread_mutex_unlock(&LOCK_thread_registry);
|
||||
/* sic: race condition here, cond can be signaled in deliver_shutdown */
|
||||
int rc= pthread_cond_timedwait(cond, mutex, wait_time);
|
||||
if ((rc= pthread_cond_timedwait(cond, mutex, wait_time)) == ETIME)
|
||||
rc= ETIMEDOUT; // For easier usage
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
info->current_cond= 0;
|
||||
pthread_mutex_unlock(&LOCK_thread_registry);
|
||||
|
@ -172,6 +174,7 @@ void Thread_registry::deliver_shutdown()
|
|||
{
|
||||
Thread_info *info;
|
||||
struct timespec shutdown_time;
|
||||
int error;
|
||||
set_timespec(shutdown_time, 1);
|
||||
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
|
@ -204,11 +207,13 @@ void Thread_registry::deliver_shutdown()
|
|||
released - the only case when the predicate is false is when no other
|
||||
threads exist.
|
||||
*/
|
||||
while (pthread_cond_timedwait(&COND_thread_registry_is_empty,
|
||||
&LOCK_thread_registry,
|
||||
&shutdown_time) != ETIMEDOUT &&
|
||||
while (((error= pthread_cond_timedwait(&COND_thread_registry_is_empty,
|
||||
&LOCK_thread_registry,
|
||||
&shutdown_time)) != ETIMEDOUT &&
|
||||
error != ETIME) &&
|
||||
head.next != &head)
|
||||
;
|
||||
|
||||
/*
|
||||
If previous signals did not reach some threads, they must be sleeping
|
||||
in pthread_cond_wait or in a blocking syscall. Wake them up:
|
||||
|
|
|
@ -480,6 +480,7 @@ static int check_foreign_data_source(
|
|||
String query(query_buffer, sizeof(query_buffer), &my_charset_bin);
|
||||
MYSQL *mysql;
|
||||
DBUG_ENTER("ha_federated::check_foreign_data_source");
|
||||
|
||||
/* Zero the length, otherwise the string will have misc chars */
|
||||
query.length(0);
|
||||
|
||||
|
@ -564,6 +565,7 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num)
|
|||
char buf[FEDERATED_QUERY_BUFFER_SIZE];
|
||||
int buf_len;
|
||||
DBUG_ENTER("ha_federated parse_url_error");
|
||||
|
||||
if (share->scheme)
|
||||
{
|
||||
DBUG_PRINT("info",
|
||||
|
@ -572,11 +574,9 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num)
|
|||
my_free((gptr) share->scheme, MYF(0));
|
||||
share->scheme= 0;
|
||||
}
|
||||
buf_len= (table->s->connect_string.length > (FEDERATED_QUERY_BUFFER_SIZE - 1))
|
||||
? FEDERATED_QUERY_BUFFER_SIZE - 1 : table->s->connect_string.length;
|
||||
|
||||
strnmov(buf, table->s->connect_string.str, buf_len);
|
||||
buf[buf_len]= '\0';
|
||||
buf_len= min(table->s->connect_string.length,
|
||||
FEDERATED_QUERY_BUFFER_SIZE-1);
|
||||
strmake(buf, table->s->connect_string.str, buf_len);
|
||||
my_error(error_num, MYF(0), buf);
|
||||
DBUG_RETURN(error_num);
|
||||
}
|
||||
|
@ -767,12 +767,9 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row)
|
|||
{
|
||||
ulong *lengths;
|
||||
Field **field;
|
||||
|
||||
DBUG_ENTER("ha_federated::convert_row_to_internal_format");
|
||||
|
||||
// num_fields= mysql_num_fields(stored_result);
|
||||
lengths= mysql_fetch_lengths(stored_result);
|
||||
|
||||
memset(record, 0, table->s->null_bytes);
|
||||
|
||||
for (field= table->field; *field; field++)
|
||||
|
@ -824,13 +821,8 @@ static bool emit_key_part_element(String *to, KEY_PART_INFO *part,
|
|||
|
||||
*buf++= '0';
|
||||
*buf++= 'x';
|
||||
for (; len; ptr++,len--)
|
||||
{
|
||||
uint tmp= (uint)(uchar) *ptr;
|
||||
*buf++= _dig_vec_upper[tmp >> 4];
|
||||
*buf++= _dig_vec_upper[tmp & 15];
|
||||
}
|
||||
if (to->append(buff, (uint)(buf - buff)))
|
||||
buf= octet2hex(buf, (char*) ptr, len);
|
||||
if (to->append((char*) buff, (uint)(buf - buff)))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
else if (part->key_part_flag & HA_BLOB_PART)
|
||||
|
@ -1127,8 +1119,8 @@ bool ha_federated::create_where_from_key(String *to,
|
|||
char tmpbuff[FEDERATED_QUERY_BUFFER_SIZE];
|
||||
String tmp(tmpbuff, sizeof(tmpbuff), system_charset_info);
|
||||
const key_range *ranges[2]= { start_key, end_key };
|
||||
|
||||
DBUG_ENTER("ha_federated::create_where_from_key");
|
||||
|
||||
tmp.length(0);
|
||||
if (start_key == NULL && end_key == NULL)
|
||||
DBUG_RETURN(1);
|
||||
|
@ -1334,7 +1326,6 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
|
|||
query.append(FEDERATED_FROM);
|
||||
query.append(FEDERATED_BTICK);
|
||||
|
||||
|
||||
if (!(share= (FEDERATED_SHARE *)
|
||||
my_multi_malloc(MYF(MY_WME),
|
||||
&share, sizeof(*share),
|
||||
|
@ -1389,8 +1380,8 @@ error:
|
|||
static int free_share(FEDERATED_SHARE *share)
|
||||
{
|
||||
DBUG_ENTER("free_share");
|
||||
pthread_mutex_lock(&federated_mutex);
|
||||
|
||||
pthread_mutex_lock(&federated_mutex);
|
||||
if (!--share->use_count)
|
||||
{
|
||||
hash_delete(&federated_open_tables, (byte*) share);
|
||||
|
@ -1581,7 +1572,6 @@ int ha_federated::write_row(byte *buf)
|
|||
values_string.length(0);
|
||||
insert_string.length(0);
|
||||
insert_field_value_string.length(0);
|
||||
|
||||
DBUG_ENTER("ha_federated::write_row");
|
||||
DBUG_PRINT("info",
|
||||
("table charset name %s csname %s",
|
||||
|
@ -1708,7 +1698,6 @@ int ha_federated::optimize(THD* thd, HA_CHECK_OPT* check_opt)
|
|||
{
|
||||
char query_buffer[STRING_BUFFER_USUAL_SIZE];
|
||||
String query(query_buffer, sizeof(query_buffer), &my_charset_bin);
|
||||
|
||||
DBUG_ENTER("ha_federated::optimize");
|
||||
|
||||
query.length(0);
|
||||
|
@ -1732,7 +1721,6 @@ int ha_federated::repair(THD* thd, HA_CHECK_OPT* check_opt)
|
|||
{
|
||||
char query_buffer[STRING_BUFFER_USUAL_SIZE];
|
||||
String query(query_buffer, sizeof(query_buffer), &my_charset_bin);
|
||||
|
||||
DBUG_ENTER("ha_federated::repair");
|
||||
|
||||
query.length(0);
|
||||
|
@ -1778,14 +1766,16 @@ int ha_federated::repair(THD* thd, HA_CHECK_OPT* check_opt)
|
|||
int ha_federated::update_row(const byte *old_data, byte *new_data)
|
||||
{
|
||||
/*
|
||||
This used to control how the query was built. If there was a primary key,
|
||||
the query would be built such that there was a where clause with only
|
||||
that column as the condition. This is flawed, because if we have a multi-part
|
||||
primary key, it would only use the first part! We don't need to do this anyway,
|
||||
because read_range_first will retrieve the correct record, which is what is used
|
||||
to build the WHERE clause. We can however use this to append a LIMIT to the end
|
||||
if there is NOT a primary key. Why do this? Because we only are updating one
|
||||
record, and LIMIT enforces this.
|
||||
This used to control how the query was built. If there was a
|
||||
primary key, the query would be built such that there was a where
|
||||
clause with only that column as the condition. This is flawed,
|
||||
because if we have a multi-part primary key, it would only use the
|
||||
first part! We don't need to do this anyway, because
|
||||
read_range_first will retrieve the correct record, which is what
|
||||
is used to build the WHERE clause. We can however use this to
|
||||
append a LIMIT to the end if there is NOT a primary key. Why do
|
||||
this? Because we only are updating one record, and LIMIT enforces
|
||||
this.
|
||||
*/
|
||||
bool has_a_primary_key= (table->s->primary_key == 0 ? TRUE : FALSE);
|
||||
/*
|
||||
|
@ -1812,7 +1802,6 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
|
|||
String where_string(where_buffer,
|
||||
sizeof(where_buffer),
|
||||
&my_charset_bin);
|
||||
|
||||
DBUG_ENTER("ha_federated::update_row");
|
||||
/*
|
||||
set string lengths to 0 to avoid misc chars in string
|
||||
|
@ -2007,12 +1996,10 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
|
|||
sizeof(sql_query_buffer),
|
||||
&my_charset_bin);
|
||||
key_range range;
|
||||
DBUG_ENTER("ha_federated::index_read_idx");
|
||||
|
||||
index_string.length(0);
|
||||
sql_query.length(0);
|
||||
|
||||
DBUG_ENTER("ha_federated::index_read_idx");
|
||||
|
||||
statistic_increment(table->in_use->status_var.ha_read_key_count,
|
||||
&LOCK_status);
|
||||
|
||||
|
@ -2101,8 +2088,8 @@ int ha_federated::read_range_first(const key_range *start_key,
|
|||
String sql_query(sql_query_buffer,
|
||||
sizeof(sql_query_buffer),
|
||||
&my_charset_bin);
|
||||
|
||||
DBUG_ENTER("ha_federated::read_range_first");
|
||||
|
||||
if (start_key == NULL && end_key == NULL)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
|
@ -2417,7 +2404,6 @@ void ha_federated::info(uint flag)
|
|||
MYSQL_RES *result= 0;
|
||||
MYSQL_ROW row;
|
||||
String status_query_string(status_buf, sizeof(status_buf), &my_charset_bin);
|
||||
|
||||
DBUG_ENTER("ha_federated::info");
|
||||
|
||||
error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE;
|
||||
|
@ -2508,10 +2494,10 @@ error:
|
|||
|
||||
int ha_federated::delete_all_rows()
|
||||
{
|
||||
DBUG_ENTER("ha_federated::delete_all_rows");
|
||||
|
||||
char query_buffer[FEDERATED_QUERY_BUFFER_SIZE];
|
||||
String query(query_buffer, sizeof(query_buffer), &my_charset_bin);
|
||||
DBUG_ENTER("ha_federated::delete_all_rows");
|
||||
|
||||
query.length(0);
|
||||
|
||||
query.set_charset(system_charset_info);
|
||||
|
@ -2606,32 +2592,14 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd,
|
|||
int ha_federated::create(const char *name, TABLE *table_arg,
|
||||
HA_CREATE_INFO *create_info)
|
||||
{
|
||||
int retval= 0;
|
||||
/*
|
||||
only a temporary share, to test the url
|
||||
*/
|
||||
FEDERATED_SHARE tmp_share;
|
||||
int retval;
|
||||
FEDERATED_SHARE tmp_share; // Only a temporary share, to test the url
|
||||
DBUG_ENTER("ha_federated::create");
|
||||
|
||||
if ((retval= parse_url(&tmp_share, table_arg, 1)))
|
||||
goto error;
|
||||
if (!(retval= parse_url(&tmp_share, table_arg, 1)))
|
||||
retval= check_foreign_data_source(&tmp_share, 1);
|
||||
|
||||
if ((retval= check_foreign_data_source(&tmp_share, 1)))
|
||||
goto error;
|
||||
|
||||
if (tmp_share.scheme)
|
||||
{
|
||||
my_free((gptr) tmp_share.scheme, MYF(0));
|
||||
tmp_share.scheme= 0;
|
||||
}
|
||||
DBUG_RETURN(retval);
|
||||
|
||||
error:
|
||||
if (tmp_share.scheme)
|
||||
{
|
||||
my_free((gptr) tmp_share.scheme, MYF(0));
|
||||
tmp_share.scheme= 0;
|
||||
}
|
||||
my_free((gptr) tmp_share.scheme, MYF(MY_ALLOW_ZERO_PTR));
|
||||
DBUG_RETURN(retval);
|
||||
|
||||
}
|
||||
|
|
|
@ -7042,8 +7042,7 @@ ha_innobase::cmp_ref(
|
|||
(const char*)ref1, len1,
|
||||
(const char*)ref2, len2);
|
||||
} else {
|
||||
result = field->key_cmp((const char*)ref1,
|
||||
(const char*)ref2);
|
||||
result = field->key_cmp(ref1, ref2);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
|
|
|
@ -5930,7 +5930,6 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
|
|||
{
|
||||
THD *thd; /* needs to be first for thread_stack */
|
||||
Ndb* ndb;
|
||||
int error= 0;
|
||||
struct timespec abstime;
|
||||
|
||||
my_thread_init();
|
||||
|
@ -5959,9 +5958,9 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
|
|||
{
|
||||
|
||||
pthread_mutex_lock(&LOCK_ndb_util_thread);
|
||||
error= pthread_cond_timedwait(&COND_ndb_util_thread,
|
||||
&LOCK_ndb_util_thread,
|
||||
&abstime);
|
||||
pthread_cond_timedwait(&COND_ndb_util_thread,
|
||||
&LOCK_ndb_util_thread,
|
||||
&abstime);
|
||||
pthread_mutex_unlock(&LOCK_ndb_util_thread);
|
||||
|
||||
DBUG_PRINT("ndb_util_thread", ("Started, ndb_cache_check_time: %d",
|
||||
|
|
|
@ -215,6 +215,8 @@ retest:
|
|||
|
||||
return DB_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
const char *ha_get_storage_engine(enum db_type db_type)
|
||||
{
|
||||
handlerton **types;
|
||||
|
@ -223,25 +225,19 @@ const char *ha_get_storage_engine(enum db_type db_type)
|
|||
if (db_type == (*types)->db_type)
|
||||
return (*types)->name;
|
||||
}
|
||||
|
||||
return "none";
|
||||
return "*NONE*";
|
||||
}
|
||||
|
||||
|
||||
bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag)
|
||||
{
|
||||
handlerton **types;
|
||||
for (types= sys_table_types; *types; types++)
|
||||
{
|
||||
if (db_type == (*types)->db_type)
|
||||
{
|
||||
if ((*types)->flags & flag)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
return test((*types)->flags & flag);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return FALSE; // No matching engine
|
||||
}
|
||||
|
||||
|
||||
|
@ -856,18 +852,25 @@ int ha_autocommit_or_rollback(THD *thd, int error)
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
|
||||
{
|
||||
handlerton **types;
|
||||
int res= 1;
|
||||
|
||||
for (types= sys_table_types; *types; types++)
|
||||
{
|
||||
if ((*types)->state == SHOW_OPTION_YES && (*types)->recover)
|
||||
res= res &&
|
||||
(*(commit ? (*types)->commit_by_xid : (*types)->rollback_by_xid))(xid);
|
||||
{
|
||||
if ((*(commit ? (*types)->commit_by_xid :
|
||||
(*types)->rollback_by_xid))(xid));
|
||||
res= 0;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
/* this does not need to be multi-byte safe or anything */
|
||||
static char* xid_to_str(char *buf, XID *xid)
|
||||
|
|
46
sql/item.cc
46
sql/item.cc
|
@ -817,9 +817,12 @@ String *Item_splocal::val_str(String *sp)
|
|||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
Item *it= this_item();
|
||||
String *ret= it->val_str(sp);
|
||||
String *res= it->val_str(sp);
|
||||
|
||||
null_value= it->null_value;
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
This way we mark returned value of val_str as const,
|
||||
so that various functions (e.g. CONCAT) won't try to
|
||||
|
@ -836,12 +839,11 @@ String *Item_splocal::val_str(String *sp)
|
|||
Item_param class contain some more details on the topic.
|
||||
*/
|
||||
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
str_value_ptr.set(ret->ptr(), ret->length(),
|
||||
ret->charset());
|
||||
return &str_value_ptr;
|
||||
if (res != &str_value)
|
||||
str_value.set(res->ptr(), res->length(), res->charset());
|
||||
else
|
||||
res->mark_as_const();
|
||||
return &str_value;
|
||||
}
|
||||
|
||||
|
||||
|
@ -858,17 +860,13 @@ my_decimal *Item_splocal::val_decimal(my_decimal *decimal_value)
|
|||
bool Item_splocal::is_null()
|
||||
{
|
||||
Item *it= this_item();
|
||||
bool ret= it->is_null();
|
||||
null_value= it->null_value;
|
||||
return ret;
|
||||
return it->is_null();
|
||||
}
|
||||
|
||||
|
||||
Item *
|
||||
Item_splocal::this_item()
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
|
||||
return thd->spcont->get_item(m_offset);
|
||||
}
|
||||
|
||||
|
@ -882,25 +880,23 @@ Item_splocal::this_item_addr(THD *thd, Item **addr)
|
|||
Item *
|
||||
Item_splocal::this_const_item() const
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
|
||||
return thd->spcont->get_item(m_offset);
|
||||
}
|
||||
|
||||
Item::Type
|
||||
Item_splocal::type() const
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
|
||||
if (thd->spcont)
|
||||
if (thd && thd->spcont)
|
||||
return thd->spcont->get_item(m_offset)->type();
|
||||
return NULL_ITEM; // Anything but SUBSELECT_ITEM
|
||||
}
|
||||
|
||||
|
||||
bool Item_splocal::fix_fields(THD *, Item **)
|
||||
bool Item_splocal::fix_fields(THD *thd_arg, Item **ref)
|
||||
{
|
||||
Item *it= this_item();
|
||||
Item *it;
|
||||
thd= thd_arg; // Must be set before this_item()
|
||||
it= this_item();
|
||||
DBUG_ASSERT(it->fixed);
|
||||
max_length= it->max_length;
|
||||
decimals= it->decimals;
|
||||
|
@ -928,6 +924,7 @@ void Item_splocal::print(String *str)
|
|||
/*****************************************************************************
|
||||
Item_name_const methods
|
||||
*****************************************************************************/
|
||||
|
||||
double Item_name_const::val_real()
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
|
@ -966,9 +963,7 @@ my_decimal *Item_name_const::val_decimal(my_decimal *decimal_value)
|
|||
|
||||
bool Item_name_const::is_null()
|
||||
{
|
||||
bool ret= value_item->is_null();
|
||||
null_value= value_item->null_value;
|
||||
return ret;
|
||||
return value_item->is_null();
|
||||
}
|
||||
|
||||
Item::Type Item_name_const::type() const
|
||||
|
@ -977,7 +972,7 @@ Item::Type Item_name_const::type() const
|
|||
}
|
||||
|
||||
|
||||
bool Item_name_const::fix_fields(THD *thd, Item **)
|
||||
bool Item_name_const::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
char buf[128];
|
||||
String *item_name;
|
||||
|
@ -2783,7 +2778,7 @@ int Item_copy_string::save_in_field(Field *field, bool no_conversions)
|
|||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
bool Item::fix_fields(THD *thd, Item ** ref)
|
||||
bool Item::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
|
||||
// We do not check fields which are fixed during construction
|
||||
|
@ -4765,8 +4760,7 @@ String *Item_ref::val_str(String* tmp)
|
|||
bool Item_ref::is_null()
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
(void) (*ref)->val_int_result();
|
||||
return (*ref)->null_value;
|
||||
return (*ref)->is_null();
|
||||
}
|
||||
|
||||
|
||||
|
|
16
sql/item.h
16
sql/item.h
|
@ -721,13 +721,7 @@ class Item_splocal : public Item
|
|||
|
||||
public:
|
||||
LEX_STRING m_name;
|
||||
|
||||
/*
|
||||
Buffer, pointing to the string value of the item. We need it to
|
||||
protect internal buffer from changes. See comment to analogous
|
||||
member in Item_param for more details.
|
||||
*/
|
||||
String str_value_ptr;
|
||||
THD *thd;
|
||||
|
||||
/*
|
||||
Position of this reference to SP variable in the statement (the
|
||||
|
@ -739,10 +733,10 @@ public:
|
|||
Value of 0 means that this object doesn't corresponding to reference to
|
||||
SP variable in query text.
|
||||
*/
|
||||
int pos_in_query;
|
||||
uint pos_in_query;
|
||||
|
||||
Item_splocal(LEX_STRING name, uint offset, int pos_in_q=0)
|
||||
: m_offset(offset), m_name(name), pos_in_query(pos_in_q)
|
||||
Item_splocal(LEX_STRING name, uint offset, uint pos_in_q=0)
|
||||
: m_offset(offset), m_name(name), thd(0), pos_in_query(pos_in_q)
|
||||
{
|
||||
maybe_null= TRUE;
|
||||
}
|
||||
|
@ -1622,7 +1616,7 @@ public:
|
|||
}
|
||||
Item *real_item()
|
||||
{
|
||||
return (ref && *ref) ? (*ref)->real_item() : this;
|
||||
return ref ? (*ref)->real_item() : this;
|
||||
}
|
||||
bool walk(Item_processor processor, byte *arg)
|
||||
{ return (*ref)->walk(processor, arg); }
|
||||
|
|
128
sql/item_func.cc
128
sql/item_func.cc
|
@ -32,6 +32,11 @@
|
|||
#include "sp_rcontext.h"
|
||||
#include "sp.h"
|
||||
|
||||
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
||||
#define sp_restore_security_context(A,B) while (0) {}
|
||||
#endif
|
||||
|
||||
|
||||
bool check_reserved_words(LEX_STRING *name)
|
||||
{
|
||||
if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") ||
|
||||
|
@ -2015,7 +2020,6 @@ String *Item_func_min_max::val_str(String *str)
|
|||
{
|
||||
String *res;
|
||||
LINT_INIT(res);
|
||||
null_value= 0;
|
||||
for (uint i=0; i < arg_count ; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
|
@ -2030,14 +2034,11 @@ String *Item_func_min_max::val_str(String *str)
|
|||
if ((cmp_sign < 0 ? cmp : -cmp) < 0)
|
||||
res=res2;
|
||||
}
|
||||
else
|
||||
res= 0;
|
||||
}
|
||||
if ((null_value= args[i]->null_value))
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
if (res) // If !NULL
|
||||
res->set_charset(collation.collation);
|
||||
res->set_charset(collation.collation);
|
||||
return res;
|
||||
}
|
||||
case ROW_RESULT:
|
||||
|
@ -2054,7 +2055,6 @@ double Item_func_min_max::val_real()
|
|||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
double value=0.0;
|
||||
null_value= 0;
|
||||
for (uint i=0; i < arg_count ; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
|
@ -2076,7 +2076,6 @@ longlong Item_func_min_max::val_int()
|
|||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
longlong value=0;
|
||||
null_value= 0;
|
||||
for (uint i=0; i < arg_count ; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
|
@ -2097,21 +2096,21 @@ longlong Item_func_min_max::val_int()
|
|||
my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
my_decimal tmp_buf, *tmp, *res= NULL;
|
||||
null_value= 0;
|
||||
my_decimal tmp_buf, *tmp, *res;
|
||||
LINT_INIT(res);
|
||||
|
||||
for (uint i=0; i < arg_count ; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
res= args[i]->val_decimal(dec);
|
||||
else
|
||||
{
|
||||
tmp= args[i]->val_decimal(&tmp_buf);
|
||||
if (args[i]->null_value)
|
||||
res= 0;
|
||||
else if ((my_decimal_cmp(tmp, res) * cmp_sign) < 0)
|
||||
tmp= args[i]->val_decimal(&tmp_buf); // Zero if NULL
|
||||
if (tmp && (my_decimal_cmp(tmp, res) * cmp_sign) < 0)
|
||||
{
|
||||
if (tmp == &tmp_buf)
|
||||
{
|
||||
/* Move value out of tmp_buf as this will be reused on next loop */
|
||||
my_decimal2decimal(tmp, dec);
|
||||
res= dec;
|
||||
}
|
||||
|
@ -2120,7 +2119,10 @@ my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
|
|||
}
|
||||
}
|
||||
if ((null_value= args[i]->null_value))
|
||||
{
|
||||
res= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -3031,9 +3033,13 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
|
|||
thd->mysys_var->current_cond= &ull->cond;
|
||||
|
||||
set_timespec(abstime,lock_timeout);
|
||||
while (!thd->killed &&
|
||||
pthread_cond_timedwait(&ull->cond, &LOCK_user_locks,
|
||||
&abstime) != ETIMEDOUT && ull->locked) ;
|
||||
while (ull->locked && !thd->killed)
|
||||
{
|
||||
int error= pthread_cond_timedwait(&ull->cond, &LOCK_user_locks, &abstime);
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ull->locked)
|
||||
{
|
||||
if (!--ull->count)
|
||||
|
@ -3077,7 +3083,7 @@ longlong Item_func_get_lock::val_int()
|
|||
struct timespec abstime;
|
||||
THD *thd=current_thd;
|
||||
User_level_lock *ull;
|
||||
int error=0;
|
||||
int error;
|
||||
|
||||
/*
|
||||
In slave thread no need to get locks, everything is serialized. Anyway
|
||||
|
@ -3133,22 +3139,29 @@ longlong Item_func_get_lock::val_int()
|
|||
thd->mysys_var->current_cond= &ull->cond;
|
||||
|
||||
set_timespec(abstime,timeout);
|
||||
while (!thd->killed &&
|
||||
(error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
|
||||
!= ETIMEDOUT && error != EINVAL && ull->locked) ;
|
||||
if (thd->killed)
|
||||
error=EINTR; // Return NULL
|
||||
error= 0;
|
||||
while (ull->locked && !thd->killed)
|
||||
{
|
||||
error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime);
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
break;
|
||||
error= 0;
|
||||
}
|
||||
|
||||
if (ull->locked)
|
||||
{
|
||||
if (!--ull->count)
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
delete ull; // Should never happen
|
||||
if (error != ETIMEDOUT)
|
||||
}
|
||||
if (!error) // Killed (thd->killed != 0)
|
||||
{
|
||||
error=1;
|
||||
null_value=1; // Return NULL
|
||||
}
|
||||
}
|
||||
else
|
||||
else // We got the lock
|
||||
{
|
||||
ull->locked=1;
|
||||
ull->thread=thd->real_id;
|
||||
|
@ -3270,6 +3283,7 @@ void Item_func_benchmark::print(String *str)
|
|||
str->append(')');
|
||||
}
|
||||
|
||||
|
||||
/* This function is just used to create tests with time gaps */
|
||||
|
||||
longlong Item_func_sleep::val_int()
|
||||
|
@ -3290,10 +3304,14 @@ longlong Item_func_sleep::val_int()
|
|||
thd->mysys_var->current_mutex= &LOCK_user_locks;
|
||||
thd->mysys_var->current_cond= &cond;
|
||||
|
||||
while (!thd->killed &&
|
||||
(error= pthread_cond_timedwait(&cond, &LOCK_user_locks,
|
||||
&abstime)) != ETIMEDOUT &&
|
||||
error != EINVAL) ;
|
||||
error= 0;
|
||||
while (!thd->killed)
|
||||
{
|
||||
error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime);
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
break;
|
||||
error= 0;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&thd->mysys_var->mutex);
|
||||
thd->mysys_var->current_mutex= 0;
|
||||
|
@ -3303,7 +3321,7 @@ longlong Item_func_sleep::val_int()
|
|||
pthread_mutex_unlock(&LOCK_user_locks);
|
||||
pthread_cond_destroy(&cond);
|
||||
|
||||
return (error == ETIMEDOUT) ? 0 : 1;
|
||||
return test(!error); // Return 1 killed
|
||||
}
|
||||
|
||||
|
||||
|
@ -4732,10 +4750,7 @@ Item_func_sp::execute(Item **itp)
|
|||
ER_FAILED_ROUTINE_BREAK_BINLOG,
|
||||
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
#endif
|
||||
|
||||
error:
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
@ -4849,11 +4864,12 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
|
|||
find_and_check_access()
|
||||
thd thread handler
|
||||
want_access requested access
|
||||
backup backup of security context or 0
|
||||
save backup of security context
|
||||
|
||||
RETURN
|
||||
FALSE Access granted
|
||||
TRUE Requested access can't be granted or function doesn't exists
|
||||
In this case security context is not changed and *save = 0
|
||||
|
||||
NOTES
|
||||
Checks if requested access to function can be granted to user.
|
||||
|
@ -4868,12 +4884,11 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
|
|||
|
||||
bool
|
||||
Item_func_sp::find_and_check_access(THD *thd, ulong want_access,
|
||||
Security_context **backup)
|
||||
Security_context **save)
|
||||
{
|
||||
bool res;
|
||||
Security_context *local_save,
|
||||
**save= (backup ? backup : &local_save);
|
||||
res= TRUE;
|
||||
bool res= TRUE;
|
||||
|
||||
*save= 0; // Safety if error
|
||||
if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE)))
|
||||
{
|
||||
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
|
||||
|
@ -4883,26 +4898,31 @@ Item_func_sp::find_and_check_access(THD *thd, ulong want_access,
|
|||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_routine_access(thd, want_access,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
sp_change_security_context(thd, m_sp, save);
|
||||
/*
|
||||
If we changed context to run as another user, we need to check the
|
||||
access right for the new context again as someone may have deleted
|
||||
this person the right to use the procedure
|
||||
|
||||
TODO:
|
||||
Cache if the definer has the right to use the object on the first
|
||||
usage and only reset the cache if someone does a GRANT statement
|
||||
that 'may' affect this.
|
||||
*/
|
||||
if (*save &&
|
||||
check_routine_access(thd, want_access,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
|
||||
{
|
||||
goto error_check_ctx;
|
||||
sp_restore_security_context(thd, *save);
|
||||
*save= 0; // Safety
|
||||
goto error;
|
||||
}
|
||||
res= FALSE;
|
||||
error_check_ctx:
|
||||
if (*save && (res || !backup))
|
||||
sp_restore_security_context(thd, local_save);
|
||||
error:
|
||||
#else
|
||||
res= 0;
|
||||
error:
|
||||
#endif
|
||||
res= FALSE; // no error
|
||||
|
||||
error:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -4912,7 +4932,11 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
|
|||
bool res;
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
res= Item_func::fix_fields(thd, ref);
|
||||
if (!res && find_and_check_access(thd, EXECUTE_ACL, NULL))
|
||||
res= 1;
|
||||
if (!res)
|
||||
{
|
||||
Security_context *save_ctx;
|
||||
if (!(res= find_and_check_access(thd, EXECUTE_ACL, &save_ctx)))
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1964,21 +1964,16 @@ String *Item_func_char::val_str(String *str)
|
|||
int32 num=(int32) args[i]->val_int();
|
||||
if (!args[i]->null_value)
|
||||
{
|
||||
#ifdef USE_MB
|
||||
if (use_mb(collation.collation))
|
||||
{
|
||||
if (num&0xFF000000L) {
|
||||
str->append((char)(num>>24));
|
||||
goto b2;
|
||||
} else if (num&0xFF0000L) {
|
||||
b2: str->append((char)(num>>16));
|
||||
goto b1;
|
||||
} else if (num&0xFF00L) {
|
||||
b1: str->append((char)(num>>8));
|
||||
}
|
||||
if (num&0xFF000000L) {
|
||||
str->append((char)(num>>24));
|
||||
goto b2;
|
||||
} else if (num&0xFF0000L) {
|
||||
b2: str->append((char)(num>>16));
|
||||
goto b1;
|
||||
} else if (num&0xFF00L) {
|
||||
b1: str->append((char)(num>>8));
|
||||
}
|
||||
#endif
|
||||
str->append((char)num);
|
||||
str->append((char) num);
|
||||
}
|
||||
}
|
||||
str->set_charset(collation.collation);
|
||||
|
@ -1997,7 +1992,7 @@ b1: str->append((char)(num>>8));
|
|||
enum MYSQL_ERROR::enum_warning_level level;
|
||||
uint diff= str->length() - wlen;
|
||||
set_if_smaller(diff, 3);
|
||||
octet2hex(hexbuf, (const uchar*) str->ptr() + wlen, diff);
|
||||
octet2hex(hexbuf, str->ptr() + wlen, diff);
|
||||
if (thd->variables.sql_mode &
|
||||
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))
|
||||
{
|
||||
|
@ -2436,6 +2431,7 @@ String *Item_func_collation::val_str(String *str)
|
|||
|
||||
String *Item_func_hex::val_str(String *str)
|
||||
{
|
||||
String *res;
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (args[0]->result_type() != STRING_RESULT)
|
||||
{
|
||||
|
@ -2464,24 +2460,16 @@ String *Item_func_hex::val_str(String *str)
|
|||
}
|
||||
|
||||
/* Convert given string to a hex string, character by character */
|
||||
String *res= args[0]->val_str(str);
|
||||
const char *from, *end;
|
||||
char *to;
|
||||
if (!res || tmp_value.alloc(res->length()*2))
|
||||
res= args[0]->val_str(str);
|
||||
if (!res || tmp_value.alloc(res->length()*2+1))
|
||||
{
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
null_value=0;
|
||||
tmp_value.length(res->length()*2);
|
||||
for (from=res->ptr(), end=from+res->length(), to= (char*) tmp_value.ptr();
|
||||
from < end ;
|
||||
from++, to+=2)
|
||||
{
|
||||
uint tmp=(uint) (uchar) *from;
|
||||
to[0]=_dig_vec_upper[tmp >> 4];
|
||||
to[1]=_dig_vec_upper[tmp & 15];
|
||||
}
|
||||
|
||||
octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length());
|
||||
return &tmp_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -484,7 +484,7 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
collation.set(default_charset());
|
||||
collation.set(&my_charset_bin);
|
||||
maybe_null=0; max_length=arg_count;
|
||||
}
|
||||
const char *func_name() const { return "char"; }
|
||||
|
|
|
@ -121,8 +121,9 @@ static char *pretty_print_str(char *packet, char *str, int len)
|
|||
static inline char* slave_load_file_stem(char*buf, uint file_id,
|
||||
int event_server_id)
|
||||
{
|
||||
fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "",
|
||||
MY_UNPACK_FILENAME | MY_UNIX_PATH);
|
||||
fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
|
||||
to_unix_path(buf);
|
||||
|
||||
buf = strend(buf);
|
||||
buf = int10_to_str(::server_id, buf, 10);
|
||||
*buf++ = '-';
|
||||
|
@ -211,24 +212,18 @@ static inline int read_str(char **buf, char *buf_end, char **str,
|
|||
/*
|
||||
Transforms a string into "" or its expression in 0x... form.
|
||||
*/
|
||||
|
||||
char *str_to_hex(char *to, const char *from, uint len)
|
||||
{
|
||||
char *p= to;
|
||||
if (len)
|
||||
{
|
||||
p= strmov(p, "0x");
|
||||
for (uint i= 0; i < len; i++, p+= 2)
|
||||
{
|
||||
/* val[i] is char. Casting to uchar helps greatly if val[i] < 0 */
|
||||
uint tmp= (uint) (uchar) from[i];
|
||||
p[0]= _dig_vec_upper[tmp >> 4];
|
||||
p[1]= _dig_vec_upper[tmp & 15];
|
||||
}
|
||||
*p= 0;
|
||||
*to++= '0';
|
||||
*to++= 'x';
|
||||
to= octet2hex(to, from, len);
|
||||
}
|
||||
else
|
||||
p= strmov(p, "\"\"");
|
||||
return p; // pointer to end 0 of 'to'
|
||||
to= strmov(to, "\"\"");
|
||||
return to; // pointer to end 0 of 'to'
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -579,6 +579,20 @@ HANDLE smem_event_connect_request= 0;
|
|||
|
||||
#include "sslopt-vars.h"
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/crypto.h>
|
||||
#ifndef HAVE_YASSL
|
||||
typedef struct CRYPTO_dynlock_value
|
||||
{
|
||||
rw_lock_t lock;
|
||||
} openssl_lock_t;
|
||||
|
||||
static openssl_lock_t *openssl_stdlocks;
|
||||
static openssl_lock_t *openssl_dynlock_create(const char *, int);
|
||||
static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int);
|
||||
static void openssl_lock_function(int, int, const char *, int);
|
||||
static void openssl_lock(int, openssl_lock_t *, const char *, int);
|
||||
static unsigned long openssl_id_function();
|
||||
#endif
|
||||
char *des_key_file;
|
||||
struct st_VioSSLAcceptorFd *ssl_acceptor_fd;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
@ -1170,6 +1184,11 @@ static void clean_up_mutexes()
|
|||
(void) pthread_mutex_destroy(&LOCK_user_conn);
|
||||
#ifdef HAVE_OPENSSL
|
||||
(void) pthread_mutex_destroy(&LOCK_des_key_file);
|
||||
#ifndef HAVE_YASSL
|
||||
for (int i= 0; i < CRYPTO_num_locks(); ++i)
|
||||
(void) rwlock_destroy(&openssl_stdlocks[i].lock);
|
||||
OPENSSL_free(openssl_stdlocks);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_REPLICATION
|
||||
(void) pthread_mutex_destroy(&LOCK_rpl_status);
|
||||
|
@ -2726,6 +2745,17 @@ static int init_thread_environment()
|
|||
(void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
|
||||
#ifdef HAVE_OPENSSL
|
||||
(void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
|
||||
#ifndef HAVE_YASSL
|
||||
openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() *
|
||||
sizeof(openssl_lock_t));
|
||||
for (int i= 0; i < CRYPTO_num_locks(); ++i)
|
||||
(void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL);
|
||||
CRYPTO_set_dynlock_create_callback(openssl_dynlock_create);
|
||||
CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy);
|
||||
CRYPTO_set_dynlock_lock_callback(openssl_lock);
|
||||
CRYPTO_set_locking_callback(openssl_lock_function);
|
||||
CRYPTO_set_id_callback(openssl_id_function);
|
||||
#endif
|
||||
#endif
|
||||
(void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
|
||||
(void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
|
||||
|
@ -2758,6 +2788,75 @@ static int init_thread_environment()
|
|||
}
|
||||
|
||||
|
||||
#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
|
||||
static unsigned long openssl_id_function()
|
||||
{
|
||||
return (unsigned long) pthread_self();
|
||||
}
|
||||
|
||||
|
||||
static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
|
||||
{
|
||||
openssl_lock_t *lock= new openssl_lock_t;
|
||||
my_rwlock_init(&lock->lock, NULL);
|
||||
return lock;
|
||||
}
|
||||
|
||||
|
||||
static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
|
||||
int line)
|
||||
{
|
||||
rwlock_destroy(&lock->lock);
|
||||
delete lock;
|
||||
}
|
||||
|
||||
|
||||
static void openssl_lock_function(int mode, int n, const char *file, int line)
|
||||
{
|
||||
if (n < 0 || n > CRYPTO_num_locks())
|
||||
{
|
||||
/* Lock number out of bounds. */
|
||||
sql_print_error("Fatal: OpenSSL interface problem (n = %d)", n);
|
||||
abort();
|
||||
}
|
||||
openssl_lock(mode, &openssl_stdlocks[n], file, line);
|
||||
}
|
||||
|
||||
|
||||
static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
|
||||
int line)
|
||||
{
|
||||
int err;
|
||||
char const *what;
|
||||
|
||||
switch (mode) {
|
||||
case CRYPTO_LOCK|CRYPTO_READ:
|
||||
what = "read lock";
|
||||
err = rw_rdlock(&lock->lock);
|
||||
break;
|
||||
case CRYPTO_LOCK|CRYPTO_WRITE:
|
||||
what = "write lock";
|
||||
err = rw_wrlock(&lock->lock);
|
||||
break;
|
||||
case CRYPTO_UNLOCK|CRYPTO_READ:
|
||||
case CRYPTO_UNLOCK|CRYPTO_WRITE:
|
||||
what = "unlock";
|
||||
err = rw_unlock(&lock->lock);
|
||||
break;
|
||||
default:
|
||||
/* Unknown locking mode. */
|
||||
sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
|
||||
abort();
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
sql_print_error("Fatal: can't %s OpenSSL %s lock", what);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
|
||||
static void init_ssl()
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
|
|
@ -7040,19 +7040,15 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
|
|||
*/
|
||||
if (thd->query_id == cur_field->query_id)
|
||||
{
|
||||
bool is_covered= FALSE;
|
||||
KEY_PART_INFO *key_part= cur_index_info->key_part;
|
||||
KEY_PART_INFO *key_part_end= key_part + cur_index_info->key_parts;
|
||||
for (; key_part != key_part_end ; key_part++)
|
||||
for (;;)
|
||||
{
|
||||
if (key_part->field == cur_field)
|
||||
{
|
||||
is_covered= TRUE;
|
||||
break;
|
||||
}
|
||||
if (++key_part == key_part_end)
|
||||
goto next_index; // Field was not part of key
|
||||
}
|
||||
if (!is_covered)
|
||||
goto next_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -372,8 +372,10 @@ my_bool rename_in_schema_file(const char *schema, const char *old_name,
|
|||
|
||||
if (revision > 0 && !access(arc_path, F_OK))
|
||||
{
|
||||
ulonglong limit= (revision > num_view_backups) ? revision - num_view_backups : 0;
|
||||
while (revision > limit) {
|
||||
ulonglong limit= ((revision > num_view_backups) ?
|
||||
revision - num_view_backups : 0);
|
||||
for (; revision > limit ; revision--)
|
||||
{
|
||||
my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu",
|
||||
arc_path, old_name, reg_ext, (ulong)revision);
|
||||
(void) unpack_filename(old_path, old_path);
|
||||
|
@ -381,7 +383,6 @@ my_bool rename_in_schema_file(const char *schema, const char *old_name,
|
|||
arc_path, new_name, reg_ext, (ulong)revision);
|
||||
(void) unpack_filename(new_path, new_path);
|
||||
my_rename(old_path, new_path, MYF(0));
|
||||
revision--;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -316,18 +316,21 @@ void create_random_string(char *to, uint length, struct rand_struct *rand_st)
|
|||
octet2hex()
|
||||
buf OUT output buffer. Must be at least 2*len+1 bytes
|
||||
str, len IN the beginning and the length of the input string
|
||||
|
||||
RETURN
|
||||
buf+len*2
|
||||
*/
|
||||
|
||||
void
|
||||
octet2hex(char *to, const unsigned char *str, uint len)
|
||||
char *octet2hex(char *to, const char *str, uint len)
|
||||
{
|
||||
const uint8 *str_end= str + len;
|
||||
const byte *str_end= str + len;
|
||||
for (; str != str_end; ++str)
|
||||
{
|
||||
*to++= _dig_vec_upper[(*str & 0xF0) >> 4];
|
||||
*to++= _dig_vec_upper[*str & 0x0F];
|
||||
*to++= _dig_vec_upper[((uchar) *str) >> 4];
|
||||
*to++= _dig_vec_upper[((uchar) *str) & 0x0F];
|
||||
}
|
||||
*to= '\0';
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5420,3 +5420,5 @@ ER_ROW_IS_REFERENCED_2 23000
|
|||
eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)"
|
||||
ER_NO_REFERENCED_ROW_2 23000
|
||||
eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)"
|
||||
ER_SP_BAD_VAR_SHADOW 42000
|
||||
eng "Variable '%-.64s' must be quoted with `...`, or renamed"
|
||||
|
|
|
@ -2747,7 +2747,7 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name,
|
|||
else
|
||||
pthread_cond_wait(&data_cond, &data_lock);
|
||||
DBUG_PRINT("info",("Got signal of master update or timed out"));
|
||||
if (error == ETIMEDOUT)
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
{
|
||||
error= -1;
|
||||
break;
|
||||
|
|
31
sql/sp.cc
31
sql/sp.cc
|
@ -208,7 +208,7 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
|
|||
{
|
||||
byte key[MAX_KEY_LENGTH]; // db, name, optional key length type
|
||||
DBUG_ENTER("db_find_routine_aux");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s",
|
||||
DBUG_PRINT("enter", ("type: %d name: %.*s",
|
||||
type, name->m_name.length, name->m_name.str));
|
||||
|
||||
/*
|
||||
|
@ -275,7 +275,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
|
|||
ulong sql_mode;
|
||||
Open_tables_state open_tables_state_backup;
|
||||
DBUG_ENTER("db_find_routine");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s",
|
||||
DBUG_PRINT("enter", ("type: %d name: %.*s",
|
||||
type, name->m_name.length, name->m_name.str));
|
||||
|
||||
*sphp= 0; // In case of errors
|
||||
|
@ -479,7 +479,8 @@ db_create_routine(THD *thd, int type, sp_head *sp)
|
|||
char olddb[128];
|
||||
bool dbchanged;
|
||||
DBUG_ENTER("db_create_routine");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s",type,sp->m_name.length,sp->m_name.str));
|
||||
DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length,
|
||||
sp->m_name.str));
|
||||
|
||||
dbchanged= FALSE;
|
||||
if ((ret= sp_use_new_db(thd, sp->m_db.str, olddb, sizeof(olddb),
|
||||
|
@ -606,7 +607,7 @@ db_drop_routine(THD *thd, int type, sp_name *name)
|
|||
TABLE *table;
|
||||
int ret;
|
||||
DBUG_ENTER("db_drop_routine");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s",
|
||||
DBUG_PRINT("enter", ("type: %d name: %.*s",
|
||||
type, name->m_name.length, name->m_name.str));
|
||||
|
||||
if (!(table= open_proc_table_for_update(thd)))
|
||||
|
@ -628,7 +629,7 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
|
|||
int ret;
|
||||
bool opened;
|
||||
DBUG_ENTER("db_update_routine");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s",
|
||||
DBUG_PRINT("enter", ("type: %d name: %.*s",
|
||||
type, name->m_name.length, name->m_name.str));
|
||||
|
||||
if (!(table= open_proc_table_for_update(thd)))
|
||||
|
@ -922,7 +923,7 @@ sp_find_procedure(THD *thd, sp_name *name, bool cache_only)
|
|||
{
|
||||
sp_head *sp;
|
||||
DBUG_ENTER("sp_find_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s.%*s",
|
||||
DBUG_PRINT("enter", ("name: %.*s.%.*s",
|
||||
name->m_db.length, name->m_db.str,
|
||||
name->m_name.length, name->m_name.str));
|
||||
|
||||
|
@ -980,7 +981,7 @@ sp_create_procedure(THD *thd, sp_head *sp)
|
|||
{
|
||||
int ret;
|
||||
DBUG_ENTER("sp_create_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str));
|
||||
DBUG_PRINT("enter", ("name: %.*s", sp->m_name.length, sp->m_name.str));
|
||||
|
||||
ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, sp);
|
||||
DBUG_RETURN(ret);
|
||||
|
@ -992,7 +993,7 @@ sp_drop_procedure(THD *thd, sp_name *name)
|
|||
{
|
||||
int ret;
|
||||
DBUG_ENTER("sp_drop_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
|
||||
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
|
||||
|
||||
ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name);
|
||||
if (!ret)
|
||||
|
@ -1006,7 +1007,7 @@ sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics)
|
|||
{
|
||||
int ret;
|
||||
DBUG_ENTER("sp_update_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
|
||||
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
|
||||
|
||||
ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, chistics);
|
||||
if (!ret)
|
||||
|
@ -1020,7 +1021,7 @@ sp_show_create_procedure(THD *thd, sp_name *name)
|
|||
{
|
||||
sp_head *sp;
|
||||
DBUG_ENTER("sp_show_create_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
|
||||
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
|
||||
|
||||
if ((sp= sp_find_procedure(thd, name)))
|
||||
{
|
||||
|
@ -1072,7 +1073,7 @@ sp_find_function(THD *thd, sp_name *name, bool cache_only)
|
|||
{
|
||||
sp_head *sp;
|
||||
DBUG_ENTER("sp_find_function");
|
||||
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
|
||||
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
|
||||
|
||||
if (!(sp= sp_cache_lookup(&thd->sp_func_cache, name)) &&
|
||||
!cache_only)
|
||||
|
@ -1089,7 +1090,7 @@ sp_create_function(THD *thd, sp_head *sp)
|
|||
{
|
||||
int ret;
|
||||
DBUG_ENTER("sp_create_function");
|
||||
DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str));
|
||||
DBUG_PRINT("enter", ("name: %.*s", sp->m_name.length, sp->m_name.str));
|
||||
|
||||
ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, sp);
|
||||
DBUG_RETURN(ret);
|
||||
|
@ -1101,7 +1102,7 @@ sp_drop_function(THD *thd, sp_name *name)
|
|||
{
|
||||
int ret;
|
||||
DBUG_ENTER("sp_drop_function");
|
||||
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
|
||||
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
|
||||
|
||||
ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name);
|
||||
if (!ret)
|
||||
|
@ -1115,7 +1116,7 @@ sp_update_function(THD *thd, sp_name *name, st_sp_chistics *chistics)
|
|||
{
|
||||
int ret;
|
||||
DBUG_ENTER("sp_update_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
|
||||
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
|
||||
|
||||
ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, chistics);
|
||||
if (!ret)
|
||||
|
@ -1129,7 +1130,7 @@ sp_show_create_function(THD *thd, sp_name *name)
|
|||
{
|
||||
sp_head *sp;
|
||||
DBUG_ENTER("sp_show_create_function");
|
||||
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
|
||||
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
|
||||
|
||||
if ((sp= sp_find_function(thd, name)))
|
||||
{
|
||||
|
|
|
@ -132,7 +132,7 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp)
|
|||
return; // End of memory error
|
||||
c->version= Cversion; // No need to lock when reading long variable
|
||||
}
|
||||
DBUG_PRINT("info",("sp_cache: inserting: %*s", sp->m_qname.length,
|
||||
DBUG_PRINT("info",("sp_cache: inserting: %.*s", sp->m_qname.length,
|
||||
sp->m_qname.str));
|
||||
c->insert(sp);
|
||||
*cp= c; // Update *cp if it was NULL
|
||||
|
|
|
@ -280,7 +280,7 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
|
|||
DBUG_PRINT("info", ("STRING_RESULT: null"));
|
||||
goto return_null_item;
|
||||
}
|
||||
DBUG_PRINT("info",("STRING_RESULT: %*s",
|
||||
DBUG_PRINT("info",("STRING_RESULT: %.*s",
|
||||
s->length(), s->c_ptr_quick()));
|
||||
/*
|
||||
Reuse mechanism in sp_eval_func_item() is only employed for assignments
|
||||
|
@ -354,7 +354,7 @@ sp_name::init_qname(THD *thd)
|
|||
return;
|
||||
m_qname.length= m_sroutines_key.length - 1;
|
||||
m_qname.str= m_sroutines_key.str + 1;
|
||||
sprintf(m_qname.str, "%*s.%*s",
|
||||
sprintf(m_qname.str, "%.*s.%.*s",
|
||||
m_db.length, (m_db.length ? m_db.str : ""),
|
||||
m_name.length, m_name.str);
|
||||
}
|
||||
|
@ -794,6 +794,7 @@ static bool subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
|
|||
splocal < sp_vars_uses.back(); splocal++)
|
||||
{
|
||||
Item *val;
|
||||
(*splocal)->thd= thd; // fix_fields() is not yet done
|
||||
/* append the text between sp ref occurences */
|
||||
res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos);
|
||||
prev_pos= (*splocal)->pos_in_query + (*splocal)->m_name.length;
|
||||
|
@ -1051,8 +1052,10 @@ int sp_head::execute(THD *thd)
|
|||
original thd->db will then have been freed */
|
||||
if (dbchanged)
|
||||
{
|
||||
/* No access check when changing back to where we came from.
|
||||
(It would generate an error from mysql_change_db() when olddb=="") */
|
||||
if (! thd->killed)
|
||||
ret= mysql_change_db(thd, olddb, 0);
|
||||
ret= mysql_change_db(thd, olddb, 1);
|
||||
}
|
||||
m_flags&= ~IS_INVOKED;
|
||||
DBUG_RETURN(ret);
|
||||
|
|
|
@ -2784,7 +2784,6 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
|||
Natural_join_column *nj_col;
|
||||
Field *found_field;
|
||||
Query_arena *arena, backup;
|
||||
|
||||
DBUG_ENTER("find_field_in_natural_join");
|
||||
DBUG_PRINT("enter", ("field name: '%s', ref 0x%lx",
|
||||
name, (ulong) ref));
|
||||
|
@ -2809,6 +2808,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
|||
|
||||
if (nj_col->view_field)
|
||||
{
|
||||
Item *item;
|
||||
/*
|
||||
The found field is a view field, we do as in find_field_in_view()
|
||||
and return a pointer to pointer to the Item of that field.
|
||||
|
@ -2816,7 +2816,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
|||
if (register_tree_change)
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
|
||||
Item *item= nj_col->create_item(thd);
|
||||
item= nj_col->create_item(thd);
|
||||
|
||||
if (register_tree_change && arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
|
|
|
@ -1703,15 +1703,19 @@ Statement_map::Statement_map() :
|
|||
|
||||
int Statement_map::insert(Statement *statement)
|
||||
{
|
||||
int rc= my_hash_insert(&st_hash, (byte *) statement);
|
||||
int res= my_hash_insert(&st_hash, (byte *) statement);
|
||||
if (res)
|
||||
return res;
|
||||
if (statement->name.str)
|
||||
{
|
||||
if ((rc= my_hash_insert(&names_hash, (byte*)statement)))
|
||||
if ((res= my_hash_insert(&names_hash, (byte*)statement)))
|
||||
{
|
||||
hash_delete(&st_hash, (byte*)statement);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if (rc == 0)
|
||||
last_found_statement= statement;
|
||||
return rc;
|
||||
last_found_statement= statement;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1809,7 +1809,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
|
|||
#endif
|
||||
if (thd->killed || di->status)
|
||||
break;
|
||||
if (error == ETIMEDOUT)
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
{
|
||||
thd->killed= THD::KILL_CONNECTION;
|
||||
break;
|
||||
|
|
|
@ -58,12 +58,14 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused)))
|
|||
set_timespec(abstime, flush_time);
|
||||
reset_flush_time = FALSE;
|
||||
}
|
||||
while (!manager_status && !error && !abort_loop)
|
||||
error = pthread_cond_timedwait(&COND_manager, &LOCK_manager, &abstime);
|
||||
while (!manager_status && (!error || error == EINTR) && !abort_loop)
|
||||
error= pthread_cond_timedwait(&COND_manager, &LOCK_manager, &abstime);
|
||||
}
|
||||
else
|
||||
while (!manager_status && !error && !abort_loop)
|
||||
error = pthread_cond_wait(&COND_manager, &LOCK_manager);
|
||||
{
|
||||
while (!manager_status && (!error || error == EINTR) && !abort_loop)
|
||||
error= pthread_cond_wait(&COND_manager, &LOCK_manager);
|
||||
}
|
||||
status = manager_status;
|
||||
manager_status = 0;
|
||||
pthread_mutex_unlock(&LOCK_manager);
|
||||
|
@ -71,7 +73,7 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused)))
|
|||
if (abort_loop)
|
||||
break;
|
||||
|
||||
if (error) /* == ETIMEDOUT */
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
{
|
||||
flush_tables();
|
||||
error = 0;
|
||||
|
|
|
@ -2402,7 +2402,7 @@ mysql_execute_command(THD *thd)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* !HAVE_REPLICATION */
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
/*
|
||||
When option readonly is set deny operations which change tables.
|
||||
|
@ -3194,36 +3194,36 @@ end_with_restore_list:
|
|||
if (result != 2)
|
||||
break;
|
||||
case SQLCOM_UPDATE_MULTI:
|
||||
{
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
/* if we switched from normal update, rights are checked */
|
||||
if (result != 2)
|
||||
{
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
/* if we switched from normal update, rights are checked */
|
||||
if (result != 2)
|
||||
{
|
||||
if ((res= multi_update_precheck(thd, all_tables)))
|
||||
break;
|
||||
}
|
||||
else
|
||||
res= 0;
|
||||
if ((res= multi_update_precheck(thd, all_tables)))
|
||||
break;
|
||||
}
|
||||
else
|
||||
res= 0;
|
||||
|
||||
if ((res= mysql_multi_update_prepare(thd)))
|
||||
break;
|
||||
if ((res= mysql_multi_update_prepare(thd)))
|
||||
break;
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
/* Check slave filtering rules */
|
||||
if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
|
||||
{
|
||||
/* we warn the slave SQL thread */
|
||||
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
||||
break;
|
||||
}
|
||||
/* Check slave filtering rules */
|
||||
if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
|
||||
{
|
||||
/* we warn the slave SQL thread */
|
||||
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
res= mysql_multi_update(thd, all_tables,
|
||||
&select_lex->item_list,
|
||||
&lex->value_list,
|
||||
select_lex->where,
|
||||
select_lex->options,
|
||||
lex->duplicates, lex->ignore, unit, select_lex);
|
||||
res= mysql_multi_update(thd, all_tables,
|
||||
&select_lex->item_list,
|
||||
&lex->value_list,
|
||||
select_lex->where,
|
||||
select_lex->options,
|
||||
lex->duplicates, lex->ignore, unit, select_lex);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_REPLACE:
|
||||
|
@ -4524,7 +4524,8 @@ end_with_restore_list:
|
|||
command[thd->lex->create_view_mode].length);
|
||||
view_store_options(thd, first_table, &buff);
|
||||
buff.append("VIEW ", 5);
|
||||
if (!first_table->current_db_used)
|
||||
/* Test if user supplied a db (ie: we did not use thd->db) */
|
||||
if (first_table->db != thd->db && first_table->db[0])
|
||||
{
|
||||
append_identifier(thd, &buff, first_table->db,
|
||||
first_table->db_length);
|
||||
|
@ -4842,7 +4843,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
|
|||
bool db_is_pattern= test(want_access & GRANT_ACL);
|
||||
#endif
|
||||
ulong dummy;
|
||||
const char *db_name;
|
||||
DBUG_ENTER("check_access");
|
||||
DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
|
||||
db ? db : "", want_access, sctx->master_access));
|
||||
|
@ -4860,15 +4860,16 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
|
|||
DBUG_RETURN(TRUE); /* purecov: tested */
|
||||
}
|
||||
|
||||
db_name= db ? db : thd->db;
|
||||
if (schema_db)
|
||||
{
|
||||
if (want_access & ~(SELECT_ACL | EXTRA_ACL))
|
||||
{
|
||||
if (!no_errors)
|
||||
{
|
||||
const char *db_name= db ? db : thd->db;
|
||||
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
|
||||
sctx->priv_user,
|
||||
sctx->priv_host, db_name);
|
||||
sctx->priv_user, sctx->priv_host, db_name);
|
||||
}
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
else
|
||||
|
@ -5043,11 +5044,16 @@ check_routine_access(THD *thd, ulong want_access,char *db, char *name,
|
|||
tables->db= db;
|
||||
tables->table_name= tables->alias= name;
|
||||
|
||||
if ((thd->security_ctx->master_access & want_access) == want_access &&
|
||||
!thd->db)
|
||||
/*
|
||||
The following test is just a shortcut for check_access() (to avoid
|
||||
calculating db_access) under the assumption that it's common to
|
||||
give persons global right to execute all stored SP (but not
|
||||
necessary to create them).
|
||||
*/
|
||||
if ((thd->security_ctx->master_access & want_access) == want_access)
|
||||
tables->grant.privilege= want_access;
|
||||
else if (check_access(thd,want_access,db,&tables->grant.privilege,
|
||||
0, no_errors, test(tables->schema_table)))
|
||||
0, no_errors, 0))
|
||||
return TRUE;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
@ -6134,14 +6140,12 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||
{
|
||||
ptr->db= thd->db;
|
||||
ptr->db_length= thd->db_length;
|
||||
ptr->current_db_used= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The following can't be "" as we may do 'casedn_str()' on it */
|
||||
ptr->db= empty_c_string;
|
||||
ptr->db_length= 0;
|
||||
ptr->current_db_used= 1;
|
||||
}
|
||||
if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
|
||||
ptr->db= thd->strdup(ptr->db);
|
||||
|
@ -7390,9 +7394,9 @@ Item *negate_expression(THD *thd, Item *expr)
|
|||
Assign as view definer current user
|
||||
|
||||
SYNOPSIS
|
||||
default_definer()
|
||||
Secytity_context current decurity context
|
||||
definer structure where it should be assigned
|
||||
default_view_definer()
|
||||
sctx current security context
|
||||
definer structure where it should be assigned
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
|
@ -7403,15 +7407,14 @@ bool default_view_definer(Security_context *sctx, st_lex_user *definer)
|
|||
{
|
||||
definer->user.str= sctx->priv_user;
|
||||
definer->user.length= strlen(sctx->priv_user);
|
||||
if (*sctx->priv_host != 0)
|
||||
{
|
||||
definer->host.str= sctx->priv_host;
|
||||
definer->host.length= strlen(sctx->priv_host);
|
||||
}
|
||||
else
|
||||
|
||||
if (!*sctx->priv_host)
|
||||
{
|
||||
my_error(ER_NO_VIEW_USER, MYF(0));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
definer->host.str= sctx->priv_host;
|
||||
definer->host.length= strlen(sctx->priv_host);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,11 @@ public:
|
|||
class Prepared_statement: public Statement
|
||||
{
|
||||
public:
|
||||
enum flag_values
|
||||
{
|
||||
IS_IN_USE= 1
|
||||
};
|
||||
|
||||
THD *thd;
|
||||
Select_fetch_protocol_prep result;
|
||||
Protocol *protocol;
|
||||
|
@ -131,19 +136,8 @@ public:
|
|||
bool execute(String *expanded_query, bool open_cursor);
|
||||
/* Destroy this statement */
|
||||
bool deallocate();
|
||||
|
||||
/* Possible values of flags */
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||
static const int IS_IN_USE;
|
||||
#else
|
||||
static const int IS_IN_USE= 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* VC6 can't handle initializing in declaration */
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||
const int Prepared_statement::IS_IN_USE= 1;
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
Implementation
|
||||
|
@ -1830,7 +1824,7 @@ static bool init_param_array(Prepared_statement *stmt)
|
|||
void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
|
||||
{
|
||||
Prepared_statement *stmt= new Prepared_statement(thd, &thd->protocol_prep);
|
||||
bool rc;
|
||||
bool error;
|
||||
DBUG_ENTER("mysql_stmt_prepare");
|
||||
|
||||
DBUG_PRINT("prep_query", ("%s", packet));
|
||||
|
@ -1853,12 +1847,12 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
|
|||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
|
||||
|
||||
rc= stmt->prepare(packet, packet_length);
|
||||
error= stmt->prepare(packet, packet_length);
|
||||
|
||||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||
my_pthread_setprio(pthread_self(),WAIT_PRIOR);
|
||||
|
||||
if (rc)
|
||||
if (error)
|
||||
{
|
||||
/* Statement map deletes statement on erase */
|
||||
thd->stmt_map.erase(stmt);
|
||||
|
@ -1900,7 +1894,7 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len)
|
|||
CHARSET_INFO *to_cs= thd->variables.collation_connection;
|
||||
bool needs_conversion;
|
||||
user_var_entry *entry;
|
||||
String *pstr= &str;
|
||||
String *var_value= &str;
|
||||
uint32 unused, len;
|
||||
/*
|
||||
Convert @var contents to string in connection character set. Although
|
||||
|
@ -1914,13 +1908,13 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len)
|
|||
&& entry->value)
|
||||
{
|
||||
my_bool is_var_null;
|
||||
pstr= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC);
|
||||
var_value= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC);
|
||||
/*
|
||||
NULL value of variable checked early as entry->value so here
|
||||
we can't get NULL in normal conditions
|
||||
*/
|
||||
DBUG_ASSERT(!is_var_null);
|
||||
if (!pstr)
|
||||
if (!var_value)
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
|
@ -1932,22 +1926,25 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len)
|
|||
str.set("NULL", 4, &my_charset_latin1);
|
||||
}
|
||||
|
||||
needs_conversion= String::needs_conversion(pstr->length(),
|
||||
pstr->charset(), to_cs, &unused);
|
||||
needs_conversion= String::needs_conversion(var_value->length(),
|
||||
var_value->charset(), to_cs,
|
||||
&unused);
|
||||
|
||||
len= needs_conversion ? pstr->length() * to_cs->mbmaxlen : pstr->length();
|
||||
len= (needs_conversion ? var_value->length() * to_cs->mbmaxlen :
|
||||
var_value->length());
|
||||
if (!(query_str= alloc_root(thd->mem_root, len+1)))
|
||||
goto end;
|
||||
|
||||
if (needs_conversion)
|
||||
{
|
||||
uint dummy_errors;
|
||||
len= copy_and_convert(query_str, len, to_cs, pstr->ptr(), pstr->length(),
|
||||
pstr->charset(), &dummy_errors);
|
||||
len= copy_and_convert(query_str, len, to_cs, var_value->ptr(),
|
||||
var_value->length(), var_value->charset(),
|
||||
&dummy_errors);
|
||||
}
|
||||
else
|
||||
memcpy(query_str, pstr->ptr(), pstr->length());
|
||||
query_str[len]= '\0';
|
||||
memcpy(query_str, var_value->ptr(), var_value->length());
|
||||
query_str[len]= '\0'; // Safety (mostly for debug)
|
||||
*query_len= len;
|
||||
}
|
||||
else
|
||||
|
@ -1997,10 +1994,9 @@ void mysql_sql_stmt_prepare(THD *thd)
|
|||
Prepared_statement *stmt;
|
||||
const char *query;
|
||||
uint query_len;
|
||||
|
||||
DBUG_ENTER("mysql_sql_stmt_prepare");
|
||||
|
||||
DBUG_ASSERT(thd->protocol == &thd->protocol_simple);
|
||||
|
||||
if ((stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
|
||||
{
|
||||
/*
|
||||
|
@ -2182,7 +2178,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
|||
uchar *packet_end= (uchar *) packet + packet_length - 1;
|
||||
#endif
|
||||
Prepared_statement *stmt;
|
||||
bool rc;
|
||||
bool error;
|
||||
DBUG_ENTER("mysql_stmt_execute");
|
||||
|
||||
packet+= 9; /* stmt_id + 5 bytes of flags */
|
||||
|
@ -2217,12 +2213,11 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
|||
#endif
|
||||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
|
||||
rc= stmt->execute(&expanded_query,
|
||||
test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
|
||||
error= stmt->execute(&expanded_query,
|
||||
test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
|
||||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
|
||||
|
||||
if (rc == 0)
|
||||
if (error == 0)
|
||||
mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %s", stmt->id, thd->query);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -2261,9 +2256,7 @@ void mysql_sql_stmt_execute(THD *thd)
|
|||
LEX_STRING *name= &lex->prepared_stmt_name;
|
||||
/* Query text for binary, general or slow log, if any of them is open */
|
||||
String expanded_query;
|
||||
|
||||
DBUG_ENTER("mysql_sql_stmt_execute");
|
||||
|
||||
DBUG_PRINT("info", ("EXECUTE: %.*s\n", name->length, name->str));
|
||||
|
||||
if (!(stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
|
||||
|
@ -2408,7 +2401,6 @@ void mysql_stmt_close(THD *thd, char *packet)
|
|||
/* There is always space for 4 bytes in packet buffer */
|
||||
ulong stmt_id= uint4korr(packet);
|
||||
Prepared_statement *stmt;
|
||||
|
||||
DBUG_ENTER("mysql_stmt_close");
|
||||
|
||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close")))
|
||||
|
@ -2418,7 +2410,7 @@ void mysql_stmt_close(THD *thd, char *packet)
|
|||
The only way currently a statement can be deallocated when it's
|
||||
in use is from within Dynamic SQL.
|
||||
*/
|
||||
DBUG_ASSERT(! (stmt->flags & Prepared_statement::IS_IN_USE));
|
||||
DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
|
||||
(void) stmt->deallocate();
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -2462,7 +2454,7 @@ void mysql_sql_stmt_close(THD *thd)
|
|||
mysql_stmt_get_longdata()
|
||||
thd Thread handle
|
||||
packet String to append
|
||||
packet_length Length of string
|
||||
packet_length Length of string (including end \0)
|
||||
|
||||
DESCRIPTION
|
||||
Get a part of a long data. To make the protocol efficient, we are
|
||||
|
@ -2479,13 +2471,12 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
|
|||
Prepared_statement *stmt;
|
||||
Item_param *param;
|
||||
char *packet_end= packet + packet_length - 1;
|
||||
|
||||
DBUG_ENTER("mysql_stmt_get_longdata");
|
||||
|
||||
statistic_increment(thd->status_var.com_stmt_send_long_data, &LOCK_status);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/* Minimal size of long data packet is 6 bytes */
|
||||
if ((ulong) (packet_end - packet) < MYSQL_LONG_DATA_HEADER)
|
||||
if (packet_length <= MYSQL_LONG_DATA_HEADER)
|
||||
{
|
||||
my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_send_long_data");
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -2592,7 +2583,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
|
|||
param_array(0),
|
||||
param_count(0),
|
||||
last_errno(0),
|
||||
flags(IS_IN_USE)
|
||||
flags((uint) IS_IN_USE)
|
||||
{
|
||||
*last_error= '\0';
|
||||
}
|
||||
|
@ -2709,7 +2700,7 @@ bool Prepared_statement::set_name(LEX_STRING *name_arg)
|
|||
|
||||
bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
||||
{
|
||||
bool rc;
|
||||
bool error;
|
||||
Statement stmt_backup;
|
||||
Query_arena *old_stmt_arena;
|
||||
DBUG_ENTER("Prepared_statement::prepare");
|
||||
|
@ -2740,7 +2731,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||
lex->safe_to_cache_query= FALSE;
|
||||
lex->stmt_prepare_mode= TRUE;
|
||||
|
||||
rc= yyparse((void *)thd) || thd->is_fatal_error ||
|
||||
error= yyparse((void *)thd) || thd->is_fatal_error ||
|
||||
thd->net.report_error || init_param_array(this);
|
||||
/*
|
||||
While doing context analysis of the query (in check_prepared_statement)
|
||||
|
@ -2764,10 +2755,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||
*/
|
||||
DBUG_ASSERT(thd->free_list == NULL);
|
||||
|
||||
if (rc == 0)
|
||||
rc= check_prepared_statement(this, name.str != 0);
|
||||
if (error == 0)
|
||||
error= check_prepared_statement(this, name.str != 0);
|
||||
|
||||
if (rc && lex->sphead)
|
||||
if (error && lex->sphead)
|
||||
{
|
||||
delete lex->sphead;
|
||||
lex->sphead= NULL;
|
||||
|
@ -2777,14 +2768,14 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||
thd->restore_backup_statement(this, &stmt_backup);
|
||||
thd->stmt_arena= old_stmt_arena;
|
||||
|
||||
if (rc == 0)
|
||||
if (error == 0)
|
||||
{
|
||||
setup_set_params();
|
||||
init_stmt_after_parse(lex);
|
||||
state= Query_arena::PREPARED;
|
||||
flags&= ~IS_IN_USE;
|
||||
flags&= ~ (uint) IS_IN_USE;
|
||||
}
|
||||
DBUG_RETURN(rc);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2806,6 +2797,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||
Preconditions, postconditions.
|
||||
------------------------------
|
||||
See the comment for Prepared_statement::prepare().
|
||||
|
||||
RETURN
|
||||
FALSE ok
|
||||
TRUE Error
|
||||
*/
|
||||
|
||||
bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
||||
|
@ -2813,7 +2808,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||
Statement stmt_backup;
|
||||
Query_arena *old_stmt_arena;
|
||||
Item *old_free_list;
|
||||
bool rc= TRUE;
|
||||
bool error= TRUE;
|
||||
|
||||
statistic_increment(thd->status_var.com_stmt_execute, &LOCK_status);
|
||||
|
||||
|
@ -2823,7 +2818,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||
my_message(last_errno, last_error, MYF(0));
|
||||
return TRUE;
|
||||
}
|
||||
if (flags & IS_IN_USE)
|
||||
if (flags & (uint) IS_IN_USE)
|
||||
{
|
||||
my_error(ER_PS_NO_RECURSION, MYF(0));
|
||||
return TRUE;
|
||||
|
@ -2885,13 +2880,14 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||
reinit_stmt_before_use(thd, lex);
|
||||
|
||||
thd->protocol= protocol; /* activate stmt protocol */
|
||||
rc= open_cursor ? mysql_open_cursor(thd, (uint) ALWAYS_MATERIALIZED_CURSOR,
|
||||
&result, &cursor) :
|
||||
mysql_execute_command(thd);
|
||||
error= (open_cursor ?
|
||||
mysql_open_cursor(thd, (uint) ALWAYS_MATERIALIZED_CURSOR,
|
||||
&result, &cursor) :
|
||||
mysql_execute_command(thd));
|
||||
thd->protocol= &thd->protocol_simple; /* use normal protocol */
|
||||
|
||||
/* Assert that if an error, no cursor is open */
|
||||
DBUG_ASSERT(! (rc && cursor));
|
||||
DBUG_ASSERT(! (error && cursor));
|
||||
|
||||
if (! cursor)
|
||||
{
|
||||
|
@ -2906,8 +2902,8 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||
state= Query_arena::EXECUTED;
|
||||
|
||||
error:
|
||||
flags&= ~IS_IN_USE;
|
||||
return rc;
|
||||
flags&= ~ (uint) IS_IN_USE;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2917,7 +2913,7 @@ bool Prepared_statement::deallocate()
|
|||
{
|
||||
/* We account deallocate in the same manner as mysql_stmt_close */
|
||||
statistic_increment(thd->status_var.com_stmt_close, &LOCK_status);
|
||||
if (flags & IS_IN_USE)
|
||||
if (flags & (uint) IS_IN_USE)
|
||||
{
|
||||
my_error(ER_PS_NO_RECURSION, MYF(0));
|
||||
return TRUE;
|
||||
|
|
|
@ -2474,11 +2474,11 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
|||
and use them in equality propagation process (see details in
|
||||
OptimizerKBAndTodo)
|
||||
*/
|
||||
if ((cond->functype() == Item_func::BETWEEN) &&
|
||||
value[0]->eq(value[1], field->binary()))
|
||||
eq_func= TRUE;
|
||||
else
|
||||
if ((cond->functype() != Item_func::BETWEEN) ||
|
||||
((Item_func_between*) cond)->negated ||
|
||||
!value[0]->eq(value[1], field->binary()))
|
||||
return;
|
||||
eq_func= TRUE;
|
||||
}
|
||||
|
||||
if (field->result_type() == STRING_RESULT)
|
||||
|
@ -6254,6 +6254,21 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal)
|
|||
{
|
||||
Item *left_item= ((Item_func*) item)->arguments()[0];
|
||||
Item *right_item= ((Item_func*) item)->arguments()[1];
|
||||
|
||||
if (left_item->type() == Item::REF_ITEM &&
|
||||
((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF)
|
||||
{
|
||||
if (((Item_ref*)left_item)->depended_from)
|
||||
return FALSE;
|
||||
left_item= left_item->real_item();
|
||||
}
|
||||
if (right_item->type() == Item::REF_ITEM &&
|
||||
((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF)
|
||||
{
|
||||
if (((Item_ref*)right_item)->depended_from)
|
||||
return FALSE;
|
||||
right_item= right_item->real_item();
|
||||
}
|
||||
if (left_item->type() == Item::FIELD_ITEM &&
|
||||
right_item->type() == Item::FIELD_ITEM &&
|
||||
!((Item_field*)left_item)->depended_from &&
|
||||
|
|
|
@ -1023,6 +1023,11 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
|
|||
packet->append(" COMMENT=", 9);
|
||||
append_unescaped(packet, share->comment, strlen(share->comment));
|
||||
}
|
||||
if (share->connect_string.length)
|
||||
{
|
||||
packet->append(" CONNECTION=", 12);
|
||||
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
|
||||
}
|
||||
if (file->raid_type)
|
||||
{
|
||||
uint length;
|
||||
|
@ -1258,9 +1263,6 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
|||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
|
||||
thread_info *thd_info;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *sctx;
|
||||
#endif
|
||||
time_t now= time(0);
|
||||
while ((thd_info=thread_infos.get()))
|
||||
{
|
||||
|
|
|
@ -1571,7 +1571,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (wait_if_global_read_lock(thd, 0, 1))
|
||||
DBUG_RETURN(error);
|
||||
DBUG_RETURN(TRUE);
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
|
||||
{
|
||||
|
@ -1636,20 +1636,20 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
error= FALSE;
|
||||
goto end;
|
||||
|
||||
warn:
|
||||
error= 0;
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
|
||||
alias);
|
||||
create_info->table_existed= 1; // Mark that table existed
|
||||
|
||||
end:
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
start_waiting_global_read_lock(thd);
|
||||
thd->proc_info="After create";
|
||||
DBUG_RETURN(error);
|
||||
|
||||
warn:
|
||||
error= FALSE;
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
|
||||
alias);
|
||||
create_info->table_existed= 1; // Mark that table existed
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3156,15 +3156,14 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
if (create_info->row_type == ROW_TYPE_NOT_USED)
|
||||
create_info->row_type= table->s->row_type;
|
||||
|
||||
DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type));
|
||||
if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED)
|
||||
|| ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
|
||||
DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type));
|
||||
if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
|
||||
ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
|
||||
{
|
||||
DBUG_PRINT("info", ("doesn't support alter"));
|
||||
my_error(ER_ILLEGAL_HA, MYF(0), table_name);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
DBUG_PRINT("info", ("supports alter"));
|
||||
|
||||
thd->proc_info="setup";
|
||||
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
|
||||
|
|
|
@ -1427,7 +1427,7 @@ mysql_rename_view(THD *thd,
|
|||
|
||||
/* get view definition and source */
|
||||
if (parser->parse((gptr)&view_def, thd->mem_root, view_parameters,
|
||||
sizeof(view_parameters)/sizeof(view_parameters[0])-1))
|
||||
array_elements(view_parameters)-1))
|
||||
goto err;
|
||||
|
||||
/* rename view and it's backups */
|
||||
|
|
|
@ -7992,6 +7992,18 @@ option_value:
|
|||
$2= $2 ? $2: global_system_variables.character_set_client;
|
||||
lex->var_list.push_back(new set_var_collation_client($2,thd->variables.collation_database,$2));
|
||||
}
|
||||
| NAMES_SYM equal expr
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_pcontext *spc= lex->spcont;
|
||||
LEX_STRING names;
|
||||
|
||||
names.str= (char *)"names";
|
||||
names.length= 5;
|
||||
if (spc && spc->find_pvar(&names))
|
||||
my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str);
|
||||
YYABORT;
|
||||
}
|
||||
| NAMES_SYM charset_name_or_default opt_collate
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
|
@ -8009,6 +8021,17 @@ option_value:
|
|||
{
|
||||
THD *thd=YYTHD;
|
||||
LEX_USER *user;
|
||||
LEX *lex= Lex;
|
||||
sp_pcontext *spc= lex->spcont;
|
||||
LEX_STRING pw;
|
||||
|
||||
pw.str= (char *)"password";
|
||||
pw.length= 8;
|
||||
if (spc && spc->find_pvar(&pw))
|
||||
{
|
||||
my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str);
|
||||
YYABORT;
|
||||
}
|
||||
if (!(user=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))
|
||||
YYABORT;
|
||||
user->host=null_lex_str;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
struct st_table;
|
||||
class Field;
|
||||
|
||||
#define STRING_WITH_LEN(X) X, (sizeof(X)-1)
|
||||
#define STRING_WITH_LEN(X) ((char*) X), (sizeof(X)-1)
|
||||
|
||||
typedef struct st_lex_string
|
||||
{
|
||||
|
|
16
sql/table.cc
16
sql/table.cc
|
@ -476,9 +476,11 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
|
|||
{
|
||||
outparam->null_flags=null_pos=(uchar*) record+1;
|
||||
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
|
||||
/* null_bytes below is only correct under the condition that
|
||||
there are no bit fields. Correct values is set below after the
|
||||
table struct is initialized */
|
||||
/*
|
||||
null_bytes below is only correct under the condition that
|
||||
there are no bit fields. Correct values is set below after the
|
||||
table struct is initialized
|
||||
*/
|
||||
share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
|
||||
}
|
||||
else
|
||||
|
@ -891,8 +893,12 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
|
|||
}
|
||||
}
|
||||
|
||||
/* the correct null_bytes can now be set, since bitfields have been taken into account */
|
||||
share->null_bytes= null_pos - (uchar*) outparam->null_flags + (null_bit_pos + 7) / 8;
|
||||
/*
|
||||
the correct null_bytes can now be set, since bitfields have been taken
|
||||
into account
|
||||
*/
|
||||
share->null_bytes= (null_pos - (uchar*) outparam->null_flags +
|
||||
(null_bit_pos + 7) / 8);
|
||||
share->last_null_bit_pos= null_bit_pos;
|
||||
|
||||
/* The table struct is now initialized; Open the table */
|
||||
|
|
|
@ -585,8 +585,6 @@ typedef struct st_table_list
|
|||
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
|
||||
/* view where processed */
|
||||
bool where_processed;
|
||||
/* db part was not defined in table definition */
|
||||
bool current_db_used;
|
||||
/* FRMTYPE_ERROR if any type is acceptable */
|
||||
enum frm_type_enum required_type;
|
||||
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */
|
||||
|
|
|
@ -485,16 +485,10 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
|
|||
char *dst;
|
||||
uint length= field->interval->type_lengths[pos], hex_length;
|
||||
const char *src= field->interval->type_names[pos];
|
||||
const char *srcend= src + length;
|
||||
hex_length= length * 2;
|
||||
field->interval->type_lengths[pos]= hex_length;
|
||||
field->interval->type_names[pos]= dst= sql_alloc(hex_length + 1);
|
||||
for ( ; src < srcend; src++)
|
||||
{
|
||||
*dst++= _dig_vec_upper[((uchar) *src) >> 4];
|
||||
*dst++= _dig_vec_upper[((uchar) *src) & 15];
|
||||
}
|
||||
*dst= '\0';
|
||||
octet2hex(dst, src, length);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2018,7 +2018,7 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
|
|||
if (to->buf < buf1)
|
||||
{
|
||||
dec1 *cur_d= to->buf;
|
||||
for (; d_to_move; d_to_move--, cur_d++, buf1++)
|
||||
for (; d_to_move--; cur_d++, buf1++)
|
||||
*cur_d= *buf1;
|
||||
}
|
||||
return error;
|
||||
|
|
|
@ -26,95 +26,88 @@
|
|||
.type longlong2str_with_dig_vector,@function
|
||||
|
||||
longlong2str_with_dig_vector:
|
||||
subl $80,%esp
|
||||
subl $80,%esp # Temporary buffer for up to 64 radix-2 digits
|
||||
pushl %ebp
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
movl 100(%esp),%esi # Lower part of val
|
||||
movl 112(%esp),%ebx # Radix
|
||||
movl 104(%esp),%ebp # Higher part of val
|
||||
movl %ebx,%eax
|
||||
movl 108(%esp),%edi # get dst
|
||||
testl %eax,%eax
|
||||
jge .L144
|
||||
movl 100(%esp),%esi # esi = Lower part of val
|
||||
movl 112(%esp),%ebx # ebx = Radix
|
||||
movl 104(%esp),%ebp # ebp = Higher part of val
|
||||
movl 108(%esp),%edi # edi = dst
|
||||
|
||||
addl $36,%eax
|
||||
cmpl $34,%eax
|
||||
ja .Lerror # Wrong radix
|
||||
testl %ebp,%ebp
|
||||
jge .L146
|
||||
testl %ebx,%ebx
|
||||
jge .L144 # Radix was positive
|
||||
negl %ebx # Change radix to positive
|
||||
testl %ebp,%ebp # Test if given value is negative
|
||||
jge .L144
|
||||
movb $45,(%edi) # Add sign
|
||||
incl %edi # Change sign of val
|
||||
negl %esi
|
||||
adcl $0,%ebp
|
||||
negl %ebp
|
||||
.L146:
|
||||
negl %ebx # Change radix to positive
|
||||
jmp .L148
|
||||
.align 4
|
||||
.L144:
|
||||
addl $-2,%eax
|
||||
|
||||
.L144: # Test that radix is between 2 and 36
|
||||
movl %ebx, %eax
|
||||
addl $-2,%eax # Test that radix is between 2 and 36
|
||||
cmpl $34,%eax
|
||||
ja .Lerror # Radix in range
|
||||
ja .Lerror # Radix was not in range
|
||||
|
||||
.L148:
|
||||
movl %esi,%eax # Test if zero (for easy loop)
|
||||
orl %ebp,%eax
|
||||
jne .L150
|
||||
movb $48,(%edi)
|
||||
incl %edi
|
||||
jmp .L10_end
|
||||
.align 4
|
||||
|
||||
.L150:
|
||||
leal 92(%esp),%ecx # End of buffer
|
||||
movl %edi, 108(%esp) # Store possible modified dest
|
||||
movl 116(%esp), %edi # dig_vec_upper
|
||||
jmp .L155
|
||||
.align 4
|
||||
testl %ebp,%ebp # Test if value > 0xFFFFFFFF
|
||||
jne .Llongdiv
|
||||
cmpl %ebx, %esi # Test if <= radix, for easy loop
|
||||
movl %esi, %eax # Value in eax (for Llow)
|
||||
jae .Llow
|
||||
|
||||
.L153:
|
||||
# val is stored in in ebp:esi
|
||||
# Value is one digit (negative or positive)
|
||||
movb (%eax,%edi),%bl
|
||||
movl 108(%esp),%edi # get dst
|
||||
movb %bl,(%edi)
|
||||
incl %edi # End null here
|
||||
jmp .L10_end
|
||||
|
||||
movl %ebp,%eax # High part of value
|
||||
.Llongdiv:
|
||||
# Value in ebp:esi. div the high part by the radix,
|
||||
# then div remainder + low part by the radix.
|
||||
movl %ebp,%eax # edx=0,eax=high(from ebp)
|
||||
xorl %edx,%edx
|
||||
decl %ecx
|
||||
divl %ebx
|
||||
movl %eax,%ebp
|
||||
movl %eax,%ebp # edx=result of last, eax=low(from esi)
|
||||
movl %esi,%eax
|
||||
divl %ebx
|
||||
decl %ecx
|
||||
movl %eax,%esi # quotent in ebp:esi
|
||||
movb (%edx,%edi),%al # al is faster than dl
|
||||
movb %al,(%ecx) # store value in buff
|
||||
.align 4
|
||||
.L155:
|
||||
movl %eax,%esi # ebp:esi = quotient
|
||||
movb (%edx,%edi),%dl # Store result number in temporary buffer
|
||||
testl %ebp,%ebp
|
||||
ja .L153
|
||||
testl %esi,%esi # rest value
|
||||
jl .L153
|
||||
je .L160 # Ready
|
||||
movl %esi,%eax
|
||||
movb %dl,(%ecx) # store value in buff
|
||||
ja .Llongdiv # (Higher part of val still > 0)
|
||||
|
||||
.align 4
|
||||
|
||||
.L154: # Do rest with integer precision
|
||||
cltd
|
||||
divl %ebx
|
||||
.Llow: # Do rest with integer precision
|
||||
# Value in 0:eax. div 0 + low part by the radix.
|
||||
xorl %edx,%edx
|
||||
decl %ecx
|
||||
divl %ebx
|
||||
movb (%edx,%edi),%dl # bh is always zero as ebx=radix < 36
|
||||
testl %eax,%eax
|
||||
movb %dl,(%ecx)
|
||||
jne .L154
|
||||
jne .Llow
|
||||
|
||||
.L160:
|
||||
movl 108(%esp),%edi # get dst
|
||||
|
||||
.L10_mov:
|
||||
movl %ecx,%esi
|
||||
leal 92(%esp),%ecx # End of buffer
|
||||
subl %esi,%ecx
|
||||
rep
|
||||
movsb
|
||||
|
||||
.Lcopy_end:
|
||||
leal 92(%esp),%esi # End of buffer
|
||||
.Lmov: # mov temporary buffer to result (%ecx -> %edi)
|
||||
movb (%ecx), %al
|
||||
movb %al, (%edi)
|
||||
incl %ecx
|
||||
incl %edi
|
||||
cmpl %ecx,%esi
|
||||
jne .Lmov
|
||||
|
||||
.L10_end:
|
||||
movl %edi,%eax # Pointer to end null
|
||||
|
@ -166,21 +159,23 @@ longlong10_to_str:
|
|||
negl %esi # Change sign of val (ebp:esi)
|
||||
adcl $0,%ebp
|
||||
negl %ebp
|
||||
.align 4
|
||||
|
||||
.L10_10:
|
||||
leal 92(%esp),%ecx # End of buffer
|
||||
movl %esi,%eax # Test if zero (for easy loop)
|
||||
orl %ebp,%eax
|
||||
jne .L10_30 # Not zero
|
||||
testl %ebp,%ebp # Test if value > 0xFFFFFFFF
|
||||
jne .L10_longdiv
|
||||
cmpl $10, %esi # Test if <= radix, for easy loop
|
||||
movl %esi, %ebx # Value in eax (for L10_low)
|
||||
jae .L10_low
|
||||
|
||||
# Here when value is zero
|
||||
movb $48,(%edi)
|
||||
# Value is one digit (negative or positive)
|
||||
addb $48, %bl
|
||||
movb %bl,(%edi)
|
||||
incl %edi
|
||||
jmp .L10_end
|
||||
.align 4
|
||||
|
||||
.L10_20:
|
||||
.L10_longdiv:
|
||||
# val is stored in in ebp:esi
|
||||
movl %ebp,%eax # High part of value
|
||||
xorl %edx,%edx
|
||||
|
@ -195,17 +190,15 @@ longlong10_to_str:
|
|||
|
||||
.L10_30:
|
||||
testl %ebp,%ebp
|
||||
ja .L10_20
|
||||
testl %esi,%esi # rest value
|
||||
jl .L10_20 # Unsigned, do ulonglong div once more
|
||||
je .L10_mov # Ready
|
||||
ja .L10_longdiv
|
||||
movl %esi,%ebx # Move val to %ebx
|
||||
|
||||
.L10_low:
|
||||
# The following code uses some tricks to change division by 10 to
|
||||
# multiplication and shifts
|
||||
movl $0xcccccccd,%esi
|
||||
|
||||
.L10_40:
|
||||
.L10_40: # Divide %ebx with 10
|
||||
movl %ebx,%eax
|
||||
mull %esi
|
||||
decl %ecx
|
||||
|
@ -218,7 +211,7 @@ longlong10_to_str:
|
|||
movl %edx,%ebx
|
||||
testl %ebx,%ebx
|
||||
jne .L10_40
|
||||
jmp .L10_mov # Shared end with longlong10_to_str
|
||||
jmp .Lcopy_end # Shared end with longlong2str
|
||||
|
||||
.L10end:
|
||||
.size longlong10_to_str,.L10end-longlong10_to_str
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#undef ULONGLONG_MAX
|
||||
/* Needed under MetroWerks Compiler, since MetroWerks compiler does not properly handle a constant expression containing a mod operator */
|
||||
#if defined(__NETWARE__) && defined(__MWERKS__)
|
||||
ulonglong tmp;
|
||||
#define ULONGLONG_MAX (tmp =(~(ulonglong) 0))
|
||||
static ulonglong ulonglong_max= ~(ulonglong) 0;
|
||||
#define ULONGLONG_MAX ulonglong_max
|
||||
#else
|
||||
#define ULONGLONG_MAX (~(ulonglong) 0)
|
||||
#endif /* __NETWARE__ && __MWERKS__ */
|
||||
|
|
Loading…
Add table
Reference in a new issue