diff options
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 89 |
1 files changed, 65 insertions, 24 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 67f3955ea61..09e4953cdc4 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2252,11 +2253,8 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, want to send "Server shutdown in progress" in the INSERT THREAD. */ - if (di->thd.stmt_da->sql_errno() == ER_SERVER_SHUTDOWN) - my_message(ER_QUERY_INTERRUPTED, ER(ER_QUERY_INTERRUPTED), MYF(0)); - else - my_message(di->thd.stmt_da->sql_errno(), di->thd.stmt_da->message(), - MYF(0)); + my_message(di->thd.stmt_da->sql_errno(), di->thd.stmt_da->message(), + MYF(0)); } di->unlock(); goto end_create; @@ -2305,7 +2303,8 @@ end_create: TABLE *Delayed_insert::get_local_table(THD* client_thd) { my_ptrdiff_t adjust_ptrs; - Field **field,**org_field, *found_next_number_field, **dfield_ptr= 0; + Field **field,**org_field, *found_next_number_field; + Field **UNINIT_VAR(vfield), **UNINIT_VAR(dfield_ptr); TABLE *copy; TABLE_SHARE *share; uchar *bitmap; @@ -2341,7 +2340,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) killed using mysql_notify_thread_having_shared_lock() or kill_delayed_threads_for_table(). */ - if (!thd.is_error() || thd.stmt_da->sql_errno() == ER_SERVER_SHUTDOWN) + if (!thd.is_error()) my_message(ER_QUERY_INTERRUPTED, ER(ER_QUERY_INTERRUPTED), MYF(0)); else my_message(thd.stmt_da->sql_errno(), thd.stmt_da->message(), MYF(0)); @@ -2365,6 +2364,13 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) if (!copy_tmp) goto error; + if (share->vfields) + { + vfield= (Field **) client_thd->alloc((share->vfields+1)*sizeof(Field*)); + if (!vfield) + goto error; + } + /* Copy the TABLE object. */ copy= new (copy_tmp) TABLE; *copy= *table; @@ -2410,6 +2416,28 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) } } *field=0; + + if (share->vfields) + { + copy->vfield= vfield; + for (field= copy->field; *field; field++) + { + if ((*field)->vcol_info) + { + bool error_reported= FALSE; + if (unpack_vcol_info_from_frm(client_thd, + client_thd->mem_root, + copy, + *field, + &(*field)->vcol_info->expr_str, + &error_reported)) + goto error; + *vfield++= *field; + } + } + *vfield= 0; + } + if (share->default_fields) *dfield_ptr= NULL; @@ -2484,7 +2512,9 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, goto err; } - if (!(row->record= (char*) my_malloc(table->s->reclength, MYF(MY_WME)))) + /* This can't be THREAD_SPECIFIC as it's freed in delayed thread */ + if (!(row->record= (char*) my_malloc(table->s->reclength, + MYF(MY_WME)))) goto err; memcpy(row->record, table->record[0], table->s->reclength); row->start_time= thd->start_time; @@ -2715,7 +2745,10 @@ pthread_handler_t handle_delayed_insert(void *arg) thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; thd->set_current_time(); threads.append(thd); - thd->killed=abort_loop ? KILL_CONNECTION : NOT_KILLED; + if (abort_loop) + thd->killed= KILL_CONNECTION; + else + thd->reset_killed(); mysql_mutex_unlock(&LOCK_thread_count); mysql_thread_set_psi_id(thd->thread_id); @@ -2814,8 +2847,12 @@ pthread_handler_t handle_delayed_insert(void *arg) set_timespec(abstime, delayed_insert_timeout); /* Information for pthread_kill */ + mysql_mutex_unlock(&di->mutex); + mysql_mutex_lock(&di->thd.mysys_var->mutex); di->thd.mysys_var->current_mutex= &di->mutex; di->thd.mysys_var->current_cond= &di->cond; + mysql_mutex_unlock(&di->thd.mysys_var->mutex); + mysql_mutex_lock(&di->mutex); THD_STAGE_INFO(&(di->thd), stage_waiting_for_insert); DBUG_PRINT("info",("Waiting for someone to insert rows")); @@ -2900,24 +2937,28 @@ pthread_handler_t handle_delayed_insert(void *arg) DBUG_LEAVE; } - di->table=0; - thd->killed= KILL_CONNECTION; // If error - mysql_mutex_unlock(&di->mutex); + { + DBUG_ENTER("handle_delayed_insert-cleanup"); + di->table=0; + thd->killed= KILL_CONNECTION; // If error + mysql_mutex_unlock(&di->mutex); - close_thread_tables(thd); // Free the table - thd->mdl_context.release_transactional_locks(); - mysql_cond_broadcast(&di->cond_client); // Safety + close_thread_tables(thd); // Free the table + thd->mdl_context.release_transactional_locks(); + mysql_cond_broadcast(&di->cond_client); // Safety - mysql_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table - mysql_mutex_lock(&LOCK_delayed_insert); - /* - di should be unlinked from the thread handler list and have no active - clients - */ - delete di; - mysql_mutex_unlock(&LOCK_delayed_insert); - mysql_mutex_unlock(&LOCK_delayed_create); + mysql_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table + mysql_mutex_lock(&LOCK_delayed_insert); + /* + di should be unlinked from the thread handler list and have no active + clients + */ + delete di; + mysql_mutex_unlock(&LOCK_delayed_insert); + mysql_mutex_unlock(&LOCK_delayed_create); + DBUG_LEAVE; + } my_thread_end(); pthread_exit(0); |