summaryrefslogtreecommitdiff
path: root/sql/sql_insert.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r--sql/sql_insert.cc89
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);