The world's most popular open source database
#include "mysql_priv.h"#include "sp_head.h"#include "sql_trigger.h"#include "sql_select.h"#include "sql_show.h"Include dependency graph for sql_insert.cc:

Go to the source code of this file.
Classes | |
| class | delayed_row |
| class | delayed_insert |
Defines | |
| #define | my_safe_alloca(size, min_length) my_alloca(size) |
| #define | my_safe_afree(ptr, size, min_length) my_afree(ptr) |
Functions | |
| static int | check_null_fields (THD *thd, TABLE *entry) |
| static TABLE * | delayed_get_table (THD *thd, TABLE_LIST *table_list) |
| static int | write_delayed (THD *thd, TABLE *table, enum_duplicates dup, LEX_STRING query, bool ignore, bool log_on) |
| static void | end_delayed_insert (THD *thd) |
| pthread_handler_t | handle_delayed_insert (void *arg) |
| static void | unlink_blobs (register TABLE *table) |
| static bool | check_view_insertability (THD *thd, TABLE_LIST *view) |
| static int | check_insert_fields (THD *thd, TABLE_LIST *table_list, List< Item > &fields, List< Item > &values, bool check_unique) |
| static int | check_update_fields (THD *thd, TABLE_LIST *insert_table_list, List< Item > &update_fields) |
| bool | mysql_insert (THD *thd, TABLE_LIST *table_list, List< Item > &fields, List< List_item > &values_list, List< Item > &update_fields, List< Item > &update_values, enum_duplicates duplic, bool ignore) |
| static bool | mysql_prepare_insert_check_table (THD *thd, TABLE_LIST *table_list, List< Item > &fields, bool select_insert) |
| bool | mysql_prepare_insert (THD *thd, TABLE_LIST *table_list, TABLE *table, List< Item > &fields, List_item *values, List< Item > &update_fields, List< Item > &update_values, enum_duplicates duplic, COND **where, bool select_insert) |
| static int | last_uniq_key (TABLE *table, uint keynr) |
| int | write_record (THD *thd, TABLE *table, COPY_INFO *info) |
| int | check_that_all_fields_are_given_values (THD *thd, TABLE *entry, TABLE_LIST *table_list) |
| delayed_insert * | find_handler (THD *thd, TABLE_LIST *table_list) |
| void | kill_delayed_threads (void) |
| static void | free_delayed_insert_blobs (register TABLE *table) |
| bool | mysql_insert_select_prepare (THD *thd) |
| static TABLE * | create_table_from_items (THD *thd, HA_CREATE_INFO *create_info, TABLE_LIST *create_table, List< create_field > *extra_fields, List< Key > *keys, List< Item > *items, MYSQL_LOCK **lock, TABLEOP_HOOKS *hooks) |
Variables | |
| I_List< delayed_insert > | delayed_threads |
| #define my_safe_afree | ( | ptr, | |||
| size, | |||||
| min_length | ) | my_afree(ptr) |
| #define my_safe_alloca | ( | size, | |||
| min_length | ) | my_alloca(size) |
| static int check_insert_fields | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| List< Item > & | fields, | |||
| List< Item > & | values, | |||
| bool | check_unique | |||
| ) | [static] |
Definition at line 107 of file sql_insert.cc.
References st_table_list::alias, bitmap_is_set(), bitmap_set_all, bitmap_set_bit(), check_grant_all_columns(), check_key_in_view(), st_table_list::check_single_table(), check_view_insertability(), clear_timestamp_auto_bits, st_table_share::db, st_table_list::effective_algorithm, base_list::elements, ER_FIELD_SPECIFIED_TWICE, ER_NON_UPDATABLE_TABLE, ER_VIEW_MULTIUPDATE, ER_VIEW_NO_INSERT_FIELD_LIST, ER_WRONG_VALUE_COUNT_ON_ROW, FALSE, Field::field_index, st_table_share::fields, st_table::grant, grant_option, INSERT_ACL, map, MARK_COLUMNS_WRITE, my_error(), MYF, st_table_list::next_local, st_grant_info::privilege, Name_resolution_context::resolve_in_table_list_only(), Name_resolution_context_state::restore_state(), st_table::s, Name_resolution_context_state::save_state(), SELECT_ACL, Field_iterator_table::set_table(), setup_fields(), LEX_STRING::str, st_table_list::table, st_table_share::table_name, TIMESTAMP_AUTO_SET_ON_INSERT, st_table::timestamp_field, st_table::timestamp_field_type, TRUE, st_table_list::updatable, Item::used_tables(), st_table_list::view, VIEW_ALGORITHM_MERGE, st_table_list::view_db, st_table_list::view_name, st_grant_info::want_privilege, and st_table::write_set.
Referenced by mysql_prepare_insert().
00110 { 00111 TABLE *table= table_list->table; 00112 00113 if (!table_list->updatable) 00114 { 00115 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT"); 00116 return -1; 00117 } 00118 00119 if (fields.elements == 0 && values.elements != 0) 00120 { 00121 if (!table) 00122 { 00123 my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0), 00124 table_list->view_db.str, table_list->view_name.str); 00125 return -1; 00126 } 00127 if (values.elements != table->s->fields) 00128 { 00129 my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L); 00130 return -1; 00131 } 00132 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00133 if (grant_option) 00134 { 00135 Field_iterator_table fields; 00136 fields.set_table(table); 00137 if (check_grant_all_columns(thd, INSERT_ACL, &table->grant, 00138 table->s->db.str, table->s->table_name.str, 00139 &fields)) 00140 return -1; 00141 } 00142 #endif 00143 clear_timestamp_auto_bits(table->timestamp_field_type, 00144 TIMESTAMP_AUTO_SET_ON_INSERT); 00145 /* 00146 No fields are provided so all fields must be provided in the values. 00147 Thus we set all bits in the write set. 00148 */ 00149 bitmap_set_all(table->write_set); 00150 } 00151 else 00152 { // Part field list 00153 SELECT_LEX *select_lex= &thd->lex->select_lex; 00154 Name_resolution_context *context= &select_lex->context; 00155 Name_resolution_context_state ctx_state; 00156 int res; 00157 00158 if (fields.elements != values.elements) 00159 { 00160 my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L); 00161 return -1; 00162 } 00163 00164 thd->dup_field= 0; 00165 select_lex->no_wrap_view_item= TRUE; 00166 00167 /* Save the state of the current name resolution context. */ 00168 ctx_state.save_state(context, table_list); 00169 00170 /* 00171 Perform name resolution only in the first table - 'table_list', 00172 which is the table that is inserted into. 00173 */ 00174 table_list->next_local= 0; 00175 context->resolve_in_table_list_only(table_list); 00176 res= setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0); 00177 00178 /* Restore the current context. */ 00179 ctx_state.restore_state(context, table_list); 00180 thd->lex->select_lex.no_wrap_view_item= FALSE; 00181 00182 if (res) 00183 return -1; 00184 00185 if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE) 00186 { 00187 /* it is join view => we need to find table for update */ 00188 List_iterator_fast<Item> it(fields); 00189 Item *item; 00190 TABLE_LIST *tbl= 0; // reset for call to check_single_table() 00191 table_map map= 0; 00192 00193 while ((item= it++)) 00194 map|= item->used_tables(); 00195 if (table_list->check_single_table(&tbl, map, table_list) || tbl == 0) 00196 { 00197 my_error(ER_VIEW_MULTIUPDATE, MYF(0), 00198 table_list->view_db.str, table_list->view_name.str); 00199 return -1; 00200 } 00201 table_list->table= table= tbl->table; 00202 } 00203 00204 if (check_unique && thd->dup_field) 00205 { 00206 my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dup_field->field_name); 00207 return -1; 00208 } 00209 if (table->timestamp_field) // Don't automaticly set timestamp if used 00210 { 00211 if (bitmap_is_set(table->write_set, 00212 table->timestamp_field->field_index)) 00213 clear_timestamp_auto_bits(table->timestamp_field_type, 00214 TIMESTAMP_AUTO_SET_ON_INSERT); 00215 else 00216 { 00217 bitmap_set_bit(table->write_set, 00218 table->timestamp_field->field_index); 00219 } 00220 } 00221 } 00222 // For the values we need select_priv 00223 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00224 table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege); 00225 #endif 00226 00227 if (check_key_in_view(thd, table_list) || 00228 (table_list->view && 00229 check_view_insertability(thd, table_list))) 00230 { 00231 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT"); 00232 return -1; 00233 } 00234 00235 return 0; 00236 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int check_null_fields | ( | THD * | thd, | |
| TABLE * | entry | |||
| ) | [static] |
| int check_that_all_fields_are_given_values | ( | THD * | thd, | |
| TABLE * | entry, | |||
| TABLE_LIST * | table_list | |||
| ) |
Definition at line 1271 of file sql_insert.cc.
References bitmap_is_set(), ER, ER_NO_DEFAULT_FOR_FIELD, ER_NO_DEFAULT_FOR_VIEW_FIELD, err, FALSE, st_find_field::field, FIELD_TYPE_ENUM, NO_DEFAULT_VALUE_FLAG, push_warning_printf(), LEX_STRING::str, test, st_table_list::top_table(), st_table_list::view, st_table_list::view_db, st_table_list::view_name, and MYSQL_ERROR::WARN_LEVEL_WARN.
Referenced by mysql_insert(), and mysql_load().
01273 { 01274 int err= 0; 01275 MY_BITMAP *write_set= entry->write_set; 01276 01277 for (Field **field=entry->field ; *field ; field++) 01278 { 01279 if (!bitmap_is_set(write_set, (*field)->field_index) && 01280 ((*field)->flags & NO_DEFAULT_VALUE_FLAG) && 01281 ((*field)->real_type() != FIELD_TYPE_ENUM)) 01282 { 01283 bool view= FALSE; 01284 if (table_list) 01285 { 01286 table_list= table_list->top_table(); 01287 view= test(table_list->view); 01288 } 01289 if (view) 01290 { 01291 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 01292 ER_NO_DEFAULT_FOR_VIEW_FIELD, 01293 ER(ER_NO_DEFAULT_FOR_VIEW_FIELD), 01294 table_list->view_db.str, 01295 table_list->view_name.str); 01296 } 01297 else 01298 { 01299 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 01300 ER_NO_DEFAULT_FOR_FIELD, 01301 ER(ER_NO_DEFAULT_FOR_FIELD), 01302 (*field)->field_name); 01303 } 01304 err= 1; 01305 } 01306 } 01307 return thd->abort_on_warning ? err : 0; 01308 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int check_update_fields | ( | THD * | thd, | |
| TABLE_LIST * | insert_table_list, | |||
| List< Item > & | update_fields | |||
| ) | [static] |
Definition at line 258 of file sql_insert.cc.
References bitmap_is_set(), bitmap_set_bit(), bitmap_test_and_clear(), clear_timestamp_auto_bits, Field::field_index, MARK_COLUMNS_WRITE, setup_fields(), st_table_list::table, TIMESTAMP_AUTO_SET_ON_UPDATE, st_table::timestamp_field, st_table::timestamp_field_type, and st_table::write_set.
Referenced by mysql_prepare_insert().
00260 { 00261 TABLE *table= insert_table_list->table; 00262 my_bool timestamp_mark; 00263 00264 if (table->timestamp_field) 00265 { 00266 /* 00267 Unmark the timestamp field so that we can check if this is modified 00268 by update_fields 00269 */ 00270 timestamp_mark= bitmap_test_and_clear(table->write_set, 00271 table->timestamp_field->field_index); 00272 } 00273 00274 /* Check the fields we are going to modify */ 00275 if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, 0)) 00276 return -1; 00277 00278 if (table->timestamp_field) 00279 { 00280 /* Don't set timestamp column if this is modified. */ 00281 if (bitmap_is_set(table->write_set, 00282 table->timestamp_field->field_index)) 00283 clear_timestamp_auto_bits(table->timestamp_field_type, 00284 TIMESTAMP_AUTO_SET_ON_UPDATE); 00285 if (timestamp_mark) 00286 bitmap_set_bit(table->write_set, 00287 table->timestamp_field->field_index); 00288 } 00289 return 0; 00290 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool check_view_insertability | ( | THD * | thd, | |
| TABLE_LIST * | view | |||
| ) | [static] |
Definition at line 722 of file sql_insert.cc.
References bitmap_buffer_size, bitmap_clear_all, bitmap_fast_test_and_set(), bitmap_init(), st_table_list::contain_auto_increment, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, FALSE, st_find_field::field, st_table::field, Field::field_index, st_table_list::field_translation, st_table_share::fields, Item::filed_for_view_update(), Item::fix_fields(), Item::fixed, Field_translator::item, MARK_COLUMNS_NONE, Field::NEXT_NUMBER, st_table::s, Field::table, st_table_list::table, TRUE, Field::unireg_check, st_table_list::view, and VOID.
Referenced by check_insert_fields().
00723 { 00724 uint num= view->view->select_lex.item_list.elements; 00725 TABLE *table= view->table; 00726 Field_translator *trans_start= view->field_translation, 00727 *trans_end= trans_start + num; 00728 Field_translator *trans; 00729 Field **field_ptr= table->field; 00730 uint used_fields_buff_size= bitmap_buffer_size(table->s->fields); 00731 uint32 *used_fields_buff= (uint32*)thd->alloc(used_fields_buff_size); 00732 MY_BITMAP used_fields; 00733 enum_mark_columns save_mark_used_columns= thd->mark_used_columns; 00734 DBUG_ENTER("check_key_in_view"); 00735 00736 if (!used_fields_buff) 00737 DBUG_RETURN(TRUE); // EOM 00738 00739 DBUG_ASSERT(view->table != 0 && view->field_translation != 0); 00740 00741 VOID(bitmap_init(&used_fields, used_fields_buff, table->s->fields, 0)); 00742 bitmap_clear_all(&used_fields); 00743 00744 view->contain_auto_increment= 0; 00745 /* 00746 we must not set query_id for fields as they're not 00747 really used in this context 00748 */ 00749 thd->mark_used_columns= MARK_COLUMNS_NONE; 00750 /* check simplicity and prepare unique test of view */ 00751 for (trans= trans_start; trans != trans_end; trans++) 00752 { 00753 if (!trans->item->fixed && trans->item->fix_fields(thd, &trans->item)) 00754 { 00755 thd->mark_used_columns= save_mark_used_columns; 00756 DBUG_RETURN(TRUE); 00757 } 00758 Item_field *field; 00759 /* simple SELECT list entry (field without expression) */ 00760 if (!(field= trans->item->filed_for_view_update())) 00761 { 00762 thd->mark_used_columns= save_mark_used_columns; 00763 DBUG_RETURN(TRUE); 00764 } 00765 if (field->field->unireg_check == Field::NEXT_NUMBER) 00766 view->contain_auto_increment= 1; 00767 /* prepare unique test */ 00768 /* 00769 remove collation (or other transparent for update function) if we have 00770 it 00771 */ 00772 trans->item= field; 00773 } 00774 thd->mark_used_columns= save_mark_used_columns; 00775 /* unique test */ 00776 for (trans= trans_start; trans != trans_end; trans++) 00777 { 00778 /* Thanks to test above, we know that all columns are of type Item_field */ 00779 Item_field *field= (Item_field *)trans->item; 00780 /* check fields belong to table in which we are inserting */ 00781 if (field->field->table == table && 00782 bitmap_fast_test_and_set(&used_fields, field->field->field_index)) 00783 DBUG_RETURN(TRUE); 00784 } 00785 00786 DBUG_RETURN(FALSE); 00787 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static TABLE* create_table_from_items | ( | THD * | thd, | |
| HA_CREATE_INFO * | create_info, | |||
| TABLE_LIST * | create_table, | |||
| List< create_field > * | extra_fields, | |||
| List< Key > * | keys, | |||
| List< Item > * | items, | |||
| MYSQL_LOCK ** | lock, | |||
| TABLEOP_HOOKS * | hooks | |||
| ) | [static] |
Definition at line 2735 of file sql_insert.cc.
References st_table::alias, st_table_share::blob_ptr_size, create_table(), create_tmp_field(), st_table_share::db_create_options, st_table_share::db_low_byte_first, st_ha_create_information::db_type, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, base_list::elements, handler::extra(), Item::FIELD_ITEM, st_table::file, create_field::flags, Item::FUNC_ITEM, HA_EXTRA_WRITE_CACHE, HA_LEX_CREATE_TMP_TABLE, hash_delete(), heap_hton, init_tmp_table_share(), keys, lock, LOCK_open, st_reginfo::lock_type, Item::maybe_null, st_table::maybe_null, myisam_hton, mysql_create_table(), mysql_lock_tables(), NOT_NULL_FLAG, st_table::null_row, open_cache, open_table(), st_ha_create_information::options, portable_sizeof_char_ptr, TABLEOP_HOOKS::prelock(), pthread_mutex_lock, pthread_mutex_unlock, List< T >::push_back(), quick_rm_table(), st_table::reginfo, st_table::s, test, st_table::timestamp_field, TL_WRITE, Item::tmp_table_field(), Item::type(), and VOID.
02742 { 02743 TABLE tmp_table; // Used during 'create_field()' 02744 TABLE_SHARE share; 02745 TABLE *table= 0; 02746 uint select_field_count= items->elements; 02747 /* Add selected items to field list */ 02748 List_iterator_fast<Item> it(*items); 02749 Item *item; 02750 Field *tmp_field; 02751 bool not_used; 02752 DBUG_ENTER("create_table_from_items"); 02753 02754 tmp_table.alias= 0; 02755 tmp_table.timestamp_field= 0; 02756 tmp_table.s= &share; 02757 init_tmp_table_share(&share, "", 0, "", ""); 02758 02759 tmp_table.s->db_create_options=0; 02760 tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr; 02761 tmp_table.s->db_low_byte_first= 02762 test(create_info->db_type == &myisam_hton || 02763 create_info->db_type == &heap_hton); 02764 tmp_table.null_row=tmp_table.maybe_null=0; 02765 02766 while ((item=it++)) 02767 { 02768 create_field *cr_field; 02769 Field *field, *def_field; 02770 if (item->type() == Item::FUNC_ITEM) 02771 field= item->tmp_table_field(&tmp_table); 02772 else 02773 field= create_tmp_field(thd, &tmp_table, item, item->type(), 02774 (Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0, 02775 0); 02776 if (!field || 02777 !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ? 02778 ((Item_field *)item)->field : 02779 (Field*) 0)))) 02780 DBUG_RETURN(0); 02781 if (item->maybe_null) 02782 cr_field->flags &= ~NOT_NULL_FLAG; 02783 extra_fields->push_back(cr_field); 02784 } 02785 /* 02786 create and lock table 02787 02788 We don't log the statement, it will be logged later. 02789 02790 If this is a HEAP table, the automatic DELETE FROM which is written to the 02791 binlog when a HEAP table is opened for the first time since startup, must 02792 not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we 02793 don't want to delete from it) 2) it would be written before the CREATE 02794 TABLE, which is a wrong order. So we keep binary logging disabled when we 02795 open_table(). 02796 NOTE: By locking table which we just have created (or for which we just 02797 have have found that it already exists) separately from other tables used 02798 by the statement we create potential window for deadlock. 02799 TODO: create and open should be done atomic ! 02800 */ 02801 { 02802 tmp_disable_binlog(thd); 02803 if (!mysql_create_table(thd, create_table->db, create_table->table_name, 02804 create_info, *extra_fields, *keys, 0, 02805 select_field_count, 0)) 02806 { 02807 /* 02808 If we are here in prelocked mode we either create temporary table 02809 or prelocked mode is caused by the SELECT part of this statement. 02810 */ 02811 DBUG_ASSERT(!thd->prelocked_mode || 02812 create_info->options & HA_LEX_CREATE_TMP_TABLE || 02813 thd->lex->requires_prelocking()); 02814 02815 /* 02816 NOTE: We don't want to ignore set of locked tables here if we are 02817 under explicit LOCK TABLES since it will open gap for deadlock 02818 too wide (and also is not backward compatible). 02819 */ 02820 02821 if (! (table= open_table(thd, create_table, thd->mem_root, (bool*) 0, 02822 (MYSQL_LOCK_IGNORE_FLUSH | 02823 ((thd->prelocked_mode == PRELOCKED) ? 02824 MYSQL_OPEN_IGNORE_LOCKED_TABLES:0))))) 02825 quick_rm_table(create_info->db_type, create_table->db, 02826 table_case_name(create_info, create_table->table_name), 02827 0); 02828 } 02829 reenable_binlog(thd); 02830 if (!table) // open failed 02831 DBUG_RETURN(0); 02832 } 02833 02834 /* 02835 FIXME: What happens if trigger manages to be created while we are 02836 obtaining this lock ? May be it is sensible just to disable 02837 trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH 02838 save us from that ? 02839 */ 02840 table->reginfo.lock_type=TL_WRITE; 02841 hooks->prelock(&table, 1); // Call prelock hooks 02842 if (! ((*lock)= mysql_lock_tables(thd, &table, 1, 02843 MYSQL_LOCK_IGNORE_FLUSH, ¬_used))) 02844 { 02845 VOID(pthread_mutex_lock(&LOCK_open)); 02846 hash_delete(&open_cache,(byte*) table); 02847 VOID(pthread_mutex_unlock(&LOCK_open)); 02848 quick_rm_table(create_info->db_type, create_table->db, 02849 table_case_name(create_info, create_table->table_name), 0); 02850 DBUG_RETURN(0); 02851 } 02852 table->file->extra(HA_EXTRA_WRITE_CACHE); 02853 DBUG_RETURN(table); 02854 }
Here is the call graph for this function:

| static TABLE * delayed_get_table | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) | [static] |
Definition at line 1456 of file sql_insert.cc.
References st_table_list::alias, connection_attrib, st_table_list::db, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, delayed_insert_threads, ER, ER_CANT_CREATE_THREAD, ER_OUT_OF_RESOURCES, ER_OUTOFMEMORY, err, error, find_handler(), delayed_insert::get_local_table(), handle_delayed_insert(), delayed_insert::lock(), LOCK_delayed_create, LOCK_thread_count, delayed_insert::mutex, my_error(), my_message(), my_strdup(), MY_WME, MYF, NULL, pthread_mutex_lock, pthread_mutex_unlock, strlen(), strmov(), st_table_list::table, delayed_insert::table_list, st_table_list::table_name, delayed_insert::thd, thread_count, and delayed_insert::unlock().
Referenced by mysql_insert().
01457 { 01458 int error; 01459 delayed_insert *tmp; 01460 TABLE *table; 01461 DBUG_ENTER("delayed_get_table"); 01462 01463 /* Must be set in the parser */ 01464 DBUG_ASSERT(table_list->db); 01465 01466 /* Find the thread which handles this table. */ 01467 if (!(tmp=find_handler(thd,table_list))) 01468 { 01469 /* 01470 No match. Create a new thread to handle the table, but 01471 no more than max_insert_delayed_threads. 01472 */ 01473 if (delayed_insert_threads >= thd->variables.max_insert_delayed_threads) 01474 DBUG_RETURN(0); 01475 thd->proc_info="Creating delayed handler"; 01476 pthread_mutex_lock(&LOCK_delayed_create); 01477 /* 01478 The first search above was done without LOCK_delayed_create. 01479 Another thread might have created the handler in between. Search again. 01480 */ 01481 if (! (tmp= find_handler(thd, table_list))) 01482 { 01483 if (!(tmp=new delayed_insert())) 01484 { 01485 my_error(ER_OUTOFMEMORY,MYF(0),sizeof(delayed_insert)); 01486 goto err1; 01487 } 01488 pthread_mutex_lock(&LOCK_thread_count); 01489 thread_count++; 01490 pthread_mutex_unlock(&LOCK_thread_count); 01491 tmp->thd.set_db(table_list->db, strlen(table_list->db)); 01492 tmp->thd.query= my_strdup(table_list->table_name,MYF(MY_WME)); 01493 if (tmp->thd.db == NULL || tmp->thd.query == NULL) 01494 { 01495 delete tmp; 01496 my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); 01497 goto err1; 01498 } 01499 tmp->table_list= *table_list; // Needed to open table 01500 tmp->table_list.alias= tmp->table_list.table_name= tmp->thd.query; 01501 tmp->lock(); 01502 pthread_mutex_lock(&tmp->mutex); 01503 if ((error=pthread_create(&tmp->thd.real_id,&connection_attrib, 01504 handle_delayed_insert,(void*) tmp))) 01505 { 01506 DBUG_PRINT("error", 01507 ("Can't create thread to handle delayed insert (error %d)", 01508 error)); 01509 pthread_mutex_unlock(&tmp->mutex); 01510 tmp->unlock(); 01511 delete tmp; 01512 my_error(ER_CANT_CREATE_THREAD, MYF(0), error); 01513 goto err1; 01514 } 01515 01516 /* Wait until table is open */ 01517 thd->proc_info="waiting for handler open"; 01518 while (!tmp->thd.killed && !tmp->table && !thd->killed) 01519 { 01520 pthread_cond_wait(&tmp->cond_client,&tmp->mutex); 01521 } 01522 pthread_mutex_unlock(&tmp->mutex); 01523 thd->proc_info="got old table"; 01524 if (tmp->thd.killed) 01525 { 01526 if (tmp->thd.is_fatal_error) 01527 { 01528 /* Copy error message and abort */ 01529 thd->fatal_error(); 01530 strmov(thd->net.last_error,tmp->thd.net.last_error); 01531 thd->net.last_errno=tmp->thd.net.last_errno; 01532 } 01533 tmp->unlock(); 01534 goto err; 01535 } 01536 if (thd->killed) 01537 { 01538 tmp->unlock(); 01539 goto err; 01540 } 01541 } 01542 pthread_mutex_unlock(&LOCK_delayed_create); 01543 } 01544 01545 pthread_mutex_lock(&tmp->mutex); 01546 table= tmp->get_local_table(thd); 01547 pthread_mutex_unlock(&tmp->mutex); 01548 if (table) 01549 thd->di=tmp; 01550 else if (tmp->thd.is_fatal_error) 01551 thd->fatal_error(); 01552 /* Unlock the delayed insert object after its last access. */ 01553 tmp->unlock(); 01554 DBUG_RETURN((table_list->table=table)); 01555 01556 err1: 01557 thd->fatal_error(); 01558 err: 01559 pthread_mutex_unlock(&LOCK_delayed_create); 01560 DBUG_RETURN(0); // Continue with normal insert 01561 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void end_delayed_insert | ( | THD * | thd | ) | [static] |
Definition at line 1756 of file sql_insert.cc.
References delayed_insert::cond, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, delayed_insert::mutex, pthread_mutex_lock, pthread_mutex_unlock, delayed_insert::status,

