Commit a4df2210 authored by unknown's avatar unknown

Merge tsmith@bk-internal.mysql.com:/home/bk/mysql-5.0

into  ramayana.hindu.god:/home/tsmith/m/bk/maint/50


sql/sql_table.cc:
  Auto merged
parents 8c033250 21fd6c0f
...@@ -550,16 +550,6 @@ unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, ...@@ -550,16 +550,6 @@ unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
char *to,const char *from, char *to,const char *from,
unsigned long length); unsigned long length);
void STDCALL mysql_debug(const char *debug); void STDCALL mysql_debug(const char *debug);
char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
char *to,
unsigned long to_length,
const char *from,
unsigned long from_length,
void *param,
char *
(*extend_buffer)
(void *, char *to,
unsigned long *length));
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int STDCALL mysql_thread_safe(void); unsigned int STDCALL mysql_thread_safe(void);
my_bool STDCALL mysql_embedded(void); my_bool STDCALL mysql_embedded(void);
......
This diff is collapsed.
...@@ -1617,78 +1617,6 @@ mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, ...@@ -1617,78 +1617,6 @@ mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
return escape_string_for_mysql(mysql->charset, to, 0, from, length); return escape_string_for_mysql(mysql->charset, to, 0, from, length);
} }
char * STDCALL
mysql_odbc_escape_string(MYSQL *mysql,
char *to, ulong to_length,
const char *from, ulong from_length,
void *param,
char * (*extend_buffer)
(void *, char *, ulong *))
{
char *to_end=to+to_length-5;
const char *end;
#ifdef USE_MB
my_bool use_mb_flag=use_mb(mysql->charset);
#endif
for (end=from+from_length; from != end ; from++)
{
if (to >= to_end)
{
to_length = (ulong) (end-from)+512; /* We want this much more */
if (!(to=(*extend_buffer)(param, to, &to_length)))
return to;
to_end=to+to_length-5;
}
#ifdef USE_MB
{
int l;
if (use_mb_flag && (l = my_ismbchar(mysql->charset, from, end)))
{
while (l--)
*to++ = *from++;
from--;
continue;
}
}
#endif
switch (*from) {
case 0: /* Must be escaped for 'mysql' */
*to++= '\\';
*to++= '0';
break;
case '\n': /* Must be escaped for logs */
*to++= '\\';
*to++= 'n';
break;
case '\r':
*to++= '\\';
*to++= 'r';
break;
case '\\':
*to++= '\\';
*to++= '\\';
break;
case '\'':
*to++= '\\';
*to++= '\'';
break;
case '"': /* Better safe than sorry */
*to++= '\\';
*to++= '"';
break;
case '\032': /* This gives problems on Win32 */
*to++= '\\';
*to++= 'Z';
break;
default:
*to++= *from;
}
}
return to;
}
void STDCALL void STDCALL
myodbc_remove_escape(MYSQL *mysql,char *name) myodbc_remove_escape(MYSQL *mysql,char *name)
{ {
......
...@@ -78,7 +78,6 @@ EXPORTS ...@@ -78,7 +78,6 @@ EXPORTS
mysql_next_result mysql_next_result
mysql_num_fields mysql_num_fields
mysql_num_rows mysql_num_rows
mysql_odbc_escape_string
mysql_options mysql_options
mysql_stmt_param_count mysql_stmt_param_count
mysql_stmt_param_metadata mysql_stmt_param_metadata
......
...@@ -71,7 +71,6 @@ EXPORTS ...@@ -71,7 +71,6 @@ EXPORTS
mysql_next_result mysql_next_result
mysql_num_fields mysql_num_fields
mysql_num_rows mysql_num_rows
mysql_odbc_escape_string
mysql_options mysql_options
mysql_ping mysql_ping
mysql_query mysql_query
......
...@@ -55,3 +55,20 @@ flush tables with read lock; ...@@ -55,3 +55,20 @@ flush tables with read lock;
insert into t2 values(1); insert into t2 values(1);
unlock tables; unlock tables;
drop table t1, t2; drop table t1, t2;
drop table if exists t1, t2;
set session low_priority_updates=1;
create table t1 (a int);
create table t2 (b int);
lock tables t1 write;
flush tables with read lock;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables;
lock tables t1 read, t2 write;
flush tables with read lock;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables;
lock tables t1 read;
flush tables with read lock;
unlock tables;
drop table t1, t2;
set session low_priority_updates=default;
...@@ -88,3 +88,14 @@ alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 ...@@ -88,3 +88,14 @@ alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1
alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
unlock tables; unlock tables;
drop table t1; drop table t1;
drop table if exists t1;
create table t1 (a int);
connection: locker
lock tables t1 read;
connection: writer
create table t2 like t1;;
connection: default
kill query
ERROR 70100: Query execution was interrupted
unlock tables;
drop table t1;
...@@ -133,4 +133,35 @@ disconnect con3; ...@@ -133,4 +133,35 @@ disconnect con3;
connection default; connection default;
drop table t1, t2; drop table t1, t2;
#
# Bug#32528 Global read lock with a low priority write lock causes a server crash
#
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
set session low_priority_updates=1;
create table t1 (a int);
create table t2 (b int);
lock tables t1 write;
--error ER_LOCK_OR_ACTIVE_TRANSACTION
flush tables with read lock;
unlock tables;
lock tables t1 read, t2 write;
--error ER_LOCK_OR_ACTIVE_TRANSACTION
flush tables with read lock;
unlock tables;
lock tables t1 read;
flush tables with read lock;
unlock tables;
drop table t1, t2;
set session low_priority_updates=default;
# End of 5.0 tests # End of 5.0 tests
...@@ -249,4 +249,36 @@ reap; ...@@ -249,4 +249,36 @@ reap;
connection locker; connection locker;
drop table t1; drop table t1;
#
# Bug#31479 Bad lock interaction if CREATE TABLE LIKE is killed
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int);
--echo connection: locker
connection locker;
lock tables t1 read;
--echo connection: writer
connection writer;
let $ID= `select connection_id()`;
--send create table t2 like t1;
--echo connection: default
connection default;
let $show_type= open tables where in_use=2 and name_locked=1;
let $show_pattern= '%t1%2%1';
--source include/wait_show_pattern.inc
--echo kill query
disable_query_log;
eval kill query $ID;
enable_query_log;
connection writer;
--error ER_QUERY_INTERRUPTED
--reap
connection locker;
unlock tables;
connection default;
drop table t1;
# End of 5.0 tests # End of 5.0 tests
...@@ -1085,11 +1085,16 @@ void mysql_read_default_options(struct st_mysql_options *options, ...@@ -1085,11 +1085,16 @@ void mysql_read_default_options(struct st_mysql_options *options,
my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME)); options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME));
break; break;
case 26: /* ssl_cipher */
my_free(options->ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME));
break;
#else #else
case 13: /* Ignore SSL options */ case 13: /* Ignore SSL options */
case 14: case 14:
case 15: case 15:
case 16: case 16:
case 26:
break; break;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
case 17: /* charset-lib */ case 17: /* charset-lib */
......
...@@ -3739,13 +3739,12 @@ longlong Item_func_sleep::val_int() ...@@ -3739,13 +3739,12 @@ longlong Item_func_sleep::val_int()
break; break;
error= 0; error= 0;
} }
pthread_mutex_unlock(&LOCK_user_locks);
pthread_mutex_lock(&thd->mysys_var->mutex); pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0; thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0; thd->mysys_var->current_cond= 0;
pthread_mutex_unlock(&thd->mysys_var->mutex); pthread_mutex_unlock(&thd->mysys_var->mutex);
pthread_mutex_unlock(&LOCK_user_locks);
pthread_cond_destroy(&cond); pthread_cond_destroy(&cond);
return test(!error); // Return 1 killed return test(!error); // Return 1 killed
......
...@@ -2502,7 +2502,12 @@ static int my_message_sql(uint error, const char *str, myf MyFlags) ...@@ -2502,7 +2502,12 @@ static int my_message_sql(uint error, const char *str, myf MyFlags)
thd->query_error= 1; // needed to catch query errors during replication thd->query_error= 1; // needed to catch query errors during replication
if (!thd->no_warnings_for_error) if (!thd->no_warnings_for_error)
{
thd->no_warnings_for_error= TRUE;
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str); push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
thd->no_warnings_for_error= FALSE;
}
/* /*
thd->lex->current_select == 0 if lex structure is not inited thd->lex->current_select == 0 if lex structure is not inited
(not query command (COM_QUERY)) (not query command (COM_QUERY))
...@@ -4307,8 +4312,13 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) ...@@ -4307,8 +4312,13 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
sock == unix_sock ? VIO_LOCALHOST: 0)) || sock == unix_sock ? VIO_LOCALHOST: 0)) ||
my_net_init(&thd->net,vio_tmp)) my_net_init(&thd->net,vio_tmp))
{ {
if (vio_tmp) /*
vio_delete(vio_tmp); Only delete the temporary vio if we didn't already attach it to the
NET object. The destructor in THD will delete any initialized net
structure.
*/
if (vio_tmp && thd->net.vio != vio_tmp)
vio_delete(vio_tmp);
else else
{ {
(void) shutdown(new_sock, SHUT_RDWR); (void) shutdown(new_sock, SHUT_RDWR);
......
...@@ -437,14 +437,16 @@ check_routine_name(LEX_STRING ident) ...@@ -437,14 +437,16 @@ check_routine_name(LEX_STRING ident)
*/ */
void * void *
sp_head::operator new(size_t size) sp_head::operator new(size_t size) throw()
{ {
DBUG_ENTER("sp_head::operator new"); DBUG_ENTER("sp_head::operator new");
MEM_ROOT own_root; MEM_ROOT own_root;
sp_head *sp; sp_head *sp;
init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
sp= (sp_head *) alloc_root(&own_root, size); sp= (sp_head *) alloc_root(&own_root, size);
if (sp == NULL)
return NULL;
sp->main_mem_root= own_root; sp->main_mem_root= own_root;
DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root)); DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
DBUG_RETURN(sp); DBUG_RETURN(sp);
...@@ -455,6 +457,10 @@ sp_head::operator delete(void *ptr, size_t size) ...@@ -455,6 +457,10 @@ sp_head::operator delete(void *ptr, size_t size)
{ {
DBUG_ENTER("sp_head::operator delete"); DBUG_ENTER("sp_head::operator delete");
MEM_ROOT own_root; MEM_ROOT own_root;
if (ptr == NULL)
DBUG_VOID_RETURN;
sp_head *sp= (sp_head *) ptr; sp_head *sp= (sp_head *) ptr;
/* Make a copy of main_mem_root as free_root will free the sp */ /* Make a copy of main_mem_root as free_root will free the sp */
...@@ -498,6 +504,9 @@ sp_head::init(LEX *lex) ...@@ -498,6 +504,9 @@ sp_head::init(LEX *lex)
lex->spcont= m_pcont= new sp_pcontext(); lex->spcont= m_pcont= new sp_pcontext();
if (!lex->spcont)
DBUG_VOID_RETURN;
/* /*
Altough trg_table_fields list is used only in triggers we init for all Altough trg_table_fields list is used only in triggers we init for all
types of stored procedures to simplify reset_lex()/restore_lex() code. types of stored procedures to simplify reset_lex()/restore_lex() code.
...@@ -999,7 +1008,7 @@ sp_head::execute(THD *thd) ...@@ -999,7 +1008,7 @@ sp_head::execute(THD *thd)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
/* init per-instruction memroot */ /* init per-instruction memroot */
init_alloc_root(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0); init_sql_alloc(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
DBUG_ASSERT(!(m_flags & IS_INVOKED)); DBUG_ASSERT(!(m_flags & IS_INVOKED));
m_flags|= IS_INVOKED; m_flags|= IS_INVOKED;
...@@ -1821,16 +1830,29 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -1821,16 +1830,29 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
} }
// Reset lex during parsing, before we parse a sub statement. /**
void @brief Reset lex during parsing, before we parse a sub statement.
@param thd Thread handler.
@return Error state
@retval true An error occurred.
@retval false Success.
*/
bool
sp_head::reset_lex(THD *thd) sp_head::reset_lex(THD *thd)
{ {
DBUG_ENTER("sp_head::reset_lex"); DBUG_ENTER("sp_head::reset_lex");
LEX *sublex; LEX *sublex;
LEX *oldlex= thd->lex; LEX *oldlex= thd->lex;
sublex= new (thd->mem_root)st_lex_local;
if (sublex == 0)
DBUG_RETURN(TRUE);
thd->lex= sublex;
(void)m_lex.push_front(oldlex); (void)m_lex.push_front(oldlex);
thd->lex= sublex= new st_lex;
/* Reset most stuff. */ /* Reset most stuff. */
lex_start(thd); lex_start(thd);
...@@ -1853,7 +1875,7 @@ sp_head::reset_lex(THD *thd) ...@@ -1853,7 +1875,7 @@ sp_head::reset_lex(THD *thd)
sublex->interval_list.empty(); sublex->interval_list.empty();
sublex->type= 0; sublex->type= 0;
DBUG_VOID_RETURN; DBUG_RETURN(FALSE);
} }
// Restore lex during parsing, after we have parsed a sub statement. // Restore lex during parsing, after we have parsed a sub statement.
...@@ -3729,7 +3751,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex, ...@@ -3729,7 +3751,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex,
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST)))) if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
{ {
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(TABLE_LIST)); thd->fatal_error();
return NULL; return NULL;
} }
table->db_length= strlen(db); table->db_length= strlen(db);
......
...@@ -182,10 +182,10 @@ public: ...@@ -182,10 +182,10 @@ public:
Security_context m_security_ctx; Security_context m_security_ctx;
static void * static void *
operator new(size_t size); operator new(size_t size) throw ();
static void static void
operator delete(void *ptr, size_t size); operator delete(void *ptr, size_t size) throw ();
sp_head(); sp_head();
...@@ -245,7 +245,7 @@ public: ...@@ -245,7 +245,7 @@ public:
} }
// Resets lex in 'thd' and keeps a copy of the old one. // Resets lex in 'thd' and keeps a copy of the old one.
void bool
reset_lex(THD *thd); reset_lex(THD *thd);
// Restores lex in 'thd' from our copy, but keeps some status from the // Restores lex in 'thd' from our copy, but keeps some status from the
......
...@@ -80,7 +80,6 @@ bool Prelock_error_handler::safely_trapped_errors() ...@@ -80,7 +80,6 @@ bool Prelock_error_handler::safely_trapped_errors()
return ((m_handled_errors > 0) && (m_unhandled_errors == 0)); return ((m_handled_errors > 0) && (m_unhandled_errors == 0));
} }
TABLE *unused_tables; /* Used by mysql_test */ TABLE *unused_tables; /* Used by mysql_test */
HASH open_cache; /* Used by mysql_test */ HASH open_cache; /* Used by mysql_test */
...@@ -2653,7 +2652,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) ...@@ -2653,7 +2652,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
temporary mem_root for new .frm parsing. temporary mem_root for new .frm parsing.
TODO: variables for size TODO: variables for size
*/ */
init_alloc_root(&new_frm_mem, 8024, 8024); init_sql_alloc(&new_frm_mem, 8024, 8024);
thd->current_tablenr= 0; thd->current_tablenr= 0;
restart: restart:
......
...@@ -1283,11 +1283,11 @@ typedef struct st_lex : public Query_tables_list ...@@ -1283,11 +1283,11 @@ typedef struct st_lex : public Query_tables_list
struct st_lex_local: public st_lex struct st_lex_local: public st_lex
{ {
static void *operator new(size_t size) static void *operator new(size_t size) throw()
{ {
return (void*) sql_alloc((uint) size); return (void*) sql_alloc((uint) size);
} }
static void *operator new(size_t size, MEM_ROOT *mem_root) static void *operator new(size_t size, MEM_ROOT *mem_root) throw()
{ {
return (void*) alloc_root(mem_root, (uint) size); return (void*) alloc_root(mem_root, (uint) size);
} }
...@@ -1303,3 +1303,4 @@ extern void lex_start(THD *thd); ...@@ -1303,3 +1303,4 @@ extern void lex_start(THD *thd);
extern void lex_end(LEX *lex); extern void lex_end(LEX *lex);
extern int MYSQLlex(void *arg, void *yythd); extern int MYSQLlex(void *arg, void *yythd);
extern char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end); extern char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end);
...@@ -7070,7 +7070,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, ...@@ -7070,7 +7070,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
for (; lock_p < end_p; lock_p++) for (; lock_p < end_p; lock_p++)
{ {
if ((*lock_p)->type == TL_WRITE) if ((*lock_p)->type >= TL_WRITE_ALLOW_WRITE)
{ {
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
return 1; return 1;
......
...@@ -2659,7 +2659,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg) ...@@ -2659,7 +2659,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
last_errno(0), last_errno(0),
flags((uint) IS_IN_USE) flags((uint) IS_IN_USE)
{ {
init_alloc_root(&main_mem_root, thd_arg->variables.query_alloc_block_size, init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size,
thd_arg->variables.query_prealloc_size); thd_arg->variables.query_prealloc_size);
*last_error= '\0'; *last_error= '\0';
} }
......
...@@ -2771,7 +2771,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *src_table, ...@@ -2771,7 +2771,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *src_table,
operations on the target table. operations on the target table.
*/ */
if (lock_and_wait_for_table_name(thd, src_table)) if (lock_and_wait_for_table_name(thd, src_table))
goto err; DBUG_RETURN(res);
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment