Merge mysql.com:/usr/local/bk/mysql-5.0

into  mysql.com:/home/pem/work/bug7049/mysql-5.0
This commit is contained in:
pem@mysql.com 2005-10-12 16:39:39 +02:00
commit 6a88684eb3
73 changed files with 1054 additions and 758 deletions

View file

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

View file

@ -104,6 +104,10 @@ else
make=make
fi
if test -z "$CC" ; then
CC=gcc
fi
if test -z "$CXX" ; then
CXX=gcc
fi

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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